diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md
index 580d119..b1ee742 100644
--- a/docs/DECISIONS.md
+++ b/docs/DECISIONS.md
@@ -3347,3 +3347,105 @@ synthetisches `.blur()` löst im Automaten keinen aus. Gegenprobe am
ebenfalls nichts, es ist also die Werkzeuggrenze und keine Regression. Dieselbe
Lehre wie in D25 und D17-Nachtrag 4 — was die Geräteumgebung stellt, beweist
der Emulator nicht.
+
+## D52 — Auf Touch öffnet der einfache Tipp das Knoten-Fenster, nicht den Link
+Die Beschreibungen (D40) lebten im `title` — und ein `title` braucht einen
+Zeiger. D40 hat das als bekannte Grenze notiert („auf Touch-Geräten gibt es
+keine Tooltips — dort bleibt der Text vorerst nur im `aria-label`; ein Pop-up
+kann später ergänzt werden"). Auf dem Telefon war die Beschreibung damit **gar
+nicht** zu sehen, und seit D48 hängt an jedem der 172 Plan-Knoten eine.
+
+**Die eine echte Frage war der Link.** Ein Knoten mit URL ist ein `` und
+belegt den einfachen Klick vollständig (§6, D6); ein Tipp kann nicht beides
+tun. Entschieden (Nutzer): **Auf Touch öffnet der Tipp immer das Fenster, und
+der Link steht darin als Knopf.** Damit hat die Geste dort **eine** Bedeutung —
+„ansehen" —, und die Tooltips sind auf **allen** Knoten erreichbar. Preis:
+SPEC §6 bekommt eine Touch-Ausnahme, und der Link kostet einen zweiten Tipp.
+
+**Verworfen:**
+- **Nur unverlinkte Knoten** — hätte §6 unangetastet gelassen, aber derselbe
+ Tipp hätte je nach Knoten Verschiedenes getan. Genau das hat D25 für diese
+ Geste ausdrücklich abgelehnt, und ausgerechnet die verlinkten Knoten (oft die
+ interessanten) wären ohne Beschreibung geblieben.
+- **Erster Tipp Fenster, zweiter Tipp Link** — spart den Knopf, führt aber eine
+ unsichtbare Zusatzregel ein: Nichts zeigt an, dass ein zweiter Tipp etwas
+ anderes tut.
+
+**Es hängt an den Touch-Ereignissen, nicht an einer Media Query.** Damit
+verhält sich ein Gerät mit **beidem** (Touch-Notebook) richtig, ohne
+Sonderfall: Der Finger öffnet das Fenster, die Maus öffnet weiterhin den Link
+und zeigt den Tooltip. Nachgemessen am Schreibtisch: Klick auf den verlinkten
+Wurzelknoten öffnet den Link, das Fenster bleibt zu, der `title` steht
+unverändert am Knoten.
+
+**Die drei Touch-Gesten unterscheiden sich am vorhandenen Zustand, ohne neues
+Merkerfeld.** Der lange Druck (D25) setzt nach 500 ms `armedEl`, und jedes
+`touchmove` räumt den Timer weg. Bei `touchend` gilt also: `armedEl` gesetzt ⇒
+Sprung; Timer läuft noch ⇒ kurzer Tipp ohne Wischen ⇒ Fenster; beides weg ⇒ es
+wurde gescrollt ⇒ nichts. **Ausgenommen ist das Falt-Zeichen** (D38): Der Tipp
+darauf muss weiter umklappen, und weil das Fenster `preventDefault()` braucht
+(sonst öffnete der Link-Knoten zusätzlich seine URL), hätte es den folgenden
+Klick sonst verschluckt — Falten wäre auf Touch unbedienbar geworden.
+Nachgemessen: Tipp auf das ▾ des Wurzelknotens 149 → 1 Knoten, kein Fenster.
+
+**Es ist ein Fenster, kein zweiter Tooltip — also nutzt es, was ein `title`
+nicht kann.** Der Trennstrich zwischen Beschreibung und Kurz-Fakten musste
+dort aus 24 `─` gebaut werden (D40-Nachtrag), weil `title` kein Markup kennt;
+hier ist er eine echte Linie, und ohne Beschreibung entfällt er ganz. Zerlegt
+wird der `title` **an genau diesem Strich** (`TIP_RULE`, jetzt exportiert). Die
+Alternative wäre ein zweites data-Attribut mit derselben Beschreibung gewesen —
+im Werkbaum-Plan rund 20 kB DOM-Text als reine Verdopplung.
+
+**Einzelne Zeilenumbrüche werden zu Leerzeichen, Leerzeilen zu Absätzen.** Das
+ist die Lesart von SPEC §1 („Leerzeilen bleiben als Absatztrenner"), und es war
+im Fenster sofort zu sehen: Die Beschreibungen im Plan sind bei ~76 Zeichen
+umgebrochen, und in einem 336 px breiten Fenster stand der Text dadurch
+ausgefranst („…a textual notation for work breakdown / structures, a browser
+editor…"). Der `title` zeigt die harten Umbrüche weiterhin — dort haben wir
+keine Wahl.
+
+**Der Sprung-Hinweis nennt hier den langen Druck.** Der Tooltip endet mit
+„Alt+Klick: zur Zeile im Text"; Alt gibt es auf dem Telefon nicht. Neuer
+i18n-Schlüssel `jumpHintTouch` in allen neun Sprachen, plus `tipClose` und
+`tipOpenLink`.
+
+**`position:fixed` auf ``, nicht in `#out`.** Ein Kind von `#out` erbte
+dessen CSS-`zoom` (der Fenstertext skalierte mit dem Diagramm) und würde von
+dessen `overflow` beschnitten — die Falle aus D50. Gesetzt wird aus
+`getBoundingClientRect()`, das den Zoom schon enthält; waagerecht an den
+Fensterrand geklemmt, nach oben ausweichend, wenn unten kein Platz ist. Die
+Spitze bleibt über `--tipx` am Knoten, auch wenn geklemmt wurde (nachgemessen:
+0 px Abweichung von der Knotenmitte im Normalfall).
+
+**Zu macht es alles, was seine Aussage hinfällig macht:** Tipp daneben, zweiter
+Tipp auf denselben Knoten, Esc, das ×, **Scrollen des Diagramms** (das Fenster
+ist `fixed`, der Knoten wandert — es zeigte danach auf etwas anderes), der
+**Bereichswechsel** auf Mobil (das Ziel ist dann `display:none`), der **Sprung
+in den Text** (er führt weg) und jeder **Neubau** (er ersetzt das Element, an
+dem es hängt). Die letzten drei fehlten in der ersten Fassung und fielen erst
+im Durchspielen auf.
+
+**Nachgemessen** (375 × 812, mitgelieferter Werkbaum-Plan): Tipp auf den
+Wurzelknoten öffnet 336 × 220 px vollständig im Bild, mit Beschreibung als
+einem Absatz ohne harte Umbrüche, Fakten `#wb · in Arbeit · Langer Druck: zur
+Zeile im Text` und Knopf „↗ Link öffnen"; der Knoten trägt den Petrol-Ring, die
+URL wird **nicht** geöffnet. Knoten ohne Beschreibung: nur die Faktenzeile,
+39 px, ohne Trennstrich. Zweiter Tipp, Esc, Tipp daneben und eine **echte**
+Wischgeste (`scrollLeft` 0 → 300) schließen; der lange Druck springt und
+schließt mit.
+
+**Werkzeuggrenze, wie in D25 und D17-Nachtrag 4:** Synthetische `TouchEvent`s
+beweisen nur die eigene Ereignis-Logik — dass der Tipp den Link unterdrückt,
+dass die drei Gesten auseinandergehalten werden, dass Position und Inhalt
+stimmen. Sie beweisen **nicht**, wie ein echter Finger mit dem 300-ms-Klick,
+dem Doppeltipp-Zoom und der Textauswahl des Systems zusammenspielt. Zwei
+Messungen liefen deshalb auffällig ins Leere und sind hier festgehalten, damit
+sie niemand für Befunde nimmt: Ein programmatisch gesetztes `scrollLeft` löste
+**kein** `scroll`-Ereignis aus (die D33-Falle — geprüft wurde daraufhin mit
+einer echten Wischgeste), und ein synthetischer Tipp trifft einen Knoten auch
+dann, wenn er 8968 px **außerhalb** des Bildes liegt — dort zeigte das Fenster
+folgerichtig auf nichts. Ein Finger kann das nicht.
+
+**Nicht im Druck** (`.nodetip` und der `.tipped`-Ring ausgeblendet) und nicht
+im Grafikexport — Bedienung, keine Aussage über den Plan; der Export liest
+ohnehin nur `#out`.
diff --git a/docs/SPEC.md b/docs/SPEC.md
index b7a70d5..de3387c 100644
--- a/docs/SPEC.md
+++ b/docs/SPEC.md
@@ -286,6 +286,11 @@ effektiv nicht weiter sein als das, was er braucht.
- Ein nacktes `https://…`-Token macht den ganzen Knoten klickbar
(neuer Tab, `rel="noopener"`); Kennzeichnung mit ↗ hinter dem Label.
+- **Ausnahme auf Touch-Geräten:** Dort öffnet der einfache Tipp nicht die URL,
+ sondern das Knoten-Fenster (§9) — der Link steht darin als eigener Knopf. Ohne
+ Zeiger gibt es keinen Tooltip, und ein einziger Tipp kann nicht beides tun;
+ „ansehen" ist die häufigere Absicht, und der Link bleibt einen Tipp entfernt.
+ Siehe D52.
## 7. Personen-Tags
@@ -330,6 +335,26 @@ spiegelt das `"`-Zeichen der Notation. Die Marke erscheint **nicht** im
Grafikexport: Der Text selbst kann dort nicht angezeigt werden, eine Marke
ohne Ziel wäre Rauschen. Siehe D40.
+**Auf Touch-Geräten zeigt der einfache Tipp auf einen Knoten dasselbe als
+Fenster** — ohne Zeiger gibt es keinen Tooltip, die Beschreibung wäre dort sonst
+gar nicht zu sehen. Es ist derselbe Inhalt, nur mit dem, was ein `title` nicht
+kann: Die Beschreibung steht als Absatz, die Kurz-Fakten dahinter durch eine
+echte Linie abgesetzt.
+
+- Das Fenster hängt am angetippten Knoten (kleine Spitze zu ihm hin) und weicht
+ nach oben aus, wenn unten kein Platz ist. Der Knoten trägt, solange es offen
+ ist, einen Petrol-Ring.
+- Es schließt beim Tipp daneben, beim erneuten Tipp auf denselben Knoten, mit
+ **Esc**, über sein ×, beim Scrollen des Diagramms und bei jedem Neubau.
+- Ein **verlinkter** Knoten (§6) bekommt darin einen ↗-Knopf, der die URL im
+ neuen Tab öffnet — auf Touch ist das der Weg zum Link.
+- Der **Sprung-Hinweis** nennt hier den langen Druck statt Alt+Klick (§9,
+ Sprung zwischen Diagramm und Text) — Alt gibt es auf dem Telefon nicht.
+- Reine Bedienhilfe: nicht im Grafikexport, nicht im Druck. Auf Geräten mit
+ Zeiger ändert sich nichts, dort bleibt es beim Tooltip.
+
+Siehe D52.
+
**Die Knotenfarbe zeigt den effektiven Status (§4)**, nicht den intrinsischen —
das Diagramm beantwortet „wie weit ist das wirklich?“. Wo der eigene Status
**weiter** ist als der effektive (der Knoten wird von Abhängigkeiten
diff --git a/docs/examples/werkbaum.werkbaum b/docs/examples/werkbaum.werkbaum
index 6826b82..1765751 100644
--- a/docs/examples/werkbaum.werkbaum
+++ b/docs/examples/werkbaum.werkbaum
@@ -59,6 +59,7 @@
- [^] #ed.i18n.auto: Default taken from the browser (XS)
- [^] #ed.a11y: Accessibility: aria labels, focus order (S)
- [^] #ed.mobile: Works on a phone (S)
+ - [x] #ed.mobile.tip: A tap on a node opens its tooltip as a window (XS) %% no pointer, no tooltip
- [^] #ed.docs: Several documents in one editor (M)
- [^] #ed.docs.picker: Switcher in the editor title bar (S)
- [^] #ed.docs.url: Load a document from ?sourceUrl= (S)
@@ -441,6 +442,11 @@
Below 640 px exactly one area is visible, diagram or text, and a button
switches between them. Any split would leave both halves too small to use.
+#ed.mobile.tip
+ A tooltip needs a pointer, so without one the description could not be seen
+ at all. A tap opens the same content as a window instead; on a linked node
+ the link becomes a button inside it, because one tap cannot do both.
+
#ed.docs
Several notation texts side by side, kept in the browser. Each is only text
plus a name — no invented structure format, so this maps onto a server later
diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md
index 6871717..cf9f608 100644
--- a/frontend/CLAUDE.md
+++ b/frontend/CLAUDE.md
@@ -532,3 +532,16 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
(das einzige Element ohne feste Größe) auf einen 2-px-Strich, während sein
Icon darüber hinausragt. Das sieht aus wie ein Trennstrich und ist
unbenutzbar.
+- **Die drei Touch-Gesten am Knoten (D25, D38, D52)** teilen sich `touchstart`/
+ `touchend` und werden am vorhandenen Zustand unterschieden: `armedEl` gesetzt
+ (500 ms um) ⇒ Sprung, Timer läuft noch ⇒ kurzer Tipp ⇒ Knoten-Fenster, beides
+ weg (jedes `touchmove` räumt auf) ⇒ es wurde gescrollt ⇒ nichts. Kein eigenes
+ Merkerfeld nötig. Wer hier eine vierte Geste einhängt, denkt an das
+ **Falt-Zeichen**: Es ist ausgenommen, weil das Fenster `preventDefault()`
+ braucht (sonst öffnet ein Link-Knoten zusätzlich seine URL) — und das
+ verschluckt den Klick, mit dem gefaltet wird.
+- **Das Knoten-Fenster liegt auf ``, nicht in `#out` (D52):** In `#out`
+ erbte es dessen CSS-`zoom` und würde von dessen `overflow` beschnitten (D50).
+ Es schließt bei allem, was seine Aussage hinfällig macht — Tipp daneben,
+ zweiter Tipp, Esc, ×, Diagramm-Scroll, Bereichswechsel, Sprung in den Text,
+ `render()`. Die letzten drei sind beim Bauen zuerst vergessen worden.
diff --git a/frontend/index.html b/frontend/index.html
index d8dc943..6979134 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -229,6 +229,16 @@
+
+ ${esc(p)}
. */ + .nodetip-desc p + p{margin-top:.55em} + /* Die echte Linie an der Stelle, an der der Tooltip 24 `─` zeichnen musste. */ + .nodetip-facts{ + margin-top:8px;padding-top:7px;border-top:1px solid rgba(36,52,71,.15); + color:var(--muted);font-size:.72rem; + } + /* Ohne Beschreibung gibt es nichts zu trennen — der Strich stünde sonst als + erste Zeile im Fenster. Dieselbe Regel wie im Tooltip (D40-Nachtrag). */ + .nodetip-facts:first-child{margin-top:0;padding-top:0;border-top:0} + .nodetip-link{ + display:inline-flex;align-items:center;gap:5px;margin-top:9px; + padding:5px 10px;border:1px solid var(--or);border-radius:7px; + color:var(--or);text-decoration:none;font-size:.74rem;font-weight:500; + } + /* Die Spitze zeigt auf den Knoten — ohne sie wäre bei dicht stehenden Knoten + nicht zu sehen, welcher gemeint ist. Ein gedrehtes Quadrat mit zwei Kanten: + so erbt es Rahmen UND Schatten des Fensters. JS setzt --tipx (Spitze) und + dreht sie per .above nach unten, wenn das Fenster über dem Knoten sitzt. */ + .nodetip-arrow{ + position:absolute;top:-6px;left:var(--tipx, 50%);width:11px;height:11px; + margin-left:-5.5px;background:var(--card); + border-left:1px solid rgba(36,52,71,.15); + border-top:1px solid rgba(36,52,71,.15); + transform:rotate(45deg); + } + .nodetip.above .nodetip-arrow{ + top:auto;bottom:-6px; + border:0;border-right:1px solid rgba(36,52,71,.15); + border-bottom:1px solid rgba(36,52,71,.15); + } + /* Solange das Fenster offen ist, trägt sein Knoten einen Petrol-Ring — wie + der „scharfe" Knoten beim langen Druck (D25). #out-Präfix nötig, weil + `ul.or .node{box-shadow:none}` spezifischer ist. */ + #out .node.tipped{box-shadow:0 0 0 3px rgba(15,118,110,.55)} + /* --- ALL OF: Kinder nebeneinander, durchgezogener Verteiler --- */ ul.and{display:flex;align-items:flex-start;position:relative;padding-top:14px} ul.and::before{ @@ -1210,7 +1268,7 @@ @media print{ html,body{height:auto!important;overflow:visible!important;background:#fff!important} header,.panel.editor,.gutter,.panel.right .panel-head, - .warnings,.zoomctl,.site-footer{display:none!important} + .warnings,.zoomctl,.site-footer,.nodetip{display:none!important} .app,.app.side{display:block!important;max-width:none!important;width:auto!important; height:auto!important;margin:0!important;gap:0!important} .panel.right{grid-area:auto!important;background:#fff!important;border:0!important; @@ -1228,6 +1286,7 @@ .node.current{transform:none!important;animation:none!important} .node.current::after{display:none!important} .node.fresh{box-shadow:none!important} /* „neu seit dem letzten Besuch" ist persönlich (D28) */ + .node.tipped{box-shadow:none!important} /* offenes Knoten-Fenster ist Bedienung (D52) */ /* Faltung (D38): das ▾ offener Knoten ist Bedienelement — nicht drucken; das „▸ n" eingeklappter Knoten ist Kennzeichnung und bleibt. */ .node:not(.folded) .fold{display:none!important}