From 2f77674c5504f98ba51bfc087b4bc1ea86cd09d3 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Fri, 10 Apr 2026 16:21:05 +0700 Subject: [PATCH] feat: add theme selector with multiple dark themes Add theme dropdown in settings with Light, Dark, System plus Zinc, Midnight, Claude, and Ghostty dark variants. Each theme has its own accent color and surface tints. Desaturate terminal ANSI colors across all dark themes. Add surfaceSidebarHover semantic token so hover states go the right direction in both light and dark modes. Self-heal if a stored theme no longer exists. --- packages/app/src/app/_layout.tsx | 3 +- .../app/src/components/explorer-sidebar.tsx | 2 +- .../app/src/components/file-explorer-pane.tsx | 2 +- packages/app/src/components/left-sidebar.tsx | 6 +- .../src/components/sidebar-workspace-list.tsx | 10 +- packages/app/src/hooks/use-settings.ts | 9 +- packages/app/src/screens/settings-screen.tsx | 119 ++++-- packages/app/src/styles/theme.ts | 339 +++++++++++++----- packages/app/src/styles/unistyles.ts | 20 +- 9 files changed, 375 insertions(+), 135 deletions(-) diff --git a/packages/app/src/app/_layout.tsx b/packages/app/src/app/_layout.tsx index 03483af99..e1b41b450 100644 --- a/packages/app/src/app/_layout.tsx +++ b/packages/app/src/app/_layout.tsx @@ -14,6 +14,7 @@ import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import { PortalProvider } from "@gorhom/portal"; import { VoiceProvider } from "@/contexts/voice-context"; import { useAppSettings } from "@/hooks/use-settings"; +import { THEME_TO_UNISTYLES } from "@/styles/theme"; import { useFaviconStatus } from "@/hooks/use-favicon-status"; import { View, Text } from "react-native"; import { UnistylesRuntime, useUnistyles } from "react-native-unistyles"; @@ -561,7 +562,7 @@ function ProvidersWrapper({ children }: { children: ReactNode }) { UnistylesRuntime.setAdaptiveThemes(true); } else { UnistylesRuntime.setAdaptiveThemes(false); - UnistylesRuntime.setTheme(settings.theme); + UnistylesRuntime.setTheme(THEME_TO_UNISTYLES[settings.theme]); } }, [settingsLoading, settings.theme]); diff --git a/packages/app/src/components/explorer-sidebar.tsx b/packages/app/src/components/explorer-sidebar.tsx index fcfe9a140..f324ae158 100644 --- a/packages/app/src/components/explorer-sidebar.tsx +++ b/packages/app/src/components/explorer-sidebar.tsx @@ -472,7 +472,7 @@ const styles = StyleSheet.create((theme) => ({ borderRadius: theme.borderRadius.md, }, tabActive: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, tabText: { fontSize: theme.fontSize.sm, diff --git a/packages/app/src/components/file-explorer-pane.tsx b/packages/app/src/components/file-explorer-pane.tsx index 983fd1147..b1d0230f9 100644 --- a/packages/app/src/components/file-explorer-pane.tsx +++ b/packages/app/src/components/file-explorer-pane.tsx @@ -849,7 +849,7 @@ const styles = StyleSheet.create((theme) => ({ borderRadius: theme.borderRadius.md, }, entryRowActive: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, indentGuide: { position: "absolute", diff --git a/packages/app/src/components/left-sidebar.tsx b/packages/app/src/components/left-sidebar.tsx index 5d9b27e63..c3eb01e31 100644 --- a/packages/app/src/components/left-sidebar.tsx +++ b/packages/app/src/components/left-sidebar.tsx @@ -885,10 +885,10 @@ const styles = StyleSheet.create((theme) => ({ color: theme.colors.foreground, }, newAgentButtonHovered: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, newAgentButtonActive: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, hostTrigger: { flexDirection: "row", @@ -901,7 +901,7 @@ const styles = StyleSheet.create((theme) => ({ borderRadius: theme.borderRadius.lg, }, hostTriggerHovered: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, hostStatusDot: { width: 8, diff --git a/packages/app/src/components/sidebar-workspace-list.tsx b/packages/app/src/components/sidebar-workspace-list.tsx index 5ae598445..e6fb347b7 100644 --- a/packages/app/src/components/sidebar-workspace-list.tsx +++ b/packages/app/src/components/sidebar-workspace-list.tsx @@ -1980,7 +1980,7 @@ const styles = StyleSheet.create((theme) => ({ gap: theme.spacing[2], }, projectRowHovered: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, projectRowPressed: { backgroundColor: theme.colors.surface2, @@ -2050,7 +2050,7 @@ const styles = StyleSheet.create((theme) => ({ flexShrink: 0, }, projectActionButtonHovered: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, projectActionButtonText: { color: theme.colors.foregroundMuted, @@ -2065,7 +2065,7 @@ const styles = StyleSheet.create((theme) => ({ flexShrink: 0, }, projectIconActionButtonHovered: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, projectIconActionButtonHidden: { opacity: 0, @@ -2143,7 +2143,7 @@ const styles = StyleSheet.create((theme) => ({ flexShrink: 0, }, workspaceRowHovered: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, workspaceRowPressed: { backgroundColor: theme.colors.surface2, @@ -2157,7 +2157,7 @@ const styles = StyleSheet.create((theme) => ({ ...theme.shadow.md, }, sidebarRowSelected: { - backgroundColor: theme.colors.surface1, + backgroundColor: theme.colors.surfaceSidebarHover, }, workspaceRowContainer: { position: "relative", diff --git a/packages/app/src/hooks/use-settings.ts b/packages/app/src/hooks/use-settings.ts index 762f610e5..1c3793e49 100644 --- a/packages/app/src/hooks/use-settings.ts +++ b/packages/app/src/hooks/use-settings.ts @@ -6,10 +6,14 @@ export const APP_SETTINGS_KEY = "@paseo:app-settings"; const LEGACY_SETTINGS_KEY = "@paseo:settings"; const APP_SETTINGS_QUERY_KEY = ["app-settings"]; +import { THEME_TO_UNISTYLES, type ThemeName } from "@/styles/theme"; + export type SendBehavior = "interrupt" | "queue"; +const VALID_THEMES = new Set([...Object.keys(THEME_TO_UNISTYLES), "auto"]); + export interface AppSettings { - theme: "dark" | "light" | "auto"; + theme: ThemeName | "auto"; manageBuiltInDaemon: boolean; sendBehavior: SendBehavior; } @@ -78,6 +82,9 @@ export async function loadSettingsFromStorage(): Promise { const stored = await AsyncStorage.getItem(APP_SETTINGS_KEY); if (stored) { const parsed = JSON.parse(stored) as Partial; + if (parsed.theme && !VALID_THEMES.has(parsed.theme)) { + parsed.theme = DEFAULT_APP_SETTINGS.theme; + } return { ...DEFAULT_APP_SETTINGS, ...parsed }; } diff --git a/packages/app/src/screens/settings-screen.tsx b/packages/app/src/screens/settings-screen.tsx index 507a5a220..f25aa969b 100644 --- a/packages/app/src/screens/settings-screen.tsx +++ b/packages/app/src/screens/settings-screen.tsx @@ -10,6 +10,7 @@ import { Sun, Moon, Monitor, + ChevronDown, Globe, Settings, RotateCw, @@ -24,6 +25,7 @@ import { Smartphone, } from "lucide-react-native"; import { useAppSettings, type AppSettings, type SendBehavior } from "@/hooks/use-settings"; +import { THEME_SWATCHES, type ThemeName } from "@/styles/theme"; import type { HostProfile, HostConnection } from "@/types/host-connection"; import { useHosts, useHostMutations } from "@/runtime/host-runtime"; import { formatConnectionStatus, getConnectionStatusTone } from "@/utils/daemons"; @@ -47,6 +49,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, + DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { AdaptiveModalSheet, AdaptiveTextInput } from "@/components/adaptive-modal-sheet"; @@ -362,11 +365,53 @@ interface GeneralSectionProps { handleSendBehaviorChange: (behavior: SendBehavior) => void; } +function ThemeIcon({ theme, size, color }: { theme: AppSettings["theme"]; size: number; color: string }) { + switch (theme) { + case "light": + return ; + case "dark": + return ; + case "auto": + return ; + default: + return ; + } +} + +function ThemeSwatch({ color, size }: { color: string; size: number }) { + return ( + + ); +} + +const THEME_LABELS: Record = { + light: "Light", + dark: "Dark", + zinc: "Zinc", + midnight: "Midnight", + claude: "Claude", + ghostty: "Ghostty", + auto: "System", +}; + function GeneralSection({ settings, handleThemeChange, handleSendBehaviorChange, }: GeneralSectionProps) { + const { theme } = useUnistyles(); + const iconSize = theme.iconSize.md; + const iconColor = theme.colors.foregroundMuted; + return ( General @@ -375,29 +420,43 @@ function GeneralSection({ Theme - , - }, - { - value: "dark", - label: "Dark", - icon: ({ color, size }) => , - }, - { - value: "auto", - label: "System", - icon: ({ color, size }) => , - }, - ]} - /> + + [ + styles.themeTrigger, + pressed && { opacity: 0.85 }, + ]} + > + + + {THEME_LABELS[settings.theme]} + + + + + {(["light", "dark", "auto"] as const).map((t) => ( + handleThemeChange(t)} + leading={} + > + {THEME_LABELS[t]} + + ))} + + {(["zinc", "midnight", "claude", "ghostty"] as const).map((t) => ( + handleThemeChange(t)} + leading={} + > + {THEME_LABELS[t]} + + ))} + + @@ -1806,6 +1865,20 @@ const styles = StyleSheet.create((theme) => ({ fontSize: theme.fontSize.sm, fontWeight: theme.fontWeight.medium, }, + themeTrigger: { + flexDirection: "row", + alignItems: "center", + gap: theme.spacing[1], + paddingVertical: theme.spacing[1], + paddingHorizontal: theme.spacing[2], + borderRadius: theme.borderRadius.md, + borderWidth: 1, + borderColor: theme.colors.border, + }, + themeTriggerText: { + color: theme.colors.foreground, + fontSize: theme.fontSize.sm, + }, disabled: { opacity: theme.opacity[50], }, diff --git a/packages/app/src/styles/theme.ts b/packages/app/src/styles/theme.ts index 1c72d8b59..c0f40f86b 100644 --- a/packages/app/src/styles/theme.ts +++ b/packages/app/src/styles/theme.ts @@ -103,6 +103,8 @@ export const baseColors = { }, } as const; +export type ThemeName = "light" | "dark" | "zinc" | "midnight" | "claude" | "ghostty"; + // Semantic color tokens - Layer-based system const lightSemanticColors = { // Surfaces (layers) - shifted one step lighter @@ -113,10 +115,11 @@ const lightSemanticColors = { surface4: "#d4d4d8", // Extra emphasis (was zinc-400, now zinc-300) surfaceDiffEmpty: "#f6f6f6", // Empty side of split diff rows, between surface1 and surface2 and biased toward surface2 surfaceSidebar: "#f4f4f5", // Sidebar background (darker than main) + surfaceSidebarHover: "#e9e9ec", // Sidebar hover (darker in light mode) surfaceWorkspace: "#ffffff", // Workspace main background // Text - foreground: "#09090b", + foreground: "#1a1a1e", foregroundMuted: "#71717a", // Controls @@ -140,11 +143,11 @@ const lightSemanticColors = { // Legacy aliases (for gradual migration) background: "#ffffff", popover: "#ffffff", - popoverForeground: "#09090b", + popoverForeground: "#1a1a1e", primary: "#18181b", primaryForeground: "#fafafa", secondary: "#f4f4f5", - secondaryForeground: "#09090b", + secondaryForeground: "#1a1a1e", muted: "#f4f4f5", mutedForeground: "#71717a", accentBorder: "#ececf1", @@ -153,13 +156,13 @@ const lightSemanticColors = { terminal: { background: "#ffffff", - foreground: "#09090b", - cursor: "#09090b", + foreground: "#1a1a1e", + cursor: "#1a1a1e", cursorAccent: "#ffffff", selectionBackground: "rgba(0, 0, 0, 0.15)", - selectionForeground: "#09090b", + selectionForeground: "#1a1a1e", - black: "#09090b", + black: "#1a1a1e", red: "#dc2626", green: "#16a34a", yellow: "#ca8a04", @@ -179,80 +182,194 @@ const lightSemanticColors = { }, } as const; -const darkSemanticColors = { - // Surfaces (layers) — subtle teal tint - surface0: "#181B1A", // App background - surface1: "#1E2120", // Subtle hover - surface2: "#272A29", // Elevated: badges, inputs, sheets - surface3: "#434645", // Highest elevation - surface4: "#595B5B", // Extra emphasis - surfaceDiffEmpty: "#252827", // Empty side of split diff rows, between surface1 and surface2 and biased toward surface2 - surfaceSidebar: "#141716", // Sidebar background (darker than main) - surfaceWorkspace: "#1E2120", // Workspace main background (surface1) +// --------------------------------------------------------------------------- +// Dark theme variant builder +// --------------------------------------------------------------------------- - // Text - foreground: "#fafafa", +interface DarkThemeConfig { + surface0: string; + surface1: string; + surface2: string; + surface3: string; + surface4: string; + surfaceDiffEmpty: string; + surfaceSidebar: string; + surfaceSidebarHover: string; + foregroundMuted: string; + scrollbarHandle: string; + border: string; + borderAccent: string; + accent: string; + accentBright: string; +} + +const darkTerminalAnsi = { + red: "#e07070", + green: "#5dba80", + yellow: "#d4a44a", + blue: "#6a9de0", + magenta: "#b07ad0", + cyan: "#4aabb8", + white: "#d4d4d8", + brightRed: "#e89090", + brightGreen: "#7ecf9a", + brightYellow: "#e0be6e", + brightBlue: "#8ab4e8", + brightMagenta: "#c49ae0", + brightCyan: "#6ec2cc", + brightWhite: "#f0f0f2", +} as const; + +function buildDarkSemanticColors(tint: DarkThemeConfig) { + return { + surface0: tint.surface0, + surface1: tint.surface1, + surface2: tint.surface2, + surface3: tint.surface3, + surface4: tint.surface4, + surfaceDiffEmpty: tint.surfaceDiffEmpty, + surfaceSidebar: tint.surfaceSidebar, + surfaceSidebarHover: tint.surfaceSidebarHover, + surfaceWorkspace: tint.surface1, + + foreground: "#fafafa", + foregroundMuted: tint.foregroundMuted, + + scrollbarHandle: tint.scrollbarHandle, + + border: tint.border, + borderAccent: tint.borderAccent, + + accent: tint.accent, + accentBright: tint.accentBright, + accentForeground: "#ffffff", + + destructive: "#ef4444", + destructiveForeground: "#ffffff", + success: tint.accent, + successForeground: "#ffffff", + + // Legacy aliases (for gradual migration) + background: tint.surface0, + popover: tint.surface2, + popoverForeground: "#fafafa", + primary: "#fafafa", + primaryForeground: tint.surface0, + secondary: tint.surface2, + secondaryForeground: "#fafafa", + muted: tint.surface2, + mutedForeground: tint.foregroundMuted, + accentBorder: tint.borderAccent, + input: tint.surface2, + ring: "#d4d4d8", + + terminal: { + background: tint.surface0, + foreground: "#fafafa", + cursor: "#fafafa", + cursorAccent: tint.surface0, + selectionBackground: "rgba(255, 255, 255, 0.2)", + selectionForeground: "#fafafa", + black: tint.surfaceSidebar, + ...darkTerminalAnsi, + brightBlack: tint.surface3, + }, + }; +} + +// --------------------------------------------------------------------------- +// Dark tint definitions +// --------------------------------------------------------------------------- + +// Paseo — subtle teal-green tint (default) +const paseoDarkColors = buildDarkSemanticColors({ + surface0: "#181B1A", + surface1: "#1E2120", + surface2: "#272A29", + surface3: "#434645", + surface4: "#595B5B", + surfaceDiffEmpty: "#252827", + surfaceSidebar: "#141716", + surfaceSidebarHover: "#1c1f1e", foregroundMuted: "#A1A5A4", - - // Controls - scrollbarHandle: "#717574", // zinc-500 w/ teal tint - - // Borders + scrollbarHandle: "#717574", border: "#252B2A", borderAccent: "#2F3534", - - // Brand accent: "#20744A", accentBright: "#7ccba0", - accentForeground: "#ffffff", +}); - // Semantic - destructive: "#ef4444", - destructiveForeground: "#ffffff", - success: "#20744A", - successForeground: "#ffffff", +// Zinc — neutral gray, no tint +const zincDarkColors = buildDarkSemanticColors({ + surface0: "#18181b", + surface1: "#1f1f22", + surface2: "#27272a", + surface3: "#3f3f46", + surface4: "#52525b", + surfaceDiffEmpty: "#242427", + surfaceSidebar: "#131316", + surfaceSidebarHover: "#1b1b1e", + foregroundMuted: "#a1a1aa", + scrollbarHandle: "#71717a", + border: "#27272a", + borderAccent: "#303036", + accent: "#20744A", + accentBright: "#7ccba0", +}); - // Legacy aliases (for gradual migration) - background: "#181B1A", - popover: "#272A29", - popoverForeground: "#fafafa", - primary: "#fafafa", - primaryForeground: "#181B1A", - secondary: "#272A29", - secondaryForeground: "#fafafa", - muted: "#272A29", - mutedForeground: "#A1A5A4", - accentBorder: "#2F3534", - input: "#272A29", - ring: "#d4d4d8", +// Midnight — subtle blue tint +const midnightDarkColors = buildDarkSemanticColors({ + surface0: "#161820", + surface1: "#1c1e27", + surface2: "#252731", + surface3: "#3c3e4c", + surface4: "#535564", + surfaceDiffEmpty: "#222430", + surfaceSidebar: "#121420", + surfaceSidebarHover: "#1a1c28", + foregroundMuted: "#9a9db0", + scrollbarHandle: "#6b6e82", + border: "#242636", + borderAccent: "#2e3040", + accent: "#3b6fcf", + accentBright: "#7eaaeb", +}); - terminal: { - background: "#181B1A", - foreground: "#fafafa", - cursor: "#fafafa", - cursorAccent: "#181B1A", - selectionBackground: "rgba(255, 255, 255, 0.2)", - selectionForeground: "#fafafa", +// Claude — warm neutral with subtle orange undertone +const claudeDarkColors = buildDarkSemanticColors({ + surface0: "#1f1f1e", + surface1: "#262523", + surface2: "#2f2d2b", + surface3: "#4a4745", + surface4: "#605d5b", + surfaceDiffEmpty: "#2a2826", + surfaceSidebar: "#1a1918", + surfaceSidebarHover: "#222120", + foregroundMuted: "#ada9a5", + scrollbarHandle: "#78746f", + border: "#2c2a27", + borderAccent: "#36332f", + accent: "#d97757", + accentBright: "#e89a7f", +}); - black: "#141716", - red: "#ef4444", - green: "#22c55e", - yellow: "#f59e0b", - blue: "#3b82f6", - magenta: "#a855f7", - cyan: "#06b6d4", - white: "#e4e4e7", - - brightBlack: "#434645", - brightRed: "#f87171", - brightGreen: "#4ade80", - brightYellow: "#fbbf24", - brightBlue: "#60a5fa", - brightMagenta: "#c084fc", - brightCyan: "#22d3ee", - brightWhite: "#ffffff", - }, -} as const; +// Ghostty — blue-tinted dark based on Ghostty default background +const ghosttyDarkColors = buildDarkSemanticColors({ + surface0: "#282c34", + surface1: "#2f333d", + surface2: "#383c48", + surface3: "#4a4f5e", + surface4: "#5b6175", + surfaceDiffEmpty: "#323643", + surfaceSidebar: "#21252d", + surfaceSidebarHover: "#292d36", + foregroundMuted: "#c8ccd8", + scrollbarHandle: "#a0a4b2", + border: "#353a47", + borderAccent: "#3f4454", + accent: "#89b4fa", + accentBright: "#b4d0fc", +}); const commonTheme = { spacing: { @@ -323,35 +440,45 @@ const commonTheme = { }, } as const; -export const darkTheme = { - colorScheme: "dark" as const, - colors: { - ...darkSemanticColors, - palette: baseColors, +const darkShadow = { + sm: { + shadowColor: "rgba(0, 0, 0, 0.25)", + shadowOffset: { width: 0, height: 2 }, + shadowRadius: 4, + elevation: 2, }, - shadow: { - sm: { - shadowColor: "rgba(0, 0, 0, 0.25)", - shadowOffset: { width: 0, height: 2 }, - shadowRadius: 4, - elevation: 2, - }, - md: { - shadowColor: "rgba(0, 0, 0, 0.20)", - shadowOffset: { width: 0, height: 4 }, - shadowRadius: 8, - elevation: 8, - }, - lg: { - shadowColor: "rgba(0, 0, 0, 0.40)", - shadowOffset: { width: 0, height: 12 }, - shadowRadius: 24, - elevation: 8, - }, + md: { + shadowColor: "rgba(0, 0, 0, 0.20)", + shadowOffset: { width: 0, height: 4 }, + shadowRadius: 8, + elevation: 8, + }, + lg: { + shadowColor: "rgba(0, 0, 0, 0.40)", + shadowOffset: { width: 0, height: 12 }, + shadowRadius: 24, + elevation: 8, }, - ...commonTheme, } as const; +function buildDarkTheme(semanticColors: ReturnType) { + return { + colorScheme: "dark" as const, + colors: { + ...semanticColors, + palette: baseColors, + }, + shadow: darkShadow, + ...commonTheme, + } as const; +} + +export const darkTheme = buildDarkTheme(paseoDarkColors); +export const darkZincTheme = buildDarkTheme(zincDarkColors); +export const darkMidnightTheme = buildDarkTheme(midnightDarkColors); +export const darkClaudeTheme = buildDarkTheme(claudeDarkColors); +export const darkGhosttyTheme = buildDarkTheme(ghosttyDarkColors); + export const lightTheme = { colorScheme: "light" as const, colors: { @@ -386,3 +513,23 @@ export const theme = darkTheme; // Export a union type that works for both themes export type Theme = typeof darkTheme | typeof lightTheme; + +type UnistylesThemeKey = "light" | "dark" | "darkZinc" | "darkMidnight" | "darkClaude" | "darkGhostty"; + +export const THEME_TO_UNISTYLES: Record = { + light: "light", + dark: "dark", + zinc: "darkZinc", + midnight: "darkMidnight", + claude: "darkClaude", + ghostty: "darkGhostty", +}; + +export const THEME_SWATCHES: Record = { + light: "#ffffff", + dark: "#2D8B62", + zinc: "#808080", + midnight: "#4A6BA8", + claude: "#D97757", + ghostty: "#8caaee", +}; diff --git a/packages/app/src/styles/unistyles.ts b/packages/app/src/styles/unistyles.ts index 4bcb6e072..3bb09dc8a 100644 --- a/packages/app/src/styles/unistyles.ts +++ b/packages/app/src/styles/unistyles.ts @@ -1,11 +1,21 @@ import { StyleSheet } from "react-native-unistyles"; -// import { UnistylesRuntime } from "react-native-unistyles"; -import { lightTheme, darkTheme } from "./theme"; +import { + lightTheme, + darkTheme, + darkZincTheme, + darkMidnightTheme, + darkClaudeTheme, + darkGhosttyTheme, +} from "./theme"; StyleSheet.configure({ themes: { light: lightTheme, dark: darkTheme, + darkZinc: darkZincTheme, + darkMidnight: darkMidnightTheme, + darkClaude: darkClaudeTheme, + darkGhostty: darkGhosttyTheme, }, breakpoints: { xs: 0, @@ -23,6 +33,10 @@ StyleSheet.configure({ type AppThemes = { light: typeof lightTheme; dark: typeof darkTheme; + darkZinc: typeof darkZincTheme; + darkMidnight: typeof darkMidnightTheme; + darkClaude: typeof darkClaudeTheme; + darkGhostty: typeof darkGhosttyTheme; }; type AppBreakpoints = { @@ -37,5 +51,3 @@ declare module "react-native-unistyles" { export interface UnistylesThemes extends AppThemes {} export interface UnistylesBreakpoints extends AppBreakpoints {} } - -// UnistylesRuntime.setRootViewBackgroundColor(lightTheme.colors.background);