Post 9: Varianten überarbeitet, Variante 6 und 7 nach Noahs Arbeitsheft

- Variante 2/3: Webinar statt HiveGrid, Noahs Satz zum Kopf des Chefs,
  vorher und heute am Beispiel „Angebot nachfassen“ als Schema
- Variante 4/5: drei verschiedene Grafiken, Wabenanimation gelb dann rot,
  Titel mit Wabenwelle animiert
- Variante 6/7: Aussagen, Zeichnungen und Schriften aus „Jede Frage lief
  über meinen Tisch“, Titel dunkel, Pfeile werden gezeichnet (Test)
- post9-hub.mjs legt alle Varianten als Bilder und Videos ins Marketing-Hub
- Menüs aller Posts und Übersicht mit Variante 6 und 7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5.5 committed 2026-11-06 21:51:51 +01:00
1 parent f9f48609dd
commit 07deacde41
39 files changed
+18434 -205

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
View File
@@ -810,6 +810,8 @@ if (location.search.indexOf("nur=streifen") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1113,6 +1113,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1006,6 +1006,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1026,6 +1026,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1054,6 +1054,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1054,6 +1054,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1058,6 +1058,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1068,6 +1068,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+2
View File
@@ -1068,6 +1068,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+111
View File
@@ -0,0 +1,111 @@
// Legt alle Varianten von Post 9 ins Marketing-Hub, damit Noah sie auf
// hivegrid-marketing.pages.dev sieht (Dejan, 04.11.2026). Die Seiten in
// PostGrid laufen nur lokal, deshalb kommen dort Bilder und Videos an:
//
// jede Slide als PNG, 1080 x 1080, so wie der Streifen sie zeigt
// die animierten Slides als MP4 aus animation/
// varianten.json mit Reihenfolge und Texten fuer die Webinar-Seite
//
// Aufruf, wenn PostGrid laeuft (./serve.sh): node post9-hub.mjs
// Danach im Hub committen, pushen und ./veroeffentlichen.sh.
//
// Vorher die Animationen neu bauen, wenn sich an ihnen etwas geaendert hat:
// node animation.mjs post9.html animWebinar 1x1
// node animation.mjs post9-v4.html animBuerokratie 1x1 (ebenso animKi, v5)
import { spawn } from "node:child_process";
import { writeFile, mkdir, copyFile, rm, readdir } from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
const HUB = path.resolve("../HiveGrid Marketing /webinar/anzeigen/post9");
const POSTGRID = "http://127.0.0.1:4321/";
/* Reihenfolge im Carousel. "bild:n" ist Slide n des Streifens, "video:x"
eine Datei aus animation/. In Variante 1 steht das Video vorn, in 4 und 5
ersetzen die Videos Slide 2 und 3 des Streifens (dort steht ihr Endstand). */
const VARIANTEN = [
{ nr: 1, datei: "post9.html", name: "Webinar-Fenster",
text: "Das Bewegtbild zeigt das Webinar mit seinen Teilen und beiden Sprechern, danach die Anmeldung.",
folge: ["video:post9-animWebinar-1x1.mp4", "bild:0"] },
{ nr: 2, datei: "post9-v2.html", name: "Kundengeschichte",
text: "Angelehnt an ein Karussell von weclapp. Noah als Gesicht, dann vorher und heute am Beispiel „Angebot nachfassen“, dann die Anmeldung.",
folge: ["bild:0", "bild:1", "bild:2", "bild:3", "bild:4"] },
{ nr: 3, datei: "post9-v3.html", name: "Kundengeschichte dunkel",
text: "Wie Variante 2, auf dunklem Grund.",
folge: ["bild:0", "bild:1", "bild:2", "bild:3", "bild:4"] },
{ nr: 4, datei: "post9-v4.html", name: "Zahlen",
text: "Angelehnt an HERO Insights. Noah als Teaser, dann drei Zahlen aus Studien zur Zeit im Handwerk, dann die Anmeldung. Slide 1 bis 3 sind kurze Videos.",
folge: ["video:post9-v4-animTitel-1x1.mp4", "video:post9-v4-animBuerokratie-1x1.mp4", "video:post9-v4-animKi-1x1.mp4", "bild:3", "bild:4"] },
{ nr: 5, datei: "post9-v5.html", name: "Zahlen dunkel",
text: "Wie Variante 4, auf dunklem Grund.",
folge: ["video:post9-v5-animTitel-1x1.mp4", "video:post9-v5-animBuerokratie-1x1.mp4", "video:post9-v5-animKi-1x1.mp4", "bild:3", "bild:4"] },
{ nr: 6, datei: "post9-v6.html", name: "Arbeitsheft",
text: "Aussagen und Zeichnungen aus Noahs Arbeitsheft „Jede Frage lief über meinen Tisch“, im Look des Hefts, der Titel dunkel wie der Umschlag. Vom Engpass über die Inseln und den Bewegungsmelder bis zu den zehn Handgriffen, dann die Anmeldung. Auf dem Titel werden die Pfeile gezeichnet (Test).",
folge: ["video:post9-v6-animTitel-1x1.mp4", "bild:1", "bild:2", "bild:3", "bild:4", "bild:5"] },
{ nr: 7, datei: "post9-v7.html", name: "Arbeitsheft dunkel",
text: "Wie Variante 6, auf dunklem Grund.",
folge: ["video:post9-v7-animTitel-1x1.mp4", "bild:1", "bild:2", "bild:3", "bild:4", "bild:5"] },
];
const PORT = 9542;
const profil = path.join(tmpdir(), "pg-hub");
const chrome = spawn("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
["--headless", "--disable-gpu", "--hide-scrollbars", "--remote-debugging-port=" + PORT,
"--user-data-dir=" + profil, "about:blank"], { stdio: "ignore" });
let ziele;
for (let i = 0; i < 60; i++) {
ziele = await fetch(`http://127.0.0.1:${PORT}/json/list`).then(r => r.json()).catch(() => null);
if (ziele && ziele.some(t => t.type === "page")) break;
await new Promise(r => setTimeout(r, 200));
}
const ws = new WebSocket(ziele.find(t => t.type === "page").webSocketDebuggerUrl);
const offen = new Map(); let n = 0;
ws.onmessage = e => { const m = JSON.parse(e.data); if (m.id && offen.has(m.id)) { offen.get(m.id)(m); offen.delete(m.id); } };
await new Promise(ok => ws.onopen = ok);
const ruf = (method, params = {}) => new Promise((ok, weg) => { const id = ++n;
offen.set(id, m => m.error ? weg(new Error(m.error.message)) : ok(m.result)); ws.send(JSON.stringify({ id, method, params })); });
const warte = ms => new Promise(r => setTimeout(r, ms));
await ruf("Page.enable"); await ruf("Runtime.enable");
await rm(HUB, { recursive: true, force: true });
await mkdir(HUB, { recursive: true });
const liste = [];
for (const v of VARIANTEN) {
/* Breit genug fuer jeden Streifen, danach auf die echte Breite stellen. */
await ruf("Emulation.setDeviceMetricsOverride", { width: 7560, height: 1080, deviceScaleFactor: 1, mobile: false });
await ruf("Page.navigate", { url: POSTGRID + v.datei + "?nur=streifen&format=1x1" });
await warte(4500);
const breite = (await ruf("Runtime.evaluate", { expression: "document.documentElement.scrollWidth", returnByValue: true })).result.value;
const anzahl = Math.round(breite / 1080);
const slides = [];
for (const [i, teil] of v.folge.entries()) {
const [art, wert] = teil.split(":");
const name = `v${v.nr}-${i + 1}` + (art === "video" ? ".mp4" : ".png");
if (art === "video") {
await copyFile(path.join("animation", wert), path.join(HUB, name));
} else {
const k = Number(wert);
if (k >= anzahl) throw new Error(`${v.datei}: Slide ${k + 1} fehlt im Streifen (${anzahl} Slides)`);
const bild = await ruf("Page.captureScreenshot", { format: "png",
clip: { x: k * 1080, y: 0, width: 1080, height: 1080, scale: 1 } });
await writeFile(path.join(HUB, name), Buffer.from(bild.data, "base64"));
}
slides.push({ art: art === "video" ? "video" : "bild", datei: name });
}
liste.push({ nr: v.nr, name: v.name, text: v.text, slides });
console.log(`Variante ${v.nr}: ${slides.length} Elemente`);
}
const heute = new Date().toISOString().slice(0, 10);
await writeFile(path.join(HUB, "varianten.json"), JSON.stringify({
titel: "Post 9 · Webinar-Anzeige",
stand: heute,
hinweis: "Format 1:1 für die Anzeige. Datum und Uhrzeit des Webinars sind noch Platzhalter.",
varianten: liste,
}, null, 1) + "\n");
console.log("Fertig:", (await readdir(HUB)).length, "Dateien in", HUB);
ws.close();
if (chrome.exitCode === null) { const zu = new Promise(ok => chrome.once("exit", ok)); chrome.kill(); await zu; }
await rm(profil, { recursive: true, force: true }).catch(() => {});
+135 -52
View File
@@ -1063,6 +1063,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
@@ -1451,13 +1453,21 @@ if (location.search.indexOf("nur=anim") >= 0)
KEINE ERFUNDENEN ZAHLEN. weclapp beginnt mit einem Ergebnis in Zahlen.
Fuer Geerkens gibt es keine gemessene Zahl, also steht keine da. Belegt:
- vierte Generation, mit der Schwester, „Wir wollten auch gar nicht
wechseln. Wir wollten mehr. KI-Lösungen. Ein CRM.
Automatisierungen.“: Website, LandingPageClient.tsx, „Warum es
HiveGrid gibt“
- Postfach und Zettel, Nachfassen, WhatsApp-Gruppe, Urlaubsliste,
Passwort am Bildschirm, KWP und PDS: Webinar-Skript (Hub,
webinar/Skript.md), Noahs Teile „Bei uns war es so“
- vierte Generation: Website, LandingPageClient.tsx
- „Ich kriege das, was in meinem Kopf ist, nicht in die Ausführung.“:
Noah, festgehalten in Kontext.md im Hub, im Webinar Slide „problem“
- Postfach, Zettel im Auto, WhatsApp-Gruppe, Excel-Liste: Webinar-
Skript (Hub, webinar/Skript.md), Noahs Teile „Bei uns war es so“.
Ordner und Kopf: „Bei Geerkens war es vorher auch so“ im PDF
„Dunford und JOLT im Trichter“ vom 03.11.2026, Kapitel 3
- Das Branchenprogramm bleibt: Website, „kein Ersatz für dein
Branchenprogramm“
Umbau 04.11.2026 (Dejan): HiveGrid kommt im Text nicht mehr vor, es geht
um das Webinar. Slide 3 und 4 als Bild statt Liste, keine Fachwoerter
wie CRM, Pipeline oder Automatisierung. Grundlage sind die drei PDFs
aus dem Vertrieb (02. und 03.11.): Anzeigen holen den Betrieb bei der
Szene ab, in der er sich wiedererkennt, nicht beim Produkt.
Fotos: assets/eigene/geerkens-team.jpg (Dejan, 02.11.2026),
assets/team/noah-person.webp und assets/brand/geerkens-logo.png aus
Post 2. Wer auf dem Teamfoto steht, ist nicht bekannt, deshalb kein
@@ -1470,8 +1480,8 @@ if (location.search.indexOf("nur=anim") >= 0)
const VORLAGEN = [
V2_VORLAGE("betrieb", "Der Betrieb"),
V2_VORLAGE("zitat", "Das Zitat"),
V2_VORLAGE("vorher", "Die Ausgangslage"),
V2_VORLAGE("nachher", "Mit HiveGrid"),
V2_VORLAGE("vorher", "Vorher"),
V2_VORLAGE("nachher", "Heute"),
V2_VORLAGE("anmeldung", "Jetzt anmelden"),
];
@@ -5024,17 +5034,6 @@ if (location.search.indexOf("nur=anim") >= 0)
'<g clip-path="url(#' + id + ')">' + m + "</g>";
}
/* Eine Liste mit Waben als Aufzaehlungszeichen, je Punkt zwei Zeilen. */
function v2Liste(y0, punkte, zeichenFarbe) {
let g = "";
punkte.forEach((p, i) => {
const y = y0 + i * 116;
g += v2Wabe(V2_RAND + 13, y - 10, 13, zeichenFarbe);
p.forEach((z, j) => { g += v2Text(V2_RAND + 50, y + j * 40, z, 31, V2.text, { gew: 700, sperr: "-0.01em" }); });
});
return g;
}
/* 1 · Der Betrieb. weclapp: „In 15 Monaten auf 11 Standorte. Das steckt
hinter dem Erfolg von PV Green.“ Eine Zahl haben wir nicht, also traegt
die Tatsache: vierte Generation. */
@@ -5045,10 +5044,12 @@ if (location.search.indexOf("nur=anim") >= 0)
g += v2Wabe(1050, 120, 170, V2.gelb); // oben rechts
g += v2Wabe(40, H - 70, 300, V2.form); // hinter dem Foto
g += v2Logo(V2_RAND, 86, 42);
g += v2Chamfer(V2_RAND + 180, 82, 292, 50, 10, V2.gelbHell);
g += uiText(V2_RAND + 180 + 146, 115, "AUS DEM HANDWERK", 19, 700, V2.gelbText, { anker: "middle", sperr: "0.14em" });
/* Seit 04.11.2026 das Webinar statt „Aus dem Handwerk“: Die Anzeige
laedt ins Webinar ein und nicht zu HiveGrid. */
g += v2Chamfer(V2_RAND + 180, 82, 236, 50, 10, V2.gelbHell);
g += uiText(V2_RAND + 180 + 118, 115, "LIVE-WEBINAR", 19, 700, V2.gelbText, { anker: "middle", sperr: "0.14em" });
[["SHK-Betrieb in", V2.gelb], ["vierter Generation.", V2.gelb],
["Das steckt hinter", V2.text], ["HiveGrid.", V2.text]].forEach(([z, f], i) => {
["Wie er Zeit spart,", V2.text], ["zeigt Noah im Webinar.", V2.text]].forEach(([z, f], i) => {
g += v2Text(V2_RAND, 232 + i * 70, z, 64, f);
});
const fy = 500, fb = 780, fh = H - fy - 132;
@@ -5067,9 +5068,15 @@ if (location.search.indexOf("nur=anim") >= 0)
return v2Svg(g);
}
/* 2 · Das Zitat. Der Satz steht so auf der Website, „Warum es HiveGrid
gibt“. Noah freigestellt vor einer grossen gelben Wabe: Er traegt
Schwarz, vor dem Dunkel waere er darin verschwunden. */
/* 2 · Das Zitat. Noah ueber seine Rolle als Chef, so festgehalten im Hub
(Brainstorming Kickoff/Kontext/Kontext.md) und im Webinar auf der Slide
„problem“. Seit 04.11.2026 (Dejan: mehr um Zeit und das, was von selbst
laeuft): Der Satz oeffnet die Geschichte von Slide 3 und 4, was im Kopf
des Chefs haengt, laeuft heute von selbst. Davor stand „Kein Chef fährt
seinen Betrieb für ein halbes Jahr an die Wand …“ (Website), davor
„KI-Lösungen. Ein CRM. Automatisierungen.“ (zu technisch). Noah
freigestellt vor einer grossen gelben Wabe: Er traegt Schwarz, vor dem
Dunkel waere er darin verschwunden. */
function v2Zitat() {
v2Ton();
const H = SLIDE_H;
@@ -5077,13 +5084,15 @@ if (location.search.indexOf("nur=anim") >= 0)
g += v2Wabe(60, H - 40, 150, V2.form);
g += v2UebergangWabe(0);
g += v2Logo(1080 - V2_RAND, 86, 42, { rechts: true });
[["„Wir wollten auch gar", V2.text], ["nicht wechseln.", V2.text], ["Wir wollten mehr.", V2.gelb],
["KI-Lösungen. Ein CRM.", V2.text], ["Automatisierungen.“", V2.text]].forEach(([z, f], i) => {
[["„Ich kriege das,", V2.text], ["was in meinem Kopf ist,", V2.gelb],
["nicht in die", V2.text], ["Ausführung.“", V2.text]].forEach(([z, f], i) => {
g += v2Text(V2_RAND - 12, 236 + i * 66, z, 56, f);
});
g += uiText(V2_RAND, 640, "NOAH GEERKENS", 30, 800, V2.kopf, { sperr: "0.04em" });
g += uiText(V2_RAND, 682, "Handwerksmeister und Gründer", 23, 600, V2.text2);
g += uiText(V2_RAND, 714, "SHK-Betrieb in vierter Generation", 23, 600, V2.text2);
g += v2Chamfer(V2_RAND, 574, 236, 46, 10, V2.gelbHell);
g += uiText(V2_RAND + 118, 605, "LIVE-WEBINAR", 18, 700, V2.gelbText, { anker: "middle", sperr: "0.14em" });
g += uiText(V2_RAND, 676, "NOAH GEERKENS", 30, 800, V2.kopf, { sperr: "0.04em" });
g += uiText(V2_RAND, 718, "Handwerksmeister", 23, 600, V2.text2);
g += uiText(V2_RAND, 750, "SHK-Betrieb in vierter Generation", 23, 600, V2.text2);
/* noah-person.webp ist 1600 x 1049, die Person steht etwa zwischen 20
und 75 Prozent der Breite. So gesetzt, dass sie rechts unten steht. */
const pb = 980, ph = pb * 1049 / 1600;
@@ -5091,38 +5100,109 @@ if (location.search.indexOf("nur=anim") >= 0)
return v2Svg(g);
}
/* 3 · Die Ausgangslage. weclapp: „Herausforderungen“. Die vier Punkte
sind Noahs „Bei uns war es so“ aus dem Webinar-Skript. */
/* ─── Slide 3 und 4: vorher und heute ───────────────────────────────────
Stand 04.11.2026, dritter Umbau. Dejan: Es muss mehr um das gehen, was
von selbst laeuft, und um Zeit, aber ohne das Wort Automatisierung. Also
umschreiben und zeigen, an einem einzigen Fall: Angebot raus, und dann?
Das ist das Beispiel aus dem Webinar, Teil 2 („Wenn das passiert, dann
mach das.“) und im Vertrieb der staerkste Schmerz („Angebot raus und
dann passiert nichts“, PDF „Dunford und JOLT im Trichter“ vom 03.11.).
Vorbilder aus der Werbebibliothek (Nachtrag 04.11. in webinar/
Ad-Recherche.md im Hub): weclapp, Karte „vorher“ mit drei kurzen Zeilen
(ID 2419932468433925); Zapier, drei Schritte in Alltagssprache als
Karten untereinander, mit einer Linie verbunden, am Ende das Ergebnis
(ID 393789279875187, laeuft seit Januar 2024). Slide 3 sind die drei
Handgriffe des Chefs, Slide 4 dieselben drei als Kette, die von selbst
laeuft. Das ist der Ablauf „Angebot nachfassen“ aus dem Webinar, Teil 2,
als Schema und nicht als Screen: Dejan, 04.11.2026, „es sollen nur
Schemas und Prozesse dargestellt werden, wir verkaufen das Produkt
nicht“. Der Nachbau des Editors davor sah zu sehr nach angeschnittenem
Screenshot aus. */
/* Lucide-Formen, wie sie Subframe als Feather-Icons zeichnet
(lucide-static 0.460.0, wie LUCIDE in Post 8). */
const V2_LUCIDE = {
"send": '<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>',
"clock": '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
"phone": '<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>',
};
const v2Lucide = (name, cx, cy, s, farbe, strich) =>
'<g transform="translate(' + n1(cx - s / 2) + ',' + n1(cy - s / 2) + ') scale(' + (s / 24).toFixed(4) +
')" fill="none" stroke="' + farbe + '" stroke-width="' + (strich || 2) +
'" stroke-linecap="round" stroke-linejoin="round">' + V2_LUCIDE[name] + "</g>";
/* Die Ueberschrift beider Slides: Rubrik, darunter eine Zeile. */
function v2KopfZeilen(rubrik, farbe, zeilen) {
let g = v2Text(V2_RAND, 200, rubrik, 52, farbe, { sperr: "0.01em" });
zeilen.forEach((z, i) => { g += v2Text(V2_RAND, 262 + i * 46, z, 38, V2.text, { gew: 700 }); });
return g;
}
/* 3 · Vorher. Die Karte „vorher“ von weclapp: drei Zeilen, je ein Zeichen.
Was der Chef selbst machen musste, damit ein Angebot nicht liegen
bleibt. Auf Slide 4 macht das der Ablauf. */
const V2_HANDGRIFFE = [
["send", "Das Angebot geht raus."],
["clock", "Drei Tage dran denken."],
["phone", "Abends nachtelefonieren."],
];
function v2Vorher() {
v2Ton();
const dunkel = variant === "dunkel", dy = (SLIDE_H - 1080) / 2;
let g = "";
g += v2Logo(1080 - V2_RAND, 86, 42, { rechts: true });
g += v2Text(V2_RAND, 262, "DIE AUSGANGSLAGE", 52, V2.kopf, { sperr: "0.01em" });
g += v2Liste(372, [
["Anfragen landen im Postfach", "und auf Zetteln im Auto"],
["Nach dem Angebot fragt keiner nach,", "jeder denkt, der andere ruft an"],
["Fotos, Urlaub, Material: alles in", "einer WhatsApp-Gruppe"],
["Urlaubsliste in Excel, das Passwort", "fürs Großhändler-Portal am Bildschirm"],
], V2.kopf);
g += v2KopfZeilen("VORHER", V2.kopf, ["Alles hing am Kopf vom Chef."]);
const x = V2_RAND, y = 340 + dy, b = 770, zh = 132, h = 3 * zh + 36;
g += v2Chamfer(x, y, b, h, 18, dunkel ? "#16243B" : "#F5F4F4",
dunkel ? { stroke: "rgba(255,255,255,.12)" } : null);
V2_HANDGRIFFE.forEach(([zeichen, text], i) => {
const ym = y + 18 + i * zh + zh / 2;
if (i) g += '<path d="M' + (x + 36) + "," + n1(y + 18 + i * zh) + "H" + (x + b - 36) +
'" stroke="' + (dunkel ? "rgba(255,255,255,.12)" : "#E5E5E5") + '" stroke-width="1.5"/>';
g += v2Chamfer(x + 36, ym - 36, 72, 72, 10, dunkel ? "rgba(255,255,255,.08)" : "#FFFFFF",
dunkel ? null : { stroke: "#E5E5E5" });
g += v2Lucide(zeichen, x + 72, ym, 34, dunkel ? "#FFFFFF" : "#24242B");
g += v2Text(x + 140, ym + 13, text, 36, V2.text, { gew: 700, sperr: "-0.01em" });
});
g += v2Band(SLIDE_H - V2_BAND_H, 2);
g += v2UebergangWabe(-1080);
return v2Svg(g);
}
/* 4 · Mit HiveGrid. weclapp: „Ergebnisse“, im Akzent. Gemessene
Ergebnisse gibt es nicht, deshalb steht hier, was sich aendert: die
Teile des Webinars und das Versprechen, dass das Programm bleibt. */
/* 4 · Heute. Dieselben drei Handgriffe wie auf Slide 3, jetzt als Kette
wie bei Zapier: Karten untereinander, eine Linie dazwischen, die Zeichen
gelb, weil das jetzt erledigt ist. Liest sich als ein Satz. Am Ende das
Ergebnis als Etikett, wie das „Faster communication“ bei Zapier. Inhalt
wie die Notiz im Webinar-Ablauf (S08): „Kommt ein Projekt auf ‚Angebot
versendet‘, ruft das Büro nach drei Tagen beim Kunden an. Der Chef
bekommt Bescheid.“ */
const V2_KETTE = [
["send", "Wenn ein Angebot rausgeht,"],
["clock", "nach drei Tagen"],
["phone", "steht der Anruf auf der Liste."],
];
function v2Nachher() {
v2Ton();
const dunkel = variant === "dunkel", dy = (SLIDE_H - 1080) / 2;
let g = "";
g += v2Logo(1080 - V2_RAND, 86, 42, { rechts: true });
g += v2Text(V2_RAND, 262, "MIT HIVEGRID", 52, V2.gelb, { sperr: "0.01em" });
g += v2Liste(372, [
["Jede Anfrage landet in der Pipeline,", "bis daraus ein Auftrag wird"],
["Das Nachfassen läuft automatisch,", "über die Workflow-Engine"],
["Chat, Personal und Passwörter", "an einem Ort statt verstreut"],
["Das Branchenprogramm bleibt und ist", "angebunden, zum Beispiel KWP und PDS"],
], V2.gelb);
g += v2KopfZeilen("HEUTE", V2.gelb, ["Dran denken muss keiner mehr."]);
const x = V2_RAND, b = 770, kh = 104, luecke = 40, y0 = 334 + dy;
const linie = dunkel ? "rgba(255,255,255,.28)" : "#B5B5B7";
V2_KETTE.forEach(([zeichen, text], i) => {
const y = y0 + i * (kh + luecke), ym = y + kh / 2;
g += v2Chamfer(x, y, b, kh, 16, dunkel ? "#16243B" : "#F5F4F4",
dunkel ? { stroke: "rgba(255,255,255,.12)" } : null);
g += v2Chamfer(x + 22, ym - 32, 64, 64, 10, V2.gelb);
g += v2Lucide(zeichen, x + 54, ym, 30, "#1A1A1A");
g += v2Text(x + 112, ym + 13, text, 36, V2.text, { gew: 700, sperr: "-0.01em" });
/* Die Linie zur naechsten Karte, unter den Zeichen. */
g += '<path d="M' + (x + 54) + "," + n1(y + kh) + "V" + n1(y + kh + luecke) +
'" stroke="' + linie + '" stroke-width="2"/>';
});
const ty = y0 + 3 * (kh + luecke);
g += v2Chamfer(x + 22, ty, 404, 56, 12, V2.gelbHell);
g += v2Text(x + 22 + 202, ty + 37, "Und der Chef weiß Bescheid.", 26, V2.gelbText, { anker: "middle", gew: 800, sperr: "-0.01em" });
g += v2Band(SLIDE_H - V2_BAND_H, 3);
return v2Svg(g);
}
@@ -5138,12 +5218,15 @@ if (location.search.indexOf("nur=anim") >= 0)
g += v2BandEnde();
g += v2Text(m, 300 + dy, "Live zuschauen,", 56, V2.gelb, { anker: "middle" });
g += v2Text(m, 366 + dy, "live fragen:", 56, V2.gelb, { anker: "middle" });
g += v2Text(m, 462 + dy, "Automatisierung im Handwerk.", 50, V2.text, { anker: "middle" });
/* Bis 04.11.2026 „Automatisierung im Handwerk.“, der Arbeitstitel des
Webinars. Der Titel ist noch offen (Hub, daten/webinar.json), und das
Wort ist zu technisch (Dejan). */
g += v2Text(m, 462 + dy, "Weniger Zeit im Büro.", 50, V2.text, { anker: "middle" });
g += v2Text(m, 522 + dy, "Mit dem Programm, das du hast.", 50, V2.text, { anker: "middle" });
const kb = 420, kh = 88, ky = 590 + dy;
g += v2Chamfer(m - kb / 2, ky, kb, kh, 16, V2.gelb);
g += uiText(m, ky + 56, "Jetzt anmelden", 32, 800, V2.aufHell, { anker: "middle" });
g += uiText(m, ky + 160, WEBINAR.wochentag + ", " + WEBINAR.datum + ", " + WEBINAR.uhrzeit + " Uhr, online",
g += uiText(m, ky + 160, "Webinar am " + WEBINAR.wochentag + ", " + WEBINAR.datum + ", " + WEBINAR.uhrzeit + " Uhr, online",
26, 600, V2.text2, { anker: "middle" });
g += uiText(m, ky + 198, "Mit Noah Geerkens und David Bertram", 26, 600, V2.text2, { anker: "middle" });
g += v2Logo(m, H - 150, 46, { mitte: true });
+135 -52
View File
@@ -1063,6 +1063,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
@@ -1451,13 +1453,21 @@ if (location.search.indexOf("nur=anim") >= 0)
KEINE ERFUNDENEN ZAHLEN. weclapp beginnt mit einem Ergebnis in Zahlen.
Fuer Geerkens gibt es keine gemessene Zahl, also steht keine da. Belegt:
- vierte Generation, mit der Schwester, „Wir wollten auch gar nicht
wechseln. Wir wollten mehr. KI-Lösungen. Ein CRM.
Automatisierungen.“: Website, LandingPageClient.tsx, „Warum es
HiveGrid gibt“
- Postfach und Zettel, Nachfassen, WhatsApp-Gruppe, Urlaubsliste,
Passwort am Bildschirm, KWP und PDS: Webinar-Skript (Hub,
webinar/Skript.md), Noahs Teile „Bei uns war es so“
- vierte Generation: Website, LandingPageClient.tsx
- „Ich kriege das, was in meinem Kopf ist, nicht in die Ausführung.“:
Noah, festgehalten in Kontext.md im Hub, im Webinar Slide „problem“
- Postfach, Zettel im Auto, WhatsApp-Gruppe, Excel-Liste: Webinar-
Skript (Hub, webinar/Skript.md), Noahs Teile „Bei uns war es so“.
Ordner und Kopf: „Bei Geerkens war es vorher auch so“ im PDF
„Dunford und JOLT im Trichter“ vom 03.11.2026, Kapitel 3
- Das Branchenprogramm bleibt: Website, „kein Ersatz für dein
Branchenprogramm“
Umbau 04.11.2026 (Dejan): HiveGrid kommt im Text nicht mehr vor, es geht
um das Webinar. Slide 3 und 4 als Bild statt Liste, keine Fachwoerter
wie CRM, Pipeline oder Automatisierung. Grundlage sind die drei PDFs
aus dem Vertrieb (02. und 03.11.): Anzeigen holen den Betrieb bei der
Szene ab, in der er sich wiedererkennt, nicht beim Produkt.
Fotos: assets/eigene/geerkens-team.jpg (Dejan, 02.11.2026),
assets/team/noah-person.webp und assets/brand/geerkens-logo.png aus
Post 2. Wer auf dem Teamfoto steht, ist nicht bekannt, deshalb kein
@@ -1470,8 +1480,8 @@ if (location.search.indexOf("nur=anim") >= 0)
const VORLAGEN = [
V2_VORLAGE("betrieb", "Der Betrieb"),
V2_VORLAGE("zitat", "Das Zitat"),
V2_VORLAGE("vorher", "Die Ausgangslage"),
V2_VORLAGE("nachher", "Mit HiveGrid"),
V2_VORLAGE("vorher", "Vorher"),
V2_VORLAGE("nachher", "Heute"),
V2_VORLAGE("anmeldung", "Jetzt anmelden"),
];
@@ -5024,17 +5034,6 @@ if (location.search.indexOf("nur=anim") >= 0)
'<g clip-path="url(#' + id + ')">' + m + "</g>";
}
/* Eine Liste mit Waben als Aufzaehlungszeichen, je Punkt zwei Zeilen. */
function v2Liste(y0, punkte, zeichenFarbe) {
let g = "";
punkte.forEach((p, i) => {
const y = y0 + i * 116;
g += v2Wabe(V2_RAND + 13, y - 10, 13, zeichenFarbe);
p.forEach((z, j) => { g += v2Text(V2_RAND + 50, y + j * 40, z, 31, V2.text, { gew: 700, sperr: "-0.01em" }); });
});
return g;
}
/* 1 · Der Betrieb. weclapp: „In 15 Monaten auf 11 Standorte. Das steckt
hinter dem Erfolg von PV Green.“ Eine Zahl haben wir nicht, also traegt
die Tatsache: vierte Generation. */
@@ -5045,10 +5044,12 @@ if (location.search.indexOf("nur=anim") >= 0)
g += v2Wabe(1050, 120, 170, V2.gelb); // oben rechts
g += v2Wabe(40, H - 70, 300, V2.form); // hinter dem Foto
g += v2Logo(V2_RAND, 86, 42);
g += v2Chamfer(V2_RAND + 180, 82, 292, 50, 10, V2.gelbHell);
g += uiText(V2_RAND + 180 + 146, 115, "AUS DEM HANDWERK", 19, 700, V2.gelbText, { anker: "middle", sperr: "0.14em" });
/* Seit 04.11.2026 das Webinar statt „Aus dem Handwerk“: Die Anzeige
laedt ins Webinar ein und nicht zu HiveGrid. */
g += v2Chamfer(V2_RAND + 180, 82, 236, 50, 10, V2.gelbHell);
g += uiText(V2_RAND + 180 + 118, 115, "LIVE-WEBINAR", 19, 700, V2.gelbText, { anker: "middle", sperr: "0.14em" });
[["SHK-Betrieb in", V2.gelb], ["vierter Generation.", V2.gelb],
["Das steckt hinter", V2.text], ["HiveGrid.", V2.text]].forEach(([z, f], i) => {
["Wie er Zeit spart,", V2.text], ["zeigt Noah im Webinar.", V2.text]].forEach(([z, f], i) => {
g += v2Text(V2_RAND, 232 + i * 70, z, 64, f);
});
const fy = 500, fb = 780, fh = H - fy - 132;
@@ -5067,9 +5068,15 @@ if (location.search.indexOf("nur=anim") >= 0)
return v2Svg(g);
}
/* 2 · Das Zitat. Der Satz steht so auf der Website, „Warum es HiveGrid
gibt“. Noah freigestellt vor einer grossen gelben Wabe: Er traegt
Schwarz, vor dem Dunkel waere er darin verschwunden. */
/* 2 · Das Zitat. Noah ueber seine Rolle als Chef, so festgehalten im Hub
(Brainstorming Kickoff/Kontext/Kontext.md) und im Webinar auf der Slide
„problem“. Seit 04.11.2026 (Dejan: mehr um Zeit und das, was von selbst
laeuft): Der Satz oeffnet die Geschichte von Slide 3 und 4, was im Kopf
des Chefs haengt, laeuft heute von selbst. Davor stand „Kein Chef fährt
seinen Betrieb für ein halbes Jahr an die Wand …“ (Website), davor
„KI-Lösungen. Ein CRM. Automatisierungen.“ (zu technisch). Noah
freigestellt vor einer grossen gelben Wabe: Er traegt Schwarz, vor dem
Dunkel waere er darin verschwunden. */
function v2Zitat() {
v2Ton();
const H = SLIDE_H;
@@ -5077,13 +5084,15 @@ if (location.search.indexOf("nur=anim") >= 0)
g += v2Wabe(60, H - 40, 150, V2.form);
g += v2UebergangWabe(0);
g += v2Logo(1080 - V2_RAND, 86, 42, { rechts: true });
[["„Wir wollten auch gar", V2.text], ["nicht wechseln.", V2.text], ["Wir wollten mehr.", V2.gelb],
["KI-Lösungen. Ein CRM.", V2.text], ["Automatisierungen.“", V2.text]].forEach(([z, f], i) => {
[["„Ich kriege das,", V2.text], ["was in meinem Kopf ist,", V2.gelb],
["nicht in die", V2.text], ["Ausführung.“", V2.text]].forEach(([z, f], i) => {
g += v2Text(V2_RAND - 12, 236 + i * 66, z, 56, f);
});
g += uiText(V2_RAND, 640, "NOAH GEERKENS", 30, 800, V2.kopf, { sperr: "0.04em" });
g += uiText(V2_RAND, 682, "Handwerksmeister und Gründer", 23, 600, V2.text2);
g += uiText(V2_RAND, 714, "SHK-Betrieb in vierter Generation", 23, 600, V2.text2);
g += v2Chamfer(V2_RAND, 574, 236, 46, 10, V2.gelbHell);
g += uiText(V2_RAND + 118, 605, "LIVE-WEBINAR", 18, 700, V2.gelbText, { anker: "middle", sperr: "0.14em" });
g += uiText(V2_RAND, 676, "NOAH GEERKENS", 30, 800, V2.kopf, { sperr: "0.04em" });
g += uiText(V2_RAND, 718, "Handwerksmeister", 23, 600, V2.text2);
g += uiText(V2_RAND, 750, "SHK-Betrieb in vierter Generation", 23, 600, V2.text2);
/* noah-person.webp ist 1600 x 1049, die Person steht etwa zwischen 20
und 75 Prozent der Breite. So gesetzt, dass sie rechts unten steht. */
const pb = 980, ph = pb * 1049 / 1600;
@@ -5091,38 +5100,109 @@ if (location.search.indexOf("nur=anim") >= 0)
return v2Svg(g);
}
/* 3 · Die Ausgangslage. weclapp: „Herausforderungen“. Die vier Punkte
sind Noahs „Bei uns war es so“ aus dem Webinar-Skript. */
/* ─── Slide 3 und 4: vorher und heute ───────────────────────────────────
Stand 04.11.2026, dritter Umbau. Dejan: Es muss mehr um das gehen, was
von selbst laeuft, und um Zeit, aber ohne das Wort Automatisierung. Also
umschreiben und zeigen, an einem einzigen Fall: Angebot raus, und dann?
Das ist das Beispiel aus dem Webinar, Teil 2 („Wenn das passiert, dann
mach das.“) und im Vertrieb der staerkste Schmerz („Angebot raus und
dann passiert nichts“, PDF „Dunford und JOLT im Trichter“ vom 03.11.).
Vorbilder aus der Werbebibliothek (Nachtrag 04.11. in webinar/
Ad-Recherche.md im Hub): weclapp, Karte „vorher“ mit drei kurzen Zeilen
(ID 2419932468433925); Zapier, drei Schritte in Alltagssprache als
Karten untereinander, mit einer Linie verbunden, am Ende das Ergebnis
(ID 393789279875187, laeuft seit Januar 2024). Slide 3 sind die drei
Handgriffe des Chefs, Slide 4 dieselben drei als Kette, die von selbst
laeuft. Das ist der Ablauf „Angebot nachfassen“ aus dem Webinar, Teil 2,
als Schema und nicht als Screen: Dejan, 04.11.2026, „es sollen nur
Schemas und Prozesse dargestellt werden, wir verkaufen das Produkt
nicht“. Der Nachbau des Editors davor sah zu sehr nach angeschnittenem
Screenshot aus. */
/* Lucide-Formen, wie sie Subframe als Feather-Icons zeichnet
(lucide-static 0.460.0, wie LUCIDE in Post 8). */
const V2_LUCIDE = {
"send": '<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>',
"clock": '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
"phone": '<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>',
};
const v2Lucide = (name, cx, cy, s, farbe, strich) =>
'<g transform="translate(' + n1(cx - s / 2) + ',' + n1(cy - s / 2) + ') scale(' + (s / 24).toFixed(4) +
')" fill="none" stroke="' + farbe + '" stroke-width="' + (strich || 2) +
'" stroke-linecap="round" stroke-linejoin="round">' + V2_LUCIDE[name] + "</g>";
/* Die Ueberschrift beider Slides: Rubrik, darunter eine Zeile. */
function v2KopfZeilen(rubrik, farbe, zeilen) {
let g = v2Text(V2_RAND, 200, rubrik, 52, farbe, { sperr: "0.01em" });
zeilen.forEach((z, i) => { g += v2Text(V2_RAND, 262 + i * 46, z, 38, V2.text, { gew: 700 }); });
return g;
}
/* 3 · Vorher. Die Karte „vorher“ von weclapp: drei Zeilen, je ein Zeichen.
Was der Chef selbst machen musste, damit ein Angebot nicht liegen
bleibt. Auf Slide 4 macht das der Ablauf. */
const V2_HANDGRIFFE = [
["send", "Das Angebot geht raus."],
["clock", "Drei Tage dran denken."],
["phone", "Abends nachtelefonieren."],
];
function v2Vorher() {
v2Ton();
const dunkel = variant === "dunkel", dy = (SLIDE_H - 1080) / 2;
let g = "";
g += v2Logo(1080 - V2_RAND, 86, 42, { rechts: true });
g += v2Text(V2_RAND, 262, "DIE AUSGANGSLAGE", 52, V2.kopf, { sperr: "0.01em" });
g += v2Liste(372, [
["Anfragen landen im Postfach", "und auf Zetteln im Auto"],
["Nach dem Angebot fragt keiner nach,", "jeder denkt, der andere ruft an"],
["Fotos, Urlaub, Material: alles in", "einer WhatsApp-Gruppe"],
["Urlaubsliste in Excel, das Passwort", "fürs Großhändler-Portal am Bildschirm"],
], V2.kopf);
g += v2KopfZeilen("VORHER", V2.kopf, ["Alles hing am Kopf vom Chef."]);
const x = V2_RAND, y = 340 + dy, b = 770, zh = 132, h = 3 * zh + 36;
g += v2Chamfer(x, y, b, h, 18, dunkel ? "#16243B" : "#F5F4F4",
dunkel ? { stroke: "rgba(255,255,255,.12)" } : null);
V2_HANDGRIFFE.forEach(([zeichen, text], i) => {
const ym = y + 18 + i * zh + zh / 2;
if (i) g += '<path d="M' + (x + 36) + "," + n1(y + 18 + i * zh) + "H" + (x + b - 36) +
'" stroke="' + (dunkel ? "rgba(255,255,255,.12)" : "#E5E5E5") + '" stroke-width="1.5"/>';
g += v2Chamfer(x + 36, ym - 36, 72, 72, 10, dunkel ? "rgba(255,255,255,.08)" : "#FFFFFF",
dunkel ? null : { stroke: "#E5E5E5" });
g += v2Lucide(zeichen, x + 72, ym, 34, dunkel ? "#FFFFFF" : "#24242B");
g += v2Text(x + 140, ym + 13, text, 36, V2.text, { gew: 700, sperr: "-0.01em" });
});
g += v2Band(SLIDE_H - V2_BAND_H, 2);
g += v2UebergangWabe(-1080);
return v2Svg(g);
}
/* 4 · Mit HiveGrid. weclapp: „Ergebnisse“, im Akzent. Gemessene
Ergebnisse gibt es nicht, deshalb steht hier, was sich aendert: die
Teile des Webinars und das Versprechen, dass das Programm bleibt. */
/* 4 · Heute. Dieselben drei Handgriffe wie auf Slide 3, jetzt als Kette
wie bei Zapier: Karten untereinander, eine Linie dazwischen, die Zeichen
gelb, weil das jetzt erledigt ist. Liest sich als ein Satz. Am Ende das
Ergebnis als Etikett, wie das „Faster communication“ bei Zapier. Inhalt
wie die Notiz im Webinar-Ablauf (S08): „Kommt ein Projekt auf ‚Angebot
versendet‘, ruft das Büro nach drei Tagen beim Kunden an. Der Chef
bekommt Bescheid.“ */
const V2_KETTE = [
["send", "Wenn ein Angebot rausgeht,"],
["clock", "nach drei Tagen"],
["phone", "steht der Anruf auf der Liste."],
];
function v2Nachher() {
v2Ton();
const dunkel = variant === "dunkel", dy = (SLIDE_H - 1080) / 2;
let g = "";
g += v2Logo(1080 - V2_RAND, 86, 42, { rechts: true });
g += v2Text(V2_RAND, 262, "MIT HIVEGRID", 52, V2.gelb, { sperr: "0.01em" });
g += v2Liste(372, [
["Jede Anfrage landet in der Pipeline,", "bis daraus ein Auftrag wird"],
["Das Nachfassen läuft automatisch,", "über die Workflow-Engine"],
["Chat, Personal und Passwörter", "an einem Ort statt verstreut"],
["Das Branchenprogramm bleibt und ist", "angebunden, zum Beispiel KWP und PDS"],
], V2.gelb);
g += v2KopfZeilen("HEUTE", V2.gelb, ["Dran denken muss keiner mehr."]);
const x = V2_RAND, b = 770, kh = 104, luecke = 40, y0 = 334 + dy;
const linie = dunkel ? "rgba(255,255,255,.28)" : "#B5B5B7";
V2_KETTE.forEach(([zeichen, text], i) => {
const y = y0 + i * (kh + luecke), ym = y + kh / 2;
g += v2Chamfer(x, y, b, kh, 16, dunkel ? "#16243B" : "#F5F4F4",
dunkel ? { stroke: "rgba(255,255,255,.12)" } : null);
g += v2Chamfer(x + 22, ym - 32, 64, 64, 10, V2.gelb);
g += v2Lucide(zeichen, x + 54, ym, 30, "#1A1A1A");
g += v2Text(x + 112, ym + 13, text, 36, V2.text, { gew: 700, sperr: "-0.01em" });
/* Die Linie zur naechsten Karte, unter den Zeichen. */
g += '<path d="M' + (x + 54) + "," + n1(y + kh) + "V" + n1(y + kh + luecke) +
'" stroke="' + linie + '" stroke-width="2"/>';
});
const ty = y0 + 3 * (kh + luecke);
g += v2Chamfer(x + 22, ty, 404, 56, 12, V2.gelbHell);
g += v2Text(x + 22 + 202, ty + 37, "Und der Chef weiß Bescheid.", 26, V2.gelbText, { anker: "middle", gew: 800, sperr: "-0.01em" });
g += v2Band(SLIDE_H - V2_BAND_H, 3);
return v2Svg(g);
}
@@ -5138,12 +5218,15 @@ if (location.search.indexOf("nur=anim") >= 0)
g += v2BandEnde();
g += v2Text(m, 300 + dy, "Live zuschauen,", 56, V2.gelb, { anker: "middle" });
g += v2Text(m, 366 + dy, "live fragen:", 56, V2.gelb, { anker: "middle" });
g += v2Text(m, 462 + dy, "Automatisierung im Handwerk.", 50, V2.text, { anker: "middle" });
/* Bis 04.11.2026 „Automatisierung im Handwerk.“, der Arbeitstitel des
Webinars. Der Titel ist noch offen (Hub, daten/webinar.json), und das
Wort ist zu technisch (Dejan). */
g += v2Text(m, 462 + dy, "Weniger Zeit im Büro.", 50, V2.text, { anker: "middle" });
g += v2Text(m, 522 + dy, "Mit dem Programm, das du hast.", 50, V2.text, { anker: "middle" });
const kb = 420, kh = 88, ky = 590 + dy;
g += v2Chamfer(m - kb / 2, ky, kb, kh, 16, V2.gelb);
g += uiText(m, ky + 56, "Jetzt anmelden", 32, 800, V2.aufHell, { anker: "middle" });
g += uiText(m, ky + 160, WEBINAR.wochentag + ", " + WEBINAR.datum + ", " + WEBINAR.uhrzeit + " Uhr, online",
g += uiText(m, ky + 160, "Webinar am " + WEBINAR.wochentag + ", " + WEBINAR.datum + ", " + WEBINAR.uhrzeit + " Uhr, online",
26, 600, V2.text2, { anker: "middle" });
g += uiText(m, ky + 198, "Mit Noah Geerkens und David Bertram", 26, 600, V2.text2, { anker: "middle" });
g += v2Logo(m, H - 150, 46, { mitte: true });
+118 -46
View File
@@ -1063,6 +1063,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
@@ -1466,7 +1468,7 @@ if (location.search.indexOf("nur=anim") >= 0)
const VORLAGEN = [
V4_VORLAGE("titel", "Titel"),
V4_VORLAGE("buerokratie", "Bürokratie"),
V4_VORLAGE("ki", "Künstliche Intelligenz"),
V4_VORLAGE("ki", "KI im Handwerk"),
V4_VORLAGE("zeit", "Zeit"),
V4_VORLAGE("webinar", "Jetzt anmelden"),
];
@@ -1485,11 +1487,17 @@ if (location.search.indexOf("nur=anim") >= 0)
Carousel stehen sie an Stelle 2 und 3, die Standbilder im Streifen
zeigen ihren Endstand. Mit Video bleibt die Anzeige im Instagram-Feed
1:1 und laeuft nicht in Reels (rules.md 5). */
/* Seit 06.11.2026 laeuft auch der Titel als Video (Dejan): eine gelbe
Lichtwelle durchs Wabenmuster. Bild 0 ist der fertige Titel, damit die
Vorschau im Feed vollstaendig ist. */
const ANIMS = [
Object.assign({ key: "animBuerokratie", type: "feature", dauer: 6, eyebrow: "Bürokratie",
Object.assign({ key: "animTitel", type: "feature", dauer: 6, eyebrow: "Titel",
layouts: [{ id: "standard", label: "Standard" }], vis: "v4titelAnim" },
{ head: "", body: "", visW: 1080, visLeft: 0, visBottom: 0, quadrat: { visW: 1080, visLeft: 0, visBottom: 0 } }),
Object.assign({ key: "animBuerokratie", type: "feature", dauer: 8, eyebrow: "Bürokratie",
layouts: [{ id: "standard", label: "Standard" }], vis: "v4buerokratieAnim" },
{ head: "", body: "", visW: 1080, visLeft: 0, visBottom: 0, quadrat: { visW: 1080, visLeft: 0, visBottom: 0 } }),
Object.assign({ key: "animKi", type: "feature", dauer: 6, eyebrow: "Künstliche Intelligenz",
Object.assign({ key: "animKi", type: "feature", dauer: 8, eyebrow: "KI im Handwerk",
layouts: [{ id: "standard", label: "Standard" }], vis: "v4kiAnim" },
{ head: "", body: "", visW: 1080, visLeft: 0, visBottom: 0, quadrat: { visW: 1080, visLeft: 0, visBottom: 0 } }),
];
@@ -5166,6 +5174,10 @@ if (location.search.indexOf("nur=anim") >= 0)
titelGrund: "#30313D", gelb: "#F1B729", text: "#1A1A1A", text2: "#555555", text3: "#858589",
balkenDunkel: "#1A1A1A", balkenDunkelText: "#FFFFFF", spur: "#F0F0F0", linie: "#E5E5E5",
spurWabe: "#ECECEC",
/* Seit 06.11.2026 fuer die Waben, die herausstechen sollen (Bürokratie,
KI). Warm, damit es neben dem Gelb steht und nicht wie eine
Fehlermeldung wirkt. */
rot: "#E2462F",
};
const V4_DUNKEL = Object.assign({}, V4_HELL, {
titelGrund: "#0F1A2E", text: "#FFFFFF", text2: "#B9BDC9", text3: "#8A93A6",
@@ -5201,24 +5213,41 @@ if (location.search.indexOf("nur=anim") >= 0)
/* Ein Wabenfeld als Struktur auf dem Titelbild, nach links unten
auslaufend. Das Gegenstueck zum hellen Schleier auf dem Titel von HERO. */
function v4Struktur() {
/* t: Stand der Animation (0 bis 1) oder null fuer das Standbild. Eine
gelbe Welle laeuft schraeg von rechts oben nach links unten durchs Muster
(1,2 bis 4,8 s): In den Waben im Band waechst eine gelbe auf und
schrumpft wieder, die vier gelben wippen mit. Die Groesse folgt dem
Verlauf der Maske, damit die Welle dort ausklingt, wo das Muster
ausklingt. Bei 0 und 1 steht
das Standbild, die Schleife setzt also ohne Sprung neu an. */
function v4Struktur(t) {
const r = 54, w = r * Math.sqrt(3), sx = 1.5 * r;
const id = "v4verlauf" + (++v2Nr);
let m = "", voll = "";
let m = "", voll = "", glanz = "";
const band = t == null ? null : -260 + stufe(t, 0.2, 0.8) * 2360;
const welle = (cx, cy) => band == null ? 0 : Math.max(0, 1 - Math.abs((1080 - cx) + cy - band) / 170);
const maske = (cx, cy) => 0.9 * (1 - Math.max(0, Math.min(1, ((cx - 1080) * -700 + cy * 760) / (700 * 700 + 760 * 760))));
/* Die gelben liegen ueber dem Verlauf, sonst wirkten sie olivgruen. */
const gelb = new Set(["12,1", "15,3", "10,4", "14,0"]);
for (let sp = 0; sp * sx < 1080 + r; sp++) {
for (let z = -1; z * w < 760; z++) {
const cx = sp * sx, cy = z * w + (sp % 2 ? w / 2 : 0);
if (gelb.has(sp + "," + z)) voll += v2Wabe(cx, cy, r - 6, V4.gelb);
else m += v2Wabe(cx, cy, r - 6, "none", { stroke: "#FFFFFF", sw: 1.6 });
const cx = sp * sx, cy = z * w + (sp % 2 ? w / 2 : 0), e = welle(cx, cy);
if (gelb.has(sp + "," + z)) { voll += v2Wabe(cx, cy, (r - 6) * (1 + 0.16 * e), V4.gelb); continue; }
m += v2Wabe(cx, cy, r - 6, "none", { stroke: "#FFFFFF", sw: 1.6 });
/* Voll gelb und ueber die Groesse ein- und ausgeblendet: Halb
durchsichtiges Gelb wirkt auf dem dunklen Grund olivgruen. */
/* Vor Logo, Etikett und Ueberschrift laeuft die Welle aus, sonst
stehen gelbe Waben hinter der gelben Schrift. */
const frei = Math.max(0, Math.min(1, (cx - (cy < 250 ? 400 : 600)) / 130));
const s = e * frei * (0.35 + 0.65 * maske(cx, cy) / 0.9);
if (s > 0.06) glanz += v2Wabe(cx, cy, (r - 6) * Math.min(1, s * 1.15), V4.gelb);
}
}
return '<linearGradient id="' + id + 'g" gradientUnits="userSpaceOnUse" x1="1080" y1="0" x2="380" y2="760">' +
'<stop offset="0" stop-color="#FFFFFF" stop-opacity=".9"/><stop offset="1" stop-color="#FFFFFF" stop-opacity="0"/></linearGradient>' +
'<mask id="' + id + '" maskUnits="userSpaceOnUse" x="0" y="0" width="1080" height="1080">' +
'<rect width="1080" height="1080" fill="url(#' + id + 'g)"/></mask>' +
'<g mask="url(#' + id + ')" stroke-opacity=".16">' + m + "</g>" + voll;
'<g mask="url(#' + id + ')" stroke-opacity=".16">' + m + "</g>" + glanz + voll;
}
/* Ein Feld aus 100 Waben, 20 Spalten zu 5 Reihen, als Mengenbild: jede
@@ -5226,12 +5255,18 @@ if (location.search.indexOf("nur=anim") >= 0)
gezaehlt wird spaltenweise von links. Dejan, 02.11.2026: weniger Zahlen,
mehr Grafik, aber nichts erfunden. Die Grafik zeigt nur den Prozentwert
der Quelle, auf ganze Waben gerundet. */
function v4Hundert(y0, art, zeit) {
const r = 28, sx = 1.5 * r, w = r * Math.sqrt(3);
const x0 = V2_RAND + r + (1080 - 2 * V2_RAND - (19 * sx + 2 * r)) / 2;
/* o.reihen, o.r, o.x0: Form des Felds. Ohne o das breite Band, 20 Spalten
zu 5 Reihen, mittig. Seit 04.11.2026 zeigt Slide 3 dasselbe Feld als
Block 10 x 10 (Dejan: „dass das back to back gleich aussieht, finde ich
nicht so gut, einzelne Slides stechen dadurch nicht raus“). */
function v4Hundert(y0, art, zeit, o) {
o = o || {};
const reihen = o.reihen || 5, spalten = 100 / reihen;
const r = o.r || 28, sx = 1.5 * r, w = r * Math.sqrt(3);
const x0 = o.x0 != null ? o.x0 : V2_RAND + r + (1080 - 2 * V2_RAND - ((spalten - 1) * sx + 2 * r)) / 2;
let g = "", oben = "";
for (let i = 0; i < 100; i++) {
const sp = Math.floor(i / 5), z = i % 5;
const sp = Math.floor(i / reihen), z = i % reihen;
const cx = x0 + sp * sx, cy = y0 + w / 2 + z * w + (sp % 2 ? w / 2 : 0);
const a = art(i);
/* p: wie weit diese Wabe schon da ist, 0 bis 1. Ohne zeit (Standbild)
@@ -5243,6 +5278,7 @@ if (location.search.indexOf("nur=anim") >= 0)
if (!a || p <= 0) continue;
const sk = rueck(p);
oben += a === "voll" ? v2Wabe(cx, cy, (r - 4) * sk, V4.gelb)
: a === "rot" ? v2Wabe(cx, cy, (r - 4) * sk, V4.rot)
: v2Wabe(cx, cy, (r - 6) * sk, "none", { stroke: V4.gelb, sw: 3 });
}
return g + oben;
@@ -5259,6 +5295,8 @@ if (location.search.indexOf("nur=anim") >= 0)
if (jetzt - zuletzt > 33) {
zuletzt = jetzt;
const t = ((jetzt - start) / 1000 % V4_DAUER) / V4_DAUER;
const tt = ((jetzt - start) / 1000 % 6) / 6;
document.querySelectorAll(".vis.vis-v4titel").forEach(v => { v.innerHTML = v4Titel(tt); });
document.querySelectorAll(".vis.vis-v4buerokratie").forEach(v => { v.innerHTML = v4Buerokratie(t); });
document.querySelectorAll(".vis.vis-v4ki").forEach(v => { v.innerHTML = v4Ki(t); });
}
@@ -5271,21 +5309,36 @@ if (location.search.indexOf("nur=anim") >= 0)
Sekunden. Die Waben kommen nacheinander (start, abstand, je dauer), am
Ende ziehen sich alle zusammen zurueck, damit die Schleife auf
Instagram weich neu ansetzt statt zu springen. */
const V4_DAUER = 6;
/* Seit 06.11.2026 8 statt 6 Sekunden (Dejan: zu langweilig, zu wenig
Waben farbig). Erst laufen alle uebrigen Waben gelb durch, dann kommen
die roten, langsamer und einzeln. */
const V4_DAUER = 8;
const v4Welle = (t, k, start, abstand, dauer) => {
const rein = stufe(t, start + k * abstand, start + k * abstand + dauer);
const raus = 1 - daempfen(stufe(t, 0.92, 1));
const raus = 1 - daempfen(stufe(t, 0.925, 1));
return rein * raus;
};
/* Zeitplan fuer ein Feld mit roten Waben: Die gelben laufen in einer Welle
von links nach rechts durch (0,3 bis 3 s), die roten danach eine nach der
anderen, jede fast eine Sekunde lang (ab 3,4 s). */
const v4Zeitplan = (t, rot, abstandRot) => {
const gelbe = [], rote = [];
for (let i = 0; i < 100; i++) (rot(i) ? rote : gelbe).push(i);
return i => {
const r = rote.indexOf(i);
return r >= 0 ? v4Welle(t, r, 0.425, abstandRot, 0.12)
: v4Welle(t, gelbe.indexOf(i), 0.04, 0.30 / gelbe.length, 0.07);
};
};
/* 1 · Titel. Noah freigestellt vor der grossen gelben Wabe, wie in
Variante 2 auf der Zitat-Karte: Er traegt Schwarz und braucht das Gelb
dahinter. Die Karte teasert das Webinar, die Zahlen kommen danach. */
function v4Titel() {
function v4Titel(t) {
v4Ton();
const H = SLIDE_H;
let g = '<rect width="1080" height="' + H + '" fill="' + V4.titelGrund + '"/>';
g += v4Struktur();
g += v4Struktur(t == null ? null : t);
g += v2Wabe(800, H - 170, 330, V4.gelb);
const pb = 1000, ph = pb * 1049 / 1600;
/* Gespiegelt an x 800 (Dejan, 02.11.2026): Noah schaut so zum Text. */
@@ -5310,45 +5363,60 @@ if (location.search.indexOf("nur=anim") >= 0)
v4Ton();
let g = v4Kopf("Zeitfresser Bürokratie", "Im Bau: 8 von 100 Arbeitsstunden", "gehen für Bürokratie drauf.");
/* Grafik und Legende stehen mittig zwischen Kopf (bis 306) und Fuss (ab 952). */
/* Animiert: die 8 gelben ab 0,6 s nacheinander, je 0,5 s. */
g += v4Hundert(456, i => i >= 92 ? "voll" : "",
t == null ? null : i => v4Welle(t, i - 92, 0.10, 0.035, 0.08));
g += v2Wabe(V2_RAND + 13, 777, 13, V4.gelb);
g += uiText(V2_RAND + 40, 785, "Jede Wabe ist eine Arbeitsstunde. Gelb ist Bürokratie.", 24, 600, V4.text2);
/* Animiert: erst die 92 Stunden gelb, dann die 8 roten langsam. */
const rot = i => i >= 92;
g += v4Hundert(456, i => rot(i) ? "rot" : "voll", t == null ? null : v4Zeitplan(t, rot, 0.04));
g += v2Wabe(V2_RAND + 13, 777, 13, V4.rot);
g += uiText(V2_RAND + 40, 785, "Jede Wabe ist eine Arbeitsstunde. Rot ist Bürokratie.", 24, 600, V4.text2);
g += v4Fuss(["Quelle: KfW-Mittelstandspanel, KfW Research Nr. 495, April 2025.",
"Anteil der Arbeitszeit für Bürokratie im mittelständischen Baugewerbe: 8,1 %."]);
return v2Svg(g);
}
/* 3 · KI. Bitkom: 4 % nutzen KI, 9 % planen es. Dasselbe Bild, jede Wabe
ein Betrieb. */
/* 3 · KI. Bitkom: 4 % nutzen KI. Dasselbe Bild wie Slide 2, jede Wabe ein
Betrieb, und derselbe Satzbau in den Balken. Bis 04.11.2026 standen
dazu die 9 % mit Plaenen als umrandete Waben, mit eigener Legende
(Dejan: zu viel Text). */
/* Anders als Slide 2: links die Zahl gross, wie die KI-Karte bei HERO
Insights („96 % > nur 2 %“), rechts dieselben 100 Waben als Block,
10 x 10, groesser. So stehen die beiden Wabenbilder nicht gleich
hintereinander. */
function v4Ki(t) {
v4Ton();
let g = v4Kopf("Künstliche Intelligenz", "KI ist im Handwerk kaum angekommen.", "4 von 100 Betrieben nutzen sie.");
/* Animiert: erst die 4 vollen, dann die 9 umrandeten. */
g += v4Hundert(456, i => i < 4 ? "voll" : i < 13 ? "rand" : "",
t == null ? null : i => i < 4 ? v4Welle(t, i, 0.10, 0.05, 0.08) : v4Welle(t, i - 4, 0.40, 0.03, 0.07));
g += v2Wabe(V2_RAND + 13, 777, 13, V4.gelb);
g += uiText(V2_RAND + 40, 785, "nutzen KI", 24, 600, V4.text2);
g += v2Wabe(V2_RAND + 213, 777, 11, "none", { stroke: V4.gelb, sw: 3 });
g += uiText(V2_RAND + 240, 785, "planen es", 24, 600, V4.text2);
g += uiText(1080 - V2_RAND, 785, "Jede Wabe ist ein Betrieb.", 24, 600, V4.text3, { anker: "end" });
let g = v4Kopf("KI im Handwerk", "Erst 4 von 100 Betrieben", "nutzen sie.");
const r = 30, bw = 9 * 1.5 * r + 2 * r, bh = 10.5 * r * Math.sqrt(3);
const bx = 1080 - V2_RAND - bw, by = 640 - bh / 2;
/* Animiert: erst die 96 gelb, dann die 4 roten oben links, langsam. */
const rot = i => i < 4;
g += v4Hundert(by, i => rot(i) ? "rot" : "voll", t == null ? null : v4Zeitplan(t, rot, 0.07),
{ reihen: 10, r, x0: bx + r });
g += v2Text(V2_RAND - 14, 660, "4", 330, V4.rot, { sperr: "-0.04em" });
g += v2Text(V2_RAND, 740, "von 100", 56, V4.text);
g += v2Text(V2_RAND, 802, "Betrieben", 56, V4.text);
g += v2Wabe(V2_RAND + 13, 862, 13, V4.rot);
g += uiText(V2_RAND + 40, 870, "Rot nutzt KI.", 24, 600, V4.text2);
g += v4Fuss(["Quelle: Bitkom Research, Digitalisierung des Handwerks,", "504 Handwerksbetriebe, Sommer 2025."]);
return v2Svg(g);
}
/* 4 · Zeit. Nur noch der Widerspruch: Zeitersparnis gilt als Vorteil,
und die meisten haben keine Zeit dafuer. Der Ring zeigt die 72 %. */
/* 4 · Zeit. Bitkom, Abbildung 19: 72 % sagen „Wir haben zu viel zu tun, um
uns mit der Digitalisierung zu beschäftigen“ (im Text: „zu stark
ausgelastet“). Die Balken tragen den Satz in einfachen Worten, der Kasten
die Zahl.
Bis 04.11.2026 zuerst zwei Ringe mit Wortspiel, dann 72 von 100 Waben
(Dejan: „die dritte Slide hintereinander mit derselben Grafik“). Vorbilder
aus der Werbebibliothek: HERO Insights, Karte 4 (ID 3818182885142025,
die Zahl gross im gelben Kasten), die Umfrage von HERO (ID
1480540019958925, Aussage, dann „sagen“ und die Zahl) und GL-Webinnovate
(ID 2200760394202873, dieselbe Bitkom-Zahl als „Zu ausgelastet“). */
function v4Zeit() {
v4Ton();
let g = v4Kopf("Digitalisierung und Zeit", "76 % sagen: Digitalisierung spart Zeit.", "Aber 72 % fehlt die Zeit dafür.");
const cx = V2_RAND + 170, cy = 600, r = 150, sw = 44, u = 2 * Math.PI * r;
g += '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="none" stroke="' + V4.spur + '" stroke-width="' + sw + '"/>';
g += '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="none" stroke="' + V4.gelb + '" stroke-width="' + sw +
'" stroke-dasharray="' + n1(u * 0.72) + " " + n1(u) + '" transform="rotate(-90 ' + cx + " " + cy + ')"/>';
g += v2Text(cx, cy + 28, "72 %", 76, V4.text, { anker: "middle" });
["„Wir haben zu viel", "zu tun, um uns mit", "der Digitalisierung", "zu beschäftigen.“"].forEach((z, i) => {
g += v2Text(V2_RAND + 400, 530 + i * 48, z, 38, V4.text, { gew: 800 });
let g = v4Kopf("Zu ausgelastet", "Wir haben zu viel zu tun,", "um uns um Neues zu kümmern.");
const x = V2_RAND, y = 470, b = 1080 - 2 * V2_RAND, h = 300;
g += v2Chamfer(x, y, b, h, 22, V4.gelb);
g += v2Text(x + 56, y + 212, "72 %", 190, "#1A1A1A", { sperr: "-0.04em" });
["der Betriebe", "im Handwerk", "sagen das."].forEach((z, i) => {
g += v2Text(x + 560, y + 108 + i * 50, z, 42, "#1A1A1A", { gew: 700 });
});
g += v4Fuss(["Quelle: Bitkom Research, Digitalisierung des Handwerks,", "504 Handwerksbetriebe, Sommer 2025."]);
return v2Svg(g);
@@ -5358,8 +5426,11 @@ if (location.search.indexOf("nur=anim") >= 0)
der Anmeldekarte von Variante 1. */
function v4Webinar() {
v4Ton();
let g = v4Kopf("Im Webinar", "Automatisierung im Handwerk.", "Mit dem Programm, das du hast.");
["Von der Anfrage zum Auftrag", "Das Herzstück: Automatisierung", "Chat, Personal, Passwörter"].forEach((z, i) => {
/* Bis 04.11.2026 „Automatisierung im Handwerk.“ und „Das Herzstück:
Automatisierung“ (Dejan: zu technisch, alles ganz einfach). Die
Punkte sind dieselben drei Teile des Webinars. */
let g = v4Kopf("Im Webinar", "Weniger Zeit im Büro.", "Mit dem Programm, das du hast.");
["Von der Anfrage zum Auftrag", "Was von selbst laufen kann", "Chat, Urlaub, Passwörter"].forEach((z, i) => {
const y = 400 + i * 56;
g += v2Wabe(V2_RAND + 13, y - 10, 13, V4.gelb);
g += uiText(V2_RAND + 50, y, z, 28, 700, V4.text);
@@ -5429,7 +5500,8 @@ if (location.search.indexOf("nur=anim") >= 0)
animMail: (j, t) => animMail(j, t),
anmeldung: () => visAnmeldung(),
animWebinar: (j, t) => animWebinar(j, t),
v4titel: () => v4Titel(),
v4titel: () => v4Titel(null),
v4titelAnim: (j, t) => v4Titel(t),
v4buerokratie: () => v4Buerokratie(null),
v4buerokratieAnim: (j, t) => v4Buerokratie(t),
v4ki: () => v4Ki(null),
+118 -46
View File
@@ -1063,6 +1063,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
@@ -1466,7 +1468,7 @@ if (location.search.indexOf("nur=anim") >= 0)
const VORLAGEN = [
V4_VORLAGE("titel", "Titel"),
V4_VORLAGE("buerokratie", "Bürokratie"),
V4_VORLAGE("ki", "Künstliche Intelligenz"),
V4_VORLAGE("ki", "KI im Handwerk"),
V4_VORLAGE("zeit", "Zeit"),
V4_VORLAGE("webinar", "Jetzt anmelden"),
];
@@ -1485,11 +1487,17 @@ if (location.search.indexOf("nur=anim") >= 0)
Carousel stehen sie an Stelle 2 und 3, die Standbilder im Streifen
zeigen ihren Endstand. Mit Video bleibt die Anzeige im Instagram-Feed
1:1 und laeuft nicht in Reels (rules.md 5). */
/* Seit 06.11.2026 laeuft auch der Titel als Video (Dejan): eine gelbe
Lichtwelle durchs Wabenmuster. Bild 0 ist der fertige Titel, damit die
Vorschau im Feed vollstaendig ist. */
const ANIMS = [
Object.assign({ key: "animBuerokratie", type: "feature", dauer: 6, eyebrow: "Bürokratie",
Object.assign({ key: "animTitel", type: "feature", dauer: 6, eyebrow: "Titel",
layouts: [{ id: "standard", label: "Standard" }], vis: "v4titelAnim" },
{ head: "", body: "", visW: 1080, visLeft: 0, visBottom: 0, quadrat: { visW: 1080, visLeft: 0, visBottom: 0 } }),
Object.assign({ key: "animBuerokratie", type: "feature", dauer: 8, eyebrow: "Bürokratie",
layouts: [{ id: "standard", label: "Standard" }], vis: "v4buerokratieAnim" },
{ head: "", body: "", visW: 1080, visLeft: 0, visBottom: 0, quadrat: { visW: 1080, visLeft: 0, visBottom: 0 } }),
Object.assign({ key: "animKi", type: "feature", dauer: 6, eyebrow: "Künstliche Intelligenz",
Object.assign({ key: "animKi", type: "feature", dauer: 8, eyebrow: "KI im Handwerk",
layouts: [{ id: "standard", label: "Standard" }], vis: "v4kiAnim" },
{ head: "", body: "", visW: 1080, visLeft: 0, visBottom: 0, quadrat: { visW: 1080, visLeft: 0, visBottom: 0 } }),
];
@@ -5166,6 +5174,10 @@ if (location.search.indexOf("nur=anim") >= 0)
titelGrund: "#30313D", gelb: "#F1B729", text: "#1A1A1A", text2: "#555555", text3: "#858589",
balkenDunkel: "#1A1A1A", balkenDunkelText: "#FFFFFF", spur: "#F0F0F0", linie: "#E5E5E5",
spurWabe: "#ECECEC",
/* Seit 06.11.2026 fuer die Waben, die herausstechen sollen (Bürokratie,
KI). Warm, damit es neben dem Gelb steht und nicht wie eine
Fehlermeldung wirkt. */
rot: "#E2462F",
};
const V4_DUNKEL = Object.assign({}, V4_HELL, {
titelGrund: "#0F1A2E", text: "#FFFFFF", text2: "#B9BDC9", text3: "#8A93A6",
@@ -5201,24 +5213,41 @@ if (location.search.indexOf("nur=anim") >= 0)
/* Ein Wabenfeld als Struktur auf dem Titelbild, nach links unten
auslaufend. Das Gegenstueck zum hellen Schleier auf dem Titel von HERO. */
function v4Struktur() {
/* t: Stand der Animation (0 bis 1) oder null fuer das Standbild. Eine
gelbe Welle laeuft schraeg von rechts oben nach links unten durchs Muster
(1,2 bis 4,8 s): In den Waben im Band waechst eine gelbe auf und
schrumpft wieder, die vier gelben wippen mit. Die Groesse folgt dem
Verlauf der Maske, damit die Welle dort ausklingt, wo das Muster
ausklingt. Bei 0 und 1 steht
das Standbild, die Schleife setzt also ohne Sprung neu an. */
function v4Struktur(t) {
const r = 54, w = r * Math.sqrt(3), sx = 1.5 * r;
const id = "v4verlauf" + (++v2Nr);
let m = "", voll = "";
let m = "", voll = "", glanz = "";
const band = t == null ? null : -260 + stufe(t, 0.2, 0.8) * 2360;
const welle = (cx, cy) => band == null ? 0 : Math.max(0, 1 - Math.abs((1080 - cx) + cy - band) / 170);
const maske = (cx, cy) => 0.9 * (1 - Math.max(0, Math.min(1, ((cx - 1080) * -700 + cy * 760) / (700 * 700 + 760 * 760))));
/* Die gelben liegen ueber dem Verlauf, sonst wirkten sie olivgruen. */
const gelb = new Set(["12,1", "15,3", "10,4", "14,0"]);
for (let sp = 0; sp * sx < 1080 + r; sp++) {
for (let z = -1; z * w < 760; z++) {
const cx = sp * sx, cy = z * w + (sp % 2 ? w / 2 : 0);
if (gelb.has(sp + "," + z)) voll += v2Wabe(cx, cy, r - 6, V4.gelb);
else m += v2Wabe(cx, cy, r - 6, "none", { stroke: "#FFFFFF", sw: 1.6 });
const cx = sp * sx, cy = z * w + (sp % 2 ? w / 2 : 0), e = welle(cx, cy);
if (gelb.has(sp + "," + z)) { voll += v2Wabe(cx, cy, (r - 6) * (1 + 0.16 * e), V4.gelb); continue; }
m += v2Wabe(cx, cy, r - 6, "none", { stroke: "#FFFFFF", sw: 1.6 });
/* Voll gelb und ueber die Groesse ein- und ausgeblendet: Halb
durchsichtiges Gelb wirkt auf dem dunklen Grund olivgruen. */
/* Vor Logo, Etikett und Ueberschrift laeuft die Welle aus, sonst
stehen gelbe Waben hinter der gelben Schrift. */
const frei = Math.max(0, Math.min(1, (cx - (cy < 250 ? 400 : 600)) / 130));
const s = e * frei * (0.35 + 0.65 * maske(cx, cy) / 0.9);
if (s > 0.06) glanz += v2Wabe(cx, cy, (r - 6) * Math.min(1, s * 1.15), V4.gelb);
}
}
return '<linearGradient id="' + id + 'g" gradientUnits="userSpaceOnUse" x1="1080" y1="0" x2="380" y2="760">' +
'<stop offset="0" stop-color="#FFFFFF" stop-opacity=".9"/><stop offset="1" stop-color="#FFFFFF" stop-opacity="0"/></linearGradient>' +
'<mask id="' + id + '" maskUnits="userSpaceOnUse" x="0" y="0" width="1080" height="1080">' +
'<rect width="1080" height="1080" fill="url(#' + id + 'g)"/></mask>' +
'<g mask="url(#' + id + ')" stroke-opacity=".16">' + m + "</g>" + voll;
'<g mask="url(#' + id + ')" stroke-opacity=".16">' + m + "</g>" + glanz + voll;
}
/* Ein Feld aus 100 Waben, 20 Spalten zu 5 Reihen, als Mengenbild: jede
@@ -5226,12 +5255,18 @@ if (location.search.indexOf("nur=anim") >= 0)
gezaehlt wird spaltenweise von links. Dejan, 02.11.2026: weniger Zahlen,
mehr Grafik, aber nichts erfunden. Die Grafik zeigt nur den Prozentwert
der Quelle, auf ganze Waben gerundet. */
function v4Hundert(y0, art, zeit) {
const r = 28, sx = 1.5 * r, w = r * Math.sqrt(3);
const x0 = V2_RAND + r + (1080 - 2 * V2_RAND - (19 * sx + 2 * r)) / 2;
/* o.reihen, o.r, o.x0: Form des Felds. Ohne o das breite Band, 20 Spalten
zu 5 Reihen, mittig. Seit 04.11.2026 zeigt Slide 3 dasselbe Feld als
Block 10 x 10 (Dejan: „dass das back to back gleich aussieht, finde ich
nicht so gut, einzelne Slides stechen dadurch nicht raus“). */
function v4Hundert(y0, art, zeit, o) {
o = o || {};
const reihen = o.reihen || 5, spalten = 100 / reihen;
const r = o.r || 28, sx = 1.5 * r, w = r * Math.sqrt(3);
const x0 = o.x0 != null ? o.x0 : V2_RAND + r + (1080 - 2 * V2_RAND - ((spalten - 1) * sx + 2 * r)) / 2;
let g = "", oben = "";
for (let i = 0; i < 100; i++) {
const sp = Math.floor(i / 5), z = i % 5;
const sp = Math.floor(i / reihen), z = i % reihen;
const cx = x0 + sp * sx, cy = y0 + w / 2 + z * w + (sp % 2 ? w / 2 : 0);
const a = art(i);
/* p: wie weit diese Wabe schon da ist, 0 bis 1. Ohne zeit (Standbild)
@@ -5243,6 +5278,7 @@ if (location.search.indexOf("nur=anim") >= 0)
if (!a || p <= 0) continue;
const sk = rueck(p);
oben += a === "voll" ? v2Wabe(cx, cy, (r - 4) * sk, V4.gelb)
: a === "rot" ? v2Wabe(cx, cy, (r - 4) * sk, V4.rot)
: v2Wabe(cx, cy, (r - 6) * sk, "none", { stroke: V4.gelb, sw: 3 });
}
return g + oben;
@@ -5259,6 +5295,8 @@ if (location.search.indexOf("nur=anim") >= 0)
if (jetzt - zuletzt > 33) {
zuletzt = jetzt;
const t = ((jetzt - start) / 1000 % V4_DAUER) / V4_DAUER;
const tt = ((jetzt - start) / 1000 % 6) / 6;
document.querySelectorAll(".vis.vis-v4titel").forEach(v => { v.innerHTML = v4Titel(tt); });
document.querySelectorAll(".vis.vis-v4buerokratie").forEach(v => { v.innerHTML = v4Buerokratie(t); });
document.querySelectorAll(".vis.vis-v4ki").forEach(v => { v.innerHTML = v4Ki(t); });
}
@@ -5271,21 +5309,36 @@ if (location.search.indexOf("nur=anim") >= 0)
Sekunden. Die Waben kommen nacheinander (start, abstand, je dauer), am
Ende ziehen sich alle zusammen zurueck, damit die Schleife auf
Instagram weich neu ansetzt statt zu springen. */
const V4_DAUER = 6;
/* Seit 06.11.2026 8 statt 6 Sekunden (Dejan: zu langweilig, zu wenig
Waben farbig). Erst laufen alle uebrigen Waben gelb durch, dann kommen
die roten, langsamer und einzeln. */
const V4_DAUER = 8;
const v4Welle = (t, k, start, abstand, dauer) => {
const rein = stufe(t, start + k * abstand, start + k * abstand + dauer);
const raus = 1 - daempfen(stufe(t, 0.92, 1));
const raus = 1 - daempfen(stufe(t, 0.925, 1));
return rein * raus;
};
/* Zeitplan fuer ein Feld mit roten Waben: Die gelben laufen in einer Welle
von links nach rechts durch (0,3 bis 3 s), die roten danach eine nach der
anderen, jede fast eine Sekunde lang (ab 3,4 s). */
const v4Zeitplan = (t, rot, abstandRot) => {
const gelbe = [], rote = [];
for (let i = 0; i < 100; i++) (rot(i) ? rote : gelbe).push(i);
return i => {
const r = rote.indexOf(i);
return r >= 0 ? v4Welle(t, r, 0.425, abstandRot, 0.12)
: v4Welle(t, gelbe.indexOf(i), 0.04, 0.30 / gelbe.length, 0.07);
};
};
/* 1 · Titel. Noah freigestellt vor der grossen gelben Wabe, wie in
Variante 2 auf der Zitat-Karte: Er traegt Schwarz und braucht das Gelb
dahinter. Die Karte teasert das Webinar, die Zahlen kommen danach. */
function v4Titel() {
function v4Titel(t) {
v4Ton();
const H = SLIDE_H;
let g = '<rect width="1080" height="' + H + '" fill="' + V4.titelGrund + '"/>';
g += v4Struktur();
g += v4Struktur(t == null ? null : t);
g += v2Wabe(800, H - 170, 330, V4.gelb);
const pb = 1000, ph = pb * 1049 / 1600;
/* Gespiegelt an x 800 (Dejan, 02.11.2026): Noah schaut so zum Text. */
@@ -5310,45 +5363,60 @@ if (location.search.indexOf("nur=anim") >= 0)
v4Ton();
let g = v4Kopf("Zeitfresser Bürokratie", "Im Bau: 8 von 100 Arbeitsstunden", "gehen für Bürokratie drauf.");
/* Grafik und Legende stehen mittig zwischen Kopf (bis 306) und Fuss (ab 952). */
/* Animiert: die 8 gelben ab 0,6 s nacheinander, je 0,5 s. */
g += v4Hundert(456, i => i >= 92 ? "voll" : "",
t == null ? null : i => v4Welle(t, i - 92, 0.10, 0.035, 0.08));
g += v2Wabe(V2_RAND + 13, 777, 13, V4.gelb);
g += uiText(V2_RAND + 40, 785, "Jede Wabe ist eine Arbeitsstunde. Gelb ist Bürokratie.", 24, 600, V4.text2);
/* Animiert: erst die 92 Stunden gelb, dann die 8 roten langsam. */
const rot = i => i >= 92;
g += v4Hundert(456, i => rot(i) ? "rot" : "voll", t == null ? null : v4Zeitplan(t, rot, 0.04));
g += v2Wabe(V2_RAND + 13, 777, 13, V4.rot);
g += uiText(V2_RAND + 40, 785, "Jede Wabe ist eine Arbeitsstunde. Rot ist Bürokratie.", 24, 600, V4.text2);
g += v4Fuss(["Quelle: KfW-Mittelstandspanel, KfW Research Nr. 495, April 2025.",
"Anteil der Arbeitszeit für Bürokratie im mittelständischen Baugewerbe: 8,1 %."]);
return v2Svg(g);
}
/* 3 · KI. Bitkom: 4 % nutzen KI, 9 % planen es. Dasselbe Bild, jede Wabe
ein Betrieb. */
/* 3 · KI. Bitkom: 4 % nutzen KI. Dasselbe Bild wie Slide 2, jede Wabe ein
Betrieb, und derselbe Satzbau in den Balken. Bis 04.11.2026 standen
dazu die 9 % mit Plaenen als umrandete Waben, mit eigener Legende
(Dejan: zu viel Text). */
/* Anders als Slide 2: links die Zahl gross, wie die KI-Karte bei HERO
Insights („96 % > nur 2 %“), rechts dieselben 100 Waben als Block,
10 x 10, groesser. So stehen die beiden Wabenbilder nicht gleich
hintereinander. */
function v4Ki(t) {
v4Ton();
let g = v4Kopf("Künstliche Intelligenz", "KI ist im Handwerk kaum angekommen.", "4 von 100 Betrieben nutzen sie.");
/* Animiert: erst die 4 vollen, dann die 9 umrandeten. */
g += v4Hundert(456, i => i < 4 ? "voll" : i < 13 ? "rand" : "",
t == null ? null : i => i < 4 ? v4Welle(t, i, 0.10, 0.05, 0.08) : v4Welle(t, i - 4, 0.40, 0.03, 0.07));
g += v2Wabe(V2_RAND + 13, 777, 13, V4.gelb);
g += uiText(V2_RAND + 40, 785, "nutzen KI", 24, 600, V4.text2);
g += v2Wabe(V2_RAND + 213, 777, 11, "none", { stroke: V4.gelb, sw: 3 });
g += uiText(V2_RAND + 240, 785, "planen es", 24, 600, V4.text2);
g += uiText(1080 - V2_RAND, 785, "Jede Wabe ist ein Betrieb.", 24, 600, V4.text3, { anker: "end" });
let g = v4Kopf("KI im Handwerk", "Erst 4 von 100 Betrieben", "nutzen sie.");
const r = 30, bw = 9 * 1.5 * r + 2 * r, bh = 10.5 * r * Math.sqrt(3);
const bx = 1080 - V2_RAND - bw, by = 640 - bh / 2;
/* Animiert: erst die 96 gelb, dann die 4 roten oben links, langsam. */
const rot = i => i < 4;
g += v4Hundert(by, i => rot(i) ? "rot" : "voll", t == null ? null : v4Zeitplan(t, rot, 0.07),
{ reihen: 10, r, x0: bx + r });
g += v2Text(V2_RAND - 14, 660, "4", 330, V4.rot, { sperr: "-0.04em" });
g += v2Text(V2_RAND, 740, "von 100", 56, V4.text);
g += v2Text(V2_RAND, 802, "Betrieben", 56, V4.text);
g += v2Wabe(V2_RAND + 13, 862, 13, V4.rot);
g += uiText(V2_RAND + 40, 870, "Rot nutzt KI.", 24, 600, V4.text2);
g += v4Fuss(["Quelle: Bitkom Research, Digitalisierung des Handwerks,", "504 Handwerksbetriebe, Sommer 2025."]);
return v2Svg(g);
}
/* 4 · Zeit. Nur noch der Widerspruch: Zeitersparnis gilt als Vorteil,
und die meisten haben keine Zeit dafuer. Der Ring zeigt die 72 %. */
/* 4 · Zeit. Bitkom, Abbildung 19: 72 % sagen „Wir haben zu viel zu tun, um
uns mit der Digitalisierung zu beschäftigen“ (im Text: „zu stark
ausgelastet“). Die Balken tragen den Satz in einfachen Worten, der Kasten
die Zahl.
Bis 04.11.2026 zuerst zwei Ringe mit Wortspiel, dann 72 von 100 Waben
(Dejan: „die dritte Slide hintereinander mit derselben Grafik“). Vorbilder
aus der Werbebibliothek: HERO Insights, Karte 4 (ID 3818182885142025,
die Zahl gross im gelben Kasten), die Umfrage von HERO (ID
1480540019958925, Aussage, dann „sagen“ und die Zahl) und GL-Webinnovate
(ID 2200760394202873, dieselbe Bitkom-Zahl als „Zu ausgelastet“). */
function v4Zeit() {
v4Ton();
let g = v4Kopf("Digitalisierung und Zeit", "76 % sagen: Digitalisierung spart Zeit.", "Aber 72 % fehlt die Zeit dafür.");
const cx = V2_RAND + 170, cy = 600, r = 150, sw = 44, u = 2 * Math.PI * r;
g += '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="none" stroke="' + V4.spur + '" stroke-width="' + sw + '"/>';
g += '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="none" stroke="' + V4.gelb + '" stroke-width="' + sw +
'" stroke-dasharray="' + n1(u * 0.72) + " " + n1(u) + '" transform="rotate(-90 ' + cx + " " + cy + ')"/>';
g += v2Text(cx, cy + 28, "72 %", 76, V4.text, { anker: "middle" });
["„Wir haben zu viel", "zu tun, um uns mit", "der Digitalisierung", "zu beschäftigen.“"].forEach((z, i) => {
g += v2Text(V2_RAND + 400, 530 + i * 48, z, 38, V4.text, { gew: 800 });
let g = v4Kopf("Zu ausgelastet", "Wir haben zu viel zu tun,", "um uns um Neues zu kümmern.");
const x = V2_RAND, y = 470, b = 1080 - 2 * V2_RAND, h = 300;
g += v2Chamfer(x, y, b, h, 22, V4.gelb);
g += v2Text(x + 56, y + 212, "72 %", 190, "#1A1A1A", { sperr: "-0.04em" });
["der Betriebe", "im Handwerk", "sagen das."].forEach((z, i) => {
g += v2Text(x + 560, y + 108 + i * 50, z, 42, "#1A1A1A", { gew: 700 });
});
g += v4Fuss(["Quelle: Bitkom Research, Digitalisierung des Handwerks,", "504 Handwerksbetriebe, Sommer 2025."]);
return v2Svg(g);
@@ -5358,8 +5426,11 @@ if (location.search.indexOf("nur=anim") >= 0)
der Anmeldekarte von Variante 1. */
function v4Webinar() {
v4Ton();
let g = v4Kopf("Im Webinar", "Automatisierung im Handwerk.", "Mit dem Programm, das du hast.");
["Von der Anfrage zum Auftrag", "Das Herzstück: Automatisierung", "Chat, Personal, Passwörter"].forEach((z, i) => {
/* Bis 04.11.2026 „Automatisierung im Handwerk.“ und „Das Herzstück:
Automatisierung“ (Dejan: zu technisch, alles ganz einfach). Die
Punkte sind dieselben drei Teile des Webinars. */
let g = v4Kopf("Im Webinar", "Weniger Zeit im Büro.", "Mit dem Programm, das du hast.");
["Von der Anfrage zum Auftrag", "Was von selbst laufen kann", "Chat, Urlaub, Passwörter"].forEach((z, i) => {
const y = 400 + i * 56;
g += v2Wabe(V2_RAND + 13, y - 10, 13, V4.gelb);
g += uiText(V2_RAND + 50, y, z, 28, 700, V4.text);
@@ -5429,7 +5500,8 @@ if (location.search.indexOf("nur=anim") >= 0)
animMail: (j, t) => animMail(j, t),
anmeldung: () => visAnmeldung(),
animWebinar: (j, t) => animWebinar(j, t),
v4titel: () => v4Titel(),
v4titel: () => v4Titel(null),
v4titelAnim: (j, t) => v4Titel(t),
v4buerokratie: () => v4Buerokratie(null),
v4buerokratieAnim: (j, t) => v4Buerokratie(t),
v4ki: () => v4Ki(null),
+8876
View File
File diff suppressed because it is too large. Load diff
+8879
View File
File diff suppressed because it is too large. Load diff
+38 -9
View File
@@ -66,13 +66,15 @@
<a href="./post9-v3.html">Variante 3 bearbeiten</a>
<a href="./post9-v4.html">Variante 4 bearbeiten</a>
<a href="./post9-v5.html">Variante 5 bearbeiten</a>
<a href="./post9-v6.html">Variante 6 bearbeiten</a>
<a href="./post9-v7.html">Variante 7 bearbeiten</a>
</div>
<main class="stage" id="stage">
<div class="flaeche">
<div class="kopf">
<h1>Post 9 · Webinar-Anzeige</h1>
<p id="meta">Fünf Varianten derselben Anzeige. Lade Streifen ...</p>
<p id="meta">Sieben Varianten derselben Anzeige. Lade Streifen ...</p>
</div>
<section class="variante">
@@ -87,9 +89,12 @@
<section class="variante">
<h2><b>Variante 2</b> · <span>Kundengeschichte</span> · angelehnt an weclapp</h2>
<p>Komposition wie das Karussell von weclapp zu PV Green (Werbebibliothek, ID 792638160291622): Logo mit Etikett
und Foto, Zitat mit freigestellter Person, Ausgangslage, mit HiveGrid, Anmeldung. Farben, Schrift und Formen
von uns: Gelb und Dunkel, Manrope, Waben, Chamfer. Fünf Bilder, kein Video, als Anzeige also auch in 4:5 möglich.</p>
<p>Komposition wie das Karussell von weclapp zu PV Green (Werbebibliothek, ID 792638160291622): Etikett
„Live-Webinar“ und Foto, Zitat mit freigestellter Person, Vorher, Heute, Anmeldung. Seit 04.11. ohne HiveGrid
im Text und ohne Fachwörter. Die Geschichte: Noah kriegt nicht in die Ausführung, was in seinem Kopf ist.
Vorher hing das Nachfassen am Chef (Karte wie bei weclapp), heute laufen dieselben drei Schritte als Kette von selbst
(Schema wie bei Zapier), wie der Ablauf „Angebot nachfassen“ im Webinar Teil 2. Farben, Schrift und Formen von uns. Fünf Bilder, kein Video, als Anzeige also auch in
4:5 möglich.</p>
<div class="reihe">
<div class="rahmen"><iframe id="f2" src="./post9-v2.html?nur=streifen" loading="eager"></iframe></div>
</div>
@@ -108,8 +113,10 @@
<h2><b>Variante 4</b> · <span>Zahlen</span> · angelehnt an HERO Insights</h2>
<p>Komposition wie das Karussell „HERO Insights“ (Werbebibliothek, ID 3818182885142025): dunkles Titelbild,
dann Karten mit Titel, schwarzem und gelbem Balken und einer Grafik. Titelbild mit Noah als Teaser fürs Webinar,
Zahlen als Wabenbild (100 Waben) und Ring statt Tabellen. Thema: Zeit, die Betriebe verlieren, und wie wenig KI bisher
genutzt wird. Zahlen aus KfW Research (April 2025) und Bitkom (504 Betriebe, 2025), Quelle auf jeder Karte.</p>
dann 100 Waben als Band für 8 Stunden Bürokratie, eine große 4 mit den 100 Waben als Block für KI, zuletzt 72 %
„zu ausgelastet“ groß im gelben Kasten. Jede Karte sieht anders aus. Titel, Bürokratie und KI laufen als Video:
eine gelbe Welle durchs Wabenmuster, dann die Waben erst gelb, die wichtigen zuletzt rot.
Zahlen aus KfW Research (April 2025) und Bitkom (504 Betriebe, 2025), Quelle auf jeder Karte.</p>
<div class="reihe">
<div class="rahmen"><iframe id="f4" src="./post9-v4.html?nur=streifen" loading="eager"></iframe></div>
</div>
@@ -122,6 +129,26 @@
<div class="rahmen"><iframe id="f5" src="./post9-v5.html?nur=streifen" loading="eager"></iframe></div>
</div>
</section>
<section class="variante">
<h2><b>Variante 6</b> · <span>Arbeitsheft</span> · angelehnt an Noahs E-Book</h2>
<p>Aussagen und Zeichnungen aus Noahs Arbeitsheft „Jede Frage lief über meinen Tisch“: Titel dunkel wie der
Umschlag, mit den drei Fragen in Handschrift, der Rest weiß, dann Engpass, Inseln, Bewegungsmelder, zehn Handgriffe bei einer Wärmepumpe
und die Anmeldung. Manrope, Literata und Caveat wie im Heft, Skizzen-Kästen und gelbe Pfeile nach der Website.
Der Titel läuft als Video, die Pfeile werden wie mit dem Stift gezogen (Test).</p>
<div class="reihe">
<div class="rahmen"><iframe id="f6" src="./post9-v6.html?nur=streifen" loading="eager"></iframe></div>
</div>
</section>
<section class="variante">
<h2><b>Variante 7</b> · <span>Arbeitsheft dunkel</span> · wie Variante 6</h2>
<p>Dieselben sechs Slides auf dem dunklen Grund. Die Zeichnungen liegen auf weißen Karten, wie im Heft auf den
dunklen Seiten.</p>
<div class="reihe">
<div class="rahmen"><iframe id="f7" src="./post9-v7.html?nur=streifen" loading="eager"></iframe></div>
</div>
</section>
</div>
</main>
@@ -137,6 +164,8 @@
f3: { el: document.getElementById("f3"), w: 5400, h: 1080, da: false },
f4: { el: document.getElementById("f4"), w: 5400, h: 1080, da: false },
f5: { el: document.getElementById("f5"), w: 5400, h: 1080, da: false },
f6: { el: document.getElementById("f6"), w: 6480, h: 1080, da: false },
f7: { el: document.getElementById("f7"), w: 6480, h: 1080, da: false },
};
const video = document.getElementById("anim1"), videoRahmen = document.getElementById("video1");
@@ -151,7 +180,7 @@
/* Alle Slides im selben Massstab, eingepasst an die laengste Reihe. */
function legen() {
const breit = Math.max(st.f1.w + 1080, st.f2.w, st.f3.w, st.f4.w, st.f5.w);
const breit = Math.max(st.f1.w + 1080, st.f2.w, st.f3.w, st.f4.w, st.f5.w, st.f6.w, st.f7.w);
const k = Math.min((stage.clientWidth - 108) / breit, 0.42);
Object.values(st).forEach(r => {
r.el.style.width = r.w + "px";
@@ -167,9 +196,9 @@
if (!video.src.endsWith(quelle.slice(1))) { video.src = quelle; video.play().catch(() => {}); }
const fertig = Object.values(st).every(r => r.da);
meta.textContent = fertig
? "Fünf Varianten derselben Anzeige · Variante 1: 1 Video, 1 Bild · Varianten 2 bis 5: je 5 Bilder · Format " +
? "Sieben Varianten derselben Anzeige · Variante 1: 1 Video, 1 Bild · Varianten 2 bis 5: je 5 Elemente · 6 und 7: je 6 Bilder · Format " +
Object.values(st).map(r => r.h === 1080 ? "1:1" : "4:5").join(", ")
: "Fünf Varianten derselben Anzeige. Lade Streifen ...";
: "Sieben Varianten derselben Anzeige. Lade Streifen ...";
}
window.addEventListener("resize", legen);
legen();
+2
View File
@@ -1063,6 +1063,8 @@ if (location.search.indexOf("nur=anim") >= 0)
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-gehe="./uebersicht.html">Alle Projekte im Streifen</button>
+4
View File
@@ -117,6 +117,8 @@
<button type="button" data-gehe="./post9-v3.html">Post 9 · Variante 3 · Kundengeschichte dunkel</button>
<button type="button" data-gehe="./post9-v4.html">Post 9 · Variante 4 · Zahlen</button>
<button type="button" data-gehe="./post9-v5.html">Post 9 · Variante 5 · Zahlen dunkel</button>
<button type="button" data-gehe="./post9-v6.html">Post 9 · Variante 6 · Arbeitsheft</button>
<button type="button" data-gehe="./post9-v7.html">Post 9 · Variante 7 · Arbeitsheft dunkel</button>
<button type="button" data-gehe="./post9-varianten.html">Post 9 · Varianten im Vergleich</button>
<hr>
<button type="button" data-klick="neu">Streifen neu laden</button>
@@ -152,6 +154,8 @@
{ datei: "./post9-v3.html", name: "Post 9 · Variante 3 · Kundengeschichte dunkel", theme: "modern" },
{ datei: "./post9-v4.html", name: "Post 9 · Variante 4 · Zahlen", theme: "modern" },
{ datei: "./post9-v5.html", name: "Post 9 · Variante 5 · Zahlen dunkel", theme: "modern" },
{ datei: "./post9-v6.html", name: "Post 9 · Variante 6 · Arbeitsheft", theme: "modern" },
{ datei: "./post9-v7.html", name: "Post 9 · Variante 7 · Arbeitsheft dunkel", theme: "modern" },
];
const flaeche = document.getElementById("flaeche");