feat: Auf Touch öffnet der einfache Tipp das Knoten-Fenster (D52)
Ein `title` braucht einen Zeiger — auf dem Telefon war die Beschreibung (D40) damit gar nicht zu sehen, und seit D48 hängt an jedem der 172 Plan-Knoten eine. Der einfache Tipp zeigt jetzt denselben Inhalt als Fenster. Die eine echte Frage war der Link: Ein Knoten mit URL belegt den einfachen Klick vollständig (SPEC §6), ein Tipp kann nicht beides tun. Entschieden: Auf Touch öffnet der Tipp immer das Fenster, der Link steht darin als Knopf. Damit hat die Geste dort eine Bedeutung, und die Tooltips sind auf allen Knoten erreichbar. SPEC §6 bekommt dafür eine Touch-Ausnahme. Es hängt an den Touch-Ereignissen, nicht an einer Media Query — ein Gerät mit beidem verhält sich dadurch ohne Sonderfall richtig: Finger öffnet das Fenster, Maus öffnet den Link und zeigt den Tooltip. Die drei Touch-Gesten unterscheiden sich am vorhandenen Zustand, ohne neues Merkerfeld (armedEl gesetzt ⇒ Sprung, Timer läuft ⇒ Tipp, beides weg ⇒ gescrollt). Ausgenommen ist das Falt-Zeichen: Das Fenster braucht preventDefault(), das sonst den Falt-Klick verschluckt. Das Fenster nutzt, was ein `title` nicht kann: echte Trennlinie statt 24 `─` (der title wird an genau diesem Strich zerlegt, TIP_RULE exportiert — ein zweites data-Attribut hätte 20 kB DOM-Text verdoppelt), Absätze aus Leerzeilen statt harter Quell-Umbrüche, Knöpfe. Der Sprung-Hinweis nennt hier den langen Druck (neuer i18n-Schlüssel jumpHintTouch, plus tipClose und tipOpenLink, je 9 Sprachen). position:fixed auf <body>: in #out erbte es dessen zoom und würde von dessen overflow beschnitten (D50). Zu macht es alles, was seine Aussage hinfällig macht — Tipp daneben, zweiter Tipp, Esc, ×, Diagramm-Scroll, Bereichswechsel, Sprung in den Text, render(). Nachgemessen (375x812): Wurzelknoten 336x220 px ganz im Bild, ein Absatz ohne harte Umbrüche, Fakten mit Langdruck-Hinweis, Link-Knopf, Ring am Knoten, URL nicht geöffnet; Knoten ohne Beschreibung 39 px ohne Trennstrich; Spitze 0 px von der Knotenmitte. Echte Wischgeste (scrollLeft 0 -> 300) schließt. Schreibtisch unverändert: Klick öffnet den Link, Fenster bleibt zu. Plan: 150 Knoten, 0 Warnungen, 24 Stationen. 240 Tests grün. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b6e83b4f2a
commit
b2248c45bc
+60
-1
@@ -815,6 +815,64 @@
|
||||
/* Stationspunkt: groß, aber blass gefüllt — der Knotentext bleibt lesbar */
|
||||
.cheap-dot{fill:var(--or);fill-opacity:.2;stroke:var(--or);stroke-opacity:.35;stroke-width:1.5}
|
||||
|
||||
/* ---------- Knoten-Fenster für Touch (SPEC §6/§9, D52) ----------
|
||||
Auf einem Zeigergerät zeigt der `title` den Tooltip; ohne Zeiger gibt es
|
||||
keinen. Der einfache Tipp öffnet deshalb dieses Fenster mit demselben
|
||||
Inhalt — und mit dem, was ein `title` nicht kann: Absatz, echte Trennlinie,
|
||||
Knöpfe. `position:fixed` (JS setzt left/top aus `getBoundingClientRect()`,
|
||||
die den `zoom` von #out schon enthält): Ein Kind von #out erbte dessen
|
||||
`zoom` und würde von dessen `overflow` beschnitten (D50). */
|
||||
.nodetip{
|
||||
position:fixed;z-index:60;max-width:min(21rem, calc(100vw - 24px));
|
||||
background:var(--card);color:var(--ink);
|
||||
border:1px solid rgba(36,52,71,.15);border-radius:10px;
|
||||
box-shadow:0 8px 24px rgba(36,52,71,.3);
|
||||
padding:10px 30px 10px 12px;font-size:.78rem;line-height:1.45;
|
||||
}
|
||||
.nodetip[hidden]{display:none}
|
||||
.nodetip-x{
|
||||
position:absolute;top:2px;right:2px;width:26px;height:26px;
|
||||
display:flex;align-items:center;justify-content:center;
|
||||
background:none;border:0;border-radius:6px;cursor:pointer;
|
||||
color:var(--muted);font-size:1.05rem;line-height:1;
|
||||
}
|
||||
.nodetip-x:hover{color:var(--ink);background:rgba(36,52,71,.06)}
|
||||
/* Absätze kommen aus Leerzeilen der Notation (§1); JS baut sie zu <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}
|
||||
|
||||
Reference in New Issue
Block a user