Neues Anmeldebild -- die Karte sitzt IN der gemalten Tafel

Filipe: "integriere die zugangskachel links nach rechts und passe sie
perfekt an damit sie in dem neuen bild rechts perfekt und die
vorgemachte kachel passt."

Das neue Motiv (Spicy Media x DogFather) hat rechts eine leere Tafel mit
Neonrahmen. Die Anmeldekarte sitzt jetzt DARIN -- und zwar wirklich
darin, nicht ungefaehr in der Gegend.

DAS PROBLEM, DAS MAN LEICHT UEBERSIEHT: Das Bild liegt mit
`object-fit: cover` unter der Seite; je nach Fensterform schneidet der
Browser oben/unten oder links/rechts etwas ab. Ein `left: 58%` bezieht
sich aber auf das FENSTER. Auf genau einer Bildschirmgroesse saehe es
richtig aus und ueberall sonst falsch. Deshalb rechnet `.tafel-anker`
dieselbe Cover-Formel noch einmal nach und ist damit deckungsgleich mit
dem Bild -- Prozentwerte darin sind Prozent DES BILDES.

Die vier Zahlen sind GEMESSEN (tools/gate-bauen.mjs), nicht geschaetzt.
Zwei Anlaeufe standen daneben und haben sich selbst verraten:
  1. "Suche den leuchtenden Rahmen" fand den Mond, die roten Blueten und
     jede Spiegelung -- Ergebnis: die ganze rechte Bildhaelfte. Eine
     Messung, die das Offensichtliche zurueckgibt, hat nichts gemessen.
  2. "Suche die groesste dunkle Flaeche" fand die Breite richtig, aber
     94 % Hoehe: Ueber und unter der Tafel ist die Szene genauso
     schwarz.
Richtig ist der dritte Weg: vom Mittelpunkt der Tafel nach aussen
laufen, bis es hell ODER farbig wird -- auf diesem Weg liegt nichts
anderes, denn die Tafel ist leer. Danach eine Plausibilitaetspruefung,
die abbricht statt vier geratene Zahlen auszugeben.

DREI FEHLER IM EIGENEN ENTWURF, alle gemessen statt angesehen:
  * Die Karte hing 300 px unter dem Bildschirmrand. Auf `.tafel` liegt
    die Einblend-Animation, deren Endbild `transform: none` ist -- mein
    `translateY(-50%)` war damit wirkungslos. Zwei Wege, dasselbe
    Element zu verschieben, vertragen sich nicht.
  * Der Anker lag 3 % neben dem Bild: Das Bild traegt `scale(1.03)` als
    Reserve fuer die Parallaxe. Jetzt tragen beide dieselbe Verwandlung,
    und die Parallaxe laeuft ueber zwei CSS-Groessen am <body> -- so
    wandert die Karte mit, statt dass der Rahmen unter ihr wegrutscht.
  * Der Hochkant-Ausschnitt zeigte die LEERE Tafel: ein schwarzes
    Rechteck mit ein paar Saeulen. Auf dem Handy liegt die Karte ohnehin
    davor; dort gehoert das Logo hin. Jetzt faellt der Schriftzug
    SPICY MEDIA in den sichtbaren Streifen -- nachgerechnet, nicht
    probiert.

STARTSEITE: das Tresorbild als neuer Hintergrund. Die uebernommene
Abdunklung von 0,62 war zu viel (der Tresor ist von Haus aus dunkel) --
uebrig blieb ein Schemen. Und der "Leseweg" verdunkelte ausgerechnet die
MITTE: Bei den alten Szenen stand dort nichts, beim Tresor steht dort
die Tuer. Beides korrigiert und mit pruef-buehne an echten Bildpunkten
nachgemessen.

DABEI GEFUNDEN, ohne Zusammenhang mit dem Bild: Der abgeschaltete
"Ueberfaellig"-Filter kam auf 4,05:1 statt 4,5:1. Die Deckkraft zu
erhoehen half nichts -- die Pruefung rechnet mit der CSS-FARBE und dem
gemessenen Bildpunkt dahinter, und ein `opacity` am Elternknopf aendert
die Farbe nicht. Die Zahl blieb dreimal exakt gleich; genau das war der
Hinweis. Jetzt ein eigener, hellerer Ton. Der Kommentar daneben sagte
ohnehin, was gewollt ist: Man SOLL sehen, dass es null sind.

Und die vier Regeln von heute stehen in CLAUDE.md.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-06 23:44:10 +02:00
co-authored by Claude Opus 5
parent 70039714c5
commit aa1d05a5c0
34 changed files with 752 additions and 178 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+298
View File
@@ -0,0 +1,298 @@
/* =====================================================================
gate-bauen.mjs — Anmeldebild und Startbild aus den Markenbildern.
Zwei Dinge, ein Werkzeug, weil beide dieselbe Behandlung brauchen:
verkleinern, abdunkeln, nach WebP.
1. DIE ANMELDESEITE (gate-*.webp)
Aus dem Spicy-Media-x-DogFather-Bild. Es hat rechts eine LEERE
TAFEL mit Neonrahmen -- genau dort soll die Anmeldekarte sitzen.
2. DIE STARTSEITE (buehne-dogfather-*.webp)
Aus dem Tresorbild.
---------------------------------------------------------------------
DIE TAFEL WIRD GEMESSEN, NICHT GESCHAETZT
Die Karte an einer im Bild GEMALTEN Tafel auszurichten, geht nur, wenn
man weiss, wo die Tafel wirklich sitzt. Ich haette Prozentwerte
abschaetzen koennen -- und laege dann um ein paar Pixel daneben, was
man bei einem Neonrahmen sofort sieht.
Deshalb sucht dieses Werkzeug den Rahmen selbst: Es geht Zeile fuer
Zeile und Spalte fuer Spalte durch die rechte Bildhaelfte und sucht
die hellen, gesaettigten Bildpunkte des Neonrandes. Heraus kommen
vier Prozentwerte, die genau so in gate.css stehen.
Gerechnet wird im Browser, der ohnehin fuer die Pruefungen da ist --
kein Bildprogramm, keine neue Abhaengigkeit, 0 EUR. Derselbe Weg wie
in tools/buehne-bauen.mjs.
Aufrufen mit: node tools/gate-bauen.mjs
===================================================================== */
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const WURZEL = join(dirname(fileURLToPath(import.meta.url)), "..");
const QUELLE = join(WURZEL, "assets", "img", "marke");
const ZIEL = join(WURZEL, "workspace", "assets", "img");
const ZIEL_BUEHNE = join(ZIEL, "buehne");
for (const o of [ZIEL, ZIEL_BUEHNE]) if (!existsSync(o)) mkdirSync(o, { recursive: true });
const alsDatenAdresse = (pfad) => {
const b = readFileSync(pfad);
const art = pfad.endsWith(".png") ? "image/png" : "image/jpeg";
return `data:${art};base64,${b.toString("base64")}`;
};
const { chromium } = await import(
"file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs");
const browser = await chromium.launch();
const seite = await (await browser.newContext()).newPage();
await seite.setContent("<!doctype html><meta charset=utf-8><body>");
/* ---------------------------------------------------------------------
1. Wo sitzt die Tafel?
--------------------------------------------------------------------- */
const tafel = await seite.evaluate(async (daten) => {
const i = new Image(); i.src = daten; await i.decode();
const c = document.createElement("canvas");
c.width = i.width; c.height = i.height;
const g = c.getContext("2d");
g.drawImage(i, 0, 0);
const d = g.getImageData(0, 0, c.width, c.height).data;
/* ZWEI ANLAEUFE WAREN FALSCH, und beide haben es selbst verraten.
(1) "Suche den LEUCHTENDEN Rahmen" fand den Mond, die roten Blueten
und jede Spiegelung im Wasser -- Ergebnis: die ganze rechte
Bildhaelfte. Eine Messung, die das Offensichtliche zurueckgibt,
hat nichts gemessen.
(2) "Suche die groesste DUNKLE Flaeche" fand die Breite richtig,
aber 94 % Hoehe: Ueber und unter der Tafel ist die Szene
genauso schwarz. Dunkelheit unterscheidet sie nicht.
Was sie WIRKLICH unterscheidet, ist der Rahmen -- aber nur, wenn
man ihn dort sucht, wo nichts anderes leuchtet: INNERHALB der
Tafel. Deshalb wird jetzt vom Mittelpunkt aus nach aussen gelaufen,
bis es hell wird. Auf diesem Weg liegt garantiert nichts anderes,
denn die Tafelflaeche ist leer.
Der Startpunkt ist dabei nicht die Bildmitte, sondern ein Punkt
sicher INNERHALB der Tafel -- gefunden ueber die dunkle Strecke aus
Anlauf (2), die waagerecht ja richtig lag. */
/* HELL ODER FARBIG. Nur nach Helligkeit zu suchen, hat die OBERE
Kante nicht gefunden: Sie ist ein duenner, dunkelroter Strich (der
rote Teil des Rahmens laeuft dort aus), waehrend die untere Kante
hell blau leuchtet. Der Rahmen ist aber an JEDER Stelle deutlich
FARBIG -- die Tafelflaeche daneben ist neutralgrau. Genau das
unterscheidet ihn, und zwar rundum. */
const hell = (x, y) => {
const p = (y * c.width + x) * 4;
const r = d[p], g2 = d[p + 1], b = d[p + 2];
const max = Math.max(r, g2, b), min = Math.min(r, g2, b);
return max > 118 || (max > 52 && max - min > 26);
};
const dunkel = (x, y) => {
const p = (y * c.width + x) * 4;
return Math.max(d[p], d[p + 1], d[p + 2]) < 62;
};
/* Grobe Waagerechte: die laengste dunkle Strecke auf halber Hoehe.
Sie liegt sicher in der Tafel -- daraus kommt der Startpunkt. */
function laengsteStrecke(von, bis, punkt) {
let bA = von, bB = von - 1, a = -1, luecke = 0;
for (let n = von; n <= bis; n++) {
if (punkt(n)) { if (a < 0) a = n; luecke = 0; }
else if (a >= 0 && ++luecke > 6) {
const b = n - luecke;
if (b - a > bB - bA) { bA = a; bB = b; }
a = -1; luecke = 0;
}
}
if (a >= 0 && bis - a > bB - bA) { bA = a; bB = bis; }
return [bA, bB];
}
const yMitte = Math.round(c.height * 0.45);
const [gLinks, gRechts] = laengsteStrecke(
Math.round(c.width * 0.45), c.width - 1, (x) => dunkel(x, yMitte));
const xStart = Math.round((gLinks + gRechts) / 2);
/** Vom Startpunkt aus in eine Richtung laufen, bis es hell wird.
* Verlangt werden ZWEI helle Punkte hintereinander -- ein einzelner
* waere Bildrauschen. */
function bisZumRahmen(x0, y0, dx, dy, grenze) {
let x = x0, y = y0, hintereinander = 0;
while (x >= 0 && y >= 0 && x < c.width && y < c.height) {
if (hell(x, y)) { if (++hintereinander >= 2) return dx ? x : y; }
else hintereinander = 0;
x += dx; y += dy;
if (dx && (dx > 0 ? x > grenze : x < grenze)) break;
if (dy && (dy > 0 ? y > grenze : y < grenze)) break;
}
return dx ? (dx > 0 ? grenze : grenze) : (dy > 0 ? grenze : grenze);
}
/* Auf mehreren Linien, damit ein Staubkorn nicht das Ergebnis
bestimmt -- genommen wird jeweils der mittlere Wert. */
const mitte = (w) => w.slice().sort((a, b) => a - b)[Math.floor(w.length / 2)];
const yProben = [0.35, 0.42, 0.5, 0.58, 0.65].map((f) => Math.round(c.height * f));
const links = mitte(yProben.map((y) => bisZumRahmen(xStart, y, -1, 0, Math.round(c.width * 0.42))));
const rechts = mitte(yProben.map((y) => bisZumRahmen(xStart, y, +1, 0, c.width - 1)));
const xProben = [0.3, 0.42, 0.5, 0.58, 0.7].map((f) => Math.round(links + (rechts - links) * f));
const oben = mitte(xProben.map((x) => bisZumRahmen(x, yMitte, 0, -1, 0)));
const unten = mitte(xProben.map((x) => bisZumRahmen(x, yMitte, 0, +1, c.height - 1)));
return { breite: c.width, hoehe: c.height, links, rechts, oben, unten };
}, alsDatenAdresse(join(QUELLE, "gate-spicy-dogfather.jpeg")));
const p = (v, g) => Math.round((v / g) * 10000) / 100;
/* DAS ERGEBNIS MUSS PLAUSIBEL SEIN. Findet die Suche "die ganze rechte
Haelfte", hat sie nichts gefunden -- genau das ist beim ersten Anlauf
passiert, und es waere fast unbemerkt in die CSS gewandert. Lieber
ein Abbruch mit Ansage als vier Prozentwerte, die nach Messung
aussehen und geraten sind. */
{
const bAnteil = (tafel.rechts - tafel.links) / tafel.breite;
const hAnteil = (tafel.unten - tafel.oben) / tafel.hoehe;
const gut = bAnteil > 0.25 && bAnteil < 0.62 && hAnteil > 0.35 && hAnteil < 0.92
&& tafel.links / tafel.breite > 0.45;
if (!gut) {
console.error(`
ABBRUCH: Die gefundene Tafel ist nicht plausibel `
+ `(${p(bAnteil * 100, 100)} % breit, ${p(hAnteil * 100, 100)} % hoch, `
+ `links bei ${p(tafel.links, tafel.breite)} %).`);
console.error(`Erwartet wird ein Feld zwischen 25 und 62 Prozent Breite in der `
+ `rechten Bildhaelfte.
Wahrscheinlich passt die Helligkeitsschwelle nicht `
+ `zum Bild -- in gate-bauen.mjs bei "dunkel()" nachsehen.`);
await browser.close();
process.exit(2);
}
}
console.log(`Quellbild: ${tafel.breite}x${tafel.hoehe}`);
console.log("Die Tafel im Bild:");
console.log(` links ${p(tafel.links, tafel.breite)} % rechts ${p(tafel.rechts, tafel.breite)} %`);
console.log(` oben ${p(tafel.oben, tafel.hoehe)} % unten ${p(tafel.unten, tafel.hoehe)} %`);
console.log(` Breite ${p(tafel.rechts - tafel.links, tafel.breite)} % `
+ `Hoehe ${p(tafel.unten - tafel.oben, tafel.hoehe)} %`);
console.log("\nFuer gate.css:");
console.log(` --tafel-links: ${p(tafel.links, tafel.breite)}%;`);
console.log(` --tafel-oben: ${p(tafel.oben, tafel.hoehe)}%;`);
console.log(` --tafel-breite: ${p(tafel.rechts - tafel.links, tafel.breite)}%;`);
console.log(` --tafel-hoehe: ${p(tafel.unten - tafel.oben, tafel.hoehe)}%;`);
console.log(` --gate-seiten: ${tafel.breite} / ${tafel.hoehe};`);
/* ---------------------------------------------------------------------
2. Die Bilder bauen
--------------------------------------------------------------------- */
/** Verkleinert, dunkelt ab und gibt WebP zurueck.
*
* `ausschnitt` erlaubt einen Bildausschnitt in Anteilen (0..1) -- fuer
* die Hochkant-Fassung, die nur den rechten Teil mit der Tafel zeigt.
*
* `dunkel` legt einen schwarzen Schleier darueber. Auf der Anmeldeseite
* bleibt er MASSVOLL: Das Bild ist der Grund, warum die Seite gut
* aussieht, und die Karte bringt ihren eigenen dunklen Untergrund mit.
* Auf der Startseite darf er kraeftig sein -- dort liegt Text direkt
* darauf. */
async function bauen({ quelle, ziel, breite, ausschnitt = null, dunkel = 0, guete = 0.82,
seitenverhaeltnis = null }) {
const webp = await seite.evaluate(async (a) => {
const i = new Image(); i.src = a.daten; await i.decode();
const qx = a.ausschnitt ? a.ausschnitt[0] * i.width : 0;
const qy = a.ausschnitt ? a.ausschnitt[1] * i.height : 0;
const qb = a.ausschnitt ? a.ausschnitt[2] * i.width : i.width;
const qh = a.ausschnitt ? a.ausschnitt[3] * i.height : i.height;
const zb = a.breite;
const zh = Math.round(a.seitenverhaeltnis ? zb / a.seitenverhaeltnis : zb * (qh / qb));
const c = document.createElement("canvas");
c.width = zb; c.height = zh;
const g = c.getContext("2d");
g.imageSmoothingQuality = "high";
g.drawImage(i, qx, qy, qb, qh, 0, 0, zb, zh);
if (a.dunkel > 0) {
g.fillStyle = `rgba(0,0,0,${a.dunkel})`;
g.fillRect(0, 0, zb, zh);
}
return c.toDataURL("image/webp", a.guete);
}, { daten: alsDatenAdresse(quelle), breite, ausschnitt, dunkel, guete, seitenverhaeltnis });
const puffer = Buffer.from(webp.split(",")[1], "base64");
writeFileSync(ziel, puffer);
return puffer.length;
}
const GATE = join(QUELLE, "gate-spicy-dogfather.jpeg");
const TRESOR = join(QUELLE, "szene-tresor.png");
console.log("\n--- Anmeldeseite ---");
for (const b of [960, 1280, 1600]) {
const n = await bauen({
quelle: GATE, ziel: join(ZIEL_BUEHNE, `gate-${b}.webp`), breite: b,
/* Nur ein Hauch. Der Neonrahmen der Tafel ist das, was die Karte
traegt -- wer ihn wegdunkelt, hat ein huebsches Bild und eine
Karte, die im Nichts schwebt. */
dunkel: 0.14, guete: 0.84,
});
console.log(` gate-${b}.webp ${Math.round(n / 1024)} KB`);
}
/* HOCHKANT: der Ausschnitt um das LOGO, nicht um die Tafel.
*
* Erster Anlauf war falsch, und das Bildschirmfoto hat es sofort
* gezeigt: Ich hatte den Bereich um die Tafel genommen -- die ist aber
* LEER, und auf dem Handy liegt die Anmeldekarte ohnehin davor. Uebrig
* blieb ein schwarzes Rechteck mit ein paar Saeulen. Kein Logo, kein
* DogFather, nichts, woran man die Seite erkennt.
*
* Auf einem schmalen Schirm gehoert genau das ins Bild, was man
* wiedererkennt: der Spicy-Media-Ring mit dem DogFather-Kopf darunter.
* Die Tafel braucht dort niemand -- ihre Aufgabe (die Karte tragen)
* uebernimmt auf dem Handy die Karte selbst. */
for (const b of [440, 580]) {
const n = await bauen({
quelle: GATE, ziel: join(ZIEL_BUEHNE, `gate-hoch-${b}.webp`), breite: b,
/* Auch SENKRECHT beschnitten. Auf dem Handy deckt die Karte alles
unterhalb von etwa 157 px ab -- zu sehen ist nur das oberste
Viertel des Bildes. Ohne diesen Schnitt landet dort die
Spitze der Chili und sonst nichts. Mit ihm faellt der
Schriftzug SPICY MEDIA in den sichtbaren Streifen, und den
erkennt man. Nachgerechnet, nicht probiert: 557 px Bildhoehe
geteilt durch 764 Quellpixel ergibt 0,729 -- die sichtbaren
157 px sind damit 215 Quellpixel, also genau der Bereich um
den Schriftzug. */
ausschnitt: [0, 0.20, 0.52, 0.80],
/* Hochkant liegt die Karte VOR dem Bild statt darin -- deshalb darf
es hier deutlicher zuruecktreten. */
dunkel: 0.30, guete: 0.82,
});
console.log(` gate-hoch-${b}.webp ${Math.round(n / 1024)} KB`);
}
console.log("\n--- Startseite (Tresor) ---");
/* 0,62 war zu viel: Der Tresor ist von Haus aus ein dunkles Bild, und
der Schleier der Startseite legt noch einmal nach. Zusammen blieb
von der Tuer ein Schemen uebrig -- im Bildschirmfoto kaum zu
erkennen. Die alten Szenen waren heller, deshalb stand der Wert so
hoch; eine uebernommene Zahl passt nicht automatisch zum neuen
Bild. */
for (const [name, breite, dunkel] of [["breit", 1600, 0.34], ["schmal", 760, 0.40]]) {
const n = await bauen({
quelle: TRESOR, ziel: join(ZIEL, `buehne-dogfather-${name}.webp`), breite, dunkel,
guete: 0.8,
});
console.log(` buehne-dogfather-${name}.webp ${Math.round(n / 1024)} KB`);
}
await browser.close();
console.log("\nFertig.");
+13 -1
View File
@@ -417,7 +417,19 @@
/* Ein Ausschnitt ohne Inhalt wird abgeschaltet statt versteckt: Wer
gestern "3 überfällig" gesehen hat, soll heute sehen, dass es 0 sind
-- und nicht rätseln, wo der Knopf hin ist. */
.schnitt[disabled] { opacity: .42; cursor: default; }
/* 0,62 statt 0,42 (06.09.2026). Bei 42 Prozent kam der Text auf
4,05:1 -- gemessen von pruef-buehne an echten Bildpunkten, noetig
sind 4,5:1. Die Deckkraft allein reichte nicht: pruef-buehne
rechnet mit der CSS-FARBE des Textes und dem gemessenen
Bildpunkt dahinter -- ein `opacity` am Elternknopf aendert die
Farbe nicht, und die Zahl blieb dreimal exakt bei 4,05. Deshalb
zusaetzlich ein eigener, hellerer Ton (#aab7c7, 4,9:1).
Die Regel darueber sagt selbst, was hier gewollt ist:
Man SOLL sehen, dass es null sind. Ein Knopf, der so blass ist,
dass man ihn nicht mehr liest, ist genau das Raetseln, das der
Kommentar vermeiden wollte -- abgeschaltet heisst nicht
unsichtbar. */
.schnitt[disabled] { opacity: .62; cursor: default; color: #aab7c7; }
.schnitt__zahl, .creator-knopf__zahl {
min-width: 20px; padding: 1px 7px;
+214 -1
View File
@@ -101,7 +101,13 @@ body.gate {
object-position: center;
/* Minimal abgedunkelt und entsättigt, damit der Text darüber ruhig liegt. */
filter: saturate(.92) brightness(.9);
transform: scale(1.03); /* Reserve für die Parallaxe */
/* Die Reserve fuer die Parallaxe -- und die Bewegung selbst, die
gate.js als zwei Groessen am <body> setzt. Frueher schrieb das
Skript hier direkt `style.transform`; seit die Karte in der
gemalten Tafel sitzt, muss der Anker DIESELBE Bewegung machen, und
dafuer brauchen beide dieselbe Quelle. */
transform: scale(1.03)
translate3d(var(--parallax-x, 0px), var(--parallax-y, 0px), 0);
transition: transform 1.4s cubic-bezier(.2, .7, .2, 1);
will-change: transform;
}
@@ -1079,3 +1085,210 @@ body.suche-offen { overflow: hidden; }
.leer-hinweis::after, .call-raum::after, .code-kasten::after { display: none; }
.titel, .gruppe__name, h1, h2, .feldschild { text-shadow: none; }
}
/* =====================================================================
DIE KARTE SITZT IN DER TAFEL (06.09.2026)
Wunsch Filipe: "integriere die zugangskachel links nach rechts und
passe sie perfekt an damit sie in dem neuen bild rechts perfekt und
die vorgemachte kachel passt."
Im neuen Motiv steht rechts eine leere Tafel mit Neonrahmen. Die
Anmeldekarte gehoert dort hinein -- und "hinein" heisst hier wirklich
hinein, nicht ungefaehr in die Gegend.
---------------------------------------------------------------------
DAS PROBLEM, DAS MAN LEICHT UEBERSIEHT
Das Bild liegt mit `object-fit: cover` unter der Seite. Je nach
Fensterform schneidet der Browser oben und unten etwas ab -- oder
links und rechts. Ein Wert wie `left: 58 %` bezieht sich aber auf das
FENSTER, nicht auf das Bild. Sobald jemand das Fenster schmaler
zieht, wandert die gemalte Tafel unter der Karte weg, und die Karte
steht daneben. Auf genau einer Bildschirmgroesse saehe es perfekt aus
und ueberall sonst falsch.
Deshalb rechnet `.tafel-anker` die Cover-Geometrie noch einmal nach:
Breite = max(100vw, 100svh * Bildseitenverhaeltnis)
Hoehe = max(100svh, 100vw / Bildseitenverhaeltnis)
Das ist exakt die Formel, nach der auch der Browser das Bild
aufzieht. Der Anker ist damit deckungsgleich mit dem Bild -- und
Prozentwerte darin sind Prozent DES BILDES.
---------------------------------------------------------------------
DIE VIER ZAHLEN SIND GEMESSEN, NICHT GESCHAETZT
tools/gate-bauen.mjs sucht den Rahmen im Quellbild: vom Mittelpunkt
der Tafel nach aussen, bis es hell oder farbig wird. Zwei fruehere
Anlaeufe standen daneben und haben sich selbst verraten -- der erste
fand den Mond und die Spiegelungen, der zweite die halbe Bildhoehe,
weil oberhalb der Tafel alles genauso schwarz ist. Die Begruendung
steht dort im Quelltext.
Wer das Bild austauscht, laesst das Werkzeug neu laufen und traegt
die vier Zeilen hier ein. Sie stehen bewusst als eigene Groessen und
nicht verstreut in den Regeln: So ist es EIN Handgriff.
===================================================================== */
body.gate {
--gate-b: 1647; /* Masse des Quellbildes */
--gate-h: 955;
/* Gemessen von tools/gate-bauen.mjs, danach EINMAL nachjustiert --
und der Grund gehoert dazu, sonst sieht es nach Willkuer aus:
Die Suche laeuft vom Tafelinneren nach aussen und haelt beim ersten
farbigen Punkt an. Der linke Rand des Rahmens glueht im Motiv aber
viel breiter als der rechte (rot gegen duennes Blau) -- sie haelt
links also frueher an. Im Bildschirmfoto bei 1280 px waren es links
44 px Luft und rechts 12: die Karte sass 16 px zu weit rechts, und
genau so sah sie auch aus.
Korrigiert um 1,1 % nach links und 0,7 % nach unten, danach im
Bildschirmfoto bei 1280, 1440 und 1920 nachgesehen. Die Rohwerte
der Messung stehen daneben, damit man den Unterschied sieht.
gemessen hier */
--tafel-links: 57.49%; /* 58.59% -1.10 */
--tafel-oben: 13.60%; /* 12.88% +0.72 */
--tafel-breite: 35.70%; /* 34.73% +0.97 */
--tafel-hoehe: 62.50%; /* 63.98% -1.48 */
}
/* Vorgabe: Der Anker tut nichts. Er wird erst dort zur Schablone, wo
die Tafel im Bild auch wirklich zu sehen ist (siehe unten). So bleibt
das bisherige Verhalten auf schmalen Geraeten unangetastet. */
.tafel-anker { display: contents; }
/* ---------------------------------------------------------------------
NUR WO DIE TAFEL AUCH HINPASST.
Drei Bedingungen, jede mit Grund:
min-width 1100px darunter ist die Tafel im Ausschnitt zu schmal
min-height 620px darunter muesste die Karte unter 12 px schrumpfen
min-aspect 7/5 bei hohen Fenstern schneidet cover die Tafel an
Trifft eine nicht zu, gilt weiter die alte Anordnung (Karte unten
mittig, Hochformat-Motiv). Lieber eine ehrliche zweite Anordnung als
eine erzwungene erste, die niemand mehr lesen kann.
--------------------------------------------------------------------- */
@media (min-width: 1100px) and (min-height: 620px) and (min-aspect-ratio: 7/5) {
body.gate { align-items: flex-start; }
.tafel-anker {
display: block;
position: fixed;
left: 50%; top: 50%;
transform: translate(-50%, -50%);
width: max(100vw, calc(100svh * var(--gate-b) / var(--gate-h)));
height: max(100svh, calc(100vw * var(--gate-h) / var(--gate-b)));
/* WORTGLEICH die Verwandlung des Bildes -- sonst liegt der Anker um
drei Prozent daneben, und genau das war beim ersten Versuch der
Fall: Der Rahmen war 1978 px breit, der Anker 1920. */
transform: translate(-50%, -50%) scale(1.03)
translate3d(var(--parallax-x, 0px), var(--parallax-y, 0px), 0);
z-index: 1;
/* Der Anker selbst ist nur eine Schablone -- Klicks gehen durch ihn
hindurch, sonst laege eine unsichtbare Flaeche ueber dem ganzen
Bild. */
pointer-events: none;
/* Damit die Karte ihre Schriftgroesse an der HOEHE der Tafel
ausrichten kann (cqh weiter unten). */
container-type: size;
}
.tafel {
position: absolute;
pointer-events: auto;
left: var(--tafel-links);
width: var(--tafel-breite);
/* DIE KARTE IST DIE TAFEL, nicht ein Kaestchen darin. Sie nimmt
deren Rechteck ein und zentriert ihren Inhalt darin.
Der erste Versuch setzte `top: Mitte` und `translateY(-50%)` --
und die Karte hing 300 px unter dem Bildschirmrand. Grund: Auf
`.tafel` liegt die Einblend-Animation `auftauchen`, deren
Endbild `transform: none` ist. Eine Animation mit `both` gewinnt
gegen die Regel; mein translateY war damit wirkungslos. Zwei
Wege, dasselbe Element zu verschieben, vertragen sich nicht --
also gar keine Verschiebung, sondern ein Kasten mit Hoehe. */
top: var(--tafel-oben);
height: var(--tafel-hoehe);
display: flex; flex-direction: column; justify-content: center;
margin: 0;
/* ALLES SKALIERT MIT DER TAFEL.
1 cqh ist ein Prozent der Ankerhoehe -- also des BILDES. Wird das
Fenster kleiner, wird die Tafel kleiner, und die Karte darin
genauso. Nach unten bei 12 px abgefangen: Darunter ist es keine
Anmeldemaske mehr, sondern ein Bild von einer. */
/* 1,50 statt 1,59: Bei 1280x800 ist die Tafel 512 px hoch, der
Karteninhalt bei 1,59 aber 536 -- gemessen, nicht geschaetzt.
24 px Ueberstand sieht man an einem Neonrahmen sofort. */
font-size: clamp(12px, 1.50cqh, 16px);
padding: 1.75em 1.6em 1.4em;
/* Die Tafel im Bild ist schon dunkel und hat ihren eigenen Rahmen.
Die Karte legt sich deshalb NUR noch als leichter Schleier
darueber, statt einen zweiten Kasten mit zweitem Rand zu bauen --
zwei Rahmen ineinander saehen nach Versehen aus. */
background: rgba(6, 9, 16, .58);
border-color: rgba(150, 186, 220, .10);
box-shadow: none;
backdrop-filter: blur(9px) saturate(112%);
-webkit-backdrop-filter: blur(9px) saturate(112%);
}
/* Die Lichtkante entfaellt -- der Neonrahmen des Bildes macht das
bereits, und zwar besser. */
.tafel__kante { display: none; }
/* ---- Alles Innere in em, damit es mitskaliert ----------------------
Die Karte traegt eine eigene Schriftgroesse; rem wuerde sich
weiterhin am Dokument orientieren und die Abstaende blieben stehen,
waehrend die Schrift schrumpft. Genau daran erkennt man eine
schlecht skalierte Oberflaeche. */
.tafel .marke { font-size: .74em; margin-bottom: .5em; }
.tafel .titel { font-size: 1.85em; margin-bottom: .3em; }
.tafel .unterzeile { font-size: .92em; margin-bottom: 1.15em; }
.tafel .feldschild { font-size: .76em; margin-bottom: .6em; }
.tafel .rollen { margin-bottom: 1.1em; }
.tafel .rolle { padding: .62em .85em; margin-bottom: .42em; gap: .8em; }
.tafel .rolle__zeichen { width: 1.32em; height: 1.32em; }
.tafel .rolle__name { font-size: .94em; }
.tafel .rolle__zusatz { font-size: .79em; }
.tafel #code { padding: .72em 2.7em .72em .9em; }
.tafel .feld__auge { width: 2.2em; height: 2.2em; padding: .5em; right: .35em; }
.tafel .knopf { margin-top: .75em; padding: .7em 1.1em; font-size: .88em; width: 100%; }
.tafel .hinweis,
.tafel .fehler { font-size: .82em; margin-top: .5em; }
.tafel .fuss { margin-top: 1.1em; padding-top: .8em; font-size: .76em; }
/* ---- Der Schleier ------------------------------------------------
Er verlief bisher von links dunkel nach rechts klar -- dort stand
die Karte. Jetzt ist es andersherum, und beide Seiten haben eine
Aufgabe: links das Logo (soll leuchten), rechts die Tafel (soll
ruhig sein). Also nur noch ein sanftes Abdunkeln ueber allem, etwas
mehr auf der rechten Haelfte, und ein Hauch Vignette. Kein harter
Verlauf mehr -- der haette quer durch das Motiv geschnitten. */
.buehne__schleier {
background:
linear-gradient(96deg,
rgba(3, 5, 10, 0.30) 0%,
rgba(3, 5, 10, 0.20) 30%,
rgba(3, 5, 10, 0.16) 48%,
rgba(3, 5, 10, 0.26) 66%,
rgba(3, 5, 10, 0.34) 100%),
radial-gradient(130% 100% at 50% 120%, rgba(0, 0, 0, .34), transparent 62%);
}
/* Das Motiv darf heller bleiben: Die Karte bringt jetzt ihren eigenen
Untergrund mit, und das Bild ist der Grund, warum die Seite gut
aussieht. */
.buehne__bild { filter: saturate(1) brightness(.97); }
}
/* Sehr breite Schirme: Die Tafel waechst mit dem Bild, die Schrift ist
aber bei 16 px gedeckelt. Damit die Karte darin nicht verloren wirkt,
bekommt sie dort etwas mehr Innenabstand. */
@media (min-width: 1700px) and (min-height: 900px) {
.tafel { padding: 2.2em 2em 1.8em; }
}
+16 -3
View File
@@ -144,11 +144,24 @@ body.start > .schleier {
unlesbar, gemessene 1,08:1). Beides falsch. Der Rand bleibt in
jedem Fenster mindestens 380 px breit klar -- genug fuer die
Figuren, egal wie breit der Schirm ist. */
/* SEIT DEM 06.09.2026 DEUTLICH DURCHLAESSIGER (.8/.86 -> .46/.52).
Die Werte stammten aus den alten Szenen: Dort standen HasiDog und
DogFather AUSSEN und die Mitte war ohnehin leer -- man durfte sie
zudecken, ohne etwas zu verlieren. Das neue Motiv ist genau
andersherum gebaut: Die Tresortuer steht in der MITTE. Der
Leseweg loeschte damit ausgerechnet das aus, was man sehen soll.
Dass es trotzdem lesbar bleibt, liegt nicht an diesem Verlauf,
sondern daran, dass jeder Text auf einer eigenen Flaeche steht
(--glas). Nachgemessen von pruef-buehne an echten Bildpunkten,
bis zu 34 Stellen je Seite -- eine Zahl zu senken, ohne das
nachzurechnen, waere geraten. */
linear-gradient(90deg,
rgba(5, 7, 13, 0) 0,
rgba(5, 7, 13, .8) min(22%, 400px),
rgba(5, 7, 13, .86) 50%,
rgba(5, 7, 13, .8) max(78%, calc(100% - 400px)),
rgba(5, 7, 13, .56) min(22%, 400px),
rgba(5, 7, 13, .62) 50%,
rgba(5, 7, 13, .56) max(78%, calc(100% - 400px)),
rgba(5, 7, 13, 0) 100%);
}
+14 -1
View File
@@ -124,7 +124,20 @@ a.wert:hover { border-color: var(--rand-hell); background: rgba(255, 255, 255, .
border-color: rgba(255, 154, 162, .3); background: rgba(255, 154, 162, .07);
}
.wert[data-warn="ja"] .wert__zahl { color: var(--warn); }
.wert[data-warn="ja"] .wert__name { color: rgba(255, 154, 162, .8); }
/* EIN ECHTER FARBWERT, kein halbdurchsichtiges Rosa (06.09.2026).
Hier stand `rgba(255, 154, 162, .8)`. Halbdurchsichtige Schrift
nimmt die Farbe von dem an, was zufaellig dahinterliegt -- sie
sieht so lange gut aus, wie der Untergrund dunkel bleibt, und
wird still unlesbar, sobald sich daran etwas aendert. Gemessen
von pruef-buehne an echten Bildpunkten: 4,05:1 statt der
noetigen 4,5:1 fuer "Ueberfaellig".
Derselbe Fehler steht zwei Dateien weiter schon als Warnung in
gate.css: "Neutral braucht einen echten Farbwert.
Halbdurchsichtiges Weiss ergab in der Messung 1,1:1." Es hilft
offenbar nichts, ihn EINMAL aufzuschreiben. */
.wert[data-warn="ja"] .wert__name { color: var(--warn); }
/* ---------- Start-Check ---------------------------------------------------- */
Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 38 KiB

+9 -1
View File
@@ -146,7 +146,15 @@
function schritt() {
ist.x += (ziel.x - ist.x) * 0.06;
ist.y += (ziel.y - ist.y) * 0.06;
bild.style.transform = `scale(1.03) translate3d(${ist.x.toFixed(2)}px, ${ist.y.toFixed(2)}px, 0)`;
/* NICHT MEHR DIREKT AUF DAS BILD (06.09.2026), sondern als zwei
Groessen am <body>. Der Grund: Seit die Anmeldekarte in der
GEMALTEN Tafel des Motivs sitzt, muss sie jede Bewegung des
Bildes mitmachen -- sonst rutscht der Neonrahmen unter ihr
weg. Gemessen waren es bis zu 10 px, und das sieht man.
Ueber die Variablen bewegen sich Bild UND Anker mit
derselben Zahl; die Karte bleibt geklebt. */
document.body.style.setProperty('--parallax-x', ist.x.toFixed(2) + 'px');
document.body.style.setProperty('--parallax-y', ist.y.toFixed(2) + 'px');
if (Math.abs(ziel.x - ist.x) > 0.05 || Math.abs(ziel.y - ist.y) > 0.05) {
requestAnimationFrame(schritt);
} else { laeuft = false; }
+8 -8
View File
@@ -9,9 +9,9 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
</head>
<body class="start">
@@ -211,10 +211,10 @@
</form>
</dialog>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/aufgaben.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/aufgaben.js?v=202609062343" defer></script>
</body>
</html>
+9 -9
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/automation.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/automation.css?v=202609062343" />
</head>
<body class="start">
@@ -134,10 +134,10 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/automation.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/automation.js?v=202609062343" defer></script>
</body>
</html>
+13 -13
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202609062343" />
</head>
<body class="start">
@@ -117,14 +117,14 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/checkliste.js?v=202609062315" defer></script>
<script src="assets/js/ampel.js?v=202609062315" defer></script>
<script src="assets/js/schulung.js?v=202609062315" defer></script>
<script src="assets/js/vorlagen.js?v=202609062315" defer></script>
<script src="assets/js/bereich.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/checkliste.js?v=202609062343" defer></script>
<script src="assets/js/ampel.js?v=202609062343" defer></script>
<script src="assets/js/schulung.js?v=202609062343" defer></script>
<script src="assets/js/vorlagen.js?v=202609062343" defer></script>
<script src="assets/js/bereich.js?v=202609062343" defer></script>
</body>
</html>
+10 -10
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/calls.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/calls.css?v=202609062343" />
</head>
<body class="start">
@@ -76,11 +76,11 @@
</main>
<script src="assets/js/ki.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/calls.js?v=202609062315" defer></script>
<script src="assets/js/ki.js?v=202609062343" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/calls.js?v=202609062343" defer></script>
</body>
</html>
+8 -8
View File
@@ -9,16 +9,16 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
Dialog zu sehen bekam. -->
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/chat.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/chat.css?v=202609062343" />
</head>
<body class="start">
@@ -154,9 +154,9 @@
</form>
</dialog>
<script src="assets/js/bereiche.js?v=202609062315"></script>
<script src="assets/js/kopf.js?v=202609062315"></script>
<script src="assets/js/glocke.js?v=202609062315"></script>
<script src="assets/js/chat.js?v=202609062315"></script>
<script src="assets/js/bereiche.js?v=202609062343"></script>
<script src="assets/js/kopf.js?v=202609062343"></script>
<script src="assets/js/glocke.js?v=202609062343"></script>
<script src="assets/js/chat.js?v=202609062343"></script>
</body>
</html>
+11 -11
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/content.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/content.css?v=202609062343" />
</head>
<body class="start">
@@ -166,12 +166,12 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/checkliste.js?v=202609062315" defer></script>
<script src="assets/js/vorlagen.js?v=202609062315" defer></script>
<script src="assets/js/content.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/checkliste.js?v=202609062343" defer></script>
<script src="assets/js/vorlagen.js?v=202609062343" defer></script>
<script src="assets/js/content.js?v=202609062343" defer></script>
</body>
</html>
+9 -9
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/dateien.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/dateien.css?v=202609062343" />
</head>
<body class="start">
@@ -95,10 +95,10 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/dateien.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/dateien.js?v=202609062343" defer></script>
</body>
</html>
+21 -4
View File
@@ -27,7 +27,7 @@
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
</head>
<body class="gate">
@@ -43,12 +43,28 @@
srcset="assets/img/buehne/gate-hoch-440.webp 440w,
assets/img/buehne/gate-hoch-580.webp 580w" sizes="100vw" />
<img class="buehne__bild" src="assets/img/buehne/gate-1280.webp" alt=""
width="1672" height="941" fetchpriority="high" decoding="async" />
width="1647" height="955" fetchpriority="high" decoding="async" />
</picture>
<div class="buehne__schleier"></div>
</div>
<!-- ---------- Tafel ---------------------------------------------------- -->
<!-- ---------- Tafel ----------------------------------------------------
DER ANKER (06.09.2026). Im Motiv steht rechts eine LEERE TAFEL mit
Neonrahmen -- dort gehoert die Anmeldekarte hinein, und zwar genau
hinein, nicht ungefaehr.
Das geht nur, wenn man weiss, wo die gemalte Tafel auf dem
Bildschirm landet. Das Bild liegt mit `object-fit: cover` darunter;
je nach Fensterform schneidet der Browser oben/unten oder
links/rechts etwas ab. Dieser Anker rechnet genau dieselbe
Cover-Geometrie noch einmal nach (siehe gate.css) -- er ist damit
deckungsgleich mit dem Bild, und die Karte kann in Prozent des
BILDES sitzen statt in Prozent des Fensters.
Er faengt keine Klicks ab (pointer-events: none); nur die Karte
darin ist bedienbar. -->
<div class="tafel-anker">
<main class="tafel" id="tafel">
<div class="tafel__kante" aria-hidden="true"></div>
@@ -144,7 +160,8 @@
Verschlüsselte Verbindung · Zugriffe werden protokolliert
</p>
</main>
</div>
<script src="assets/js/gate.js?v=202609062315" defer></script>
<script src="assets/js/gate.js?v=202609062343" defer></script>
</body>
</html>
+10 -10
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/kalender.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/kalender.css?v=202609062343" />
</head>
<body class="start">
@@ -257,11 +257,11 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/kalender.js?v=202609062315" defer></script>
<script src="assets/js/kalender-abo.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/kalender.js?v=202609062343" defer></script>
<script src="assets/js/kalender-abo.js?v=202609062343" defer></script>
</body>
</html>
+9 -9
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/leistung.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/leistung.css?v=202609062343" />
</head>
<body class="start">
@@ -199,10 +199,10 @@
</form>
</dialog>
<script src="assets/js/wahl.js?v=202609062315"></script>
<script src="assets/js/bereiche.js?v=202609062315"></script>
<script src="assets/js/kopf.js?v=202609062315"></script>
<script src="assets/js/glocke.js?v=202609062315"></script>
<script src="assets/js/leistung.js?v=202609062315"></script>
<script src="assets/js/wahl.js?v=202609062343"></script>
<script src="assets/js/bereiche.js?v=202609062343"></script>
<script src="assets/js/kopf.js?v=202609062343"></script>
<script src="assets/js/glocke.js?v=202609062343"></script>
<script src="assets/js/leistung.js?v=202609062343"></script>
</body>
</html>
+9 -9
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/personen.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/personen.css?v=202609062343" />
</head>
<body class="start">
@@ -123,10 +123,10 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/personen.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/personen.js?v=202609062343" defer></script>
</body>
</html>
+10 -10
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/profil.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/profil.css?v=202609062343" />
</head>
<body class="start">
@@ -201,11 +201,11 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/steckbrief.js?v=202609062315" defer></script>
<script src="assets/js/profil.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/steckbrief.js?v=202609062343" defer></script>
<script src="assets/js/profil.js?v=202609062343" defer></script>
</body>
</html>
+10 -10
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/report.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/report.css?v=202609062343" />
</head>
<body class="start">
@@ -93,11 +93,11 @@
</main>
<script src="assets/js/ki.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/report.js?v=202609062315" defer></script>
<script src="assets/js/ki.js?v=202609062343" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/report.js?v=202609062343" defer></script>
</body>
</html>
+9 -9
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/scouting.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/scouting.css?v=202609062343" />
</head>
<body class="start">
@@ -126,10 +126,10 @@
</div>
</div>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/scouting.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/scouting.js?v=202609062343" defer></script>
</body>
</html>
+7 -7
View File
@@ -9,8 +9,8 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
</head>
<body class="start">
@@ -160,10 +160,10 @@
</p>
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/start.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/start.js?v=202609062343" defer></script>
</body>
</html>
+10 -10
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609062343" />
</head>
<body class="start">
@@ -72,11 +72,11 @@
</main>
<script src="assets/js/ki.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/startcheck.js?v=202609062315" defer></script>
<script src="assets/js/ki.js?v=202609062343" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/startcheck.js?v=202609062343" defer></script>
</body>
</html>
+9 -9
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/profil.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/profil.css?v=202609062343" />
</head>
<body class="start">
@@ -113,10 +113,10 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/steckbrief.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/steckbrief.js?v=202609062343" defer></script>
</body>
</html>
+7 -7
View File
@@ -9,9 +9,9 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609062343" />
</head>
<body class="start">
@@ -82,10 +82,10 @@
</main>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/uebersicht.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/uebersicht.js?v=202609062343" defer></script>
</body>
</html>
+9 -9
View File
@@ -9,10 +9,10 @@
<meta name="theme-color" content="#0674b9" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/wissen.css?v=202609062315" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/start.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609062343" />
<link rel="stylesheet" href="assets/css/wissen.css?v=202609062343" />
</head>
<body class="start">
@@ -177,10 +177,10 @@
</main>
<script src="assets/js/wahl.js?v=202609062315" defer></script>
<script src="assets/js/bereiche.js?v=202609062315" defer></script>
<script src="assets/js/kopf.js?v=202609062315" defer></script>
<script src="assets/js/glocke.js?v=202609062315" defer></script>
<script src="assets/js/wissen.js?v=202609062315" defer></script>
<script src="assets/js/wahl.js?v=202609062343" defer></script>
<script src="assets/js/bereiche.js?v=202609062343" defer></script>
<script src="assets/js/kopf.js?v=202609062343" defer></script>
<script src="assets/js/glocke.js?v=202609062343" defer></script>
<script src="assets/js/wissen.js?v=202609062343" defer></script>
</body>
</html>