diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx index c5fe497..bb4bcf9 100644 --- a/frontend/src/pages/Settings.tsx +++ b/frontend/src/pages/Settings.tsx @@ -218,29 +218,24 @@ const Settings: React.FC = ({ themeName, onThemeChange }) => { label={t('settings.themeLabel')} onChange={(e) => onThemeChange(e.target.value as CatppuccinTheme)} > - Holy Energy - Holy Light (Default) - Holy Dark + Holy Archive + Holy Light (Clean) + Holy Dark (Premium) Light Themes - Latte - Pastel Pink - Solarized Light - One Light - Paper White + Catppuccin Latte + Pink Pastel Dark Themes - Mocha - Frappé - Macchiato - Atom One Dark + Catppuccin Mocha + Catppuccin Frappé + Catppuccin Macchiato Dracula - Gruvbox Dark - Nord - Cyberpunk - Forest Dark + Nordic Frost + Gruvbox Retro + Oceanic Deep diff --git a/frontend/src/theme.ts b/frontend/src/theme.ts index 7908ab9..7842f98 100644 --- a/frontend/src/theme.ts +++ b/frontend/src/theme.ts @@ -3,85 +3,49 @@ import { flavors } from '@catppuccin/palette'; export type CatppuccinTheme = | 'holy_light' | 'holy_dark' - | 'latte' | 'pink' | 'solarized_light' | 'one_light' | 'paper' - | 'frappe' | 'macchiato' | 'mocha' | 'atom' | 'dracula' | 'gruvbox' | 'nord' | 'cyberpunk' | 'forest'; + | 'latte' | 'frappe' | 'macchiato' | 'mocha' + | 'pink_pastel' | 'dracula' | 'nord' | 'gruvbox' | 'oceanic'; export const isLightTheme = (mode: CatppuccinTheme): boolean => { - return ['holy_light', 'latte', 'pink', 'solarized_light', 'one_light', 'paper'].includes(mode); + return ['holy_light', 'latte', 'pink_pastel'].includes(mode); }; export const getTheme = (mode: CatppuccinTheme) => { let palette: any; + // Define Holy branding colors + const holyPurple = { light: '#7c3aed', dark: '#a78bfa' }; + const holyPink = { light: '#db2777', dark: '#f472b6' }; + if (mode === 'holy_light') { palette = { - base: { hex: '#f0f2f5' }, // Softer off-white/gray - surface0: { hex: '#ffffff' }, // Pure white for cards/surfaces - crust: { hex: '#e4e6eb' }, // Darker divider/header color - text: { hex: '#1c1e21' }, - subtext0: { hex: '#65676b' }, - mauve: { hex: '#6a1b9a' }, // Softer Holy Purple - pink: { hex: '#d81b60' }, // Softer, more professional Pink/Magenta + base: { hex: '#f8fafc' }, + surface0: { hex: '#ffffff' }, + crust: { hex: '#f1f5f9' }, + text: { hex: '#0f172a' }, + subtext0: { hex: '#64748b' }, + primary: { hex: holyPurple.light }, + secondary: { hex: holyPink.light }, }; } else if (mode === 'holy_dark') { palette = { - base: { hex: '#0f0f0f' }, - surface0: { hex: '#1a1a1a' }, + base: { hex: '#020617' }, + surface0: { hex: '#0f172a' }, crust: { hex: '#000000' }, - text: { hex: '#ffffff' }, - subtext0: { hex: '#a0a0a0' }, - mauve: { hex: '#9d4edd' }, // Brighter Purple for Dark - pink: { hex: '#ff4dff' }, // Brighter Pink for Dark + text: { hex: '#f8fafc' }, + subtext0: { hex: '#94a3b8' }, + primary: { hex: holyPurple.dark }, + secondary: { hex: holyPink.dark }, }; - } else if (mode === 'pink') { + } else if (mode === 'pink_pastel') { palette = { - base: { hex: '#fdf6f7' }, - surface0: { hex: '#f8e1e5' }, - crust: { hex: '#f2ccd5' }, - text: { hex: '#4a3135' }, - subtext0: { hex: '#7d5c62' }, - mauve: { hex: '#e05a8d' }, - pink: { hex: '#4ecdc4' }, - }; - } else if (mode === 'solarized_light') { - palette = { - base: { hex: '#fdf6e3' }, - surface0: { hex: '#eee8d5' }, - crust: { hex: '#e3dbbc' }, - text: { hex: '#586e75' }, - subtext0: { hex: '#839496' }, - mauve: { hex: '#6c71c4' }, - pink: { hex: '#d33682' }, - }; - } else if (mode === 'one_light') { - palette = { - base: { hex: '#fafafa' }, - surface0: { hex: '#f0f0f0' }, - crust: { hex: '#e5e5e6' }, - text: { hex: '#383a42' }, - subtext0: { hex: '#a0a1a7' }, - mauve: { hex: '#a626a4' }, - pink: { hex: '#e45649' }, - }; - } else if (mode === 'paper') { - palette = { - base: { hex: '#ffffff' }, - surface0: { hex: '#f5f5f5' }, - crust: { hex: '#eeeeee' }, - text: { hex: '#222222' }, - subtext0: { hex: '#666666' }, - mauve: { hex: '#007aff' }, - pink: { hex: '#ff2d55' }, - }; - } else if (mode === 'atom') { - palette = { - base: { hex: '#282c34' }, - surface0: { hex: '#353b45' }, - crust: { hex: '#21252b' }, - text: { hex: '#abb2bf' }, - subtext0: { hex: '#5c6370' }, - mauve: { hex: '#c678dd' }, - pink: { hex: '#e06c75' }, + base: { hex: '#fff1f2' }, + surface0: { hex: '#ffffff' }, + crust: { hex: '#ffe4e6' }, + text: { hex: '#881337' }, + subtext0: { hex: '#be123c' }, + primary: { hex: '#fb7185' }, + secondary: { hex: '#2dd4bf' }, }; } else if (mode === 'dracula') { palette = { @@ -90,18 +54,8 @@ export const getTheme = (mode: CatppuccinTheme) => { crust: { hex: '#191a21' }, text: { hex: '#f8f8f2' }, subtext0: { hex: '#6272a4' }, - mauve: { hex: '#bd93f9' }, - pink: { hex: '#ff79c6' }, - }; - } else if (mode === 'gruvbox') { - palette = { - base: { hex: '#282828' }, - surface0: { hex: '#3c3836' }, - crust: { hex: '#1d2021' }, - text: { hex: '#ebdbb2' }, - subtext0: { hex: '#928374' }, - mauve: { hex: '#d3869b' }, - pink: { hex: '#fb4934' }, + primary: { hex: '#bd93f9' }, + secondary: { hex: '#ff79c6' }, }; } else if (mode === 'nord') { palette = { @@ -110,55 +64,69 @@ export const getTheme = (mode: CatppuccinTheme) => { crust: { hex: '#242933' }, text: { hex: '#eceff4' }, subtext0: { hex: '#d8dee9' }, - mauve: { hex: '#b48ead' }, - pink: { hex: '#88c0d0' }, + primary: { hex: '#88c0d0' }, + secondary: { hex: '#b48ead' }, }; - } else if (mode === 'cyberpunk') { + } else if (mode === 'gruvbox') { palette = { - base: { hex: '#1a1a2e' }, - surface0: { hex: '#16213e' }, - crust: { hex: '#0f3460' }, - text: { hex: '#e94560' }, - subtext0: { hex: '#0f3460' }, - mauve: { hex: '#e94560' }, - pink: { hex: '#00d2ff' }, + base: { hex: '#282828' }, + surface0: { hex: '#3c3836' }, + crust: { hex: '#1d2021' }, + text: { hex: '#ebdbb2' }, + subtext0: { hex: '#928374' }, + primary: { hex: '#fabd2f' }, + secondary: { hex: '#fb4934' }, }; - } else if (mode === 'forest') { + } else if (mode === 'oceanic') { palette = { base: { hex: '#1b262c' }, - surface0: { hex: '#213e3b' }, + surface0: { hex: '#0f4c75' }, crust: { hex: '#0f161c' }, - text: { hex: '#e8e8e8' }, - subtext0: { hex: '#aebb83' }, - mauve: { hex: '#4e8d7c' }, - pink: { hex: '#aebb83' }, + text: { hex: '#bbe1fa' }, + subtext0: { hex: '#3282b8' }, + primary: { hex: '#3282b8' }, + secondary: { hex: '#bbe1fa' }, }; } else { + // Handle Catppuccin flavors const flavor = (flavors as any)[mode]; if (flavor) { - palette = flavor.colors; - } else { + const colors = flavor.colors; palette = { - base: { hex: '#f0f2f5' }, + base: colors.base, + surface0: colors.surface0, + crust: colors.crust, + text: colors.text, + subtext0: colors.subtext0, + primary: colors.mauve, + secondary: colors.pink, + }; + } else { + // Fallback to holy_light + palette = { + base: { hex: '#f8fafc' }, surface0: { hex: '#ffffff' }, - crust: { hex: '#e4e6eb' }, - text: { hex: '#1c1e21' }, - subtext0: { hex: '#65676b' }, - mauve: { hex: '#6a1b9a' }, - pink: { hex: '#d81b60' }, + crust: { hex: '#f1f5f9' }, + text: { hex: '#0f172a' }, + subtext0: { hex: '#64748b' }, + primary: { hex: holyPurple.light }, + secondary: { hex: holyPink.light }, }; mode = 'holy_light'; } } + const isLight = isLightTheme(mode); + const themeOptions: ThemeOptions = { palette: { - mode: isLightTheme(mode) ? 'light' : 'dark', + mode: isLight ? 'light' : 'dark', primary: { - main: palette.mauve.hex, + main: palette.primary.hex, + contrastText: isLight ? '#ffffff' : '#000000', }, secondary: { - main: palette.pink.hex, + main: palette.secondary.hex, }, background: { default: palette.base.hex, @@ -168,41 +136,100 @@ export const getTheme = (mode: CatppuccinTheme) => { primary: palette.text.hex, secondary: palette.subtext0.hex, }, + divider: alpha(palette.text.hex, 0.1), + action: { + hover: alpha(palette.primary.hex, 0.08), + selected: alpha(palette.primary.hex, 0.12), + } + }, + shape: { + borderRadius: 12, }, typography: { - fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', + fontFamily: '"Plus Jakarta Sans", "Inter", "Roboto", sans-serif', + h1: { fontWeight: 800 }, + h2: { fontWeight: 800 }, + h3: { fontWeight: 700 }, + h4: { fontWeight: 700 }, + h5: { fontWeight: 600 }, + h6: { fontWeight: 600 }, + button: { textTransform: 'none', fontWeight: 600 }, }, components: { + MuiCssBaseline: { + styleOverrides: { + body: { + scrollbarColor: `${alpha(palette.text.hex, 0.2)} transparent`, + '&::-webkit-scrollbar': { width: '8px', height: '8px' }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: alpha(palette.text.hex, 0.2), + borderRadius: '10px', + '&:hover': { backgroundColor: alpha(palette.text.hex, 0.3) } + }, + } + } + }, MuiPaper: { styleOverrides: { root: { - backgroundColor: alpha(palette.surface0.hex, 0.7), - backdropFilter: 'blur(12px)', + backgroundColor: isLight ? palette.surface0.hex : alpha(palette.surface0.hex, 0.8), + backgroundImage: 'none', + backdropFilter: isLight ? 'none' : 'blur(16px)', border: '1px solid', - borderColor: alpha(palette.text.hex, 0.1), - boxShadow: '0 4px 30px rgba(0, 0, 0, 0.1)', + borderColor: alpha(palette.text.hex, 0.08), + boxShadow: isLight + ? '0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)' + : '0 4px 20px rgba(0,0,0,0.2)', } } }, MuiCard: { + defaultProps: { + elevation: 0, + }, styleOverrides: { root: { - backgroundColor: alpha(palette.surface0.hex, 0.6), - backdropFilter: 'blur(10px)', + backgroundColor: isLight ? palette.surface0.hex : alpha(palette.surface0.hex, 0.6), + backdropFilter: 'blur(12px)', border: '1px solid', borderColor: alpha(palette.text.hex, 0.1), - borderRadius: '16px', + borderRadius: '20px', + transition: 'all 0.2s ease-in-out', } } }, MuiAppBar: { styleOverrides: { root: { - backgroundColor: alpha(palette.crust.hex, 0.8), - backdropFilter: 'blur(16px)', + backgroundColor: alpha(palette.base.hex, 0.8), + backdropFilter: 'blur(20px)', + borderBottom: '1px solid', + borderColor: alpha(palette.text.hex, 0.08), color: palette.text.hex, } } + }, + MuiButton: { + styleOverrides: { + root: { + borderRadius: '10px', + padding: '8px 20px', + }, + containedPrimary: { + boxShadow: `0 4px 14px 0 ${alpha(palette.primary.hex, 0.39)}`, + '&:hover': { + boxShadow: `0 6px 20px rgba(0,0,0,0.23)`, + } + } + } + }, + MuiTab: { + styleOverrides: { + root: { + minHeight: '48px', + fontWeight: 700, + } + } } } };