IBM Plex Sans and Mono are now embedded locally (`woff2`) under `src/fonts`, licensed under SIL OFL 1.1. Removed external `<link>` to Google Fonts for enhanced privacy and compliance. Updated `style.css` with `@font-face` and unicode ranges for `latin` and `latin-ext` subsets. Added license details to documentation.
Der sichtbare Abstand kam fast ganz vom internen Weißraum des Emoji-Glyphs
(~11px), nicht vom margin. margin-left auf -.5em gesetzt -> Abstand
Titelende->Badge von 12px auf 5px. Laufzeit-gemessen im Dev-Server.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
TASKS Phase 2. @media print in style.css blendet Kopfzeile, Editor-Panel,
Splitter, alle Bedienelemente des Diagramm-Kopfs, Warnungen und Footer aus; das
Diagramm füllt die Seite (App-Grid -> Block, Overflow sichtbar) und darf über
mehrere Seiten laufen. Statusfarben werden mitgedruckt (print-color-adjust:
exact), Knoten brechen nicht über den Seitenrand (break-inside: avoid), der
Günstigster-Pfad-Overlay (in #out) kommt mit.
Verifiziert per Druck-Emulation (Regeln testweise als Screen-Style angewendet):
Editor/Kopf/Splitter/Warnungen/Footer display:none, Diagramm sichtbar, 18
Knoten, Farben + Pfadlinie erhalten. SPEC §9 (Druck) ergänzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
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>
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>
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>