# Werkbaum · Frontend Editor: `index.html` ist der funktionierende Prototyp (Text links, Diagramm rechts, Toggles für transponierte Ansicht und verworfene Elemente). ## Konventionen - Vanilla HTML/CSS/JS, ES-Module; keine Frameworks. Testwerkzeug (Vitest) ok. - Parser und Renderer müssen headless (ohne Editor-UI) nutzbar bleiben — Basis für SVG-Export und Mermaid-Plugin (docs/ROADMAP.md). - Design: Farben/Typografie beibehalten (CSS-Variablen, IBM Plex); Statusfarben sind in SPEC §4 normiert. Marke nach ../brand/BRAND.md; Pastelltöne nie im Logo. ## Stolperfallen - Abzweig-Linien zielen auf die **Knotenmitte** (fester 23-px-Offset, `line-height: 1.3`), nicht auf die Mitte des Teilbaums — bei Layout- Änderungen alle drei Modi (horizontal/vertikal/kompakt) prüfen. Vertikal + kompakt teilen die transponierte Basis-CSS; nur vertikal bekommt den Rechts-Ausgang für „all of“, kompakt führt auch „all of“ nach unten. Any-of ist in allen Modi grau: Linien gestrichelt grau und Alternative-Rahmen grau (Basis-CSS `ul.or`). Kein Petrol im Diagramm mehr; `var(--or)` nur noch für UI-Akzente/Logo (SPEC §9, D15). - Extraktionsreihenfolge im Parser nicht umstellen: Kommentar → Zeichen/ Status → URL → Größe → Tags (sonst kollidiert `@` in URLs). - Günstigster Pfad: `markCheapest()`/`cheapestCost()` markieren die nötigen Knoten (Klassen `cheap`, `cheap-leaf`); `drawCheapPath()` zeichnet nach jedem `render()` **und** nach `applyLayout()` zwei Overlay-SVGs in `#out` (hinten kräftige Linie, vorne abgetönte Kopie + Stationspunkte). Overlays erben den CSS-`zoom` von `#out`, Punkte in unskalierte `#out`-Koordinaten umrechnen (`/zoom`). `diagramToSvg()` zeichnet dieselbe Linie/Punkte nach (SPEC §9, D18). - Zerlegt eine any-of-Alternative selbst all-of, wird der Teilbaum **nur horizontal** schmal transponiert (`ul.or>li.has-and>ul.and`, siehe D18) — sonst schiebt der breite Fächer den Elternbaum nach rechts. Bei Layout- Umbauten dieses Nesting mitprüfen. - „verworfen" ist per Default ausgeblendet; Filterlogik steckt in `visibleChildren()` und muss bei Renderer-Umbauten erhalten bleiben. - Zustand wird im `localStorage` gehalten (noch kein Backend): `werkbaum-lang` (Sprache), `werkbaum-src` (Editortext), `werkbaum-ui` (JSON: Modus, verworfene, günstigster Pfad, Split-Zustand inkl. `--col`/`--drow`, Zoom, Vollbild). Neue GUI-Einstellungen in `saveUI()`/`restoreState()` mitführen; `saveUI` liefert während `restoring===true` nichts, damit das Wiederherstellen nicht sofort zurückschreibt. Fehlender `werkbaum-src` fällt auf `INITIAL` zurück, ein leerer String bleibt jedoch leer. - Kleiner Bildschirm: `body.mobile` (per `matchMedia`, ≤ 640 px) stapelt Diagramm/Editor mit **stufenlosem** Splitter (kein Snap/Collapse wie auf Desktop): der Gutter-Drag ruft `setMobileDrow()` (klemmt `--drow` zwischen den Kopfhöhen `--pmin-d`/`--pmin-e`, per `syncPanelMins()` gemessen), ein Tipp auf eine Titelzeile maximiert das Panel. `applyLayout` ruft auf Mobil **kein** `applySplit` (das würde `--drow` löschen). Dazu eigener Legenden-Umschalter (`#legendBtn`), schlanke Sprachwahl, Download-Overlay; Default Vollbild + Diagramm maximiert. Layout-CSS hängt an `body.mobile`, nicht an einer eigenen `@media`-Regel — beide Seiten müssen denselben 640-px-Schwellwert nutzen (SPEC §9, D17).