Compare commits
2
Commits
b0ec520a72
...
bd06f77a60
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd06f77a60 | ||
|
|
276cced03c |
No files matched your search
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1074.12 930.23">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #f1b729;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="Ebene_2" data-name="Ebene 2">
|
||||
<polygon class="cls-1" points="1074.12 465.12 939.87 232.54 537.06 465.12 805.59 465.12 671.34 697.66 402.78 697.66 268.53 465.12 402.78 232.54 939.87 232.54 832.69 46.91 805.59 0 268.53 0 0 465.12 268.53 930.23 805.59 930.23 1074.12 465.12"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 532 B |
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
+56
-56
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>HiveGrid Post 1 (Lösung, Carousel)</title>
|
||||
<title>PostGrid Post 1 · Lösung</title>
|
||||
<link rel="stylesheet" href="./assets/fonts/manrope.css">
|
||||
<style>
|
||||
/* ─── HiveGrid design tokens (mirrored from app/globals.css) ─────────────
|
||||
@@ -249,7 +249,10 @@
|
||||
Klar abgesetzt von der Sidebar: eigener Grund, eigener Scroll, eigener
|
||||
Zoom. Was hier passiert, lässt die Bedienleiste unberührt. */
|
||||
.stage {
|
||||
flex: 1; position: relative; height: 100vh; overflow: hidden;
|
||||
/* Nicht 100vh: darueber sitzt die Menueleiste. Mit voller
|
||||
Fensterhoehe rutscht die Fussleiste samt Zoom und Merkzettel
|
||||
unter den unteren Rand. */
|
||||
flex: 1; position: relative; height: 100%; overflow: hidden;
|
||||
background-color: #101116;
|
||||
background-image: radial-gradient(circle, #282B35 1.6px, transparent 1.6px);
|
||||
background-size: 24px 24px;
|
||||
@@ -755,7 +758,7 @@
|
||||
<body>
|
||||
|
||||
<div class="menubar" id="menubar">
|
||||
<span class="marke">HiveGrid</span>
|
||||
<span class="marke">PostGrid</span>
|
||||
|
||||
<div class="menu" data-menu="projekt">
|
||||
<button type="button">Projekt</button>
|
||||
@@ -786,9 +789,6 @@
|
||||
<button type="button" data-tun="undo">Rückgängig<span class="kurz">⌘Z</span></button>
|
||||
<button type="button" data-tun="redo">Wiederherstellen<span class="kurz">⇧⌘Z</span></button>
|
||||
<hr>
|
||||
<button type="button" data-opt="editmodes:e:an">Bearbeiten an<span class="kurz">E</span></button>
|
||||
<button type="button" data-opt="editmodes:e:aus">Bearbeiten aus</button>
|
||||
<hr>
|
||||
<button type="button" data-klick="reset-one">Element auf Standard</button>
|
||||
<button type="button" data-klick="reset-all">Alles auf Standard</button>
|
||||
</div>
|
||||
@@ -809,6 +809,8 @@
|
||||
<div class="menu" data-menu="ansicht">
|
||||
<button type="button">Ansicht</button>
|
||||
<div class="liste">
|
||||
<button type="button" data-tun="vorschau">Vorschau<span class="kurz">P</span></button>
|
||||
<hr>
|
||||
<button type="button" data-opt="views:w:streifen">Streifen<span class="kurz">W</span></button>
|
||||
<button type="button" data-opt="views:w:einzeln">Einzeln</button>
|
||||
<hr>
|
||||
@@ -860,29 +862,31 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="layout-nur-diese-slide">
|
||||
<summary>Layout (nur diese Slide)</summary>
|
||||
<!-- Nicht mehr in der Seitenleiste: Layout und Perspektive sind
|
||||
post-spezifisch, Vorschau steht oben unter Ansicht, der Tag ist
|
||||
ausgeblendet. Die Schalter bleiben trotzdem im Dokument, weil die
|
||||
Menueleiste, die Tastenkuerzel und die Abgleich-Funktionen sie
|
||||
betaetigen. Sonst gaebe es zwei Wahrheiten ueber denselben Zustand. -->
|
||||
<div hidden>
|
||||
<div class="opts" id="layouts"></div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="tag-optisch-ausger-ckt">
|
||||
<summary>Tag optisch ausgerückt</summary>
|
||||
<div class="opts" id="tagouts">
|
||||
<button data-o="an" aria-pressed="true">An</button>
|
||||
<button data-o="aus" aria-pressed="false">Aus</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="bearbeiten">
|
||||
<summary>Bearbeiten</summary>
|
||||
<div class="opts" id="editmodes">
|
||||
<button data-e="an" aria-pressed="false">An</button>
|
||||
<button data-e="aus" aria-pressed="true">Aus</button>
|
||||
<div class="opts" id="vorschau">
|
||||
<button data-p="aus" aria-pressed="true">Aus</button>
|
||||
<button data-p="an" aria-pressed="false">An</button>
|
||||
</div>
|
||||
<div class="hint" style="margin-top:8px">Ein angeklicktes Element öffnet
|
||||
sein eigenes Feld rechts.</div>
|
||||
<button class="btn secondary" id="reset-all" style="width:100%;margin-top:8px">Alles auf Standard</button>
|
||||
</details>
|
||||
<div class="opts" id="ints">
|
||||
<button data-i="dezent" aria-pressed="true">Dezent</button>
|
||||
<button data-i="kraeftig" aria-pressed="false">Kräftig</button>
|
||||
</div>
|
||||
<div class="opts" id="tilts">
|
||||
<button data-t="an" aria-pressed="true">Gekippt</button>
|
||||
<button data-t="aus" aria-pressed="false">Gerade</button>
|
||||
</div>
|
||||
<button id="reset-all">Alles auf Standard</button>
|
||||
</div>
|
||||
|
||||
<details class="std">
|
||||
<summary>Standardwerte</summary>
|
||||
@@ -897,14 +901,6 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="intensit-t">
|
||||
<summary>Intensität</summary>
|
||||
<div class="opts" id="ints">
|
||||
<button data-i="dezent" aria-pressed="true">Dezent</button>
|
||||
<button data-i="kraeftig" aria-pressed="false">Kräftig</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="bildrahmen">
|
||||
<summary>Bildrahmen</summary>
|
||||
<div class="opts three" id="frames">
|
||||
@@ -915,14 +911,6 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="mockup-perspektive">
|
||||
<summary>Mockup-Perspektive</summary>
|
||||
<div class="opts" id="tilts">
|
||||
<button data-t="an" aria-pressed="true">Gekippt</button>
|
||||
<button data-t="aus" aria-pressed="false">Gerade</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="renderqualit-t">
|
||||
<summary>Renderqualität</summary>
|
||||
<div class="opts three" id="quality">
|
||||
@@ -932,12 +920,13 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<div class="group">
|
||||
<label>Download</label>
|
||||
<div class="row" style="margin-bottom:8px">
|
||||
<button id="dl-png" disabled>Diese Slide</button>
|
||||
</div>
|
||||
<button id="dl-all" class="btn secondary" style="width:100%" disabled>Alle 5 Slides als ZIP</button>
|
||||
<!-- Der Export steht oben unter Datei. Die Knoepfe bleiben trotzdem im
|
||||
Dokument: die Menueleiste betaetigt sie, und sie tragen den Zustand
|
||||
"noch nicht bereit", solange die Schrift nicht geladen ist. Ohne sie
|
||||
muesste beides doppelt gefuehrt werden. -->
|
||||
<div hidden>
|
||||
<button id="dl-png" disabled>Diese Slide</button>
|
||||
<button id="dl-all" disabled>Alle Slides als ZIP</button>
|
||||
</div>
|
||||
|
||||
<details class="group" style="margin-bottom:0" data-grp="tastatur">
|
||||
@@ -945,10 +934,10 @@
|
||||
<div class="keys">
|
||||
<kbd>←</kbd><kbd>→</kbd> Slide · <kbd>V</kbd> Variante<br>
|
||||
<kbd>L</kbd> Layout · <kbd>I</kbd> Intensität<br>
|
||||
<kbd>W</kbd> Ansicht · <kbd>G</kbd> Tag<br>
|
||||
<kbd>W</kbd> Ansicht<br>
|
||||
<kbd>R</kbd> Bildrahmen<br>
|
||||
<kbd>T</kbd> Perspektive<br>
|
||||
<kbd>E</kbd> Bearbeiten · Pfeile verschieben (<kbd>⇧</kbd> = 10 px)<br>
|
||||
<kbd>P</kbd> Vorschau · Pfeile verschieben (<kbd>⇧</kbd> = 10 px)<br>
|
||||
<kbd>+</kbd> <kbd>−</kbd> <kbd>0</kbd> Zoom · ⌘/Strg + Rad<br>
|
||||
<kbd>Leer</kbd> + ziehen verschiebt die Fläche<br>
|
||||
<kbd>⌘/Strg</kbd>+<kbd>Z</kbd> Rückgängig (<kbd>⇧</kbd> = wiederherstellen)<br>
|
||||
@@ -1222,7 +1211,8 @@
|
||||
let edits = SLIDES.map(() => ({}));
|
||||
|
||||
let picked = null; // { slide, key }
|
||||
let editMode = "aus";
|
||||
// Bearbeiten ist immer an. "aus" heisst Vorschau: alles festgelegt.
|
||||
let editMode = "an";
|
||||
|
||||
let current = 0;
|
||||
let variant = "dunkel", tilt = "an", superSample = 2, view = "streifen", tagOut = "an", frameStyle = "chamfer";
|
||||
@@ -3115,18 +3105,24 @@
|
||||
})();
|
||||
|
||||
document.getElementById("forget").addEventListener("click", forgetProject);
|
||||
document.getElementById("editmodes").addEventListener("click", e => {
|
||||
document.getElementById("vorschau").addEventListener("click", e => {
|
||||
const b = e.target.closest("button");
|
||||
if (!b) return;
|
||||
editMode = b.dataset.e;
|
||||
press("editmodes", "e", editMode);
|
||||
setVorschau(b.dataset.p === "an");
|
||||
});
|
||||
|
||||
/* In der Vorschau ist alles festgelegt: keine Auswahl, kein Ziehen, keine
|
||||
Rahmen. Blaettern und Zoomen bleiben, das ist der Sinn der Sache. */
|
||||
function setVorschau(an) {
|
||||
editMode = an ? "aus" : "an";
|
||||
press("vorschau", "p", an ? "an" : "aus");
|
||||
deck.querySelectorAll(".slide").forEach(el => { el.dataset.editmode = editMode; });
|
||||
if (editMode === "aus") {
|
||||
if (an) {
|
||||
picked = null;
|
||||
deck.querySelectorAll("[data-edit]").forEach(n => n.classList.remove("picked"));
|
||||
syncEditPanel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ─── Angleichen über alle Slides ────────────────────────────────────────
|
||||
Das gewählte Element ist die Vorlage, alle gleichnamigen auf den anderen
|
||||
@@ -3286,7 +3282,7 @@
|
||||
const menues = [...bar.querySelectorAll(".menu")];
|
||||
const zu = () => menues.forEach(m => delete m.dataset.offen);
|
||||
|
||||
const AKTION = { undo, redo };
|
||||
const AKTION = { undo, redo, vorschau: () => setVorschau(editMode === "an") };
|
||||
|
||||
// Haken und graue Eintraege erst beim Oeffnen setzen: vorher weiss die
|
||||
// Leiste nicht, was gerade gilt.
|
||||
@@ -3299,6 +3295,11 @@
|
||||
b.insertAdjacentHTML("afterbegin",
|
||||
'<span class="haken">' + (an ? "✓" : "") + "</span>");
|
||||
});
|
||||
m.querySelectorAll('button[data-tun="vorschau"]').forEach(b => {
|
||||
b.querySelector(".haken")?.remove();
|
||||
b.insertAdjacentHTML("afterbegin",
|
||||
'<span class="haken">' + (editMode === "aus" ? "✓" : "") + "</span>");
|
||||
});
|
||||
m.querySelectorAll("button[data-klick]").forEach(b => {
|
||||
const q = document.getElementById(b.dataset.klick);
|
||||
b.disabled = !q || q.disabled;
|
||||
@@ -3545,13 +3546,12 @@
|
||||
else if (e.key === "-") { setZoom((zoom || autoFit()) / 1.25); }
|
||||
else if (e.key === "0") { zoom = null; fitStrip(); }
|
||||
else if (k === "w") { view = view === "streifen" ? "einzeln" : "streifen"; deck.dataset.view = view; press("views", "w", view); zoom = null; show(current); }
|
||||
else if (k === "e") { document.querySelector('#editmodes button[data-e="' + (editMode === "an" ? "aus" : "an") + '"]').click(); }
|
||||
else if (k === "p") { setVorschau(editMode === "an"); }
|
||||
else if (k === "r") {
|
||||
const cyc = ["chamfer", "rund", "stapel", "aus"];
|
||||
frameStyle = cyc[(cyc.indexOf(frameStyle) + 1) % cyc.length];
|
||||
press("frames", "f", frameStyle); applyAll(); saveState();
|
||||
}
|
||||
else if (k === "g") { tagOut = tagOut === "an" ? "aus" : "an"; press("tagouts", "o", tagOut); applyAll(); saveState(); }
|
||||
else if (k === "d") guard(downloadOne)();
|
||||
else if (k === "a") guard(downloadAll)();
|
||||
});
|
||||
|
||||
+348
-119
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>HiveGrid Post 2 (Carousel)</title>
|
||||
<title>PostGrid Post 2</title>
|
||||
<link rel="stylesheet" href="./assets/fonts/manrope.css">
|
||||
<style>
|
||||
/* ─── HiveGrid design tokens (mirrored from app/globals.css) ─────────────
|
||||
@@ -249,7 +249,10 @@
|
||||
Klar abgesetzt von der Sidebar: eigener Grund, eigener Scroll, eigener
|
||||
Zoom. Was hier passiert, lässt die Bedienleiste unberührt. */
|
||||
.stage {
|
||||
flex: 1; position: relative; height: 100vh; overflow: hidden;
|
||||
/* Nicht 100vh: darueber sitzt die Menueleiste. Mit voller
|
||||
Fensterhoehe rutscht die Fussleiste samt Zoom und Merkzettel
|
||||
unter den unteren Rand. */
|
||||
flex: 1; position: relative; height: 100%; overflow: hidden;
|
||||
background-color: #101116;
|
||||
background-image: radial-gradient(circle, #282B35 1.6px, transparent 1.6px);
|
||||
background-size: 24px 24px;
|
||||
@@ -353,6 +356,166 @@
|
||||
opacity: calc(var(--pat-strength) * var(--int-mul, 1));
|
||||
}
|
||||
|
||||
|
||||
/* ─── Visualisierungen ───────────────────────────────────────────────────
|
||||
Post 2 zeigt keine Screenshots, sondern das Stichwort aus dem Text als
|
||||
Bild. Gebaut aus derselben Formensprache wie die Slides: chamferte
|
||||
Kaesten, Sechsecke, der eine gelbe Akzent. Alles HTML, damit es beim
|
||||
3-fachen Export genauso scharf bleibt wie die Schrift und sich im Canvas
|
||||
verschieben laesst wie jedes andere Element. */
|
||||
.vis {
|
||||
position: absolute; z-index: 1;
|
||||
left: var(--vis-left, 92px);
|
||||
bottom: var(--vis-bottom, 96px);
|
||||
width: var(--vis-w, 900px);
|
||||
color: var(--head-color);
|
||||
}
|
||||
.vis-kasten {
|
||||
position: relative; padding: 22px 26px;
|
||||
background: var(--frame-bg);
|
||||
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
|
||||
);
|
||||
}
|
||||
.vis-titel { font-size: 27px; font-weight: 700; letter-spacing: -0.01em; }
|
||||
.vis-zeile { margin-top: 6px; font-size: 21px; font-weight: 500; color: var(--body-color); }
|
||||
.vis-marke { background: var(--accent-yellow); color: #3E2C0A; }
|
||||
.vis-marke .vis-zeile { color: #6B4E12; }
|
||||
|
||||
/* Verbindungen: 6 px starke Balken in der Rahmenfarbe. Durchgezogen heisst
|
||||
verbunden, gestrichelt heisst offen. */
|
||||
.vis-linie { position: absolute; height: 6px; background: var(--shape-line); }
|
||||
.vis-linie.senk { width: 6px; height: auto; }
|
||||
.vis-offen { border-top: 6px dashed var(--shape-line); background: none; height: 0; }
|
||||
|
||||
/* Slide 2: drei Schritte fest auf einer Schiene. Sie sitzen nicht dort,
|
||||
weil es sinnvoll waere, sondern weil die Schiene es vorgibt. */
|
||||
.vis-schiene { display: flex; align-items: stretch; gap: 0; }
|
||||
.vis-schiene .vis-kasten { flex: 1; }
|
||||
.vis-schiene .verbund { flex: none; width: 54px; align-self: center; height: 6px; background: var(--shape-line); }
|
||||
.vis-riegel {
|
||||
margin-top: 26px; height: 14px; background: var(--shape-fill); opacity: .28;
|
||||
clip-path: polygon(7px 0, calc(100% - 7px) 0, 100% 7px, 100% 100%, 0 100%, 0 7px);
|
||||
}
|
||||
|
||||
/* Slide 3: der Bestand ist schwer, der Wechsel daneben leer. Das Kreuz
|
||||
liegt auf dem Pfeil, nicht auf dem Ziel. */
|
||||
.vis-ersetzen { display: flex; align-items: center; gap: 34px; }
|
||||
.vis-ersetzen .schwer { flex: 1.35; }
|
||||
.vis-ersetzen .leer {
|
||||
flex: 1; padding: 22px 26px; min-height: 168px;
|
||||
border: 6px dashed var(--shape-line);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: var(--body-color); font-size: 21px; font-weight: 600;
|
||||
}
|
||||
.vis-ersetzen .pfeil { flex: none; position: relative; width: 96px; height: 6px; background: var(--shape-line); }
|
||||
.vis-ersetzen .pfeil::after {
|
||||
content: ""; position: absolute; right: -2px; top: -11px;
|
||||
border: 14px solid transparent; border-left-color: var(--shape-line);
|
||||
}
|
||||
.vis-kreuz {
|
||||
position: absolute; left: 50%; top: 50%; width: 74px; height: 74px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.vis-kreuz i {
|
||||
position: absolute; left: 0; top: 34px; width: 100%; height: 8px;
|
||||
background: var(--accent-yellow);
|
||||
}
|
||||
.vis-kreuz i:first-child { transform: rotate(45deg); }
|
||||
.vis-kreuz i:last-child { transform: rotate(-45deg); }
|
||||
.vis-stapel { display: grid; gap: 10px; }
|
||||
|
||||
/* Slide 4: vier Kacheln, die nichts voneinander wissen. Die gestrichelten
|
||||
Stummel laufen ins Leere. */
|
||||
.vis-lose { display: grid; grid-template-columns: repeat(2, 1fr); gap: 30px 74px; }
|
||||
.vis-lose .feld { position: relative; }
|
||||
.vis-lose .stummel {
|
||||
position: absolute; top: 50%; width: 54px; height: 0;
|
||||
border-top: 6px dashed var(--shape-line);
|
||||
}
|
||||
.vis-lose .feld:nth-child(odd) .stummel { right: -60px; }
|
||||
.vis-lose .feld:nth-child(even) .stummel { left: -60px; }
|
||||
|
||||
/* Slide 5: das ERP bleibt in der Mitte, HiveGrid liegt als Sechseck
|
||||
drumherum und haelt die drei Neuen daran. */
|
||||
.vis-verbinden { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 0; }
|
||||
.vis-verbinden .saeule { display: grid; gap: 20px; }
|
||||
.vis-verbinden .mitte { position: relative; width: 300px; padding: 0 26px; }
|
||||
.vis-nabe {
|
||||
position: relative; width: 248px; height: 215px; margin: 0 auto;
|
||||
background: var(--shape-fill);
|
||||
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
color: var(--text-white);
|
||||
}
|
||||
.slide[data-variant="hell"] .vis-nabe { color: #fff; }
|
||||
.vis-nabe b { font-size: 25px; font-weight: 800; letter-spacing: -0.01em; }
|
||||
.vis-nabe small { margin-top: 4px; font-size: 17px; font-weight: 600; opacity: .72; }
|
||||
.vis-verbinden .quer { position: absolute; top: 50%; width: 26px; height: 6px; background: var(--shape-line); }
|
||||
.vis-verbinden .quer.li { left: 0; }
|
||||
.vis-verbinden .quer.re { right: 0; }
|
||||
|
||||
/* Slide 6: der Abschluss ist ein Feld, kein Bild. */
|
||||
.vis-warteliste { text-align: center; }
|
||||
.vis-warteliste .feldzeile {
|
||||
display: flex; align-items: stretch; gap: 14px; margin-top: 22px;
|
||||
}
|
||||
.vis-warteliste .eingabe {
|
||||
flex: 1; padding: 20px 24px; text-align: left;
|
||||
font-size: 22px; font-weight: 500; color: var(--body-color);
|
||||
border: 3px solid var(--shape-line);
|
||||
clip-path: polygon(
|
||||
14px 0, calc(100% - 14px) 0, 100% 14px, 100% calc(100% - 14px),
|
||||
calc(100% - 14px) 100%, 14px 100%, 0 calc(100% - 14px), 0 14px
|
||||
);
|
||||
}
|
||||
.vis-warteliste .knopf {
|
||||
flex: none; padding: 20px 32px; font-size: 22px; font-weight: 800;
|
||||
background: var(--accent-yellow); color: #3E2C0A;
|
||||
clip-path: polygon(
|
||||
14px 0, calc(100% - 14px) 0, 100% 14px, 100% calc(100% - 14px),
|
||||
calc(100% - 14px) 100%, 14px 100%, 0 calc(100% - 14px), 0 14px
|
||||
);
|
||||
}
|
||||
.vis-warteliste .adresse {
|
||||
margin-top: 18px; font-size: 21px; font-weight: 700; letter-spacing: .02em;
|
||||
color: var(--body-color);
|
||||
}
|
||||
|
||||
/* ─── Teamkarte ──────────────────────────────────────────────────────────
|
||||
Nachbau der Karte von der Ueber-uns-Seite im aktiven Zustand: Hintergrund
|
||||
entsaettigt und abgedunkelt, die Person in voller Farbe, das gelbe
|
||||
Namensschild sichtbar. Werte aus TeamCards.tsx uebernommen.
|
||||
Ohne die weichgezeichnete Ellipse aus dem Original: die haengt an
|
||||
backdrop-filter, und was der Export daraus macht, ist nicht verlaesslich. */
|
||||
.karte {
|
||||
position: relative; aspect-ratio: 4/5; overflow: hidden;
|
||||
border-radius: 38px; background: #0f1a2e; isolation: isolate;
|
||||
}
|
||||
.karte-grund {
|
||||
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;
|
||||
background: linear-gradient(180deg, rgba(15,26,46,.01), rgba(15,26,46,.12));
|
||||
}
|
||||
.karte-person {
|
||||
position: absolute; inset: 0; z-index: 4;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
filter: saturate(1) contrast(1.01);
|
||||
}
|
||||
.karte-name {
|
||||
position: absolute; left: 6%; bottom: 5.7%; z-index: 5;
|
||||
display: flex; align-items: baseline; gap: 13px;
|
||||
padding: 13px 17px; background: var(--accent-yellow); color: #101010;
|
||||
}
|
||||
.karte-name span { font-size: 27px; font-weight: 700; letter-spacing: -.03em; line-height: 1.15; }
|
||||
.karte-name small { font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
|
||||
|
||||
/* ─── Bearbeitung im Canvas ───────────────────────────────────────────────
|
||||
Verschieben läuft über --ex/--ey, also über transform statt über den
|
||||
Textfluss: So verschiebt ein Element nie seine Nachbarn und lässt sich
|
||||
@@ -755,7 +918,7 @@
|
||||
<body>
|
||||
|
||||
<div class="menubar" id="menubar">
|
||||
<span class="marke">HiveGrid</span>
|
||||
<span class="marke">PostGrid</span>
|
||||
|
||||
<div class="menu" data-menu="projekt">
|
||||
<button type="button">Projekt</button>
|
||||
@@ -786,9 +949,6 @@
|
||||
<button type="button" data-tun="undo">Rückgängig<span class="kurz">⌘Z</span></button>
|
||||
<button type="button" data-tun="redo">Wiederherstellen<span class="kurz">⇧⌘Z</span></button>
|
||||
<hr>
|
||||
<button type="button" data-opt="editmodes:e:an">Bearbeiten an<span class="kurz">E</span></button>
|
||||
<button type="button" data-opt="editmodes:e:aus">Bearbeiten aus</button>
|
||||
<hr>
|
||||
<button type="button" data-klick="reset-one">Element auf Standard</button>
|
||||
<button type="button" data-klick="reset-all">Alles auf Standard</button>
|
||||
</div>
|
||||
@@ -809,6 +969,8 @@
|
||||
<div class="menu" data-menu="ansicht">
|
||||
<button type="button">Ansicht</button>
|
||||
<div class="liste">
|
||||
<button type="button" data-tun="vorschau">Vorschau<span class="kurz">P</span></button>
|
||||
<hr>
|
||||
<button type="button" data-opt="views:w:streifen">Streifen<span class="kurz">W</span></button>
|
||||
<button type="button" data-opt="views:w:einzeln">Einzeln</button>
|
||||
<hr>
|
||||
@@ -860,29 +1022,31 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="layout-nur-diese-slide">
|
||||
<summary>Layout (nur diese Slide)</summary>
|
||||
<!-- Nicht mehr in der Seitenleiste: Layout und Perspektive sind
|
||||
post-spezifisch, Vorschau steht oben unter Ansicht, der Tag ist
|
||||
ausgeblendet. Die Schalter bleiben trotzdem im Dokument, weil die
|
||||
Menueleiste, die Tastenkuerzel und die Abgleich-Funktionen sie
|
||||
betaetigen. Sonst gaebe es zwei Wahrheiten ueber denselben Zustand. -->
|
||||
<div hidden>
|
||||
<div class="opts" id="layouts"></div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="tag-optisch-ausger-ckt">
|
||||
<summary>Tag optisch ausgerückt</summary>
|
||||
<div class="opts" id="tagouts">
|
||||
<button data-o="an" aria-pressed="true">An</button>
|
||||
<button data-o="aus" aria-pressed="false">Aus</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="bearbeiten">
|
||||
<summary>Bearbeiten</summary>
|
||||
<div class="opts" id="editmodes">
|
||||
<button data-e="an" aria-pressed="false">An</button>
|
||||
<button data-e="aus" aria-pressed="true">Aus</button>
|
||||
<div class="opts" id="vorschau">
|
||||
<button data-p="aus" aria-pressed="true">Aus</button>
|
||||
<button data-p="an" aria-pressed="false">An</button>
|
||||
</div>
|
||||
<div class="hint" style="margin-top:8px">Ein angeklicktes Element öffnet
|
||||
sein eigenes Feld rechts.</div>
|
||||
<button class="btn secondary" id="reset-all" style="width:100%;margin-top:8px">Alles auf Standard</button>
|
||||
</details>
|
||||
<div class="opts" id="ints">
|
||||
<button data-i="dezent" aria-pressed="true">Dezent</button>
|
||||
<button data-i="kraeftig" aria-pressed="false">Kräftig</button>
|
||||
</div>
|
||||
<div class="opts" id="tilts">
|
||||
<button data-t="an" aria-pressed="true">Gekippt</button>
|
||||
<button data-t="aus" aria-pressed="false">Gerade</button>
|
||||
</div>
|
||||
<button id="reset-all">Alles auf Standard</button>
|
||||
</div>
|
||||
|
||||
<details class="std">
|
||||
<summary>Standardwerte</summary>
|
||||
@@ -897,14 +1061,6 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="intensit-t">
|
||||
<summary>Intensität</summary>
|
||||
<div class="opts" id="ints">
|
||||
<button data-i="dezent" aria-pressed="true">Dezent</button>
|
||||
<button data-i="kraeftig" aria-pressed="false">Kräftig</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="bildrahmen">
|
||||
<summary>Bildrahmen</summary>
|
||||
<div class="opts three" id="frames">
|
||||
@@ -915,14 +1071,6 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="mockup-perspektive">
|
||||
<summary>Mockup-Perspektive</summary>
|
||||
<div class="opts" id="tilts">
|
||||
<button data-t="an" aria-pressed="true">Gekippt</button>
|
||||
<button data-t="aus" aria-pressed="false">Gerade</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="group" data-grp="renderqualit-t">
|
||||
<summary>Renderqualität</summary>
|
||||
<div class="opts three" id="quality">
|
||||
@@ -932,12 +1080,13 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<div class="group">
|
||||
<label>Download</label>
|
||||
<div class="row" style="margin-bottom:8px">
|
||||
<button id="dl-png" disabled>Diese Slide</button>
|
||||
</div>
|
||||
<button id="dl-all" class="btn secondary" style="width:100%" disabled>Alle 5 Slides als ZIP</button>
|
||||
<!-- Der Export steht oben unter Datei. Die Knoepfe bleiben trotzdem im
|
||||
Dokument: die Menueleiste betaetigt sie, und sie tragen den Zustand
|
||||
"noch nicht bereit", solange die Schrift nicht geladen ist. Ohne sie
|
||||
muesste beides doppelt gefuehrt werden. -->
|
||||
<div hidden>
|
||||
<button id="dl-png" disabled>Diese Slide</button>
|
||||
<button id="dl-all" disabled>Alle Slides als ZIP</button>
|
||||
</div>
|
||||
|
||||
<details class="group" style="margin-bottom:0" data-grp="tastatur">
|
||||
@@ -945,10 +1094,10 @@
|
||||
<div class="keys">
|
||||
<kbd>←</kbd><kbd>→</kbd> Slide · <kbd>V</kbd> Variante<br>
|
||||
<kbd>L</kbd> Layout · <kbd>I</kbd> Intensität<br>
|
||||
<kbd>W</kbd> Ansicht · <kbd>G</kbd> Tag<br>
|
||||
<kbd>W</kbd> Ansicht<br>
|
||||
<kbd>R</kbd> Bildrahmen<br>
|
||||
<kbd>T</kbd> Perspektive<br>
|
||||
<kbd>E</kbd> Bearbeiten · Pfeile verschieben (<kbd>⇧</kbd> = 10 px)<br>
|
||||
<kbd>P</kbd> Vorschau · Pfeile verschieben (<kbd>⇧</kbd> = 10 px)<br>
|
||||
<kbd>+</kbd> <kbd>−</kbd> <kbd>0</kbd> Zoom · ⌘/Strg + Rad<br>
|
||||
<kbd>Leer</kbd> + ziehen verschiebt die Fläche<br>
|
||||
<kbd>⌘/Strg</kbd>+<kbd>Z</kbd> Rückgängig (<kbd>⇧</kbd> = wiederherstellen)<br>
|
||||
@@ -1017,82 +1166,70 @@
|
||||
Website say exactly the same thing; the headlines are new and short,
|
||||
because a full sentence does not work as a carousel hook.
|
||||
img-scale/x/y frame each capture on its telling region. */
|
||||
/* ─── Die Geschichte ──────────────────────────────────────────────────────
|
||||
Post 2 erzaehlt die Herkunft, nicht die Funktionen. Statt Screenshots
|
||||
traegt jede Slide eine gebaute Visualisierung: der Text nennt ein
|
||||
Stichwort, das Bild zeigt es. Alle sind aus derselben Formensprache wie
|
||||
die Slides selbst gebaut, also chamferte Kaesten, Sechsecke und der eine
|
||||
gelbe Akzent. Kein Bildmaterial ausser Noahs Karte. */
|
||||
/* ─── Die Geschichte ──────────────────────────────────────────────────────
|
||||
Post 2 erzaehlt die Herkunft, nicht die Funktionen. Statt Screenshots
|
||||
traegt jede Slide eine gebaute Visualisierung: der Text nennt ein
|
||||
Stichwort, das Bild zeigt es.
|
||||
|
||||
Die Texte sind NICHT die von der Website. Dort stehen ganze Absaetze, hier
|
||||
muss eine Zeile im Vorbeiscrollen sitzen. Der volle Text kommt unter den
|
||||
Beitrag, die Slide traegt nur die Zuspitzung. Faustregel aus den
|
||||
gemessenen Breiten: bei 74 px und -0,03em passen rund 26 Zeichen in eine
|
||||
Zeile, mit Marker etwas weniger. Keine Zeile hier ist laenger als 22. */
|
||||
const VORLAGEN = [
|
||||
{
|
||||
key: "titel", type: "title",
|
||||
layouts: [{ id: "klassisch", label: "Klassisch" }, { id: "wabe", label: "Wabe" }, { id: "laptop", label: "Laptop" }, { id: "laptop-logo", label: "Laptop · Logo" }, { id: "laptop-blur", label: "Laptop · Blur" }, { id: "laptop-footer", label: "Laptop · Logo unten" }, { id: "szene", label: "Laptop · Board" }],
|
||||
head: 'Vom <span class="a">Handwerker</span><br>f\u00fcr Handwerker',
|
||||
sub: "Die Software, die deine Branchenprogramme nicht ersetzt, sondern verbindet.",
|
||||
key: "titel", type: "feature",
|
||||
layouts: [{ id: "standard", label: "Standard" }],
|
||||
eyebrow: "Titel",
|
||||
head: 'Die Geschichte fängt<br><span class="a">auf der Baustelle an.</span>',
|
||||
body: "Noah Geerkens, SHK-Betrieb in vierter Generation.",
|
||||
vis: "karte", visW: 520, visLeft: 280, visBottom: 130,
|
||||
},
|
||||
{
|
||||
key: "workflow-engine", type: "feature",
|
||||
key: "prozesse", type: "feature",
|
||||
layouts: [{ id: "standard", label: "Standard" }],
|
||||
eyebrow: "Automation & KI",
|
||||
head: '<span class="a">Wenn-dann</span><br>statt Handarbeit.',
|
||||
body: "Auslöser wählen, Aktionen dranhängen, fertig. Alles automatisch und ohne eine Zeile Code.",
|
||||
img: "./assets/screens/workflow.png",
|
||||
mockW: 940, mockAR: 2.366,
|
||||
imgScale: 1, imgX: "0%", imgY: "0%",
|
||||
// Die Bausteinliste ragt über den Ablauf hinaus: sie zeigt, woraus er entsteht.
|
||||
media2: {
|
||||
img: "./assets/screens/workflow-bausteine.png",
|
||||
w: 340, ar: 0.8326, left: 700, bottom: 96, z: 2, rot: 0,
|
||||
},
|
||||
// Der Zettel liegt bewusst schief und leicht über der linken Blattkante:
|
||||
// er gehört zum Ablauf, ist aber sichtbar von Hand dazugelegt.
|
||||
note: {
|
||||
text: "Eigene Notizen direkt am Ablauf hinterlegen.",
|
||||
w: 320, left: 44, bottom: 150, z: 3, rot: -3,
|
||||
},
|
||||
eyebrow: "Prozesse",
|
||||
head: 'Nicht sinnvoll.<br><span class="a">Nur so gewachsen.</span>',
|
||||
body: "Die Software gibt den Takt vor. Nicht der Betrieb.",
|
||||
vis: "schiene", visW: 900, visLeft: 92, visBottom: 210,
|
||||
},
|
||||
{
|
||||
key: "projektmanagement", type: "feature",
|
||||
key: "wechseln", type: "feature",
|
||||
layouts: [{ id: "standard", label: "Standard" }],
|
||||
eyebrow: "Vertrieb",
|
||||
head: 'Du siehst auf einen Blick,<br><span class="a">wo alle Auftr\u00e4ge stehen.</span>',
|
||||
body: "Projekte, Kunden, Angebote, F\u00f6rderantr\u00e4ge. Kein Suchen, kein Nachfragen, kein Zettelchaos.",
|
||||
img: "./assets/screens/pipelines.png",
|
||||
// Nur die linke Bildhälfte: Zoom 2 bei Versatz 0 zeigt exakt den Anteil
|
||||
// 0 bis 0,5. Das Rahmenverhältnis ist die halbierte Bildbreite.
|
||||
mockW: 580, mockAR: 0.8855,
|
||||
imgScale: 2, imgX: "0%", imgY: "0%",
|
||||
// Detailspalte eines Projekts vor dem Board: zeigt, was hinter einer
|
||||
// Karte steckt, ohne das Board zu verdecken.
|
||||
media2: {
|
||||
img: "./assets/screens/pipelines-detail.png",
|
||||
w: 300, ar: 0.781, left: 500, bottom: 52, z: 2, rot: -2,
|
||||
},
|
||||
eyebrow: "Wechseln",
|
||||
head: 'Wechseln?<br><span class="a">Kannst du vergessen.</span>',
|
||||
body: "Jahre an Daten und Wissen hängen drin. Am Ende dasselbe, nur woanders.",
|
||||
vis: "ersetzen", visW: 900, visLeft: 92, visBottom: 190,
|
||||
},
|
||||
{
|
||||
key: "chat", type: "feature",
|
||||
key: "mehr", type: "feature",
|
||||
layouts: [{ id: "standard", label: "Standard" }],
|
||||
eyebrow: "Chat",
|
||||
// Zweizeilig, aber knapp: Zeile 2 misst mit Marker 880 px bei 896
|
||||
// verfuegbaren. Ein laengeres Wort bricht sofort um.
|
||||
head: 'Projekte bekommen<br>automatisch <span class="a">ihren Kanal.</span>',
|
||||
body: "Foto von der Baustelle rein, alle sehen's sofort. Aus jeder Nachricht wird mit einem Klick eine Aufgabe.",
|
||||
img: "./assets/screens/chat.png",
|
||||
mockW: 1030, mockAR: 1.703,
|
||||
imgScale: 1, imgX: "0%", imgY: "0%",
|
||||
// Das hinterste Blatt zeigt sonst den Form Builder bei 3,8-fachem Zoom:
|
||||
// unscharf, und die Kopieren- und Papierkorb-Symbole gehören zu einem
|
||||
// anderen Feature. Stattdessen der Chat im Hochformat, ungezoomt.
|
||||
back: { img: "./assets/screens/chat-tablet.png", imgScale: 1, imgX: "0%", imgY: "0%" },
|
||||
// Das Anhang-Menü zeigt, was aus einer Nachricht alles werden kann.
|
||||
media2: {
|
||||
img: "./assets/screens/chat-menue.png",
|
||||
w: 300, ar: 0.866, left: 120, bottom: 55, z: 2, rot: -3,
|
||||
},
|
||||
eyebrow: "Mehr",
|
||||
head: 'Wir wollten nicht weg.<br><span class="a">Wir wollten mehr.</span>',
|
||||
body: "KI, CRM, Automatisierung. Und Tools, die miteinander reden.",
|
||||
vis: "lose", visW: 900, visLeft: 92, visBottom: 200,
|
||||
},
|
||||
{
|
||||
key: "form-builder", type: "feature",
|
||||
key: "verbinden", type: "feature",
|
||||
layouts: [{ id: "standard", label: "Standard" }],
|
||||
eyebrow: "Formulare",
|
||||
head: 'Formulare selbst bauen.<br><span class="a">Per Drag-and-drop.</span>',
|
||||
body: "Von der Kontaktanfrage bis zum Aufmaß mit Unterschrift vor Ort. Teil sie per Link oder QR-Code, jede Einsendung wird automatisch zu Lead, Kontakt oder Auftrag.",
|
||||
img: "./assets/screens/form-builder.png",
|
||||
mockW: 540, mockAR: 0.75, mockLeft: 270,
|
||||
imgScale: 3.8, imgX: "-36.9%", imgY: "-10%",
|
||||
eyebrow: "Verbinden",
|
||||
head: 'Dein ERP bleibt.<br><span class="a">Der Rest kommt dazu.</span>',
|
||||
body: "Nichts wird ersetzt. Alles wird verbunden.",
|
||||
vis: "verbinden", visW: 880, visLeft: 100, visBottom: 170,
|
||||
},
|
||||
{
|
||||
key: "warteliste", type: "feature",
|
||||
layouts: [{ id: "standard", label: "Standard" }],
|
||||
eyebrow: "Warteliste",
|
||||
head: 'Gebaut im Betrieb.<br><span class="a">Für den Betrieb.</span>',
|
||||
body: "Setz dich auf die Warteliste.",
|
||||
vis: "warteliste", visW: 820, visLeft: 130, visBottom: 220,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1130,6 +1267,73 @@
|
||||
{ pfad: "./assets/screens/form-builder.png", name: "Form Builder" },
|
||||
];
|
||||
|
||||
/* ─── Visualisierungen ───────────────────────────────────────────────────
|
||||
Jede Slide nennt ueber "vis" ihr Bild. Gebaut wird es hier aus HTML, nicht
|
||||
aus einer Aufnahme: so bleibt es beim Export scharf und laesst sich wie
|
||||
jedes andere Element im Canvas verschieben. */
|
||||
const kasten = (titel, zeile, marke) =>
|
||||
'<div class="vis-kasten' + (marke ? " vis-marke" : "") + '">' +
|
||||
'<div class="vis-titel">' + titel + '</div>' +
|
||||
(zeile ? '<div class="vis-zeile">' + zeile + '</div>' : '') +
|
||||
'</div>';
|
||||
|
||||
const VIS = {
|
||||
karte: () =>
|
||||
'<div class="karte">' +
|
||||
'<div class="karte-grund"><img alt="" src="' + assets["./assets/team/noah-bg.webp"] + '">' +
|
||||
'<span class="karte-wash"></span></div>' +
|
||||
'<img class="karte-person" alt="Noah Geerkens" src="' +
|
||||
assets["./assets/team/noah-person.webp"] + '">' +
|
||||
'<div class="karte-name"><span>Noah</span><small>CEO</small></div>' +
|
||||
'</div>',
|
||||
|
||||
schiene: () =>
|
||||
'<div class="vis-schiene">' +
|
||||
kasten("Anfrage", "so wie immer") + '<div class="verbund"></div>' +
|
||||
kasten("Angebot", "so wie immer") + '<div class="verbund"></div>' +
|
||||
kasten("Rechnung", "so wie immer") +
|
||||
'</div><div class="vis-riegel"></div>',
|
||||
|
||||
ersetzen: () =>
|
||||
'<div class="vis-ersetzen">' +
|
||||
'<div class="schwer vis-stapel">' +
|
||||
kasten("Stammdaten", "seit Jahren gepflegt") +
|
||||
kasten("Aufträge", "die ganze Historie") +
|
||||
kasten("Buchhaltung", "und die Leute, die es kennen") +
|
||||
'</div>' +
|
||||
'<div class="pfeil"><div class="vis-kreuz"><i></i><i></i></div></div>' +
|
||||
'<div class="leer">alles noch mal von vorn</div>' +
|
||||
'</div>',
|
||||
|
||||
lose: () =>
|
||||
'<div class="vis-lose">' +
|
||||
'<div class="feld">' + kasten("KI", "fehlt") + '<span class="stummel"></span></div>' +
|
||||
'<div class="feld">' + kasten("CRM", "fehlt") + '<span class="stummel"></span></div>' +
|
||||
'<div class="feld">' + kasten("Automation", "fehlt") + '<span class="stummel"></span></div>' +
|
||||
'<div class="feld">' + kasten("ERP", "läuft, redet aber mit niemandem") + '<span class="stummel"></span></div>' +
|
||||
'</div>',
|
||||
|
||||
verbinden: () =>
|
||||
'<div class="vis-verbinden">' +
|
||||
'<div class="saeule">' + kasten("KI") + kasten("CRM") + '</div>' +
|
||||
'<div class="mitte">' +
|
||||
'<span class="quer li"></span>' +
|
||||
'<div class="vis-nabe"><b>Dein ERP</b><small>bleibt, wo es ist</small></div>' +
|
||||
'<span class="quer re"></span>' +
|
||||
'</div>' +
|
||||
'<div class="saeule">' + kasten("Automation") + kasten("Chat", "", true) + '</div>' +
|
||||
'</div>',
|
||||
|
||||
warteliste: () =>
|
||||
'<div class="vis-warteliste">' +
|
||||
'<div class="feldzeile">' +
|
||||
'<div class="eingabe">deine@firma.de</div>' +
|
||||
'<div class="knopf">Auf die Warteliste</div>' +
|
||||
'</div>' +
|
||||
'<div class="adresse">hivegrid.de</div>' +
|
||||
'</div>',
|
||||
};
|
||||
|
||||
/* ─── Das Deck ────────────────────────────────────────────────────────────
|
||||
Welche Slides der Post hat, steht nicht mehr fest. Jeder Eintrag ist
|
||||
entweder eine mitgelieferte Vorlage (ref) oder eine selbst angelegte, und
|
||||
@@ -1191,6 +1395,7 @@
|
||||
"screen-logo": { label: "Logo im Screen", size: 430, prop: "width" },
|
||||
"laptop": { label: "Laptop", size: 960, prop: "width" },
|
||||
"szene": { label: "Laptop · Board", size: 880, prop: "width" },
|
||||
"vis": { label: "Visualisierung", size: null, prop: "width" },
|
||||
"mock": { label: "Bild", size: null, prop: "width" },
|
||||
"mock-2": { label: "Zweites Bild", size: null, prop: "width" },
|
||||
"note": { label: "Notizzettel", size: null, prop: "width" },
|
||||
@@ -1205,6 +1410,7 @@
|
||||
if (key === "mock") return SLIDES[i].mockW || 1090;
|
||||
if (key === "mock-2") return (SLIDES[i].media2 || {}).w || 400;
|
||||
if (key === "note") return (SLIDES[i].note || {}).w || 320;
|
||||
if (key === "vis") return SLIDES[i].visW || 900;
|
||||
return (STANDARD[key] || {}).size;
|
||||
}
|
||||
|
||||
@@ -1222,7 +1428,8 @@
|
||||
let edits = SLIDES.map(() => ({}));
|
||||
|
||||
let picked = null; // { slide, key }
|
||||
let editMode = "aus";
|
||||
// Bearbeiten ist immer an. "aus" heisst Vorschau: alles festgelegt.
|
||||
let editMode = "an";
|
||||
|
||||
let current = 0;
|
||||
let variant = "dunkel", tilt = "an", superSample = 2, view = "streifen", tagOut = "an", frameStyle = "chamfer";
|
||||
@@ -1731,6 +1938,16 @@
|
||||
content.className = "content";
|
||||
page.appendChild(content);
|
||||
|
||||
if (sl.vis && VIS[sl.vis]) {
|
||||
const v = document.createElement("div");
|
||||
v.className = "vis vis-" + sl.vis;
|
||||
v.style.cssText =
|
||||
"--vis-w:" + (sl.visW || 900) + "px;--vis-left:" + (sl.visLeft || 92) +
|
||||
"px;--vis-bottom:" + (sl.visBottom || 96) + "px";
|
||||
v.innerHTML = VIS[sl.vis]();
|
||||
page.appendChild(v);
|
||||
}
|
||||
|
||||
if (sl.type === "feature" && assets[sl.img]) {
|
||||
const mock = document.createElement("div");
|
||||
mock.className = "mock";
|
||||
@@ -1882,7 +2099,9 @@
|
||||
.concat(SLIDES.filter(s => s.img).map(s => s.img))
|
||||
.concat(SLIDES.filter(s => s.back).map(s => s.back.img))
|
||||
.concat(SLIDES.filter(s => s.media2).map(s => s.media2.img));
|
||||
paths.push("./assets/screens/pipelines.png", "./assets/screens/chat-tablet.png");
|
||||
// Noahs Karte von der Ueber-uns-Seite. Zwei Bilder, weil die Karte die
|
||||
// Person freigestellt vor ihren eigenen Hintergrund legt.
|
||||
paths.push("./assets/team/noah-bg.webp", "./assets/team/noah-person.webp");
|
||||
/* Alle Screens, nicht nur die gerade benutzten: eine selbst angelegte
|
||||
Slide kann jeden davon waehlen, und ein Bild, das erst beim Auswaehlen
|
||||
geladen wuerde, fehlt im Export. */
|
||||
@@ -3115,18 +3334,24 @@
|
||||
})();
|
||||
|
||||
document.getElementById("forget").addEventListener("click", forgetProject);
|
||||
document.getElementById("editmodes").addEventListener("click", e => {
|
||||
document.getElementById("vorschau").addEventListener("click", e => {
|
||||
const b = e.target.closest("button");
|
||||
if (!b) return;
|
||||
editMode = b.dataset.e;
|
||||
press("editmodes", "e", editMode);
|
||||
setVorschau(b.dataset.p === "an");
|
||||
});
|
||||
|
||||
/* In der Vorschau ist alles festgelegt: keine Auswahl, kein Ziehen, keine
|
||||
Rahmen. Blaettern und Zoomen bleiben, das ist der Sinn der Sache. */
|
||||
function setVorschau(an) {
|
||||
editMode = an ? "aus" : "an";
|
||||
press("vorschau", "p", an ? "an" : "aus");
|
||||
deck.querySelectorAll(".slide").forEach(el => { el.dataset.editmode = editMode; });
|
||||
if (editMode === "aus") {
|
||||
if (an) {
|
||||
picked = null;
|
||||
deck.querySelectorAll("[data-edit]").forEach(n => n.classList.remove("picked"));
|
||||
syncEditPanel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ─── Angleichen über alle Slides ────────────────────────────────────────
|
||||
Das gewählte Element ist die Vorlage, alle gleichnamigen auf den anderen
|
||||
@@ -3286,7 +3511,7 @@
|
||||
const menues = [...bar.querySelectorAll(".menu")];
|
||||
const zu = () => menues.forEach(m => delete m.dataset.offen);
|
||||
|
||||
const AKTION = { undo, redo };
|
||||
const AKTION = { undo, redo, vorschau: () => setVorschau(editMode === "an") };
|
||||
|
||||
// Haken und graue Eintraege erst beim Oeffnen setzen: vorher weiss die
|
||||
// Leiste nicht, was gerade gilt.
|
||||
@@ -3299,6 +3524,11 @@
|
||||
b.insertAdjacentHTML("afterbegin",
|
||||
'<span class="haken">' + (an ? "✓" : "") + "</span>");
|
||||
});
|
||||
m.querySelectorAll('button[data-tun="vorschau"]').forEach(b => {
|
||||
b.querySelector(".haken")?.remove();
|
||||
b.insertAdjacentHTML("afterbegin",
|
||||
'<span class="haken">' + (editMode === "aus" ? "✓" : "") + "</span>");
|
||||
});
|
||||
m.querySelectorAll("button[data-klick]").forEach(b => {
|
||||
const q = document.getElementById(b.dataset.klick);
|
||||
b.disabled = !q || q.disabled;
|
||||
@@ -3545,13 +3775,12 @@
|
||||
else if (e.key === "-") { setZoom((zoom || autoFit()) / 1.25); }
|
||||
else if (e.key === "0") { zoom = null; fitStrip(); }
|
||||
else if (k === "w") { view = view === "streifen" ? "einzeln" : "streifen"; deck.dataset.view = view; press("views", "w", view); zoom = null; show(current); }
|
||||
else if (k === "e") { document.querySelector('#editmodes button[data-e="' + (editMode === "an" ? "aus" : "an") + '"]').click(); }
|
||||
else if (k === "p") { setVorschau(editMode === "an"); }
|
||||
else if (k === "r") {
|
||||
const cyc = ["chamfer", "rund", "stapel", "aus"];
|
||||
frameStyle = cyc[(cyc.indexOf(frameStyle) + 1) % cyc.length];
|
||||
press("frames", "f", frameStyle); applyAll(); saveState();
|
||||
}
|
||||
else if (k === "g") { tagOut = tagOut === "an" ? "aus" : "an"; press("tagouts", "o", tagOut); applyAll(); saveState(); }
|
||||
else if (k === "d") guard(downloadOne)();
|
||||
else if (k === "a") guard(downloadAll)();
|
||||
});
|
||||
|
||||
+31
-124
@@ -14,7 +14,11 @@
|
||||
},
|
||||
{
|
||||
"bg": "raster",
|
||||
"int": "kraeftig"
|
||||
"int": "dezent"
|
||||
},
|
||||
{
|
||||
"bg": "raster",
|
||||
"int": "dezent"
|
||||
},
|
||||
{
|
||||
"bg": "raster",
|
||||
@@ -28,159 +32,62 @@
|
||||
"werte": {}
|
||||
},
|
||||
{
|
||||
"ref": "workflow-engine",
|
||||
"ref": "prozesse",
|
||||
"werte": {}
|
||||
},
|
||||
{
|
||||
"ref": "projektmanagement",
|
||||
"ref": "wechseln",
|
||||
"werte": {}
|
||||
},
|
||||
{
|
||||
"ref": "chat",
|
||||
"ref": "mehr",
|
||||
"werte": {}
|
||||
},
|
||||
{
|
||||
"ref": "form-builder",
|
||||
"ref": "verbinden",
|
||||
"werte": {}
|
||||
},
|
||||
{
|
||||
"ref": "warteliste",
|
||||
"werte": {}
|
||||
}
|
||||
],
|
||||
"edits": [
|
||||
{
|
||||
"laptop": {
|
||||
"dx": -15,
|
||||
"dy": -39,
|
||||
"size": 827
|
||||
},
|
||||
"logo-full": {
|
||||
"dx": -40,
|
||||
"dy": 597
|
||||
},
|
||||
"szene": {
|
||||
"dx": 129,
|
||||
"dy": -286,
|
||||
"size": 1816
|
||||
},
|
||||
"wabe-claim": {
|
||||
"dx": 1214,
|
||||
"dy": -1110
|
||||
},
|
||||
"wabe-logo": {
|
||||
"dx": 215,
|
||||
"dy": 831
|
||||
},
|
||||
"wabe-tagline": {
|
||||
"dx": 141,
|
||||
"dy": -33,
|
||||
"size": 88
|
||||
"vis": {
|
||||
"dx": -100,
|
||||
"dy": 250,
|
||||
"size": 700
|
||||
}
|
||||
},
|
||||
{
|
||||
"badge": {
|
||||
"dx": 311,
|
||||
"dy": -77
|
||||
},
|
||||
"body": {
|
||||
"dx": 2,
|
||||
"dy": -55
|
||||
},
|
||||
"headline": {
|
||||
"dx": 0,
|
||||
"dy": -109
|
||||
},
|
||||
"mock": {
|
||||
"dx": -38,
|
||||
"dy": -383,
|
||||
"size": 965
|
||||
},
|
||||
"mock-2": {
|
||||
"dx": -75,
|
||||
"dy": 1,
|
||||
"size": 354
|
||||
},
|
||||
"note": {
|
||||
"dx": 150,
|
||||
"dy": -244,
|
||||
"size": 320
|
||||
"vis": {
|
||||
"dx": -7,
|
||||
"dy": -19
|
||||
}
|
||||
},
|
||||
{
|
||||
"badge": {
|
||||
"dx": -42,
|
||||
"dy": -68
|
||||
},
|
||||
"body": {
|
||||
"dx": 2,
|
||||
"dy": -55
|
||||
},
|
||||
"headline": {
|
||||
"dx": 0,
|
||||
"dy": -109
|
||||
},
|
||||
"mock": {
|
||||
"dx": 107,
|
||||
"dy": 1,
|
||||
"size": 706
|
||||
},
|
||||
"mock-2": {
|
||||
"dx": 159,
|
||||
"dy": 8,
|
||||
"size": 360
|
||||
"vis": {
|
||||
"dx": 19,
|
||||
"dy": -27
|
||||
}
|
||||
},
|
||||
{
|
||||
"badge": {
|
||||
"dx": -42,
|
||||
"dy": -68
|
||||
},
|
||||
"body": {
|
||||
"dx": 2,
|
||||
"dy": -55
|
||||
},
|
||||
"headline": {
|
||||
"dx": 0,
|
||||
"dy": -109
|
||||
},
|
||||
"mock": {
|
||||
"dx": -20,
|
||||
"dy": -222,
|
||||
"size": 931
|
||||
},
|
||||
"mock-2": {
|
||||
"dx": -69,
|
||||
"dy": -139
|
||||
}
|
||||
},
|
||||
{
|
||||
"badge": {
|
||||
"dx": -42,
|
||||
"dy": -68
|
||||
},
|
||||
"body": {
|
||||
"dx": 2,
|
||||
"dy": -55
|
||||
},
|
||||
"headline": {
|
||||
"dx": 0,
|
||||
"dy": -109
|
||||
},
|
||||
"mock": {
|
||||
"dx": -24,
|
||||
"dy": -8,
|
||||
"size": 584
|
||||
}
|
||||
}
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
"frameStyle": "rund",
|
||||
"frameStyle": "chamfer",
|
||||
"layoutState": [
|
||||
"szene",
|
||||
"standard",
|
||||
"standard",
|
||||
"standard",
|
||||
"standard",
|
||||
"standard",
|
||||
"standard"
|
||||
],
|
||||
"superSample": 3,
|
||||
"superSample": 2,
|
||||
"tagOut": "an",
|
||||
"tilt": "aus",
|
||||
"tilt": "an",
|
||||
"v": 6,
|
||||
"variant": "hell",
|
||||
"view": "streifen"
|
||||
|
||||
Reference in new issue
Block a user