feat(theme): implement single-file CSS theming engine with dark, light, high-contrast, and soft themes
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
This commit is contained in:
1 parent
0f24cbdbf4
commit
b3e651b3b9
18 files changed
+1455
-804
No files matched your search
@@ -0,0 +1,93 @@
|
||||
export type ThemeId = 'dark' | 'light' | 'high-contrast' | 'soft';
|
||||
|
||||
export interface ThemeOption {
|
||||
id: ThemeId;
|
||||
name: string;
|
||||
subtitle: string;
|
||||
file: string;
|
||||
previewBg: string;
|
||||
previewPanel: string;
|
||||
previewAccent: string;
|
||||
previewText: string;
|
||||
isRounded: boolean;
|
||||
}
|
||||
|
||||
export const THEME_STORAGE_KEY = 'mindsift_active_theme';
|
||||
|
||||
export const AVAILABLE_THEMES: ThemeOption[] = [
|
||||
{
|
||||
id: 'dark',
|
||||
name: 'MindSift Dark (Standard)',
|
||||
subtitle: 'Monochrom, dunkel & eckig (0px)',
|
||||
file: 'src/themes/theme-dark.css',
|
||||
previewBg: '#121316',
|
||||
previewPanel: '#1a1c20',
|
||||
previewAccent: '#2563eb',
|
||||
previewText: '#f4f4f5',
|
||||
isRounded: false,
|
||||
},
|
||||
{
|
||||
id: 'light',
|
||||
name: 'MindSift Light (Tagmodus)',
|
||||
subtitle: 'Helles Papier-Design & klare Kontraste',
|
||||
file: 'src/themes/theme-light.css',
|
||||
previewBg: '#f3f4f6',
|
||||
previewPanel: '#ffffff',
|
||||
previewAccent: '#2563eb',
|
||||
previewText: '#111827',
|
||||
isRounded: false,
|
||||
},
|
||||
{
|
||||
id: 'high-contrast',
|
||||
name: 'High Contrast (Scharf)',
|
||||
subtitle: 'Tiefschwarz (#000) & weiße Konturen',
|
||||
file: 'src/themes/theme-high-contrast.css',
|
||||
previewBg: '#000000',
|
||||
previewPanel: '#09090b',
|
||||
previewAccent: '#38bdf8',
|
||||
previewText: '#ffffff',
|
||||
isRounded: false,
|
||||
},
|
||||
{
|
||||
id: 'soft',
|
||||
name: 'Soft Slate (Abgerundet)',
|
||||
subtitle: 'Schiefer-Blau mit weichen Radien (10px)',
|
||||
file: 'src/themes/theme-soft.css',
|
||||
previewBg: '#0f172a',
|
||||
previewPanel: '#1e293b',
|
||||
previewAccent: '#3b82f6',
|
||||
previewText: '#f8fafc',
|
||||
isRounded: true,
|
||||
},
|
||||
];
|
||||
|
||||
export function getActiveTheme(): ThemeId {
|
||||
try {
|
||||
const saved = localStorage.getItem(THEME_STORAGE_KEY) as ThemeId | null;
|
||||
if (saved && AVAILABLE_THEMES.some((t) => t.id === saved)) {
|
||||
return saved;
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return 'dark';
|
||||
}
|
||||
|
||||
export function setActiveTheme(themeId: ThemeId): void {
|
||||
try {
|
||||
localStorage.setItem(THEME_STORAGE_KEY, themeId);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
if (typeof document !== 'undefined') {
|
||||
document.documentElement.setAttribute('data-theme', themeId);
|
||||
}
|
||||
}
|
||||
|
||||
export function initThemeOnBoot(): ThemeId {
|
||||
const active = getActiveTheme();
|
||||
if (typeof document !== 'undefined') {
|
||||
document.documentElement.setAttribute('data-theme', active);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
Reference in new issue
Block a user