feat: Cursor-Zeile hebt sich aus der Ebene, plus Puls beim Zeilenwechsel

Die Hervorhebung der Cursor-Zeile (D25) war zu leise. Sie benutzte denselben
Kanal, den schon jeder Knoten belegt — jeder Status hat einen Rahmen (SPEC §4);
ein weiterer Ring darunter ist ein Unterschied im Grad, nicht in der Art.

Dazu kommt jetzt Tiefe: Schlagschatten + scale(1.04). Der einzige Kanal, den im
Diagramm noch nichts belegt, also ohne Konflikt mit einer Farbcodierung. Um die
Mitte skaliert, damit die Knotenmitte erhalten bleibt (alignStems, Stationspunkte
messen genau die — nachgemessen dx=dy=0). Beim Zeilenwechsel meldet sie sich
zusätzlich mit einem einmaligen Puls (Hüpfer + auslaufender Ring auf ::after);
kein Blinken, prefers-reduced-motion schaltet ihn ab.

Behoben dabei: Die Pfad-Inversion (D18) blasste den Ring auf 0,32 aus — die
Ausnahme, die .fresh (D28) und .focusmark (D32) längst haben, fehlte für
.current als einziger, obwohl der Fall der häufigste ist (Umschalter default an,
im Beispiel 7 von 18 Knoten betroffen).

diagramToSvg() muss die Erhebung abschalten (Klasse `exporting`): Der Export
zieht die Live-Geometrie per getBoundingClientRect() nach, anders als beim
box-shadow schlägt eine Vergrößerung dort durch. Nachgemessen: 155,6 statt
161,9 px. Im Druck fällt beides ebenso weg.

SPEC §9 und D25 (Nachtrag) nachgezogen; llms.md unberührt (Notation, keine
Editor-UI, D43).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-23 07:24:04 +02:00
co-authored by Claude Fable 5
parent 618149a36d
commit 099ee87bc1
5 changed files with 190 additions and 17 deletions
+76
View File
@@ -634,6 +634,82 @@ weiter, Alt+Enter zurück in die Zeile.
Umbruch. Auf einer Zeile ohne Knoten (Kommentar, Leerzeile, ausgeblendetes
Verworfenes) geschieht nichts — dieselbe stille Regel wie bei der Cursor-Zeile.
**Nachtrag — die Cursor-Zeile hebt sich jetzt aus der Ebene, und die fehlende
Ausnahme gegen die Pfad-Inversion.** Gemeldet als „müsste etwas deutlicher
sein". Beim Nachsehen kam zuerst etwas anderes heraus, das keine
Gestaltungsfrage ist:
**Auf einem guten Drittel der Knoten war der Ring gar nicht zu sehen.** Die
Pfad-Inversion (D18) setzt `.cheap-on .node:not(.cheap){opacity:.32;
filter:saturate(.4)}` — und das trifft den `box-shadow` mit. Genau diese Falle
haben D28 (gelber Kranz) und D32 (Fokusmarke) je für sich gefunden und mit
einer Ausnahmeregel behoben; `.current` hat seine nie bekommen. Gemessen im
mitgelieferten Beispiel mit dem Cursor auf `+ [?] Dark mode`: Deckkraft 0,32.
Der Fall ist zudem der häufigste der drei — der Pfad-Umschalter ist
voreingestellt an, und jeder optionale Knoten und jede nicht gewählte
Alternative fällt darunter (im Beispiel 7 von 18 Knoten). Anders als beim
optionalen Knoten (D29), wo das Zurücktreten die **Aussage** ist, wird hier
überhaupt keine Aussage über den Plan gemacht: Es ist eine Editierhilfe, und wo
der Cursor steht, muss sichtbar bleiben, egal wie der Pfad entschieden hat.
**Warum der Ring auch ungedimmt leise wirkt:** Er benutzt denselben Kanal, den
schon jeder Knoten belegt — **jeder Status hat einen Rahmen** (SPEC §4). Ein
weiterer Ring in einem Feld aus lauter gerahmten Kästchen ist ein Unterschied
im Grad, nicht in der Art. Die beiden Strahlenkränze entkommen dem, weil sie
einen Kanal benutzen, den sonst nichts hat (Leuchten nach außen); die
Cursor-Zeile war auf dem Rahmen-Kanal sitzen geblieben.
**Gewählt: Tiefe** — Ring behalten, dazu Schlagschatten und `scale(1.04)`. Der
Knoten hebt sich aus der Ebene. Das ist der einzige Kanal, den im Diagramm noch
gar nichts belegt (nichts anderes wirft Schatten oder bewegt sich), kollidiert
also mit **keiner** Farbcodierung und wirkt über allen acht Statusfarben
gleich. Zwei angenehme Eigenschaften, beide nachgemessen: `transform` ändert
kein Layout (die Linien bleiben stehen), und weil um die **Mitte** skaliert
wird, bleibt die Knotenmitte punktgenau erhalten (dx = dy = 0) — `alignStems()`
(D29) und die Stationspunkte des günstigsten Pfads (D18) messen genau die und
bleiben unberührt. Nur `drawDepLinks()` (D41) setzt auf Knoten**kanten** auf und
verschiebt sich für diesen einen Knoten um ~4 px; das ist flüchtig und fällt
nicht auf. Ein Spalt zur Anschlusslinie entsteht nicht — der Knoten wächst
darüber, statt sich zurückzuziehen.
**Dazu ein einmaliger Puls beim Zeilenwechsel:** Man verliert den Knoten beim
**Bewegen**, nicht im Stillstand — also meldet er sich genau dann einmal, mit
einem kurzen Hüpfer und einem auslaufenden Ring. Kein WCAG-Problem: 2.2.2 zielt
auf Blinkendes, 2.3.1 auf Flackern über 3 Hz, ein einzelner Durchlauf ist
keines von beidem (dieselbe Prüfung wie in D28); `prefers-reduced-motion`
schaltet ihn ab. Ausgelöst wird er an derselben Bedingung, an der schon das
Scrollen hängt (`caretLine` hat sich geändert) — sonst pulste er bei jedem
Tastendruck. Bewusst **nicht** über `box-shadow` animiert: Die Kombinationen
mit `.fresh` und `.focusmark` haben je eigene Schatten-Listen, eine Animation
darauf ließe den gelben bzw. petrolfarbenen Kranz für die Dauer des Pulses
verschwinden. Stattdessen `transform` plus das freie `.node::after`
(`::before` gehört dem Optional-Kreis, D29).
**Der Export brauchte eine eigene Behandlung** — und das ist die Stelle, an der
die Erhebung anders liegt als der Ring. D25 konnte sich darauf verlassen, dass
`diagramToSvg()` nie `box-shadow` ausliest; die Vergrößerung schlägt aber über
`getBoundingClientRect()` durch, mit dem der Export die Live-Geometrie nachzieht
— genau ein Knoten stünde 4 % zu groß im Bild. Während des Messens trägt `#out`
deshalb die Klasse `exporting`, die Erhebung und Puls neutralisiert.
Nachgemessen: 155,6 statt 161,9 px, also die unskalierte Breite. Per Klasse
statt durch Abnehmen von `.current`/`.pulse`, damit der Export keine laufende
Animation abreißt und hinterher neu startet. Im Druck fällt beides ebenso weg.
**Verworfene Alternativen:** ein **dritter Strahlenkranz** (ein dunkles
Tinte-Leuchten liest sich auf hellem Grund als Schatten — die Lehre steht schon
im D32-Nachtrag —, und ein heller Schein bräuchte eine dritte Signalfarbe neben
Gelb und Teal); **Invertieren** des Knotens auf Tinte-Füllung mit weißer Schrift
(das stärkste Signal, kostet aber für die Cursor-Zeile die Statusfarbe — genau
die Regel, wegen der D28 und D32 ihre Kränze nach außen gelegt haben, und für
eine Editierhilfe wäre sie schlecht gebrochen); ein **Zeiger-Dreieck** links am
Knoten (`::after` wäre frei, bräuchte aber wie der Optional-Kreis eigene
Geometrie für alle drei Darstellungsmodi); und **die Umgebung zurücktreten
lassen** (flackerte bei jedem Pfeiltastendruck durch den ganzen Baum).
Nebenbefund beim Aufräumen: Der Kommentar über der Regel behauptete noch, die
Fokusmarke `!!!` trage „bewusst DIESELBE Hervorhebung" — überholt, seit der
D32-Nachtrag ihr den eigenen Petrol-Kranz gegeben hat. Ersetzt.
## D26 — Legende scrollbar: eigener Container statt `<details>`, plus Splitter
Die Legende („Agenda") im Editor-Panel war zu hoch für ihren Platz und wurde
**abgeschnitten** statt scrollbar zu sein — obwohl `.hint` seit jeher
+11 -3
View File
@@ -556,9 +556,17 @@ verknüpft (siehe D25):
„hinschauen": Er holt **keine Bildschirmtastatur** herauf — die erscheint erst,
wenn das Textfeld selbst angetippt wird.
- **Text → Diagramm:** Der Knoten der **Cursor-Zeile** wird im Diagramm
hervorgehoben (weißer Halo + Ring in Tinte) und beim Zeilenwechsel ins Bild
gescrollt. Zeilen ohne Knoten (Kommentar, Leerzeile, ausgeblendetes
verworfenes Element) heben nichts hervor.
hervorgehoben und beim Zeilenwechsel ins Bild gescrollt. Zeilen ohne Knoten
(Kommentar, Leerzeile, ausgeblendetes verworfenes Element) heben nichts
hervor. Die Hervorhebung arbeitet auf einer **eigenen Achse — Tiefe**: weißer
Halo + Ring in Tinte, dazu ein Schlagschatten und eine leichte Vergrößerung,
sodass der Knoten sich aus der Ebene hebt. Das ist der einzige Kanal, den
sonst nichts im Diagramm belegt, kollidiert also mit keiner Farbcodierung
(Status §4, gelber Kranz und Petrol-Kranz oben). **Beim Zeilenwechsel** meldet
sie sich zusätzlich mit einem **einmaligen Puls** — einem kurzen Hüpfer und
einem auslaufenden Ring; kein Blinken, und bei `prefers-reduced-motion`
entfällt er. Der Pfad-Filter (§9, günstigster Pfad) blasst sie nie aus: Wo der
Cursor steht, bleibt sichtbar. Siehe D25.
- **Text → Diagramm, ausdrücklich:** **Alt+Klick** im Textfeld (Tastatur:
**Alt+Enter**) holt den Knoten der Cursor-Zeile in die **Mitte** des Diagramms
und gibt ihm den Tastaturfokus — dieselbe Geste in beide Richtungen. Sie
+16 -1
View File
@@ -211,7 +211,22 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
`syncCaret()` setzt die Klasse `current` auf den Knoten der Cursor-Zeile;
`render()` stellt sie nach jedem Neubau wieder her (ohne zu scrollen). Die
CSS-Regel braucht den `#out`-Präfix (`ul.or .node{box-shadow:none}` ist
spezifischer). Auffindbarkeit: `setAltMode()` setzt bei gedrückter Alt-Taste
spezifischer) **und** — wie `.fresh`/`.focusmark` — die Ausnahme
`.cheap-on .node:not(.cheap).current{opacity:1;filter:none}`; sie fehlte lange
als einzige, obwohl der Fall der häufigste ist (Pfad-Umschalter default an,
jeder `+`-Knoten und jede nicht gewählte Alternative betroffen).
Zum Ring kommen **Schlagschatten + `scale(1.04)`** (D25-Nachtrag): Tiefe ist der
einzige noch freie Kanal. Um die **Mitte** skalieren ist Bedingung — `alignStems()`
und die Stationspunkte messen die Knotenmitte, die dadurch unverändert bleibt.
**`diagramToSvg()` muss die Erhebung abschalten** (Klasse `exporting` an `#out`,
am Ende wieder ab): Der Export zieht die Live-Geometrie per
`getBoundingClientRect()` nach, anders als beim `box-shadow` schlägt die
Vergrößerung dort durch. Der **Puls** (`pulse`, Hüpfer + Ring auf dem freien
`.node::after`) wird nur bei geändertem `caretLine` gesetzt — sonst pulst es bei
jedem Tastendruck — und braucht das Lesen von `offsetWidth` als Neustart-Trick,
weil dieselbe Aufgabe die Klasse vorher entfernt. Nicht über `box-shadow`
animieren: Das löschte für die Dauer des Pulses den gelben bzw. Petrol-Kranz der
Kombinationen. Auffindbarkeit: `setAltMode()` setzt bei gedrückter Alt-Taste
die Klasse `alt` an `#out` (Cursor + Ring am Knoten unter dem Zeiger) — der
`blur`-Handler ist Pflicht, sonst bleibt der Modus nach Alt+Tab hängen; dazu
`jumpHint` im Knoten-Tooltip und `hint_jump` als letzte Zeile der Legende.
+21 -4
View File
@@ -394,6 +394,13 @@ out.addEventListener('focusout', () => setTimeout(drawDepLinks, 0));
(und = durchgezogen Tinte, oder = gestrichelt Grau) neu gezogen und treffen
so garantiert die Knoten unabhängig vom Darstellungsmodus. */
function diagramToSvg(){
/* Der Export misst die **Live-Geometrie**. Den Ring der Cursor-Zeile liest er
nie aus (`box-shadow` steht nicht in der Liste), ihre Erhebung
(D25-Nachtrag) schlüge aber über `getBoundingClientRect()` durch und
exportierte genau einen Knoten 4 % zu groß. Neutralisiert wird sie per
Klasse statt durch Abnehmen von `.current`/`.pulse` so reißt der Export
keine laufende Puls-Animation ab und startet sie hinterher nicht neu. */
out.classList.add('exporting');
const treeRect = out.getBoundingClientRect();
const PAD = 24;
const W = Math.ceil(treeRect.width) + PAD*2;
@@ -570,6 +577,7 @@ function diagramToSvg(){
});
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}" font-family="'IBM Plex Sans',system-ui,sans-serif">${parts.join('')}</svg>`;
out.classList.remove('exporting');
return {svg, W, H};
}
function svgToPng(svg, W, H, scale){
@@ -925,9 +933,9 @@ out.addEventListener('touchcancel', disarmPress);
out.addEventListener('contextmenu', e => { if(pressTimer || armedEl) e.preventDefault(); });
/* Text -> Diagramm: Knoten der Cursor-Zeile hervorheben (`caretLine` steht oben). */
function highlightCurrentNode(scroll){
function highlightCurrentNode(moved){
markCurrentLineNo(); /* die eine Stelle, an der die Cursor-Zeile neu gesetzt wird */
if(currentNodeEl) currentNodeEl.classList.remove('current');
if(currentNodeEl) currentNodeEl.classList.remove('current', 'pulse');
currentNodeEl = caretLine == null
? null
: out.querySelector('.node[data-line="' + caretLine + '"]');
@@ -936,8 +944,17 @@ function highlightCurrentNode(scroll){
/* Die Cursor-Zeile ist die zweite Lesart von ausgewählt" ihre
Abhängigkeits-Kanten hervorheben (D41). */
drawDepLinks();
/* Nur beim Zeilenwechsel scrollen, sonst ruckelte das Diagramm beim Tippen. */
if(scroll) currentNodeEl.scrollIntoView({block:'nearest', inline:'nearest', behavior:'smooth'});
/* Beides nur beim **Zeilenwechsel**: Scrollen ruckelte sonst bei jedem
Tastendruck, und der Puls (D25-Nachtrag) flackerte beim Tippen. */
if(!moved) return;
/* Neustart der Animation erzwingen: Steht der Cursor wieder auf demselben
Knoten (Zeile mit Knoten -> Zeile ohne -> zurück), wurde `pulse` oben in
DERSELBEN Aufgabe entfernt der Browser sieht dann keinen Klassenwechsel
und startet nichts. Das Lesen von `offsetWidth` erzwingt den Zwischenstand. */
currentNodeEl.classList.remove('pulse');
void currentNodeEl.offsetWidth;
currentNodeEl.classList.add('pulse');
currentNodeEl.scrollIntoView({block:'nearest', inline:'nearest', behavior:'smooth'});
}
function caretLineOf(){
return src.value.slice(0, src.selectionStart).split('\n').length;
+66 -9
View File
@@ -578,11 +578,21 @@
im Druck. Der `#out`-Präfix ist nötig: `ul.or .node{box-shadow:none}`
(weiter unten) ist spezifischer als `.node.current` und schluckte den Ring
sonst überall unterhalb einer any-of-Gruppe. */
/* Die Fokusmarke `!!!` (SPEC §1) trägt bewusst DIESELBE Hervorhebung: Es gibt
nur einen Begriff hier schauen", und ein dritter Ring neben Fokusring,
Strahlenkranz und Cursor-Ring wäre ein Zeichen zu viel. Der Unterschied
steht im `aria-label`. */
#out .node.current{box-shadow:0 0 0 2px var(--card),0 0 0 4px var(--ink)}
/* Der Ring allein war zu leise (D25-Nachtrag): Er benutzt denselben Kanal, den
schon jeder Knoten belegt **jeder Status hat einen Rahmen** (SPEC §4). Ein
weiterer Ring in einem Feld aus lauter gerahmten Kästchen ist ein Unterschied
im Grad, nicht in der Art. Deshalb kommt **Tiefe** dazu: Schlagschatten plus
leichte Vergrößerung. Das ist der einzige Kanal, den im Diagramm noch nichts
belegt (nichts anderes wirft Schatten oder hebt sich), kollidiert also mit
keiner Farbcodierung und wirkt über allen acht Statusfarben gleich.
`transform` ändert **kein Layout** die Linien bleiben stehen; und weil um
die **Mitte** skaliert wird, bleibt auch die Knotenmitte unverändert, auf die
`alignStems()` und `drawCheapPath()` messen. `z-index`, weil Schatten und
vergrößerter Knoten AUSSERHALB der Box liegen (dasselbe wie bei `.fresh`). */
#out .node.current{
box-shadow:0 0 0 2px var(--card),0 0 0 4px var(--ink),0 10px 20px -6px rgba(36,52,71,.5);
transform:scale(1.04);z-index:3;
}
/* Fokusmarke `!!!` (SPEC §1, D32): **Strahlenkranz in Petrol**, nach dem Muster
der Neuheiten-Markierung (D28), nur in der Akzentfarbe der App statt in Gelb.
Der geteilte Ring mit der Cursor-Zeile war zu leise das erkennt man zu
@@ -598,8 +608,10 @@
obwohl die Geometrie dieselbe war. Der Ring bleibt dunkles Petrol und ordnet
die Marke der Akzentfarbe zu; das Leuchten macht die Reichweite. */
#out .node.focusmark{box-shadow:0 0 0 3px var(--or),0 0 20px 7px rgba(20,184,166,.85);z-index:2}
/* Beides zugleich: Cursor-Zeile innen (Tinte), fremde Marke außen (Petrol). */
#out .node.focusmark.current{box-shadow:0 0 0 2px var(--card),0 0 0 4px var(--ink),0 0 20px 7px rgba(20,184,166,.85)}
/* Beides zugleich: Cursor-Zeile innen (Tinte), fremde Marke außen (Petrol).
Die Erhebung der Cursor-Zeile gilt in jeder Kombination der Schlagschatten
wird deshalb hier mit angehängt (das `transform` erbt die Regel oben). */
#out .node.focusmark.current{box-shadow:0 0 0 2px var(--card),0 0 0 4px var(--ink),0 0 20px 7px rgba(20,184,166,.85),0 10px 20px -6px rgba(36,52,71,.5);z-index:3}
/* Neu in Produktion seit dem letzten Besuch (D28): gelber Strahlenkranz um den
Knoten. Bewusst ein Schein nach AUSSEN statt Farbe im Knoten die Füllung
gehört dem Status (SPEC §4) und bleibt lesbar. Kein Blinken: WCAG 2.2.2/2.3.1
@@ -610,13 +622,44 @@
Kante stehen sieht aus wie ein halber Hintergrund statt eines Rahmens). */
#out .node.fresh{box-shadow:0 0 0 2px #FACC15,0 0 16px 5px rgba(234,179,8,.65);z-index:2}
/* Beides zugleich: Cursor-Zeile innen (Tinte), Neuheit außen (gelb). */
#out .node.fresh.current{box-shadow:0 0 0 2px var(--card),0 0 0 4px var(--ink),0 0 18px 6px rgba(234,179,8,.65)}
#out .node.fresh.current{box-shadow:0 0 0 2px var(--card),0 0 0 4px var(--ink),0 0 18px 6px rgba(234,179,8,.65),0 10px 20px -6px rgba(36,52,71,.5);z-index:3}
/* Neu in Produktion UND jemand zeigt darauf: Ring in Petrol (der bewusste
Zuruf, innen), Kranz in Gelb (die stehende Nachricht, außen). Zwei Scheine
nach außen gingen nicht einer muss der Ring sein. Steht bewusst **nach**
`.node.focusmark.current`: gleiche Spezifität (drei Klassen), und wenn alles
drei zutrifft, soll Zuruf + Neuheit gewinnen, nicht die eigene Cursor-Zeile. */
#out .node.fresh.focusmark{box-shadow:0 0 0 3px var(--or),0 0 20px 7px rgba(234,179,8,.65);z-index:2}
/* Puls beim Zeilenwechsel (D25-Nachtrag): Man verliert den Knoten beim
**Bewegen**, nicht im Stillstand also meldet er sich genau dann einmal.
Einmalig, kein Blinken: WCAG 2.2.2 zielt auf Blinkendes, 2.3.1 auf Flackern
über 3 Hz; ein einzelner Durchlauf ist keins von beidem (vgl. D28).
Ausgelöst wird er in `highlightCurrentNode()` **nur** bei geändertem
`caretLine` sonst pulste er bei jedem Tastendruck.
Bewusst NICHT über `box-shadow` animiert: die Kombinationen mit `.fresh` und
`.focusmark` haben je eigene Schatten-Listen, eine Animation darauf ließe den
gelben bzw. petrolfarbenen Kranz für die Dauer des Pulses verschwinden.
Stattdessen zwei Kanäle, die niemand sonst benutzt: ein kurzer Hüpfer im
`transform` und ein auslaufender Ring auf dem freien `::after`
(`::before` gehört dem Optional-Kreis, D29). */
@keyframes nodeLift{0%{transform:scale(1.04)}40%{transform:scale(1.11)}100%{transform:scale(1.04)}}
@keyframes nodeRipple{from{transform:scale(1);opacity:.5}to{transform:scale(1.4);opacity:0}}
#out .node.current.pulse{animation:nodeLift .36s ease-out 1}
/* `both` ist Pflicht: ohne Fill-Mode schnappt der Ring am Ende auf die
Anfangsdeckkraft zurück und bliebe stehen. */
#out .node.current.pulse::after{
content:'';position:absolute;inset:-3px;border-radius:calc(var(--r) + 3px);
border:2px solid var(--ink);pointer-events:none;
animation:nodeRipple .45s ease-out 1 both;
}
@media (prefers-reduced-motion: reduce){
#out .node.current.pulse{animation:none}
#out .node.current.pulse::after{display:none}
}
/* Während `diagramToSvg()` misst: Erhebung und Puls abschalten der Export
zeichnet aus der Live-Geometrie nach, und die Vergrößerung ist eine
Editierhilfe, keine Aussage über den Plan (D25). */
#out.exporting .node.current{transform:none;animation:none}
#out.exporting .node.current::after{display:none}
/* Alt gedrückt = Sprung-Geste scharf: Cursor an allen Knoten, Petrol-Ring am
Knoten unter dem Zeiger. Auf verlinkten Knoten ist das die einzige
Rückmeldung, weil dort der einfache Klick dem Link gehört (D25). */
@@ -696,6 +739,16 @@
der wahrscheinlichsten Gründe, überhaupt zu zeigen. Anders als beim
optionalen Knoten (D29), wo das Zurücktreten die Aussage IST. */
.cheap-on .node:not(.cheap).focusmark{opacity:1;filter:none}
/* Und dasselbe für die Cursor-Zeile (D25-Nachtrag) die Ausnahme fehlte hier
als einzige, obwohl der Fall der häufigste ist: Der Umschalter ist
voreingestellt an, und jeder optionale Knoten und jede nicht gewählte
Alternative ist nicht auf dem Pfad" (im mitgelieferten Beispiel 7 von 18
Knoten). Gemessen auf `+ [?] Dark mode`: Deckkraft 0,32 der Ring war dort
praktisch unsichtbar. Wo der Cursor steht, muss sichtbar bleiben, egal wie
der Pfad entschieden hat; anders als beim optionalen Knoten (D29), wo das
Zurücktreten die Aussage IST, ist hier gar keine Aussage über den Plan
gemeint es ist eine Editierhilfe. */
.cheap-on .node:not(.cheap).current{opacity:1;filter:none}
/* implizit als M angenommene Größe: invertiertes Badge (weiß statt petrol) */
.size.implicit{background:var(--card);color:var(--or);border-color:var(--or)}
/* Günstigster-Pfad-Linie: gestrichelt, geschwungen, petrol fädelt durch
@@ -1078,8 +1131,12 @@
*{-webkit-print-color-adjust:exact!important;print-color-adjust:exact!important}
/* Knoten nicht über den Seitenrand zerschneiden */
#out li{break-inside:avoid}
/* Editierhilfe bzw. Zuruf, nicht drucken (D25, Fokusmarke SPEC §1) */
/* Editierhilfe bzw. Zuruf, nicht drucken (D25, Fokusmarke SPEC §1).
Bei der Cursor-Zeile gehören Erhebung und Puls mit dazu sonst stünde ein
Knoten im Druck grundlos vergrößert und schief zu seiner Anschlusslinie. */
.node.current,.node.focusmark{box-shadow:none!important}
.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) */
/* Faltung (D38): das offener Knoten ist Bedienelement nicht drucken;
das n" eingeklappter Knoten ist Kennzeichnung und bleibt. */