Theme modern: Metallband, Icon-Satz und echte G-Marke
Das Band laeuft als durchgehende Zeichnung ueber den ganzen Streifen, jede Slide zeigt ihren Ausschnitt ueber --slide-i. An der Naht laeuft es weiter statt neu anzusetzen -- der Uebergang, den ein Carousel sonst nicht hat. Es ist ein Rohr, kein Farbband: vierzig Streifen aus einer Rampe, die Glanzstelle eingerueckt bei 20 % und fast weiss, der Kernschatten bei 78 % statt an der Unterkante, darunter Licht vom Grund zurueck. Der erste Anlauf mit vier weichen Streifen sah nach Bonbon aus. Damit das Band quer durch die Komposition laufen darf, liegt jede Visualisierung jetzt auf einer deckenden Karte. Linienwerk auf Transparenz verschwindet darin. Slide 5 musste dafuer von 988 auf 896 schrumpfen, Slide 6 bekam links Einzug. Ausserdem: - Feather-Icons aus @subframe/core statt selbst gezeichneter Zeichen, auf Slide 2 bis 5. Slide 6 behaelt ihre Nachbauten aus WaitlistNext. - Die echte G-Marke auf dem Ring, als Polygon statt als Bilddatei. - Die 01/02/03 auf Slide 6 sind raus. - Slide 1 uebernimmt den Rahmen der Ueber-uns-Seite: Radius 38 auf teal-hellem Grund, Foto 4,2 % eingerueckt. - Der Grund ist wieder #FFFFFF, wie Post 1 und Post 2. Den Kontrast tragen die Karten jetzt ueber die Kante (#D5DBE1). - Slide 4 und 5 hiessen abweichend vom Original; Beschriftungen und Fliesstext gleichen jetzt post2.html. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
af6afe8e6e
commit
5fe1d2945f
3 files changed
+328
-90
No files matched your search
+245
-80
@@ -353,6 +353,22 @@
|
||||
im Markup, damit beide Themes denselben Aufbau haben. */
|
||||
.layer-raster { background: none; }
|
||||
|
||||
/* ─── Das Band ──────────────────────────────────────────────────────────
|
||||
Ein durchgehendes Band ueber den ganzen Streifen, jede Slide zeigt nur
|
||||
ihren Ausschnitt. Die Verschiebung laeuft ueber --slide-i, das die
|
||||
Slide ohnehin schon traegt: Slide 3 zeigt also die dritten 1080 px
|
||||
derselben Zeichnung. An der Naht laeuft die Linie damit weiter, statt
|
||||
neu anzusetzen -- das ist der Uebergang, den ein Carousel sonst nicht
|
||||
hat, weil jede Slide fuer sich steht.
|
||||
|
||||
Es liegt in .bg und damit unter allem. Deckend heisst aber auch:
|
||||
es deckt. Was darueber liegen soll, muss selbst deckend sein --
|
||||
Linienwerk auf Transparenz verschwindet darin. */
|
||||
.layer-band {
|
||||
position: absolute; top: 0;
|
||||
left: calc(var(--slide-i) * -1080px);
|
||||
}
|
||||
|
||||
|
||||
/* ─── Visualisierungen ───────────────────────────────────────────────────
|
||||
Post 2 zeigt keine Screenshots, sondern das Stichwort aus dem Text als
|
||||
@@ -411,22 +427,23 @@
|
||||
Markenform, und ein dunkles Bild auf hellem Grund braucht keine
|
||||
Umrandung. Die Zeichenebene bleibt im Markup, zeichnet aber nichts. */
|
||||
.vis svg.karte-skizze { display: none; }
|
||||
/* Der Rahmen der Ueber-uns-Seite, Werte aus TeamCards.tsx: die Karte
|
||||
traegt aussen Radius 38 auf teal-hellem Grund, das abgedunkelte Foto
|
||||
sitzt 4,2 % eingerueckt mit Radius 27 (= 38 x .72). Die Person darf
|
||||
ueber diesen Rand hinausragen und wird erst vom Aussenradius
|
||||
beschnitten -- daher inset 0 und z-index 4. */
|
||||
.karte {
|
||||
position: relative; aspect-ratio: 4/5; overflow: hidden;
|
||||
background: #0f1a2e; isolation: isolate;
|
||||
clip-path: polygon(
|
||||
16px 0, calc(100% - 16px) 0, 100% 16px, 100% calc(100% - 16px),
|
||||
calc(100% - 16px) 100%, 16px 100%, 0 calc(100% - 16px), 0 16px
|
||||
);
|
||||
background: #E8F4F4; isolation: isolate; border-radius: 38px;
|
||||
}
|
||||
.karte-grund {
|
||||
position: absolute; inset: 0; z-index: 1; overflow: hidden;
|
||||
border-radius: 8px; background: #2b2d2a;
|
||||
position: absolute; inset: 4.2%; z-index: 1; overflow: hidden;
|
||||
border-radius: 27px; background: #2b2d2a;
|
||||
filter: grayscale(.04) saturate(.74) brightness(.73);
|
||||
}
|
||||
.karte-grund img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
|
||||
.karte-wash {
|
||||
position: absolute; inset: 0;
|
||||
position: absolute; inset: 4.2%; border-radius: 27px;
|
||||
background: linear-gradient(180deg, rgba(15,26,46,.01), rgba(15,26,46,.12));
|
||||
}
|
||||
.karte-person {
|
||||
@@ -871,7 +888,7 @@
|
||||
text-secondary, container-bg, border-neutral. Eine erfundene Palette war
|
||||
der erste Fehler dieser Fassung. */
|
||||
.slide[data-variant="hell"] {
|
||||
background: #FFFFFF;
|
||||
background: var(--surface);
|
||||
--head-color: #1A1A1A;
|
||||
--body-color: #555555;
|
||||
--accent-on: #C8901A;
|
||||
@@ -1205,14 +1222,14 @@
|
||||
eyebrow: "Der Wechsel",
|
||||
head: 'Und wechseln?<br><span class="a">Kannst du vergessen.</span>',
|
||||
body: "Da hängen Jahre an Stammdaten, Aufträgen und Buchhaltung drin. Ein Wechsel führt ins Chaos.",
|
||||
vis: "ersetzen", visW: 896, visLeft: 92, visBottom: 195,
|
||||
vis: "ersetzen", visW: 896, visLeft: 92, visBottom: 130,
|
||||
},
|
||||
{
|
||||
key: "mehr", type: "feature",
|
||||
layouts: [{ id: "standard", label: "Standard" }],
|
||||
eyebrow: "Was gefehlt hat",
|
||||
head: 'Wir wollten nicht weg.<br><span class="a">Wir wollten mehr.</span>',
|
||||
body: "Ein CRM, Vertrieb, Marketing, Automatisierungen. Unsere Tools sollen endlich miteinander reden.",
|
||||
body: "KI-Lösungen, Projektmanagement, Automatisierungen. Unsere Tools sollen endlich miteinander reden.",
|
||||
vis: "lose", visW: 988, visLeft: 92, visBottom: 120,
|
||||
},
|
||||
{
|
||||
@@ -1221,7 +1238,7 @@
|
||||
eyebrow: "Die Lösung",
|
||||
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,
|
||||
vis: "verbinden", visW: 896, visLeft: 92, visBottom: 120,
|
||||
},
|
||||
{
|
||||
key: "warteliste", type: "feature",
|
||||
@@ -1356,7 +1373,7 @@
|
||||
GELB = "#F1B729", GELB_DUNKEL = "#3E2C0A", GELB_HELL = "#FFE082",
|
||||
TEAL = "#0D6E6E", TEAL_HELL = "#E8F4F4",
|
||||
ROT = "#E07B54", ROT_HELL = "#FBEAE4", // accent-orange der Website
|
||||
LINIE = "#E5E5E5", KARTE = "#F6F8FA";
|
||||
LINIE = "#E5E5E5", KANTE = "#D5DBE1", KARTE = "#FFFFFF";
|
||||
function farbenNachziehen() {
|
||||
const d = variant === "dunkel";
|
||||
TINTE = d ? "#FFFFFF" : "#1A1A1A";
|
||||
@@ -1367,15 +1384,31 @@
|
||||
ROT = "#E07B54";
|
||||
ROT_HELL = d ? "rgba(224,123,84,.18)" : "#FBEAE4";
|
||||
LINIE = d ? "rgba(255,255,255,.14)" : "#E5E5E5";
|
||||
KARTE = d ? "#1A2740" : "#F6F8FA";
|
||||
KANTE = d ? "rgba(255,255,255,.22)" : "#D5DBE1";
|
||||
KARTE = d ? "#1A2740" : "#FFFFFF";
|
||||
}
|
||||
|
||||
/* Der Chamfer der Marke: 16 px Schnitt, wie in lib/chamfer.ts der Website.
|
||||
Dort steht auch, warum eine chamferte Flaeche keinen Rand bekommt --
|
||||
clip-path beschneidet ihn mit. Also fuellen statt umranden. */
|
||||
const CHAMFER_C = 16;
|
||||
const chamferFlaeche = (x, y, w, h, fuell, c) =>
|
||||
'<path d="' + chamfer(x, y, w, h, c == null ? CHAMFER_C : c) + '" fill="' + fuell + '"/>';
|
||||
|
||||
/* Die G-Marke, Punkte woertlich aus assets/brand/g-mark.svg. Als Pfad und
|
||||
nicht als Bild: ein PNG im foreignObject kann beim Export verschwinden
|
||||
(rules.md §7), ein Pfad nie. Der Massstab braucht mehr als eine
|
||||
Nachkommastelle, sonst schrumpft die Marke sichtbar. */
|
||||
const G_PUNKTE = "384.5,166.5 336.4,83.2 192.2,166.5 288.3,166.5 240.3,249.7 " +
|
||||
"144.2,249.7 96.1,166.5 144.2,83.2 336.4,83.2 298,16.8 288.3,0 96.1,0 " +
|
||||
"0,166.5 96.1,332.9 288.3,332.9";
|
||||
function gMarke(cx, cy, hoehe, farbe) {
|
||||
const s = hoehe / 332.9;
|
||||
return '<g transform="translate(' + n1(cx - 384.5 * s / 2) + ',' + n1(cy - hoehe / 2) +
|
||||
') scale(' + s.toFixed(5) + ')"><polygon points="' + G_PUNKTE + '" fill="' +
|
||||
farbe + '"/></g>';
|
||||
}
|
||||
const chamferFlaeche = (x, y, w, h, fuell, c, rand) =>
|
||||
'<path d="' + chamfer(x, y, w, h, c == null ? CHAMFER_C : c) + '" fill="' + fuell + '"' +
|
||||
(rand ? ' stroke="' + KANTE + '" stroke-width="1.5"' : "") + '/>';
|
||||
const zug = (d, o) => {
|
||||
o = o || {};
|
||||
return '<path d="' + d + '" fill="none" stroke="' + (o.f || TINTE) +
|
||||
@@ -1694,18 +1727,19 @@
|
||||
die Leitung sie erwartet. Wer eine Beschriftung aendert, aendert die
|
||||
Kastenbreite und muss die Ankerpunkte unten mitziehen. */
|
||||
const chips = [
|
||||
{ x: 34, y: 60, t: "E-Mails", g: glyBrief },
|
||||
{ x: 104, y: 200, t: "Zettel im Auto", g: glyZettel },
|
||||
{ x: 48, y: 340, t: "Tabellen", g: glyTabelle },
|
||||
{ x: 128, y: 480, t: "Fotos auf dem Handy", g: glyHandy },
|
||||
{ x: 60, y: 620, t: "Ordner im Regal", g: glyOrdner },
|
||||
{ x: 34, y: 60, t: "E-Mails", i: "mail" },
|
||||
{ x: 104, y: 200, t: "Zettel im Auto", i: "sticky-note" },
|
||||
{ x: 48, y: 340, t: "Tabellen", i: "table" },
|
||||
{ x: 128, y: 480, t: "Fotos auf dem Handy", i: "smartphone" },
|
||||
{ x: 60, y: 620, t: "Ordner im Regal", i: "folder" },
|
||||
];
|
||||
chips.forEach(c => {
|
||||
c.w = Math.round(84 + c.t.length * 14.2);
|
||||
c.r = c.x + c.w;
|
||||
});
|
||||
|
||||
let raus = "";
|
||||
// Deckender Grund: sonst laeuft das Band mitten durch die Leitung.
|
||||
let raus = chamferFlaeche(0, 0, W, H, KARTE, 22, true);
|
||||
|
||||
// Rechte Kette: von rechter Kante zu rechter Kante, mit weiten Bogen.
|
||||
const rechts = [
|
||||
@@ -1732,14 +1766,17 @@
|
||||
als in Grau, weil eine unterbrochene Linie weniger Flaeche hat. */
|
||||
raus += zug(leitung, { f: GELB, w: 2.9, op: .78, strichel: "11 13" });
|
||||
|
||||
[[700, 96, "blatt", 52], [770, 236, "bild", 46], [760, 430, "person", 50],
|
||||
[250, 690, "blatt", 44]]
|
||||
.forEach(k => { raus += zug(kachel(k[0], k[1], k[2], k[3]), { w: 2.5, op: .8 }); });
|
||||
[[700, 96, "file-text", 52], [770, 236, "image", 46], [760, 430, "user", 50],
|
||||
[250, 690, "file-text", 44]]
|
||||
.forEach(k => {
|
||||
raus += chamferFlaeche(k[0] - k[3] / 2, k[1] - k[3] / 2, k[3], k[3], KARTE, 9, true);
|
||||
raus += feather(k[2], k[0], k[1], k[3] * 0.46, TEXT3, 2);
|
||||
});
|
||||
|
||||
chips.forEach(c => {
|
||||
const y = c.y - HOCH / 2;
|
||||
raus += zug(chamfer(c.x, y, c.w, HOCH, 13), { w: 3.4 });
|
||||
raus += zug(c.g(c.x + 34, c.y), { w: 2.6 });
|
||||
raus += chamferFlaeche(c.x, y, c.w, HOCH, KARTE, 13, true);
|
||||
raus += feather(c.i, c.x + 34, c.y, 30, TINTE, 2);
|
||||
raus += '<text x="' + (c.x + 64) + '" y="' + (c.y + 10) + '" ' +
|
||||
'font-family="Manrope, sans-serif" font-size="27" font-weight="600" ' +
|
||||
'letter-spacing="-0.01em" fill="' + TINTE + '">' + c.t + '</text>';
|
||||
@@ -1948,7 +1985,7 @@
|
||||
Ein Betrieb, der ueber einen Wechsel nachdenkt, versteht eine
|
||||
abgebrochene Uebernahme sofort und braucht dafuer kein Sinnbild. */
|
||||
function visWechseln() {
|
||||
const W = 896, H = 580, P = 52;
|
||||
const W = 896, H = 700, P = 56;
|
||||
const zeilen = [
|
||||
{ t: "Stammdaten", s: "übertragen", art: "ok" },
|
||||
{ t: "Aufträge", s: "1.284 Konflikte", art: "warn" },
|
||||
@@ -1956,15 +1993,15 @@
|
||||
];
|
||||
const ton = { ok: [TEAL_HELL, TEAL], warn: [GELB_HELL, GELB_DUNKEL], fehler: [ROT_HELL, ROT] };
|
||||
|
||||
let raus = chamferFlaeche(0, 0, W, H, KARTE);
|
||||
let raus = chamferFlaeche(0, 0, W, H, KARTE, null, true);
|
||||
|
||||
raus += '<text x="' + P + '" y="74" font-family="Manrope, sans-serif" font-size="20" ' +
|
||||
raus += '<text x="' + P + '" y="86" font-family="Manrope, sans-serif" font-size="20" ' +
|
||||
'font-weight="700" letter-spacing="0.16em" fill="' + TEXT3 + '">MIGRATION</text>';
|
||||
raus += '<text x="' + P + '" y="134" font-family="Manrope, sans-serif" font-size="38" ' +
|
||||
raus += '<text x="' + P + '" y="152" font-family="Manrope, sans-serif" font-size="38" ' +
|
||||
'font-weight="800" letter-spacing="-0.025em" fill="' + TINTE + '">Alles mitnehmen</text>';
|
||||
|
||||
// Fortschritt: er bleibt stehen, das ist die Aussage.
|
||||
const BY = 200, BW = W - 2 * P;
|
||||
const BY = 248, BW = W - 2 * P;
|
||||
raus += '<text x="' + P + '" y="' + (BY - 14) + '" font-family="Manrope, sans-serif" ' +
|
||||
'font-size="24" font-weight="600" fill="' + TEXT2 + '">Fortschritt</text>';
|
||||
raus += '<text x="' + (W - P) + '" y="' + (BY - 14) + '" text-anchor="end" ' +
|
||||
@@ -1976,20 +2013,11 @@
|
||||
GELB + '"/>';
|
||||
|
||||
zeilen.forEach((z, i) => {
|
||||
const y = 302 + i * 78, f = ton[z.art];
|
||||
const y = 366 + i * 96, f = ton[z.art];
|
||||
raus += '<circle cx="' + (P + 17) + '" cy="' + (y - 9) + '" r="17" fill="' + f[0] + '"/>';
|
||||
const cx = P + 17, cy = y - 9;
|
||||
if (z.art === "ok") {
|
||||
raus += '<path d="M' + (cx - 7) + ',' + cy + 'l5,5l9,-10" fill="none" stroke="' + f[1] +
|
||||
'" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>';
|
||||
} else if (z.art === "warn") {
|
||||
raus += '<path d="M' + cx + ',' + (cy - 8) + 'v9" stroke="' + f[1] +
|
||||
'" stroke-width="3.2" stroke-linecap="round"/>' +
|
||||
'<circle cx="' + cx + '" cy="' + (cy + 7) + '" r="2" fill="' + f[1] + '"/>';
|
||||
} else {
|
||||
raus += '<path d="M' + (cx - 6) + ',' + (cy - 6) + 'l12,12M' + (cx + 6) + ',' + (cy - 6) +
|
||||
'l-12,12" stroke="' + f[1] + '" stroke-width="3.2" stroke-linecap="round"/>';
|
||||
}
|
||||
const zeichen = { ok: "check", warn: "alert-triangle", fehler: "x" }[z.art];
|
||||
raus += feather(zeichen, cx, cy, 19, f[1], 2.6);
|
||||
raus += '<text x="' + (P + 52) + '" y="' + y + '" font-family="Manrope, sans-serif" ' +
|
||||
'font-size="30" font-weight="700" letter-spacing="-0.015em" fill="' + TINTE + '">' +
|
||||
z.t + '</text>';
|
||||
@@ -1997,7 +2025,7 @@
|
||||
'font-family="Manrope, sans-serif" font-size="26" font-weight="600" fill="' +
|
||||
(z.art === "fehler" ? ROT : TEXT2) + '">' + z.s + '</text>';
|
||||
if (i < zeilen.length - 1) {
|
||||
raus += '<rect x="' + P + '" y="' + (y + 30) + '" width="' + BW + '" height="1" fill="' +
|
||||
raus += '<rect x="' + P + '" y="' + (y + 38) + '" width="' + BW + '" height="1" fill="' +
|
||||
LINIE + '"/>';
|
||||
}
|
||||
});
|
||||
@@ -2014,6 +2042,45 @@
|
||||
'" xmlns="http://www.w3.org/2000/svg">' + raus + '</svg>';
|
||||
}
|
||||
|
||||
/* ─── Feather-Icons ──────────────────────────────────────────────────────
|
||||
Die Pfade stammen aus @subframe/core, dem Icon-Satz, mit dem unsere
|
||||
Oberflaeche gebaut ist (siehe hivegrid-pitch). 24x24-Raster, 2 px Strich,
|
||||
runde Enden. Selbst gezeichnete Zeichen sahen daneben immer eine Spur
|
||||
anders aus; das hier ist dieselbe Hand.
|
||||
|
||||
Die Strichstaerke wird durch den Massstab geteilt, damit sie bei jeder
|
||||
Groesse gleich schwer aussieht -- sonst wird ein grosses Icon fett. */
|
||||
const FEATHER = {
|
||||
"alert-triangle": '<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',
|
||||
"check": '<polyline points="20 6 9 17 4 12"/>',
|
||||
"clipboard-list": '<rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M12 11h4"/><path d="M12 16h4"/><path d="M8 11h.01"/><path d="M8 16h.01"/>',
|
||||
"columns-3": '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18"/><path d="M15 3v18"/>',
|
||||
"file-text": '<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/><line x1="16" x2="8" y1="13" y2="13"/><line x1="16" x2="8" y1="17" y2="17"/><line x1="10" x2="8" y1="9" y2="9"/>',
|
||||
"filter": '<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>',
|
||||
"folder": '<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/>',
|
||||
"image": '<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>',
|
||||
"mail": '<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',
|
||||
"megaphone": '<path d="m3 11 18-5v12L3 14v-3z"/><path d="M11.6 16.8a3 3 0 1 1-5.8-1.6"/>',
|
||||
"message-square": '<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
|
||||
"smartphone": '<rect width="14" height="20" x="5" y="2" rx="2" ry="2"/><path d="M12 18h.01"/>',
|
||||
"sparkles": '<path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/>',
|
||||
"sticky-note": '<path d="M15.5 3H5a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2V8.5L15.5 3Z"/><path d="M15 3v6h6"/>',
|
||||
"table": '<path d="M12 3v18"/><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/>',
|
||||
"user": '<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',
|
||||
"users": '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
|
||||
"workflow": '<rect width="8" height="8" x="3" y="3" rx="2"/><path d="M7 11v4a2 2 0 0 0 2 2h4"/><rect width="8" height="8" x="13" y="13" rx="2"/>',
|
||||
"x": '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
|
||||
"zap": '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>'
|
||||
};
|
||||
|
||||
function feather(name, cx, cy, groesse, farbe, staerke) {
|
||||
const s = groesse / 24;
|
||||
return '<g transform="translate(' + n1(cx - groesse / 2) + ',' + n1(cy - groesse / 2) +
|
||||
') scale(' + n1(s) + ')" fill="none" stroke="' + farbe + '" stroke-width="' +
|
||||
n1((staerke == null ? 2 : staerke) / s) +
|
||||
'" stroke-linecap="round" stroke-linejoin="round">' + FEATHER[name] + '</g>';
|
||||
}
|
||||
|
||||
/* ─── Formen fuer die zugespitzte Fassung ───────────────────────────────
|
||||
Workflow-Engine, Vertrieb und Marketing brauchen eigene Zeichen: die
|
||||
bestehenden zeigen Dinge, die ein Branchenprogramm schon kann.
|
||||
@@ -2109,10 +2176,10 @@
|
||||
haengen zusammen, statt nur untereinander zu stehen. */
|
||||
const W = 896, H = 730, KB = 636, KH = 116, LU = 44, KX = 130;
|
||||
const punkte = [
|
||||
{ t: "Workflow-Engine", g: (x, y) => formWorkflow(x, y, 0.82) },
|
||||
{ t: "CRM", g: (x, y) => glyLeute(x, y) },
|
||||
{ t: "Vertrieb", g: (x, y) => formTrichter(x, y, 0.86) },
|
||||
{ t: "Marketing", g: (x, y) => formMegafon(x, y, 0.86) },
|
||||
{ t: "Workflow-Engine", i: "workflow" },
|
||||
{ t: "Projektmanagement", i: "columns-3" },
|
||||
{ t: "Chat", i: "message-square" },
|
||||
{ t: "Mitarbeiter-Management", i: "users" },
|
||||
];
|
||||
const oben = (H - (punkte.length * KH + (punkte.length - 1) * LU)) / 2;
|
||||
const kachelGrund = TEAL_HELL;
|
||||
@@ -2124,15 +2191,15 @@
|
||||
// Verbinder zur naechsten Karte, mit Knoten in der Mitte.
|
||||
if (i < punkte.length - 1) {
|
||||
const vy = y + KH, vm = vy + LU / 2;
|
||||
raus += zug(strich(mx, vy, mx, vy + LU), { f: LINIE, w: 2 });
|
||||
raus += '<circle cx="' + mx + '" cy="' + n1(vm) + '" r="10" fill="' + KARTE + '"/>';
|
||||
raus += zug(strich(mx - 5, vm, mx + 5, vm) + strich(mx, vm - 5, mx, vm + 5),
|
||||
{ f: TEAL, w: 2 });
|
||||
raus += zug(strich(mx, vy, mx, vy + LU), { f: TEAL, w: 2, op: .32 });
|
||||
raus += '<circle cx="' + mx + '" cy="' + n1(vm) + '" r="13" fill="' + TEAL_HELL + '"/>';
|
||||
raus += zug(strich(mx - 6, vm, mx + 6, vm) + strich(mx, vm - 6, mx, vm + 6),
|
||||
{ f: TEAL, w: 2.4 });
|
||||
}
|
||||
|
||||
raus += chamferFlaeche(KX, y, KB, KH, KARTE);
|
||||
raus += chamferFlaeche(KX, y, KB, KH, KARTE, null, true);
|
||||
raus += chamferFlaeche(KX + 28, y + 26, 64, 64, kachelGrund, 10);
|
||||
raus += zug(p.g(KX + 60, y + 58), { f: TEAL, w: 2.6 });
|
||||
raus += feather(p.i, KX + 60, y + 58, 34, TEAL, 2.2);
|
||||
raus += '<text x="' + (KX + 118) + '" y="' + n1(my + 12) + '" ' +
|
||||
'font-family="Manrope, sans-serif" font-size="34" font-weight="700" ' +
|
||||
'letter-spacing="-0.02em" fill="' + TINTE + '">' + p.t + '</text>';
|
||||
@@ -2170,14 +2237,14 @@
|
||||
aktiv. */
|
||||
function visWarteliste() {
|
||||
const W = 896, H = 600;
|
||||
const HB = 86, HH = 77, HX = 0, TX = 120, ABSTAND = 84;
|
||||
const HB = 86, HH = 77, HX = 52, TX = 172, ABSTAND = 84;
|
||||
|
||||
const schritte = [
|
||||
{ n: "01", t: "Du trägst dich ein", ikon: "brief",
|
||||
{ t: "Du trägst dich ein", ikon: "brief",
|
||||
z: ["Eine E-Mail genügt. Kein Vertrag,", "keine Kreditkarte, unverbindlich."] },
|
||||
{ n: "02", t: "Wir melden uns", ikon: "chat",
|
||||
{ t: "Wir melden uns", ikon: "chat",
|
||||
z: ["Sobald HiveGrid für deinen Betrieb", "bereit ist, persönlich und ohne Spam."] },
|
||||
{ n: "03", t: "Du bist von Anfang an dabei", ikon: "konfetti",
|
||||
{ t: "Du bist von Anfang an dabei", ikon: "konfetti",
|
||||
z: ["Unter den Ersten, die HiveGrid", "nutzen und mitgestalten."] },
|
||||
];
|
||||
|
||||
@@ -2224,11 +2291,12 @@
|
||||
},
|
||||
};
|
||||
|
||||
let raus = "";
|
||||
// Deckender Grund: sonst laeuft das Band mitten durch die Liste.
|
||||
let raus = chamferFlaeche(0, 0, W, H, KARTE, 22, true);
|
||||
const mitte = i => oben + i * (blockHoehe + ABSTAND) + HH / 2;
|
||||
|
||||
// Die Schiene liegt hinter den Waben und verbindet ihre Mitten.
|
||||
raus += '<rect x="' + n1(HB / 2 - 1.5) + '" y="' + n1(mitte(0)) + '" width="3" height="' +
|
||||
raus += '<rect x="' + n1(HX + HB / 2 - 1.5) + '" y="' + n1(mitte(0)) + '" width="3" height="' +
|
||||
n1(mitte(schritte.length - 1) - mitte(0)) + '" rx="1.5" fill="' + GELB + '"/>';
|
||||
|
||||
schritte.forEach((sc, i) => {
|
||||
@@ -2236,9 +2304,6 @@
|
||||
raus += '<path d="' + wabeForm(HX, y) + '" fill="' + GELB + '"/>';
|
||||
raus += zeichen[sc.ikon](HX + HB / 2, y + HH / 2);
|
||||
raus += '<text x="' + TX + '" y="' + n1(y + 42) + '" font-family="Manrope, sans-serif" ' +
|
||||
'font-size="21" font-weight="800" letter-spacing="0.14em" fill="' + GELB_DUNKEL + '">' +
|
||||
sc.n + '</text>';
|
||||
raus += '<text x="' + (TX + 52) + '" y="' + n1(y + 42) + '" font-family="Manrope, sans-serif" ' +
|
||||
'font-size="32" font-weight="700" letter-spacing="-0.015em" fill="' + TINTE + '">' +
|
||||
sc.t + '</text>';
|
||||
sc.z.forEach((z, k) => {
|
||||
@@ -2266,17 +2331,18 @@
|
||||
const KERN = 104, RING = 202, SATX = 344, SATY = 262, KACHEL = 88;
|
||||
|
||||
const module = [
|
||||
{ a: 240, t: "KI & MCP", ikon: (x, y) => formWorkflow(x, y, 0) },
|
||||
{ a: 300, t: "Marketing", ikon: (x, y) => formMegafon(x, y, 1.0) },
|
||||
{ a: 0, t: "CRM", ikon: (x, y) => glyLeute(x, y) },
|
||||
{ a: 60, t: "Vertrieb", ikon: (x, y) => formTrichter(x, y, 1.0) },
|
||||
{ a: 120, t: "Automatisierung", ikon: (x, y) => glyZahnrad(x, y) },
|
||||
{ a: 180, t: "Workflow-Engine", ikon: (x, y) => formWorkflow(x, y, 1.0) },
|
||||
{ a: 240, t: "KI", i: "sparkles" },
|
||||
{ a: 300, t: "Chat", i: "message-square" },
|
||||
{ a: 0, t: "Mitarbeiter", i: "users" },
|
||||
{ a: 60, t: "Automation", i: "zap" },
|
||||
{ a: 120, t: "Projekte", i: "columns-3" },
|
||||
{ a: 180, t: "Formulare", i: "clipboard-list" },
|
||||
];
|
||||
// KI hat kein eigenes Zeichen im Satz, deshalb der Funke von Slide 5 alt.
|
||||
module[0].ikon = (x, y) => funkeForm(x, y, 20);
|
||||
|
||||
let raus = "";
|
||||
// Deckender Grund: sonst laeuft das Band mitten durch das Diagramm.
|
||||
let raus = chamferFlaeche(0, 0, W, H, KARTE, 22, true);
|
||||
|
||||
// Der Ring: HiveGrid liegt um den Kern, nicht an seiner Stelle.
|
||||
raus += '<circle cx="' + CX + '" cy="' + CY + '" r="' + RING + '" fill="none" stroke="' +
|
||||
@@ -2293,8 +2359,8 @@
|
||||
'" stroke="' + LINIE + '" stroke-width="2"/>';
|
||||
raus += '<circle cx="' + n1(CX + ux * RING) + '" cy="' + n1(CY + uy * RING) +
|
||||
'" r="7" fill="' + GELB + '"/>';
|
||||
raus += chamferFlaeche(sx - KACHEL / 2, sy - KACHEL / 2, KACHEL, KACHEL, TEAL_HELL, 12);
|
||||
raus += zug(m.ikon(sx, sy), { f: TEAL, w: 2.6 });
|
||||
raus += chamferFlaeche(sx - KACHEL / 2, sy - KACHEL / 2, KACHEL, KACHEL, KARTE, 12, true);
|
||||
raus += feather(m.i, sx, sy, 42, GELB, 2.3);
|
||||
const ty = m.a > 180 ? sy - KACHEL / 2 - 16 : sy + KACHEL / 2 + 34;
|
||||
raus += '<text x="' + n1(sx) + '" y="' + n1(ty) + '" text-anchor="middle" ' +
|
||||
'font-family="Manrope, sans-serif" font-size="24" font-weight="700" ' +
|
||||
@@ -2316,11 +2382,9 @@
|
||||
/* Die Pille auf dem Ring, wie im Pitch-Diagramm. Sie sitzt auf der Bahn
|
||||
und macht damit sichtbar, dass HiveGrid der Ring ist und nicht die
|
||||
Mitte. */
|
||||
const PB = 210, PH = 54, PX = CX - PB / 2, PY = CY - RING - PH / 2;
|
||||
raus += chamferFlaeche(PX, PY, PB, PH, GELB, 12);
|
||||
raus += '<text x="' + CX + '" y="' + n1(PY + 36) + '" text-anchor="middle" ' +
|
||||
'font-family="Manrope, sans-serif" font-size="25" font-weight="800" ' +
|
||||
'letter-spacing="0.1em" fill="' + GELB_DUNKEL + '">HIVEGRID</text>';
|
||||
const PB = 94, PH = 72, PX = CX - PB / 2, PY = CY - RING - PH / 2;
|
||||
raus += chamferFlaeche(PX, PY, PB, PH, KARTE, 14, true);
|
||||
raus += gMarke(CX, CY - RING, 42, GELB);
|
||||
|
||||
return '<svg viewBox="0 0 ' + W + ' ' + H + '" width="' + W + '" height="' + H +
|
||||
'" xmlns="http://www.w3.org/2000/svg">' + raus + '</svg>';
|
||||
@@ -2834,10 +2898,111 @@
|
||||
'<circle cx="12" cy="19" r="1.9"/></svg>';
|
||||
|
||||
|
||||
/* ─── Das Band ──────────────────────────────────────────────────────────
|
||||
Die Wellenlaenge ist mit Absicht kein Vielfaches von 1080. Waere sie es,
|
||||
laege an jeder Naht derselbe Punkt der Welle -- meist ein Scheitel, und
|
||||
ein waagerechtes Band an der Kante sagt dem Auge nichts. So trifft jede
|
||||
Naht eine andere Stelle der Flanke.
|
||||
|
||||
Der Querschnitt ist ein Rohr, kein Farbband. Die Rampe unten ist das,
|
||||
was einen Metallzylinder von einem Bonbon unterscheidet:
|
||||
|
||||
- Die Glanzstelle liegt NICHT an der Oberkante, sondern eingerueckt
|
||||
bei etwa 20 %, und sie ist schmal und fast weiss. Ein breites,
|
||||
weiches Hellgelb obenauf ist genau der Bonbon-Eindruck.
|
||||
- Der dunkelste Punkt liegt NICHT an der Unterkante, sondern bei
|
||||
etwa 78 %. Darunter kommt Licht vom weissen Grund zurueck.
|
||||
- Der Tonumfang ist gross: von #6E4205 bis fast Weiss. Metall hat
|
||||
Kontrast, lackierter Kunststoff nicht.
|
||||
- Beide Silhouetten sind aufgehellt (Fresnel): streifendes Licht
|
||||
wird staerker reflektiert.
|
||||
- Ein paar Laengsstreifen als Schliff. Ohne die bleibt die Oberflaeche
|
||||
zu glatt, um echt zu wirken.
|
||||
|
||||
Kein SVG-Verlauf: der laeuft immer geradlinig durch die Bounding-Box,
|
||||
das Band wellt sich aber, er wuerde also quer statt laengs schattieren.
|
||||
Versetzte Streifen folgen der Kurve von selbst.
|
||||
|
||||
Der Versatz ist senkrecht und nicht rechtwinklig zur Bahn. Dadurch wird
|
||||
das Band an den Flanken um bis zu 14 % schmaler -- das liest sich als
|
||||
Verkuerzung und ist erwuenscht, waehrend echte Parallelkurven an engen
|
||||
Radien Selbstschnitte bekommen. */
|
||||
const BAND_RAMPE = [
|
||||
[0.00, "#D9A65E"], // Oberkante, streifendes Licht
|
||||
[0.07, "#C2841C"],
|
||||
[0.14, "#F0C144"],
|
||||
[0.20, "#FFF6E2"], // Glanzstelle
|
||||
[0.27, "#F6C94E"],
|
||||
[0.40, "#EBA81E"], // Koerperton, unser Orange
|
||||
[0.54, "#C68310"],
|
||||
[0.68, "#985E08"],
|
||||
[0.78, "#6E4205"], // Kernschatten
|
||||
[0.88, "#B67B12"], // Licht vom Grund zurueck
|
||||
[0.96, "#96620F"],
|
||||
[1.00, "#C08B34"], // Unterkante, streifendes Licht
|
||||
];
|
||||
const BAND_STRIEME = [
|
||||
[0.11, 1.4, .16], [0.31, 1.2, -.14], [0.47, 1.8, .12],
|
||||
[0.62, 1.3, -.16], [0.85, 1.5, .14],
|
||||
];
|
||||
|
||||
function mischen(x, y, t) {
|
||||
const z = h => [1, 3, 5].map(i => parseInt(h.slice(i, i + 2), 16));
|
||||
const v = z(x), w = z(y);
|
||||
const k = n => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
|
||||
return "#" + k(v[0] + (w[0] - v[0]) * t) + k(v[1] + (w[1] - v[1]) * t) +
|
||||
k(v[2] + (w[2] - v[2]) * t);
|
||||
}
|
||||
function rampe(stufen, p) {
|
||||
for (let i = 1; i < stufen.length; i++)
|
||||
if (p <= stufen[i][0]) {
|
||||
const v = stufen[i - 1], w = stufen[i];
|
||||
return mischen(v[1], w[1], w[0] === v[0] ? 0 : (p - v[0]) / (w[0] - v[0]));
|
||||
}
|
||||
return stufen[stufen.length - 1][1];
|
||||
}
|
||||
|
||||
function bandSvg() {
|
||||
const W = SLIDES.length * 1080, H = 1350;
|
||||
const MITTE = 880, HUB = 215, WELLE = 2650, PHASE = 700, HALB = 95, N = 40;
|
||||
const y = x => MITTE + HUB * Math.sin(2 * Math.PI * (x + PHASE) / WELLE);
|
||||
const xs = [];
|
||||
for (let x = -180; x <= W + 180; x += 80) xs.push(x);
|
||||
const punkte = v => xs.map(x => x + "," + (y(x) + v).toFixed(1));
|
||||
const bahn = v => "M" + punkte(v).join("L");
|
||||
const flaeche = "M" + punkte(-HALB).join("L") + "L" +
|
||||
punkte(HALB).reverse().join("L") + "Z";
|
||||
const streifen = (p, w, f) => '<path d="' + bahn((p * 2 - 1) * HALB) +
|
||||
'" fill="none" stroke="' + f + '" stroke-width="' + w.toFixed(2) +
|
||||
'" stroke-linecap="butt" stroke-linejoin="round"/>';
|
||||
|
||||
let raus = "";
|
||||
// Die Woelbung: schmale Streifen, leicht ueberlappend, damit zwischen
|
||||
// ihnen keine Naht stehen bleibt.
|
||||
const dicke = (2 * HALB / N) * 1.3;
|
||||
for (let i = 0; i < N; i++) {
|
||||
const p = (i + 0.5) / N;
|
||||
raus += streifen(p, dicke, rampe(BAND_RAMPE, p));
|
||||
}
|
||||
// Die harte Glanzkante -- der einzige Strich mit scharfem Rand.
|
||||
raus += streifen(0.20, 2.6, "#FFFDF4");
|
||||
// Schliffspuren laengs.
|
||||
BAND_STRIEME.forEach(v => {
|
||||
raus += streifen(v[0], v[1],
|
||||
mischen(rampe(BAND_RAMPE, v[0]), v[2] > 0 ? "#FFFFFF" : "#000000", Math.abs(v[2])));
|
||||
});
|
||||
// Die Silhouette. Ohne sie franst das Band auf hellem Grund aus.
|
||||
raus += '<path d="' + flaeche + '" fill="none" stroke="#8A5A10" stroke-width="1.4"/>';
|
||||
|
||||
return '<svg class="layer-band" width="' + W + '" height="' + H + '" viewBox="0 0 ' +
|
||||
W + ' ' + H + '" xmlns="http://www.w3.org/2000/svg">' + raus + '</svg>';
|
||||
}
|
||||
|
||||
// Positionen im 5400er Raum. Die Nähte liegen auf 1080 / 2160 / 3240 / 4320.
|
||||
const BG_HTML =
|
||||
const bgHtml = () =>
|
||||
'<div class="bg">' +
|
||||
'<div class="layer-raster"></div>' +
|
||||
bandSvg() +
|
||||
'</div>';
|
||||
|
||||
function contentHtml(s, i) {
|
||||
@@ -3083,7 +3248,7 @@
|
||||
el.dataset.frame = frameStyle;
|
||||
el.dataset.editmode = editMode;
|
||||
el.style.setProperty("--slide-i", i);
|
||||
el.innerHTML = BG_HTML;
|
||||
el.innerHTML = bgHtml();
|
||||
|
||||
/* Jede Slide traegt das vollstaendige Blatt, nicht nur ihre Nachbarn.
|
||||
Vorher waren es i-1 bis i+1, und ein Element liess sich damit genau eine
|
||||
|
||||
@@ -33,6 +33,12 @@ werden** — das passiert nicht automatisch.
|
||||
Beitrag; das Theme sagt, *wie er aussieht*. Beide Themes teilen Aufbau, Texte
|
||||
und Kompositionen der Visualisierungen.
|
||||
|
||||
> **Der Grund ist über alle Beiträge hinweg derselbe: `--surface` `#FFFFFF`.**
|
||||
> Kein Theme darf ihn ändern. Im Profilraster stehen die Beiträge nebeneinander,
|
||||
> und schon ein leicht getönter Grund fällt dort als Fehler auf. Ein Theme, das
|
||||
> mehr Kontrast für seine Karten braucht, holt ihn sich über die Kante
|
||||
> (`--border-neutral` `#D5DBE1`), nicht über den Grund.
|
||||
|
||||
| Theme | Erkennungszeichen | Datei |
|
||||
|---|---|---|
|
||||
| `notebook` | Rasterhintergrund, Zeichenblock-Optik, Marker in der Überschrift, handgezogene Formen | `post2.html` |
|
||||
@@ -45,11 +51,75 @@ nur — die Unterschiede stecken in den CSS-Werten und in den Zeichen-Primitiven
|
||||
|
||||
| | notebook | modern |
|
||||
|---|---|---|
|
||||
| Grund | Raster, 78 px | einfarbig, keine Textur |
|
||||
| Grund | Raster, 78 px | weiß, keine Textur |
|
||||
| Über alle Slides | — | ein durchgehendes Band |
|
||||
| Akzent in der Überschrift | Marker-Fläche | farbiges Wort |
|
||||
| Formen | `strich` schwingt, Ecken schießen über | exakt, keine Abweichung |
|
||||
| Flächen | Schraffur | Füllung |
|
||||
| Zweitfarbe | keine | Teal `#0D6E6E` |
|
||||
| Zeichen | selbst gezeichnet | Feather aus `@subframe/core` |
|
||||
|
||||
**Karten stehen weiß auf weiß und tragen über ihre Kante.** `#D5DBE1`, nicht
|
||||
`#E5E5E5` — die hellere Linie verschwindet auf Weiß. Den Grund zu tönen wäre
|
||||
der einfachere Weg und ist verboten, siehe oben. Auf der Website reicht
|
||||
`#E5E5E5`, weil dort ein Schatten mitträgt; hier nicht (§7).
|
||||
|
||||
**Das Band ist ein einziges Bild über den ganzen Streifen.** Jede Slide zeigt
|
||||
ihren Ausschnitt, verschoben über `--slide-i`. An der Naht läuft es deshalb
|
||||
weiter, statt neu anzusetzen — das ist der Übergang, den ein Carousel sonst
|
||||
nicht hat, weil jede Slide für sich steht. Drei Punkte, die daran hängen:
|
||||
|
||||
- **Die Wellenlänge darf kein Vielfaches von 1080 sein.** Sonst liegt an jeder
|
||||
Naht derselbe Punkt der Welle, meist ein Scheitel, und ein waagerechtes Band
|
||||
an der Kante sagt dem Auge nichts.
|
||||
- **Der Querschnitt ist ein Rohr, kein Farbband.** Vierzig schmale Streifen,
|
||||
versetzt entlang derselben Bahn, eingefärbt aus der Rampe `BAND_RAMPE`. Was
|
||||
Metall von Bonbon unterscheidet, steht in diesen vier Punkten:
|
||||
- Die **Glanzstelle liegt nicht an der Oberkante**, sondern eingerückt bei
|
||||
20 %, und sie ist schmal und fast weiß. Ein breites weiches Hellgelb
|
||||
obenauf ist genau der Bonbon-Eindruck.
|
||||
- Der **dunkelste Punkt liegt nicht an der Unterkante**, sondern bei 78 %.
|
||||
Darunter kommt Licht vom weißen Grund zurück.
|
||||
- Der **Tonumfang ist groß**: `#6E4205` bis fast Weiß. Metall hat Kontrast,
|
||||
lackierter Kunststoff nicht.
|
||||
- Beide **Silhouetten sind aufgehellt** (Fresnel), dazu ein paar
|
||||
Längsstreifen als Schliff.
|
||||
- **Kein SVG-Verlauf.** Nicht weil Verläufe verboten wären — verboten sind sie
|
||||
nur beim Marker (§5) —, sondern weil ein `linearGradient` immer geradlinig
|
||||
durch die Bounding-Box läuft. Das Band wellt sich, der Verlauf würde also
|
||||
quer statt längs schattieren. Versetzte Streifen folgen der Kurve von selbst.
|
||||
- **Der Versatz ist senkrecht, nicht rechtwinklig zur Bahn.** Dadurch wird das
|
||||
Band an den Flanken um bis zu 14 % schmaler. Das liest sich als Verkürzung
|
||||
und ist erwünscht; echte Parallelkurven bekommen an engen Radien
|
||||
Selbstschnitte.
|
||||
- **Volle Deckkraft.** Jede Abschwächung nimmt dem Band genau das wieder weg,
|
||||
was es zum Körper macht.
|
||||
|
||||
**Das Band läuft quer durch die Komposition, nicht am Rand entlang.** Es liegt
|
||||
in `.bg` und damit unter allem. Damit das trägt, gilt für das Theme `modern`:
|
||||
|
||||
> **Jede Visualisierung liegt auf einer deckenden Karte.** Linienwerk auf
|
||||
> Transparenz verschwindet im Band. Alle sechs Slides von Post 2 sind deshalb
|
||||
> auf `chamferFlaeche(0, 0, W, H, KARTE, 22, true)` gesetzt — das Band taucht
|
||||
> dahinter ab und kommt daneben wieder hoch, wie der Schlauch in der Vorlage
|
||||
> von awork. Eine weiße Ummantelung um einzelne Linien war der erste Versuch
|
||||
> und sah nach Panne aus.
|
||||
|
||||
Daraus folgt: **`visW` darf den Satzspiegel nicht überschreiten.** Solange eine
|
||||
Visualisierung Linienwerk war, durfte sie breiter sein als 896; als Karte muss
|
||||
sie auf die 92er Kante. `.vis svg` skaliert über `--vis-w` mit, die Innenmaße
|
||||
bleiben also unangetastet — bei Slide 5 genügte `visW: 988 → 896`.
|
||||
|
||||
**Die Zeichen kommen aus dem Icon-Satz der Software, nicht aus der Hand.**
|
||||
`@subframe/core`, dieselben Feather-Icons, mit denen die Oberfläche gebaut ist
|
||||
(im Pitch-Paket unter `node_modules/@subframe/core/…/icons/final/`). Sie liegen
|
||||
als `FEATHER`-Tabelle in der Datei, gezogen mit dem Skript aus dem
|
||||
Gesprächsverlauf. Zwei Fallen beim Ziehen: die Props stehen teils als Zahl ohne
|
||||
Anführungszeichen (`x: 3`), und bei Icons mit nur einem Kind muss der
|
||||
`<svg>`-Rahmen weg, sonst rendert nichts.
|
||||
|
||||
Ausnahme ist Slide 6 in `post2-alt.html`: deren drei Zeichen sind Nachbauten
|
||||
aus `WaitlistNext.tsx` und bleiben es.
|
||||
|
||||
**Teal ist die Zweitfarbe des Themes `modern`.** In `notebook` kommt sie nicht
|
||||
vor. Damit hat der bisher ungenutzte Marken-Ton eine Aufgabe: er trägt
|
||||
|
||||
+12
-9
@@ -25,7 +25,7 @@
|
||||
"int": "dezent"
|
||||
}
|
||||
],
|
||||
"current": 2,
|
||||
"current": 1,
|
||||
"deck": [
|
||||
{
|
||||
"ref": "titel",
|
||||
@@ -82,8 +82,8 @@
|
||||
"dy": 3
|
||||
},
|
||||
"vis": {
|
||||
"dx": 0,
|
||||
"dy": 16
|
||||
"dx": 3,
|
||||
"dy": 13
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -96,7 +96,7 @@
|
||||
},
|
||||
"vis": {
|
||||
"dx": 0,
|
||||
"dy": -109
|
||||
"dy": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -109,8 +109,8 @@
|
||||
"dy": 3
|
||||
},
|
||||
"vis": {
|
||||
"dx": -17,
|
||||
"dy": 3
|
||||
"dx": -46,
|
||||
"dy": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -120,7 +120,10 @@
|
||||
"headline": {
|
||||
"dy": 3
|
||||
},
|
||||
"vis": {}
|
||||
"vis": {
|
||||
"dx": 0,
|
||||
"dy": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"body": {
|
||||
@@ -135,9 +138,9 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"frameStyle": "rund",
|
||||
"frameStyle": "aus",
|
||||
"layoutState": [
|
||||
"ecke",
|
||||
"standard",
|
||||
"standard",
|
||||
"standard",
|
||||
"standard",
|
||||
|
||||
Reference in new issue
Block a user