Post 2: Texte an Noahs Original, Pfeil ueber die Naht

Die Texte lasen sich maschinell, und der Grund war nicht die Kuerze. Alle
fuenf Ueberschriften hatten dieselbe Form: zwei abgehackte Fragmente mit
Punkt dazwischen, fuenfmal hintereinander, und die Fliesstexte machten es
nach. Jetzt wechseln sich Aussage mit Wendung, Frage und Antwort, Paar und
durchlaufender Satz ab. Die Formulierungen kommen aus Noahs Text statt aus
dem Nichts: "Und wechseln? Kannst du vergessen", "Stammdaten, Auftraegen
und Buchhaltung", "kein Ersatz, sondern der Aufbau drumherum".

Das Wort ERP kommt nicht mehr vor, es heisst Branchenprogramm wie bei
Noah. Slide 2 traegt die Enthuellung aus seinem Absatz, dass ein alter
Betrieb nicht nur Erfahrung vererbt. Slide 6 traegt die Marken-Tagline,
ausgezeichnet wie in Post 1: der Marker sitzt auf dem zweiten Handwerker,
nicht auf der ganzen Zeile.

Der Beitrag ist Noahs Konzept, sagt das aber nirgends geradeheraus. Slide
2 stellt fest, dass hinter den gewachsenen Ablaeufen keines steckt, Slide
5 liefert eines. Das Wort faellt genau einmal.

Slide 1 bekommt Randnotizen: Gluehbirne, Zettel, Maulschluessel. Der
Schluessel brauchte zwei Anlaeufe, erst war er ein Knochen, weil glatt()
die Kanten wegrundet. Ein Werkzeug lebt von scharfen Kanten. Aus CEO wird
Gruender.

Slide 4 zeigt statt einer Wunschliste vier Funktionen mit Haken und
Zeichen. Die Zeichen stehen in einer Spalte statt hinter dem Wort, sonst
haetten die unterschiedlich langen Zeilen eine ausgefranste Kante ergeben.

Zwischen Slide 4 und 5 laeuft ein Pfeil ueber die Naht, auf halber
Slide-Hoehe. Umriss gezeichnet, innen mit Schraegstrichen ausgemalt, in
Tinte statt Gelb: Gelb bedeutet hier Verbindung und gehoert der Zeichnung,
der Pfeil weist nur weiter. Dafuer reichen beide Zeichenflaechen jetzt bis
an die Slide-Kanten, Slide 5 beginnt bei 0 statt bei 92.

Dabei kam ein Fehler heraus, der jede kuenftige Slide getroffen haette:

    "--vis-left:" + (sl.visLeft || 92)

Die 0 ist falsy, also hat || sie als fehlenden Wert behandelt und den
Vorgabewert eingesetzt. Steht jetzt auf ??, ebenso bei visW und visBottom.
Aufgefallen ist es nur beim Nachmessen, nicht beim Hinsehen.

Der Projektstand kommt mit. Er traegt eigene Textfassungen fuer Slide 3
und 6 sowie die Groesse und Lage der Karte auf Slide 1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-12 11:52:32 +02:00
1 parent 9cc82e59ee
commit 8590fa7e6e
3 files changed
+336 -68

No files matched your search

+287 -45
View File
@@ -407,8 +407,8 @@
verschoben. Deshalb hier svg.karte-skizze und nicht nur die Klasse. */
.vis svg.karte-skizze {
position: absolute; z-index: 6; pointer-events: none;
left: -7.42%; width: 128.39%;
top: -19.35%; height: 125.29%;
left: -24.19%; width: 153.23%;
top: -23.23%; height: 141.29%;
}
.karte {
position: relative; aspect-ratio: 4/5; overflow: hidden;
@@ -1098,11 +1098,31 @@
traegt jede Slide eine gebaute Visualisierung: der Text nennt ein
Stichwort, das Bild zeigt es.
Die Texte sind NICHT die von der Website. Dort stehen ganze Absaetze, hier
muss eine Zeile im Vorbeiscrollen sitzen. Der volle Text kommt unter den
Beitrag, die Slide traegt nur die Zuspitzung. Faustregel aus den
gemessenen Breiten: bei 74 px und -0,03em passen rund 26 Zeichen in eine
Zeile, mit Marker etwas weniger. Keine Zeile hier ist laenger als 22. */
Die Texte sind Zuspitzungen von Noahs Text, nicht dessen Absaetze: auf
einer Slide muss eine Zeile im Vorbeiscrollen sitzen. Formulierungen und
Stimme kommen aber von dort, nicht aus dem Nichts.
Der Beitrag ist Noahs Konzept, sagt das aber nirgends geradeheraus. Er
baut es auf: Slide 2 stellt im Fliesstext fest, dass hinter den
gewachsenen Ablaeufen keines steckt, Slide 5 liefert dann eines. Das Wort
faellt genau einmal und wird danach nicht wiederholt.
Slide 2 traegt ausserdem die Enthuellung aus Noahs Absatz: ein alter
Betrieb vererbt nicht nur Erfahrung. Genau daran haengt der Beitrag, und
deshalb steht sie in der Ueberschrift und nicht im Fliesstext. Der
Fliesstext behaelt Noahs eigene Konstruktion "weil die Software es
vorgibt. Nicht, weil ...". Das angehaengte "Nicht, weil" ist bei ihm ein
Stilmittel und keine abgehackte Halbzeile.
Wichtiger als die Kuerze ist die Satzform. In einer frueheren Fassung
hatten alle fuenf Ueberschriften dieselbe: zwei abgehackte Fragmente mit
Punkt dazwischen, fuenfmal hintereinander. Das liest sich maschinell,
egal wie gut der einzelne Satz ist. Jetzt wechseln sich Aussage mit
Wendung, Frage und Antwort, Paar und durchlaufender Satz ab.
Faustregel aus den gemessenen Breiten: bei 74 px und -0,03em passen rund
26 Zeichen in eine Zeile, mit Marker etwas weniger. Keine Zeile hier ist
laenger als 22. */
const VORLAGEN = [
{
key: "titel", type: "feature",
@@ -1116,17 +1136,17 @@
{
key: "prozesse", type: "feature",
layouts: [{ id: "standard", label: "Standard" }],
eyebrow: "Prozesse",
head: 'Nicht sinnvoll.<br><span class="a">Nur so gewachsen.</span>',
body: "Die Software gibt den Takt vor. Nicht der Betrieb.",
eyebrow: "Zettelwirtschaft",
head: 'Nicht nur Erfahrung,<br><span class="a">auch Zettelwirtschaft.</span>',
body: "Abläufe, die so laufen, weil die Software es vorgibt. Nicht, weil ein Konzept dahintersteckt.",
vis: "schiene", visW: 896, visLeft: 92, visBottom: 120,
},
{
key: "wechseln", type: "feature",
layouts: [{ id: "standard", label: "Standard" }],
eyebrow: "Wechseln",
head: 'Wechseln?<br><span class="a">Kannst du vergessen.</span>',
body: "Jahre an Daten und Wissen hängen drin. Am Ende dasselbe, nur woanders.",
head: 'Und wechseln?<br><span class="a">Kannst du vergessen.</span>',
body: "Da hängen Jahre an Stammdaten, Aufträgen und Buchhaltung drin. Und die Leute, die es kennen.",
vis: "ersetzen", visW: 896, visLeft: 92, visBottom: 120,
},
{
@@ -1134,23 +1154,27 @@
layouts: [{ id: "standard", label: "Standard" }],
eyebrow: "Mehr",
head: 'Wir wollten nicht weg.<br><span class="a">Wir wollten mehr.</span>',
body: "KI, CRM, Automatisierung. Und Tools, die miteinander reden.",
vis: "lose", visW: 896, visLeft: 92, visBottom: 120,
body: "KI-Lösungen, ein CRM, Automatisierungen. Unsere Tools sollen endlich miteinander reden.",
vis: "lose", visW: 988, visLeft: 92, visBottom: 120,
},
{
key: "verbinden", type: "feature",
layouts: [{ id: "standard", label: "Standard" }],
eyebrow: "Verbinden",
head: 'Dein ERP bleibt.<br><span class="a">Der Rest kommt dazu.</span>',
body: "Nichts wird ersetzt. Alles wird verbunden.",
vis: "verbinden", visW: 896, visLeft: 92, visBottom: 120,
head: 'Dein Branchenprogramm<br><span class="a">bleibt, wo es ist.</span>',
body: "Kein Ersatz, sondern der Aufbau drumherum. HiveGrid holt raus, was bisher gefehlt hat.",
vis: "verbinden", visW: 988, visLeft: 0, visBottom: 120,
},
{
key: "warteliste", type: "feature",
layouts: [{ id: "standard", label: "Standard" }],
eyebrow: "Warteliste",
head: 'Gebaut im Betrieb.<br><span class="a">Für den Betrieb.</span>',
body: "Setz dich auf die Warteliste.",
/* Die Marken-Tagline. Sie wird genauso ausgezeichnet wie in Post 1 und
im Titel-Layout: der Marker sitzt auf dem zweiten "Handwerker", nicht
auf der ganzen Zeile. Eine zweite Schreibweise derselben Zeile waere
eine Abweichung, die niemandem auffaellt und trotzdem stoert. */
head: 'Vom Handwerker<br>für <span class="a">Handwerker</span>',
body: "Kein Startup-Projekt. Setz dich auf die Warteliste, dann melden wir uns.",
vis: "warteliste", visW: 896, visLeft: 92, visBottom: 120,
},
];
@@ -1410,6 +1434,38 @@
}
ikonFormular.rad = 62; ikonFormular.unten = 96;
/* Ein Linienzug aus Einzelstrichen. Jede Kante bekommt ihren eigenen Zug
mit Ueberschuss an den Enden, dadurch bleiben die Ecken kantig. Eine
durchgehende weiche Kurve wuerde eine Pfeilspitze zum Tropfen runden. */
function linienzug(pts, ue) {
let d = "";
for (let i = 0; i < pts.length - 1; i++) {
d += strich(pts[i][0], pts[i][1], pts[i + 1][0], pts[i + 1][1],
{ ue: ue == null ? 3 : ue, j: 1.1 });
}
return d;
}
/* Kritzelfuellung: schnelle Schraegstriche quer durch die Form, jeder von
Kante zu Kante. halb(x) gibt die halbe Hoehe an dieser Stelle, dadurch
laeuft die Fuellung in einer Spitze von selbst aus.
Der erste Versuch war ein durchgehendes Zickzack die Laenge entlang. In
der Spitze schlug es ueber die Kanten hinaus und ergab ein Knaeuel statt
einer Flaeche. Einzelne Striche bleiben innerhalb der Form, und wo einer
ausgelassen wird, bleibt Weiss stehen -- genau so malt man schnell aus. */
function kritzel(x1, x2, my, halb, abstand) {
let d = "";
for (let x = x1; x <= x2; x += abstand) {
const bis = Math.min(x2, x + 8);
const h1 = halb(x), h2 = halb(bis);
if (h1 < 4 || h2 < 3) continue;
if (rnd() < 0.12) continue; // ab und zu bleibt Weiss stehen
d += strich(x, my - h1 + 2, bis, my + h2 - 2, { j: 1, b: 1 });
}
return d;
}
/* Ein Strich mit Spitze am Ende. Die Spitze sind zwei kurze Zuege, keine
gefuellte Flaeche: gezeichnet wird sie so, gefuellt sieht sie gesetzt aus. */
function pfeil(x1, y1, x2, y2, gr) {
@@ -1680,6 +1736,89 @@
er liegt zur Haelfte auf dem hellen Grund und zur Haelfte auf dem dunklen
Foto. Eine Tintenlinie waere auf dem Foto verschwunden. Gelb traegt auf
beidem, und ein Bauhelm ist ohnehin gelb. */
/* ─── Randnotizen ────────────────────────────────────────────────────────
Kleine Zeichen neben dem Foto, wie am Rand eines Blocks hingekritzelt.
Sie stehen ausserhalb des Rahmens, damit sie das Bild nicht stoeren, und
bleiben in Tinte -- nur was leuchtet, ist gelb. */
function gluehbirne(cx, cy, gr) {
const r = gr * 0.34, my = cy - gr * 0.12;
const kolben = kringel(cx, my, r, r * 1.06, { ueber: .12 });
const hals = strich(cx - r * 0.52, my + r * 0.9, cx - r * 0.46, my + r * 1.3, { j: .7 }) +
strich(cx + r * 0.52, my + r * 0.9, cx + r * 0.46, my + r * 1.3, { j: .7 });
const sockel = rechteck(cx - r * 0.46, my + r * 1.28, r * 0.92, r * 0.6, { ue: 1.5 }) +
strich(cx - r * 0.44, my + r * 1.5, cx + r * 0.44, my + r * 1.5, { j: .5, b: .5 });
const faden = glatt([[cx - r * 0.34, my - r * 0.08], [cx - r * 0.12, my + r * 0.3],
[cx, my - r * 0.14], [cx + r * 0.12, my + r * 0.3],
[cx + r * 0.34, my - r * 0.08]], false);
let strahlen = "";
[-2.55, -2.0, -1.45, -0.9, -0.35].forEach(a => {
strahlen += strich(cx + Math.cos(a) * r * 1.32, my + Math.sin(a) * r * 1.32,
cx + Math.cos(a) * r * 1.8, my + Math.sin(a) * r * 1.8, { j: .8 });
});
return zug(strahlen, { f: GELB, w: 3 }) + zug(kolben, { w: 3.2 }) +
zug(hals, { w: 2.6 }) + zug(sockel, { w: 2.6 }) + zug(faden, { w: 2, op: .65 });
}
/* Ein Zettel mit Eselsohr und zwei gekritzelten Zeilen. */
function zettel(cx, cy, w, h) {
const x = cx - w / 2, y = cy - h / 2, e = w * 0.32;
const blatt = glatt([[x, y], [x + w - e, y], [x + w, y + e], [x + w, y + h],
[x, y + h], [x, y]], false);
const knick = glatt([[x + w - e, y], [x + w - e + 4, y + e - 4], [x + w, y + e]], false);
let zeilen = "";
[0.44, 0.6, 0.76].forEach((f, i) => {
zeilen += strich(x + w * 0.15, y + h * f, x + w * (i === 2 ? 0.58 : 0.82), y + h * f,
{ j: .8, b: .8 });
});
return zug(blatt, { w: 2.8 }) + zug(knick, { w: 2.2, op: .7 }) +
zug(zeilen, { w: 2, op: .72 });
}
/* Ringmaulschluessel.
Zwei Anlaeufe liegen dahinter. Erst war das Maul mit glatt() gezogen, und
die weiche Kurve rundete die Kanten zu einem Knochen ab. Dann war es zwar
kantig, aber immer noch ein Umriss ohne Werkzeugcharakter.
Was ihn ausmacht, sind drei Dinge, die ein echter Schluessel hat: die
Backen stehen schraeg zur Schaftachse, der Ringkopf ist ein angestelltes
Oval mit Sechskant darin, und der Schaft ist zur Mitte hin schlanker. */
function schluessel(L) {
const t = L * 0.11;
// Schaft, zur Mitte verjuengt.
const schaft = glatt([[-L * 0.30, -t * 0.66], [-L * 0.05, -t * 0.46],
[L * 0.22, -t * 0.6]], false) +
glatt([[-L * 0.30, t * 0.66], [-L * 0.05, t * 0.46],
[L * 0.22, t * 0.6]], false);
// Ringkopf: Oval mit Sechskant, um 12 Grad angestellt.
const rx = -L * 0.42;
const kopf = kringel(rx, 0, t * 1.95, t * 1.62, { ueber: .12 });
const sechskant = wabe(rx, 0, t * 0.95);
// Maul: zwei Backen, um 16 Grad zur Schaftachse gedreht.
const eck = [[0.22, -0.6], [0.29, -1.95], [0.52, -1.95], [0.52, -1.0],
[0.35, -0.44], [0.35, 0.44], [0.52, 1.0], [0.52, 1.95],
[0.29, 1.95], [0.22, 0.6]];
let maul = "";
for (let i = 0; i < eck.length - 1; i++) {
maul += strich(L * eck[i][0], t * eck[i][1],
L * eck[i + 1][0], t * eck[i + 1][1], { j: .55, b: .5 });
}
// Zwei kurze Zuege am Schaft, sonst wirkt er wie ein flacher Streifen.
const glanz = strich(-L * 0.16, t * 0.24, L * 0.02, t * 0.16, { j: .5, b: .5 }) +
strich(L * 0.06, t * 0.2, L * 0.16, t * 0.26, { j: .5, b: .5 });
return zug(schaft, { w: 2.8 }) +
'<g transform="rotate(-12 ' + n1(rx) + ' 0)">' +
zug(kopf, { w: 2.8 }) + zug(sechskant, { w: 2.2, op: .75 }) +
'</g>' +
'<g transform="rotate(16 ' + n1(L * 0.22) + ' 0)">' + zug(maul, { w: 2.8 }) + '</g>' +
zug(glanz, { w: 1.8, op: .5 });
}
/* Der Helm. Drei Anlaeufe stecken drin, und die Zwischenschritte stehen
hier, weil sie lehrreich sind: erst war die Kuppel flach und die Krempe
eine geschlossene Scheibe darunter, zusammen eine Schirmmuetze. Dann kam
@@ -1735,13 +1874,13 @@
nicht wie eine Kappe aufliegt. */
function visKarte(lage) {
keim(20260811);
const W = 796, H = 971;
// Das Foto liegt bei x 46..666 und y 150..925, der Rahmen 16 px aussen
// herum. Rechts ist die Ebene breiter als noetig, weil der Helm in der
// Lage "ecke" ueber den Rahmen hinausragt.
const W = 950, H = 1095;
/* Das Foto liegt in dieser Ebene bei x 150..770 und y 180..955, der Rahmen
16 px aussen herum. Rundherum bleibt Platz: rechts fuer den Helm in der
Ecken-Lage, links und unten fuer die Randnotizen. */
let band = "";
for (let y = 178; y < 928; y += 13) band += strich(683, y, 699, y + 16, { j: .7, b: .7 });
for (let x = 72; x < 666; x += 13) band += strich(x, 942, x + 16, 958, { j: .7, b: .7 });
for (let y = 208; y < 958; y += 13) band += strich(787, y, 803, y + 16, { j: .7, b: .7 });
for (let x = 176; x < 770; x += 13) band += strich(x, 972, x + 16, 988, { j: .7, b: .7 });
/* Drei Sachen greifen ineinander statt nebeneinanderher zu laufen: der
versetzte Zug ist die Aussenkante des Schattens, die Schraffur fuellt
@@ -1751,16 +1890,29 @@
aber weichgezeichnete. Die dort notierte Ausnahme sagt, eine Linie ist
kein Schatten. Eine Schraffur besteht aus Linien. */
const rahmen =
zug(chamfer(48, 152, 652, 807, 30, { ue: 5 }), { w: 3, op: .38 }) +
zug(chamfer(152, 182, 652, 807, 30, { ue: 5 }), { w: 3, op: .38 }) +
zug(band, { w: 1.9, op: .34 }) +
zug(chamfer(30, 134, 652, 807, 30, { ue: 9 }), { w: 6 });
zug(chamfer(134, 164, 652, 807, 30, { ue: 9 }), { w: 6 });
/* Randnotizen. Der erste Versuch waren Sternchen und eine Wellenlinie --
huebsch, aber ohne jeden Bezug zum Beitrag. Jetzt steht dort, was in
einem SHK-Betrieb herumliegt: die Idee, ein Zettel, Werkzeug, eine
Wasserwaage. */
/* Nach innen gerueckt: das Profil-Raster schneidet die Slide auf 3:4 und
nimmt links und rechts je rund 34 px weg. Slide 1 ist das Titelbild und
damit genau die, die dort erscheint. */
const rand =
gluehbirne(72, 300, 98) +
'<g transform="translate(74 676) rotate(-34)">' + schluessel(118) + '</g>' +
'<g transform="translate(852 636) rotate(7)">' + zettel(0, 0, 82, 100) + '</g>';
const helm = lage === "kopf"
? '<g transform="translate(398 350) rotate(-4)">' + bauhelm(222) + '</g>'
: '<g transform="translate(690 168) rotate(28)">' + bauhelm(196) + '</g>';
? '<g transform="translate(502 380) rotate(-4)">' + bauhelm(222) + '</g>'
: '<g transform="translate(794 198) rotate(28)">' + bauhelm(196) + '</g>';
return '<svg viewBox="0 0 ' + W + ' ' + H + '" width="' + W + '" height="' + H +
'" xmlns="http://www.w3.org/2000/svg" class="karte-skizze">' + rahmen + helm + '</svg>';
'" xmlns="http://www.w3.org/2000/svg" class="karte-skizze">' +
rand + rahmen + helm + '</svg>';
}
/* ─── Slide 3: wechseln kannst du vergessen ──────────────────────────────
@@ -1810,7 +1962,7 @@
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 zeilen = ["Stammdaten", "Aufträge", "Buchhaltung", "Wissen im Kopf"];
const mitte = BY + BH / 2;
const inhalt = (x, farbe) => zeilen.map((z, i) =>
@@ -1875,16 +2027,59 @@
Gelb tragen die Kaestchen. Es ist der einzige Akzent hier und bleibt damit
bei seiner Rolle aus den anderen Slides: Struktur, keine Verzierung. */
/* Kleine Zeichen fuer die Liste auf Slide 4. Sie liegen in derselben
Groesse wie die Glyphen der Kanaele auf Slide 2, damit beide Listen
dieselbe Sprache sprechen. Alle geben Pfaddaten zurueck, keine Markup. */
function glyZahnrad(cx, cy) {
const r = 14, n = 8;
let d = "";
for (let i = 0; i < n; i++) {
const a = i * 6.283 / n, br = 0.24, pk = [];
[[-br, r], [-br * .8, r + 7], [br * .8, r + 7], [br, r]].forEach(v => {
const aa = a + v[0];
pk.push([cx + Math.cos(aa) * v[1] + zit(.6), cy + Math.sin(aa) * v[1] + zit(.6)]);
});
d += glatt(pk, false);
}
return kringel(cx, cy, r) + d + kringel(cx, cy, 5.5);
}
function glyBoard(cx, cy) {
const w = 44, h = 34, x = cx - w / 2, y = cy - h / 2;
let d = rechteck(x, y, w, h, { ue: 1.6 });
for (let i = 1; i < 3; i++) d += strich(x + w * i / 3, y + 5, x + w * i / 3, y + h - 5, { j: .6, b: .6 });
d += rechteck(x + 4, y + 6, w / 3 - 8, 8, { ue: 1 }) +
rechteck(x + 4, y + 19, w / 3 - 8, 8, { ue: 1 }) +
rechteck(x + w / 3 + 4, y + 6, w / 3 - 8, 8, { ue: 1 });
return d;
}
function glyBlase(cx, cy) {
return kringel(cx, cy - 3, 20, 15, { ueber: .1 }) +
glatt([[cx - 6, cy + 9], [cx - 10, cy + 19], [cx + 4, cy + 10]], false) +
[-7, 0, 7].map(o => kringel(cx + o, cy - 3, 2.4)).join("");
}
function glyLeute(cx, cy) {
const kopf = (x, y, r) => kringel(x, y, r) +
glatt([[x - r * 1.5, y + r * 2.6], [x - r * 1.45, y + r * 1.05], [x, y + r * .55],
[x + r * 1.45, y + r * 1.05], [x + r * 1.5, y + r * 2.6]], false);
return kopf(cx - 15, cy - 5, 6.5) + kopf(cx + 15, cy - 5, 6.5) + kopf(cx, cy + 1, 8.5);
}
function visMehr() {
keim(20260816);
const W = 896, H = 730;
/* 988 statt 896 breit: die Flaeche reicht bis zur rechten Slide-Kante,
damit der Pfeil dort wirklich austritt und nicht 92 px davor endet.
Die Zeichnung selbst behaelt ihre Koordinaten. */
const W = 988, 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",
{ t: "Workflow-Engine", g: glyZahnrad },
{ t: "Projektmanagement", g: glyBoard },
{ t: "Chat", g: glyBlase },
{ t: "Mitarbeiter-Management", g: glyLeute },
];
// Blatt mit abgeknickter Ecke unten rechts.
@@ -1898,20 +2093,49 @@
let raus = zug(blatt, { w: 3.4 }) + zug(knick, { w: 2.6, op: .75 });
wuensche.forEach((t, i) => {
const y = 180 + i * 120;
wuensche.forEach((w, i) => {
const y = 180 + i * 120, bx = LX + 60, by = y - 30;
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 += zug(rechteck(bx, by, 38, 38, { ue: 3 }), { f: GELB, w: 3.4 });
// Der Haken laeuft ueber den Kasten hinaus, wie von Hand abgehakt.
raus += zug(glatt([[bx + 7, by + 21], [bx + 15, by + 30], [bx + 33, by + 5]], false),
{ f: GELB, w: 4.8 });
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>';
w.t + '</text>';
/* Die Zeichen stehen in einer Spalte statt direkt hinter dem Wort. Die
Zeilen sind unterschiedlich lang, direkt angehaengt haetten sie eine
ausgefranste Kante ergeben. */
raus += zug(w.g(RX - 108, y - 11), { w: 2.5 });
});
/* Der Pfeil zur naechsten Slide: kurz, gerade, dick, auf halber
Slide-Hoehe. Die Slide ist 1350 hoch, die Zeichenflaeche beginnt bei
500, die Mitte liegt hier also auf 175.
Hier steht nur der hintere Teil des Schafts, die Spitze sitzt drueben
auf Slide 5. Beim Swipen zeigt Instagram zwischen den Slides ein paar
Pixel Abstand, der Pfeil ist dort also zerschnitten. Genau das traegt
den Effekt: eine halbierte Form zieht das Auge weiter (rules.md,
Paragraf 5).
Er steht ausserhalb der Blattdrehung, sonst laege sein Austritt nicht
mehr auf derselben Hoehe wie der Eintritt drueben.
In Tinte, nicht in Gelb: Gelb bedeutet in diesem Beitrag Verbindung
und gehoert der Zeichnung. Der Pfeil gehoert nicht dazu, er weist nur
weiter. */
const nHalb = () => 14;
const naht =
zug(kritzel(818, W - 2, 175, nHalb, 11), { w: 4.4, op: .92 }) +
zug(linienzug([[W, 157], [900, 154], [814, 156], [814, 194],
[900, 196], [W, 193]]), { w: 3.6 });
/* 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>';
'<g transform="rotate(-1.3 448 360)">' + raus + '</g>' + naht + '</svg>';
}
/* ─── Slide 6: was nach der Anmeldung passiert ───────────────────────────
@@ -1962,7 +2186,10 @@
function visVerbinden() {
keim(20260812);
const W = 896, H = 730, cx = 448, cy = 350, R = 160;
/* Die Flaeche beginnt an der linken Slide-Kante statt bei 92, damit der
Pfeil von Slide 4 dort ankommt. Die Zeichnung rueckt um dieselben 92 px
nach rechts, steht also unveraendert auf der Slide. */
const W = 988, H = 730, cx = 540, cy = 350, R = 160;
const RX = 352, RY = 300;
// Die Winkel sind nicht frei gewaehlt: sie sind die sechs Eckwinkel der
@@ -1998,8 +2225,19 @@
// Breite und Hoehe stehen als Attribute mit dran, nicht nur im viewBox.
// Ohne sie hat Chrome die Hoehe nicht aus dem Seitenverhaeltnis abgeleitet,
// das SVG wurde zu hoch und die Zeichnung lief in den Fliesstext.
/* Die Fortsetzung des Pfeils von Slide 4, auf derselben Hoehe: der vordere
Teil des Schafts und die Spitze. */
/* Die Fuellung folgt der Form: im Schaft konstant, in der Spitze laeuft
der Ausschlag auf null zu. */
const zHalb = x => x <= 104 ? 14 : Math.max(2, 40 * (1 - (x - 104) / 68));
const zulauf =
zug(kritzel(2, 168, 175, zHalb, 11), { w: 4.4, op: .92 }) +
zug(linienzug([[0, 157], [54, 155], [104, 156], [104, 130], [172, 175],
[104, 220], [104, 194], [54, 196], [0, 193]]), { w: 3.6 });
return '<svg viewBox="0 0 ' + W + ' ' + H + '" width="' + W + '" height="' + H +
'" xmlns="http://www.w3.org/2000/svg">' +
zulauf +
bilder + schrift +
zug(speichen, { f: GELB, w: 4.4 }) +
zug(wabe(cx, cy, R), { f: GELB, w: 4.8 }) +
@@ -2017,7 +2255,7 @@
'<span class="karte-wash"></span></div>' +
'<img class="karte-person" alt="Noah Geerkens" src="' +
assets["./assets/team/noah-person.webp"] + '">' +
'<div class="karte-name"><span>Noah</span><small>CEO</small></div>' +
'<div class="karte-name"><span>Noah</span><small>Gründer</small></div>' +
'</div></div>',
schiene: () => visProzesse(),
@@ -2638,9 +2876,13 @@
if (sl.vis && VIS[sl.vis]) {
const v = document.createElement("div");
v.className = "vis vis-" + sl.vis;
/* ?? statt ||: visLeft ist auf Slide 5 bewusst 0, damit die Zeichenflaeche
an der linken Slide-Kante beginnt und der Pfeil von Slide 4 dort
ankommt. Mit || waere die 0 als fehlender Wert durchgegangen und die
Flaeche haette weiter bei 92 gesessen. */
v.style.cssText =
"--vis-w:" + (sl.visW || 900) + "px;--vis-left:" + (sl.visLeft || 92) +
"px;--vis-bottom:" + (sl.visBottom || 96) + "px";
"--vis-w:" + (sl.visW ?? 900) + "px;--vis-left:" + (sl.visLeft ?? 92) +
"px;--vis-bottom:" + (sl.visBottom ?? 96) + "px";
v.innerHTML = VIS[sl.vis](j);
page.appendChild(v);
}
+20 -15
View File
@@ -2,7 +2,7 @@
"bgState": [
{
"bg": "raster",
"int": "dezent"
"int": "kraeftig"
},
{
"bg": "raster",
@@ -29,7 +29,9 @@
"deck": [
{
"ref": "titel",
"werte": {}
"werte": {
"body": "<br>"
}
},
{
"ref": "prozesse",
@@ -54,31 +56,34 @@
],
"edits": [
{
"body": {
"dx": 102,
"dy": -95
},
"headline": {
"dx": 102,
"dy": -96
},
"vis": {
"dx": -100,
"dy": 250,
"size": 700
"dx": -38,
"dy": -79,
"size": 692
}
},
{
"vis": {
"dx": -7,
"dy": -19
}
},
{
"vis": {
"dx": 19,
"dy": -27
"dx": 0,
"dy": 0
}
},
{},
{},
{},
{}
],
"frameStyle": "chamfer",
"frameStyle": "rund",
"layoutState": [
"standard",
"ecke",
"standard",
"standard",
"standard",
+29 -8
View File
@@ -25,7 +25,7 @@
"int": "dezent"
}
],
"current": 0,
"current": 2,
"deck": [
{
"ref": "titel",
@@ -39,7 +39,9 @@
},
{
"ref": "wechseln",
"werte": {}
"werte": {
"body": "Da hängen Jahre an Stammdaten, Aufträgen und Buchhaltung drin und die Leute, die es kennen."
}
},
{
"ref": "mehr",
@@ -51,7 +53,9 @@
},
{
"ref": "warteliste",
"werte": {}
"werte": {
"body": "Setz dich auf die Warteliste, dann melden wir uns."
}
}
],
"edits": [
@@ -65,20 +69,37 @@
"dy": -96
},
"vis": {
"dx": 3,
"dy": -146
"dx": -38,
"dy": -79,
"size": 692
}
},
{
"body": {},
"vis": {
"dx": 0,
"dy": 0
}
},
{
"body": {
"dx": 0,
"dy": 0
},
"headline": {}
},
{
"body": {},
"headline": {
"dx": 0,
"dy": 0
},
"vis": {}
},
{},
{},
{},
{}
{
"body": {}
}
],
"frameStyle": "rund",
"layoutState": [