# Central Theming System
Das zentrale Theming-System ermöglicht einheitliches Aussehen und Benutzereinstellungen über alle Manacore-Apps hinweg. Es besteht aus mehreren Schichten: Theme-Varianten, Light/Dark-Modus, Accessibility-Einstellungen und Custom Themes.
## Architektur
```
┌─────────────────────────────────────────────────────────────┐
│ mana-core-auth │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ user_settings (JSON-Feld) │ │
│ │ - theme: { mode, colorScheme, pinnedThemes } │ │
│ │ - nav: { desktopPosition, sidebarCollapsed } │ │
│ │ - locale: "de" │ │
│ │ - general: { startPages, sounds, etc. } │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ custom_themes Tabelle (Community Themes) │ │
│ │ - lightColors, darkColors, author, downloads, etc. │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
┌────▼────┐ ┌─────▼────┐ ┌─────▼────┐
│ Todo │ │ Calendar │ │ Contacts │
│ │ │ │ │ │
│ shared- │ │ shared- │ │ shared- │
│ theme │ │ theme │ │ theme │
└─────────┘ └──────────┘ └──────────┘
```
## Packages
| Package | Beschreibung |
|---------|--------------|
| `@manacore/shared-theme` | Theme Store, Types, Utilities, Konstanten |
| `@manacore/shared-theme-ui` | Svelte UI-Komponenten (ThemeSelector, ThemePage, etc.) |
## Theme-Varianten
Es gibt 8 vordefinierte Theme-Varianten:
### Standard-Varianten (PillNav)
| Name | Farbe | Icon | Hue |
|------|-------|------|-----|
| `lume` | Gold ✨ | sparkle | 47 |
| `nature` | Grün 🌿 | leaf | 122 |
| `stone` | Blau-Grau 🪨 | hexagon | 200 |
| `ocean` | Blau 🌊 | waves | 199 |
### Erweiterte Varianten (Themes-Seite)
| Name | Farbe | Icon | Hue |
|------|-------|------|-----|
| `sunset` | Coral/Orange 🌅 | sun | 15 |
| `midnight` | Violett 🌙 | moon | 260 |
| `rose` | Pink 🌹 | flower | 340 |
| `lavender` | Lavendel 💜 | sparkle | 270 |
## Theme-Modus
```typescript
type ThemeMode = 'light' | 'dark' | 'system';
```
- **light**: Heller Modus
- **dark**: Dunkler Modus
- **system**: Folgt der System-Einstellung
## Color Tokens
Jede Theme-Variante definiert diese HSL-Farbwerte für Light und Dark:
```typescript
interface ThemeColors {
primary: string; // Hauptfarbe
primaryForeground: string; // Text auf Primary
secondary: string; // Sekundärfarbe
secondaryForeground: string;
background: string; // Seitenhintergrund
foreground: string; // Haupttext
surface: string; // Karten-Hintergrund
surfaceHover: string; // Hover-Zustand
surfaceElevated: string; // Modals, Dropdowns
muted: string; // Deaktivierte Elemente
mutedForeground: string;
border: string; // Rahmen
borderStrong: string; // Starke Rahmen
error: string; // Fehler-Rot
success: string; // Erfolg-Grün
warning: string; // Warnung-Orange
input: string; // Input-Hintergrund
ring: string; // Focus-Ring
}
```
### HSL-Format
Farben werden als HSL-Strings ohne `hsl()` Wrapper gespeichert:
```typescript
// Format: "H S% L%"
const gold = '47 95% 58%';
const darkBlue = '199 100% 18%';
// CSS-Verwendung
--color-primary: 47 95% 58%;
background-color: hsl(var(--color-primary));
```
## Store-Nutzung
### Theme Store
```typescript
import { createThemeStore } from '@manacore/shared-theme';
// Store erstellen
export const theme = createThemeStore({
appId: 'calendar',
defaultMode: 'system',
defaultVariant: 'ocean',
});
// In Komponente initialisieren
onMount(() => {
const cleanup = theme.initialize();
return cleanup;
});
// Zugriff auf State
theme.mode // 'light' | 'dark' | 'system'
theme.variant // 'ocean' | 'nature' | ...
theme.effectiveMode // 'light' | 'dark' (aufgelöst)
theme.isDark // boolean
// Aktionen
theme.setMode('dark');
theme.setVariant('nature');
theme.toggleMode(); // Light ↔ Dark
theme.cycleMode(); // Light → Dark → System → Light
```
### App-spezifische Primary Color
```typescript
export const theme = createThemeStore({
appId: 'memoro',
primaryColor: {
light: '47 95% 58%', // Gold
dark: '47 95% 58%',
},
});
```
### User Settings Store (Server-Sync)
```typescript
import { createUserSettingsStore } from '@manacore/shared-theme';
export const userSettings = createUserSettingsStore({
appId: 'calendar',
authUrl: 'http://localhost:3001',
getAccessToken: () => authStore.getAccessToken(),
});
// Laden
await userSettings.load();
// Zugriff
userSettings.theme.mode // Theme-Modus
userSettings.theme.colorScheme // Variante
userSettings.nav.desktopPosition // 'top' | 'bottom'
userSettings.locale // 'de'
userSettings.general.soundsEnabled
// Aktualisieren (speichert auf Server)
await userSettings.updateGlobal({
theme: { mode: 'dark' }
});
// App-spezifische Überschreibung
await userSettings.updateAppOverride({
theme: { colorScheme: 'nature' }
});
```
## Accessibility (A11y)
### A11y Store
```typescript
import { createA11yStore } from '@manacore/shared-theme';
export const a11y = createA11yStore({ appId: 'calendar' });
// State
a11y.contrast // 'normal' | 'high'
a11y.colorblind // 'none' | 'deuteranopia' | 'protanopia' | 'monochrome'
a11y.reduceMotion // boolean
// Aktionen
a11y.setContrast('high');
a11y.setColorblind('deuteranopia');
a11y.setReduceMotion(true);
a11y.resetAll();
```
### A11y-Optionen
**Kontrast:**
- `normal`: Standard (WCAG AA 4.5:1)
- `high`: Erhöhter Kontrast (WCAG AAA 7:1)
**Farbenblindheit:**
- `none`: Keine Anpassung
- `deuteranopia`: Grün-Blindheit (~6% der Männer)
- `protanopia`: Rot-Blindheit (~1% der Männer)
- `monochrome`: Graustufen
**Reduzierte Bewegung:**
- Respektiert `prefers-reduced-motion`
- Kann manuell überschrieben werden
## Custom Themes
### Custom Themes Store
```typescript
import { createCustomThemesStore } from '@manacore/shared-theme';
export const customThemes = createCustomThemesStore({
authUrl: 'http://localhost:3001',
getAccessToken: () => authStore.getAccessToken(),
});
// Eigene Themes laden
await customThemes.loadCustomThemes();
// Theme erstellen
const newTheme = await customThemes.createTheme({
name: 'Mein Theme',
emoji: '🎨',
lightColors: { primary: '200 80% 50%', ... },
darkColors: { primary: '200 70% 60%', ... },
});
// Community Themes durchsuchen
await customThemes.browseCommunity({
sort: 'popular',
search: 'dark',
});
// Theme herunterladen
await customThemes.downloadTheme(themeId);
// Theme anwenden
customThemes.applyCustomTheme(theme);
```
### Theme Editor
Der Theme Editor erlaubt das visuelle Erstellen von Themes:
**Hauptfarben (immer sichtbar):**
- Primary, Background, Surface, Foreground
- Error, Success, Warning
**Erweiterte Farben (zugeklappt):**
- PrimaryForeground, Secondary, SecondaryForeground
- SurfaceHover, SurfaceElevated, Muted, MutedForeground
- Border, BorderStrong, Input, Ring
## UI-Komponenten
### ThemePage
Vollständige Themes-Seite mit allen Optionen:
```svelte