# ALICIA.md — NOVA Control Reparatur **Auftrag:** Behebe 26 binäre Gates in `index.html`. Jedes Gate ist ein klares Ja/Nein-Kriterium — erst erfüllt, wenn nachweisbar wahr. **Repo:** `git@git.datenhimmel.work:danielkrause/nova-control.git` **Branch:** `master` **Datei:** Nur `index.html` — eine Datei, kein Framework, keine Libs, kein CDN, offline. --- ## Arbeitsweise 1. **Gate für Gate.** Nicht mehrere auf einmal. Ein Gate → implementieren → testen → commit. 2. **Vor jedem Commit:** `index.html` im Browser öffnen und das Gate manuell verifizieren. 3. **Commit-Message:** `fix: P0.1 Datei-Dialog entfernt` o.ä. 4. **Push nach jeder Phase** (P0, P1, P2) — nicht nach jedem einzelnen Gate. ## Reihenfolge (P0 → P1 → P2) ### P0 — BLOCKER (zuerst, weil App sonst beim Start kaputt) **P0.1 — Datei-Dialog** - Zeile mit `document.getElementById('imp').click();` **löschen** - Test: Seite laden → KEIN Datei-Dialog **P0.2 — Command-Palette** - `rp()` wird nie aufgerufen → `cmds` bleibt `[]` - `rp()` auf ≥8 Befehle erweitern: Board, Streaks, Insights, Neues Task, Import, Export, Reset/Demo, 500 Tasks - `ld()` ruft am Ende `rp()` auf, dann `inipal()` beim Öffnen der Palette - Tasks dynamisch als anspringbare Einträge in die Liste - Test: Cmd+K → Liste zeigt ≥8 Einträge **P0.3 — Dark Mode** - `:root` hat nur Hell-Werte, `[data-theme="dark"]`-Block fehlt - CSS: `[data-theme="dark"]` mit `--bg`, `--surface`, `--text`, `--border` - `at()`: `matchMedia('(prefers-color-scheme:dark)').addEventListener('change', ...)` für Live-Reaktion - `localStorage` für Persistenz (existiert via `sv()`) - Test: 🌙 klicken → Hintergrund dunkel. Reload → bleibt dunkel. ### P1 — KERN-FEATURES **P1.1 — Maus-Drag & Drop** - HTML5 DnD API: `draggable="true"` auf `.task` - `dragstart`/`dragover`/`drop` Events - Drop-Indikator (gestrichelter Rahmen oder Platzhalter) - Inter-Spalte (Status wechselt) + Intra-Spalte (Reihenfolge) - Nach Drop: `sv()` + `rv()` - Test: Task von Backlog nach Aktiv ziehen. Nach Reload noch da. **P1.2 — Tastatur-DnD** - Fokussiertes Task: Ctrl+Alt+Pfeiltasten - ←→: Spalte wechseln | ↑↓: Position in Spalte - `
` für Status-Ansagen - Test: Nur Tastatur, Task durch alle 4 Spalten bewegen. **P1.3 — Feld-Schema** - `op()`-Create speichert Fälligkeit als `du`, Board liest `d` - `du` → `d` vereinheitlichen (in Create + Edit) - `ldDemo()` und Render prüfen: benutzen die `d`? - Test: Task mit Datum anlegen → Reload → Datum noch da. **P1.4 — Streak-Berechnung** - Pro Habit: aktuelle Serie + längste Serie - Regeln: Wert > 0 = erfüllt. Tag mit 0 = Bruch. Heute noch nicht erfüllt = kein Bruch. - Anzeige im Streak-View - Test: Serie bricht bei 0, läuft weiter wenn heute noch kein Wert. **P1.5 — Export** - `exportData()`: `{version:1, tasks, habits, theme}` als JSON-Blob → Download - Command "Export" in Palette - Import validiert `version` + `tasks` Array - Test: Export → localStorage löschen → Import → identischer Zustand. **P1.6 — Zweiter Chart + Trend-Wochen** - `` für Donut (Prioritätsverteilung) - Trend-Chart: Monate → Wochen umstellen - Datenbasis Trend: `df` (Abschlussdatum) - Legende, Labels, Empty-State - Test: Insights zeigt 2 Charts. Trend in Wochen. **P1.7 — Listener-Leak + Fokusverlust** - `rb()`: KEIN `innerHTML` = Toolbar + alles neu - Toolbar (Suche + Filter) EINMAL im HTML, nicht pro `rb()` - Event-Delegation auf `#board-section` EINMAL binden - Suche: `display:none` statt DOM-Neuaufbau - Test: 10× Views wechseln → Modal öffnet 1×. Tippen in Suche → Fokus bleibt. ### P2 — POLITUR **P2.1 — Heatmap 26 Wochen** - Spalten=Wochen, Zeilen=Mo..So, 26 Wochen zurück - Hover-Tooltip mit Datum + Wert - Test: Kein 28-Tage-Streifen mehr, Wochen-Grid sichtbar. **P2.2 — Responsive** - `@media (max-width: 768px)`: Layout einspaltig - `@media (max-width: 480px)`: Board untereinander - `overflow-x: auto` NUR auf `.board`, nicht `body` - Test: 360px Breite → kein Body-Scroll. **P2.3 — prefers-reduced-motion** - `@media (prefers-reduced-motion: reduce) { ... }` - Animationen deaktivieren (Toast, Drag-Transitions) - Test: OS-Einstellung "Reduzierte Bewegung" → keine Animationen. **P2.4 — Focus-Trap** - Modal + Palette: Tab/Shift+Tab zyklisch im Dialog - ESC schließt + Fokus zurück auf Auslöser - Test: Modal offen → Tab kreist. ESC → Fokus auf Button davor. **P2.5 — Palette-Tastatur** - Keydown auf `#pal-q` (Eingabefeld) statt `#pal-list` - ↑/↓ navigieren Liste, Enter führt aus - Fokus bleibt im Eingabefeld - Test: Pfeiltasten bei Fokus im Suchfeld. **P2.6 — Hash-Routing** - Navigation setzt `location.hash = '#/' + view` - `hashchange`-Event schaltet View - Beim Laden: View aus Hash setzen - Test: `#/insights` → Insights-View. Reload bleibt. Zurück-Button. **P2.7 — 500 Tasks** - `gen500()`: 500 Tasks generieren - Command in Palette - Performance: Batch-Rendering, kein 500× Einzel-Push - Test: 500 Tasks → Board flüssig, Suche filtert sofort. **P2.8 — Robustheit** - `ld()`: `nv_t` validieren → `Array.isArray()` + try/catch → Fallback `[]` - Import: Jeden Task auf `id`, `tl`, `st` prüfen - Fehlerhafte Einträge → Meldung, bestehende Daten bleiben - Test: Kaputtes JSON importieren → Fehlermeldung, keine Daten verloren. --- ## Git-Workflow ```bash git clone git@git.datenhimmel.work:danielkrause/nova-control.git cd nova-control # Gate bearbeiten... git add index.html git commit -m "fix: P0.1 Datei-Dialog entfernt" # Nach jeder Phase: git push # Nach Abschluss: git tag v1.0 # alle 26 Gates geschlossen git push --tags ``` --- ## Constraints (unveränderlich) - ❌ Keine zweite Datei (kein .css, kein .js) - ❌ Keine externen Libs/CDNs (kein jQuery, kein React, kein Bootstrap) - ❌ Kein Build-Step, kein npm - ✅ CSS `