# Design & UX Guidelines
Richtlinien für konsistentes Design und User Experience im ManaCore Monorepo.
## Grundprinzipien
### 1. Inline vor Modal
**Bevorzuge Inline-Interaktionen** statt separater Modals, um Kontext zu bewahren und visuelle Unruhe zu vermeiden.
```
BEVORZUGT: Inline-Expansion
┌─────────────────────────────┐
│ ○ Task Title ▼ │ ← Klick klappt auf
├─────────────────────────────┤
│ [Titel-Input] │
│ [Beschreibung] │
│ [Weitere Felder...] │
│ [Abbrechen] [Speichern] │
└─────────────────────────────┘
VERMEIDEN: Separate Modals für einfache Bearbeitungen
```
**Ausnahmen für Modals:**
- Bestätigungsdialoge (Löschen, kritische Aktionen)
- Komplexe Wizards mit mehreren Schritten
- Vollbild-Medienansichten
- Auth-Gates (Login-Aufforderung)
### 2. Mobile-First
Designs beginnen mit der mobilen Ansicht und werden für größere Screens erweitert.
```css
/* Mobile-First Breakpoints */
@media (min-width: 640px) {
/* sm */
}
@media (min-width: 768px) {
/* md */
}
@media (min-width: 1024px) {
/* lg */
}
@media (min-width: 1280px) {
/* xl */
}
```
### 3. Reduktion vor Addition
- Weniger UI-Elemente = bessere UX
- Leere Sektionen ausblenden statt "Keine Daten" anzeigen
- Progressive Disclosure: Details erst bei Bedarf zeigen
## Layout & Spacing
### Spacing-System
Verwende konsistente Abstände basierend auf 4px-Raster:
| Token | Wert | Verwendung |
| --------- | ---- | --------------------------------- |
| `0.25rem` | 4px | Minimaler Abstand (Icons, Badges) |
| `0.5rem` | 8px | Kompakte Elemente |
| `0.75rem` | 12px | Standard innerhalb Komponenten |
| `1rem` | 16px | Standard zwischen Elementen |
| `1.5rem` | 24px | Sektions-Padding |
| `2rem` | 32px | Große Abstände |
### Container & Max-Width
```css
/* Standard Content Container */
max-width: 640px; /* Formulare, Listen */
max-width: 800px; /* Breitere Inhalte */
max-width: 1200px; /* Dashboard-Layouts */
```
### Border-Radius
| Verwendung | Wert |
| ------------------------------ | ------------------------------ |
| Kleine Elemente (Badges, Tags) | `9999px` (pill) oder `0.25rem` |
| Buttons, Inputs | `0.5rem` - `0.75rem` |
| Cards, Modals | `0.75rem` - `1.5rem` |
| Große Container | `1rem` - `1.5rem` |
## Farben & Theming
### CSS Custom Properties
Alle Farben über CSS-Variablen definieren für Dark Mode Kompatibilität:
```css
/* Richtig */
color: hsl(var(--color-foreground));
background: hsl(var(--color-surface));
border-color: hsl(var(--color-border));
/* Falsch - hardcoded Farben */
color: #374151;
background: white;
```
### Semantische Farben
| Variable | Verwendung |
| -------------------------- | ------------------------------ |
| `--color-primary` | Primäre Aktionen, Links, Fokus |
| `--color-foreground` | Haupttext |
| `--color-muted-foreground` | Sekundärtext, Platzhalter |
| `--color-surface` | Hintergründe |
| `--color-border` | Rahmen, Trennlinien |
| `--color-error` | Lösch-Aktionen, Fehler |
| `--color-success` | Erfolgsmeldungen |
| `--color-warning` | Warnungen |
### ⚠️ Nie bare shadcn-Tokens
Manche Komponenten aus shadcn- oder theme-Vorlagen sprechen bare Token-Namen
an (`--muted`, `--primary`, `--theme-muted`). **Diese existieren im Mana-Theme
nicht** und fallen stumm aus — das Theme-Wechseln wird nicht mehr mitgezogen.
Immer den `--color-*`-Präfix nutzen:
```css
/* Falsch */
background: hsl(var(--muted));
color: var(--foreground, #111);
border: 1px solid var(--theme-border);
/* Richtig */
background: hsl(var(--color-muted));
color: hsl(var(--color-foreground));
border: 1px solid hsl(var(--color-border));
```
Der Audit `pnpm audit:theme-tokens` (läuft auch in `lint-staged`) schlägt
jeden Drift an.
### Dark Mode
Immer beide Modi berücksichtigen:
```css
.element {
background: rgba(255, 255, 255, 0.85);
border: 1px solid rgba(0, 0, 0, 0.08);
}
:global(.dark) .element {
background: rgba(255, 255, 255, 0.12);
border: 1px solid rgba(255, 255, 255, 0.15);
}
```
## Animationen & Transitions
### Standard-Timings
| Typ | Dauer | Easing |
| ------------------------- | --------------- | ------------- |
| Micro-Interaktionen | `150ms` | `ease` |
| UI-Feedback | `200ms` | `ease-out` |
| Layout-Änderungen | `200ms - 300ms` | `ease-out` |
| Aufmerksamkeits-Animation | `2s - 3s` | `ease-in-out` |
### Transition-Beispiele
```css
/* Hover-Effekte */
transition: all 0.15s ease;
/* Expand/Collapse */
transition: all 0.2s ease-out;
/* Subtile Aufmerksamkeit (z.B. Float-Animation) */
animation: float 3s ease-in-out infinite;
@keyframes float {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-8px);
}
}
```
### Wann animieren
**Ja:**
- Zustandsänderungen (expand, collapse, toggle)
- Feedback bei Aktionen (Checkbox, Button-Press)
- Aufmerksamkeit lenken (leere Zustände)
- Smooth Scrolling
**Nein:**
- Initiales Laden von Inhalten
- Jeder einzelne Listen-Eintrag
- Performance-kritische Bereiche
- Wenn `prefers-reduced-motion` aktiv
```css
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
```
## Komponenten-Patterns
### Buttons
```
Hierarchie:
1. Primary → Hauptaktion (1x pro Ansicht)
2. Secondary → Alternative Aktionen
3. Ghost → Tertiäre Aktionen, Links
4. Danger → Destruktive Aktionen
```
```css
/* Primary */
background: hsl(var(--color-primary));
color: hsl(var(--color-primary-foreground));
/* Secondary */
background: rgba(0, 0, 0, 0.05);
color: hsl(var(--color-foreground));
/* Danger */
background: rgba(239, 68, 68, 0.1);
color: #ef4444;
```
### Inputs & Forms
- Labels immer über dem Input
- Placeholder für Hinweise, nicht als Label-Ersatz
- Fokus-Ring mit Primary-Farbe
- Fehler-States mit rotem Border + Fehlermeldung
```css
.input:focus {
outline: none;
border-color: hsl(var(--color-primary));
box-shadow: 0 0 0 2px hsl(var(--color-primary) / 0.1);
}
```
### Cards & Listen-Elemente
Glassmorphism-Stil für erhöhte Elemente:
```css
.card {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(0, 0, 0, 0.08);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
border-radius: 0.75rem;
}
```
### Empty States
Leere Zustände sollten:
1. Visuell ansprechend sein (Icon, Illustration)
2. Erklären was hier normalerweise ist
3. Eine klare Handlungsaufforderung bieten
```
┌─────────────────────────────┐
│ │
│ [Animiertes Icon] │
│ │
│ Motivierender Titel │
│ Kurze Beschreibung │
│ │
│ [Primäre Aktion] │
│ │
└─────────────────────────────┘
```
### Loading States
- Skeleton-Loader für bekannte Layouts
- Spinner für unbekannte Ladezeiten
- Inline-Spinner in Buttons während Aktionen
```svelte
{#if isLoading}