# REKORD - Design-Sprache Normative Design-Doku für REKORD (Trainings-Tracker). Sie beschreibt die Design-Entscheidungen so präzise, dass sie auch in anderen Projekten wiederverwendbar sind. Wo ein Punkt geklärt wird, gilt er verbindlich - mit der einen Ausnahme: **Nutzbarkeit schlägt Stil.** Eine Regel, die die Software unbrauchbar macht, darf gebrochen werden - dann aber bewusst und begründet. --- ## 1. Philosophie REKORD ist ein Werkzeug für den täglichen Gebrauch, kein Schaufenster. Daraus folgt: - **Erst Funktion, dann Form.** Die App reibt sich nicht zwischen dich und die Übung. Kompaktheit und Bedienbarkeit gehen jedem ästhetischen Detail voraus. - **Ehrliche Fläche.** Alles ist flach, kantig, offen. Kein Schein, keine Tiefe, kein Verlauf. Eine Kante ist eine Kante (2px), ein Zustand ist ein Zustand (klar unterscheidbar). - **Konfiguration statt Auftrag.** Der Nicht-Programmierer pflegt `config.json`; das Design muss das widerspiegeln: ruhig, vorhersehbar, nicht überraschend. - **Daten bleiben Daten.** Zahlen sind Daten und werden in einer Daten-Schrift gesetzt; Einheiten sind immer sichtbar (kg, km, min - nie nackte Zahlen). - **Weniger ist mehr.** Ein Akzent. Eine Karte. Eine Idee pro Bildschirm. ## 2. Leitprinzipien 1. **0px Radius.** Keine abgerundeten Ecken. Kanten sind hart. 2. **2px-Border.** Trennungen und Rahmen sind durchgängig 2px, nie schlanker. 3. **Dunkler Grund.** Dunkle Themes sind der Default. Schwarz bleibt Schwarz (OLED), Hell ist eine Option, nie der Standard. 4. **Ein Akzent.** Eine Akzentfarbe pro Sitzung, flach eingesetzt für aktive/ gewählte Zustände. Kein zweiter Akzent, kein Farbverlauf. 5. **Zustände denken.** Hover, Fokus, Aktiv, Deaktiviert, "Erledigt" - jeder Zustand ist visuell eindeutig. 6. **Zwei Schriften, zwei Aufgaben.** Sans für UI und Fließtext, Mono für Zahlen und Daten. Kein unreflektierter System-Stack als einzige Schrift. 7. **Bewegung nur, wenn sie dient.** Und dann `prefers-reduced-motion` respektieren. ## 3. Tokens Die Tokens leben als CSS-Variablen in `:root` und werden über `data-theme` / `data-accent` auf `` gewechselt. Komponenten nutzen **nur** Tokens - keine hartkodierten Farben. ### 3.1 Farbe (Dunkel, Default) | Token | Wert | Verwendung | |---|---|---| | `--bg` | `#0e0e0e` | Seitenhintergrund | | `--bg-panel` | `#161616` | Karten, Panels, Modals | | `--bg-input` | `#0a0a0a` | Eingabefelder | | `--bg-hover` | `#202020` | Hover-Hintergrund | | `--bg-subtle` | `#1d1d1d` | Zebra, Header, Done-Zeilen | | `--border` | `#333` | Standardrahmen | | `--border-hover` | `#4d4d4d` | Rahmen im Hover | | `--text` | `#e8e8e8` | Primärtext | | `--muted` | `#a0a0a0` | Sekundärtext (Kontrast >= 7:1 auf Panel) | | `--danger` | `#c0392b` | destruktive Aktionen | | `--ok` | `#6fae5c` | Erfolg | ### 3.2 Akzent-Palette Zehn flache Akzentfarben, alle mit **einer einheitlichen dunklen Tinte** (`--accent-ink: #141414`, Kontrast >= 4,2:1 überall - mathematisch geprüft). Jede Farbe hat `--accent-hover` (heller) und `--accent-active` (dunkler). | Akzent | Wert | Hover | Active | |---|---|---|---| | amber | `#e0a33c` | `#e9b257` | `#cf9130` | | orange | `#e4582e` | `#ed6a36` | `#ca4a22` | | red | `#d64541` | `#e1514c` | `#be3a37` | | green | `#3fae5a` | `#4ebc68` | `#36984b` | | teal | `#2aa198` | `#39afa5` | `#258d84` | | cyan | `#25b8cc` | `#39c5d8` | `#219fb2` | | blue | `#4a86c8` | `#5a96d6` | `#4073b0` | | violet | `#9a6fd0` | `#ab80e0` | `#875db7` | | pink | `#e0567f` | `#eb6890` | `#c74b6e` | | **white** | `#ffffff` | `#f2f2f2` | `#e6e6e6` | Sonderfall weißer Akzent: auf hellem Theme braucht er eine sichtbare Umrandung (`--accent-border: #9a9a9a`), sonst verschwinden Buttons weiß-auf-weiß. Gleiches gilt für Fortschrittssegmente (auf hellem Theme schwarz statt unsichtbar-weiß). ### 3.3 Themes | Theme | `--bg` | `--bg-panel` | `--bg-input` | `--border` | `--text` | `--muted` | |---|---|---|---|---|---|---| | dark | `#0e0e0e` | `#161616` | `#0a0a0a` | `#333` | `#e8e8e8` | `#a0a0a0` | | light | `#f2f2f0` | `#ffffff` | `#ffffff` | `#c6c6c2` | `#1c1c1c` | `#5c5c59` | | oled | `#000000` | `#050505` | `#000000` | `#232323` | `#e8e8e8` | `#a0a0a0` | - `system` folgt `prefers-color-scheme` (mit Live-Watch über Media Query). - `oled` ist eine **Eigenschaft** des dunklen Modus (Schalter), kein eigenes Theme: Wenn `oled` aktiv und die Auflösung dunkel, gelten reines-Schwarz- Tokens. - `color-scheme` wird pro Theme gesetzt (native Formulare folgen). ### 3.4 Typografie - `--font-ui`: System-Sans für UI, Labels, Fließtext. - `--font-data`: Mono (tabular-nums) für Zahlen, Gewichte, Zeiten, Datums-, Statistik- und Eingabefelder. - Hierarchie über **Gewicht und Abstand**, nicht über Größen-Vielfalt: h1 > h2 > h3, bei begrenzter Größenspreizung. Kein "alles gleich". - Kein webfont-Download nötig - offline-fähig. ### 3.5 Form, Abstand, Bewegung - Radius: **0**. - Border: **2px** (Buttons, Karten, Inputs, Tabs, Segmente). - Abstand: konsistente Raster (8/10/12/14/16/20px), Modals großzügig (Padding >= 32px, min-height fuer konstante Groesse). - Schatten: **keine**. Trennung über Kanten und Abstand. - Motion: höchstens kurzzeitige Transitions (Farbwechsel); nichts Animiertes ohne `prefers-reduced-motion`-Schutz. ## 4. Komponenten & Regeln ### 4.1 Buttons - **Primary** (`.btn-primary`): Akzent-Hintergrund + `--accent-ink`-Tinte. Hover = `--accent-hover`, Active = `--accent-active` (Border bleibt `--accent-border`). Nur für die eine Hauptaktion. - **Secondary** (`.btn`): transparent, 2px-Border, `--text`. Für Nebenaktionen. - **Danger** (`.btn-danger-ghost`): rote Border/Tinte. Destruktiv. - **`min-width`** (96px / 64px bei `.btn-small`): Buttons springen nicht in der Breite, wenn die Sprache wechselt. - **Disabled**: Opacity 0.45 + `not-allowed`. - Icons statt Text bei platzsparenden Aktionen (Reset = SVG-Pfeilkreislauf, Loeschen = ×). Keine Emojis als Icons. ### 4.2 Eingabefelder (Field-Box) Eine zusammengehoerige Box: **Zahl links, Einheit rechts als festes Suffix in derselben Box** (z.B. `[18,5 | kg]`). Klick auf die ganze Box fokussiert den Input. Einheiten sind nie nackt. `:focus-within` faerbt die Border im Akzent. Leer bleibt leer - nie 0. ### 4.3 Set-Zeile Kompakte 5-Spalten-Grid: `auto auto auto auto auto` (Check | kg | reps | Reset-Icon | X-Icon). Check = "Set n [ ]", ganzer Button klickbar, Kette ohne Luecken. Die Zeile muss auf ein normales Handy-Display passen - ohne horizontales Scrollen. ### 4.4 Karten & Panels 2px-Border, `--bg-panel`, Radius 0. Keine Schatten, keine `rounded-2xl`-Karten. Karten durch Trennlinien/Kanten strukturieren statt durch Abstaende allein. ### 4.5 Tabellen 2px-Border auf allen Zellen, Header auf `--bg-subtle`, Zahlen rechtsbündig in Mono. Balken (Statistik) als flache Akzent-Rechtecke. ### 4.6 Modals / Setup-Wizard - Feste Mindesthoehe (konstante Groesse zwischen Schritten), Navigation unten verankert, Inhalt intern scrollbar. - Fortschritt = **segmentierter Balken** oben rechts (Striche mit gap). Erledigt = gefuellt, aktuell = nur Umrandung, kommend = ausgegraut. - Explizite Navigation (Zurueck / Weiter / Abschliessen), Auswahl springt nie automatisch weiter. ### 4.7 Toasts Fixiert unten, 2px-Border. Fehler = `--danger`, Erfolg = `--ok`, und **Einstellungs-Bestaetigungen in der Akzentfarbe** (nicht fix gruen). ## 5. Zustände | Zustand | Regel | |---|---| | hover | `--bg-hover` / `--border-hover`; bei Akzent-Buttons `--accent-hover` | | focus | `:focus-visible` 2px Akzent-Outline (nie `outline: none` ohne Ersatz) | | active/pressed | `--accent-active` bei Primary, `--bg-hover` bei Secondary | | disabled | Opacity 0.45, `cursor: not-allowed` | | done/selected | Akzent-Hintergrund + `--accent-ink` (Check, aktiver Tab, Toggle) | | error | `--danger` (Border + Text), nie nur Farb-Luecke | ## 6. i18n & Sprache - Alle UI-Texte über `t(key)` aus einem `LANG`-Dictionary (de/en). Keine hartkodierten Strings in Views. - Buttons bekommen `min-width`, damit Sprachwechsel die Groesse nicht aendern. - Server-Fehlermeldungen werden ueber `eMsg()` lokalisiert. - Der Login-Screen erscheint in der Server-Standardsprache (aus `/api/meta`). ## 7. Accessibility & Responsive - Tastatur: alles bedienbar, sichtbarer Fokus. - Kontrast: `--muted` auf Panel >= 7:1; Akzent-Tinte >= 4,2:1. - `aria-label`/`aria-pressed` an interaktiven Icons/Checks. - `prefers-reduced-motion` schaltet Transitions aus. - Mobil: keine horizontalen Scrollleisten fuer Inhalte; Tabs wrappen statt abzuschneiden; Eingaben flexibel-schrumpfbar mit `min-width: 0`. ## 8. Verboten (Anti-Patterns) - Verlaeufe (auch subtile), Glow, Glassmorphism, `backdrop-filter`. - Schatten statt Kanten. - Mehr als ein Akzent gleichzeitig; Lila-zu-Blau-Heroes. - Emojis als Icons, rohe Unicode-Pfeile in Labels, Em-Dashes als Stilmittel. - Abgerundete Pillen/Buttons ohne Grund. - "Nahtlos", "Leistungsstark", "Elevate" - Vage-Floskel-Copy. - Zentrierter Hero + 3-Karten-SaaS-Skelett. - Eingaben, die bei jedem Tastendruck neu gerendert werden (Fokus-Verlust). - Nackte Zahlen ohne Einheit. ## 9. Abschluss-Check (vor dem Shippen) 1. Diff gegen die Tokens: keine hartkodierten Farben in Komponenten. 2. Scan auf Em-Dashes, Verlaeufe, rohe Pfeile, Emojis, Bannwoerter. 3. Einheiten/Labels ueberall sichtbar? 4. Zustaende (hover/focus/active/disabled/done) durchgeklickt? 5. Mobil ohne horizontales Scrollen geprueft? 6. Sprachwechsel (de/en) auf Button-Groessen getestet?