Vertraulicher Meldeweg, klappbare Abschnitte, lila Stunden, Logos
Eine Nacht voller Auftraege von Filipe. Der Reihe nach: 1. VERTRAULICH MELDEN -- der groesste neue Teil. "es soll auch eine kategorie also eine hauptkachel geben wo die community leute sich anonym melden koennen wenn sie probleme haben ... rechte hand und dogfather sollen zugriff auf diese anonyme nachrichten haben. also anonym fuer die anderen." WICHTIG, UND ES STEHT SO AUF DER SEITE: "anonym" heisst hier VERTRAULICH. DogFather und die rechte Hand sehen den Namen -- so bestellt und auch richtig, ohne Namen kann man niemandem helfen. Anonym ist es gegenueber allen anderen: kein Modi, kein anderes Mitglied. Wer glaubt, er schreibe unerkannt, schreibt anders und fuehlt sich hinterher getaeuscht -- deshalb steht der Satz im Formular, bevor jemand tippt. Der strikte Wechsel (melden -> warten -> antworten -> warten) ist im SERVER erzwungen, nicht nur im Knopf. Ein ausgegrauter Knopf ist keine Regel. Geschlossen wird nur von der Leitung; abgeschlossene Faelle werden nach 90 Tagen samt Nachrichten geloescht -- hier stehen die empfindlichsten Texte des Hauses. Modis sind ausdruecklich AUSSEN VOR: Sehr oft geht es in diesen Meldungen um eine Moderationsentscheidung. 2. JEDE KATEGORIE LAESST SICH ZUKLAPPEN. "man soll auf dieser seite jede kategorie auf und zu klappen koennen mit einem button ... ueberall wo so eine liste entstehen kann." Das Muster gab es auf der Startseite schon; es steht jetzt als `abschnittKlappbar` in kopf.js und wird von den Brettern und dem Zeitstrahl benutzt. Die Koepfe sind echte <button> (fuer die Tastatur), der Zustand haelt in localStorage, und er haengt je Brett UND Art -- sonst waere "Regel zugeklappt" ueberall gleichzeitig zu. 3. DIE SPRUNGLEISTE SIEHT AUS WIE ETWAS ZUM ANFASSEN. Vorher unterstrichene Woerter, die aussahen wie eine Fusszeile. Jetzt Marken mit Rahmen in einem eigenen Block. 4. DIE STUNDEN SIND LILA. UMGERECHNET, NICHT NEU GEWAEHLT: Jeder der fuenf Verlaufsstopps wurde nach OKLCH zerlegt, der Farbton auf 303 Grad gedreht, zurueckgerechnet. Helligkeit und Buntheit blieben gleich -- eine frei gegriffene Palette waere heller oder bunter geworden, und die Uhr damit unruhiger. 5. DIE KARTEN "UNSERE SEITEN": babyblau und lila, mit schwebenden Logos. Beide Logos wurden zu MASKEN gerechnet (tools/logo-maske.mjs): Die PNG tragen nur Alpha, die Farbe kommt aus dem CSS. Dadurch passt dasselbe Logo in jede Kachel, egal welchen Ton sie hat -- und VanVans 378-KB- Logo wurde dabei zu 109 KB. Vier Stueck je Karte, verschieden gross, zwei Bahnen, 26 bis 41 Sekunden Umlauf. Der erste Versuch war mit 5-9 % Deckkraft praktisch unsichtbar; jetzt 10-16 %. 6. "ENTWICKLUNG" HEISST JETZT "EURE AUFGABEN". Filipe hat recht: Die Kachel fuehrt seit dem 11.09. auf den Katalog -- eine Aufgabenliste. Der Name blieb stehen, weil beim Umhaengen des Ziels niemand ihn angefasst hat. Der Name "Entwicklung" ist damit frei fuer das, was er darunter versteht (Auswertung je Person mit Verlauf und Text) -- das ist noch NICHT gebaut. DREI PRUEFUNGEN, DIE ZUFAELLIG GRUEN WAREN, sind nebenbei aufgefallen: - pruef-kachelraster wartete feste 500 ms auf eine gestaffelte Einblendung und mass vier Reihen, wo drei sind. Jetzt reducedMotion. - pruef-start-ansicht scrollte 600 px und nahm an, danach liege keine Kachel mehr unter dem Zeiger. - pruef-wege-nach-draussen zaehlte das Kachelraster ueber ALLE Gruppen statt je Gruppe. GEMESSEN: pruef-hilfe (neu) 55/0, pruef-wege-nach-draussen 64/0, pruef-jeder-hat-eine-seite 65/0, pruef-community-sicht 10/0, pruef-bereiche-lesend, pruef-steckbrief, pruef-start-ansicht, pruef-kachelraster alle gruen. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 378 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.0 MiB |
@@ -0,0 +1,132 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
DER VERTRAULICHE MELDEWEG -- Tabellen (19.09.2026)
|
||||||
|
|
||||||
|
Filipe: „es soll auch eine kategorie also eine hauptkachel geben wo
|
||||||
|
die community leute sich anonym melden können wenn sie probleme
|
||||||
|
haben. so wie ein support sie melden was und müssen dan auf die
|
||||||
|
antwort warten, dan können die erst antworten dan wieder auf antwort
|
||||||
|
von mir warten und immer so weiter bis ich es zu mache. rechte hand
|
||||||
|
und dogfather sollen zugriff auf diese anonyme nachrichten haben.
|
||||||
|
also anonym für die anderen. keiner soll sie sehen in dem sinne aber
|
||||||
|
wir sollen sehen wer die geschrieben hat, den namen."
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
„ANONYM" HEISST HIER VERTRAULICH -- UND DAS MUSS DRANSTEHEN
|
||||||
|
|
||||||
|
Der Melder ist NICHT anonym: DogFather und die rechte Hand sehen
|
||||||
|
seinen Namen, genau so hat Filipe es bestellt, und es ist auch
|
||||||
|
richtig so (ohne Namen kann man niemandem helfen und keine Maßnahme
|
||||||
|
ergreifen). Anonym ist er gegenüber allen ANDEREN -- kein anderes
|
||||||
|
Mitglied, kein Modi, niemand sonst sieht diese Fälle.
|
||||||
|
|
||||||
|
DAS IST EIN UNTERSCHIED, DER AUF DIE SEITE GEHÖRT. Wer glaubt,
|
||||||
|
niemand wisse, dass er es war, schreibt anders -- und fühlt sich
|
||||||
|
hinterher getäuscht. Der Satz „DogFather und die rechte Hand sehen
|
||||||
|
deinen Namen. Sonst niemand." steht deshalb im Formular, bevor man
|
||||||
|
tippt, und nicht im Kleingedruckten darunter.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
WARUM DER STRIKTE WECHSEL
|
||||||
|
|
||||||
|
Filipe will: melden -> warten -> antworten -> warten. Immer
|
||||||
|
abwechselnd. Das ist keine technische Einschränkung, sondern die
|
||||||
|
eigentliche Idee:
|
||||||
|
|
||||||
|
1. Es sagt IMMER, wer am Zug ist. Ein Verlauf, in den beide
|
||||||
|
jederzeit schreiben können, endet damit, dass niemand weiß, ob
|
||||||
|
noch eine Antwort kommt.
|
||||||
|
2. Es schützt den, der meldet. Wer aufgeregt ist, schreibt
|
||||||
|
sonst fünf Nachrichten hintereinander -- und liest die Antwort
|
||||||
|
dann als Reaktion auf die letzte statt auf alles.
|
||||||
|
3. Es schützt den, der antwortet. Ein Fall mit drei offenen
|
||||||
|
Fragen wird nicht beantwortet, er wird verschoben.
|
||||||
|
|
||||||
|
Geschlossen wird nur von der Leitung. Ein Fall, den der Melder
|
||||||
|
selbst zumachen kann, wird in einem schlechten Moment zugemacht.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
DIESE DATEI IMPORTIERT NICHTS -- derselbe Grund wie bei
|
||||||
|
treff-tabellen.js: Sie wird aus dem Bauplan in workspace.js
|
||||||
|
aufgerufen und darf keinen Kreis erzeugen.
|
||||||
|
===================================================================== */
|
||||||
|
|
||||||
|
/** Die drei Zustände eines Falls.
|
||||||
|
*
|
||||||
|
* Sie stehen hier und nicht als Zeichenkette an zwanzig Stellen --
|
||||||
|
* ein Tippfehler in einem `WHERE status = 'offen'` findet lautlos
|
||||||
|
* nichts.
|
||||||
|
*
|
||||||
|
* „wartet_auf_antwort" Der Melder hat geschrieben, die Leitung ist dran.
|
||||||
|
* „antwort_da" Die Leitung hat geantwortet, der Melder ist dran.
|
||||||
|
* „geschlossen" Erledigt. Nur die Leitung setzt das.
|
||||||
|
*/
|
||||||
|
export const FALL_STAND = {
|
||||||
|
wartet: "wartet_auf_antwort",
|
||||||
|
antwort: "antwort_da",
|
||||||
|
zu: "geschlossen",
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Wie lange ein geschlossener Fall aufgehoben wird (Tage).
|
||||||
|
*
|
||||||
|
* NICHT FÜR IMMER. Hier stehen die empfindlichsten Texte des ganzen
|
||||||
|
* Hauses -- jemand beschreibt ein Problem, oft mit anderen Menschen
|
||||||
|
* darin. Was niemand mehr braucht, soll auch nicht mehr da sein.
|
||||||
|
*
|
||||||
|
* 90 Tage, weil ein Fall manchmal wieder aufkommt („das ist schon
|
||||||
|
* wieder passiert") und man dann nachlesen können muss, was damals
|
||||||
|
* vereinbart wurde. Länger hilft niemandem. */
|
||||||
|
export const AUFBEWAHRUNG_TAGE = 90;
|
||||||
|
|
||||||
|
export function hilfeTabellen(d) {
|
||||||
|
d.exec(`
|
||||||
|
/* EIN FALL. Nicht "Ticket" -- das Wort kennt hier niemand.
|
||||||
|
|
||||||
|
"betreff" ist kurz und steht in der Liste; der eigentliche Text
|
||||||
|
ist die erste Nachricht. Das trennt "worum geht es" von "was ist
|
||||||
|
passiert" und macht eine Liste von zwanzig Fällen lesbar.
|
||||||
|
|
||||||
|
"person_id" MIT ON DELETE CASCADE: Wer sein Konto verliert,
|
||||||
|
verliert auch seine Fälle. Ein Fall ohne Melder ist eine
|
||||||
|
Beschwerde von niemandem -- daran kann man nichts mehr klären,
|
||||||
|
und aufheben sollte man ihn erst recht nicht. */
|
||||||
|
CREATE TABLE IF NOT EXISTS hilfe_faelle (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
person_id INTEGER NOT NULL REFERENCES personen(id) ON DELETE CASCADE,
|
||||||
|
betreff TEXT NOT NULL,
|
||||||
|
stand TEXT NOT NULL DEFAULT 'wartet_auf_antwort'
|
||||||
|
CHECK (stand IN ('wartet_auf_antwort','antwort_da','geschlossen')),
|
||||||
|
erstellt TEXT NOT NULL,
|
||||||
|
geaendert TEXT NOT NULL,
|
||||||
|
geschlossen_am TEXT,
|
||||||
|
geschlossen_von INTEGER REFERENCES personen(id) ON DELETE SET NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
/* DIE NACHRICHTEN. "von_leitung" statt eines Rollennamens: Wer
|
||||||
|
geantwortet hat, ist für den Melder unerheblich -- er soll nicht
|
||||||
|
überlegen müssen, ob eine Antwort von DogFather mehr gilt als
|
||||||
|
eine von der rechten Hand. Für das Protokoll bleibt "von_id".
|
||||||
|
|
||||||
|
Das ist ausserdem stabil gegen Rollenwechsel: Wird jemand später
|
||||||
|
etwas anderes, bleibt seine Antwort trotzdem eine der Leitung. */
|
||||||
|
CREATE TABLE IF NOT EXISTS hilfe_nachrichten (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
fall_id INTEGER NOT NULL REFERENCES hilfe_faelle(id) ON DELETE CASCADE,
|
||||||
|
von_id INTEGER REFERENCES personen(id) ON DELETE SET NULL,
|
||||||
|
von_leitung INTEGER NOT NULL DEFAULT 0,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
erstellt TEXT NOT NULL,
|
||||||
|
/* Wann der jeweils andere es gelesen hat. Nur dafür da, dem
|
||||||
|
Melder zu zeigen, dass seine Meldung angekommen ist -- das ist
|
||||||
|
die erste Frage, die jemand hat, der etwas Unangenehmes
|
||||||
|
geschrieben hat. */
|
||||||
|
gelesen_am TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_hilfe_faelle_person
|
||||||
|
ON hilfe_faelle (person_id, geaendert DESC);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_hilfe_faelle_stand
|
||||||
|
ON hilfe_faelle (stand, geaendert DESC);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_hilfe_nachrichten_fall
|
||||||
|
ON hilfe_nachrichten (fall_id, id);
|
||||||
|
`);
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ import { aufbewahrungRouter, aufbewahrungStarten } from "./workspace-aufbewahrun
|
|||||||
import { auskunftRouter } from "./workspace-auskunft.js";
|
import { auskunftRouter } from "./workspace-auskunft.js";
|
||||||
import { uebernahmeRouter } from "./workspace-uebernahme.js";
|
import { uebernahmeRouter } from "./workspace-uebernahme.js";
|
||||||
import { befindenRouter } from "./workspace-befinden.js";
|
import { befindenRouter } from "./workspace-befinden.js";
|
||||||
|
import { hilfeRouter } from "./workspace-hilfe.js";
|
||||||
import { reportRouter } from "./workspace-reports.js";
|
import { reportRouter } from "./workspace-reports.js";
|
||||||
import { scoutRouter } from "./workspace-scouts.js";
|
import { scoutRouter } from "./workspace-scouts.js";
|
||||||
import { callRouter } from "./workspace-calls.js";
|
import { callRouter } from "./workspace-calls.js";
|
||||||
@@ -292,6 +293,7 @@ app.use(aufbewahrungRouter);
|
|||||||
app.use(auskunftRouter);
|
app.use(auskunftRouter);
|
||||||
app.use(uebernahmeRouter);
|
app.use(uebernahmeRouter);
|
||||||
app.use(befindenRouter);
|
app.use(befindenRouter);
|
||||||
|
app.use(hilfeRouter);
|
||||||
app.use(bewerbungRouter);
|
app.use(bewerbungRouter);
|
||||||
app.use(reportRouter);
|
app.use(reportRouter);
|
||||||
app.use(scoutRouter);
|
app.use(scoutRouter);
|
||||||
|
|||||||
@@ -0,0 +1,402 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
DER VERTRAULICHE MELDEWEG -- 19.09.2026
|
||||||
|
|
||||||
|
Filipe: "es soll auch eine kategorie also eine hauptkachel geben wo
|
||||||
|
die community leute sich anonym melden koennen wenn sie probleme
|
||||||
|
haben ... rechte hand und dogfather sollen zugriff auf diese anonyme
|
||||||
|
nachrichten haben. also anonym fuer die anderen."
|
||||||
|
|
||||||
|
HIER LIEGEN DIE EMPFINDLICHSTEN TEXTE DES GANZEN HAUSES. Jemand
|
||||||
|
beschreibt ein Problem, oft mit anderen Menschen darin. Diese
|
||||||
|
Pruefung fragt deshalb vor allem eines: Kann irgendjemand etwas
|
||||||
|
sehen, das nicht fuer ihn ist?
|
||||||
|
|
||||||
|
DREI SORTEN FEHLER WERDEN GESUCHT:
|
||||||
|
|
||||||
|
1. EIN FALL BEIM FALSCHEN. Ein zweites Mitglied darf einen fremden
|
||||||
|
Fall weder in der Liste noch ueber die Fallnummer sehen. Auch ein
|
||||||
|
Modi nicht -- sehr oft geht es genau um eine
|
||||||
|
Moderationsentscheidung.
|
||||||
|
|
||||||
|
2. DER WECHSEL LAESST SICH UMGEHEN. Die Oberflaeche blendet den
|
||||||
|
Knopf aus; wer die Route direkt aufruft, kaeme daran vorbei. Die
|
||||||
|
Regel muss im Server stehen, und genau das wird hier geprueft --
|
||||||
|
nicht, ob ein Knopf verschwindet.
|
||||||
|
|
||||||
|
3. EIN GESCHLOSSENER FALL NIMMT NOCH NACHRICHTEN AN. Dann ist
|
||||||
|
"zugemacht" eine Meinung und keine Tatsache.
|
||||||
|
|
||||||
|
Aufrufen mit: node server/pruef-hilfe.mjs
|
||||||
|
===================================================================== */
|
||||||
|
import { mkdtempSync, rmSync } from "node:fs";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import { request as httpAnfrage } from "node:http";
|
||||||
|
import { portMussFreiSein } from "./helfer-port.mjs";
|
||||||
|
|
||||||
|
const PORT = await portMussFreiSein(4188, "pruef-hilfe");
|
||||||
|
const ordner = mkdtempSync(join(tmpdir(), "ws-hilfe-"));
|
||||||
|
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
|
||||||
|
process.env.PORT = String(PORT);
|
||||||
|
process.env.SITE_ACCESS_SECRET = "lokaler-test";
|
||||||
|
process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00";
|
||||||
|
|
||||||
|
const express = (await import("express")).default;
|
||||||
|
const ec = express.response.cookie;
|
||||||
|
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
|
||||||
|
import { notbremse } from "./helfer-notbremse.mjs";
|
||||||
|
await import("./index.js");
|
||||||
|
notbremse(150_000, "pruef-hilfe");
|
||||||
|
await new Promise((r) => setTimeout(r, 700));
|
||||||
|
|
||||||
|
process.on("uncaughtException", (f) => { console.error("ABSTURZ:", f); process.exit(7); });
|
||||||
|
|
||||||
|
let fehler = 0, geprueft = 0;
|
||||||
|
const melde = (t) => console.log(t);
|
||||||
|
const ok = (b, t) => { geprueft++; console.log((b ? " ok " : " FEHL ") + t); if (!b) fehler++; };
|
||||||
|
|
||||||
|
const CREW = "crew.dogfather-universe.com";
|
||||||
|
|
||||||
|
function roh(pfad, host, kopf = {}, koerper = null, methode = null) {
|
||||||
|
return new Promise((fertig, schief) => {
|
||||||
|
const a = httpAnfrage({
|
||||||
|
host: "127.0.0.1", port: PORT, path: pfad,
|
||||||
|
method: methode || (koerper ? "POST" : "GET"),
|
||||||
|
headers: { Host: host, ...(koerper ? { "Content-Type": "application/json" } : {}), ...kopf },
|
||||||
|
}, (antwort) => {
|
||||||
|
let text = "";
|
||||||
|
antwort.on("data", (s) => { text += s; });
|
||||||
|
antwort.on("end", () => fertig({ code: antwort.statusCode, text, kopf: antwort.headers }));
|
||||||
|
});
|
||||||
|
a.on("error", schief);
|
||||||
|
if (koerper) a.write(JSON.stringify(koerper));
|
||||||
|
a.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const json = (a) => { try { return JSON.parse(a.text); } catch { return {}; } };
|
||||||
|
|
||||||
|
const { DatabaseSync } = await import("node:sqlite");
|
||||||
|
const { scryptSync, randomBytes } = await import("node:crypto");
|
||||||
|
|
||||||
|
const LEUTE = [
|
||||||
|
["Filipe", "admin", "CODE-DOGI-0001"],
|
||||||
|
["Rieke", "hand", "CODE-HAND-0001"],
|
||||||
|
["Kessi", "modi", "CODE-MODI-0001"],
|
||||||
|
["Mara", "gast", "CODE-GAST-0001"],
|
||||||
|
["Tim", "gast", "CODE-GAST-0002"],
|
||||||
|
];
|
||||||
|
{
|
||||||
|
const d = new DatabaseSync(process.env.WORKSPACE_DB);
|
||||||
|
for (const [name, rolle, code] of LEUTE) {
|
||||||
|
const salz = randomBytes(16).toString("hex");
|
||||||
|
const hash = scryptSync(code, salz, 64,
|
||||||
|
{ N: 32768, r: 8, p: 1, maxmem: 96 * 1024 * 1024 }).toString("hex");
|
||||||
|
d.prepare("INSERT INTO personen (name, rolle, code_hash, code_salt, code_n, aktiv, erstellt)"
|
||||||
|
+ " VALUES (?,?,?,?,?,1,?)")
|
||||||
|
.run(name, rolle, hash, salz, 32768, new Date().toISOString());
|
||||||
|
}
|
||||||
|
d.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function anmelden(rolle, code) {
|
||||||
|
let a = await roh("/workspace/api/anmelden", CREW, {}, { rolle, code });
|
||||||
|
if (a.code === 400 && a.text.includes("alter_offen")) {
|
||||||
|
a = await roh("/workspace/api/anmelden", CREW, {}, { rolle, code, alter_ok: true });
|
||||||
|
}
|
||||||
|
return [].concat(a.kopf["set-cookie"] || []).map((z) => z.split(";")[0]).join("; ");
|
||||||
|
}
|
||||||
|
|
||||||
|
const k = {};
|
||||||
|
k.dogi = await anmelden("admin", "CODE-DOGI-0001");
|
||||||
|
k.hand = await anmelden("hand", "CODE-HAND-0001");
|
||||||
|
k.modi = await anmelden("modi", "CODE-MODI-0001");
|
||||||
|
k.mara = await anmelden("gast", "CODE-GAST-0001");
|
||||||
|
k.tim = await anmelden("gast", "CODE-GAST-0002");
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
1. WER DIE SEITE UEBERHAUPT OEFFNEN DARF
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 1. Die Tuer ===");
|
||||||
|
{
|
||||||
|
for (const [wer, keks, soll] of [
|
||||||
|
["Mara (Mitglied)", k.mara, 200],
|
||||||
|
["DogFather", k.dogi, 200],
|
||||||
|
["die rechte Hand", k.hand, 200],
|
||||||
|
]) {
|
||||||
|
const a = await roh("/workspace/hilfe.html", CREW, { cookie: keks });
|
||||||
|
ok(a.code === soll, `${wer}: ${a.code}`);
|
||||||
|
}
|
||||||
|
/* MODIS AUSDRUECKLICH NICHT -- sehr oft geht es um sie. */
|
||||||
|
const m = await roh("/workspace/hilfe.html", CREW, { cookie: k.modi });
|
||||||
|
ok(m.code === 302 || m.code === 403, `ein Modi kommt NICHT hinein (${m.code})`);
|
||||||
|
const o = await roh("/workspace/hilfe.html", CREW);
|
||||||
|
ok(o.code === 302 || o.code === 401 || o.code === 403, `ohne Anmeldung nicht (${o.code})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
2. MELDEN
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 2. Eine Meldung aufmachen ===");
|
||||||
|
let fallId = 0;
|
||||||
|
{
|
||||||
|
const zuKurz = await roh("/workspace/api/hilfe", CREW, { cookie: k.mara },
|
||||||
|
{ betreff: "Hm", text: "kurz" });
|
||||||
|
ok(zuKurz.code === 400, `zu kurz wird abgelehnt (${zuKurz.code})`);
|
||||||
|
|
||||||
|
const a = await roh("/workspace/api/hilfe", CREW, { cookie: k.mara }, {
|
||||||
|
betreff: "Jemand geht mich im Chat immer wieder an",
|
||||||
|
text: "Seit einer Woche schreibt mir dieselbe Person nach jedem Stream. "
|
||||||
|
+ "Ich habe schon geblockt, dann kommt ein neuer Zugang.",
|
||||||
|
});
|
||||||
|
ok(a.code === 201, `Mara kann melden (${a.code})`);
|
||||||
|
fallId = json(a).id;
|
||||||
|
ok(Number.isInteger(fallId) && fallId > 0, `der Fall hat eine Nummer (${fallId})`);
|
||||||
|
|
||||||
|
/* DIE LEITUNG MELDET SICH NICHT SELBST. */
|
||||||
|
const d = await roh("/workspace/api/hilfe", CREW, { cookie: k.dogi },
|
||||||
|
{ betreff: "Test von DogFather", text: "Das sollte nicht gehen, denke ich." });
|
||||||
|
ok(d.code === 400, `DogFather kann keinen Fall aufmachen (${d.code})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
3. WER SIEHT WAS -- der wichtigste Abschnitt
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 3. Vertraulich heisst vertraulich ===");
|
||||||
|
{
|
||||||
|
const mara = json(await roh("/workspace/api/hilfe", CREW, { cookie: k.mara }));
|
||||||
|
ok(mara.faelle?.length === 1, `Mara sieht ihren Fall (${mara.faelle?.length})`);
|
||||||
|
ok(mara.leitung === false, "und ist nicht Leitung");
|
||||||
|
/* IHR EIGENER NAME KOMMT NICHT MIT -- sie weiss, wer sie ist. Das
|
||||||
|
Feld gibt es fuer sie gar nicht, also kann es auch nicht
|
||||||
|
versehentlich angezeigt werden. */
|
||||||
|
ok(!("melder" in (mara.faelle?.[0] || {})),
|
||||||
|
"in ihrer Antwort steht kein Melder-Feld");
|
||||||
|
|
||||||
|
/* EIN ZWEITES MITGLIED SIEHT NICHTS. Das ist der Kern. */
|
||||||
|
const tim = json(await roh("/workspace/api/hilfe", CREW, { cookie: k.tim }));
|
||||||
|
ok(tim.faelle?.length === 0, `Tim sieht Maras Fall NICHT (${tim.faelle?.length})`);
|
||||||
|
const timDirekt = await roh(`/workspace/api/hilfe/${fallId}`, CREW, { cookie: k.tim });
|
||||||
|
/* 404 UND NICHT 403: Ein "darfst du nicht" verriete, dass es den
|
||||||
|
Fall gibt. */
|
||||||
|
ok(timDirekt.code === 404, `und auch nicht ueber die Nummer (${timDirekt.code})`);
|
||||||
|
|
||||||
|
/* EIN MODI AUCH NICHT. */
|
||||||
|
const modi = await roh(`/workspace/api/hilfe/${fallId}`, CREW, { cookie: k.modi });
|
||||||
|
ok(modi.code === 404 || modi.code === 302 || modi.code === 403,
|
||||||
|
`ein Modi kommt nicht an den Fall (${modi.code})`);
|
||||||
|
|
||||||
|
/* DIE LEITUNG SIEHT IHN -- MIT NAMEN. Genau so bestellt. */
|
||||||
|
const dogi = json(await roh("/workspace/api/hilfe", CREW, { cookie: k.dogi }));
|
||||||
|
ok(dogi.faelle?.length === 1, `DogFather sieht den Fall (${dogi.faelle?.length})`);
|
||||||
|
ok(dogi.faelle?.[0]?.melder === "Mara",
|
||||||
|
`und den Namen dazu (${dogi.faelle?.[0]?.melder})`);
|
||||||
|
const hand = json(await roh("/workspace/api/hilfe", CREW, { cookie: k.hand }));
|
||||||
|
ok(hand.faelle?.[0]?.melder === "Mara", "die rechte Hand ebenso");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
4. DER WECHSEL -- und zwar im Server, nicht im Knopf
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 4. Immer abwechselnd ===");
|
||||||
|
{
|
||||||
|
/* Mara ist gerade NICHT dran -- sie hat gerade geschrieben. */
|
||||||
|
const nochmal = await roh(`/workspace/api/hilfe/${fallId}/antwort`, CREW,
|
||||||
|
{ cookie: k.mara }, { text: "Und noch etwas dazu." });
|
||||||
|
ok(nochmal.code === 409,
|
||||||
|
`Mara kann nicht zweimal hintereinander schreiben (${nochmal.code})`);
|
||||||
|
|
||||||
|
const d = json(await roh(`/workspace/api/hilfe/${fallId}`, CREW, { cookie: k.mara }));
|
||||||
|
ok(d.ich_bin_dran === false, "und der Server sagt ihr das auch");
|
||||||
|
|
||||||
|
/* Die Leitung antwortet. */
|
||||||
|
const antwort = await roh(`/workspace/api/hilfe/${fallId}/antwort`, CREW,
|
||||||
|
{ cookie: k.dogi }, { text: "Danke, dass du dich meldest. Wie heisst der Zugang?" });
|
||||||
|
ok(antwort.code === 200, `DogFather antwortet (${antwort.code})`);
|
||||||
|
|
||||||
|
/* Jetzt ist die Leitung NICHT mehr dran. */
|
||||||
|
const nochmal2 = await roh(`/workspace/api/hilfe/${fallId}/antwort`, CREW,
|
||||||
|
{ cookie: k.hand }, { text: "Ergaenzung." });
|
||||||
|
ok(nochmal2.code === 409,
|
||||||
|
`auch die Leitung kann nicht zweimal (${nochmal2.code})`);
|
||||||
|
|
||||||
|
/* Und Mara schon. */
|
||||||
|
const maraJetzt = json(await roh(`/workspace/api/hilfe/${fallId}`, CREW, { cookie: k.mara }));
|
||||||
|
ok(maraJetzt.ich_bin_dran === true, "Mara ist jetzt dran");
|
||||||
|
const maraAntwort = await roh(`/workspace/api/hilfe/${fallId}/antwort`, CREW,
|
||||||
|
{ cookie: k.mara }, { text: "Der Zugang heisst xyz123." });
|
||||||
|
ok(maraAntwort.code === 200, `und kann antworten (${maraAntwort.code})`);
|
||||||
|
|
||||||
|
/* GEGENPROBE: Tim kann in einen fremden Fall nichts schreiben. */
|
||||||
|
const timSchreibt = await roh(`/workspace/api/hilfe/${fallId}/antwort`, CREW,
|
||||||
|
{ cookie: k.tim }, { text: "Ich mische mich mal ein." });
|
||||||
|
ok(timSchreibt.code === 404, `Tim kann nicht hineinschreiben (${timSchreibt.code})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
5. ZUMACHEN
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 5. Zumachen kann nur die Leitung ===");
|
||||||
|
{
|
||||||
|
const mara = await roh(`/workspace/api/hilfe/${fallId}/schliessen`, CREW,
|
||||||
|
{ cookie: k.mara }, { text: "Passt schon." });
|
||||||
|
ok(mara.code === 403, `Mara kann ihren Fall NICHT schliessen (${mara.code})`);
|
||||||
|
|
||||||
|
const zu = await roh(`/workspace/api/hilfe/${fallId}/schliessen`, CREW,
|
||||||
|
{ cookie: k.hand }, { text: "Zugang gesperrt, melde dich wenn wieder etwas ist." });
|
||||||
|
ok(zu.code === 200, `die rechte Hand schliesst ihn (${zu.code})`);
|
||||||
|
|
||||||
|
/* EIN GESCHLOSSENER FALL IST GESCHLOSSEN -- auch fuer die Leitung. */
|
||||||
|
const danach = await roh(`/workspace/api/hilfe/${fallId}/antwort`, CREW,
|
||||||
|
{ cookie: k.dogi }, { text: "Noch ein Nachtrag." });
|
||||||
|
ok(danach.code === 409, `danach nimmt er nichts mehr an (${danach.code})`);
|
||||||
|
const maraDanach = await roh(`/workspace/api/hilfe/${fallId}/antwort`, CREW,
|
||||||
|
{ cookie: k.mara }, { text: "Doch noch etwas." });
|
||||||
|
ok(maraDanach.code === 409, `auch von Mara nicht (${maraDanach.code})`);
|
||||||
|
|
||||||
|
const d = json(await roh(`/workspace/api/hilfe/${fallId}`, CREW, { cookie: k.mara }));
|
||||||
|
ok(d.fall?.stand === "geschlossen", `der Stand steht auf geschlossen (${d.fall?.stand})`);
|
||||||
|
ok(d.nachrichten?.length === 4,
|
||||||
|
`vier Nachrichten im Verlauf, das Schlusswort mitgezaehlt (${d.nachrichten?.length})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
6. DIE GRENZE FUER OFFENE FAELLE
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 6. Drei offene sind genug ===");
|
||||||
|
{
|
||||||
|
let letzte = 0;
|
||||||
|
for (let i = 1; i <= 4; i++) {
|
||||||
|
const a = await roh("/workspace/api/hilfe", CREW, { cookie: k.tim }, {
|
||||||
|
betreff: `Sache Nummer ${i}`,
|
||||||
|
text: `Das ist die ${i}. Meldung und sie ist lang genug fuer die Pruefung.`,
|
||||||
|
});
|
||||||
|
letzte = a.code;
|
||||||
|
if (i <= 3) ok(a.code === 201, `Meldung ${i} geht durch (${a.code})`);
|
||||||
|
}
|
||||||
|
ok(letzte === 429, `die vierte wird abgelehnt (${letzte})`);
|
||||||
|
|
||||||
|
/* UND NACH DEM SCHLIESSEN GEHT WIEDER EINE. Ohne diese Zeile waere
|
||||||
|
die Grenze eine Sackgasse statt einer Bremse. */
|
||||||
|
const tim = json(await roh("/workspace/api/hilfe", CREW, { cookie: k.tim }));
|
||||||
|
const ersterOffener = tim.faelle?.[tim.faelle.length - 1]?.id;
|
||||||
|
await roh(`/workspace/api/hilfe/${ersterOffener}/schliessen`, CREW, { cookie: k.dogi }, {});
|
||||||
|
const wieder = await roh("/workspace/api/hilfe", CREW, { cookie: k.tim }, {
|
||||||
|
betreff: "Jetzt wieder eine",
|
||||||
|
text: "Nachdem einer geschlossen wurde, sollte das hier wieder gehen.",
|
||||||
|
});
|
||||||
|
ok(wieder.code === 201, `nach dem Schliessen geht wieder eine (${wieder.code})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
7. AUFRAEUMEN
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 7. Was niemand mehr braucht, verschwindet ===");
|
||||||
|
{
|
||||||
|
const { hilfeAufraeumen } = await import("./workspace-hilfe.js");
|
||||||
|
const { db } = await import("./workspace.js");
|
||||||
|
|
||||||
|
/* Einen geschlossenen Fall kuenstlich altern lassen. KEIN echtes
|
||||||
|
Warten -- eine Pruefung, die 90 Tage braucht, ist keine. */
|
||||||
|
const alt = new Date(Date.now() - 100 * 86400000).toISOString();
|
||||||
|
db().prepare("UPDATE hilfe_faelle SET geschlossen_am = ? WHERE id = ?").run(alt, fallId);
|
||||||
|
|
||||||
|
const vorher = db().prepare("SELECT COUNT(*) AS n FROM hilfe_faelle").get().n;
|
||||||
|
const weg = hilfeAufraeumen(90);
|
||||||
|
const nachher = db().prepare("SELECT COUNT(*) AS n FROM hilfe_faelle").get().n;
|
||||||
|
ok(weg === 1 && nachher === vorher - 1,
|
||||||
|
`ein alter, geschlossener Fall wird geloescht (${weg}, ${vorher} -> ${nachher})`);
|
||||||
|
|
||||||
|
/* UND DIE NACHRICHTEN MIT IHM. Ein Fall ohne Text waere geloescht,
|
||||||
|
die Texte laegen aber weiter in der Datenbank -- genau das, was
|
||||||
|
man beim Aufraeumen vermeiden will. */
|
||||||
|
const reste = db().prepare(
|
||||||
|
"SELECT COUNT(*) AS n FROM hilfe_nachrichten WHERE fall_id = ?").get(fallId).n;
|
||||||
|
ok(reste === 0, `und seine ${4 - reste} Nachrichten ebenfalls (${reste} uebrig)`);
|
||||||
|
|
||||||
|
/* GEGENPROBE: Ein OFFENER Fall wird nicht angefasst, egal wie alt. */
|
||||||
|
const offen = db().prepare("SELECT COUNT(*) AS n FROM hilfe_faelle WHERE stand != 'geschlossen'").get().n;
|
||||||
|
const weg2 = hilfeAufraeumen(0);
|
||||||
|
const offenDanach = db().prepare("SELECT COUNT(*) AS n FROM hilfe_faelle WHERE stand != 'geschlossen'").get().n;
|
||||||
|
ok(offen === offenDanach && offen > 0,
|
||||||
|
`offene Faelle bleiben, auch bei Aufbewahrung 0 (${offen} vorher, ${offenDanach} danach, ${weg2} geschlossene weg)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
8. IM BROWSER
|
||||||
|
======================================================================= */
|
||||||
|
melde("");
|
||||||
|
melde("=== 8. Im Browser ===");
|
||||||
|
{
|
||||||
|
let pw = null;
|
||||||
|
try {
|
||||||
|
pw = await import("file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs");
|
||||||
|
} catch { /* dritter Ausgang */ }
|
||||||
|
|
||||||
|
if (!pw) {
|
||||||
|
melde(" -- Playwright ist nicht da -- im Browser wurde NICHT nachgesehen.");
|
||||||
|
} else {
|
||||||
|
const browser = await pw.chromium.launch();
|
||||||
|
try {
|
||||||
|
for (const [name, keks, breite] of [
|
||||||
|
["Mara", k.mara, 1400], ["Mara am Handy", k.mara, 412], ["DogFather", k.dogi, 1400],
|
||||||
|
]) {
|
||||||
|
const ctx = await browser.newContext({
|
||||||
|
viewport: { width: breite, height: 950 },
|
||||||
|
isMobile: breite < 700, hasTouch: breite < 700,
|
||||||
|
reducedMotion: "reduce",
|
||||||
|
});
|
||||||
|
await ctx.addCookies(keks.split("; ").filter(Boolean).map((z) => {
|
||||||
|
const [n, ...r] = z.split("=");
|
||||||
|
return { name: n, value: r.join("="), domain: "127.0.0.1", path: "/" };
|
||||||
|
}));
|
||||||
|
const seite = await ctx.newPage();
|
||||||
|
const kaputt = [];
|
||||||
|
seite.on("pageerror", (e) => kaputt.push(String(e).slice(0, 140)));
|
||||||
|
|
||||||
|
await seite.goto(`http://127.0.0.1:${PORT}/workspace/hilfe.html`, { waitUntil: "networkidle" });
|
||||||
|
await seite.waitForTimeout(900);
|
||||||
|
|
||||||
|
const z = await seite.evaluate(() => ({
|
||||||
|
titel: document.getElementById("seiten-titel")?.textContent?.trim() || "",
|
||||||
|
hinweis: document.getElementById("vertrauen-text")?.textContent?.trim() || "",
|
||||||
|
neuSichtbar: !document.getElementById("neu-block")?.hidden,
|
||||||
|
zeilen: document.querySelectorAll(".fall-zeile").length,
|
||||||
|
/* Nichts darf ueber den rechten Rand laufen. */
|
||||||
|
ueber: Math.max(0, document.documentElement.scrollWidth - window.innerWidth),
|
||||||
|
}));
|
||||||
|
|
||||||
|
ok(z.titel.length > 0, `${name}: die Seite hat einen Titel (${z.titel})`);
|
||||||
|
/* DER HINWEIS MUSS DA SEIN, IMMER. Er ist der Unterschied
|
||||||
|
zwischen "vertraulich" und einem falschen Versprechen. */
|
||||||
|
ok(/sonst niemand|nur du und die rechte Hand/i.test(z.hinweis),
|
||||||
|
" der Hinweis, wer mitliest, steht da");
|
||||||
|
ok(z.ueber === 0, ` nichts laeuft ueber den Rand (${z.ueber} px)`);
|
||||||
|
ok(kaputt.length === 0,
|
||||||
|
` kein Skriptfehler${kaputt.length ? ": " + kaputt.join(" | ") : ""}`);
|
||||||
|
|
||||||
|
if (name.startsWith("Mara")) {
|
||||||
|
ok(z.neuSichtbar, " sie kann etwas Neues melden");
|
||||||
|
} else {
|
||||||
|
ok(!z.neuSichtbar, " DogFather bekommt KEIN Melde-Formular");
|
||||||
|
ok(z.zeilen > 0, ` und sieht die Meldungen (${z.zeilen})`);
|
||||||
|
}
|
||||||
|
await ctx.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
melde("");
|
||||||
|
melde(`${geprueft} Pruefungen, ${fehler} Fehler`);
|
||||||
|
melde(fehler ? "NICHT IN ORDNUNG" : "ALLES IN ORDNUNG");
|
||||||
|
try { rmSync(ordner, { recursive: true, force: true }); } catch { /* Rest */ }
|
||||||
|
process.exit(fehler ? 1 : 0);
|
||||||
@@ -142,11 +142,29 @@ const { bereicheFuer, TREFF_BRETTER } = await import("./workspace.js");
|
|||||||
ok(TREFF_BRETTER.length === 7,
|
ok(TREFF_BRETTER.length === 7,
|
||||||
`es bleiben genau die sieben Bretter (${TREFF_BRETTER.join(", ")})`);
|
`es bleiben genau die sieben Bretter (${TREFF_BRETTER.join(", ")})`);
|
||||||
|
|
||||||
/* DAS RASTER. Drei Spalten, „Der Treff“ belegt zwei -- die Summe
|
/* DAS RASTER -- JE GRUPPE, NICHT UEBER ALLES.
|
||||||
muss durch drei teilbar sein, sonst klafft eine Luecke. */
|
|
||||||
const plaetze = TREFF_BEREICHE.reduce((n, k) => n + (k.gross ? 2 : 1), 0);
|
Der erste Entwurf zaehlte alle Kacheln zusammen und meldete ein
|
||||||
ok(plaetze % 3 === 0,
|
Loch, sobald die Community eine zweite Gruppe bekam (Fuer dich).
|
||||||
`das Raster geht auf: ${TREFF_BEREICHE.length} Kacheln = ${plaetze} Plaetze, ${plaetze / 3} volle Reihen`);
|
Das war ein Fehler der Pruefung, nicht der Oberflaeche: Jede
|
||||||
|
Gruppe hat ihr EIGENES Raster und faengt in einer neuen Zeile an.
|
||||||
|
|
||||||
|
Eine freie Zelle am ENDE einer Gruppe ist erlaubt -- ein Loch in
|
||||||
|
der MITTE nicht. Geprueft wird deshalb die Gruppe mit den sieben
|
||||||
|
Brettern: Dort haette eine falsch einsortierte breite Kachel eine
|
||||||
|
Luecke mitten hinein geschoben. */
|
||||||
|
const jeGruppe = new Map();
|
||||||
|
for (const x of TREFF_BEREICHE) {
|
||||||
|
if (!jeGruppe.has(x.gruppe)) jeGruppe.set(x.gruppe, []);
|
||||||
|
jeGruppe.get(x.gruppe).push(x);
|
||||||
|
}
|
||||||
|
const treffGruppe = jeGruppe.get("Community") || [];
|
||||||
|
const plaetze = treffGruppe.reduce((n, k) => n + (k.gross ? 2 : 1), 0);
|
||||||
|
ok(treffGruppe.length > 0 && plaetze % 3 === 0,
|
||||||
|
`die Community-Gruppe geht auf: ${treffGruppe.length} Kacheln = ${plaetze} Plaetze,`
|
||||||
|
+ ` ${plaetze / 3} volle Reihen`);
|
||||||
|
ok(treffGruppe.findIndex((k) => k.gross) === 0,
|
||||||
|
"und die doppelt breite Kachel steht an erster Stelle");
|
||||||
|
|
||||||
/* EIGENER TON. Zwei Kacheln mit derselben Farbe nebeneinander sind
|
/* EIGENER TON. Zwei Kacheln mit derselben Farbe nebeneinander sind
|
||||||
auf einem Bildschirmfoto nicht zu unterscheiden. */
|
auf einem Bildschirmfoto nicht zu unterscheiden. */
|
||||||
|
|||||||
@@ -380,6 +380,24 @@ export const SEITEN = {
|
|||||||
nichts zu tun. */
|
nichts zu tun. */
|
||||||
"/workspace/unsere-seiten.html": ["gast", "modi", "hand", "admin"],
|
"/workspace/unsere-seiten.html": ["gast", "modi", "hand", "admin"],
|
||||||
|
|
||||||
|
/* DER VERTRAULICHE MELDEWEG (19.09.2026).
|
||||||
|
|
||||||
|
Filipe: "es soll auch eine kategorie also eine hauptkachel geben wo
|
||||||
|
die community leute sich anonym melden koennen wenn sie probleme
|
||||||
|
haben ... rechte hand und dogfather sollen zugriff auf diese
|
||||||
|
anonyme nachrichten haben."
|
||||||
|
|
||||||
|
DREI ROLLEN, UND MODIS AUSDRUECKLICH NICHT. Sehr oft geht es in
|
||||||
|
diesen Meldungen um eine Moderationsentscheidung -- wer beteiligt
|
||||||
|
ist, darf die Beschwerde ueber sich nicht lesen. Das ist keine
|
||||||
|
Geringschaetzung der Modis, sondern dieselbe Regel, die auch
|
||||||
|
anderswo gilt: Niemand prueft sich selbst.
|
||||||
|
|
||||||
|
WAS AUF DER SEITE ZU SEHEN IST, entscheidet nicht diese Zeile,
|
||||||
|
sondern `fallFuer` in workspace-hilfe.js: Ein Mitglied sieht seine
|
||||||
|
eigenen Faelle, die Leitung alle. */
|
||||||
|
"/workspace/hilfe.html": ["gast", "hand", "admin"],
|
||||||
|
|
||||||
/* WER SIEHT WAS. DogFather und die rechte Hand (Filipe, 11.09.2026:
|
/* WER SIEHT WAS. DogFather und die rechte Hand (Filipe, 11.09.2026:
|
||||||
"ich will die kategorie auch auf der team dogi seite fuer die
|
"ich will die kategorie auch auf der team dogi seite fuer die
|
||||||
dogfather und rechte hand rollen").
|
dogfather und rechte hand rollen").
|
||||||
|
|||||||
@@ -0,0 +1,342 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
DER VERTRAULICHE MELDEWEG (19.09.2026)
|
||||||
|
|
||||||
|
Die Regeln stehen samt Begründung im Kopf von hilfe-tabellen.js.
|
||||||
|
Hier sind die Wege, und die drei Stellen, an denen etwas schiefgehen
|
||||||
|
kann:
|
||||||
|
|
||||||
|
1. EIN FALL DARF NIE BEIM FALSCHEN LANDEN. Jede Leseroute fragt
|
||||||
|
zuerst `darfSehen()`. Es gibt keinen Weg, der eine Fallnummer
|
||||||
|
ohne diese Frage nimmt -- auch nicht die Antwortroute.
|
||||||
|
|
||||||
|
2. DER WECHSEL MUSS ERZWUNGEN SEIN, nicht nur in der Oberfläche
|
||||||
|
angedeutet. Ein ausgegrauter Knopf ist keine Regel; wer die
|
||||||
|
Route direkt aufruft, käme daran vorbei.
|
||||||
|
|
||||||
|
3. EIN GESCHLOSSENER FALL IST GESCHLOSSEN. Auch für die Leitung --
|
||||||
|
sonst ist "zugemacht" eine Meinung und keine Tatsache.
|
||||||
|
===================================================================== */
|
||||||
|
|
||||||
|
import express from "express";
|
||||||
|
import { db, protokolliere } from "./workspace.js";
|
||||||
|
import { FALL_STAND } from "./hilfe-tabellen.js";
|
||||||
|
import { benachrichtige } from "./workspace-push.js";
|
||||||
|
|
||||||
|
export const hilfeRouter = express.Router();
|
||||||
|
|
||||||
|
/** Wer alle Fälle sieht und beantworten darf.
|
||||||
|
*
|
||||||
|
* GENAU ZWEI ROLLEN, wie bestellt: DogFather und die rechte Hand.
|
||||||
|
* Modis ausdrücklich NICHT -- sehr oft geht es in diesen Meldungen um
|
||||||
|
* eine Moderationsentscheidung, und wer beteiligt ist, darf die
|
||||||
|
* Beschwerde über sich nicht lesen. */
|
||||||
|
const LEITUNG = new Set(["admin", "hand"]);
|
||||||
|
|
||||||
|
const istLeitung = (person) => LEITUNG.has(person?.rolle);
|
||||||
|
|
||||||
|
/** Grenzen. Nicht schön, aber ohne sie ist eine Textbox ein Einfallstor. */
|
||||||
|
const BETREFF_MAX = 120;
|
||||||
|
const TEXT_MAX = 4000;
|
||||||
|
/** Wie viele offene Fälle eine Person gleichzeitig haben darf.
|
||||||
|
*
|
||||||
|
* Drei. Nicht als Misstrauen, sondern weil ein Mensch mit acht
|
||||||
|
* offenen Meldungen keine Antwort mehr zuordnen kann -- und weil der,
|
||||||
|
* der antwortet, dann keine mehr ernst nimmt. */
|
||||||
|
const OFFEN_MAX = 3;
|
||||||
|
|
||||||
|
const jetzt = () => new Date().toISOString();
|
||||||
|
|
||||||
|
function sauber(s, max) {
|
||||||
|
return String(s ?? "").replace(/\s+/g, " ").trim().slice(0, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Darf diese Person diesen Fall sehen?
|
||||||
|
*
|
||||||
|
* Gibt den Fall zurück oder `null`. NIE `true`/`false` -- so kann
|
||||||
|
* keine Route "darf sehen" beantworten und danach trotzdem den
|
||||||
|
* falschen Datensatz laden. */
|
||||||
|
function fallFuer(person, id) {
|
||||||
|
const fall = db().prepare("SELECT * FROM hilfe_faelle WHERE id = ?").get(Number(id));
|
||||||
|
if (!fall) return null;
|
||||||
|
if (istLeitung(person)) return fall;
|
||||||
|
return fall.person_id === person.id ? fall : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Was jemand sehen darf ------------------------------------ */
|
||||||
|
|
||||||
|
/** Die eigenen Fälle -- oder für die Leitung alle.
|
||||||
|
*
|
||||||
|
* EINE ROUTE FÜR BEIDE, nicht zwei. Zwei Routen hießen zwei Stellen,
|
||||||
|
* an denen die Sichtbarkeitsregel gepflegt werden muss. */
|
||||||
|
hilfeRouter.get("/workspace/api/hilfe", (req, res) => {
|
||||||
|
try {
|
||||||
|
if (!req.person) return res.status(401).json({ fehler: "nicht_angemeldet" });
|
||||||
|
const leitung = istLeitung(req.person);
|
||||||
|
|
||||||
|
const zeilen = leitung
|
||||||
|
? db().prepare(`
|
||||||
|
SELECT f.*, p.name AS melder_name, p.rolle AS melder_rolle,
|
||||||
|
(SELECT COUNT(*) FROM hilfe_nachrichten n WHERE n.fall_id = f.id) AS nachrichten
|
||||||
|
FROM hilfe_faelle f
|
||||||
|
LEFT JOIN personen p ON p.id = f.person_id
|
||||||
|
ORDER BY CASE f.stand WHEN 'wartet_auf_antwort' THEN 0
|
||||||
|
WHEN 'antwort_da' THEN 1 ELSE 2 END,
|
||||||
|
f.geaendert DESC`).all()
|
||||||
|
: db().prepare(`
|
||||||
|
SELECT f.*,
|
||||||
|
(SELECT COUNT(*) FROM hilfe_nachrichten n WHERE n.fall_id = f.id) AS nachrichten
|
||||||
|
FROM hilfe_faelle f
|
||||||
|
WHERE f.person_id = ?
|
||||||
|
ORDER BY CASE f.stand WHEN 'antwort_da' THEN 0
|
||||||
|
WHEN 'wartet_auf_antwort' THEN 1 ELSE 2 END,
|
||||||
|
f.geaendert DESC`).all(req.person.id);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
faelle: zeilen.map((z) => ({
|
||||||
|
id: z.id,
|
||||||
|
betreff: z.betreff,
|
||||||
|
stand: z.stand,
|
||||||
|
erstellt: z.erstellt,
|
||||||
|
geaendert: z.geaendert,
|
||||||
|
nachrichten: z.nachrichten,
|
||||||
|
/* DER NAME NUR FÜR DIE LEITUNG. Er wird gar nicht erst in die
|
||||||
|
Antwort geschrieben, wenn jemand anderes fragt -- eine
|
||||||
|
Oberfläche, die ihn "nicht anzeigt", wäre kein Schutz. */
|
||||||
|
...(leitung ? { melder: z.melder_name || "(gelöscht)" } : {}),
|
||||||
|
})),
|
||||||
|
leitung,
|
||||||
|
/* Damit die Oberfläche weiß, ob noch ein Fall aufgemacht werden
|
||||||
|
darf, ohne es durch einen Fehlschlag herauszufinden. */
|
||||||
|
offen_eigene: leitung ? null : zeilen.filter((z) => z.stand !== FALL_STAND.zu).length,
|
||||||
|
offen_max: OFFEN_MAX,
|
||||||
|
});
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[hilfe] Liste:", fehler?.message);
|
||||||
|
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/** Ein Fall mit seinem ganzen Verlauf. */
|
||||||
|
hilfeRouter.get("/workspace/api/hilfe/:id(\\d+)", (req, res) => {
|
||||||
|
try {
|
||||||
|
if (!req.person) return res.status(401).json({ fehler: "nicht_angemeldet" });
|
||||||
|
const fall = fallFuer(req.person, req.params.id);
|
||||||
|
/* 404 UND NICHT 403: Ein "darfst du nicht" verrät, dass es diesen
|
||||||
|
Fall gibt. Bei vertraulichen Meldungen ist schon das zu viel. */
|
||||||
|
if (!fall) return res.status(404).json({ fehler: "nicht_gefunden" });
|
||||||
|
|
||||||
|
const leitung = istLeitung(req.person);
|
||||||
|
const nachrichten = db().prepare(
|
||||||
|
"SELECT id, von_leitung, text, erstellt, gelesen_am FROM hilfe_nachrichten"
|
||||||
|
+ " WHERE fall_id = ? ORDER BY id").all(fall.id);
|
||||||
|
|
||||||
|
/* GELESEN-STEMPEL SETZEN. Nur für die Nachrichten der jeweils
|
||||||
|
anderen Seite -- die eigenen hat man selbst geschrieben. */
|
||||||
|
const fremd = leitung ? 0 : 1;
|
||||||
|
db().prepare(
|
||||||
|
"UPDATE hilfe_nachrichten SET gelesen_am = ? WHERE fall_id = ?"
|
||||||
|
+ " AND von_leitung = ? AND gelesen_am IS NULL").run(jetzt(), fall.id, fremd);
|
||||||
|
|
||||||
|
const melder = leitung
|
||||||
|
? db().prepare("SELECT name FROM personen WHERE id = ?").get(fall.person_id)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
fall: {
|
||||||
|
id: fall.id, betreff: fall.betreff, stand: fall.stand,
|
||||||
|
erstellt: fall.erstellt, geaendert: fall.geaendert,
|
||||||
|
geschlossen_am: fall.geschlossen_am,
|
||||||
|
...(leitung ? { melder: melder?.name || "(gelöscht)" } : {}),
|
||||||
|
},
|
||||||
|
nachrichten: nachrichten.map((n) => ({
|
||||||
|
id: n.id, von_leitung: !!n.von_leitung, text: n.text,
|
||||||
|
erstellt: n.erstellt, gelesen: !!n.gelesen_am,
|
||||||
|
})),
|
||||||
|
leitung,
|
||||||
|
/* WER IST DRAN. Vom Server gerechnet, nicht im Browser -- sonst
|
||||||
|
steht in zwei Dateien dieselbe Regel, und eine davon altert. */
|
||||||
|
ich_bin_dran: fall.stand === FALL_STAND.zu ? false
|
||||||
|
: leitung ? fall.stand === FALL_STAND.wartet
|
||||||
|
: fall.stand === FALL_STAND.antwort,
|
||||||
|
});
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[hilfe] Fall lesen:", fehler?.message);
|
||||||
|
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ---------- Einen Fall aufmachen -------------------------------------- */
|
||||||
|
|
||||||
|
hilfeRouter.post("/workspace/api/hilfe", express.json(), (req, res) => {
|
||||||
|
try {
|
||||||
|
if (!req.person) return res.status(401).json({ fehler: "nicht_angemeldet" });
|
||||||
|
/* DIE LEITUNG MELDET SICH NICHT SELBST. Sie hat andere Wege --
|
||||||
|
und ein Fall, den man sich selbst beantwortet, verwirrt die
|
||||||
|
Liste für alle. */
|
||||||
|
if (istLeitung(req.person)) {
|
||||||
|
return res.status(400).json({ fehler: "leitung_meldet_nicht" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const betreff = sauber(req.body?.betreff, BETREFF_MAX);
|
||||||
|
const text = String(req.body?.text ?? "").trim().slice(0, TEXT_MAX);
|
||||||
|
if (betreff.length < 3) return res.status(400).json({ fehler: "betreff_fehlt" });
|
||||||
|
if (text.length < 10) return res.status(400).json({ fehler: "text_zu_kurz" });
|
||||||
|
|
||||||
|
const offen = db().prepare(
|
||||||
|
"SELECT COUNT(*) AS n FROM hilfe_faelle WHERE person_id = ? AND stand != ?")
|
||||||
|
.get(req.person.id, FALL_STAND.zu).n;
|
||||||
|
if (offen >= OFFEN_MAX) {
|
||||||
|
return res.status(429).json({ fehler: "zu_viele_offen", offen, max: OFFEN_MAX });
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = jetzt();
|
||||||
|
db().prepare("INSERT INTO hilfe_faelle (person_id, betreff, stand, erstellt, geaendert)"
|
||||||
|
+ " VALUES (?,?,?,?,?)").run(req.person.id, betreff, FALL_STAND.wartet, t, t);
|
||||||
|
const id = db().prepare("SELECT last_insert_rowid() AS id").get().id;
|
||||||
|
db().prepare("INSERT INTO hilfe_nachrichten (fall_id, von_id, von_leitung, text, erstellt)"
|
||||||
|
+ " VALUES (?,?,0,?,?)").run(id, req.person.id, text, t);
|
||||||
|
|
||||||
|
/* IM PROTOKOLL STEHT NUR, DASS ES EINEN FALL GIBT -- nicht, worum
|
||||||
|
es geht. Das Protokoll lesen mehr Leute als den Fall. */
|
||||||
|
protokolliere(req.person.id, "hilfe_fall_neu", `Fall ${id}`);
|
||||||
|
leitungBenachrichtigen(id, betreff).catch(() => { /* Push ist Zugabe */ });
|
||||||
|
|
||||||
|
res.status(201).json({ id });
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[hilfe] anlegen:", fehler?.message);
|
||||||
|
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ---------- Antworten -------------------------------------------------- */
|
||||||
|
|
||||||
|
hilfeRouter.post("/workspace/api/hilfe/:id(\\d+)/antwort", express.json(), (req, res) => {
|
||||||
|
try {
|
||||||
|
if (!req.person) return res.status(401).json({ fehler: "nicht_angemeldet" });
|
||||||
|
const fall = fallFuer(req.person, req.params.id);
|
||||||
|
if (!fall) return res.status(404).json({ fehler: "nicht_gefunden" });
|
||||||
|
if (fall.stand === FALL_STAND.zu) {
|
||||||
|
return res.status(409).json({ fehler: "geschlossen" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const leitung = istLeitung(req.person);
|
||||||
|
/* DER WECHSEL, ERZWUNGEN. Die Oberfläche blendet den Knopf aus --
|
||||||
|
das ist Höflichkeit. Diese Zeile ist die Regel. */
|
||||||
|
const dran = leitung ? fall.stand === FALL_STAND.wartet
|
||||||
|
: fall.stand === FALL_STAND.antwort;
|
||||||
|
if (!dran) return res.status(409).json({ fehler: "nicht_dran" });
|
||||||
|
|
||||||
|
const text = String(req.body?.text ?? "").trim().slice(0, TEXT_MAX);
|
||||||
|
if (text.length < 2) return res.status(400).json({ fehler: "text_zu_kurz" });
|
||||||
|
|
||||||
|
const t = jetzt();
|
||||||
|
db().prepare("INSERT INTO hilfe_nachrichten (fall_id, von_id, von_leitung, text, erstellt)"
|
||||||
|
+ " VALUES (?,?,?,?,?)").run(fall.id, req.person.id, leitung ? 1 : 0, text, t);
|
||||||
|
db().prepare("UPDATE hilfe_faelle SET stand = ?, geaendert = ? WHERE id = ?")
|
||||||
|
.run(leitung ? FALL_STAND.antwort : FALL_STAND.wartet, t, fall.id);
|
||||||
|
|
||||||
|
if (leitung) {
|
||||||
|
antwortBenachrichtigen(fall).catch(() => { /* Zugabe */ });
|
||||||
|
} else {
|
||||||
|
leitungBenachrichtigen(fall.id, fall.betreff).catch(() => { /* Zugabe */ });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ ok: true });
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[hilfe] antworten:", fehler?.message);
|
||||||
|
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ---------- Zumachen --------------------------------------------------- */
|
||||||
|
|
||||||
|
hilfeRouter.post("/workspace/api/hilfe/:id(\\d+)/schliessen", express.json(), (req, res) => {
|
||||||
|
try {
|
||||||
|
if (!req.person) return res.status(401).json({ fehler: "nicht_angemeldet" });
|
||||||
|
/* NUR DIE LEITUNG. Siehe hilfe-tabellen.js: Ein Fall, den der
|
||||||
|
Melder selbst zumachen kann, wird in einem schlechten Moment
|
||||||
|
zugemacht. */
|
||||||
|
if (!istLeitung(req.person)) return res.status(403).json({ fehler: "nur_leitung" });
|
||||||
|
const fall = fallFuer(req.person, req.params.id);
|
||||||
|
if (!fall) return res.status(404).json({ fehler: "nicht_gefunden" });
|
||||||
|
if (fall.stand === FALL_STAND.zu) return res.json({ ok: true, schon: true });
|
||||||
|
|
||||||
|
const t = jetzt();
|
||||||
|
const wort = String(req.body?.text ?? "").trim().slice(0, TEXT_MAX);
|
||||||
|
/* EIN SCHLUSSWORT IST ERLAUBT, ABER NICHT PFLICHT. Manche Fälle
|
||||||
|
enden mit "ist geklärt, danke" -- andere brauchen kein Wort
|
||||||
|
mehr, und dann ist ein Pflichtfeld nur eine Hürde. */
|
||||||
|
if (wort.length >= 2) {
|
||||||
|
db().prepare("INSERT INTO hilfe_nachrichten (fall_id, von_id, von_leitung, text, erstellt)"
|
||||||
|
+ " VALUES (?,?,1,?,?)").run(fall.id, req.person.id, wort, t);
|
||||||
|
}
|
||||||
|
db().prepare("UPDATE hilfe_faelle SET stand = ?, geaendert = ?,"
|
||||||
|
+ " geschlossen_am = ?, geschlossen_von = ? WHERE id = ?")
|
||||||
|
.run(FALL_STAND.zu, t, t, req.person.id, fall.id);
|
||||||
|
|
||||||
|
protokolliere(req.person.id, "hilfe_fall_zu", `Fall ${fall.id}`);
|
||||||
|
schlussBenachrichtigen(fall).catch(() => { /* Zugabe */ });
|
||||||
|
res.json({ ok: true });
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[hilfe] schliessen:", fehler?.message);
|
||||||
|
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ---------- Benachrichtigungen ----------------------------------------- */
|
||||||
|
|
||||||
|
/** Die Leitung anstupsen, dass etwas hereingekommen ist.
|
||||||
|
*
|
||||||
|
* OHNE DEN BETREFF IM TEXT. Eine Benachrichtigung erscheint auf einem
|
||||||
|
* Sperrbildschirm, den auch andere sehen -- und der Betreff ist hier
|
||||||
|
* regelmäßig das Empfindliche. Es steht nur, DASS etwas da ist. */
|
||||||
|
async function leitungBenachrichtigen(fallId) {
|
||||||
|
const leute = db().prepare(
|
||||||
|
"SELECT id FROM personen WHERE rolle IN ('admin','hand') AND aktiv = 1").all();
|
||||||
|
for (const p of leute) {
|
||||||
|
await benachrichtige(p.id, "hilfe", {
|
||||||
|
titel: "Eine vertrauliche Meldung",
|
||||||
|
text: "Jemand aus der Community braucht etwas.",
|
||||||
|
ziel: `/workspace/hilfe.html?fall=${fallId}`,
|
||||||
|
}).catch(() => { /* einer weniger ist kein Grund abzubrechen */ });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function antwortBenachrichtigen(fall) {
|
||||||
|
await benachrichtige(fall.person_id, "hilfe", {
|
||||||
|
titel: "Antwort auf deine Meldung",
|
||||||
|
text: "Es gibt eine Antwort für dich.",
|
||||||
|
ziel: `/workspace/hilfe.html?fall=${fall.id}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function schlussBenachrichtigen(fall) {
|
||||||
|
await benachrichtige(fall.person_id, "hilfe", {
|
||||||
|
titel: "Deine Meldung ist erledigt",
|
||||||
|
text: "Der Fall wurde abgeschlossen.",
|
||||||
|
ziel: `/workspace/hilfe.html?fall=${fall.id}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Aufräumen --------------------------------------------------- */
|
||||||
|
|
||||||
|
/** Löscht geschlossene Fälle, die älter sind als die Aufbewahrung.
|
||||||
|
*
|
||||||
|
* Wird beim Start aufgerufen (siehe index.js). Läuft still: Wenn es
|
||||||
|
* nichts zu tun gibt, sagt es auch nichts -- eine Meldung, die jeden
|
||||||
|
* Start begleitet, wird nach einer Woche nicht mehr gelesen. */
|
||||||
|
export function hilfeAufraeumen(tage) {
|
||||||
|
try {
|
||||||
|
const grenze = new Date(Date.now() - tage * 86400000).toISOString();
|
||||||
|
const weg = db().prepare(
|
||||||
|
"DELETE FROM hilfe_faelle WHERE stand = ? AND geschlossen_am IS NOT NULL"
|
||||||
|
+ " AND geschlossen_am < ?").run(FALL_STAND.zu, grenze);
|
||||||
|
if (weg.changes > 0) {
|
||||||
|
console.log(`[hilfe] ${weg.changes} abgeschlossene Fälle nach ${tage} Tagen gelöscht.`);
|
||||||
|
}
|
||||||
|
return weg.changes;
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[hilfe] aufraeumen:", fehler?.message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -141,6 +141,17 @@ export const ARTEN = [
|
|||||||
Einstellungen. Das ist der Unterschied zwischen einer Vorgabe und
|
Einstellungen. Das ist der Unterschied zwischen einer Vorgabe und
|
||||||
einem Zwang. */
|
einem Zwang. */
|
||||||
{ schluessel: "befinden", name: "Alle zwei Wochen: wie geht es dir?", vorgabe: true },
|
{ schluessel: "befinden", name: "Alle zwei Wochen: wie geht es dir?", vorgabe: true },
|
||||||
|
/* DER VERTRAULICHE MELDEWEG (19.09.2026).
|
||||||
|
|
||||||
|
Sie geht in BEIDE Richtungen: An die Leitung, wenn etwas
|
||||||
|
hereinkommt -- und an den Melder, wenn eine Antwort da ist. Genau
|
||||||
|
das ist der Punkt: Wer etwas Unangenehmes geschrieben hat, will
|
||||||
|
nicht stuendlich nachsehen muessen, ob schon jemand geantwortet
|
||||||
|
hat.
|
||||||
|
|
||||||
|
IM TEXT STEHT NIE, WORUM ES GEHT. Eine Benachrichtigung erscheint
|
||||||
|
auf einem Sperrbildschirm, den auch andere sehen. */
|
||||||
|
{ schluessel: "hilfe", name: "Vertrauliche Meldung: neu oder beantwortet", vorgabe: true },
|
||||||
{ schluessel: "test", name: "Probe-Benachrichtigung", vorgabe: true },
|
{ schluessel: "test", name: "Probe-Benachrichtigung", vorgabe: true },
|
||||||
];
|
];
|
||||||
const ARTEN_SCHLUESSEL = new Set(ARTEN.map((a) => a.schluessel));
|
const ARTEN_SCHLUESSEL = new Set(ARTEN.map((a) => a.schluessel));
|
||||||
|
|||||||
+42
-3
@@ -32,6 +32,7 @@ import { darfSeite, OHNE_ANMELDUNG, seitenFuer } from "./rechte.js";
|
|||||||
obwohl workspace-treff.js seinerseits aus dieser Datei importiert.
|
obwohl workspace-treff.js seinerseits aus dieser Datei importiert.
|
||||||
Begruendung im Kopf von treff-tabellen.js. */
|
Begruendung im Kopf von treff-tabellen.js. */
|
||||||
import { treffTabellen, treffSperreLesen, MINDESTALTER } from "./treff-tabellen.js";
|
import { treffTabellen, treffSperreLesen, MINDESTALTER } from "./treff-tabellen.js";
|
||||||
|
import { hilfeTabellen } from "./hilfe-tabellen.js";
|
||||||
import { sitzungPasstZurAdresse, istOhneModiAdresse, istCrewAdresse, istPruefAdresse, AUSSEN_ROLLEN,
|
import { sitzungPasstZurAdresse, istOhneModiAdresse, istCrewAdresse, istPruefAdresse, AUSSEN_ROLLEN,
|
||||||
TEAM_DOGI_ROLLEN } from "./crew-adresse.js";
|
TEAM_DOGI_ROLLEN } from "./crew-adresse.js";
|
||||||
/* Weitergereicht, damit die Fachmodule sie wie alles andere aus
|
/* Weitergereicht, damit die Fachmodule sie wie alles andere aus
|
||||||
@@ -720,9 +721,27 @@ const FUEHRUNG_GRUPPE = {
|
|||||||
gruppeUnter: "Was ihr über die Zeit beobachtet – und wer dazukommen könnte",
|
gruppeUnter: "Was ihr über die Zeit beobachtet – und wer dazukommen könnte",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* UMBENANNT AM 19.09.2026 -- von "Entwicklung" zu "Eure Aufgaben".
|
||||||
|
|
||||||
|
Filipe: "diese kategorie ist ja die aufgaben die ich an die modis
|
||||||
|
habe, also eher aufgabe und dan perfektionierst du eine neue wo
|
||||||
|
diagramme texte und so zu jedem modi gemacht wird und diese
|
||||||
|
kategorie kannst du entwicklung nenen."
|
||||||
|
|
||||||
|
Er hat recht, und der Name war seit dem 11.09. falsch: Damals fuehrte
|
||||||
|
die Kachel auf das Notizbrett (dort standen wirklich Beobachtungen),
|
||||||
|
seitdem fuehrt sie auf den KATALOG -- eine Liste dessen, was ein Modi
|
||||||
|
koennen soll. Das ist eine Aufgabenliste, und sie hiess weiter
|
||||||
|
"Entwicklung", weil beim Umhaengen des Ziels niemand den Namen
|
||||||
|
angefasst hat.
|
||||||
|
|
||||||
|
DER NAME "ENTWICKLUNG" WIRD DAMIT FREI fuer das, was Filipe wirklich
|
||||||
|
darunter versteht: eine Auswertung je Person, mit Verlauf und Text.
|
||||||
|
Die gibt es noch nicht -- sie ist der naechste Schritt und
|
||||||
|
ausdruecklich nicht diese Kachel. */
|
||||||
const ENTWICKLUNG_KACHEL = {
|
const ENTWICKLUNG_KACHEL = {
|
||||||
...FUEHRUNG_GRUPPE,
|
...FUEHRUNG_GRUPPE,
|
||||||
name: "Entwicklung", unter: "Was gut läuft, woran ihr arbeitet – je Person",
|
name: "Eure Aufgaben", unter: "Was ihr könnt – und was als Nächstes kommt",
|
||||||
/* SEIT DEM 11.09.2026 FUEHRT DIE KACHEL AUF DEN KATALOG, nicht mehr
|
/* SEIT DEM 11.09.2026 FUEHRT DIE KACHEL AUF DEN KATALOG, nicht mehr
|
||||||
auf das Notizbrett. Filipe: "ich will dass fertige aufgaben da
|
auf das Notizbrett. Filipe: "ich will dass fertige aufgaben da
|
||||||
stehen und so". Das Brett gibt es weiter -- es ist von der
|
stehen und so". Das Brett gibt es weiter -- es ist von der
|
||||||
@@ -1022,6 +1041,22 @@ export const TREFF_BRETTER = TREFF_BEREICHE
|
|||||||
Spicy Media haben mit den Zuschauern dieses Streams nichts zu tun. */
|
Spicy Media haben mit den Zuschauern dieses Streams nichts zu tun. */
|
||||||
export const TREFF_ROLLEN = new Set(["gast", "modi", "hand", "admin"]);
|
export const TREFF_ROLLEN = new Set(["gast", "modi", "hand", "admin"]);
|
||||||
|
|
||||||
|
/* DER VERTRAULICHE MELDEWEG (19.09.2026).
|
||||||
|
|
||||||
|
Eigene Gruppe, nicht bei den Brettern: Auf den sieben Brettern
|
||||||
|
schreibt man oeffentlich. Hier schreibt man an genau zwei Menschen.
|
||||||
|
Zwischen den anderen Kacheln wuerde das verschwimmen -- und wer ein
|
||||||
|
Problem hat, sucht nicht lange.
|
||||||
|
|
||||||
|
SIE STEHT VOR "FUER DICH": Ein Problem ist dringender als der eigene
|
||||||
|
Steckbrief. Die Reihenfolge innerhalb der Gruppe "Fuer dich" ergibt
|
||||||
|
sich aus der Liste, die Sortierung in start.js fasst beide ans Ende. */
|
||||||
|
const HILFE_KACHEL = {
|
||||||
|
gruppe: "Für dich", gruppeUnter: "Deine eigene Seite",
|
||||||
|
name: "Vertraulich melden", unter: "Probleme, die niemand sonst sieht",
|
||||||
|
zeichen: "schutz", ton: 39, ziel: "hilfe.html", szene: "studio",
|
||||||
|
};
|
||||||
|
|
||||||
/* DAS TEAM SIEHT DEN TREFF MIT -- als eigene Gruppe unter seinen
|
/* DAS TEAM SIEHT DEN TREFF MIT -- als eigene Gruppe unter seinen
|
||||||
uebrigen Kacheln.
|
uebrigen Kacheln.
|
||||||
|
|
||||||
@@ -1033,7 +1068,8 @@ export const TREFF_ROLLEN = new Set(["gast", "modi", "hand", "admin"]);
|
|||||||
dort waere die Stelle, an der beim naechsten neuen Brett eines fehlt. */
|
dort waere die Stelle, an der beim naechsten neuen Brett eines fehlt. */
|
||||||
const MODI_MIT_TREFF = [...MODI_BEREICHE, BEFINDEN_KACHEL, ...TREFF_BEREICHE,
|
const MODI_MIT_TREFF = [...MODI_BEREICHE, BEFINDEN_KACHEL, ...TREFF_BEREICHE,
|
||||||
TREFF_MODERATION_KACHEL];
|
TREFF_MODERATION_KACHEL];
|
||||||
const HAND_MIT_TREFF = [...HAND_BEREICHE, ...TREFF_BEREICHE, TREFF_MODERATION_KACHEL];
|
const HAND_MIT_TREFF = [...HAND_BEREICHE, ...TREFF_BEREICHE,
|
||||||
|
TREFF_MODERATION_KACHEL, HILFE_KACHEL];
|
||||||
|
|
||||||
/* AUSSEN_ROLLEN kommt aus crew-adresse.js und wird hier nur
|
/* AUSSEN_ROLLEN kommt aus crew-adresse.js und wird hier nur
|
||||||
weitergereicht -- die Adressregel braucht sie zuerst, und diese Datei
|
weitergereicht -- die Adressregel braucht sie zuerst, und diese Datei
|
||||||
@@ -1094,7 +1130,7 @@ const STECKBRIEF_KACHEL_TREFF = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Die Community: der Treff und ihre eigene Seite. Sonst nichts. */
|
/* Die Community: der Treff und ihre eigene Seite. Sonst nichts. */
|
||||||
const TREFF_MIT_EIGENEM = [...TREFF_BEREICHE, STECKBRIEF_KACHEL_TREFF];
|
const TREFF_MIT_EIGENEM = [...TREFF_BEREICHE, HILFE_KACHEL, STECKBRIEF_KACHEL_TREFF];
|
||||||
|
|
||||||
export function bereicheFuer(person) {
|
export function bereicheFuer(person) {
|
||||||
if (person?.rolle === "modi") return MODI_MIT_TREFF;
|
if (person?.rolle === "modi") return MODI_MIT_TREFF;
|
||||||
@@ -3992,6 +4028,9 @@ export function db() {
|
|||||||
und ueber einen Kreis kommen Konstanten als undefined an, ohne
|
und ueber einen Kreis kommen Konstanten als undefined an, ohne
|
||||||
dass irgendwo ein Fehler erscheint. */
|
dass irgendwo ein Fehler erscheint. */
|
||||||
treffTabellen(d);
|
treffTabellen(d);
|
||||||
|
/* Der vertrauliche Meldeweg (19.09.2026). Haengt an personen und
|
||||||
|
kommt deshalb hierher, nicht in den Bauplan darueber. */
|
||||||
|
hilfeTabellen(d);
|
||||||
umstellungen(d);
|
umstellungen(d);
|
||||||
_db = d;
|
_db = d;
|
||||||
return d;
|
return d;
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
AUS EINEM LOGO EINE MASKE MACHEN (19.09.2026)
|
||||||
|
|
||||||
|
Filipe: „die kachel links soll dogfather logo als hintergrund haben
|
||||||
|
und rechts das logo von vanvan. die logos sollen auch richtig geil im
|
||||||
|
hintegrrund sein. die sollen paar mal sein in der kacheln und so wie
|
||||||
|
schweben, sich ganz leicht bewegen."
|
||||||
|
|
||||||
|
WARUM EINE MASKE UND NICHT DAS BILD SELBST:
|
||||||
|
|
||||||
|
Ein Logo als Hintergrundbild bringt seine eigenen Farben mit. Beide
|
||||||
|
hier sind schwarz auf weiss -- auf einer dunklen Kachel waere das
|
||||||
|
entweder ein weisser Kasten (VanVan, kein Alphakanal) oder ein
|
||||||
|
schwarzer Fleck, den man nicht sieht (DogFather). Umfaerben liesse
|
||||||
|
sich das nur mit Filtern, die man raten muss.
|
||||||
|
|
||||||
|
Eine Maske traegt gar keine Farbe. Sie sagt nur, WO etwas zu sehen
|
||||||
|
ist -- die Farbe kommt aus dem CSS. Damit laesst sich dasselbe Logo
|
||||||
|
in Babyblau, in Lila und morgen in Gruen zeichnen, ohne eine neue
|
||||||
|
Datei.
|
||||||
|
|
||||||
|
WIE DIE MASKE ENTSTEHT: Alpha = (1 - Helligkeit) x vorhandenes
|
||||||
|
Alpha. Wo das Logo schwarz ist, wird die Maske dicht; wo es weiss
|
||||||
|
oder durchsichtig ist, bleibt sie offen. Die Zeichnung bleibt
|
||||||
|
dadurch erhalten -- eine reine Silhouette waere ein Klecks.
|
||||||
|
|
||||||
|
UND KLEINER. Das Original von VanVan ist 387 KB. Fuer ein
|
||||||
|
Hintergrundmuster, das nie groesser als ein paar hundert Pixel
|
||||||
|
erscheint, ist das Verschwendung: Es wird auf 320 px gerechnet, und
|
||||||
|
uebrig bleiben wenige Kilobyte.
|
||||||
|
|
||||||
|
Aufrufen mit: node tools/logo-maske.mjs
|
||||||
|
===================================================================== */
|
||||||
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
||||||
|
import { join, dirname } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
|
const HIER = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const WURZEL = join(HIER, "..");
|
||||||
|
const ZIEL = join(WURZEL, "assets", "img", "marke");
|
||||||
|
|
||||||
|
/** Woraus wird was gemacht. Beide Quellen sind schwarz-weiss. */
|
||||||
|
const AUFTRAEGE = [
|
||||||
|
{ quelle: join(WURZEL, "assets/img/marke/logo-kopf-frei.png"),
|
||||||
|
ziel: join(ZIEL, "maske-dogi.png"), kante: 320,
|
||||||
|
was: "Der Huskykopf" },
|
||||||
|
{ quelle: join(WURZEL, "assets/img/marke/vanvan-logo-quelle.png"),
|
||||||
|
ziel: join(ZIEL, "maske-vanvan.png"), kante: 320,
|
||||||
|
was: "Van's DIY & Bastelbedarf" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const fehlend = AUFTRAEGE.filter((a) => !existsSync(a.quelle));
|
||||||
|
if (fehlend.length) {
|
||||||
|
console.error("KANN NICHT ARBEITEN -- diese Vorlagen fehlen:");
|
||||||
|
for (const f of fehlend) console.error(" " + f.quelle);
|
||||||
|
console.error("");
|
||||||
|
console.error("Das VanVan-Logo liegt unter https://vans-diy-bastelbedarf.com/logo.png");
|
||||||
|
console.error("und gehoert VanVan. Es wird hier nur verkleinert und entfaerbt.");
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { chromium } = await import(
|
||||||
|
"file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs");
|
||||||
|
const browser = await chromium.launch();
|
||||||
|
const seite = await browser.newPage();
|
||||||
|
|
||||||
|
for (const auftrag of AUFTRAEGE) {
|
||||||
|
const roh = readFileSync(auftrag.quelle).toString("base64");
|
||||||
|
const ergebnis = await seite.evaluate(async ([daten, kante]) => {
|
||||||
|
const bild = new Image();
|
||||||
|
bild.src = "data:image/png;base64," + daten;
|
||||||
|
await bild.decode();
|
||||||
|
|
||||||
|
/* Quadratisch und mittig -- beide Logos sind schon nahezu
|
||||||
|
quadratisch, aber "nahezu" ist keine Zusicherung. */
|
||||||
|
const s = Math.max(bild.width, bild.height);
|
||||||
|
const gross = document.createElement("canvas");
|
||||||
|
gross.width = s; gross.height = s;
|
||||||
|
const gk = gross.getContext("2d");
|
||||||
|
gk.drawImage(bild, (s - bild.width) / 2, (s - bild.height) / 2);
|
||||||
|
|
||||||
|
const d = gk.getImageData(0, 0, s, s);
|
||||||
|
const p = d.data;
|
||||||
|
for (let i = 0; i < p.length; i += 4) {
|
||||||
|
/* Helligkeit nach Wahrnehmung, nicht als Mittelwert: Gruen
|
||||||
|
wiegt schwerer als Blau. Bei Schwarz-Weiss macht das keinen
|
||||||
|
Unterschied, bei einem spaeter farbigen Logo schon. */
|
||||||
|
const hell = (0.2126 * p[i] + 0.7152 * p[i + 1] + 0.0722 * p[i + 2]) / 255;
|
||||||
|
const alpha = p[i + 3] / 255;
|
||||||
|
const neu = Math.round((1 - hell) * alpha * 255);
|
||||||
|
p[i] = p[i + 1] = p[i + 2] = 255; // Farbe egal, die Maske traegt nur Alpha
|
||||||
|
p[i + 3] = neu;
|
||||||
|
}
|
||||||
|
gk.putImageData(d, 0, 0);
|
||||||
|
|
||||||
|
/* Verkleinern in EINEM Schritt mit hoher Glaettung. Mehrere
|
||||||
|
Halbierungen waeren schaerfer, aber hier ist ein weiches
|
||||||
|
Hintergrundmuster gewollt. */
|
||||||
|
const klein = document.createElement("canvas");
|
||||||
|
klein.width = kante; klein.height = kante;
|
||||||
|
const kk = klein.getContext("2d");
|
||||||
|
kk.imageSmoothingEnabled = true;
|
||||||
|
kk.imageSmoothingQuality = "high";
|
||||||
|
kk.drawImage(gross, 0, 0, kante, kante);
|
||||||
|
|
||||||
|
/* Wie viel ist ueberhaupt sichtbar? Eine Maske, die fast leer ist,
|
||||||
|
waere ein stiller Fehlschlag -- man sieht auf der Kachel nichts
|
||||||
|
und sucht im CSS. */
|
||||||
|
const kd = kk.getImageData(0, 0, kante, kante).data;
|
||||||
|
let sichtbar = 0;
|
||||||
|
for (let i = 3; i < kd.length; i += 4) if (kd[i] > 24) sichtbar++;
|
||||||
|
|
||||||
|
return {
|
||||||
|
png: klein.toDataURL("image/png").split(",")[1],
|
||||||
|
anteil: sichtbar / (kante * kante),
|
||||||
|
};
|
||||||
|
}, [roh, auftrag.kante]);
|
||||||
|
|
||||||
|
const bytes = Buffer.from(ergebnis.png, "base64");
|
||||||
|
if (!existsSync(ZIEL)) mkdirSync(ZIEL, { recursive: true });
|
||||||
|
writeFileSync(auftrag.ziel, bytes);
|
||||||
|
|
||||||
|
const vorher = readFileSync(auftrag.quelle).length;
|
||||||
|
const anteil = (ergebnis.anteil * 100).toFixed(1);
|
||||||
|
const warnung = ergebnis.anteil < 0.03 || ergebnis.anteil > 0.9
|
||||||
|
? " ACHTUNG: sieht nicht nach einem Logo aus" : "";
|
||||||
|
console.log(`${auftrag.was}:`);
|
||||||
|
console.log(` ${Math.round(vorher / 1024)} KB -> ${Math.round(bytes.length / 1024)} KB`
|
||||||
|
+ ` (${auftrag.kante} px, ${anteil} % gedeckt)${warnung}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await browser.close();
|
||||||
|
console.log("");
|
||||||
|
console.log("Fertig. Die Masken tragen keine Farbe -- die kommt aus dem CSS.");
|
||||||
@@ -5,9 +5,9 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||||
<title>Anruf-Probe · Team Dogi</title>
|
<title>Anruf-Probe · Team Dogi</title>
|
||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="stylesheet" href="assets/css/basis.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/basis.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/kopf.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/kopf.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
<style>
|
<style>
|
||||||
/* Bewusst in der Seite und nicht in einer eigenen Datei: Diese Seite
|
/* Bewusst in der Seite und nicht in einer eigenen Datei: Diese Seite
|
||||||
soll auch dann noch etwas anzeigen, wenn genau das schiefgeht,
|
soll auch dann noch etwas anzeigen, wenn genau das schiefgeht,
|
||||||
@@ -58,6 +58,6 @@
|
|||||||
<p class="probe__ende" id="rat"></p>
|
<p class="probe__ende" id="rat"></p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/anruf-probe.js?v=202609190139" defer></script>
|
<script src="assets/js/anruf-probe.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -22,25 +22,25 @@
|
|||||||
},
|
},
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-192.png?v=202609190139",
|
"src": "/assets/img/app-symbole/workspace-192.png?v=202609190204",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-512.png?v=202609190139",
|
"src": "/assets/img/app-symbole/workspace-512.png?v=202609190204",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609190139",
|
"src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609190204",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609190139",
|
"src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609190204",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
|
|||||||
@@ -1612,3 +1612,128 @@
|
|||||||
.marke-art[data-art="folge"] { --art-ton: #e8a5b4; }
|
.marke-art[data-art="folge"] { --art-ton: #e8a5b4; }
|
||||||
.marke-art[data-art="gesucht"] { --art-ton: #ceb480; }
|
.marke-art[data-art="gesucht"] { --art-ton: #ceb480; }
|
||||||
.marke-art[data-art="lust"] { --art-ton: #bfdbb1; }
|
.marke-art[data-art="lust"] { --art-ton: #bfdbb1; }
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
AUF- UND ZUKLAPPEN, UND DIE SPRUNGLEISTE (19.09.2026)
|
||||||
|
|
||||||
|
Filipe, zwei Sätze an einem Abend:
|
||||||
|
„man soll auf dieser seite jede kategorie auf und zu klappen können
|
||||||
|
mit einem button ... überall wo so eine liste entstehen kann"
|
||||||
|
„das soll viel geiler aussehen bitte" (zur Sprungleiste)
|
||||||
|
===================================================================== */
|
||||||
|
|
||||||
|
/* ---- Die Abschnittsköpfe sind jetzt Knöpfe --------------------------
|
||||||
|
|
||||||
|
Sie sahen als Überschrift gut aus und sollen genauso aussehen — ein
|
||||||
|
Knopf, der wie ein Knopf aussieht, wäre hier ein Rückschritt: Die
|
||||||
|
Gliederung ist das Wichtige, das Zuklappen die Zugabe. Deshalb erbt
|
||||||
|
der Knopf das komplette Aussehen der alten Überschrift und bekommt
|
||||||
|
nur zwei Dinge dazu: einen Zeiger und einen Pfeil. */
|
||||||
|
.brettabschnitt,
|
||||||
|
.zeitstrahl__schild {
|
||||||
|
width: 100%;
|
||||||
|
background: none;
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
/* 44 px hoch, damit ein Daumen ihn trifft — als Überschrift waren es
|
||||||
|
je nach Schriftgröße auch mal 18. */
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
.brettabschnitt:focus-visible,
|
||||||
|
.zeitstrahl__schild:focus-visible {
|
||||||
|
outline: 2px solid var(--akzent, #5aa0e0);
|
||||||
|
outline-offset: 3px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.brettabschnitt:hover .brettabschnitt__wort,
|
||||||
|
.zeitstrahl__schild:hover .zeitstrahl__wort { color: var(--text); }
|
||||||
|
|
||||||
|
.brettabschnitt__wort,
|
||||||
|
.zeitstrahl__wort { flex: 0 0 auto; }
|
||||||
|
|
||||||
|
/* Der Pfeil steht GANZ RECHTS, hinter der auslaufenden Linie — dort
|
||||||
|
sucht man ihn, und dort steht er auch auf der Startseite. */
|
||||||
|
.klapp-pfeil {
|
||||||
|
order: 9;
|
||||||
|
flex: none;
|
||||||
|
width: 18px; height: 18px;
|
||||||
|
color: var(--text-still);
|
||||||
|
transition: transform .2s ease, color .2s ease;
|
||||||
|
}
|
||||||
|
[data-zu="ja"] .klapp-pfeil { transform: rotate(-90deg); }
|
||||||
|
.brettabschnitt:hover .klapp-pfeil,
|
||||||
|
.zeitstrahl__schild:hover .klapp-pfeil { color: var(--text-leise); }
|
||||||
|
|
||||||
|
/* Ein zugeklappter Abschnitt soll SICHTBAR zu sein, nicht nur leer.
|
||||||
|
Ohne diesen Hinweis sieht es aus, als fehle der Inhalt. */
|
||||||
|
.brettabschnitt[data-zu="ja"] .brettabschnitt__zahl,
|
||||||
|
.zeitstrahl__schild[data-zu="ja"] .zeitstrahl__zahl {
|
||||||
|
background: color-mix(in srgb, var(--akzent, #5aa0e0) 22%, transparent);
|
||||||
|
color: var(--text-leise);
|
||||||
|
}
|
||||||
|
|
||||||
|
.brettabschnitt__inhalt[hidden],
|
||||||
|
.zeitstrahl__inhalt[hidden] { display: none; }
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.klapp-pfeil { transition: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Die Sprungleiste ------------------------------------------------
|
||||||
|
|
||||||
|
Vorher: eine Reihe unterstrichener Wörter mit kleinen Zahlen. Auf
|
||||||
|
dem Bildschirmfoto sah das aus wie eine Fußzeile — man übersieht
|
||||||
|
sie, und wer sie sieht, hält sie für Filter (genau die Verwechslung,
|
||||||
|
gegen die schon die Wörter „Springe zu" gebaut wurden).
|
||||||
|
|
||||||
|
Jetzt: echte Marken mit Rahmen und eigenem Grund. Sie sehen nach
|
||||||
|
etwas aus, das man anfassen kann — und die Zahl sitzt darin statt
|
||||||
|
daneben. Die Unterstreichung entfällt: Ein Rahmen sagt dasselbe,
|
||||||
|
ohne die Zeile unruhig zu machen. */
|
||||||
|
.brettmarken {
|
||||||
|
gap: 8px 10px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border: 1px solid var(--rand);
|
||||||
|
border-radius: 12px;
|
||||||
|
/* Ein sehr flacher Verlauf statt einer Trennlinie: Die Leiste hebt
|
||||||
|
sich als BLOCK ab, statt nur einen Strich zu ziehen. */
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.01));
|
||||||
|
}
|
||||||
|
.brettmarken__wort {
|
||||||
|
font-size: .74rem;
|
||||||
|
letter-spacing: .08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-inline-end: 4px;
|
||||||
|
}
|
||||||
|
.brettmarken__weg {
|
||||||
|
gap: 7px;
|
||||||
|
padding: 7px 12px;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid var(--rand);
|
||||||
|
background: rgba(255, 255, 255, .03);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: border-color var(--tempo), background-color var(--tempo),
|
||||||
|
color var(--tempo), transform var(--tempo);
|
||||||
|
}
|
||||||
|
.brettmarken__weg:hover,
|
||||||
|
.brettmarken__weg:focus-visible {
|
||||||
|
color: var(--text);
|
||||||
|
border-color: color-mix(in srgb, var(--akzent, #5aa0e0) 45%, var(--rand));
|
||||||
|
background: color-mix(in srgb, var(--akzent, #5aa0e0) 12%, transparent);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
.brettmarken__zahl {
|
||||||
|
background: rgba(255, 255, 255, .09);
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.brettmarken__weg { transition: none; }
|
||||||
|
.brettmarken__weg:hover { transform: none; }
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
VERTRAULICH MELDEN (19.09.2026)
|
||||||
|
|
||||||
|
Der Ton dieser Seite ist bewusst RUHIGER als der Rest des Hauses.
|
||||||
|
Wer hier schreibt, hat meist Ärger — eine Seite, die dabei glitzert,
|
||||||
|
wirkt unernst. Keine Verläufe über die ganze Fläche, keine Bewegung,
|
||||||
|
keine leuchtenden Kacheln. Die Farbe (Ton 39, #1acae2) kommt nur an
|
||||||
|
den Rändern vor.
|
||||||
|
===================================================================== */
|
||||||
|
|
||||||
|
:root { --hilfe-ton: #1acae2; }
|
||||||
|
|
||||||
|
/* ---- Der Hinweis, wer mitliest -------------------------------------- */
|
||||||
|
.vertrauen {
|
||||||
|
display: flex;
|
||||||
|
gap: .9rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin: 1.2rem 0 0;
|
||||||
|
padding: 1rem 1.1rem;
|
||||||
|
border-radius: .8rem;
|
||||||
|
border: 1px solid color-mix(in srgb, var(--hilfe-ton) 32%, transparent);
|
||||||
|
background: color-mix(in srgb, var(--hilfe-ton) 7%, transparent);
|
||||||
|
}
|
||||||
|
.vertrauen__zeichen {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: grid; place-items: center;
|
||||||
|
width: 2.2rem; height: 2.2rem;
|
||||||
|
}
|
||||||
|
.vertrauen__zeichen svg {
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
fill: none;
|
||||||
|
stroke: color-mix(in srgb, var(--hilfe-ton) 75%, #dceaf8);
|
||||||
|
stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
|
||||||
|
}
|
||||||
|
.vertrauen__text {
|
||||||
|
margin: 0;
|
||||||
|
font-size: .92rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
.vertrauen__text strong { color: #e9f2fb; }
|
||||||
|
|
||||||
|
/* ---- Blöcke ---------------------------------------------------------- */
|
||||||
|
.hilfe-block { margin: 1.6rem 0 0; }
|
||||||
|
.hilfe-block__kopf {
|
||||||
|
display: flex; align-items: center; gap: .8rem;
|
||||||
|
margin: 0 0 .8rem;
|
||||||
|
}
|
||||||
|
.hilfe-block__titel { margin: 0; font-size: 1.1rem; }
|
||||||
|
.hilfe-block__zahl {
|
||||||
|
font-size: .8rem;
|
||||||
|
padding: .1rem .5rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
border: 1px solid var(--rand, #26374b);
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
.hilfe-block__kopf .knopf { margin-left: auto; }
|
||||||
|
|
||||||
|
.hilfe-leer {
|
||||||
|
margin: 0;
|
||||||
|
padding: 1.1rem;
|
||||||
|
border: 1px dashed var(--rand, #26374b);
|
||||||
|
border-radius: .7rem;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Eine Zeile in der Liste ---------------------------------------- */
|
||||||
|
.fall-zeile {
|
||||||
|
padding: .9rem 1rem;
|
||||||
|
margin-bottom: .55rem;
|
||||||
|
border: 1px solid var(--rand, #26374b);
|
||||||
|
border-left: 3px solid var(--rand, #26374b);
|
||||||
|
border-radius: .6rem;
|
||||||
|
background: var(--flaeche, rgba(255,255,255,.02));
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color .18s ease, transform .18s ease;
|
||||||
|
}
|
||||||
|
.fall-zeile:hover,
|
||||||
|
.fall-zeile:focus-visible {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
border-color: color-mix(in srgb, var(--hilfe-ton) 35%, var(--rand, #26374b));
|
||||||
|
}
|
||||||
|
/* DIE FARBE SAGT, WER DRAN IST — nicht, wie schlimm es ist.
|
||||||
|
Ein rotes "dringend" wäre hier falsch: Jede Meldung ist für den,
|
||||||
|
der sie schreibt, dringend. */
|
||||||
|
.fall-zeile[data-stand="wartet_auf_antwort"] { border-left-color: #d9a441; }
|
||||||
|
.fall-zeile[data-stand="antwort_da"] { border-left-color: var(--hilfe-ton); }
|
||||||
|
.fall-zeile[data-stand="geschlossen"] { border-left-color: #4a5b70; opacity: .72; }
|
||||||
|
|
||||||
|
.fall-zeile__oben {
|
||||||
|
display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.fall-zeile__titel { margin: 0; font-size: 1rem; line-height: 1.35; }
|
||||||
|
.fall-zeile__unten {
|
||||||
|
display: flex; gap: .75rem; flex-wrap: wrap;
|
||||||
|
margin: .45rem 0 0;
|
||||||
|
font-size: .8rem;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
.fall-zeile__wer { color: #cfe0f0; }
|
||||||
|
|
||||||
|
.fall-marke {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: .72rem;
|
||||||
|
letter-spacing: .04em;
|
||||||
|
padding: .12rem .5rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
border: 1px solid currentColor;
|
||||||
|
}
|
||||||
|
.fall-marke[data-stand="wartet_auf_antwort"] { color: #d9a441; }
|
||||||
|
.fall-marke[data-stand="antwort_da"] { color: var(--hilfe-ton); }
|
||||||
|
.fall-marke[data-stand="geschlossen"] { color: #7d90a6; }
|
||||||
|
|
||||||
|
/* ---- Der Verlauf ----------------------------------------------------- */
|
||||||
|
.fall-kopf {
|
||||||
|
display: flex; gap: .7rem; flex-wrap: wrap; align-items: center;
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
font-size: .82rem;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
.fall-kopf__wer { color: #cfe0f0; }
|
||||||
|
|
||||||
|
.blase {
|
||||||
|
max-width: 44rem;
|
||||||
|
padding: .8rem 1rem;
|
||||||
|
margin-bottom: .7rem;
|
||||||
|
border-radius: .7rem;
|
||||||
|
border: 1px solid var(--rand, #26374b);
|
||||||
|
}
|
||||||
|
/* Zwei Seiten, zwei Ausrichtungen. Auf dem Handy genügt der Versatz —
|
||||||
|
zwei Spalten wären dort zu eng. */
|
||||||
|
.blase[data-seite="melder"] {
|
||||||
|
background: rgba(255,255,255,.025);
|
||||||
|
}
|
||||||
|
.blase[data-seite="leitung"] {
|
||||||
|
margin-left: auto;
|
||||||
|
border-color: color-mix(in srgb, var(--hilfe-ton) 30%, transparent);
|
||||||
|
background: color-mix(in srgb, var(--hilfe-ton) 6%, transparent);
|
||||||
|
}
|
||||||
|
.blase__wer {
|
||||||
|
margin: 0 0 .3rem;
|
||||||
|
font-size: .76rem;
|
||||||
|
letter-spacing: .04em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
.blase__text {
|
||||||
|
margin: 0;
|
||||||
|
/* Zeilenumbrüche aus dem Text erhalten, ohne HTML zuzulassen. */
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
.blase__fuss {
|
||||||
|
margin: .45rem 0 0;
|
||||||
|
font-size: .74rem;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Formulare ------------------------------------------------------- */
|
||||||
|
.hilfe-form { margin: .4rem 0 0; }
|
||||||
|
.hilfe-form--antwort { margin-top: 1.1rem; }
|
||||||
|
.hilfe-form .feld { display: block; margin-bottom: .9rem; }
|
||||||
|
.hilfe-form .feld__schild {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: .35rem;
|
||||||
|
font-size: .86rem;
|
||||||
|
color: #cfe0f0;
|
||||||
|
}
|
||||||
|
.hilfe-form .feld__pflicht {
|
||||||
|
font-size: .76rem;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
.hilfe-form input[type="text"],
|
||||||
|
.hilfe-form textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: .7rem .85rem;
|
||||||
|
border-radius: .55rem;
|
||||||
|
border: 1px solid var(--rand, #26374b);
|
||||||
|
background: rgba(0,0,0,.25);
|
||||||
|
color: #e9f2fb;
|
||||||
|
font: inherit;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.hilfe-form textarea { resize: vertical; min-height: 6rem; }
|
||||||
|
.hilfe-form input:focus-visible,
|
||||||
|
.hilfe-form textarea:focus-visible {
|
||||||
|
outline: 2px solid color-mix(in srgb, var(--hilfe-ton) 60%, transparent);
|
||||||
|
outline-offset: 1px;
|
||||||
|
border-color: color-mix(in srgb, var(--hilfe-ton) 45%, transparent);
|
||||||
|
}
|
||||||
|
.hilfe-form__hinweis {
|
||||||
|
margin: 0 0 .9rem;
|
||||||
|
font-size: .82rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
.hilfe-form__fuss {
|
||||||
|
display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.hilfe-form__stand {
|
||||||
|
font-size: .82rem;
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fall-warten {
|
||||||
|
margin: 1.1rem 0 0;
|
||||||
|
padding: .9rem 1rem;
|
||||||
|
border-radius: .6rem;
|
||||||
|
border: 1px dashed var(--rand-hell, #33465e);
|
||||||
|
color: var(--text-leise, #93a7bd);
|
||||||
|
font-size: .9rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.fall-zeile { transition: none; }
|
||||||
|
.fall-zeile:hover { transform: none; }
|
||||||
|
}
|
||||||
@@ -1116,6 +1116,17 @@ body.start > main { position: relative; z-index: 1; }
|
|||||||
(Ton 33), Kontrast 4.51:1. Blau ist die einzige Ecke, die im Treff
|
(Ton 33), Kontrast 4.51:1. Blau ist die einzige Ecke, die im Treff
|
||||||
noch frei war — das ist kein Zufall, sondern das Ergebnis. */
|
noch frei war — das ist kein Zufall, sondern das Ergebnis. */
|
||||||
[data-ton="38"] { --ton: #087ce7; } /* Unsere Seiten */
|
[data-ton="38"] { --ton: #087ce7; } /* Unsere Seiten */
|
||||||
|
/* VERTRAULICH MELDEN (19.09.2026) -- ebenfalls abgesucht, nicht gewaehlt.
|
||||||
|
140 973 lesbare Kandidaten, gewonnen hat der mit dem groessten
|
||||||
|
Mindestabstand zu allen neun belegten Toenen: OKLCH L=0.77 C=0.130
|
||||||
|
H=210, Abstand 0.221, Kontrast 9.47:1.
|
||||||
|
|
||||||
|
Der Abstand ist kleiner als bei Ton 38 (0.310) -- das ist keine
|
||||||
|
Nachlaessigkeit, sondern die Folge davon, dass neun Toene belegt
|
||||||
|
sind. Mehr ist im lesbaren Bereich nicht zu holen; wer den naechsten
|
||||||
|
hinzufuegt, sollte das wissen und notfalls einen alten verschieben,
|
||||||
|
statt die Schwelle stillschweigend zu senken. */
|
||||||
|
[data-ton="39"] { --ton: #1acae2; } /* Vertraulich melden */
|
||||||
|
|
||||||
/* Rückfallwert für alles, was einen Ton braucht, aber keine Nummer hat.
|
/* Rückfallwert für alles, was einen Ton braucht, aber keine Nummer hat.
|
||||||
Steht bewusst in :where() -- damit zählt die Zeile beim Wettstreit der
|
Steht bewusst in :where() -- damit zählt die Zeile beim Wettstreit der
|
||||||
@@ -6869,6 +6880,21 @@ body[data-fremde-sicht="ja"]::after {
|
|||||||
sekunden babyblau. die punkte herum sollen eine mischung von rot
|
sekunden babyblau. die punkte herum sollen eine mischung von rot
|
||||||
schwarz und babyblau sein."
|
schwarz und babyblau sein."
|
||||||
|
|
||||||
|
SEIT DEM 19.09.2026 IST DIE STUNDE LILA. Filipe: "die stunden sollen
|
||||||
|
nicht rot sondern lila sein."
|
||||||
|
|
||||||
|
UMGERECHNET, NICHT NEU GEWAEHLT: Jeder der fuenf Verlaufsstopps
|
||||||
|
wurde nach OKLCH zerlegt, sein Farbton auf 303 Grad gedreht und
|
||||||
|
zurueckgerechnet -- Helligkeit und Buntheit blieben auf den
|
||||||
|
Tausendstel gleich. Eine frei gegriffene Lila-Palette waere mit
|
||||||
|
hoher Wahrscheinlichkeit heller oder bunter geworden, und damit
|
||||||
|
waere die Uhr unruhiger, obwohl sich "nur die Farbe" geaendert hat.
|
||||||
|
303 Grad ist der erste Ton im Lila-Bereich, bei dem alle acht Werte
|
||||||
|
(fuenf Stopps, Kopf, zwei Scheine) noch darstellbar sind.
|
||||||
|
|
||||||
|
Die Begruendung darunter gilt unveraendert: Die Stunde bewegt sich
|
||||||
|
kaum und darf deshalb die kraeftigste Farbe tragen.
|
||||||
|
|
||||||
Die Zuordnung ist nicht beliebig, sie folgt der Geschwindigkeit:
|
Die Zuordnung ist nicht beliebig, sie folgt der Geschwindigkeit:
|
||||||
Die SEKUNDE laeuft dauernd und bekommt das ruhigste Babyblau --
|
Die SEKUNDE laeuft dauernd und bekommt das ruhigste Babyblau --
|
||||||
staendige Bewegung in Signalrot ermuedet. Die STUNDE bewegt sich
|
staendige Bewegung in Signalrot ermuedet. Die STUNDE bewegt sich
|
||||||
@@ -6897,7 +6923,7 @@ body[data-fremde-sicht="ja"]::after {
|
|||||||
durchgehalten. */
|
durchgehalten. */
|
||||||
.uhr__ring > .uhr__sekunde { filter: drop-shadow(0 0 1.4px rgba(126, 200, 242, .85)); }
|
.uhr__ring > .uhr__sekunde { filter: drop-shadow(0 0 1.4px rgba(126, 200, 242, .85)); }
|
||||||
.uhr__ring > .uhr__minute { filter: drop-shadow(0 0 1.2px rgba(220, 232, 246, .6)); }
|
.uhr__ring > .uhr__minute { filter: drop-shadow(0 0 1.2px rgba(220, 232, 246, .6)); }
|
||||||
.uhr__ring > .uhr__stunde { filter: drop-shadow(0 0 1.4px rgba(255, 92, 104, .8)); }
|
.uhr__ring > .uhr__stunde { filter: drop-shadow(0 0 1.4px rgba(182, 119, 255, .8)); }
|
||||||
.uhr__schatten .uhr__sekunde, .uhr__schatten .uhr__minute, .uhr__schatten .uhr__stunde,
|
.uhr__schatten .uhr__sekunde, .uhr__schatten .uhr__minute, .uhr__schatten .uhr__stunde,
|
||||||
.uhr__kante .uhr__sekunde, .uhr__kante .uhr__minute, .uhr__kante .uhr__stunde { filter: none; }
|
.uhr__kante .uhr__sekunde, .uhr__kante .uhr__minute, .uhr__kante .uhr__stunde { filter: none; }
|
||||||
|
|
||||||
@@ -7576,9 +7602,9 @@ body[data-fremde-sicht="ja"]::after {
|
|||||||
das ist der Unterschied zwischen "das ist die aktuelle Stunde" und
|
das ist der Unterschied zwischen "das ist die aktuelle Stunde" und
|
||||||
"da stimmt etwas nicht". */
|
"da stimmt etwas nicht". */
|
||||||
.uhr__kopf--stunde {
|
.uhr__kopf--stunde {
|
||||||
stroke: #ff8c96;
|
stroke: #c59cfc;
|
||||||
stroke-width: 6;
|
stroke-width: 6;
|
||||||
filter: drop-shadow(0 0 3px rgba(255, 110, 122, .95));
|
filter: drop-shadow(0 0 3px rgba(187, 132, 254, .95));
|
||||||
}
|
}
|
||||||
/* Wer weniger Bewegung will, bekommt den Sprung ohne Ueberblendung --
|
/* Wer weniger Bewegung will, bekommt den Sprung ohne Ueberblendung --
|
||||||
der Kopf steht dann einfach am richtigen Glied. */
|
der Kopf steht dann einfach am richtigen Glied. */
|
||||||
|
|||||||
@@ -36,22 +36,153 @@
|
|||||||
gap: .75rem;
|
gap: .75rem;
|
||||||
padding: 1.35rem 1.35rem 1.2rem;
|
padding: 1.35rem 1.35rem 1.2rem;
|
||||||
border-radius: 1.1rem;
|
border-radius: 1.1rem;
|
||||||
border: 1px solid color-mix(in srgb, var(--aussen-ton) 30%, transparent);
|
border: 1px solid color-mix(in srgb, var(--aussen-ton) 42%, transparent);
|
||||||
|
/* DREI LAGEN STATT ZWEI (19.09.2026). Filipe: "auch der hintegrrund
|
||||||
|
der kacheln, ich will es viel spezieller".
|
||||||
|
|
||||||
|
Vorher lag der Ton mit 7 % auf der Flaeche -- auf einem dunklen
|
||||||
|
Bildschirm sieht man davon fast nichts, die Kachel wirkte grau.
|
||||||
|
Jetzt: ein heller Bogen oben links (woher das Licht kommt), ein
|
||||||
|
zweiter, schwacher unten rechts (damit die Flaeche nicht flach
|
||||||
|
kippt) und ein Grundverlauf, der den Ton wirklich traegt.
|
||||||
|
|
||||||
|
Nach oben begrenzt bleibt es trotzdem: Der hellste Punkt liegt bei
|
||||||
|
28 %, und Text steht nie darauf -- er hat seine eigene Lage. */
|
||||||
background:
|
background:
|
||||||
radial-gradient(120% 100% at 8% 0%,
|
radial-gradient(120% 95% at 6% -5%,
|
||||||
color-mix(in srgb, var(--aussen-ton) 15%, transparent), transparent 62%),
|
color-mix(in srgb, var(--aussen-ton) 28%, transparent), transparent 58%),
|
||||||
linear-gradient(160deg,
|
radial-gradient(90% 80% at 105% 110%,
|
||||||
color-mix(in srgb, var(--aussen-ton) 7%, #0d1523),
|
color-mix(in srgb, var(--aussen-ton) 16%, transparent), transparent 62%),
|
||||||
#0a111d 68%);
|
linear-gradient(158deg,
|
||||||
box-shadow: 0 16px 34px -22px color-mix(in srgb, var(--aussen-ton) 75%, transparent);
|
color-mix(in srgb, var(--aussen-ton) 14%, #0c1420),
|
||||||
|
#090f1a 72%);
|
||||||
|
box-shadow:
|
||||||
|
0 18px 38px -20px color-mix(in srgb, var(--aussen-ton) 85%, transparent),
|
||||||
|
inset 0 1px 0 color-mix(in srgb, var(--aussen-ton) 22%, transparent);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform .22s ease, border-color .22s ease, box-shadow .22s ease;
|
transition: transform .22s ease, border-color .22s ease, box-shadow .22s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Die Töne der beiden Karten. Sie stehen hier und nicht im HTML,
|
/* Die Töne der beiden Karten. Sie stehen hier und nicht im HTML,
|
||||||
damit eine dritte Karte eine Zeile braucht und nicht zehn. */
|
damit eine dritte Karte eine Zeile braucht und nicht zehn.
|
||||||
.aussen--dogi { --aussen-ton: #087ce7; }
|
|
||||||
.aussen--shop { --aussen-ton: #e0559b; }
|
BABYBLAU UND LILA seit dem 19.09.2026 (Filipe: „die linke kachel soll
|
||||||
|
babyblau sein und rechte lila").
|
||||||
|
|
||||||
|
Babyblau ist im Haus schon vergeben — es ist der Ton der Sekunde auf
|
||||||
|
der Uhr (#7ec8f2), und dieselbe Farbe zweimal anders zu treffen wäre
|
||||||
|
schlampig. Also derselbe Wert.
|
||||||
|
|
||||||
|
Das Lila ist dasselbe, in das an diesem Tag die Stunden der Uhr
|
||||||
|
umgerechnet wurden (OKLCH-Farbton 303°). Beide Kacheln sprechen
|
||||||
|
damit die Sprache, die die Startseite ohnehin spricht.
|
||||||
|
|
||||||
|
`--logo` nennt die Maske. Sie steht an der Karte und nicht am
|
||||||
|
Logofeld, damit eine dritte Karte nur diese zwei Zeilen braucht. */
|
||||||
|
.aussen--dogi {
|
||||||
|
--aussen-ton: #7ec8f2;
|
||||||
|
--logo: url("/assets/img/marke/maske-dogi.png");
|
||||||
|
}
|
||||||
|
.aussen--shop {
|
||||||
|
--aussen-ton: #b284ec;
|
||||||
|
--logo: url("/assets/img/marke/maske-vanvan.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- DIE SCHWEBENDEN LOGOS ------------------------------------------
|
||||||
|
|
||||||
|
Vier Stück je Karte, verschieden groß, verschieden schnell, mit
|
||||||
|
verschiedener Verzögerung. Gleich wäre Tapete.
|
||||||
|
|
||||||
|
SIE LIEGEN UNTER ALLEM (`z-index: 0` im eigenen Kontext, Text
|
||||||
|
darüber). Die Deckkraft liegt zwischen 10 und 16 Prozent — der erste
|
||||||
|
Versuch mit 5 bis 9 war auf dem Bildschirmfoto praktisch unsichtbar,
|
||||||
|
und „soll mega aussehen" heißt nicht „soll man erahnen können".
|
||||||
|
|
||||||
|
Nach oben ist trotzdem eine Grenze: Ab etwa 25 Prozent fängt das
|
||||||
|
Logo an, mit der Überschrift zu konkurrieren, und der Text wird
|
||||||
|
mühsam. Was hier entstehen soll, ist Tiefe, kein zweiter Titel.
|
||||||
|
|
||||||
|
`mask-image` statt `background-image`: Die PNG-Dateien tragen nur
|
||||||
|
Alpha. Die Farbe ist `currentColor` der Karte — dadurch ist das
|
||||||
|
Logo automatisch babyblau bzw. lila, ohne zweite Datei. */
|
||||||
|
.logo-feld {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: inherit;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-feld__stueck {
|
||||||
|
position: absolute;
|
||||||
|
background-color: var(--aussen-ton);
|
||||||
|
-webkit-mask-image: var(--logo);
|
||||||
|
mask-image: var(--logo);
|
||||||
|
-webkit-mask-repeat: no-repeat;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
-webkit-mask-size: contain;
|
||||||
|
mask-size: contain;
|
||||||
|
-webkit-mask-position: center;
|
||||||
|
mask-position: center;
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Die vier Lagen. Die Zahlen sind gesetzt, nicht gerechnet — ein
|
||||||
|
Zufallsgenerator würde bei jedem Laden anders aussehen, und dann
|
||||||
|
fällt niemandem mehr auf, wenn eines daneben liegt. */
|
||||||
|
.logo-feld__stueck[data-n="1"] {
|
||||||
|
width: 15rem; height: 15rem; right: -4.5rem; top: -3.5rem;
|
||||||
|
opacity: .16;
|
||||||
|
animation: logo-schweben-a 26s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
.logo-feld__stueck[data-n="2"] {
|
||||||
|
width: 8rem; height: 8rem; right: 4.5rem; bottom: -1.5rem;
|
||||||
|
opacity: .13;
|
||||||
|
animation: logo-schweben-b 34s ease-in-out infinite;
|
||||||
|
animation-delay: -6s;
|
||||||
|
}
|
||||||
|
.logo-feld__stueck[data-n="3"] {
|
||||||
|
width: 5rem; height: 5rem; right: 12rem; top: 35%;
|
||||||
|
opacity: .105;
|
||||||
|
animation: logo-schweben-a 41s ease-in-out infinite;
|
||||||
|
animation-delay: -15s;
|
||||||
|
}
|
||||||
|
.logo-feld__stueck[data-n="4"] {
|
||||||
|
width: 3.4rem; height: 3.4rem; right: 2rem; top: 18%;
|
||||||
|
opacity: .14;
|
||||||
|
animation: logo-schweben-b 29s ease-in-out infinite;
|
||||||
|
animation-delay: -21s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ZWEI BAHNEN, NICHT EINE. Mit nur einer bewegten sich alle vier
|
||||||
|
gleich — das sieht aus, als wackle die ganze Kachel. Die zweite
|
||||||
|
läuft andersherum, dadurch entsteht der Eindruck, dass sie
|
||||||
|
unabhängig voneinander treiben.
|
||||||
|
|
||||||
|
SEHR KLEINE WEGE (unter 14 px) und sehr lange Dauern (26–41 s). Was
|
||||||
|
man beim Hinsehen als Bewegung erkennt, lenkt beim Lesen ab. Das hier
|
||||||
|
merkt man erst, wenn man zweimal hinschaut — und genau das ist
|
||||||
|
gemeint mit „ganz leicht bewegen". */
|
||||||
|
@keyframes logo-schweben-a {
|
||||||
|
0% { transform: translate3d(0, 0, 0) rotate(0deg); }
|
||||||
|
33% { transform: translate3d(-9px, -11px, 0) rotate(2.5deg); }
|
||||||
|
66% { transform: translate3d(7px, -5px, 0) rotate(-1.8deg); }
|
||||||
|
100% { transform: translate3d(0, 0, 0) rotate(0deg); }
|
||||||
|
}
|
||||||
|
@keyframes logo-schweben-b {
|
||||||
|
0% { transform: translate3d(0, 0, 0) rotate(0deg); }
|
||||||
|
40% { transform: translate3d(8px, 9px, 0) rotate(-3deg); }
|
||||||
|
75% { transform: translate3d(-6px, 4px, 0) rotate(1.5deg); }
|
||||||
|
100% { transform: translate3d(0, 0, 0) rotate(0deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wer weniger Bewegung will, bekommt die Logos trotzdem — nur still.
|
||||||
|
Sie ganz zu entfernen wäre falsch: Sie sind Gestaltung, nicht
|
||||||
|
Animation. */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.logo-feld__stueck { animation: none; }
|
||||||
|
}
|
||||||
|
|
||||||
/* Der stille Schein im Hintergrund. Liegt UNTER allem (`z-index: -1`)
|
/* Der stille Schein im Hintergrund. Liegt UNTER allem (`z-index: -1`)
|
||||||
und ist so schwach, dass er bei Tageslicht kaum auffällt — er soll
|
und ist so schwach, dass er bei Tageslicht kaum auffällt — er soll
|
||||||
@@ -62,9 +193,9 @@
|
|||||||
height: 78%;
|
height: 78%;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
background: radial-gradient(60% 60% at 50% 50%,
|
background: radial-gradient(60% 60% at 50% 50%,
|
||||||
color-mix(in srgb, var(--aussen-ton) 22%, transparent), transparent 70%);
|
color-mix(in srgb, var(--aussen-ton) 34%, transparent), transparent 70%);
|
||||||
filter: blur(26px);
|
filter: blur(30px);
|
||||||
opacity: .55;
|
opacity: .7;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +206,14 @@
|
|||||||
box-shadow: 0 22px 40px -20px color-mix(in srgb, var(--aussen-ton) 85%, transparent);
|
box-shadow: 0 22px 40px -20px color-mix(in srgb, var(--aussen-ton) 85%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ALLES, WAS MAN LIEST, LIEGT ÜBER DEN LOGOS. Ohne diese Zeile wandert
|
||||||
|
der Text unter das Logofeld, sobald es eine eigene Ebene bekommt —
|
||||||
|
die Karte sähe dann leer aus, und man sucht den Fehler beim Text. */
|
||||||
|
.aussen > *:not(.logo-feld):not(.aussen__schein) {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.aussen__kopf {
|
.aussen__kopf {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1744,16 +1744,38 @@
|
|||||||
for (const a of faecher.keys()) {
|
for (const a of faecher.keys()) {
|
||||||
const fach = faecher.get(a);
|
const fach = faecher.get(a);
|
||||||
if (!fach.length) continue;
|
if (!fach.length) continue;
|
||||||
const kopf2 = el('h2', 'brettabschnitt');
|
/* JEDER ABSCHNITT LAESST SICH ZUKLAPPEN (19.09.2026).
|
||||||
|
|
||||||
|
Filipe: "man soll auf dieser seite jede kategorie auf und
|
||||||
|
zu klappen koennen mit einem button."
|
||||||
|
|
||||||
|
Der Kopf ist jetzt ein echter <button> und kein <h2> mit
|
||||||
|
Klickzuhoerer -- sonst waere er fuer die Tastatur nicht
|
||||||
|
erreichbar. Die Ueberschrift steckt darin, damit
|
||||||
|
Vorleseprogramme die Gliederung behalten.
|
||||||
|
|
||||||
|
Die Sprungmarke (#abschnitt-…) bleibt am Kopf: Wer aus dem
|
||||||
|
Inhaltsverzeichnis herspringt, landet weiterhin richtig --
|
||||||
|
auch wenn der Abschnitt gerade zu ist. */
|
||||||
|
const kopf2 = el('button', 'brettabschnitt');
|
||||||
|
kopf2.type = 'button';
|
||||||
kopf2.id = `abschnitt-${a}`;
|
kopf2.id = `abschnitt-${a}`;
|
||||||
kopf2.textContent = einstellung?.arten?.[a] || a;
|
kopf2.append(el('span', 'brettabschnitt__wort',
|
||||||
|
einstellung?.arten?.[a] || a));
|
||||||
kopf2.append(el('span', 'brettabschnitt__zahl', String(fach.length)));
|
kopf2.append(el('span', 'brettabschnitt__zahl', String(fach.length)));
|
||||||
|
if (window.klappPfeil) kopf2.append(window.klappPfeil());
|
||||||
ziel.append(kopf2);
|
ziel.append(kopf2);
|
||||||
|
|
||||||
|
const kasten = el('div', 'brettabschnitt__inhalt');
|
||||||
for (const e of fach) {
|
for (const e of fach) {
|
||||||
const k = karte(e);
|
const k = karte(e);
|
||||||
karten.set(e.id, k);
|
karten.set(e.id, k);
|
||||||
ziel.append(k);
|
kasten.append(k);
|
||||||
}
|
}
|
||||||
|
ziel.append(kasten);
|
||||||
|
/* Der Merker haengt am BRETT und an der Art -- sonst waere
|
||||||
|
"Regel zugeklappt" auf allen Brettern gleichzeitig zu. */
|
||||||
|
window.abschnittKlappbar?.(kopf2, kasten, `${bereich}:${a}`);
|
||||||
}
|
}
|
||||||
sprungZeigen(ziel, karten);
|
sprungZeigen(ziel, karten);
|
||||||
return;
|
return;
|
||||||
@@ -1780,14 +1802,24 @@
|
|||||||
const zb = zeitpunktVon(b)?.ms ?? 0;
|
const zb = zeitpunktVon(b)?.ms ?? 0;
|
||||||
return r === 'vorbei' ? zb - za : za - zb;
|
return r === 'vorbei' ? zb - za : za - zb;
|
||||||
});
|
});
|
||||||
const kopf = el('h2', 'zeitstrahl__schild', ABSCHNITT_NAME[r]);
|
/* Auch hier zuklappbar -- Filipe: "ueberall wo so eine
|
||||||
|
liste entstehen kann". Vorbei Gewesenes steht dabei von
|
||||||
|
sich aus zu: Es ist Nachschlagewerk, nicht das, weswegen
|
||||||
|
jemand die Seite oeffnet. */
|
||||||
|
const kopf = el('button', 'zeitstrahl__schild');
|
||||||
|
kopf.type = 'button';
|
||||||
|
kopf.append(el('span', 'zeitstrahl__wort', ABSCHNITT_NAME[r]));
|
||||||
kopf.append(el('span', 'zeitstrahl__zahl', String(fach.length)));
|
kopf.append(el('span', 'zeitstrahl__zahl', String(fach.length)));
|
||||||
|
if (window.klappPfeil) kopf.append(window.klappPfeil());
|
||||||
ziel.append(kopf);
|
ziel.append(kopf);
|
||||||
|
const kasten = el('div', 'zeitstrahl__inhalt');
|
||||||
for (const e of fach) {
|
for (const e of fach) {
|
||||||
const k = karte(e);
|
const k = karte(e);
|
||||||
karten.set(e.id, k);
|
karten.set(e.id, k);
|
||||||
ziel.append(k);
|
kasten.append(k);
|
||||||
}
|
}
|
||||||
|
ziel.append(kasten);
|
||||||
|
window.abschnittKlappbar?.(kopf, kasten, `ansteht:${r}`, r === 'vorbei');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const e of sichtbar) {
|
for (const e of sichtbar) {
|
||||||
|
|||||||
@@ -0,0 +1,345 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
VERTRAULICH MELDEN (19.09.2026)
|
||||||
|
|
||||||
|
Eine Seite, zwei Rollen: Ein Mitglied sieht seine eigenen Meldungen,
|
||||||
|
DogFather und die rechte Hand sehen alle. WELCHE das sind, entscheidet
|
||||||
|
der Server — diese Datei zeigt nur, was sie bekommt.
|
||||||
|
|
||||||
|
DIE REGEL "IMMER ABWECHSELND" STEHT NICHT HIER. Sie steht im Server
|
||||||
|
(`ich_bin_dran`), und diese Seite fragt danach. Zwei Stellen mit
|
||||||
|
derselben Regel wären zwei Stellen, die auseinanderlaufen — und die
|
||||||
|
im Browser wäre die, an der man sie umgehen kann.
|
||||||
|
|
||||||
|
KEIN innerHTML mit fremdem Text. Alles, was jemand geschrieben hat,
|
||||||
|
geht durch `textContent`. Hier landen Texte aus einem Streit —
|
||||||
|
ausgerechnet die will man nicht als HTML ausführen.
|
||||||
|
===================================================================== */
|
||||||
|
(() => {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const $ = (id) => document.getElementById(id);
|
||||||
|
const el = (was, klasse, text) => {
|
||||||
|
const e = document.createElement(was);
|
||||||
|
if (klasse) e.className = klasse;
|
||||||
|
if (text !== undefined) e.textContent = text;
|
||||||
|
return e;
|
||||||
|
};
|
||||||
|
|
||||||
|
let leitung = false;
|
||||||
|
let offeneEigene = 0;
|
||||||
|
let offenMax = 3;
|
||||||
|
|
||||||
|
/* ---- Wörter für die Zustände ----------------------------------------
|
||||||
|
|
||||||
|
Sie stehen hier als Anzeige-Texte, nicht als Regel. Der Server
|
||||||
|
schickt den Schlüssel; was daraus auf dem Bildschirm wird, ist eine
|
||||||
|
Frage der Sprache und darf sich ändern, ohne dass jemand die Logik
|
||||||
|
anfasst. */
|
||||||
|
const STAND_WORT = {
|
||||||
|
wartet_auf_antwort: { kurz: 'wartet auf Antwort', wer: 'leitung' },
|
||||||
|
antwort_da: { kurz: 'Antwort da', wer: 'melder' },
|
||||||
|
geschlossen: { kurz: 'abgeschlossen', wer: 'niemand' },
|
||||||
|
};
|
||||||
|
|
||||||
|
function melde(text) {
|
||||||
|
const f = $('fehler');
|
||||||
|
if (!f) return;
|
||||||
|
f.textContent = text || '';
|
||||||
|
f.hidden = !text;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function hole(pfad, einstellungen) {
|
||||||
|
const a = await fetch(pfad, { credentials: 'same-origin', ...einstellungen });
|
||||||
|
if (a.status === 401) { location.href = 'index.html'; throw new Error('weg'); }
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function datum(roh) {
|
||||||
|
if (!roh) return '';
|
||||||
|
const d = new Date(roh);
|
||||||
|
if (Number.isNaN(d.getTime())) return '';
|
||||||
|
return d.toLocaleString('de-DE',
|
||||||
|
{ day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
DIE LISTE
|
||||||
|
===================================================================== */
|
||||||
|
async function listeLaden() {
|
||||||
|
const ziel = $('liste');
|
||||||
|
try {
|
||||||
|
const a = await hole('/workspace/api/hilfe');
|
||||||
|
if (!a.ok) { melde('Die Liste ließ sich nicht laden.'); return; }
|
||||||
|
const d = await a.json();
|
||||||
|
leitung = !!d.leitung;
|
||||||
|
offeneEigene = d.offen_eigene ?? 0;
|
||||||
|
offenMax = d.offen_max ?? 3;
|
||||||
|
|
||||||
|
/* Die Seite heißt für beide anders — und das ist kein Schmuck:
|
||||||
|
"Deine Meldungen" wäre für DogFather schlicht falsch. */
|
||||||
|
$('seiten-titel').textContent = leitung ? 'Vertrauliche Meldungen' : 'Vertraulich melden';
|
||||||
|
$('listen-titel').textContent = leitung ? 'Alle Meldungen' : 'Deine Meldungen';
|
||||||
|
$('neu-block').hidden = leitung;
|
||||||
|
|
||||||
|
if (leitung) {
|
||||||
|
$('seiten-unter').textContent =
|
||||||
|
'Was die Community vertraulich gemeldet hat. Du siehst den Namen; sonst niemand.';
|
||||||
|
$('vertrauen-text').textContent =
|
||||||
|
'Diese Meldungen sehen nur du und die rechte Hand. Weder Modis noch '
|
||||||
|
+ 'andere Mitglieder haben Zugriff — auch nicht auf die Namen.';
|
||||||
|
}
|
||||||
|
|
||||||
|
const faelle = d.faelle || [];
|
||||||
|
$('listen-zahl').textContent = faelle.length
|
||||||
|
? `${faelle.length}` : '';
|
||||||
|
|
||||||
|
ziel.textContent = '';
|
||||||
|
ziel.removeAttribute('aria-busy');
|
||||||
|
|
||||||
|
if (!faelle.length) {
|
||||||
|
const leer = el('p', 'hilfe-leer', leitung
|
||||||
|
? 'Nichts gemeldet. Das ist die beste Nachricht auf dieser Seite.'
|
||||||
|
: 'Du hast noch nichts gemeldet. Gut so – und wenn doch mal etwas ist, '
|
||||||
|
+ 'ist der Weg hier.');
|
||||||
|
ziel.append(leer);
|
||||||
|
knopfStand();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const f of faelle) ziel.append(zeileBauen(f));
|
||||||
|
knopfStand();
|
||||||
|
} catch (fehler) {
|
||||||
|
if (String(fehler.message) !== 'weg') melde('Keine Verbindung.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function zeileBauen(f) {
|
||||||
|
const k = el('article', 'fall-zeile');
|
||||||
|
k.dataset.stand = f.stand;
|
||||||
|
k.tabIndex = 0;
|
||||||
|
k.setAttribute('role', 'button');
|
||||||
|
|
||||||
|
const oben = el('div', 'fall-zeile__oben');
|
||||||
|
const marke = el('span', 'fall-marke', STAND_WORT[f.stand]?.kurz || f.stand);
|
||||||
|
marke.dataset.stand = f.stand;
|
||||||
|
oben.append(marke);
|
||||||
|
oben.append(el('h3', 'fall-zeile__titel', f.betreff));
|
||||||
|
k.append(oben);
|
||||||
|
|
||||||
|
const unten = el('p', 'fall-zeile__unten');
|
||||||
|
/* Der Name nur, wenn der Server ihn geschickt hat — er kommt gar
|
||||||
|
nicht erst mit, wenn jemand anderes fragt. */
|
||||||
|
if (f.melder) unten.append(el('span', 'fall-zeile__wer', f.melder));
|
||||||
|
unten.append(el('span', 'fall-zeile__zeit', datum(f.geaendert)));
|
||||||
|
unten.append(el('span', 'fall-zeile__anzahl',
|
||||||
|
f.nachrichten === 1 ? '1 Nachricht' : `${f.nachrichten} Nachrichten`));
|
||||||
|
k.append(unten);
|
||||||
|
|
||||||
|
const auf = () => fallOeffnen(f.id);
|
||||||
|
k.addEventListener('click', auf);
|
||||||
|
k.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); auf(); }
|
||||||
|
});
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Darf noch eine Meldung aufgemacht werden? */
|
||||||
|
function knopfStand() {
|
||||||
|
const knopf = $('neu-auf');
|
||||||
|
if (!knopf || leitung) return;
|
||||||
|
const voll = offeneEigene >= offenMax;
|
||||||
|
knopf.disabled = voll;
|
||||||
|
knopf.title = voll
|
||||||
|
? `Du hast ${offeneEigene} offene Meldungen. Warte auf eine Antwort, `
|
||||||
|
+ 'bevor du die nächste aufmachst.'
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
EIN FALL
|
||||||
|
===================================================================== */
|
||||||
|
async function fallOeffnen(id) {
|
||||||
|
try {
|
||||||
|
const a = await hole('/workspace/api/hilfe/' + id);
|
||||||
|
if (a.status === 404) { melde('Diese Meldung gibt es nicht (mehr).'); return; }
|
||||||
|
if (!a.ok) { melde('Der Fall ließ sich nicht öffnen.'); return; }
|
||||||
|
const d = await a.json();
|
||||||
|
fallZeigen(d);
|
||||||
|
/* Die Adresse merkt sich den Fall — damit eine Benachrichtigung
|
||||||
|
direkt hierher führen kann und ein Neuladen nicht zur Liste
|
||||||
|
zurückwirft. */
|
||||||
|
history.replaceState(null, '', 'hilfe.html?fall=' + id);
|
||||||
|
} catch (fehler) {
|
||||||
|
if (String(fehler.message) !== 'weg') melde('Keine Verbindung.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fallZeigen(d) {
|
||||||
|
const f = d.fall;
|
||||||
|
$('fall-block').hidden = false;
|
||||||
|
$('fall-titel').textContent = f.betreff;
|
||||||
|
|
||||||
|
const kopf = $('fall-kopf');
|
||||||
|
kopf.textContent = '';
|
||||||
|
const marke = el('span', 'fall-marke', STAND_WORT[f.stand]?.kurz || f.stand);
|
||||||
|
marke.dataset.stand = f.stand;
|
||||||
|
kopf.append(marke);
|
||||||
|
if (f.melder) kopf.append(el('span', 'fall-kopf__wer', 'von ' + f.melder));
|
||||||
|
kopf.append(el('span', 'fall-kopf__zeit', 'seit ' + datum(f.erstellt)));
|
||||||
|
|
||||||
|
const ziel = $('verlauf');
|
||||||
|
ziel.textContent = '';
|
||||||
|
for (const n of d.nachrichten || []) {
|
||||||
|
const b = el('div', 'blase');
|
||||||
|
b.dataset.seite = n.von_leitung ? 'leitung' : 'melder';
|
||||||
|
b.append(el('p', 'blase__wer', n.von_leitung ? 'DogFather / rechte Hand' : (f.melder || 'Du')));
|
||||||
|
/* Zeilenumbrüche erhalten, ohne HTML zuzulassen: white-space im
|
||||||
|
CSS, Text über textContent. */
|
||||||
|
b.append(el('p', 'blase__text', n.text));
|
||||||
|
const fuss = el('p', 'blase__fuss', datum(n.erstellt));
|
||||||
|
if (!n.von_leitung && n.gelesen) fuss.textContent += ' · gelesen';
|
||||||
|
b.append(fuss);
|
||||||
|
ziel.append(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = $('antwort-form');
|
||||||
|
const warten = $('fall-warten');
|
||||||
|
const zuKnopf = $('fall-schliessen');
|
||||||
|
|
||||||
|
zuKnopf.hidden = !(d.leitung && f.stand !== 'geschlossen');
|
||||||
|
zuKnopf.onclick = () => fallSchliessen(f.id);
|
||||||
|
|
||||||
|
if (f.stand === 'geschlossen') {
|
||||||
|
form.hidden = true;
|
||||||
|
warten.hidden = false;
|
||||||
|
warten.textContent = 'Dieser Fall ist abgeschlossen'
|
||||||
|
+ (f.geschlossen_am ? ' (' + datum(f.geschlossen_am) + ')' : '') + '.';
|
||||||
|
} else if (d.ich_bin_dran) {
|
||||||
|
form.hidden = false;
|
||||||
|
warten.hidden = true;
|
||||||
|
$('antwort-schild').textContent = d.leitung ? 'Deine Antwort' : 'Deine Antwort';
|
||||||
|
form.onsubmit = (e) => { e.preventDefault(); antwortSenden(f.id); };
|
||||||
|
} else {
|
||||||
|
form.hidden = true;
|
||||||
|
warten.hidden = false;
|
||||||
|
/* DER SATZ SAGT, WER DRAN IST. "Bitte warten" allein lässt offen,
|
||||||
|
worauf — und ob überhaupt noch etwas kommt. */
|
||||||
|
warten.textContent = d.leitung
|
||||||
|
? 'Die andere Seite ist am Zug. Sobald sie antwortet, kannst du wieder schreiben.'
|
||||||
|
: 'Deine Meldung ist angekommen. Sobald eine Antwort da ist, siehst du sie hier '
|
||||||
|
+ '– und bekommst eine Benachrichtigung, wenn du sie erlaubt hast.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$('fall-block').scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function antwortSenden(id) {
|
||||||
|
const feld = $('antwort-text');
|
||||||
|
const text = feld.value.trim();
|
||||||
|
if (text.length < 2) { $('antwort-stand').textContent = 'Da fehlt noch etwas.'; return; }
|
||||||
|
$('antwort-senden').disabled = true;
|
||||||
|
$('antwort-stand').textContent = 'wird gesendet …';
|
||||||
|
try {
|
||||||
|
const a = await hole('/workspace/api/hilfe/' + id + '/antwort', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ text }),
|
||||||
|
});
|
||||||
|
const j = await a.json().catch(() => ({}));
|
||||||
|
if (!a.ok) {
|
||||||
|
$('antwort-stand').textContent =
|
||||||
|
j.fehler === 'nicht_dran' ? 'Die andere Seite ist gerade am Zug.'
|
||||||
|
: j.fehler === 'geschlossen' ? 'Dieser Fall ist schon abgeschlossen.'
|
||||||
|
: 'Ging nicht.';
|
||||||
|
$('antwort-senden').disabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
feld.value = '';
|
||||||
|
$('antwort-stand').textContent = 'gesendet';
|
||||||
|
await fallOeffnen(id);
|
||||||
|
await listeLaden();
|
||||||
|
} catch { $('antwort-stand').textContent = 'Keine Verbindung.'; }
|
||||||
|
$('antwort-senden').disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fallSchliessen(id) {
|
||||||
|
const wort = prompt('Ein Schlusswort? (Kann auch leer bleiben)');
|
||||||
|
if (wort === null) return;
|
||||||
|
try {
|
||||||
|
const a = await hole('/workspace/api/hilfe/' + id + '/schliessen', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ text: wort }),
|
||||||
|
});
|
||||||
|
if (!a.ok) { melde('Ließ sich nicht abschließen.'); return; }
|
||||||
|
await fallOeffnen(id);
|
||||||
|
await listeLaden();
|
||||||
|
} catch { melde('Keine Verbindung.'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
NEUE MELDUNG
|
||||||
|
===================================================================== */
|
||||||
|
$('neu-auf')?.addEventListener('click', () => {
|
||||||
|
$('neu-form').hidden = false;
|
||||||
|
$('neu-auf').hidden = true;
|
||||||
|
$('neu-betreff').focus();
|
||||||
|
});
|
||||||
|
$('neu-zu')?.addEventListener('click', () => {
|
||||||
|
$('neu-form').hidden = true;
|
||||||
|
$('neu-auf').hidden = false;
|
||||||
|
$('neu-stand').textContent = '';
|
||||||
|
});
|
||||||
|
|
||||||
|
$('neu-form')?.addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const betreff = $('neu-betreff').value.trim();
|
||||||
|
const text = $('neu-text').value.trim();
|
||||||
|
const stand = $('neu-stand');
|
||||||
|
if (betreff.length < 3) { stand.textContent = 'Eine kurze Überschrift fehlt noch.'; return; }
|
||||||
|
if (text.length < 10) { stand.textContent = 'Schreib bitte ein paar Sätze mehr.'; return; }
|
||||||
|
|
||||||
|
$('neu-senden').disabled = true;
|
||||||
|
stand.textContent = 'wird gesendet …';
|
||||||
|
try {
|
||||||
|
const a = await hole('/workspace/api/hilfe', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ betreff, text }),
|
||||||
|
});
|
||||||
|
const j = await a.json().catch(() => ({}));
|
||||||
|
if (!a.ok) {
|
||||||
|
stand.textContent =
|
||||||
|
j.fehler === 'zu_viele_offen'
|
||||||
|
? `Du hast schon ${j.offen} offene Meldungen. Warte auf eine Antwort.`
|
||||||
|
: j.fehler === 'text_zu_kurz' ? 'Schreib bitte ein paar Sätze mehr.'
|
||||||
|
: 'Ging nicht.';
|
||||||
|
$('neu-senden').disabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('neu-betreff').value = '';
|
||||||
|
$('neu-text').value = '';
|
||||||
|
$('neu-form').hidden = true;
|
||||||
|
$('neu-auf').hidden = false;
|
||||||
|
stand.textContent = '';
|
||||||
|
await listeLaden();
|
||||||
|
if (j.id) await fallOeffnen(j.id);
|
||||||
|
} catch { stand.textContent = 'Keine Verbindung.'; }
|
||||||
|
$('neu-senden').disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('fall-zurueck')?.addEventListener('click', () => {
|
||||||
|
$('fall-block').hidden = true;
|
||||||
|
history.replaceState(null, '', 'hilfe.html');
|
||||||
|
document.querySelector('.hilfe-block')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ---- Los ------------------------------------------------------------ */
|
||||||
|
(async () => {
|
||||||
|
await listeLaden();
|
||||||
|
/* Kommt jemand über eine Benachrichtigung, steht der Fall in der
|
||||||
|
Adresse — dann direkt aufmachen, statt ihn suchen zu lassen. */
|
||||||
|
const fall = new URLSearchParams(location.search).get('fall');
|
||||||
|
if (fall && /^\d+$/.test(fall)) await fallOeffnen(fall);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
@@ -370,6 +370,97 @@
|
|||||||
stand(false);
|
stand(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ---------- GANZE ABSCHNITTE AUF UND ZU (19.09.2026) ------------------
|
||||||
|
|
||||||
|
Filipe: „man soll auf dieser seite jede kategorie auf und zu
|
||||||
|
klappen können mit einem button, übrigens will ich das überall
|
||||||
|
überall wo so eine liste entstehen kann hatte ich dir schon mal
|
||||||
|
gesagt."
|
||||||
|
|
||||||
|
UNTERSCHIED ZU `klappe()` DARÜBER: Das dort verbirgt die hinteren
|
||||||
|
Zeilen EINER Liste („nur die letzten 4"). Das hier klappt einen
|
||||||
|
ganzen Abschnitt samt Überschrift zu. Zwei verschiedene Fragen,
|
||||||
|
deshalb zwei Funktionen — eine, die beides kann, müsste bei jedem
|
||||||
|
Aufruf erklärt bekommen, was gemeint ist.
|
||||||
|
|
||||||
|
DAS MUSTER STAMMT VON DER STARTSEITE, wo es seit dem 10.09.2026
|
||||||
|
funktioniert: ein Knopf als Überschrift, ein Pfeil, der sich dreht,
|
||||||
|
der Zustand in localStorage. Es steht jetzt hier, weil Filipe es
|
||||||
|
„überall" haben will — und weil eine zweite Abschrift die wäre, die
|
||||||
|
beim nächsten Umbau ausschert. (start.js hat seine eigene Fassung
|
||||||
|
noch; sie tut dasselbe und ist geprüft. Wer sie anfasst, stellt sie
|
||||||
|
auf diese hier um.)
|
||||||
|
|
||||||
|
`schluessel` darf fehlen: Dann merkt sich die Seite nichts und
|
||||||
|
alles steht beim nächsten Besuch offen. Das ist der richtige
|
||||||
|
Rückfall — ein Abschnitt, der zu ist und von dem man nicht mehr
|
||||||
|
weiß, warum, sieht aus wie fehlender Inhalt. */
|
||||||
|
window.abschnittKlappbar = function (kopf, kasten, schluessel, zuVorgabe = false) {
|
||||||
|
if (!kopf || !kasten) return;
|
||||||
|
|
||||||
|
/* Der Knopf muss ein Knopf sein. Ein `<h2 onclick>` ist für die
|
||||||
|
Tastatur nicht erreichbar und für Vorleseprogramme unsichtbar. */
|
||||||
|
if (kopf.tagName !== 'BUTTON') kopf.setAttribute('role', 'button');
|
||||||
|
if (!kopf.hasAttribute('tabindex') && kopf.tagName !== 'BUTTON') kopf.tabIndex = 0;
|
||||||
|
|
||||||
|
let zu = zuVorgabe;
|
||||||
|
if (schluessel) {
|
||||||
|
try {
|
||||||
|
const gemerkt = localStorage.getItem('abschnitt:' + schluessel);
|
||||||
|
if (gemerkt) zu = gemerkt === 'zu';
|
||||||
|
} catch { /* privates Fenster: dann eben die Vorgabe */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
const stand = (istZu) => {
|
||||||
|
kopf.dataset.zu = istZu ? 'ja' : 'nein';
|
||||||
|
kopf.setAttribute('aria-expanded', istZu ? 'false' : 'true');
|
||||||
|
kasten.hidden = istZu;
|
||||||
|
};
|
||||||
|
stand(zu);
|
||||||
|
|
||||||
|
/* NUR EINMAL EINHÄNGEN. Die Bretter bauen sich bei jeder
|
||||||
|
Aktualisierung neu auf; hinge der Zuhörer zweimal daran, würde
|
||||||
|
ein Klick zweimal umschalten und damit gar nichts tun. */
|
||||||
|
if (kopf.dataset.klappBereit) return;
|
||||||
|
kopf.dataset.klappBereit = 'ja';
|
||||||
|
|
||||||
|
const um = () => {
|
||||||
|
zu = !zu;
|
||||||
|
stand(zu);
|
||||||
|
if (schluessel) {
|
||||||
|
try { localStorage.setItem('abschnitt:' + schluessel, zu ? 'zu' : 'auf'); }
|
||||||
|
catch { /* egal */ }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
kopf.addEventListener('click', um);
|
||||||
|
if (kopf.tagName !== 'BUTTON') {
|
||||||
|
kopf.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); um(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Der Pfeil, der sich beim Zuklappen dreht.
|
||||||
|
*
|
||||||
|
* Als Funktion, damit nicht an jeder Stelle dasselbe SVG steht --
|
||||||
|
* und damit ein späterer anderer Pfeil an EINER Stelle geändert
|
||||||
|
* wird. */
|
||||||
|
window.klappPfeil = function () {
|
||||||
|
const p = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
|
p.setAttribute('class', 'klapp-pfeil');
|
||||||
|
p.setAttribute('viewBox', '0 0 24 24');
|
||||||
|
p.setAttribute('aria-hidden', 'true');
|
||||||
|
const weg = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||||
|
weg.setAttribute('d', 'm6 9.5 6 6 6-6');
|
||||||
|
weg.setAttribute('fill', 'none');
|
||||||
|
weg.setAttribute('stroke', 'currentColor');
|
||||||
|
weg.setAttribute('stroke-width', '2.2');
|
||||||
|
weg.setAttribute('stroke-linecap', 'round');
|
||||||
|
weg.setAttribute('stroke-linejoin', 'round');
|
||||||
|
p.append(weg);
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
/* Gibt es eine sinnvolle vorherige Seite INNERHALB des Workspace?
|
/* Gibt es eine sinnvolle vorherige Seite INNERHALB des Workspace?
|
||||||
|
|
||||||
Blindes history.back() reicht nicht: Wer die Adresse direkt eingibt
|
Blindes history.back() reicht nicht: Wer die Adresse direkt eingibt
|
||||||
|
|||||||
+12
-12
@@ -12,19 +12,19 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -291,10 +291,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/aufgaben.js?v=202609190139" defer></script>
|
<script src="assets/js/aufgaben.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/automation.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/automation.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -168,10 +168,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/automation.js?v=202609190139" defer></script>
|
<script src="assets/js/automation.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+12
-12
@@ -7,14 +7,14 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -105,9 +105,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/befinden.js?v=202609190139" defer></script>
|
<script src="assets/js/befinden.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+18
-18
@@ -12,24 +12,24 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/bereich.css?v=202609190204" />
|
||||||
<!-- Wegen des Blocks „Willst du dazugehoeren?" auf dem Brett
|
<!-- Wegen des Blocks „Willst du dazugehoeren?" auf dem Brett
|
||||||
„Mitmachen". Eine eigene Kopie der Regel hier waere die zweite
|
„Mitmachen". Eine eigene Kopie der Regel hier waere die zweite
|
||||||
Stelle, an der dieselbe Sache anders aussieht. -->
|
Stelle, an der dieselbe Sache anders aussieht. -->
|
||||||
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -251,14 +251,14 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/checkliste.js?v=202609190139" defer></script>
|
<script src="assets/js/checkliste.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/ampel.js?v=202609190139" defer></script>
|
<script src="assets/js/ampel.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/schulung.js?v=202609190139" defer></script>
|
<script src="assets/js/schulung.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/vorlagen.js?v=202609190139" defer></script>
|
<script src="assets/js/vorlagen.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereich.js?v=202609190139" defer></script>
|
<script src="assets/js/bereich.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+15
-15
@@ -7,17 +7,17 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/bereich.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/treff.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/treff.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein - siehe treff-regeln.html. -->
|
<!-- haus.css MUSS die letzte Stilvorlage sein - siehe treff-regeln.html. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -108,10 +108,10 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Der Fuß gehört zu jeder Seite - siehe pruef-css-klassen. -->
|
<!-- Der Fuß gehört zu jeder Seite - siehe pruef-css-klassen. -->
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/auskunft.js?v=202609190139" defer></script>
|
<script src="assets/js/auskunft.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bewerben.js?v=202609190139" defer></script>
|
<script src="assets/js/bewerben.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -7,16 +7,16 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein - siehe treff-regeln.html. -->
|
<!-- haus.css MUSS die letzte Stilvorlage sein - siehe treff-regeln.html. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -80,10 +80,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/auskunft.js?v=202609190139" defer></script>
|
<script src="assets/js/auskunft.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bewerbungen.js?v=202609190139" defer></script>
|
<script src="assets/js/bewerbungen.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/calls.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/calls.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -89,11 +89,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609190139" defer></script>
|
<script src="assets/js/ki.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/calls.js?v=202609190139" defer></script>
|
<script src="assets/js/calls.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,26 +12,26 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
|
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
|
||||||
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
|
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
|
||||||
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
|
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
|
||||||
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
|
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
|
||||||
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
|
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
|
||||||
Dialog zu sehen bekam. -->
|
Dialog zu sehen bekam. -->
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/chat.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/chat.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -341,15 +341,15 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/bereiche.js?v=202609190139"></script>
|
<script src="assets/js/bereiche.js?v=202609190204"></script>
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139"></script>
|
<script src="assets/js/kopf.js?v=202609190204"></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139"></script>
|
<script src="assets/js/glocke.js?v=202609190204"></script>
|
||||||
<!-- ANRUF VOR CHAT (18.09.2026): anruf.js stellt `window.anrufStarten`
|
<!-- ANRUF VOR CHAT (18.09.2026): anruf.js stellt `window.anrufStarten`
|
||||||
bereit, und chat.js baut die Knoepfe nur, wenn es das gibt.
|
bereit, und chat.js baut die Knoepfe nur, wenn es das gibt.
|
||||||
Andersherum waere die Reihenfolge eine stille Abhaengigkeit --
|
Andersherum waere die Reihenfolge eine stille Abhaengigkeit --
|
||||||
die Knoepfe fehlten, und niemand wuesste warum. -->
|
die Knoepfe fehlten, und niemand wuesste warum. -->
|
||||||
<script src="assets/js/anruf.js?v=202609190139"></script>
|
<script src="assets/js/anruf.js?v=202609190204"></script>
|
||||||
<script src="assets/js/chat.js?v=202609190139"></script>
|
<script src="assets/js/chat.js?v=202609190204"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+15
-15
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/content.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/content.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -179,12 +179,12 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/checkliste.js?v=202609190139" defer></script>
|
<script src="assets/js/checkliste.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/vorlagen.js?v=202609190139" defer></script>
|
<script src="assets/js/vorlagen.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/content.js?v=202609190139" defer></script>
|
<script src="assets/js/content.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -36,15 +36,15 @@
|
|||||||
<link rel="preload" as="image" href="assets/img/buehne/crew-gate-hoch-580.webp"
|
<link rel="preload" as="image" href="assets/img/buehne/crew-gate-hoch-580.webp"
|
||||||
type="image/webp" media="(max-width: 899px)" />
|
type="image/webp" media="(max-width: 899px)" />
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/crew-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/crew-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/crew-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/crew-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<!-- Diese Wand steht NUR auf der Adresse von Team Dogi (ueberall sonst
|
<!-- Diese Wand steht NUR auf der Adresse von Team Dogi (ueberall sonst
|
||||||
404, siehe crewWeiche). Sie darf das Haus deshalb direkt nennen
|
404, siehe crewWeiche). Sie darf das Haus deshalb direkt nennen
|
||||||
statt ueber den Platzhalter haus.css zu gehen -- und sie MUSS es:
|
statt ueber den Platzhalter haus.css zu gehen -- und sie MUSS es:
|
||||||
Eine Zugangswand, die sich erst nach dem Umbiegen faerbt, waere
|
Eine Zugangswand, die sich erst nach dem Umbiegen faerbt, waere
|
||||||
die eine Seite, auf der man das Umfaerben sieht. -->
|
die eine Seite, auf der man das Umfaerben sieht. -->
|
||||||
<link rel="stylesheet" href="assets/css/crew-haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/crew-haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="gate gate--crew">
|
<body class="gate gate--crew">
|
||||||
@@ -339,6 +339,6 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/gate.js?v=202609190139" defer></script>
|
<script src="assets/js/gate.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -22,25 +22,25 @@
|
|||||||
},
|
},
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-192.png?v=202609190139",
|
"src": "/assets/img/app-symbole/crew-192.png?v=202609190204",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-512.png?v=202609190139",
|
"src": "/assets/img/app-symbole/crew-512.png?v=202609190204",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609190139",
|
"src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609190204",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609190139",
|
"src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609190204",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/dateien.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/dateien.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -108,10 +108,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/dateien.js?v=202609190139" defer></script>
|
<script src="assets/js/dateien.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+17
-13
@@ -7,14 +7,14 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -40,7 +40,11 @@
|
|||||||
<section class="kopf-zeile">
|
<section class="kopf-zeile">
|
||||||
<div>
|
<div>
|
||||||
<p class="marke" id="ober">Entwicklung & Nachwuchs</p>
|
<p class="marke" id="ober">Entwicklung & Nachwuchs</p>
|
||||||
<h1 class="titel" id="titel">Entwicklung</h1>
|
<!-- UMBENANNT AM 19.09.2026 (siehe workspace.js). Diese Seite ist
|
||||||
|
der Aufgabenkatalog: was ein Modi koennen soll und wo er
|
||||||
|
gerade steht. Der Name "Entwicklung" bleibt dem vorbehalten,
|
||||||
|
was Filipe darunter versteht -- einer Auswertung je Person. -->
|
||||||
|
<h1 class="titel" id="titel">Eure Aufgaben</h1>
|
||||||
<p class="unterzeile" id="unterzeile">
|
<p class="unterzeile" id="unterzeile">
|
||||||
Anklicken statt tippen. Keine Noten, keine Punktzahl – ein Gesprächsanlass.
|
Anklicken statt tippen. Keine Noten, keine Punktzahl – ein Gesprächsanlass.
|
||||||
</p>
|
</p>
|
||||||
@@ -102,9 +106,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/entwicklung.js?v=202609190139" defer></script>
|
<script src="assets/js/entwicklung.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||||
|
<title>Vertraulich melden · Der Treff</title>
|
||||||
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
|
<meta name="theme-color" content="#06090f" />
|
||||||
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
|
<link rel="stylesheet" href="assets/css/hilfe.css?v=202609190204" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="start">
|
||||||
|
|
||||||
|
<div class="schleier" aria-hidden="true"></div>
|
||||||
|
|
||||||
|
<header class="kopfleiste">
|
||||||
|
<button type="button" class="zurueck-knopf" id="zurueck" hidden>
|
||||||
|
<svg class="zurueck-knopf__pfeil" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path d="M14.5 5.5 8 12l6.5 6.5" />
|
||||||
|
</svg>
|
||||||
|
<span class="zurueck-knopf__text">Zurück</span>
|
||||||
|
</button>
|
||||||
|
<p class="marke"><span class="marke__text"><a class="zurueck" href="start.html">Der Treff</a> · Vertraulich</span></p>
|
||||||
|
<div class="kopfleiste__rechts">
|
||||||
|
<span class="wer" id="wer">…</span>
|
||||||
|
<button type="button" class="abmelden" id="abmelden">Abmelden</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="inhalt inhalt--breit">
|
||||||
|
|
||||||
|
<section class="kopf-zeile">
|
||||||
|
<div>
|
||||||
|
<p class="marke">Der Treff · Vertraulich</p>
|
||||||
|
<h1 class="titel" id="seiten-titel">Vertraulich melden</h1>
|
||||||
|
<p class="unterzeile" id="seiten-unter">
|
||||||
|
Wenn etwas nicht stimmt – hier schreibst du direkt an DogFather.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ==================================================================
|
||||||
|
WARUM HIER "VERTRAULICH" STEHT UND NICHT "ANONYM"
|
||||||
|
|
||||||
|
Filipe hat es "anonym" genannt, und gegenüber den anderen
|
||||||
|
Mitgliedern ist es das auch: Niemand sonst sieht diese Meldungen,
|
||||||
|
kein Modi, kein anderes Mitglied.
|
||||||
|
|
||||||
|
Aber DogFather und die rechte Hand sehen den Namen — so ist es
|
||||||
|
bestellt, und es ist auch richtig so: Ohne Namen kann man
|
||||||
|
niemandem helfen. Wer glaubt, er schreibe unerkannt, schreibt
|
||||||
|
anders und fühlt sich hinterher getäuscht. Deshalb steht der
|
||||||
|
Satz oben im Formular, bevor jemand tippt.
|
||||||
|
============================================================== -->
|
||||||
|
|
||||||
|
<p class="fehler" id="fehler" role="alert" aria-live="polite"></p>
|
||||||
|
|
||||||
|
<!-- Der Hinweis, wer mitliest. Steht VOR allem anderen. -->
|
||||||
|
<div class="vertrauen" id="vertrauen">
|
||||||
|
<span class="vertrauen__zeichen" aria-hidden="true">
|
||||||
|
<svg viewBox="0 0 24 24">
|
||||||
|
<path d="M12 3.2 5 6v5.6c0 4.3 2.9 7.6 7 9.2 4.1-1.6 7-4.9 7-9.2V6z" />
|
||||||
|
<path d="M9.2 12.2l2 2 3.6-4" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<p class="vertrauen__text" id="vertrauen-text">
|
||||||
|
<strong>DogFather und die rechte Hand lesen mit – sonst niemand.</strong>
|
||||||
|
Sie sehen auch deinen Namen. Kein anderes Mitglied und kein Modi
|
||||||
|
bekommt diese Meldungen zu Gesicht.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ---- NEU MELDEN (nur für Mitglieder) ------------------------- -->
|
||||||
|
<section class="hilfe-block" id="neu-block" hidden>
|
||||||
|
<div class="hilfe-block__kopf">
|
||||||
|
<h2 class="hilfe-block__titel">Etwas melden</h2>
|
||||||
|
<button type="button" class="knopf knopf--klein" id="neu-auf">Neue Meldung</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="hilfe-form" id="neu-form" hidden>
|
||||||
|
<label class="feld">
|
||||||
|
<span class="feld__schild">Worum geht es? <span class="feld__pflicht">kurz</span></span>
|
||||||
|
<input type="text" id="neu-betreff" maxlength="120" autocomplete="off"
|
||||||
|
placeholder="z. B. Jemand geht mich im Chat immer wieder an" />
|
||||||
|
</label>
|
||||||
|
<label class="feld">
|
||||||
|
<span class="feld__schild">Was ist passiert?</span>
|
||||||
|
<textarea id="neu-text" rows="6" maxlength="4000"
|
||||||
|
placeholder="Schreib so viel, wie du willst. Wann war es, wer war dabei, was ist passiert?"></textarea>
|
||||||
|
</label>
|
||||||
|
<p class="hilfe-form__hinweis">
|
||||||
|
Nach dem Absenden wartest du auf eine Antwort. Erst wenn eine da
|
||||||
|
ist, kannst du wieder schreiben – so geht nichts durcheinander.
|
||||||
|
</p>
|
||||||
|
<div class="hilfe-form__fuss">
|
||||||
|
<button type="submit" class="knopf" id="neu-senden">Meldung abschicken</button>
|
||||||
|
<button type="button" class="knopf knopf--still" id="neu-zu">Abbrechen</button>
|
||||||
|
<span class="hilfe-form__stand" id="neu-stand" role="status" aria-live="polite"></span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ---- DIE LISTE ----------------------------------------------- -->
|
||||||
|
<section class="hilfe-block">
|
||||||
|
<div class="hilfe-block__kopf">
|
||||||
|
<h2 class="hilfe-block__titel" id="listen-titel">Deine Meldungen</h2>
|
||||||
|
<span class="hilfe-block__zahl" id="listen-zahl"></span>
|
||||||
|
</div>
|
||||||
|
<div id="liste" aria-busy="true"><p class="leise">wird geladen …</p></div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ---- EIN FALL ------------------------------------------------- -->
|
||||||
|
<section class="hilfe-block" id="fall-block" hidden>
|
||||||
|
<div class="hilfe-block__kopf">
|
||||||
|
<h2 class="hilfe-block__titel" id="fall-titel">…</h2>
|
||||||
|
<button type="button" class="knopf knopf--klein knopf--still" id="fall-zurueck">Zur Liste</button>
|
||||||
|
</div>
|
||||||
|
<p class="fall-kopf" id="fall-kopf"></p>
|
||||||
|
<div id="verlauf"></div>
|
||||||
|
|
||||||
|
<form class="hilfe-form hilfe-form--antwort" id="antwort-form" hidden>
|
||||||
|
<label class="feld">
|
||||||
|
<span class="feld__schild" id="antwort-schild">Deine Antwort</span>
|
||||||
|
<textarea id="antwort-text" rows="4" maxlength="4000"></textarea>
|
||||||
|
</label>
|
||||||
|
<div class="hilfe-form__fuss">
|
||||||
|
<button type="submit" class="knopf" id="antwort-senden">Absenden</button>
|
||||||
|
<button type="button" class="knopf knopf--still" id="fall-schliessen" hidden>Fall abschließen</button>
|
||||||
|
<span class="hilfe-form__stand" id="antwort-stand" role="status" aria-live="polite"></span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<p class="fall-warten" id="fall-warten" hidden></p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
|
<script src="assets/js/hilfe.js?v=202609190204" defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
<link rel="preload" as="image" href="assets/img/buehne/gate-hoch-580.webp"
|
<link rel="preload" as="image" href="assets/img/buehne/gate-hoch-580.webp"
|
||||||
type="image/webp" media="(max-width: 899px)" />
|
type="image/webp" media="(max-width: 899px)" />
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="gate">
|
<body class="gate">
|
||||||
@@ -401,6 +401,6 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/gate.js?v=202609190139" defer></script>
|
<script src="assets/js/gate.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/kalender.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/kalender.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -377,11 +377,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kalender.js?v=202609190139" defer></script>
|
<script src="assets/js/kalender.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kalender-abo.js?v=202609190139" defer></script>
|
<script src="assets/js/kalender-abo.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/leistung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/leistung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -444,10 +444,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139"></script>
|
<script src="assets/js/wahl.js?v=202609190204"></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139"></script>
|
<script src="assets/js/bereiche.js?v=202609190204"></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139"></script>
|
<script src="assets/js/kopf.js?v=202609190204"></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139"></script>
|
<script src="assets/js/glocke.js?v=202609190204"></script>
|
||||||
<script src="assets/js/leistung.js?v=202609190139"></script>
|
<script src="assets/js/leistung.js?v=202609190204"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/personen.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/personen.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -423,10 +423,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/personen.js?v=202609190139" defer></script>
|
<script src="assets/js/personen.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/profil.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/profil.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -214,11 +214,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/steckbrief.js?v=202609190139" defer></script>
|
<script src="assets/js/steckbrief.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/profil.js?v=202609190139" defer></script>
|
<script src="assets/js/profil.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+12
-12
@@ -7,14 +7,14 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/treff.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/treff.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -134,9 +134,9 @@
|
|||||||
Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen
|
Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen
|
||||||
Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen,
|
Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen,
|
||||||
die seit dem 07.09. jede Seite danach absucht. -->
|
die seit dem 07.09. jede Seite danach absucht. -->
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/rechte.js?v=202609190139" defer></script>
|
<script src="assets/js/rechte.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/report.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/report.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -106,11 +106,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609190139" defer></script>
|
<script src="assets/js/ki.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/report.js?v=202609190139" defer></script>
|
<script src="assets/js/report.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/scouting.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/scouting.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -173,10 +173,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/scouting.js?v=202609190139" defer></script>
|
<script src="assets/js/scouting.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+17
-17
@@ -12,21 +12,21 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<!-- Nur die Startseite: Begrüßungskachel, Uhr, Glockenmulde. Siehe
|
<!-- Nur die Startseite: Begrüßungskachel, Uhr, Glockenmulde. Siehe
|
||||||
den Hinweis in start.css -- dort stand es bis zum 07.09.2026. -->
|
den Hinweis in start.css -- dort stand es bis zum 07.09.2026. -->
|
||||||
<link rel="stylesheet" href="assets/css/heim.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/heim.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -412,11 +412,11 @@
|
|||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
|
||||||
<linearGradient id="uhr-stunde-farbe" x1="0" y1="0" x2="1" y2="1">
|
<linearGradient id="uhr-stunde-farbe" x1="0" y1="0" x2="1" y2="1">
|
||||||
<stop offset="0%" stop-color="#fb8f97" />
|
<stop offset="0%" stop-color="#c49ef8" />
|
||||||
<stop offset="28%" stop-color="#e05e6b" />
|
<stop offset="28%" stop-color="#a372df" />
|
||||||
<stop offset="52%" stop-color="#f27c87" />
|
<stop offset="52%" stop-color="#b88df0" />
|
||||||
<stop offset="74%" stop-color="#d95463" />
|
<stop offset="74%" stop-color="#9c6ad9" />
|
||||||
<stop offset="100%" stop-color="#ee717d" />
|
<stop offset="100%" stop-color="#b284ec" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
|
||||||
<!-- MINUTE: Schwarzsilber. Vier Stopps, damit es nach
|
<!-- MINUTE: Schwarzsilber. Vier Stopps, damit es nach
|
||||||
@@ -678,10 +678,10 @@
|
|||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/start.js?v=202609190139" defer></script>
|
<script src="assets/js/start.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -85,11 +85,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609190139" defer></script>
|
<script src="assets/js/ki.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/startcheck.js?v=202609190139" defer></script>
|
<script src="assets/js/startcheck.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/profil.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/profil.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -150,11 +150,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/auskunft.js?v=202609190139" defer></script>
|
<script src="assets/js/auskunft.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/steckbrief.js?v=202609190139" defer></script>
|
<script src="assets/js/steckbrief.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -7,18 +7,18 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609190204" />
|
||||||
<!-- Wegen des Kastens „Anfragen“ ueber der Liste. Eine eigene Kopie
|
<!-- Wegen des Kastens „Anfragen“ ueber der Liste. Eine eigene Kopie
|
||||||
der Regel hier waere die zweite Stelle, an der dieselbe Sache
|
der Regel hier waere die zweite Stelle, an der dieselbe Sache
|
||||||
anders aussieht. -->
|
anders aussieht. -->
|
||||||
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -111,9 +111,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/talente.js?v=202609190139" defer></script>
|
<script src="assets/js/talente.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -7,20 +7,20 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/team.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/team.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -110,10 +110,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/team.js?v=202609190139" defer></script>
|
<script src="assets/js/team.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+12
-12
@@ -7,20 +7,20 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/team.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/team.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<!-- `data-buehne` steht hier fest und nicht im Skript: Die Kachel zu
|
<!-- `data-buehne` steht hier fest und nicht im Skript: Die Kachel zu
|
||||||
@@ -84,9 +84,9 @@
|
|||||||
Kaputt ist dabei nichts -- er funktioniert. Genau deshalb faellt
|
Kaputt ist dabei nichts -- er funktioniert. Genau deshalb faellt
|
||||||
es niemandem auf, und deshalb prueft pruef-css-klassen die
|
es niemandem auf, und deshalb prueft pruef-css-klassen die
|
||||||
ABHAENGIGKEIT statt der Optik. Hier hat sie angeschlagen. -->
|
ABHAENGIGKEIT statt der Optik. Hier hat sie angeschlagen. -->
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/teamlage.js?v=202609190139" defer></script>
|
<script src="assets/js/teamlage.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+11
-11
@@ -7,13 +7,13 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/bereich.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -112,9 +112,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/teilen.js?v=202609190139" defer></script>
|
<script src="assets/js/teilen.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/treff.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/treff.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -126,9 +126,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/treff-moderation.js?v=202609190139" defer></script>
|
<script src="assets/js/treff-moderation.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -7,18 +7,18 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/treff.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/treff.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein. Auf der Adresse des
|
<!-- haus.css MUSS die letzte Stilvorlage sein. Auf der Adresse des
|
||||||
Treffs biegt der Server genau diesen Dateinamen auf crew-haus.css
|
Treffs biegt der Server genau diesen Dateinamen auf crew-haus.css
|
||||||
um, und die Seite kommt schon beim ERSTEN Abruf in Lila und
|
um, und die Seite kommt schon beim ERSTEN Abruf in Lila und
|
||||||
Babyblau an -- ohne Umfaerben im Browser, ohne Flackern. -->
|
Babyblau an -- ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -221,10 +221,10 @@
|
|||||||
Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen
|
Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen
|
||||||
Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen,
|
Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen,
|
||||||
die seit dem 07.09. jede Seite danach absucht. -->
|
die seit dem 07.09. jede Seite danach absucht. -->
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/auskunft.js?v=202609190139" defer></script>
|
<script src="assets/js/auskunft.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/treff-regeln.js?v=202609190139" defer></script>
|
<script src="assets/js/treff-regeln.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,22 +12,22 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<!-- Formular- und Dialogstile: seit dem 07.09.2026 steht hier der
|
<!-- Formular- und Dialogstile: seit dem 07.09.2026 steht hier der
|
||||||
Dialog "Creator anlegen". -->
|
Dialog "Creator anlegen". -->
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -149,11 +149,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/uebersicht.js?v=202609190139" defer></script>
|
<script src="assets/js/uebersicht.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/unsere-seiten.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/unsere-seiten.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -86,6 +86,28 @@
|
|||||||
<!-- ---- DOGFATHER UNIVERSE ------------------------------------ -->
|
<!-- ---- DOGFATHER UNIVERSE ------------------------------------ -->
|
||||||
<article class="aussen aussen--dogi" data-weg="https://dogfather-universe.com/">
|
<article class="aussen aussen--dogi" data-weg="https://dogfather-universe.com/">
|
||||||
<div class="aussen__schein" aria-hidden="true"></div>
|
<div class="aussen__schein" aria-hidden="true"></div>
|
||||||
|
<!-- DIE SCHWEBENDEN LOGOS (19.09.2026).
|
||||||
|
|
||||||
|
Filipe: "die sollen paar mal sein in der kacheln und so wie
|
||||||
|
schweben, sich ganz leicht bewegen."
|
||||||
|
|
||||||
|
VIER STUECK, VERSCHIEDEN GROSS UND VERSCHIEDEN SCHNELL. Alle
|
||||||
|
gleich waere ein Muster, und ein Muster sieht nach Tapete
|
||||||
|
aus. Verschieden heisst: Man nimmt Tiefe wahr, ohne dass
|
||||||
|
etwas ablenkt.
|
||||||
|
|
||||||
|
Sie tragen KEINE Farbe: Das PNG ist eine Maske, die Farbe
|
||||||
|
kommt aus dem CSS (--aussen-ton). Deshalb passt dasselbe
|
||||||
|
Logo in jede Kachel, egal welchen Ton sie hat.
|
||||||
|
|
||||||
|
`aria-hidden`, weil sie nichts sagen -- wer die Seite
|
||||||
|
vorlesen laesst, soll nicht viermal "Logo" hoeren. -->
|
||||||
|
<div class="logo-feld" aria-hidden="true">
|
||||||
|
<span class="logo-feld__stueck" data-n="1"></span>
|
||||||
|
<span class="logo-feld__stueck" data-n="2"></span>
|
||||||
|
<span class="logo-feld__stueck" data-n="3"></span>
|
||||||
|
<span class="logo-feld__stueck" data-n="4"></span>
|
||||||
|
</div>
|
||||||
<div class="aussen__kopf">
|
<div class="aussen__kopf">
|
||||||
<span class="aussen__zeichen" aria-hidden="true">
|
<span class="aussen__zeichen" aria-hidden="true">
|
||||||
<svg viewBox="0 0 24 24">
|
<svg viewBox="0 0 24 24">
|
||||||
@@ -130,6 +152,12 @@
|
|||||||
<!-- ---- VANVANS SHOP ------------------------------------------ -->
|
<!-- ---- VANVANS SHOP ------------------------------------------ -->
|
||||||
<article class="aussen aussen--shop" data-weg="https://vans-diy-bastelbedarf.com/">
|
<article class="aussen aussen--shop" data-weg="https://vans-diy-bastelbedarf.com/">
|
||||||
<div class="aussen__schein" aria-hidden="true"></div>
|
<div class="aussen__schein" aria-hidden="true"></div>
|
||||||
|
<div class="logo-feld" aria-hidden="true">
|
||||||
|
<span class="logo-feld__stueck" data-n="1"></span>
|
||||||
|
<span class="logo-feld__stueck" data-n="2"></span>
|
||||||
|
<span class="logo-feld__stueck" data-n="3"></span>
|
||||||
|
<span class="logo-feld__stueck" data-n="4"></span>
|
||||||
|
</div>
|
||||||
<div class="aussen__kopf">
|
<div class="aussen__kopf">
|
||||||
<span class="aussen__zeichen" aria-hidden="true">
|
<span class="aussen__zeichen" aria-hidden="true">
|
||||||
<svg viewBox="0 0 24 24">
|
<svg viewBox="0 0 24 24">
|
||||||
@@ -189,9 +217,9 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/unsere-seiten.js?v=202609190139" defer></script>
|
<script src="assets/js/unsere-seiten.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190139" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609190204" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190139" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/wissen.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/wissen.css?v=202609190204" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609190204" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609190139" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609190204" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -190,10 +190,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609190139" defer></script>
|
<script src="assets/js/wahl.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609190139" defer></script>
|
<script src="assets/js/bereiche.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609190139" defer></script>
|
<script src="assets/js/kopf.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609190139" defer></script>
|
<script src="assets/js/glocke.js?v=202609190204" defer></script>
|
||||||
<script src="assets/js/wissen.js?v=202609190139" defer></script>
|
<script src="assets/js/wissen.js?v=202609190204" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user