|
|
@@ -1,5 +1,34 @@
|
|
|
import { Plugin } from 'vite';
|
|
|
|
|
|
+/**
|
|
|
+ * Shared color palette used across light and dark themes.
|
|
|
+ * Extracting these reduces duplication and makes theme relationships clearer.
|
|
|
+ */
|
|
|
+const COLORS = {
|
|
|
+ // Primary brand color
|
|
|
+ primary: 'oklch(0.7613 0.1503 231.1314)',
|
|
|
+ // Pure white/black variants
|
|
|
+ white: 'oklch(1.0000 0 0)',
|
|
|
+ nearWhite: 'oklch(0.9851 0 0)',
|
|
|
+ // Gray scale - light theme
|
|
|
+ lightForeground: 'oklch(0.2103 0.0059 285.8852)',
|
|
|
+ lightMuted: 'oklch(0.9674 0.0013 286.3752)',
|
|
|
+ lightMutedForeground: 'oklch(0.5517 0.0138 285.9385)',
|
|
|
+ lightBorder: 'oklch(0.9197 0.0040 286.3202)',
|
|
|
+ // Gray scale - dark theme
|
|
|
+ darkBackground: 'oklch(0.1408 0.0044 285.8229)',
|
|
|
+ darkCard: 'oklch(0.2103 0.0059 285.8852)',
|
|
|
+ darkMuted: 'oklch(0.2739 0.0055 286.0326)',
|
|
|
+ darkMutedForeground: 'oklch(0.7118 0.0129 286.0665)',
|
|
|
+ // Brand colors (shared)
|
|
|
+ brand: '#17c1ff',
|
|
|
+ brandLighter: '#e6f9ff',
|
|
|
+ brandDarker: '#0099ff',
|
|
|
+ // Fonts (shared)
|
|
|
+ fontSans: 'Inter, sans-serif',
|
|
|
+ fontMono: 'Geist Mono, monospace',
|
|
|
+} as const;
|
|
|
+
|
|
|
type ThemeColors = {
|
|
|
background?: string;
|
|
|
foreground?: string;
|
|
|
@@ -53,93 +82,93 @@ export interface ThemeVariables {
|
|
|
|
|
|
const defaultVariables: ThemeVariables = {
|
|
|
light: {
|
|
|
- background: 'oklch(1.0000 0 0)',
|
|
|
- foreground: 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- card: 'oklch(1.0000 0 0)',
|
|
|
- 'card-foreground': 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- popover: 'oklch(1.0000 0 0)',
|
|
|
- 'popover-foreground': 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- primary: 'oklch(0.7613 0.1503 231.1314)',
|
|
|
+ background: COLORS.white,
|
|
|
+ foreground: COLORS.lightForeground,
|
|
|
+ card: COLORS.white,
|
|
|
+ 'card-foreground': COLORS.lightForeground,
|
|
|
+ popover: COLORS.white,
|
|
|
+ 'popover-foreground': COLORS.lightForeground,
|
|
|
+ primary: COLORS.primary,
|
|
|
'primary-foreground': 'oklch(0.261 0.043 218.379)',
|
|
|
- secondary: 'oklch(0.9674 0.0013 286.3752)',
|
|
|
- 'secondary-foreground': 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- muted: 'oklch(0.9674 0.0013 286.3752)',
|
|
|
- 'muted-foreground': 'oklch(0.5517 0.0138 285.9385)',
|
|
|
- accent: 'oklch(0.9674 0.0013 286.3752)',
|
|
|
- 'accent-foreground': 'oklch(0.2103 0.0059 285.8852)',
|
|
|
+ secondary: COLORS.lightMuted,
|
|
|
+ 'secondary-foreground': COLORS.lightForeground,
|
|
|
+ muted: COLORS.lightMuted,
|
|
|
+ 'muted-foreground': COLORS.lightMutedForeground,
|
|
|
+ accent: COLORS.lightMuted,
|
|
|
+ 'accent-foreground': COLORS.lightForeground,
|
|
|
// L=0.60 ensures WCAG AA contrast ratio (4.5:1) against white backgrounds
|
|
|
destructive: 'oklch(0.60 0.24 27.325)',
|
|
|
- 'destructive-foreground': 'oklch(0.9851 0 0)',
|
|
|
+ 'destructive-foreground': COLORS.nearWhite,
|
|
|
success: 'hsl(99deg 67.25% 33.2%)',
|
|
|
'success-foreground': 'hsl(0 0% 98%)',
|
|
|
'dev-mode': 'hsl(204, 76%, 62%)',
|
|
|
'dev-mode-foreground': 'hsl(0 0% 98%)',
|
|
|
- border: 'oklch(0.9197 0.0040 286.3202)',
|
|
|
- input: 'oklch(0.9197 0.0040 286.3202)',
|
|
|
- ring: 'oklch(0.7613 0.1503 231.1314)',
|
|
|
- 'chart-1': 'oklch(0.7613 0.1503 231.1314)',
|
|
|
+ border: COLORS.lightBorder,
|
|
|
+ input: COLORS.lightBorder,
|
|
|
+ ring: COLORS.primary,
|
|
|
+ 'chart-1': COLORS.primary,
|
|
|
'chart-2': 'oklch(0.5575 0.2525 302.3212)',
|
|
|
'chart-3': 'oklch(0.5858 0.2220 17.5846)',
|
|
|
'chart-4': 'oklch(0.6658 0.1574 58.3183)',
|
|
|
'chart-5': 'oklch(0.6271 0.1699 149.2138)',
|
|
|
radius: '0.375rem',
|
|
|
- sidebar: 'oklch(0.9674 0.0013 286.3752)',
|
|
|
- 'sidebar-foreground': 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- 'sidebar-primary': 'oklch(0.7613 0.1503 231.1314)',
|
|
|
- 'sidebar-primary-foreground': 'oklch(0.1408 0.0044 285.8229)',
|
|
|
- 'sidebar-accent': 'oklch(1.0000 0 0)',
|
|
|
- 'sidebar-accent-foreground': 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- 'sidebar-border': 'oklch(0.9197 0.0040 286.3202)',
|
|
|
- 'sidebar-ring': 'oklch(0.7613 0.1503 231.1314)',
|
|
|
- brand: '#17c1ff',
|
|
|
- 'brand-lighter': '#e6f9ff',
|
|
|
- 'brand-darker': '#0099ff',
|
|
|
- 'font-sans': 'Inter, sans-serif',
|
|
|
- 'font-mono': 'Geist Mono, monospace',
|
|
|
+ sidebar: COLORS.lightMuted,
|
|
|
+ 'sidebar-foreground': COLORS.lightForeground,
|
|
|
+ 'sidebar-primary': COLORS.primary,
|
|
|
+ 'sidebar-primary-foreground': COLORS.darkBackground,
|
|
|
+ 'sidebar-accent': COLORS.white,
|
|
|
+ 'sidebar-accent-foreground': COLORS.lightForeground,
|
|
|
+ 'sidebar-border': COLORS.lightBorder,
|
|
|
+ 'sidebar-ring': COLORS.primary,
|
|
|
+ brand: COLORS.brand,
|
|
|
+ 'brand-lighter': COLORS.brandLighter,
|
|
|
+ 'brand-darker': COLORS.brandDarker,
|
|
|
+ 'font-sans': COLORS.fontSans,
|
|
|
+ 'font-mono': COLORS.fontMono,
|
|
|
},
|
|
|
dark: {
|
|
|
- background: 'oklch(0.1408 0.0044 285.8229)',
|
|
|
- foreground: 'oklch(0.9851 0 0)',
|
|
|
- card: 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- 'card-foreground': 'oklch(0.9851 0 0)',
|
|
|
- popover: 'oklch(0.2103 0.0059 285.8852)',
|
|
|
- 'popover-foreground': 'oklch(0.9851 0 0)',
|
|
|
- primary: 'oklch(0.7613 0.1503 231.1314)',
|
|
|
- 'primary-foreground': 'oklch(0.1408 0.0044 285.8229)',
|
|
|
- secondary: 'oklch(0.2739 0.0055 286.0326)',
|
|
|
- 'secondary-foreground': 'oklch(0.9851 0 0)',
|
|
|
- muted: 'oklch(0.2739 0.0055 286.0326)',
|
|
|
- 'muted-foreground': 'oklch(0.7118 0.0129 286.0665)',
|
|
|
- accent: 'oklch(0.2739 0.0055 286.0326)',
|
|
|
- 'accent-foreground': 'oklch(0.9851 0 0)',
|
|
|
+ background: COLORS.darkBackground,
|
|
|
+ foreground: COLORS.nearWhite,
|
|
|
+ card: COLORS.darkCard,
|
|
|
+ 'card-foreground': COLORS.nearWhite,
|
|
|
+ popover: COLORS.darkCard,
|
|
|
+ 'popover-foreground': COLORS.nearWhite,
|
|
|
+ primary: COLORS.primary,
|
|
|
+ 'primary-foreground': COLORS.darkBackground,
|
|
|
+ secondary: COLORS.darkMuted,
|
|
|
+ 'secondary-foreground': COLORS.nearWhite,
|
|
|
+ muted: COLORS.darkMuted,
|
|
|
+ 'muted-foreground': COLORS.darkMutedForeground,
|
|
|
+ accent: COLORS.darkMuted,
|
|
|
+ 'accent-foreground': COLORS.nearWhite,
|
|
|
// L=0.75 ensures WCAG AA contrast ratio (4.5:1) against dark backgrounds
|
|
|
destructive: 'oklch(0.75 0.22 25)',
|
|
|
- 'destructive-foreground': 'oklch(0.9851 0 0)',
|
|
|
+ 'destructive-foreground': COLORS.nearWhite,
|
|
|
success: 'hsl(100 76.42% 22.21%)',
|
|
|
'success-foreground': 'hsl(0 0% 98%)',
|
|
|
'dev-mode': 'hsl(204, 86%, 53%)',
|
|
|
'dev-mode-foreground': 'hsl(0 0% 98%)',
|
|
|
- border: 'oklch(0.2739 0.0055 286.0326)',
|
|
|
- input: 'oklch(0.2739 0.0055 286.0326)',
|
|
|
- ring: 'oklch(0.7613 0.1503 231.1314)',
|
|
|
- 'chart-1': 'oklch(0.7613 0.1503 231.1314)',
|
|
|
+ border: COLORS.darkMuted,
|
|
|
+ input: COLORS.darkMuted,
|
|
|
+ ring: COLORS.primary,
|
|
|
+ 'chart-1': COLORS.primary,
|
|
|
'chart-2': 'oklch(0.6268 0.2325 303.9004)',
|
|
|
'chart-3': 'oklch(0.6450 0.2154 16.4393)',
|
|
|
'chart-4': 'oklch(0.7686 0.1647 70.0804)',
|
|
|
'chart-5': 'oklch(0.7227 0.1920 149.5793)',
|
|
|
sidebar: 'oklch(0.2 0 0)',
|
|
|
- 'sidebar-foreground': 'oklch(0.9851 0 0)',
|
|
|
- 'sidebar-primary': 'oklch(0.7613 0.1503 231.1314)',
|
|
|
- 'sidebar-primary-foreground': 'oklch(0.1408 0.0044 285.8229)',
|
|
|
- 'sidebar-accent': 'oklch(0.2739 0.0055 286.0326)',
|
|
|
- 'sidebar-accent-foreground': 'oklch(0.9851 0 0)',
|
|
|
- 'sidebar-border': 'oklch(0.2739 0.0055 286.0326)',
|
|
|
- 'sidebar-ring': 'oklch(0.7613 0.1503 231.1314)',
|
|
|
- brand: '#17c1ff',
|
|
|
- 'brand-lighter': '#e6f9ff',
|
|
|
- 'brand-darker': '#0099ff',
|
|
|
- 'font-sans': 'Inter, sans-serif',
|
|
|
- 'font-mono': 'Geist Mono, monospace',
|
|
|
+ 'sidebar-foreground': COLORS.nearWhite,
|
|
|
+ 'sidebar-primary': COLORS.primary,
|
|
|
+ 'sidebar-primary-foreground': COLORS.darkBackground,
|
|
|
+ 'sidebar-accent': COLORS.darkMuted,
|
|
|
+ 'sidebar-accent-foreground': COLORS.nearWhite,
|
|
|
+ 'sidebar-border': COLORS.darkMuted,
|
|
|
+ 'sidebar-ring': COLORS.primary,
|
|
|
+ brand: COLORS.brand,
|
|
|
+ 'brand-lighter': COLORS.brandLighter,
|
|
|
+ 'brand-darker': COLORS.brandDarker,
|
|
|
+ 'font-sans': COLORS.fontSans,
|
|
|
+ 'font-mono': COLORS.fontMono,
|
|
|
},
|
|
|
};
|
|
|
|