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>
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>
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>
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>
- 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>
- 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>
- 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>
- 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>
- Feste Höhe von 28px für .zoomctl (collapsed und expanded)
- Padding für .zoomToggle angepasst auf 4px 8px (gleich wie andere Buttons)
- SVG-Größe auf 16x16 optimiert
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- 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>
Attached the `aria-labelledby` attribute to the editor textarea and added an ID to the editor title. Corrected the relative path for the script reference.
Removed redundant CSS fallbacks for mobile viewport height and replaced them with a streamlined `@supports` block to handle `dvh`-capable browsers. Clarified comments to reduce warnings and improve maintainability.
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.
"Claude Code" bleibt als Produktname unveraendert. Der Credit ist hartkodiert
(kein data-i18n) und damit wie zuvor sprachunabhaengig englisch — keine
Uebersetzungen betroffen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DEPLOY_TARGET wird jetzt aus der .env im Repo-Wurzelordner gelesen (die von der
bestehenden .gitignore-Regel ohnehin ignoriert wird; Vite liest sie nicht, da
dessen Env unter frontend/ liegt). scripts/deploy.env(.example) entfaellt; neue
Vorlage .env.example im Wurzelordner. Argument hat weiterhin Vorrang, ~ bleibt
fuer die Remote-Seite erhalten (kein source).
.gitignore: eigene scripts/deploy.env-Zeile zurueckgenommen, Kommentar an der
.env-Regel ergaenzt. README (de/en) entsprechend aktualisiert.
Lokal verifiziert: Fallback liest aus Wurzel-.env, .env ignoriert, .env.example
getrackt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ohne Ziel-Argument liest das Skript DEPLOY_TARGET aus scripts/deploy.env
(git-ignoriert; Vorlage scripts/deploy.env.example ist eingecheckt). Argument
hat weiterhin Vorrang.
Der Wert wird bewusst NICHT via `source` gelesen, weil bash bei `host:~/pfad`
die Tilde nach dem ':' lokal expandieren wuerde; stattdessen roh ausgelesen,
Whitespace/CR + umgebende Quotes gestrippt, das ~ bleibt fuer die Remote-Seite
erhalten. Lokal verifiziert: Fallback greift, ~ bleibt in unquoted/single-/
double-quoted erhalten (kein lokales $HOME), Quotes entfernt.
.gitignore: scripts/deploy.env ergaenzt (die vorhandene .env-Regel greift wegen
des abweichenden Dateinamens nicht). README (de/en) aktualisiert; Beispielpfad
auf die htdocs-ssl-Direktaufschaltung umgestellt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rsync --filter='protect /.well-known/***' bewahrt am Ziel liegende
.well-known-Dateien (Let's-Encrypt-Challenge waehrend einer Erneuerung) vor dem
--delete, obwohl sie nicht in der Quelle liegen. Verhindert die Race Condition,
dass ein Deploy eine laufende Zertifikatserneuerung abraeumt. Bedient
Hostsharing die Challenge ausserhalb des Docroots, ist es ein No-op.
Lokal verifiziert: .well-known/acme-challenge/testtoken ueberlebt den Deploy,
eine sonstige Alt-Datei wird weiterhin per --delete entfernt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mktemp -d legt das Staging-Verzeichnis mit 0700 an; rsync -a uebertrug diesen
Modus auf das Ziel-Verzeichnis, sodass der Webserver es nicht betreten konnte
(Apache 403 "Server unable to read htaccess file, denying access to be safe" —
die .htaccess-Suche selbst ist normal, der Zugriff scheiterte an den Rechten).
Fix: rsync mit --chmod=D755,F644, unabhaengig von lokalen mktemp-/umask-Rechten.
Lokal verifiziert: Ziel wird 755, Dateien 644 (auch wenn das Ziel vorher 700 war).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Im "Live ausprobieren"-Banner steht jetzt die stabile Prod-Instanz
https://werkbaum.javagil.de voran, der GitHub-Pages-Link bleibt als
"latest build 🚧" daneben. Der "gehosteter Editor"-Verweis im Fliesstext
zeigt ebenfalls auf die stabile Instanz. DE + EN.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>