Nur noch das Raster als Grund, Menueleiste, Post 2

Der Grund ist fest das Raster. Raus sind die vier Formen-Bausteine, die grosse
G-Marke, das Wabenraster samt seinem Kachel-Erzeuger, die Punkte und die
Musterauswahl mit ihrer Taste. Ebenso das durchgehende Band: Sechsecke auf den
Naehten, Band und G-Marke, CSS, Schalter und Taste.

Beim Aufraeumen war zwischenzeitlich ".bg > * { display: none; }" mit
verschwunden. Diese eine Zeile hatte das Band die ganze Zeit verdeckt, eine
Einblende-Regel gab es dafuer naemlich nie. Ohne sie schwebten Sechsecke und
G-Marke ueber den Slides.

Die Projektauswahl ist eine Menueleiste ueber die volle Breite: Projekt,
Datei, Bearbeiten, Slide, Ansicht. Sie fuehrt nichts selbst aus, sondern
betaetigt die vorhandenen Schalter im Bedienfeld, damit jedes Verhalten an
genau einer Stelle steht. Haken und graue Eintraege liest sie beim Oeffnen aus
denselben Schaltern.

post2.html ist eine Kopie von post1.html bis auf Titel, Ueberschrift und
Projektschluessel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-07 19:50:35 +02:00
1 parent 92529a8c47
commit 57d1f4c540
2 files changed
+3810 -222

No files matched your search

+199 -222
View File
@@ -30,9 +30,53 @@
body {
font-family: 'Manrope', system-ui, sans-serif;
background: #17181F; color: #E8EAEE;
height: 100vh; overflow: hidden; display: flex;
height: 100vh; overflow: hidden;
display: flex; flex-direction: column;
}
/* ─── Menueleiste ────────────────────────────────────────────────────────
Statt einer Knopfreihe fuer die Projekte eine Leiste wie in einem
Bildprogramm. Sie bedient keine eigene Logik, sondern klickt die
vorhandenen Schalter im Bedienfeld an: sonst gaebe es zwei Wahrheiten
ueber denselben Zustand. */
.menubar {
flex: none; display: flex; align-items: stretch; gap: 2px;
height: 34px; padding: 0 8px;
background: #14161C; border-bottom: 1px solid #24262F;
font-size: 13px; user-select: none; position: relative; z-index: 60;
}
.menubar .marke {
display: flex; align-items: center; padding: 0 12px 0 4px;
font-weight: 800; letter-spacing: -0.01em; color: #E8EAEE;
}
.menu { position: relative; }
.menu > button {
height: 100%; padding: 0 11px; cursor: pointer;
background: none; border: 0; color: #C7CCD6;
font-family: inherit; font-size: 13px;
}
.menu > button:hover { background: #1D1F26; }
.menu[data-offen="ja"] > button { background: #262932; color: #fff; }
.menu > .liste { display: none; }
.menu[data-offen="ja"] > .liste {
display: block; position: absolute; top: 100%; left: 0;
min-width: 232px; padding: 5px;
background: #1D1F26; border: 1px solid #2E313B; border-radius: 9px;
}
.menu .liste button {
display: flex; width: 100%; align-items: center; gap: 14px;
padding: 6px 9px; cursor: pointer; text-align: left;
background: none; border: 0; border-radius: 6px;
color: #C7CCD6; font-family: inherit; font-size: 13px;
}
.menu .liste button:hover { background: #2A2D36; color: #fff; }
.menu .liste button:disabled { opacity: .38; cursor: default; background: none; }
.menu .liste button .kurz { margin-left: auto; color: #6E7480; font-size: 11.5px; }
.menu .liste button .haken { width: 12px; color: var(--accent-yellow); }
.menu .liste hr { height: 1px; margin: 5px 4px; background: #2E313B; border: 0; }
.arbeitsflaeche { flex: 1; display: flex; min-height: 0; }
/* Inhaltsfelder der gewaehlten Slide. Eine Spalte, damit lange Texte nicht
in einer schmalen Zelle kleben. */
#inhalt { display: flex; flex-direction: column; gap: 4px; }
@@ -96,7 +140,7 @@
/* ─── Control panel ──────────────────────────────────────────────────── */
.panel {
width: 306px; flex: none; height: 100vh; overflow-y: auto;
width: 306px; flex: none; height: 100%; overflow-y: auto;
padding: 28px 22px 40px 28px;
border-right: 1px solid #24262F; background: #17181F;
}
@@ -287,121 +331,20 @@
font-family: 'Manrope', system-ui, sans-serif;
}
/* ─── Background layers ──────────────────────────────────────────────────
Five interchangeable grounds. Shapes are built from the brand geometry
(chamfered blocks + flat-top hexagons) in --dark-bg, the colour of the dark
story section on the site. */
/* ─── Grund ──────────────────────────────────────────────────────────────
Ein einziger Grund: das Raster. Formen, Waben, Punkte und die grosse
G-Marke sind raus, ebenso das durchgehende Band mit den Sechsecken auf
den Naehten. Einstellbar bleibt nur die Staerke. */
.bg { position: absolute; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
.slide[data-int="dezent"] .bg { --int-mul: .55; }
.slide[data-int="kraeftig"] .bg { --int-mul: 1; }
.bg > * { display: none; }
.slide[data-bg="formen"] .layer-shapes,
.slide[data-bg="formen-g"] .layer-shapes,
.slide[data-bg="formen-g"] .layer-gmark,
.slide[data-bg="nur-g"] .layer-shapes,
.slide[data-bg="nur-g"] .layer-gmark,
.slide[data-bg="waben"] .layer-waben,
.slide[data-bg="punkte"] .layer-punkte,
.slide[data-bg="raster"] .layer-raster { display: block; }
.layer-shapes, .layer-waben, .layer-punkte, .layer-raster {
position: absolute; inset: 0; width: 100%; height: 100%;
}
.layer-gmark { inset: auto; }
.slide[data-bg="nur-g"] .sh-block { display: none; }
.layer-raster { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Optische Ausrückung des Tags: Der Kasten steht bündig zur Inhaltskante,
sein TEXT dadurch um die 20 px Innenabstand eingerückt gegenüber der
Headline. Das negative Margin holt den Text auf dieselbe Linie. Zum
Vergleichen umschaltbar. */
.sh { position: absolute; }
/* Two large forms anchored to opposite corners and mostly off canvas, plus
the yellow hex as the one warm accent. Everything stays clear of the copy:
shapes crossing the headline are what made an earlier version look thrown
together. */
.sh-block {
top: -300px; right: -290px; width: 760px; height: 760px;
background: var(--shape-fill);
transform: rotate(-14deg);
clip-path: polygon(
74px 0, calc(100% - 74px) 0, 100% 74px, 100% calc(100% - 74px),
calc(100% - 74px) 100%, 74px 100%, 0 calc(100% - 74px), 0 74px
);
}
.sh-hex-line {
bottom: -300px; left: -260px; width: 660px; height: 572px;
opacity: var(--int-mul, 1);
border: 14px solid var(--shape-line);
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}
.sh-hex-accent {
top: 268px; left: -66px; width: 172px; height: 149px;
opacity: var(--int-mul, 1);
background: var(--shape-accent);
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}
.sh-hex-small {
bottom: 296px; right: -40px; width: 108px; height: 94px;
opacity: var(--int-mul, 1);
background: var(--shape-accent-2);
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}
/* Oversized G behind the device, cropped by whatever sits in front of it, so
only its top peeks out. Same idea as the watermark on the dark comparison
card on the site, just in grey. Lives in the background layer (z-index 0),
so the mockup always covers its lower half. */
.layer-gmark {
position: absolute; left: 50%; top: 400px;
width: 880px; height: auto;
transform: translateX(-50%);
color: var(--gmark-color);
opacity: var(--int-mul, 1);
}
/* ─── Durchgehendes Carousel ──────────────────────────────────────────────
Der Post ist ein einziges durchgehendes Blatt, das in 1080er Fenster
geschnitten wird. Seine Breite folgt der Anzahl der Slides (--sheet-w). Jede Slide zeigt ihren Ausschnitt, indem die
Ebene um index * 1080 nach links verschoben wird. Elemente auf den Nähten
werden dadurch zerschnitten und laufen auf der nächsten Slide weiter. */
.continuum {
position: absolute; top: 0; height: 100%;
left: calc(var(--slide-i, 0) * -1080px);
width: var(--sheet-w, 5400px);
pointer-events: none;
opacity: var(--int-mul, 1);
}
.slide[data-cont="aus"] .continuum { display: none; }
.continuum > * { position: absolute; }
/* Sechsecke sitzen mittig auf den Nähten (1080, 2160, 3240, 4320) und werden
dort halbiert. Das ist das deutlichste Signal, dass es weitergeht. */
.ct-hex {
background: var(--shape-fill);
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}
.ct-hex-line {
border: 13px solid var(--shape-line);
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}
/* Ein Band über die volle Breite: die Klammer, die alle fünf zusammenhält. */
.ct-band {
left: 0; width: var(--sheet-w, 5400px); height: 54px; bottom: 96px;
background: var(--shape-line);
}
.ct-g { color: var(--gmark-color); }
.layer-waben { color: var(--pat-color); opacity: calc(var(--pat-strength) * var(--int-mul, 1)); }
.layer-punkte {
background-image: radial-gradient(circle, var(--pat-color) 3px, transparent 3px);
background-size: 52px 52px;
opacity: calc(var(--pat-strength) * var(--int-mul, 1));
}
.layer-raster {
background-image:
linear-gradient(var(--pat-color) 2px, transparent 2px),
@@ -780,8 +723,6 @@
--frame-bg: rgba(255,255,255,.11);
--shape-fill: #414252;
--shape-line: rgba(255,255,255,.10);
--shape-accent: var(--accent-yellow);
--shape-accent-2: rgba(255,255,255,.14);
--pat-color: #FFFFFF; --pat-strength: .07;
--gmark-color: rgba(255,255,255,.13);
--guide-line: rgba(255,255,255,.16);
@@ -802,8 +743,6 @@
--frame-bg: #E8EBF0;
--shape-fill: var(--dark-bg);
--shape-line: rgba(48,49,61,.13);
--shape-accent: var(--accent-yellow);
--shape-accent-2: rgba(48,49,61,.16);
--pat-color: #30313D; --pat-strength: .07;
--gmark-color: rgba(48,49,61,.16);
--guide-line: rgba(48,49,61,.20);
@@ -815,6 +754,73 @@
</head>
<body>
<div class="menubar" id="menubar">
<span class="marke">HiveGrid</span>
<div class="menu" data-menu="projekt">
<button type="button">Projekt</button>
<div class="liste">
<button type="button" data-gehe="./post1.html">Post 1</button>
<button type="button" data-gehe="./post2.html">Post 2</button>
<hr>
<button type="button" data-klick="snap-save">Stand merken</button>
<button type="button" data-klick="snap-load">Zurück zum gemerkten Stand</button>
<hr>
<button type="button" data-klick="forget">Projekt zurücksetzen</button>
</div>
</div>
<div class="menu" data-menu="datei">
<button type="button">Datei</button>
<div class="liste">
<button type="button" data-klick="bild-waehlen">Bild importieren</button>
<hr>
<button type="button" data-klick="dl-png">Diese Slide laden<span class="kurz">D</span></button>
<button type="button" data-klick="dl-all">Alle Slides als ZIP<span class="kurz">A</span></button>
</div>
</div>
<div class="menu" data-menu="bearbeiten">
<button type="button">Bearbeiten</button>
<div class="liste">
<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>
</div>
<div class="menu" data-menu="slide">
<button type="button">Slide</button>
<div class="liste">
<button type="button" data-klick="slide-neu">Neu dahinter</button>
<button type="button" data-klick="slide-kopie">Kopieren</button>
<button type="button" data-klick="slide-weg">Löschen</button>
<hr>
<button type="button" data-klick="slide-links">Nach vorn</button>
<button type="button" data-klick="slide-rechts">Nach hinten</button>
</div>
</div>
<div class="menu" data-menu="ansicht">
<button type="button">Ansicht</button>
<div class="liste">
<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>
<button type="button" data-klick="zoom-fit">Einpassen<span class="kurz">0</span></button>
<button type="button" data-klick="zoom-in">Größer<span class="kurz">+</span></button>
<button type="button" data-klick="zoom-out">Kleiner<span class="kurz">−</span></button>
</div>
</div>
</div>
<div class="arbeitsflaeche">
<aside class="panel">
<h1>Post 1 · Lösung</h1>
<p class="sub"><span id="kopfzeile">Carousel · 1080 × 1350 px</span><span class="saved" id="saved"></span><br><button class="forget" id="forget">Projekt zurücksetzen</button></p>
@@ -891,27 +897,6 @@
</div>
</details>
<details class="group" data-grp="durchgehend-alle-slides">
<summary>Durchgehend (alle Slides)</summary>
<div class="opts" id="conts">
<button data-c="an" aria-pressed="false">An</button>
<button data-c="aus" aria-pressed="true">Aus</button>
</div>
</details>
<details class="group" data-grp="muster-nur-diese-slide">
<summary>Muster (nur diese Slide)</summary>
<div class="opts three" id="bgs">
<button data-b="formen" aria-pressed="true">Formen</button>
<button data-b="formen-g" aria-pressed="false">Formen + G</button>
<button data-b="nur-g" aria-pressed="false">Nur G</button>
<button data-b="waben" aria-pressed="false">Waben</button>
<button data-b="punkte" aria-pressed="false">Punkte</button>
<button data-b="raster" aria-pressed="false">Raster</button>
<button data-b="aus" aria-pressed="false">Aus</button>
</div>
</details>
<details class="group" data-grp="intensit-t">
<summary>Intensität</summary>
<div class="opts" id="ints">
@@ -959,8 +944,8 @@
<summary>Tastatur</summary>
<div class="keys">
<kbd>←</kbd><kbd>→</kbd> Slide · <kbd>V</kbd> Variante<br>
<kbd>L</kbd> Layout · <kbd>M</kbd> Muster · <kbd>I</kbd> Intensität<br>
<kbd>C</kbd> Durchgehend · <kbd>W</kbd> Ansicht · <kbd>G</kbd> Tag<br>
<kbd>L</kbd> Layout · <kbd>I</kbd> Intensität<br>
<kbd>W</kbd> Ansicht · <kbd>G</kbd> Tag<br>
<kbd>R</kbd> Bildrahmen<br>
<kbd>T</kbd> Perspektive<br>
<kbd>E</kbd> Bearbeiten · Pfeile verschieben (<kbd>⇧</kbd> = 10 px)<br>
@@ -1003,6 +988,7 @@
</div>
<div id="el-inhalt"></div>
</aside>
</div>
<script src="./vendor/html-to-image.js"></script>
<script src="./vendor/jszip.min.js"></script>
@@ -1239,7 +1225,7 @@
let editMode = "aus";
let current = 0;
let variant = "dunkel", tilt = "an", superSample = 2, continuous = "aus", view = "streifen", tagOut = "an", frameStyle = "chamfer";
let variant = "dunkel", tilt = "an", superSample = 2, view = "streifen", tagOut = "an", frameStyle = "chamfer";
/* ─── Projektstand ────────────────────────────────────────────────────────
Alles, was am Projekt hängt, wird gespeichert: Einstellungen, Layouts,
@@ -1253,7 +1239,7 @@
function currentState() {
return {
v: STATE_V, variant, tilt, superSample, continuous, view, tagOut, frameStyle,
v: STATE_V, variant, tilt, superSample, view, tagOut, frameStyle,
current, layoutState, bgState, edits,
// Welche Slides der Post ueberhaupt hat. Ohne das waere eine selbst
// angelegte Slide nach dem Neuladen weg.
@@ -1380,7 +1366,6 @@
press("variants", "v", variant);
press("tilts", "t", tilt);
press("quality", "q", String(superSample));
press("conts", "c", continuous);
press("tagouts", "o", tagOut);
press("frames", "f", frameStyle);
press("views", "w", view);
@@ -1511,7 +1496,6 @@
variant = d.variant || variant;
tilt = d.tilt || tilt;
superSample = d.superSample || superSample;
continuous = d.continuous || continuous;
view = d.view || view;
tagOut = d.tagOut || tagOut;
frameStyle = d.frameStyle || frameStyle;
@@ -1538,7 +1522,8 @@
.then(() => location.reload());
}
// Per-slide so a single slide can carry a different ground.
const bgState = SLIDES.map(() => ({ bg: "formen", int: "dezent" }));
// Der Grund ist fest das Raster. Einstellbar bleibt nur seine Staerke.
const bgState = SLIDES.map(() => ({ bg: "raster", int: "dezent" }));
// Each slide picks its own layout from its own catalogue.
const layoutState = SLIDES.map(sl => sl.layouts[0].id);
// Every asset is inlined once at boot, so re-rendering a layout stays synchronous.
@@ -1603,74 +1588,13 @@
'<circle cx="12" cy="5" r="1.9"/><circle cx="12" cy="12" r="1.9"/>' +
'<circle cx="12" cy="19" r="1.9"/></svg>';
const SVG_NS = "http://www.w3.org/2000/svg";
const G_POINTS = "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";
const G_W = 384.5, G_H = 332.9;
// Positionen im 5400er Raum. Die Nähte liegen auf 1080 / 2160 / 3240 / 4320.
const CONTINUUM_HTML =
'<div class="continuum">' +
'<div class="ct-hex" style="left:870px; top:210px; width:420px; height:364px"></div>' +
'<div class="ct-hex-line" style="left:1935px; top:930px; width:450px; height:390px"></div>' +
'<div class="ct-hex" style="left:2980px; top:150px; width:520px; height:450px"></div>' +
'<div class="ct-hex-line" style="left:4130px; top:860px; width:380px; height:329px"></div>' +
'<div class="ct-band"></div>' +
'<svg class="ct-g" style="left:1840px; top:420px; width:640px" ' +
'viewBox="0 0 384.5 332.9" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">' +
'<polygon fill="currentColor" points="' + G_POINTS + '"/></svg>' +
'</div>';
const BG_HTML =
'<div class="bg">' + CONTINUUM_HTML +
'<div class="layer-shapes">' +
'<div class="sh sh-block"></div>' +
'<div class="sh sh-hex-line"></div>' +
'<div class="sh sh-hex-accent"></div>' +
'<div class="sh sh-hex-small"></div>' +
'</div>' +
'<svg class="layer-gmark" viewBox="0 0 384.5 332.9" aria-hidden="true" ' +
'xmlns="http://www.w3.org/2000/svg"><polygon fill="currentColor" points="' +
G_POINTS + '"/></svg>' +
'<svg class="layer-waben" aria-hidden="true"></svg>' +
'<div class="layer-punkte"></div>' +
'<div class="bg">' +
'<div class="layer-raster"></div>' +
'</div>';
/* Seamless flat-top honeycomb tile, generated from the same G polygon as the
logo mark. Columns step by 3/4 of the hex width and neighbouring columns sit
half a row apart, so one tile is two columns wide and one row high. The
copies hanging past the tile edges are what make the repeat seamless. */
function buildWaben(svg, uid) {
const colStep = G_W * 0.75, rowStep = G_H;
const tileW = colStep * 2, tileH = rowStep;
const centres = [
[0, 0], [tileW, 0], [0, tileH], [tileW, tileH],
[colStep, rowStep / 2], [colStep, -rowStep / 2], [colStep, tileH + rowStep / 2],
];
const id = "waben-" + uid;
const defs = document.createElementNS(SVG_NS, "defs");
const pat = document.createElementNS(SVG_NS, "pattern");
pat.setAttribute("id", id);
pat.setAttribute("patternUnits", "userSpaceOnUse");
pat.setAttribute("width", tileW);
pat.setAttribute("height", tileH);
pat.setAttribute("patternTransform", "scale(0.46)");
for (const [cx, cy] of centres) {
const poly = document.createElementNS(SVG_NS, "polygon");
poly.setAttribute("points", G_POINTS);
poly.setAttribute("fill", "currentColor");
poly.setAttribute("transform", "translate(" + (cx - G_W / 2) + "," + (cy - G_H / 2) + ")");
pat.appendChild(poly);
}
defs.appendChild(pat);
svg.appendChild(defs);
const rect = document.createElementNS(SVG_NS, "rect");
rect.setAttribute("width", "100%");
rect.setAttribute("height", "100%");
rect.setAttribute("fill", "url(#" + id + ")");
svg.appendChild(rect);
}
function contentHtml(s, i) {
if (s.type === "feature") {
return '<p class="badge">' + s.eyebrow + '</p>' +
@@ -1890,13 +1814,11 @@
el.dataset.bg = bgState[i].bg;
el.dataset.int = bgState[i].int;
el.dataset.layout = layoutState[i];
el.dataset.cont = continuous;
el.dataset.tagout = tagOut;
el.dataset.frame = frameStyle;
el.dataset.editmode = editMode;
el.style.setProperty("--slide-i", i);
el.innerHTML = BG_HTML;
buildWaben(el.querySelector(".layer-waben"), i);
/* 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
@@ -1997,7 +1919,6 @@
el.dataset.bg = bgState[i].bg;
el.dataset.int = bgState[i].int;
el.dataset.layout = layoutState[i];
el.dataset.cont = continuous;
el.dataset.tagout = tagOut;
el.dataset.frame = frameStyle;
if (SLIDES[i].type === "title") rebuildPage(i);
@@ -2023,7 +1944,6 @@
// Reflect the active slide's own ground in the panel.
function syncBgButtons() {
press("bgs", "b", bgState[current].bg);
press("ints", "i", bgState[current].int);
}
@@ -3352,6 +3272,79 @@
}
});
/* ─── Menueleiste ────────────────────────────────────────────────────────
Die Eintraege fuehren nichts selbst aus, sondern betaetigen die Schalter
im Bedienfeld. Damit gibt es weiter genau eine Stelle, an der ein
Verhalten steht, und die Leiste kann nicht auseinanderlaufen.
data-klick Knopf mit dieser id anklicken
data-opt Knopf einer Optionsgruppe: gruppe:attribut:wert
data-tun benannte Aktion
data-gehe anderes Projekt oeffnen */
(function menueleiste() {
const bar = document.getElementById("menubar");
if (!bar) return;
const menues = [...bar.querySelectorAll(".menu")];
const zu = () => menues.forEach(m => delete m.dataset.offen);
const AKTION = { undo, redo };
// Haken und graue Eintraege erst beim Oeffnen setzen: vorher weiss die
// Leiste nicht, was gerade gilt.
function stand(m) {
m.querySelectorAll("button[data-opt]").forEach(b => {
const [gruppe, attr, wert] = b.dataset.opt.split(":");
const q = document.querySelector("#" + gruppe + " button[data-" + attr + '="' + wert + '"]');
const an = q && q.getAttribute("aria-pressed") === "true";
b.querySelector(".haken")?.remove();
b.insertAdjacentHTML("afterbegin",
'<span class="haken">' + (an ? "✓" : "") + "</span>");
});
m.querySelectorAll("button[data-klick]").forEach(b => {
const q = document.getElementById(b.dataset.klick);
b.disabled = !q || q.disabled;
});
m.querySelectorAll("button[data-gehe]").forEach(b => {
const hier = b.dataset.gehe.endsWith(location.pathname.split("/").pop() || "post1.html");
b.querySelector(".haken")?.remove();
b.insertAdjacentHTML("afterbegin",
'<span class="haken">' + (hier ? "✓" : "") + "</span>");
});
}
bar.addEventListener("click", e => {
const titel = e.target.closest(".menu > button");
if (titel) {
const m = titel.parentElement;
const war = m.dataset.offen === "ja";
zu();
if (!war) { m.dataset.offen = "ja"; stand(m); }
return;
}
const el = e.target.closest(".liste button");
if (!el || el.disabled) return;
zu();
if (el.dataset.gehe) { location.href = el.dataset.gehe; return; }
if (el.dataset.tun) { (AKTION[el.dataset.tun] || (() => {}))(); return; }
if (el.dataset.klick) { document.getElementById(el.dataset.klick)?.click(); return; }
if (el.dataset.opt) {
const [gruppe, attr, wert] = el.dataset.opt.split(":");
document.querySelector("#" + gruppe + " button[data-" + attr + '="' + wert + '"]')?.click();
}
});
// Ueberfahren wechselt das offene Menue, wie gewohnt.
bar.addEventListener("mouseover", e => {
const titel = e.target.closest(".menu > button");
if (!titel || !menues.some(m => m.dataset.offen === "ja")) return;
const m = titel.parentElement;
if (m.dataset.offen === "ja") return;
zu(); m.dataset.offen = "ja"; stand(m);
});
document.addEventListener("mousedown", e => { if (!bar.contains(e.target)) zu(); });
document.addEventListener("keydown", e => { if (e.key === "Escape") zu(); });
})();
document.getElementById("reset-all").addEventListener("click", resetAll);
// Übersicht der Standards, direkt aus derselben Tabelle wie der Reset.
@@ -3478,14 +3471,6 @@
const b = e.target.closest("button");
if (b) { layoutState[current] = b.dataset.l; syncLayoutButtons(); rebuildPage(current); applyAll(); saveState(); }
});
document.getElementById("conts").addEventListener("click", e => {
const b = e.target.closest("button");
if (b) { continuous = b.dataset.c; press("conts", "c", continuous); applyAll(); saveState(); }
});
document.getElementById("bgs").addEventListener("click", e => {
const b = e.target.closest("button");
if (b) { bgState[current].bg = b.dataset.b; syncBgButtons(); applyAll(); saveState(); }
});
document.getElementById("ints").addEventListener("click", e => {
const b = e.target.closest("button");
if (b) { bgState[current].int = b.dataset.i; syncBgButtons(); applyAll(); saveState(); }
@@ -3511,7 +3496,6 @@
document.getElementById("dl-png").addEventListener("click", guard(downloadOne));
document.getElementById("dl-all").addEventListener("click", guard(downloadAll));
const BG_CYCLE = ["formen", "formen-g", "nur-g", "waben", "punkte", "raster", "aus"];
/* ⌘/Strg + Z. Eigener Zuhoerer, weil der allgemeine unten alles mit
Sondertaste durchlaesst. In Eingabefeldern hat das Zurueckgehen des
Browsers Vorrang, sonst kaeme man aus einem Tippfehler nicht mehr heraus. */
@@ -3551,11 +3535,6 @@
layoutState[current] = cat[(n + 1) % cat.length].id;
syncLayoutButtons(); rebuildPage(current); applyAll(); saveState();
}
else if (k === "m") {
const st = bgState[current];
st.bg = BG_CYCLE[(BG_CYCLE.indexOf(st.bg) + 1) % BG_CYCLE.length];
syncBgButtons(); applyAll();
}
else if (k === "i") {
const st = bgState[current];
st.int = st.int === "dezent" ? "kraeftig" : "dezent";
@@ -3573,7 +3552,6 @@
press("frames", "f", frameStyle); applyAll(); saveState();
}
else if (k === "g") { tagOut = tagOut === "an" ? "aus" : "an"; press("tagouts", "o", tagOut); applyAll(); saveState(); }
else if (k === "c") { continuous = continuous === "an" ? "aus" : "an"; press("conts", "c", continuous); applyAll(); saveState(); }
else if (k === "d") guard(downloadOne)();
else if (k === "a") guard(downloadAll)();
});
@@ -3608,7 +3586,6 @@
press("variants", "v", variant);
press("tilts", "t", tilt);
press("quality", "q", String(superSample));
press("conts", "c", continuous);
press("tagouts", "o", tagOut);
press("frames", "f", frameStyle);
press("views", "w", view);
+3611
View File
File diff suppressed because it is too large. Load diff