Post 2: Slide 3 und 4 gezeichnet, altes Layout-CSS raus

Damit sind alle sechs Slides im selben Stil. Slide 1 bleibt Noahs Foto,
das ist Absicht: ein echtes Gesicht zwischen fuenf Zeichnungen ist ein
Kontrast, kein Bruch.

Slide 3 hat zwei Haelften im Fliesstext, und beide brauchten ein Bild.
"Jahre an Daten und Wissen haengen drin" wurde zu Wurzeln im Boden, "am
Ende dasselbe, nur woanders" zu demselben Kasten noch einmal, nur
gestrichelt. Das leere Ziel der alten Fassung war schlicht die falsche
Aussage. Der Bruch sitzt weiterhin auf dem Weg und nicht auf dem Ziel,
nur ist aus dem Kreuz eine gerissene Leine geworden.

Zwei Anlaeufe waren dafuer noetig. Die Wurzeln endeten zuerst oberhalb
der Erdlinie und sahen deshalb aus wie Beine; sie muessen die Linie
kreuzen. Und die Fasern der gerissenen Leine zeigten aufeinander zu, das
ergab zwei Pfeilspitzen und damit die gegenteilige Aussage. Jetzt haengen
beide Enden nach unten.

Slide 4 zeigte vier Kaesten mit "fehlt". Das ist der Mangel, die Slide
handelt aber vom Wunsch. Jetzt ein Blatt mit einer Liste, in den Worten
eines Betriebs statt in Feature-Namen: die stehen schon im Fliesstext.
Die Kaestchen bleiben leer, erfuellt wird der Wunsch auf Slide 5.

Das Layout-CSS aller alten Visualisierungen ist entfernt, dazu die
verwaisten Kasten-Regeln und der kasten-Baustein. Die Klassen haengen
weiter am Container, und die Regeln haben dreimal zugeschlagen: zuletzt
schob .vis-lose mit zwei Spalten das SVG auf ein Drittel Breite. An der
Stelle steht jetzt ein Hinweis statt einer Leerzeile.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-12 00:58:29 +02:00
1 parent 6f58896f12
commit 87834304fa
1 file changed
+159 -100
+159 -100
View File
@@ -375,83 +375,12 @@
}
.vis svg { display: block; width: 100%; height: auto; }
.vis-kasten {
position: relative; padding: 30px 34px;
background: var(--frame-bg);
display: flex; flex-direction: column; justify-content: center;
clip-path: polygon(
18px 0, calc(100% - 18px) 0, 100% 18px, 100% calc(100% - 18px),
calc(100% - 18px) 100%, 18px 100%, 0 calc(100% - 18px), 0 18px
);
}
.vis-titel { font-size: 38px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; }
.vis-zeile { margin-top: 8px; font-size: 24px; font-weight: 500; line-height: 1.35; color: var(--body-color); }
.vis-marke { background: var(--accent-yellow); color: #3E2C0A; }
.vis-marke .vis-zeile { color: #6B4E12; }
/* Slide 2: die drei Schritte haengen an einer Schiene. Sie stehen nicht
dort, weil es sinnvoll waere, sondern weil die Schiene es vorgibt. */
.vis-schiene { display: flex; align-items: stretch; gap: 40px; }
.vis-schiene .rail {
flex: none; width: 74px; position: relative;
background: var(--shape-fill);
clip-path: polygon(
14px 0, 60px 0, 74px 14px, 74px calc(100% - 14px),
60px 100%, 14px 100%, 0 calc(100% - 14px), 0 14px
);
}
.vis-schiene .rail span {
position: absolute; left: 50%; top: 50%; white-space: nowrap;
transform: translate(-50%, -50%) rotate(-90deg);
color: #fff; font-size: 21px; font-weight: 700; letter-spacing: .13em;
text-transform: uppercase; opacity: .82;
}
.vis-schiene .stufen { flex: 1; display: flex; flex-direction: column; }
.vis-schiene .vis-kasten { min-height: 190px; }
.vis-schiene .verbund {
width: 8px; height: 56px; margin-left: 58px; background: var(--shape-line);
}
/* Slide 3: der Bestand ist schwer, das Ziel leer. Das Kreuz liegt auf dem
Pfeil, nicht auf dem Ziel: der Wechsel scheitert, nicht das System. */
.vis-ersetzen { display: flex; align-items: stretch; gap: 30px; }
.vis-ersetzen .schwer { flex: 1.25; display: grid; gap: 14px; }
.vis-ersetzen .schwer .vis-kasten { min-height: 212px; }
.vis-ersetzen .leer {
flex: 1; padding: 30px; border: 8px dashed var(--shape-line);
display: flex; align-items: center; justify-content: center; text-align: center;
color: var(--body-color); font-size: 26px; font-weight: 600; line-height: 1.35;
}
.vis-ersetzen .pfeil {
flex: none; align-self: center; position: relative;
width: 104px; height: 8px; background: var(--shape-line);
}
.vis-ersetzen .pfeil::after {
content: ""; position: absolute; right: -2px; top: -14px;
border: 18px solid transparent; border-left-color: var(--shape-line);
}
.vis-kreuz {
position: absolute; left: 50%; top: 50%; width: 92px; height: 92px;
transform: translate(-50%, -50%);
}
.vis-kreuz i {
position: absolute; left: 0; top: 42px; width: 100%; height: 10px;
background: var(--accent-yellow);
}
.vis-kreuz i:first-child { transform: rotate(45deg); }
.vis-kreuz i:last-child { transform: rotate(-45deg); }
/* Slide 4: vier Kacheln, die nichts voneinander wissen. Die gestrichelten
Stummel laufen ins Leere. */
.vis-lose { display: grid; grid-template-columns: repeat(2, 1fr); gap: 32px 96px; }
.vis-lose .feld { position: relative; }
.vis-lose .feld .vis-kasten { min-height: 320px; }
.vis-lose .stummel {
position: absolute; top: 50%; width: 72px; height: 0;
border-top: 8px dashed var(--shape-line);
}
.vis-lose .feld:nth-child(odd) .stummel { right: -84px; }
.vis-lose .feld:nth-child(even) .stummel { left: -84px; }
/* Hier stand das Layout-CSS der alten Visualisierungen. Alle sechs sind
inzwischen gezeichnet, das SVG fuellt seinen Container selbst. Die Regeln
haben dreimal zugeschlagen, weil die Klasse weiter am Container haengt:
.vis-verbinden mit display:grid schob das SVG in eine Rasterzelle,
.vis-lose mit zwei Spalten auf ein Drittel Breite. Es darf hier kein
Layout-CSS mehr auftauchen. Gebraucht werden nur .vis und .vis svg.
/* Slide 5 ist gezeichnet und braucht kein eigenes Layout mehr: das SVG
fuellt den Container. Das alte Raster stand hier noch und hat die
@@ -1250,12 +1179,6 @@
Jede Slide nennt ueber "vis" ihr Bild. Gebaut wird es hier aus HTML, nicht
aus einer Aufnahme: so bleibt es beim Export scharf und laesst sich wie
jedes andere Element im Canvas verschieben. */
const kasten = (titel, zeile, marke) =>
'<div class="vis-kasten' + (marke ? " vis-marke" : "") + '">' +
'<div class="vis-titel">' + titel + '</div>' +
(zeile ? '<div class="vis-zeile">' + zeile + '</div>' : '') +
'</div>';
/* ─── Skizzen-Primitive ─────────────────────────────────────────────────────
Handzeichnung aus gesetztem Zufall. Der Keim ist fest: der Export rendert
bei fehlgeschlagener Pruefung bis zu fuenfmal neu, und jeder Durchgang muss
@@ -1734,6 +1657,157 @@
'" xmlns="http://www.w3.org/2000/svg">' + raus + '</svg>';
}
/* ─── Slide 3: wechseln kannst du vergessen ──────────────────────────────
Der Fliesstext hat zwei Haelften, und beide brauchen ein Bild: "Jahre an
Daten und Wissen haengen drin" wird zu Wurzeln im Boden, "am Ende
dasselbe, nur woanders" zu demselben Kasten noch einmal, nur gestrichelt.
Dazwischen eine gerissene Leine.
Das Kreuz der alten Fassung lag auf dem Pfeil und nicht auf dem Ziel, aus
gutem Grund: nicht das neue System scheitert, sondern der Wechsel. Das
bleibt so. Aus dem Kreuz ist eine gerissene Leine geworden und aus dem
leeren Ziel ein gleiches, denn leer war die falsche Aussage. */
function wurzeln(x, w, oben, tief) {
let raus = "";
const n = 8;
for (let i = 0; i < n; i++) {
const t = (i + 0.5) / n;
const sx = x + w * (0.07 + 0.86 * t);
const laenge = tief * (0.5 + rnd() * 0.5);
const drift = (t - 0.5) * 165 + zit(26);
raus += zug(glatt([[sx, oben],
[sx + drift * 0.18 + zit(9), oben + laenge * 0.3],
[sx + drift * 0.62 + zit(11), oben + laenge * 0.66],
[sx + drift, oben + laenge]], false),
{ w: 3.1 - Math.abs(t - 0.5) * 1.7 });
const az = oben + laenge * 0.5, ax = sx + drift * 0.28;
const seite = t < 0.5 ? -1 : 1;
raus += zug(glatt([[ax, az],
[ax + seite * 20 + zit(7), az + laenge * 0.2],
[ax + seite * 33 + zit(9), az + laenge * 0.33]], false), { w: 1.8 });
}
return raus;
}
/* Erdreich: ungleich lange Schraegstriche. Die gleichmaessige Schraffur aus
schraff() sah nach technischer Zeichnung aus, nicht nach Boden. */
function erdreich(x1, x2, y) {
let d = "";
for (let x = x1; x < x2; x += 13 + rnd() * 6) {
const l = 11 + rnd() * 13;
d += strich(x, y + 2, x - l * 0.55, y + 2 + l, { j: .8, b: .8 });
}
return d;
}
function visWechseln() {
keim(20260815);
const W = 896, H = 730, GRAU = "#A9AFB7";
const BY = 100, BH = 360, BW = 320, LX = 30, RX = 555;
const zeilen = ["Stammdaten", "Aufträge", "Historie", "Wissen im Kopf"];
const mitte = BY + BH / 2;
const inhalt = (x, farbe) => zeilen.map((z, i) =>
'<text x="' + (x + 60) + '" y="' + (BY + 96 + i * 66) + '" ' +
'font-family="Manrope, sans-serif" font-size="28" font-weight="600" ' +
'letter-spacing="-0.01em" fill="' + farbe + '">' + z + '</text>').join("");
const striche = x => zeilen.map((z, i) =>
strich(x + 28, BY + 87 + i * 66, x + 48, BY + 87 + i * 66, { j: .8, b: .8 })).join("");
let raus = "";
// Der Bestand: schwerer Strich, doppelte Unterkante.
raus += zug(rechteck(LX, BY, BW, BH, { ue: 4.5 }), { w: 3.8 });
raus += zug(strich(LX + 6, BY + BH + 6, LX + BW - 6, BY + BH + 6, { ue: 2 }), { w: 3 });
raus += zug(striche(LX), { w: 2.6 });
/* Die Erdoberflaeche liegt dicht unter dem Kasten, nicht am unteren Rand.
Im ersten Wurf lag sie 120 px tiefer, dadurch endeten die Wurzeln in der
Luft und sahen aus wie Beine. Sie muessen die Linie kreuzen, sonst
stecken sie nicht drin. */
const boden = BY + BH + 18;
raus += zug(strich(0, boden, 500, boden, { ue: 4 }), { w: 3 });
raus += zug(erdreich(6, 494, boden), { w: 1.9, op: .45 });
raus += wurzeln(LX, BW, BY + BH + 6, 142);
/* Die Leine reisst, und der Akzent sitzt genau dort, wo die Aussage sitzt.
Entscheidend ist, dass beide Enden nach unten haengen und die Fasern in
dieselbe Richtung weiter ausfransen. Im ersten Wurf zeigten sie
aufeinander zu: das ergab zwei Pfeilspitzen, also die gegenteilige
Aussage. Eine gerissene Leine faellt, sie zielt nicht. */
const endL = [418, mitte + 62], endR = [496, mitte + 48];
raus += zug(glatt([[LX + BW, mitte - 8], [388, mitte + 2], [412, mitte + 28],
endL], false), { f: GELB, w: 4.4 });
raus += zug(glatt([[RX, mitte - 8], [528, mitte + 0], [502, mitte + 22],
endR], false), { f: GELB, w: 4.4 });
let fransen = "";
[endL, endR].forEach(e => {
[-0.42, -0.05, 0.36].forEach(o => {
fransen += strich(e[0], e[1] - 4,
e[0] + Math.sin(o) * 26, e[1] + Math.cos(o) * 26, { j: .9, b: 1.1 });
});
});
raus += zug(fransen, { f: GELB, w: 2.8 });
// Dasselbe noch einmal, nur woanders: gleiche Groesse, gleiche Zeilen.
raus += zug(rechteck(RX, BY, BW, BH, { ue: 3 }), { w: 3, op: .6, strichel: "14 13", f: GRAU });
raus += zug(striche(RX), { w: 2.4, f: GRAU });
raus += inhalt(LX, TINTE) + inhalt(RX, GRAU);
return '<svg viewBox="0 0 ' + W + ' ' + H + '" width="' + W + '" height="' + H +
'" xmlns="http://www.w3.org/2000/svg">' + raus + '</svg>';
}
/* ─── Slide 4: wir wollten mehr ──────────────────────────────────────────
Die alte Fassung zeigte vier Kaesten mit "fehlt". Das ist der Mangel, die
Slide handelt aber vom Wunsch. Also ein Blatt mit einer Liste.
Die Punkte nennen nicht noch einmal KI, CRM und Automatisierung, das steht
schon im Fliesstext darueber. Sie sagen dasselbe in den Worten eines
Betriebs. Die Kaestchen bleiben leer: erfuellt wird der Wunsch erst auf
Slide 5, und genau davon lebt der Uebergang.
Gelb tragen die Kaestchen. Es ist der einzige Akzent hier und bleibt damit
bei seiner Rolle aus den anderen Slides: Struktur, keine Verzierung. */
function visMehr() {
keim(20260816);
const W = 896, H = 730;
const LX = 60, RX = 800, OY = 70, UY = 650, KNICK = 58;
const wuensche = [
"Angebot schreibt sich selbst",
"Kunde sieht seinen Stand",
"Nichts doppelt eintippen",
"Alles redet miteinander",
];
// Blatt mit abgeknickter Ecke unten rechts.
const blatt = strich(LX, OY, RX, OY, { ue: 4 }) +
strich(RX, OY, RX, UY - KNICK, { ue: 3 }) +
strich(RX, UY - KNICK, RX - KNICK, UY, { ue: 2 }) +
strich(RX - KNICK, UY, LX, UY, { ue: 4 }) +
strich(LX, UY, LX, OY, { ue: 4 });
const knick = glatt([[RX, UY - KNICK], [RX - KNICK + 8, UY - KNICK + 12],
[RX - KNICK, UY]], false);
let raus = zug(blatt, { w: 3.4 }) + zug(knick, { w: 2.6, op: .75 });
wuensche.forEach((t, i) => {
const y = 180 + i * 120;
raus += zug(strich(LX + 60, y + 26, RX - 60, y + 26, { j: 1, b: 1 }), { w: 2, op: .22 });
raus += zug(rechteck(LX + 60, y - 30, 38, 38, { ue: 3 }), { f: GELB, w: 3.4 });
raus += '<text x="' + (LX + 126) + '" y="' + y + '" font-family="Manrope, sans-serif" ' +
'font-size="32" font-weight="600" letter-spacing="-0.015em" fill="' + TINTE + '">' +
t + '</text>';
});
/* Leicht schief aufs Blatt gelegt. Genau senkrecht wirkt gesetzt, und ein
Zettel liegt nie gerade. */
return '<svg viewBox="0 0 ' + W + ' ' + H + '" width="' + W + '" height="' + H +
'" xmlns="http://www.w3.org/2000/svg">' +
'<g transform="rotate(-1.3 448 360)">' + raus + '</g></svg>';
}
/* ─── Slide 6: was nach der Anmeldung passiert ───────────────────────────
Uebernahme der Sektion "So geht\'s weiter" von der Website, in derselben
Handschrift wie Slide 5. Drei Schritte an einer Leitung, Wabe statt Kreis,
@@ -1841,24 +1915,9 @@
schiene: () => visProzesse(),
ersetzen: () =>
'<div class="vis-ersetzen">' +
'<div class="schwer vis-stapel">' +
kasten("Stammdaten", "seit Jahren gepflegt") +
kasten("Aufträge", "die ganze Historie") +
kasten("Buchhaltung", "und die Leute, die es kennen") +
'</div>' +
'<div class="pfeil"><div class="vis-kreuz"><i></i><i></i></div></div>' +
'<div class="leer">alles noch mal von vorn</div>' +
'</div>',
ersetzen: () => visWechseln(),
lose: () =>
'<div class="vis-lose">' +
'<div class="feld">' + kasten("KI", "fehlt") + '<span class="stummel"></span></div>' +
'<div class="feld">' + kasten("CRM", "fehlt") + '<span class="stummel"></span></div>' +
'<div class="feld">' + kasten("Automation", "fehlt") + '<span class="stummel"></span></div>' +
'<div class="feld">' + kasten("ERP", "läuft, redet aber mit niemandem") + '<span class="stummel"></span></div>' +
'</div>',
lose: () => visMehr(),
verbinden: () => visVerbinden(),