Neues Skript scripts/deploy-prod.sh baut das badge-freie Prod-Bundle
(npm run build:prod), stellt es lokal wie der Pages-Workflow zusammen
(LICENSE danebenlegen + ../LICENSE-Link geradeziehen, Footer-Version +
Commit-Link) und spiegelt es per rsync --delete ueber SSH in ein als Argument
uebergebenes Zielverzeichnis — am Ziel bleibt nichts Altes stehen.
- Pflichtargument: rsync-Ziel (z. B. user@host:~/doms/.../subs-ssl/werkbaum/).
- Ohne -y erst --dry-run-Vorschau + Rueckfrage (--delete ist destruktiv).
- Warnt bei unsauberem Arbeitsbaum (Commit-Link zeigt auf HEAD).
- node_modules-Guard: npm ci nur wenn noetig.
End-to-End gegen ein lokales Ziel verifiziert: --delete raeumt Alt-Datei und
Alt-Unterordner weg, deployte index.html enthaelt 0x 🚧/🔧 (nur die ungenutzte
CSS-Regel), LICENSE danebengelegt + Link auf "LICENSE", Version 1.0.x + Commit.
Doku: README (de/en) Abschnitt Prod-Installation, DECISIONS D16 (warum die
sed-Zusammenstellung bewusst in Workflow UND Skript liegt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Der Pages-Deploy ist der frischeste Entwicklungsstand und kann Fehler
enthalten; die stabile Instanz laeuft woanders. Damit nur diese
Veroeffentlichung markiert ist, injiziert der Workflow nach demselben Muster
wie Version/LICENSE — also NUR auf der Site-Kopie — hinter dem Titel (Anker
</h1>, im Bundle eindeutig) ein kleines Symbol mit zweisprachigem Tooltip
(<span class="build-badge">🚧</span>). Quelle bleibt unberuehrt: ein schlichter
`npm run build` erzeugt die Datei ohne Hinweis. Als Deploy-Metainfo bewusst
nicht im I18N-Objekt (D14). D16 fortgeschrieben.
Verifiziert gegen das echte dist-Bundle: Badge genau 1x, Version 1.0.x +
Commit-Link unveraendert, frontend/index.html traegt 0 Badges.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Zwei zusammenhaengende Ideen unter "Kleinere Ideen" festgehalten, aufbauend
auf dem Aufwands-Rollup:
- Nutzen/Wert je Knoten als Gegenstueck zur Kosten-Groesse (Nutzen/Kosten-
Priorisierung, WSJF-artig); Syntax bewusst offen gelassen (SPEC-first).
- Gestaffelter "guenstigster Pfad": D18 status-bewusst machen (fertig/prod =
erledigt), nur den offenen Rest hervorheben und zur naechsten, per Nutzen
gewaehlten Ausbaustufe weiterspringen.
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. tests/parser.test.js mit dem kanonischen SPEC-§10-Beispiel als
Fixture und den geforderten Randfällen: URL mit @, %% am Zeilenanfang/-ende,
leere Labels, mehrere Wurzeln, Tab = 2 Leerzeichen, ungleichmäßige Einrückung,
gemischte Gates, x/X + case-insensitive Größe, Vokabular-Exporte. 18 Tests grün.
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>
Auf dem Smartphone hatte der Splitter zwei Fehler: nach dem ersten Ziehen
rastete er in eine feste Aufteilung und ließ sich nicht mehr bewegen (die
Titelzeile im Snap-Rand fing jeden weiteren Zug ab), und das Tippen auf eine
Titelzeile klappte das Panel nicht mehr aus (der Handler verlangte den
collapsed-Zustand, den ein freier Zug aufhob).
Mobil jetzt kontinuierlich statt diskret:
- Grid-Zeilen-Minima --pmin-d/--pmin-e = gemessene Kopfhöhen (syncPanelMins),
dadurch bleiben beide Titelzeilen immer stehen (kein Snap/Collapse).
- Gutter-Drag ruft setMobileDrow() (klemmt --drow frei) — jederzeit beweglich.
- Tipp auf eine Titelzeile maximiert dieses Panel (das andere = Titelzeile).
- applyLayout ruft auf Mobil kein applySplit (behält --drow bei Moduswechsel);
seg-Klick stoppt Propagation, damit er die Titelzeile nicht mit-maximiert.
- Default: Diagramm maximiert. Desktop behält das diskrete Modell + Buttons.
SPEC §9, DECISIONS D17 und frontend/CLAUDE.md nachgeführt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auf kleinen Screens brach die Diagramm-Titelzeile um, weil die Download-Buttons
mit „SVG“/„PNG“-Textlabels zu breit sind. Sie klappen jetzt auf Mobil hinter
einen einzelnen Download-Icon zusammen (dlGroup/dlTrigger/dlmenu); ein Tipp
zeigt die Formatwahl als Dropdown-Overlay unter der Kopfzeile, Auswahl oder
Tipp daneben schließt. „Kopieren“ bleibt sichtbar. Desktop unverändert (SVG/PNG
inline). Neuer i18n-Key downloadMenu (9 Sprachen), SPEC §9 nachgeführt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Im vertikalen Modus zentriert li.has-and den Alternativknoten (z. B. „Web+Nativ")
vertikal mittig zu seinem Rechts-Fächer; der einkommende any-of-Abzweig saß aber
weiter bei 23 px und traf den Knoten nicht mehr — er war von seiner Linie von
oben abgetrennt. Fix nur für .tree.vertical ul.or>li.has-and: symmetrisches
Padding hält die Knotenmitte bei 50 %, Abzweig (::before) und Rail-Endkante
(:last-child::after) auf 50 %. Horizontal/kompakt unberührt. D18 nachgeführt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
100dvh versagt bei Browsern, die ihre untere Leiste als Overlay zeichnen
(z. B. Brave): dvh meldet weiter die volle Höhe, Footer/Editor-Titelzeile
verschwinden dahinter. JS setzt nun --app-height aus window.visualViewport
.height (wirklich sichtbare Fläche), aktualisiert bei resize/orientationchange.
CSS-Kaskade bleibt Fallback: vh -> dvh -> var(--app-height).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auf Mobilgeräten ist 100vh die große Viewport-Höhe inkl. der Fläche hinter der
unteren Browserleiste — Footer und die eingeklappte Editor-Titelzeile rutschen
dahinter und sind nicht antippbar. 100dvh (dynamische Viewport-Höhe) folgt der
sichtbaren Fläche; 100vh bleibt als Fallback für alte Browser.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- eingeklappt zeigt die Leiste nur noch die aktive Sprache (kein EN-Default,
kein „…“); ein Tipp klappt die volle Liste als Overlay über die Kopfzeile auf
(position:absolute, z-index) statt die Zeile zu verbreitern
- nach Auswahl klappt sie wieder auf die gewählte Sprache ein; Tipp daneben
schließt ebenfalls; applyMobile() startet eingeklappt
- nur body.mobile betroffen; Desktop (DE EN ES FR + „…“, inline) unverändert
- SPEC §9 (Kleiner Bildschirm) und DECISIONS D17 nachgeführt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- gestrichelte, geschwungene Petrol-Linie (Katmull-Rom) durch die Endknoten
des Pfads; kräftig hinter den Knoten, abgetönte Kopie davor
- blasse, große Stationspunkte nur an echten Blättern (U-Bahn-Plan) — macht
durchquerte Fremd-/Zwischenknoten eindeutig als "nicht Endknoten" erkennbar
- Linie + Punkte auch im SVG/PNG-Export (hinten/vorne-Schichtung)
- Overlays liegen in #out, erben dessen CSS-zoom (Punkte /zoom umgerechnet);
Neuzeichnung nach render() und applyLayout()
- Beispiel erweitert: Frontend (M) -> PWA | Web+Nativ (Web[/]+Android+iOS)
- Layout-Fix: all-of unter einer any-of-Alternative wird nur horizontal schmal
transponiert gestapelt (ul.or>li.has-and>ul.and), sonst schob der breite
Fächer Alternativknoten und Elternbaum weit nach rechts
- Geist-Knoten-Label "Untergliederung fehlt" -> "…" (alle 9 Sprachen), die
Erklärung bleibt im Tooltip; der lange Text verbreiterte gestapelte Zellen
- SPEC §5/§9 und DECISIONS D18 nachgeführt, Notiz in frontend/CLAUDE.md
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Umschalter im Diagramm-Kopf (Default an, Zustand in werkbaum-ui persistiert)
- nötige Knoten: all-of ⇒ alle Kinder, any-of ⇒ günstigste Alternative
(kleinste rekursive Kosten; Gleichstand ⇒ erste); verworfene zählen nie mit
- Darstellung per Inversion: nicht benötigte Knoten treten blass/entsättigt
zurück (kein Zusatzrahmen an den ohnehin dichten Knoten-Ecken)
- fehlende T-Shirt-Größe wird für die Kostenschätzung als M gewertet;
invertiertes M-Badge (weiß mit Petrol-Rand) macht die Annahme sichtbar
- neue Tooltips i18n (DE-Quelle + 8 Übersetzungen, 50 Keys × 9)
- SPEC §9 (Günstigster Pfad) und DECISIONS D18 mitgeführt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Im Footer sind "Werkbaum" und die Versionsnummer jetzt zwei Links:
- "Werkbaum" -> Repo-Startseite (wie bisher).
- Versionsnummer (<a class="ver">) -> exakt der deployte Commit.
CI setzt beim Build sowohl den Versionstext als auch den href der
ver-Anchor: COMMIT_URL=.../commit/$(git rev-parse HEAD); zwei gezielte
seds (href + Text). Lokal zeigt die Version "1.0" und verlinkt die
Commits-Uebersicht als Fallback.
Verifiziert: YAML gueltig; Trockenlauf ersetzt href -> commit/<sha> und
Text -> 1.0.7, "Werkbaum"-Link unveraendert. Preview lokal: Name -> Repo,
Version -> /commits/main.
Doku: README (EN+DE) Deployment + DECISIONS D16 ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Verifiziert: .site-footer margin-top jetzt 14px. Gilt auf allen
Bildschirmen. Keine SPEC-Aenderung.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Untertitel nennt jetzt auch Requirements(-Baum) — analog zur
Meta-Description. Fuer kleine Bildschirme gibt es eine garantiert
einzeilige Kurzfassung (neuer i18n-Key subtitleShort, 9 Sprachen): zwei
Spans (.sub-full/.sub-short), per body.mobile umgeschaltet; zusaetzlich
white-space:nowrap + ellipsis als Sicherung gegen Umbruch.
Verifiziert (headless): Desktop zeigt die Langfassung mit Requirements,
375px zeigt die Kurzfassung einzeilig ohne Overflow in allen geprueften
Sprachen (de/en/es/fr/ru/ja); i18n konsistent (48 Keys x 9). Normalgroesse
unveraendert (Kurzfassung nur mobil).
SPEC §9 (Kleiner Bildschirm) ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der breite Schalter mit Text wird ein schmaler Druck-Button (29px statt
Schalter+Label): Symbol = gestrichelte Box mit Durchstreichung (spiegelt
den verworfenen Knoten), aria-pressed als Ein/Aus-Zustand (gedrueckt =
petrol gefuellt), Erklaerung per Tooltip (discardedTooltip). Ersetzt die
Checkbox #showc; Zustand jetzt ueber aria-pressed (discardedShown/
setDiscarded), unveraendert in Filter, Speichern und Wiederherstellen.
Verifiziert (headless): Button toggelt aria-pressed + Petrol-Fuellung,
blendet verworfene Knoten ein/aus, Zustand ueberlebt Reload. Gilt auf
allen Bildschirmen (spart auch mobil Platz).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der #legendBtn (nur auf kleinem Bildschirm sichtbar) trug ein Menue-/
Listen-Icon; die Legende ist aber eine Hilfe-/Referenzseite. Jetzt ein
Hilfe-Icon (Kreis mit Fragezeichen). Nur der Button-Inhalt geaendert,
Normalgroesse nicht betroffen (Button dort verborgen).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auf body.mobile zeigt der horizontal/kompakt/vertikal-Waehler nur noch das
aktive Icon (label:has(input:checked)); Tippen schaltet reihum zum naechsten
Modus (horizontal -> kompakt -> vertikal -> …). Spart zwei Drittel Breite.
Verifiziert (headless): mobil ein Icon sichtbar (~40px), 3x Tippen zyklt
horizontal/kompakt/vertikal/horizontal; Desktop unveraendert (3 Icons,
~118px, Direktauswahl ohne Zyklus), keine Konsolenfehler.
SPEC §9 (Kleiner Bildschirm) ergaenzt. Normalgroesse nicht betroffen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Gutter wurde auf Mobil faelschlich ganz ausgeblendet. Jetzt bleibt er
sichtbar und ziehbar (die 820-px-Regel liefert das gestapelte Layout inkl.
Gutter); nur die Min/Normal/Max-Buttons bleiben verborgen. Default weiterhin
ein Bereich gross, Umschalten per Titelzeilen-Tap unveraendert, zusaetzlich
Teilen per Ziehen moeglich.
Verifiziert (headless, 375px): Gutter sichtbar, Ziehen erzeugt Custom-Split
(--drow gesetzt, beide Bereiche sichtbar); Default-Einzelansicht und
winbtns-verborgen unveraendert. Normalgroesse nicht betroffen.
SPEC §9 und DECISIONS D17 an "Splitter bleibt" angepasst.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Default-Beispieltext (INITIAL) ist jetzt englisch (passend zur
englischen Haupt-README). Statt "Cloud" nun "Cooperative Community Cloud"
mit Link https://hostsharing.net (nackte URL -> klickbarer Knoten mit ↗).
README-Screenshot neu erzeugt (englische UI + Inhalt).
SPEC §10 (kanonisches Fixture) bleibt bewusst deutsch: normatives
Beispiel der deutschsprachigen Doku, unabhaengig vom Live-Demo-Text.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auf kleinem Bildschirm (body.mobile per matchMedia, <=640px):
- Immer nur ein Bereich gross (Diagramm ODER Editor); der andere schrumpft
auf seine Titelzeile und dient als Umschalter (Antippen holt ihn nach
vorn). Splitter und Min/Normal/Max-Buttons entfallen.
- Legende von der Bereichs-Umschaltung entkoppelt: eigener Umschalter
(#legendBtn) im Editor-Kopf statt der dauerhaften "AGENDA"-Zeile, damit
sie zugeklappt keinen Platz kostet (neuer i18n-Key legendTooltip, 9 Spr.).
- Sprachwahl schlank: nur EN + aktive Sprache + "…" (klappt alle auf); die
aktive Sprache wird auch als "extra" eingeblendet, Auto-Aufklappen entfaellt.
- Default Vollbild auf Mobil (nur ohne gespeicherte Nutzerwahl).
Verifiziert (headless, 375px): body.mobile gesetzt, Diagramm-Default +
Editor als Titelzeile, Umschalten per Tap, Legenden-Toggle, Sprachleiste
DE+EN+…/Aufklappen zeigt alle 9/aktives Extra bleibt sichtbar, Vollbild an,
keine Konsolenfehler; Desktop unveraendert (beide Panels, 4 Sprachen,
Legendenbutton verborgen). i18n konsistent (47 Keys x 9).
SPEC §9 (Kleiner Bildschirm) + DECISIONS D17 + frontend/CLAUDE.md ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
In den transponierten Modi ueberlappte das Groessen-Badge (oben rechts)
eines Knotens oft mit den Namens-Tags (unten rechts) des Knotens darueber
(gemessen: nur 10 px Luecke, 6 px Ueberlappung). Jetzt +20 px Abstand
nach unten fuer gestapelte Blaetter/any-of/kompakt (Luecke 25 px, ~9 px
Freiraum); der obere 23-px-Abzweig bleibt unveraendert. Vertikal
zentrierte all-of-Zwischenknoten bekommen den Abstand symmetrisch (16 px),
damit ihr 50%-Abzweig auf der Knotenmitte bleibt.
Verifiziert (headless): keine Ueberlappung mehr; alle Abzweige treffen die
Knotenmitte (|delta| <= 1 px) in vertikal und kompakt. Horizontal
unveraendert. SPEC §9 (Geometrie-Invarianten) ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
"Vibe-Coded with Claude Code Fable 5 and Opus 4.8" wird zu
"Vibe-Coded with Claude Code"; "Fable 5 and Opus 4.8" steckt als
title-Tooltip im span.vibe (gepunktete Unterstreichung, cursor:help).
Spart Platz auf allen Bildschirmen. Keine SPEC-Aenderung.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Micro-Version jetzt commit-basiert statt aus github.run_number:
- Major.Minor in neuer Datei VERSION (per Bump-Commit gepflegt).
- Micro = Commits seit dem letzten VERSION-Bump
(git rev-list --count <VERSION-Commit>..HEAD) -> beginnt nach einem
Bump wieder bei 0 (SemVer-artig, z. B. 1.0.0, 1.0.1, dann 1.1.0).
- checkout mit fetch-depth: 0 (flacher Klon zaehlte sonst nur 1 Commit).
- sed ersetzt jetzt ">Werkbaum <ziffern></a>" (regex), damit auch nach
einem Major/Minor-Bump im Quelltext getroffen wird; viewport-/xml-1.0
bleiben unberuehrt.
Vorteil ggue. Run-Nummer: vollstaendig aus dem Repo reproduzierbar,
zaehlt keine fehlgeschlagenen/manuellen Laeufe, kein Rueckschreiben.
Doku: README (EN+DE) Deployment-Abschnitt und DECISIONS D16 aktualisiert.
Keine SPEC-Aenderung (Notation unberuehrt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beim Site-Build ersetzt der Workflow ">Werkbaum 1.0</a>" durch
">Werkbaum 1.0.${{ github.run_number }}</a>" (per sed, nur auf der
Site-Kopie). Die Micro-Version steigt so bei jedem Deployment monoton
um 1 — ohne Commit/Tag zurueck ins Repo und ohne selbstausloesenden
Deploy-Zyklus. run_number via env BUILD_VERSION injiziert. "1.0" bleibt
die manuell gepflegte Basis und die Version beim lokalen Oeffnen; die
viewport-/xml-"1.0" bleiben unberuehrt (Anker >...</a> als Ziel).
Doku: README (EN+DE) Deployment-Abschnitt und DECISIONS D16 ergaenzt.
Keine SPEC-Aenderung (Notation unberuehrt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ohne Backend bleiben Einstellungen und Text ueber ein Neuladen erhalten
(localStorage). Gespeichert: Editortext (werkbaum-src) und GUI-Zustand
(werkbaum-ui: Modus, verworfene, Split-Zustand inkl. freier Drag-Groesse
--col/--drow, Zoom, Vollbild); Sprache bleibt in werkbaum-lang.
saveUI()/saveSrc() haengen an allen Zustandsaenderungen (Layout, Toggle,
Fenster-Buttons, Splitter-Drag, Zoom, Vollbild, Texteingabe);
restoreState() stellt beim Laden alles wieder her und unterdrueckt
waehrenddessen ueber restoring=true das Zurueckschreiben. Fehlender Text
faellt auf das Beispiel (INITIAL) zurueck, ein leerer bleibt leer.
Verifiziert (headless): Text, Modus, verworfene, Zoom, Vollbild,
Custom-Split (--col) und Minimier-Zustand ueberstehen ein Reload;
keine Konsolenfehler. Keine SPEC-Aenderung (Notation unberuehrt);
localStorage-Schluessel in frontend/CLAUDE.md dokumentiert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Link auf https://michael.hoennig.de/imprint.html am Ende des Footers.
Neuer i18n-Key "imprint": deutsch nur "Impressum", in allen anderen
Sprachen die uebersetzte Bezeichnung mit "(Impressum)" in Klammern
dahinter (z. B. EN "Imprint (Impressum)", FR "Mentions legales
(Impressum)"). Keine SPEC-Aenderung (Notation unberuehrt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auf Wunsch ist die englische Fassung jetzt die Haupt-README.md; die
deutsche Fassung liegt als README.de.md. Sprachlinks oben in beiden
Dateien angepasst. Der Hinweis in README.md stellt klar, dass die
ausfuehrliche Doku unter docs/ weiterhin auf Deutsch gepflegt wird.
Screenshot der laufenden App (docs/screenshot.png, headless Chrome gegen
den lokalen Dev-Server) im Abschnitt Usage/Nutzung eingebunden.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deutsch bleibt Quellsprache (CLAUDE: "Doku auf Deutsch"), daher die
Uebersetzung als separate README.en.md statt README.md zu ersetzen.
Wechselseitige Sprachlinks oben in beiden Dateien; Hinweis in der
englischen Fassung, dass sie eine Convenience-Uebersetzung ist und der
deutschen Vorlage hinterherhaengen kann.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Offizieller Actions-Weg (upload-pages-artifact + deploy-pages) mit
permissions pages/id-token und concurrency-Gruppe "pages"; Trigger:
Push auf main + workflow_dispatch. Vitest-Step als Platzhalter
auskommentiert (Tests folgen, TASKS.md Phase 1).
Site-Aufbau: frontend/index.html an die Wurzel-URL, dazu docs/brand/
(Favicon) und LICENSE (MIT-Link im Footer). Die ../-Pfade der Quelle
zeigten von der Wurzel aus über die Site hinaus; statt den Editor zu
aendern, zieht der Workflow sie nur auf der Site-Kopie per sed gerade
(Editor-Quelle bleibt unveraendert, lokal weiter nutzbar). backend/
und uebrige docs/ werden nicht veroeffentlicht.
Doku: README-Abschnitt "Deployment" (inkl. einmaliger Settings-
Umstellung auf Source "GitHub Actions", Repo muss oeffentlich sein),
TASKS.md-Rubrik "Deployment" abgehakt, DECISIONS D16. Hinweis: der
Auftrag nannte "D15", das war aber schon fuer den kompakten Modus
vergeben -> als D16 angelegt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LibreOffice liest weder das Browser-Bild-Clipboard noch das SVG zuverlässig.
Neben dem SVG-Download gibt es daher jetzt einen zweiten Button, der das
Diagramm als PNG-Datei (werkbaum-diagramm.png, Raster) speichert — überall
per "Bild einfügen" importierbar. Beide Download-Buttons tragen ein
Format-Label (SVG/PNG). Tooltip in allen neun Sprachen; SPEC §9 ergänzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LibreOffice Writer erkennt das Browser-Bild-Clipboard nicht zuverlässig
(sein HTML-Filter ignoriert data-URI-Bilder, und die Async-Clipboard-API
erlaubt kein SVG als Bildtyp). Neue Download-Schaltfläche im Diagramm-Kopf
speichert das Diagramm als eigenständige SVG-Datei (Vektor), die per
Einfügen → Bild überall zuverlässig importierbar ist. Der bisherige
PNG-Clipboard-Button bleibt für Apps, die ihn lesen. Tooltip in allen neun
Sprachen; SPEC §9 ergänzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Zwei weitere aufklappbare Sprachen hinter dem "…"-Umschalter mit
vollständigen UI-Übersetzungen (inkl. Diagramm-Tooltips). Reihenfolge:
de en es fr pl ru hi zh ja …. LANG_EXTRA und CLAUDE.md-Konvention ergänzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Statt bündig am Fensterrand bleibt im Vollbild links/rechts ein 7-px-Rand
(halber Panel-Zwischenraum von 14 px), damit die Panels nicht gedrängt
wirken.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Das Diagramm wird bewusst als PNG kopiert. Zusätzlich zum image/png-Flavor
wird eine text/html-Variante mit eingebettetem PNG geschrieben, die
Office-Programme wie LibreOffice Writer bevorzugt einbetten — damit ist das
Bild dort einfügbar. Der Tooltip nennt jetzt das Format ("PNG-Bild in die
Zwischenablage"). SPEC §9 entsprechend ergänzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Diagramm-Kopieren-Button liefert nun ein grafisches Format statt Text:
Das gerenderte Diagramm wird aus der Live-Geometrie in ein eigenständiges
SVG (nur Formen + Text, keine externen Ressourcen) nachgezeichnet und als
PNG in die Zwischenablage gelegt. Knotenfarben, Größen-Badges, Tags und der
Geister-Knoten werden übernommen; Verbindungslinien je Gate neu gezogen
(und = durchgezogen Tinte, oder = gestrichelt Grau) und treffen so in allen
Modi die Knoten. Fallback: SVG-Quelltext, wenn kein Bild-Clipboard verfügbar.
Der bisherige ASCII-Text-Export (treeToText, CODE_BY_KEY) entfällt.
Tooltip-Texte auf "als Bild" aktualisiert, SPEC §9 entsprechend ersetzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Erklärt in allen sieben Sprachen die Regel aus SPEC §5: ab T-Shirt-Größe M
sollte ein Element weiter untergliedert werden.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Erklärt in allen sieben Sprachen, dass der Schalter verworfene Knoten
samt Teilbaum ein-/ausblendet.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Neuer Icon-Toggle in der Kopfzeile (links vom Sprachumschalter). Aktiv
entfernt er linken/rechten Rand und die 1200px-Maximalbreite von Kopf,
Panel-Bereich und Fußzeile, sodass die Panels die ganze Fensterbreite
nutzen. Tooltip in allen sieben Sprachen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>