feat: redesign app UI — top nav, clean dashboard, warm branding

- Replace sidebar with top navigation bar (like Airbnb/Nextdoor)
- Redesign dashboard: home cards, coming up tasks, quick action pills
- Remove widget-heavy layout (charts, stats, activity feed)
- Add landing page with hero, features, how-it-works, CTA sections
- Update auth pages with split layout
- Clean white theme with neutral grays, brand orange/teal accents
- Friendly copy across all empty states and page headers
- Add Bricolage Grotesque + Outfit fonts
- Default to light mode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
treyt
2026-03-03 13:06:13 -06:00
parent a0e38e5ae5
commit db89ddb861
37 changed files with 1622 additions and 498 deletions
+17 -17
View File
@@ -26,28 +26,28 @@ export const themes: ThemeDefinition[] = [
{
id: "default",
name: "Default",
description: "Vibrant iOS system colors",
description: "Warm orange with teal accents",
light: {
primary: "#0079FF",
secondary: "#5AC7F9",
accent: "#FF9400",
error: "#FF3A2F",
primary: "#E07A3A",
secondary: "#0D7C66",
accent: "#D4A574",
error: "#DC2626",
bgPrimary: "#FFFFFF",
bgSecondary: "#F1F7F7",
textPrimary: "#111111",
textSecondary: "#3C3C3C",
bgSecondary: "#F7F7F7",
textPrimary: "#1C1917",
textSecondary: "#78716C",
textOnPrimary: "#FFFFFF",
},
dark: {
primary: "#0984FF",
secondary: "#63D2FF",
accent: "#FF9F09",
error: "#FF4539",
bgPrimary: "#1C1C1C",
bgSecondary: "#2C2C2C",
textPrimary: "#FFFFFF",
textSecondary: "#EBEBEB",
textOnPrimary: "#FFFFFF",
primary: "#F0A070",
secondary: "#4FC9AF",
accent: "#DDB892",
error: "#EF4444",
bgPrimary: "#0A0A0A",
bgSecondary: "#161616",
textPrimary: "#FAFAFA",
textSecondary: "#A1A1A1",
textOnPrimary: "#0A0A0A",
},
},
{
+17 -10
View File
@@ -3,16 +3,6 @@
import { useEffect } from "react";
import { useThemeStore } from "@/stores/theme";
/**
* ThemeProvider syncs the Zustand theme store with the DOM.
*
* It sets:
* - `data-theme` attribute on <html> for CSS theme selection
* - `dark` class on <html> for dark mode (respects system preference when mode is "system")
*
* Render this component once, near the root of the app (e.g., in layout.tsx).
* It renders no visible DOM — it only produces side effects.
*/
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const themeId = useThemeStore((s) => s.themeId);
const mode = useThemeStore((s) => s.mode);
@@ -51,5 +41,22 @@ 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}</>;
}