Commit Graph
80 Commits
Author SHA1 Message Date
mhoennigandClaude Opus 4.8 29e144eddf frontend: UI-Default-Sprache aus der Browsersprache (Fallback DE)
Ohne gespeicherte werkbaum-lang wählt detectLang() die erste vom Browser
gemeldete Sprache (navigator.languages), für die eine Übersetzung existiert
(Primär-Subtag; de-AT->de, zh-Hans->zh), sonst Deutsch. Greift auch nach dem
Reset. Deutsch bleibt Quellsprache. Als D21 dokumentiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 10:15:23 +02:00
mhoennigandClaude Opus 4.8 095dbfb63e frontend: High-Risk-Warndreieck + Prod-Gating der Test-Hilfen
- [!]-Knoten trägt jetzt ein Warndreieck (⚠) an der oberen linken Ecke,
  zusätzlich zur orangen Färbung — im Diagramm, im SVG/PNG-Export und
  barrierefrei (aria-hidden, Status steckt im aria-label). Tooltip in allen
  9 Sprachen.
- SPEC §4: [!]/highrisk-Status nachgetragen (war beim ersten Hinzufügen
  übersprungen), inkl. Warndreieck-Kennzeichnung.
- Beispiel-PSP: Backend als High-Risk ([!]) markiert.
- Debug-Panel + Reset-Button nur außerhalb des Prod-Builds (isProdBuild via
  VITE_BUILD_BADGE); im build:prod eliminiert esbuild den Zweig als toten
  Code. Update-Check + Banner bleiben in allen Builds aktiv.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 10:00:51 +02:00
mhoennigandClaude Haiku 4.5 90b5deb45b fix: Move reset button to header next to fullscreen
Reset-Button gehört in den Header neben dem Fullscreen-Button,
nicht ins Debug-Panel.

Changes:
- Reset-Button (🔄) oben rechts neben Fullscreen-Toggle
- Benutzt gleiche Styling-Klasse (fsbtn) für Konsistenz
- Title: \"App auf Defaults zurücksetzen (für Testing)\"
- Debug-Panel vereinfacht (nur Log-Text, kein Button mehr)

Intuitivere Platzierung für Testing-Feature.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 09:22:22 +02:00
mhoennigandClaude Haiku 4.5 f284e36458 improvement: Add reset button to debug panel
Reset-Button gehört ins Debug-Panel (Testing-Feature):

Changes:
- Debug-Panel erweitert mit flexiblem Layout (flex-column)
- 🔄 Reset-Button hinzugefügt (klickbar, hover-Effekt)
- ✕ Close-Button für Panel (zum Schließen)
- Bessere Styling: halbtransparente Buttons, klare Hover-States

Reset ist nur während Testing nötig — gehört ins Debug-Panel,
nicht in die Haupt-UI. Das 📦-Icon im Footer bleibt für
verfügbare Updates.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:57:30 +02:00
mhoennigandClaude Haiku 4.5 0a8bab24fb refactor: Move update notification icon to footer
Statt Reset-Button im Footer:
- 📦-Symbol rechts neben Version (nur wenn Update verfügbar)
- Klick zeigt die Update-Benachrichtigung wieder an
- Hilft, wenn man den Banner auf \"Später\" verschoben hat

Features:
- Icon nur sichtbar wenn werkbaum-update-available Flag gesetzt
- Hover-Effekt: Icon wird größer (scale 1.2)
- Tooltip erklärt Funktion
- Auto-Update nach Benachrichtigung

Reset-Button entfernt (Nutzer wünscht sich das oben neben Fullscreen,
wenn überhaupt benötigt).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:47:36 +02:00
mhoennigandClaude Haiku 4.5 ceabc34bbe improvement: Make reset button more visible in footer
Reset-Button war zu unauffällig (nur 🔄-Symbol).

Jetzt prominenter:
- Label: \"🔄 Reset\" statt nur 🔄
- Border: dünne Linie um den Button
- Hover-Effekt: Farbe ändert sich zu Petrol (#0F766E)
- Cursor zeigt es ist klickbar

Button sitzt im Footer zwischen Versionsnummer und Links.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:44:35 +02:00
mhoennigandClaude Haiku 4.5 b94f58fcd5 improvement: Clarify update detection logging
Besseres Logging zum Verständnis von Cache-Verhalten:

- \"✓ Alles aktuell\" = Content + Headers gleich
- \"⚙ Metadaten geändert, aber Inhalt gleich\" = Headers unterschiedlich,
  aber HTML-Inhalt identisch (nur Build-Metadaten/ETag geändert)
- \" NEUE VERSION ERKANNT!\" = echter neuer Inhalt entdeckt

Hilft zu verstehen, ob GitHub Pages cacht oder ob wirklich
eine neue Version deployed wurde.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:37:39 +02:00
mhoennigandClaude Haiku 4.5 3bc8f984a6 fix: Simplify update detection – back to GET with timestamp
HEAD-Request hat auf GitHub Pages zu Netzwerkfehlern geführt.
Vereinfachter Ansatz:

- Zurück zu einfachem GET-Request (statt HEAD)
- Cache-Busting via Timestamp: location.href + '?t=' + Date.now()
- ETag/Last-Modified Vergleich + Content-Hash Fallback
- Besseres Error-Logging: unterscheidet "Netzwerk/CORS" von anderen Fehlern

Robuster auf instabilen Netzwerk-Bedingungen (Smartphone).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:32:06 +02:00
mhoennigandClaude Haiku 4.5 e7db4d53d5 feat: Add reset-to-defaults button for testing
Neuer Button im Footer (🔄) zum Zurücksetzen aller Einstellungen:

Features:
- Löscht alle werkbaum-* localStorage-Einträge (Editor, Einstellungen, Update-Flags)
- Confirm-Dialog mit Warnung (Editor-Inhalt geht verloren)
- Reagiert auf alle Bildschirmgrößen
- Nach Confirm: kurze Verzögerung (Logging sichtbar), dann auto-reload

Hilfreich zum Testen:
- Update-Detection testen (Editor-Inhalt neu setzen)
- High-Risk-Status sehen (mit Reset auf Defaults und neuem Beispiel)
- Alle Einstellungen auf Default zurückbringen

Der Button sitzt unauffällig im Footer als 🔄-Symbol.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:25:06 +02:00
mhoennigandClaude Haiku 4.5 d5ef3ff800 fix: Clear update flag before reload when user clicks "Jetzt laden"
Problem: Nach Klick auf "Jetzt laden" wird die Seite neu geladen,
aber das werkbaum-update-available Flag bleibt in localStorage.
Beim Laden der neuen Version wird der alte Check noch vorhanden,
also wird der Banner wieder angezeigt (auch wenn die neue Version
schon da ist).

Lösung: Vor window.location.reload() das Flag löschen.
Damit nach dem Reload die neue Version sauber geladen wird.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:13:14 +02:00
mhoennigandClaude Haiku 4.5 e9519ed7ae fix: Improve update detection with ETag/Last-Modified headers
Robustere Update-Detection für unzuverlässige Netzwerk-Bedingungen:

Neuer Ansatz (statt nur Content-Hash):
1. HEAD-Request prüft ETag + Last-Modified Headers
   - Effizient: Kein großer HTML-Download nötig
   - Verlässlich: Standard HTTP-Cache-Header
2. Wenn Headers gleich → "✓ Alles aktuell" (schnell raus)
3. Nur bei Header-Änderung → volles HTML fetchen + Content-Hash-Vergleich
4. Speichert ETag + Last-Modified für nächste Prüfung

Besseres Logging:
- " NEUE VERSION ERKANNT!" (highlight)
- "⚠ " + Fehlerdetails (was genau fehlgeschlagen ist)
- "✓ Erste Prüfung – Hash gespeichert"
- "✓ Headers änderten sich, aber Content gleich"

Das verhindert:
- Falsche "alles aktuell" wenn Fetch fehlschlägt
- Mehrfaches Fetchen der großen HTML
- "Failed to Fetch" auf unstabilen Verbindungen

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 08:08:24 +02:00
mhoennigandClaude Haiku 4.5 68322b13d9 feat: Add High Risk status [!] for uncertain effort estimation
Neuer Status-Code [!] für Items mit unbekannter Größe/Aufwand:

Parser:
- STATUS_BY_CODE erweitert: '!' -> {key:'highrisk', name:'High Risk – Aufwand unklar'}

Style:
- .node.st-highrisk: Pastellorange (#FFE5CC) mit orange Rahmen (#F97316)
- .chip.st-highrisk: Gleiche Farben für Agenda-Beispiele

i18n (alle 9 Sprachen):
- DE: "High Risk"
- EN: "high risk"
- ES: "alto riesgo"
- FR: "risque élevé"
- PL: "wysokie ryzyko"
- RU: "высокий риск"
- HI: "उच्च जोखिम"
- ZH: "高风险"
- JA: "高リスク"

Tests:
- parser.test.js aktualisiert: 8 Status-Codes (waren 7)

Damit können Items mit ungeklärtem Aufwand im Lean-Pathfinding-Prozess
gekennzeichnet werden – wichtig für Risk-Flagging in Phase 1.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 07:52:02 +02:00
mhoennigandClaude Haiku 4.5 0454f0f50a fix: Add visible debug panel for update detection
Neue Debug-Features für Fehlersuche ohne Dev-Konsole:

- Update-Check alle 15 Sekunden (statt 60, für schnelleres Feedback beim Test)
- Logging in localStorage mit Zeitstempel
- Sichtbares Debug-Panel unten rechts (schwarz, Petrol-Rand)
  * Zeigt die letzten 6 Update-Check-Einträge
  * Klick zum Schließen
  * Hilft ohne Browser Dev-Tools zu sehen, was passiert

Logging zeigt:
-  Neue Version erkannt!
- ✓ Alles aktuell
- ⚠ Fehler: ... (falls Fetch fehlschlägt)

So kann Update-Detection auch auf Smartphone (ohne Dev-Konsole) debugged werden.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 07:40:31 +02:00
mhoennigandClaude Haiku 4.5 ae207789ef docs: Update subtitle short form – concise for mobile
Kurzversionen angepasst für kleine Bildschirme:
- DE: „PSP-Editor mit Lean Pathfinding"
- EN: „WBS editor with Lean Pathfinding"
- ES: „Editor EDT con Lean Pathfinding"
- FR: „Éditeur WBS avec Lean Pathfinding"
- PL: „Edytor WBS z Lean Pathfinding"
- RU: „Редактор СДР с Lean Pathfinding"
- HI: „WBS संपादक Lean Pathfinding के साथ"
- ZH: „WBS 编辑器和 Lean Pathfinding"
- JA: „WBS エディター & Lean Pathfinding"

Testcommit für Update-Detection.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 07:28:26 +02:00
mhoennigandClaude Haiku 4.5 a9232ecbe7 fix: Vereinfache Update-Detection – Client-seitig statt Service Worker
Service Worker mit Blob-URL funktionierte nicht zuverlässig (blob: Protocol
nicht registrierbar in einigen Browsern). Neue Lösung:

- Client-seitige Prüfung statt Service Worker
- Alle 60 Sekunden fetch() der index.html (mit Cache-Busting via Timestamp)
- Einfacher Hash-Check (erste + letzte 200 Zeichen des Content)
- localStorage speichert Hash zum Vergleichen
- Update-Flag wird gesetzt wenn sich Hash ändert
- Benachrichtigung nur wenn User aktiv ist (Page Visibility API)
- Erste Prüfung nach 3 Sekunden, dann alle 60 Sekunden

Viel zuverlässiger als der frühere SW-Ansatz. Funktioniert überall ohne Browser-Limit.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 07:22:12 +02:00
mhoennigandClaude Haiku 4.5 475b4d6fef docs: Update subtitle – PSP & Lean Pathfinding prominence
Texte unter dem Titel angepasst, um Work Breakdown Structure (PSP/WBS) und
Lean Pathfinding gleich prominent zu zeigen. Feature-Tree nur erwähnt, wenn
Platz ist. Kurzversionen auf Mobile: „PSP · Lean Pathfinding Editor".

Alle 9 Sprachen angepasst (DE/EN/ES/FR/PL/RU/HI/ZH/JA).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 07:05:02 +02:00
mhoennigandClaude Haiku 4.5 cad7a8bb6d frontend: Update-Detection überarbeitet - nur anzeigen wenn User aktiv ist
- Service Worker prüft im Hintergrund auf neue Versionen (jede 5 Minuten)
- Update-Status wird in localStorage gespeichert
- Benachrichtigung erscheint nur wenn:
  * User zur App zurückkommt (Page Visibility API)
  * Oder beim initialen Laden wenn Update verfügbar
- "Später" Button zum Dismissieren, "Jetzt laden" für Reload
- Keine Browser-Permission nötig
- localStorage-Daten bleiben beim Reload erhalten
- Pragmatisch: User sieht Updates nur wenn er arbeitet

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 06:48:16 +02:00
mhoennigandClaude Haiku 4.5 a9d2cf3054 frontend: Service Worker für Update-Detection hinzufügen
- Service Worker prüft periodisch auf neue Versionen (jede Minute)
- Bei verfügbarem Update: Benachrichtigung oben auf der Seite
- "Jetzt laden" Button triggert page reload
- Benachrichtigung verschwindet nach 30s oder bei Klick
- Service Worker als Blob registriert (Single-File-App kompatibel)
- localStorage-Daten bleiben erhalten beim Reload

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 06:37:30 +02:00
mhoennigandClaude Haiku 4.5 1c92c66c18 frontend: Fix duplicate variable declarations in ResizeObserver scope
- Rename variables to avoid conflicts with existing declarations
- Wrap ResizeObserver code in IIFE for local scope isolation
- Fixes build error: 'editorPanel' and 'legendBtn' already declared

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 06:25:08 +02:00
mhoennigandClaude Haiku 4.5 7e30a3217a frontend: Editor-Panel Copy & Agenda Buttons nur sichtbar wenn Panel offen genug ist
- ResizeObserver überwacht .editor-body Höhe
- Copy und Agenda Buttons werden versteckt wenn Body-Höhe < Head-Höhe
- Schwellwert: Buttons nur sichtbar wenn mindestens Titelzeilenhöhe Inhalt vorhanden ist

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-23 06:09:20 +02:00
mhoennigandClaude Haiku 4.5 640cb95c27 frontend: Zoom-Controls mit Auto-Collapse-Funktion
- Zoom-Controls collapse automatisch nach 3 Sekunden Inaktivität
- Toggle-Button mit Lupe+Plus-Symbol zum Expandieren der Controls
- Position weiter nach rechts-unten verschoben (6px)
- Event-Delegation für zuverlässige Click-Erfassung
- Lazy-Loading der DOM-Elemente für robuste Initialisierung

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-22 21:16:03 +02:00
mhoennig a334c60fd1 frontend: Add privacy link with multilingual support
Introduced a "Privacy" link in the footer, localized for supported languages. Default to German for DE UI, and English for all others.
2026-07-22 11:20:38 +02:00
mhoennig a92a87f135 frontend: kleinere UI-Bereinigungen (Code & i18n)
- Redundante Rückgabewerte in `overlaySvg()` entfernt
- `aria-labelledby` des Editors ersetzt durch `aria-label` für klarere i18n-Texte
2026-07-22 11:07:42 +02:00
mhoennigandClaude Opus 4.8 0f27bab905 frontend/ci: Build-Hinweis in die App-Quelle, env-gesteuert; Prod-Build ohne
Der Latest-Build-Hinweis wandert vom Workflow-sed in die App (app.js,
mountBuildBadge), damit ihn auch der Dev-Server zeigt — ein Post-Build-sed
erreicht den Dev-Server nicht. Logik umgekehrt: Hinweis ist der Normalfall,
nur die produktive Installation schaltet ihn ab.

Drei Zustaende ueber Vite-Env VITE_BUILD_BADGE (Auswertung in app.js):
- Dev-Server (import.meta.env.DEV) -> 🔧 "Vorschau/lokaler Entwicklungsstand"
- Default `npm run build` (Env ungesetzt) -> 🚧 "latest build"; der Pages-
  Deploy nutzt den Default und traegt den Hinweis dadurch automatisch (die
  sed-Injektion entfaellt).
- `npm run build:prod` (Vite-Modus prod, .env.prod: VITE_BUILD_BADGE=none)
  -> KEIN Badge; esbuild eliminiert den Zweig als toten Code.

Verifiziert zur Laufzeit (Dev + `vite preview` auf beiden Builds): 🔧 im Dev,
🚧 im Default-Build, gar nichts im Prod-Build (Titel sauber "Werkbaum").
34 Vitest-Tests gruen, Workflow-YAML/Shell gueltig.

Doku: D16 fortgeschrieben (quellbasiert/env statt sed, Begruendung); README
(de/en) mit Prod-Build-Anleitung inkl. LICENSE-/Versions-Caveats; frontend/
CLAUDE.md; .claude/launch.json bekommt einen frontend-dist-Preview (vite
preview, Port 8138) zum Verifizieren gebauter Dateien.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 05:56:59 +02:00
mhoennigandClaude Opus 4.8 0a8b3659ea frontend: Fehlertolerantes Parsen — unbekannte Statuszeichen melden
TASKS Phase 2 (Phase 2 abgeschlossen). Der Parser erfasst die Statusbox jetzt
als beliebiges Einzelzeichen `\[([^\]])\]` und validiert gegen STATUS_BY_CODE.
Unbekannte Codes (z. B. [z]) werden nicht mehr still ins Label geschluckt,
sondern als {type:'unknownStatus', line, code} in parse().warnings gemeldet;
der Knoten bleibt neutral, Folgezeilen unberührt. Mehrzeichige Klammern ([xyz])
sind keine Statusbox und bleiben im Label (kein Fehlalarm).

render() in app.js führt Parser- und Renderer-Warnungen zusammen (nach Zeile
sortiert) und zeigt sie via formatWarning. Neuer i18n-Key unknownStatusWarn in
allen 9 Sprachen.

Verifiziert: mehrere unbekannte Codes -> zeilensortierte, lokalisierte
Warnungen (DE/EN), Knoten neutral, keine Konsolenfehler. tests/parser.test.js
+5 (34 Tests grün). SPEC §4 + CLAUDE ergänzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 21:16:34 +02:00
mhoennigandClaude Opus 4.8 15699c321c frontend: Barrierefreiheit — aria-Labels, Fokusreihenfolge, Live-Region
TASKS Phase 2. Jeder Diagramm-Knoten bekommt in render.js (nodeAria) einen
sprechenden, lokalisierten aria-label: Label + Status + Aufwand (inkl.
„(angenommen)" beim impliziten M) + Zuständige + Link. Die rein visuellen
Badges (Größe, Tags, ↗) sind aria-hidden, damit der Screenreader nicht „M",
„anna", „↗" kryptisch doppelt vorliest. Neue a11y*-i18n-Keys in allen 9
Sprachen.

Alle Knoten sind fokussierbar (tabindex=0 bzw. der Link) in Dokument-/Lese-
reihenfolge; sichtbarer :focus-visible-Rahmen (Petrol). #warn ist eine
Live-Region (role=status, aria-live=polite) — neue Warnungen werden angesagt.

Verifiziert: aria-label folgt dem Sprachwechsel (DE/EN), Badges aria-hidden,
keine visuelle Regression, keine Konsolenfehler. Renderer-Snapshots
aktualisiert (29 Tests grün). SPEC §9 (Barrierefreiheit) + CLAUDE ergänzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 21:08:41 +02:00
mhoennigandClaude Opus 4.8 32a02021ed frontend: Warnungs-Modell vereinheitlichen (strukturiert: Typ + Zeile)
TASKS Phase 1 (abgeschlossen). Warnungen sind jetzt maschinenlesbare Objekte
{type, line, ...data} statt vorformatierter Strings: der Renderer emittiert
{type:'mixedGate', line, label}; src/warnings.js `formatWarning(w, t)` macht
daraus an EINER Stelle den lokalisierten, HTML-escapten Anzeigetext. Damit sind
Typ und Zeilennummer sortier-/filter-/testbar, und Phase 2 (unbekannte
Statuszeichen -> {type:'unknownStatus', line, code}) dockt ohne Formatstreuung an.

tests/warnings.test.js + Mixed-Gate-Test im Renderer (29 Tests grün).
Ende-zu-Ende im Browser verifiziert (lokalisierte Warnung mit Zeile + Label).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 21:01:43 +02:00
mhoennigandClaude Opus 4.8 5905712aa5 frontend: Renderer + Modell headless auslagern (src/model.js, src/render.js)
TASKS Phase 1. Baum-/Kostenlogik -> model.js (gateOf, needsBreakdown,
visibleChildren, computeCheapSet, cheapCls), HTML-Erzeugung -> render.js
(renderTreeHtml). Beide sind headless: UI-State (verworfene einblenden,
günstigster Pfad) kommt als Parameter herein statt aus Globals; nur cheapPathOn
bleibt UI-State in app.js. render() in app.js ist jetzt die dünne DOM-Anbindung.

Snapshot-Tests (tests/render.test.js): Grundzustand, günstigster Pfad,
verworfene einblenden, Geister-Knoten („Untergliederung fehlt"), plus die
Zusicherung, dass der Renderer nie eine Modus-Klasse erzeugt (Modus =
CSS-Container-Klasse in app.js -> ein Snapshot deckt alle drei Modi). 24 Tests
grün. Byte-identisches Rendering im Browser verifiziert (18 Knoten, 6 Blätter,
3 Geister, Toggles ok, keine Konsolenfehler).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:58:47 +02:00
mhoennigandClaude Opus 4.8 80d05a33a2 frontend: Parser nach src/parser.js auslagern (headless)
TASKS Phase 1. `parse`, `STATUS_BY_CODE` und `SIZE_RANK` wandern unverändert
in ein eigenes, DOM-freies Modul (SPEC §1–§8 normativ); app.js importiert sie.
Vorbereitung für die Parser-Unit-Tests (nächste Checkbox) und den SVG-/Mermaid-
Renderer, die den Parser headless nutzen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:49:45 +02:00
mhoennigandClaude Opus 4.8 78d1000f61 frontend: Projektgerüst mit Vite — Single-HTML in ES-Module + Bündelung
Erster Schritt der Modularisierung (ROADMAP „tragfähige Codebasis",
TASKS Phase 1). Der bisher einzelne index.html-Prototyp wird zur Vite-App:

- CSS -> src/style.css, gesamtes JS -> src/app.js (noch als ein Modul;
  Parser/Renderer werden in den folgenden Checkboxen herausgelöst).
- index.html ist der Vite-Entry (<script type="module" src="/src/app.js">).
- npm run build (vite + vite-plugin-singlefile) inlint JS+CSS+Favicon (als
  data:-URI) in EINE self-contained dist/index.html -> bleibt file://-tauglich.
- Vitest als Testrunner eingerichtet (tests/, passWithNoTests bis Schritt 2/3).
- Pages-Workflow: Node + npm ci + npm test + npm run build, deployt dist/;
  Favicon-sed entfällt (inline), nur ../LICENSE + Footer-Version bleiben.
- .claude/launch.json auf Vite-Dev-Server (Port 8137) umgestellt.

Entscheidung als D19 dokumentiert (weicht D11 „kein Build-Zwang" bewusst auf,
hält aber D16 file://-Versprechen über die gebündelte Datei). README (de/en)
und frontend/CLAUDE.md um Dev-/Build-/Test-Workflow ergänzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:47:23 +02:00