Anleitung, Etappen 3 bis 7: alle vier Fassungen, Pflege, Suche, Rundgang, Abnahme

Der Bauplan ist damit vollstaendig umgesetzt.

ETAPPE 3 -- SCOUT, MANAGER UND SPICY MEDIA.
Woertlich aus Kapitel 07 bis 09, zusammen 84 Karten. Die Zahlen des
Bauplans stimmen auf die Karte genau: 18/21/22/23, verteilt 5/6/7,
5/7/9, 6/9/7, 5/5/13.

EINE ZWEIDEUTIGKEIT IM PDF, GEMESSEN STATT GERATEN. Beim Manager
nennt die Merke-Spalte "61, 58, 51 feste Punkte", und Layout- und
Raw-Auszug ordnen sie verschiedenen Kacheln zu. Nachgezaehlt im Code:
LIVE 69, Content-Ideen 61, Community 58, Technik 51. Damit ist die
zeilenweise Lesart bewiesen richtig -- die Layout-Lesart haette "61"
der LIVE-Analyse gegeben, die 69 hat.

Die Zuordnungspruefung laeuft jetzt fuer alle vier Rollen, und die
erwartete Kartenzahl wird AUS DER KACHELLISTE abgeleitet, nicht aus
der Abnahmeliste abgeschrieben. Dazu eine Gegenprobe, dass sich die
vier Fassungen wirklich unterscheiden -- sonst waeren alle Zeilen
gruen, solange die Kachellisten zufaellig passen.

ETAPPE 4 -- DIE PFLEGE, fuer DogFather UND Spicy.
Bearbeitet wird an Ort und Stelle: Stufe und die drei Zeilen je Karte,
Titel und Text je Listenzeile, Leitgedanke je Rolle. Fehlende Karten
werden benannt und lassen sich mit einem Griff anlegen -- das ist der
Fall "Fuer diese Kachel fehlt ein Eintrag" aus Kapitel 11. Dazu "Wer
ist wie weit": eine Arbeitslage, keine Ueberwachung.

KEINE ZWEITE ROLLENAUSWAHL. Die Vorschau gibt es schon -- sie heisst
"Meine Sicht" und steht in der Kopfleiste. Geprueft wird fuers Pflegen
`req.person` und nicht `req.sicht`: Wer durch fremde Augen sieht, soll
nicht aus Versehen in fremdem Namen aendern.

DIE MARKE "NEU" HAT EIN ENDE: 14 Tage ODER bis die Person die Seite
nach der Aenderung geoeffnet hat. Der Bauplan sagt dazu nichts, und
ohne Ende waere nach einem halben Jahr alles neu.

ETAPPE 5 -- DIE SUCHE.
Die Karten stehen in der Kopfleisten-Suche, aber nur die der EIGENEN
Rolle: Faende ein Creator die Manager-Karte, stuende dort "Zuteilen,
freigeben" neben einer Kachel, die er nicht hat. Der Treffer traegt
den Zusatz hinter dem Fragezeichen, sonst landen fuenf Karten auf
derselben Seite.

ETAPPE 6 -- BEGRUESSUNG UND RUNDGANG.
Fuenf Schritte ueber die Zentrale, im letzten leuchten nur die
Muss-Kacheln. EIGENE DATEI (`rundgang.js`) und nicht ein Stueck
start.js: Er laeuft auf der meistbenutzten Seite des Hauses, und wenn
hier etwas schiefgeht, darf davon nichts anderes betroffen sein.
Keine gerechnete Koordinate, kein Loch in einer Abdeckung -- die Seite
wird leiser, das Ziel bleibt hell. Faellt das Skript aus, ist beim
naechsten Laden alles normal.

DER ROLLENWECHSEL IST KEINE SONDERREGEL, sondern der Schluessel:
`(Person, Rolle)`. Die neue Rolle hat schlicht noch keine Zeile, also
startet die Einweisung von selbst noch einmal. Eine Spalte
"zuruecksetzen", an die jemand denken muesste, waere die Stelle, an
der es vergessen wird.

EIN FUND AUS DER MESSUNG: Gemerkt wurde zuerst erst am ENDE des
Rundgangs. Wer "Los geht's" drueckte und dann wegging, bekam die
Begruessung bei jedem Aufruf wieder -- fuer immer. Jetzt wird beim
ZEIGEN gemerkt; das ist die Tatsache, um die es geht.

ETAPPE 7 -- DIE ABNAHME.
Dabei fiel auf, dass der Rollen-Rundgang SPICY MEDIA gar nicht kannte:
fuenf Durchgaenge, aber zweimal Manager, zweimal Scout und Spicy nie.
Ihr gehoert die Gruppe "Rund um das Team" samt Team-Lage -- diese
Kachel ist in keinem Durchgang je geoeffnet worden. Jetzt laeuft sie
mit: 452 statt 406 Pruefungen.

MITGENOMMEN, WEIL ES ROT WAR: `pruef-eventkarte` und
`pruef-haus-luecke` bildeten ihr Tagesdatum aus UTC. Zwischen 00:00
und 02:00 deutscher Zeit liegt UTC im Vortag -- ein naechtlicher Lauf
haette an einem Datum gesucht, das er selbst nicht geschrieben hat.
Beide benutzen jetzt `helfer-zeit`. `pruef-struktur` ist damit gruen.

Gemessen (alle gruen, kein einziger Befund)
  pruef-anleitung        125 Pruefungen (vorher 70)
  pruef-rollen           452 Pruefungen (vorher 406) -- mit Spicy Media
  pruef-struktur         gruen (vorher rot)
  pruef-rechtetafel, pruef-css-klassen, pruef-kachel-universum,
  pruef-suchfeld, pruef-kachelraster, pruef-start-ansicht,
  pruef-sicht, pruef-eventkarte     alle gruen
  mess-anleitung         Rundgang fuenf Schritte, im letzten genau 5
                         Muss-Kacheln hervorgehoben; beim zweiten
                         Aufruf keine Begruessung mehr; kein
                         Querschieben bei 412 und 1440 px

Sicherung: ~/sicherungen/workspace-vor-anleitung-e37-20261006-1536.db

OFFEN, NICHT VON MIR UND NICHT AUS DIESEM BAUPLAN: pruef-haus-luecke
endet mit Rueckgabewert 3 ("konnte nicht nachsehen") -- eine der
beiden Adressen liefert das Anschlagbrett nicht. Nachgemessen: Das war
vor dieser Arbeit genauso.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-10-06 15:37:00 +02:00
co-authored by Claude Opus 5
parent df67574f90
commit 98cfdc3ebc
58 changed files with 2765 additions and 707 deletions
+452
View File
@@ -186,6 +186,42 @@ CREATE TABLE IF NOT EXISTS anl_stand (
PRIMARY KEY (person_id, zeile_id)
);
CREATE INDEX IF NOT EXISTS idx_anl_stand_person ON anl_stand (person_id);
/* ======================================================================
WANN JEMAND ZULETZT HINEINGESEHEN HAT (Etappe 4)
Einzig fuer die Marke "Neu": Sie soll verschwinden, sobald die
Person die geaenderte Stelle gesehen hat. Dafuer reicht ein
Zeitstempel je Person -- NICHT je Eintrag. Wer eine Seite oeffnet,
sieht sie ganz; Buch zu fuehren, welche Karte wie lange im Bild
war, waere Ueberwachung und nicht Pflege.
====================================================================== */
CREATE TABLE IF NOT EXISTS anl_besuch (
person_id INTEGER PRIMARY KEY REFERENCES personen(id) ON DELETE CASCADE,
gesehen_am TEXT NOT NULL
);
/* ======================================================================
DIE EINWEISUNG BEIM ERSTEN ANMELDEN (Etappe 6)
Der Bauplan: "Nur einmal automatisch. Gespeichert pro Person, nicht
pro Geraet." -- deshalb hier und nicht im Browserspeicher. Wer sich
am Telefon anmeldet und spaeter am Rechner, hat sie schon gesehen.
DER SCHLUESSEL IST (Person, ROLLE) UND NICHT NUR DIE PERSON. Damit
erledigt sich die Sonderregel aus dem Bauplan ("Bekommt jemand eine
neue Rolle, startet die Einweisung fuer die neue Rolle beim
naechsten Login einmal neu") von selbst: Die neue Rolle hat
schlicht noch keine Zeile. Eine Spalte "zuruecksetzen", die beim
Rollenwechsel jemand anfassen muesste, waere die Stelle, an der es
vergessen wird.
====================================================================== */
CREATE TABLE IF NOT EXISTS anl_einweisung (
person_id INTEGER NOT NULL REFERENCES personen(id) ON DELETE CASCADE,
rolle TEXT NOT NULL,
gezeigt_am TEXT NOT NULL,
PRIMARY KEY (person_id, rolle)
);
`;
/* =====================================================================
@@ -329,6 +365,422 @@ export const INHALTE = {
text: "Dein Team: Bild, Name und was du über dich geschrieben hast." },
],
},
scout: {
leitgedanke:
"Finden, begleiten, übergeben. Du hast deine eigene Pipeline und betreust "
+ "die Creator, die du gebracht hast, bis ein Manager übernimmt.",
saetze: [
"Dein Platz ist die Scout-Pipeline. Dort beginnt und endet dein Tag.",
"Die Manager-Ziele sind Pflicht und starten jeden Monat neu.",
"Die Betreuungs-Kacheln brauchst du nur für Creator, die noch bei dir sind.",
],
schritte: [
{ titel: "Mein Steckbrief", ziel: "steckbrief.html",
text: "Bild, ein Satz über dich, deine Kanäle." },
{ titel: "Scout-Pipeline", ziel: "scouting.html",
text: "Mit „Neuer Kontakt“ den ersten anlegen, mit Datum für den nächsten Schritt." },
{ titel: "Manager-Ziele", ziel: "manager-ziele.html",
text: "Ansehen: deine vier festen Monatsaufgaben." },
{ titel: "Dashboard", ziel: "uebersicht.html",
text: "Unter „Wo ich diese Woche nachfassen würde“ steht, wer dich braucht." },
{ titel: "Installieren", ziel: null, text: "Oben antippen." },
],
karten: [
{ kachel: "scouting", stufe: "muss",
wozu: "Dein Kontakt-Verzeichnis.",
tust: "Kontakte durch fünf Stufen führen: Neu, Angesprochen, Gespräch, Interessiert, Übergeben.",
merke: "Immer ein Datum setzen. Nur du und DogFather sehen deine Pipeline." },
{ kachel: "manager-ziele", stufe: "muss",
wozu: "Deine Pflichtaufgaben im Monat.",
tust: "Eintragen: 3 Creator rekrutiert, 2 Manager-Meetings, 2 Schulungen oder Community Talks, 1 Werbevideo.",
merke: "Acht Einträge pro Monat. Am besten bis Monatsmitte." },
{ kachel: "aufgaben", stufe: "muss",
wozu: "Wer macht was.",
tust: "Aufgaben anlegen und zuteilen, aus der Vorlage mit 80 Aufgaben übernehmen.",
merke: "Vier Spalten: Offen, In Arbeit, Zur Freigabe, Erledigt." },
{ kachel: "chat", stufe: "muss",
wozu: "Nachrichten mit dem Team.",
tust: "Personen, Gruppen und Kanäle.",
merke: "Vereinbarungen gehören ins Protokoll, nicht nur in den Chat." },
{ kachel: "steckbrief", stufe: "muss",
wozu: "So sehen dich die anderen.",
tust: "Einmal ausfüllen: Bild, Satz, Kanäle.",
merke: "Dein Bild erscheint überall neben deinem Namen." },
{ kachel: "uebersicht", stufe: "regelmaessig",
wozu: "Deine Creator auf einen Blick.",
tust: "Sehen, wer lange nicht da war und wo ein Gespräch fehlt.",
merke: "Mit „Schreiben“ direkt in den Chat." },
{ kachel: "kalender", stufe: "regelmaessig",
wozu: "Termine und Calls.",
tust: "Termine anlegen, Wiederholungen einrichten.",
merke: "Vier Ansichten: Monat, Woche, Liste, Zeitstrahl." },
{ kachel: "calls", stufe: "regelmaessig",
wozu: "Gespräche festhalten.",
tust: "Call planen, danach „Protokoll schreiben“.",
merke: "To-dos aus dem Protokoll werden Aufgaben." },
{ kachel: "profil", stufe: "regelmaessig",
wozu: "Akte je Creator.",
tust: "Bei jedem neuen Creator: Stammdaten, Ziele und 90-Tage-Plan füllen.",
merke: "Leere Profile erscheinen bei „Was ist dran“." },
{ kachel: "startcheck", stufe: "regelmaessig",
wozu: "Erstanalyse neuer Creator.",
tust: "Bei jedem neuen Creator: 16 Punkte in vier Blöcken bewerten.",
merke: "Jeder neue Creator braucht einen." },
{ kachel: "bereich:schutz", stufe: "regelmaessig",
wozu: "Unterweisungen.",
tust: "Bei jedem neuen Creator: Dokumente durchgehen und bestätigen.",
merke: "Die abgeschlossene Bestätigung ist der Nachweis." },
{ kachel: "report", stufe: "regelmaessig",
wozu: "Rückblick je Creator.",
tust: "Einmal im Monat: Zeitraum wählen, Entscheidung festhalten.",
merke: "Erledigt, blockiert, funktioniert, als Nächstes." },
{ kachel: "leistung", stufe: "bedarf",
wozu: "Was wirklich passiert ist.",
tust: "Tage eintragen oder Backstage-Datei einlesen, Ziele setzen.",
merke: "In Backstage den Zeitraum auf einen Tag stellen, sonst fehlen Tageswerte." },
{ kachel: "bereich:live", stufe: "bedarf",
wozu: "LIVEs systematisch verbessern.",
tust: "Je Punkt setzen: passt, zu verbessern, passt nicht, kommt nicht vor.",
merke: "Der Creator sieht es sofort." },
{ kachel: "content", stufe: "bedarf",
wozu: "Content planen.",
tust: "Ideen anlegen und durch die fünf Stufen schieben.",
merke: "Fertige Vorschläge lassen sich übernehmen." },
{ kachel: "bereich:community", stufe: "bedarf",
wozu: "Moderation und Konflikte.",
tust: "Festhalten, was vorbereitet ist und was geholfen hat.",
merke: "Drei Blöcke: vorbereiten, aufbauen, wenn es kippt." },
{ kachel: "bereich:technik", stufe: "bedarf",
wozu: "Setup und Fehler je Creator.",
tust: "Aufbau, aktuelles Problem und Lösung dokumentieren.",
merke: "Spart beim nächsten Ausfall Zeit." },
{ kachel: "bereich:agentur", stufe: "bedarf",
wozu: "Events, Schulungen, Anliegen.",
tust: "Einträge anlegen, Rückmeldungen der Creator sehen.",
merke: "DogFather entscheidet am Ende über Vorschläge." },
{ kachel: "dateien", stufe: "bedarf",
wozu: "Ablage und Freigaben.",
tust: "Datei hochladen (bis 25 MB) und wählen, wer sie sehen darf.",
merke: "Niemand ausgewählt heißt: nur DogFather sieht sie." },
{ kachel: "wissen", stufe: "bedarf",
wozu: "Anleitungen zu TikTok und Technik.",
tust: "Nachschlagen und an Creator weitergeben.",
merke: "15 Themenbereiche mit Filtern." },
{ kachel: "support", stufe: "bedarf",
wozu: "Etwas ist kaputt.",
tust: "Beschreiben, Bilder anhängen, abschicken.",
merke: "Geht an DogFather und die rechte Hand." },
],
nicht: [
{ titel: "Die volle Betreuungsakte bei jedem Kontakt.",
text: "Sie beginnt erst, wenn aus dem Kontakt ein Creator geworden ist." },
{ titel: "Creator nach der Übergabe.", text: "Ab „Übergeben“ ist der Manager zuständig." },
{ titel: "Personen anlegen und Codes vergeben.",
text: "Das macht ein Manager. Sag ihm Bescheid." },
{ titel: "Die Pipeline der anderen Scouts.", text: "Du siehst nur deine eigene." },
],
takt: [
{ titel: "Täglich", text: "Zentrale, Scout-Pipeline (fällige Kontakte), Chat, Aufgaben." },
{ titel: "Wöchentlich",
text: "Dashboard, Calls & Protokolle schreiben, Start-Check und Creator-Profile neuer Creator." },
{ titel: "Monatlich",
text: "Manager-Ziele bis Monatsmitte erledigen, Reports & Review je Creator." },
],
fragen: [
{ titel: "Wann zählt ein Kontakt als übergeben?",
text: "Wenn ein Manager übernimmt. Ab da ist es Betreuung, kein Scouting mehr." },
{ titel: "Wer sieht meine Pipeline?",
text: "Du und DogFather. Manager und Spicy Media sehen die Gesamtübersicht." },
{ titel: "Bis wann müssen die Manager-Ziele erledigt sein?",
text: "Jeden Monat neu. Am besten bis Monatsmitte." },
],
},
manager: {
leitgedanke:
"Betreuung und Freigaben. Du hast dieselben Rechte wie die Leitung, nur ohne "
+ "Personenverwaltung. Du legst Creator an und hältst die Betreuung am Laufen.",
saetze: [
"Dein Tag: Dashboard ansehen, Aufgaben freigeben, im Chat antworten.",
"Die Manager-Ziele sind Pflicht und starten jeden Monat neu.",
"Die Fach-Kacheln (LIVE-Analyse bis Technik) öffnest du je Creator, nicht täglich.",
],
schritte: [
{ titel: "Mein Steckbrief", ziel: "steckbrief.html", text: "Ausfüllen." },
{ titel: "Personen & Zugänge", ziel: "personen.html",
text: "Ansehen: So legst du einen neuen Creator an und gibst den Code weiter." },
{ titel: "Dashboard", ziel: "uebersicht.html",
text: "Hier siehst du alle Creator und wo es hakt." },
{ titel: "Manager-Ziele", ziel: "manager-ziele.html",
text: "Ansehen: deine vier festen Monatsaufgaben." },
{ titel: "Aufgaben", ziel: "aufgaben.html",
text: "Unter „Wer hat gerade was“ siehst du die Verteilung." },
],
karten: [
{ kachel: "uebersicht", stufe: "muss",
wozu: "Alle Creator auf einen Blick.",
tust: "Nachfassen, wo jemand lange nicht da war.",
merke: "Je Creator: Termine, Aufgaben, Zahlen, Start-Check." },
{ kachel: "aufgaben", stufe: "muss",
wozu: "Wer macht was.",
tust: "Zuteilen, freigeben, Rückmeldung geben. Täglich die Spalte „Zur Freigabe“.",
merke: "Tippe eine Person an, um nur ihre Aufgaben zu sehen." },
{ kachel: "chat", stufe: "muss",
wozu: "Nachrichten mit dem Team.",
tust: "Personen, Gruppen, Kanäle.",
merke: "Entscheidungen ins Protokoll übernehmen." },
{ kachel: "manager-ziele", stufe: "muss",
wozu: "Deine Pflichtaufgaben im Monat.",
tust: "Rekrutierungen, Meetings, Schulungen, Werbevideo eintragen.",
merke: "Acht Einträge pro Monat." },
{ kachel: "personen", stufe: "muss",
wozu: "Neue Leute anlegen.",
tust: "Name und Rolle wählen, Code sofort weitergeben.",
merke: "Der Code wird nur einmal gezeigt." },
{ kachel: "steckbrief", stufe: "muss",
wozu: "So sehen dich die anderen.",
tust: "Einmal ausfüllen: Bild, Satz, Kanäle.",
merke: "Jeder pflegt nur seinen eigenen." },
{ kachel: "kalender", stufe: "regelmaessig",
wozu: "Termine und Calls.",
tust: "Termine und Wiederholungen anlegen.",
merke: "Reviews und Fristen haben eigene Farben." },
{ kachel: "calls", stufe: "regelmaessig",
wozu: "Gespräche festhalten.",
tust: "Call planen, Protokoll schreiben, To-dos vergeben.",
merke: "Kein Call ohne Protokoll." },
{ kachel: "profil", stufe: "regelmaessig",
wozu: "Akte je Creator.",
tust: "Stammdaten, Ziele, 90-Tage-Plan.",
merke: "Die Zahl an der Kachel zeigt leere Profile." },
{ kachel: "startcheck", stufe: "regelmaessig",
wozu: "Erstanalyse.",
tust: "16 Punkte bewerten.",
merke: "Die Zahl an der Kachel zeigt Creator ohne Start-Check." },
{ kachel: "bereich:schutz", stufe: "regelmaessig",
wozu: "Unterweisungen.",
tust: "Mit jedem neuen Creator durchgehen und bestätigen.",
merke: "Danach unveränderlich." },
{ kachel: "scouting", stufe: "regelmaessig",
wozu: "Alle Scouts im Überblick.",
tust: "Nach Scout filtern, Übergaben annehmen.",
merke: "Ab „Übergeben“ bist du zuständig." },
{ kachel: "leistung", stufe: "regelmaessig",
wozu: "Diamanten, LIVE-Tage, Verweildauer.",
tust: "Tage eintragen oder Datei einlesen, Ziele setzen.",
merke: "Quelle ist Backstage." },
{ kachel: "report", stufe: "regelmaessig",
wozu: "Rückblick und Entscheidung.",
tust: "Einmal im Monat: Zeitraum wählen, Entscheidung festhalten.",
merke: "Vergleich mit dem Zeitraum davor." },
{ kachel: "bereich:agentur", stufe: "regelmaessig",
wozu: "Events, Schulungen, Anliegen.",
tust: "Einträge anlegen, vorbereitete Vorschläge übernehmen.",
merke: "Was hier nicht steht, wird vergessen." },
{ kachel: "bereich:live", stufe: "bedarf",
wozu: "LIVEs verbessern.",
tust: "Feste Punkte bewerten, Notizen schreiben.",
merke: "Vier Stufen von Anfänger bis Meister." },
{ kachel: "content", stufe: "bedarf",
wozu: "Content planen.",
tust: "Ideen durch fünf Stufen führen.",
merke: "61 feste Punkte als Leitfaden." },
{ kachel: "bereich:community", stufe: "bedarf",
wozu: "Moderation und Konflikte.",
tust: "Vorbereitung und Vorfälle dokumentieren.",
merke: "58 feste Punkte." },
{ kachel: "bereich:technik", stufe: "bedarf",
wozu: "Setup und Fehler.",
tust: "Dokumentieren, was klemmt und was geholfen hat.",
merke: "51 feste Punkte." },
{ kachel: "dateien", stufe: "bedarf",
wozu: "Ablage und Freigaben.",
tust: "Hochladen, Sichtbarkeit wählen, freigeben.",
merke: "Entwurf, Zur Freigabe, Freigegeben." },
{ kachel: "wissen", stufe: "bedarf",
wozu: "Anleitungen zu TikTok und Technik.",
tust: "Nachschlagen und weitergeben.",
merke: "Filter nach Stufe, Gerät, Tag." },
{ kachel: "support", stufe: "bedarf",
wozu: "Etwas ist kaputt.",
tust: "Beschreiben, Bilder anhängen.",
merke: "Geht an DogFather und die rechte Hand." },
],
nicht: [
{ titel: "Personen sperren, Codes verwalten, Protokoll einsehen.",
text: "Das liegt bei DogFather." },
{ titel: "Kontakte suchen und ansprechen.",
text: "Das machen die Scouts. Du übernimmst ab „Übergeben“." },
{ titel: "Alle Fach-Kacheln für jeden Creator täglich öffnen.",
text: "Die Zentrale und das Dashboard zeigen, wo etwas fehlt." },
],
takt: [
{ titel: "Täglich", text: "Zentrale, Dashboard, Aufgaben (Spalte „Zur Freigabe“), Chat." },
{ titel: "Wöchentlich",
text: "Calls & Protokolle, Creator-Profile, Start-Check, Scout-Pipeline (Übergaben)." },
{ titel: "Monatlich", text: "Manager-Ziele, Reports & Review, Agentur-Events." },
],
fragen: [
{ titel: "Ein Creator hat seinen Code verloren.",
text: "Unter Personen & Zugänge bei der Person „Neuer Code“. Der alte gilt dann nicht mehr." },
{ titel: "Kann ich Personen sperren?",
text: "Nein. Codes verwalten, sperren und das Protokoll einsehen kann nur DogFather." },
{ titel: "Was passiert bei einer Rollenänderung?",
text: "Der Code bleibt, offene Sitzungen enden, die Person meldet sich neu an." },
{ titel: "Woran erkenne ich, wo es brennt?",
text: "Zentrale: der Satz unter „Zentrale“ und die Liste „Was ist dran“." },
],
},
spicy: {
leitgedanke:
"Überblick über alle, ohne Automationen. Du siehst das ganze Haus und zusätzlich "
+ "die Team-Lage: wer wen betreut und wo sich etwas staut.",
saetze: [
"Du brauchst den Überblick, nicht die Einzelheiten jedes Creators.",
"Team-Lage und Dashboard zeigen dir, wo sich etwas staut.",
"In der Kachel Agentur kommen die Anliegen der Creator direkt bei dir an.",
],
schritte: [
{ titel: "Mein Steckbrief", ziel: "steckbrief.html",
text: "Ausfüllen: Bild, Satz, Kanäle." },
{ titel: "Team-Lage", ziel: "team.html",
text: "Auslastung von Managern und Scouts, Creator ohne Betreuung." },
{ titel: "Dashboard", ziel: "uebersicht.html",
text: "Alle Creator mit Terminen, Aufgaben und Start-Check." },
{ titel: "Agentur", ziel: "bereich.html?b=agentur",
text: "Events, Schulungen und Anliegen an die Agentur." },
{ titel: "Kopfleiste", ziel: null,
text: "Oben findest du Teilen, Chat und Suchen." },
],
karten: [
{ kachel: "team", stufe: "muss",
wozu: "Manager und Scouts im Blick.",
tust: "Sehen, wer wen betreut, wo jemand fehlt, wer ohne Creator ist.",
merke: "Arbeitslage, keine Überwachung: keine Inhalte aus Terminen, Chats oder Dateien." },
{ kachel: "uebersicht", stufe: "muss",
wozu: "Alle Creator.",
tust: "Je Creator den Stand prüfen.",
merke: "Zeigt auch, wer lange nicht da war." },
{ kachel: "bereich:agentur", stufe: "muss",
wozu: "Offizieller Weg zur Agentur.",
tust: "Events mit Aufgaben anlegen, Schulungen eintragen, Anliegen beantworten.",
merke: "Hier schreiben Creator direkt an die Agentur." },
{ kachel: "chat", stufe: "muss",
wozu: "Nachrichten.",
tust: "Personen, Gruppen, Kanäle.",
merke: "Kanäle für Ankündigungen nutzen." },
{ kachel: "steckbrief", stufe: "muss",
wozu: "So sehen dich die anderen.",
tust: "Einmal ausfüllen: Bild, Satz, Kanäle.",
merke: "Steht unter „Leitung“ in der Teamliste." },
{ kachel: "aufgaben", stufe: "regelmaessig",
wozu: "Wer macht was.",
tust: "Verteilung sehen, freigeben.",
merke: "Filter nach Person." },
{ kachel: "manager-ziele", stufe: "regelmaessig",
wozu: "Feste Monatsaufgaben.",
tust: "Eigene Einträge machen, Stand des Teams verfolgen.",
merke: "Vorgabe der Agentur, jeden Monat neu." },
{ kachel: "scouting", stufe: "regelmaessig",
wozu: "Alle Scouts.",
tust: "Nach Scout filtern, liegengebliebene Kontakte erkennen.",
merke: "Fünf Stufen bis zur Übergabe." },
{ kachel: "kalender", stufe: "regelmaessig",
wozu: "Termine und Calls.",
tust: "Schulungen und Events eintragen.",
merke: "Wiederholungen laufen von allein." },
{ kachel: "report", stufe: "regelmaessig",
wozu: "Rückblick und Entscheidung.",
tust: "Einmal im Monat: Zeitraum wählen, Entwicklung prüfen.",
merke: "7, 30 oder 90 Tage." },
{ kachel: "calls", stufe: "bedarf",
wozu: "Gespräche festhalten.",
tust: "Protokolle lesen und schreiben.",
merke: "To-dos werden Aufgaben." },
{ kachel: "dateien", stufe: "bedarf",
wozu: "Ablage und Freigaben.",
tust: "Hochladen, Sichtbarkeit wählen, freigeben.",
merke: "Aktuelle Version ist immer erkennbar." },
{ kachel: "profil", stufe: "bedarf",
wozu: "Akte je Creator.",
tust: "Ziele und 90-Tage-Plan einsehen.",
merke: "Leere Profile werden gezählt." },
{ kachel: "leistung", stufe: "bedarf",
wozu: "Leistung je Creator.",
tust: "Wochenzahlen und Zeiträume ansehen.",
merke: "Quelle ist Backstage." },
{ kachel: "startcheck", stufe: "bedarf",
wozu: "Erstanalyse.",
tust: "Stand der Bewertung einsehen, bei Bedarf eintragen.",
merke: "Teil der Betreuungsakte." },
{ kachel: "bereich:live", stufe: "bedarf",
wozu: "LIVEs verbessern.",
tust: "Stand der Bewertung einsehen, bei Bedarf eintragen.",
merke: "Teil der Betreuungsakte." },
{ kachel: "content", stufe: "bedarf",
wozu: "Content planen.",
tust: "Stand einsehen, bei Bedarf eintragen.",
merke: "Teil der Betreuungsakte." },
{ kachel: "bereich:community", stufe: "bedarf",
wozu: "Moderation und Konflikte.",
tust: "Stand einsehen, bei Bedarf eintragen.",
merke: "Teil der Betreuungsakte." },
{ kachel: "bereich:technik", stufe: "bedarf",
wozu: "Setup und Fehler.",
tust: "Stand einsehen, bei Bedarf eintragen.",
merke: "Teil der Betreuungsakte." },
{ kachel: "bereich:schutz", stufe: "bedarf",
wozu: "Unterweisungen.",
tust: "Sehen, wer welche Dokumente bestätigt hat.",
merke: "Bestätigungen sind der Nachweis." },
{ kachel: "personen", stufe: "bedarf",
wozu: "Neue Leute anlegen.",
tust: "Person anlegen, Rolle wählen, Code weitergeben.",
merke: "Codes, Sperren und Protokoll bleiben bei DogFather." },
{ kachel: "wissen", stufe: "bedarf",
wozu: "Anleitungen und PDFs.",
tust: "Nachschlagen.",
merke: "Schulungs-PDFs der Agentur gehören hierher." },
{ kachel: "support", stufe: "bedarf",
wozu: "Etwas ist kaputt.",
tust: "Beschreiben, Bilder anhängen.",
merke: "Geht an DogFather und die rechte Hand." },
],
nicht: [
{ titel: "Die tägliche Betreuung einzelner Creator.",
text: "Das machen Manager und Scouts." },
{ titel: "Die Betreuungsakte selbst füllen.",
text: "Du schaust rein, wenn es einen Anlass gibt." },
{ titel: "Automationen (Sicherungen, lokale KI, Hintergrunddienste).",
text: "Die verwaltet nur DogFather." },
{ titel: "Codes sperren und Protokoll.", text: "Bleibt bei DogFather." },
],
takt: [
{ titel: "Täglich", text: "Zentrale, Team-Lage, Chat." },
{ titel: "Wöchentlich",
text: "Dashboard, Scout-Pipeline, Agentur (Anliegen beantworten), Aufgaben zur Freigabe." },
{ titel: "Monatlich",
text: "Manager-Ziele des Teams, Reports & Review, neue Events eintragen." },
],
fragen: [
{ titel: "Was heißt „ohne Automationen“?",
text: "Sicherungen, lokale KI und Hintergrunddienste verwaltet nur DogFather." },
{ titel: "Sehe ich private Chats oder Termine?",
text: "Nein. Die Team-Lage zeigt nur die Arbeitslage." },
{ titel: "Wo beantworte ich Anliegen der Creator?",
text: "In der Kachel Agentur unter „Anliegen an die Agentur“." },
{ titel: "Wo trage ich ein neues Event ein?",
text: "Agentur, „Neuer Eintrag“, Art „Agentur-Events“, mit Aufgaben und Frist." },
],
},
};
/* =====================================================================
+73
View File
@@ -64,6 +64,8 @@ function anlegen(name, rolle, code) {
}
anlegen("Luna", "creator", "CODE-LUNA-0001");
anlegen("Filipe", "admin", "CODE-DOGI-0001");
anlegen("Cigdem", "spicy", "CODE-SPICY-0001");
anlegen("Neu Hier", "creator", "CODE-NEU-0001");
d.close();
function anfrage(pfad, methode, koerper, keks) {
@@ -95,6 +97,8 @@ async function keksFuer(rolle, code) {
}
const keksCreator = await keksFuer("creator", "CODE-LUNA-0001");
const keksDogi = await keksFuer("admin", "CODE-DOGI-0001");
const keksSpicy = await keksFuer("spicy", "CODE-SPICY-0001");
const keksNeu = await keksFuer("creator", "CODE-NEU-0001");
/* ---------- Bilder ---------------------------------------------------- */
const pw = await import(
@@ -265,6 +269,75 @@ console.log(`
await startBild("start-ohne-schritte", keksCreator, 412);
await bild("creator-fertig", keksCreator, 412, 950);
/* =====================================================================
DIE PFLEGE (Etappe 4) -- und ob sie LEISE ist, solange sie aus ist
===================================================================== */
await bild("spicy-pflege-aus", keksSpicy, 1440, 1000);
await bild("spicy-pflege-an", keksSpicy, 1440, 1000, async (seite) => {
await seite.click("#pflege-an");
await seite.waitForTimeout(500);
});
/* =====================================================================
DER RUNDGANG (Etappe 6)
=====================================================================
Eine FRISCHE Person -- "Neu Hier" hat die Einweisung noch nie
gesehen. Gemessen wird nicht nur, dass das Fenster kommt, sondern
auch, dass die Seite danach wieder NORMAL ist: Ein Rundgang, der
die Startseite gedaempft zuruecklaesst, waere schlimmer als keiner.
===================================================================== */
async function rundgangBild(name, keks, breite, schritte) {
const kontext = await browser.newContext({
viewport: { width: breite, height: 1000 }, hasTouch: breite <= 860,
});
await kontext.addCookies(keks.split("; ").map((k) => {
const [n, ...r] = k.split("=");
return { name: n, value: r.join("="), domain: "127.0.0.1", path: "/" };
}));
const seite = await kontext.newPage();
const konsole = [];
seite.on("console", (e) => {
if (e.type() === "error" && !/favicon|net::ERR/i.test(e.text())) konsole.push(e.text().slice(0, 160));
});
seite.on("pageerror", (e) => konsole.push("Absturz: " + e.message));
await seite.goto(`http://127.0.0.1:${PORT}/workspace/start.html`, { waitUntil: "networkidle" });
/* Das Skript wartet absichtlich 1,2 s, damit die Kacheln stehen. */
await seite.waitForTimeout(2600);
const gruss = await seite.$(".rg-gruss");
console.log(`\n--- ${name} (${breite}px) ---`);
console.log(` Begruessung da: ${gruss ? "ja" : "NEIN"}`);
if (gruss) {
await seite.screenshot({ path: `bild-anleitung-${name}-gruss.png` });
await seite.click(".rg-gruss .knopf");
await seite.waitForTimeout(700);
}
for (let i = 1; i <= schritte; i++) {
const stand = await seite.evaluate(() => ({
zaehler: document.querySelector(".rg__zaehler")?.textContent || "(kein Kasten)",
titel: document.querySelector(".rg__titel")?.textContent || "",
gedaempft: document.body.dataset.rundgang === "ja",
ziele: document.querySelectorAll("[data-rundgang-ziel]").length,
mussKacheln: document.querySelectorAll('[data-rundgang-muss="ja"]').length,
}));
console.log(` ${stand.zaehler.padEnd(18)} ${stand.titel.padEnd(28)} `
+ `Ziel ${stand.ziele} Muss-Kacheln ${stand.mussKacheln}`);
if (i === schritte) await seite.screenshot({ path: `bild-anleitung-${name}-letzter.png` });
const weiter = await seite.$(".rg__weiter");
if (!weiter) break;
if (i < schritte) { await weiter.click(); await seite.waitForTimeout(600); }
}
if (konsole.length) console.log(` KONSOLE: ${konsole.join(" | ")}`);
await kontext.close();
}
await rundgangBild("rundgang", keksNeu, 412, 5);
/* Und: Wer die Begruessung schon gesehen hat, bekommt sie nicht noch
einmal. Dieselbe Person, zweiter Aufruf. */
await rundgangBild("rundgang-zweites-mal", keksNeu, 412, 1);
await browser.close();
try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ }
console.log("\nBilder geschrieben: bild-anleitung-*.png");
+284
View File
@@ -235,6 +235,9 @@ melde("\n=== Die Stufen ===");
const jeStufe = {};
for (const k of creator.j.karten) jeStufe[k.stufe] = (jeStufe[k.stufe] || 0) + 1;
const bekannt = new Set((creator.j.stufen || []).map((s) => s.schluessel));
/* Dieselbe Menge weiter unten fuer alle vier Rollen -- der Server
nennt die Stufen, diese Datei kennt keine eigene Liste. */
const STUFEN_DA = bekannt;
ok([...Object.keys(jeStufe)].every((s) => bekannt.has(s)),
`jede Karte traegt eine bekannte Stufe (${Object.keys(jeStufe).join(", ")})`);
ok(Object.values(jeStufe).reduce((a, b) => a + b, 0) === creator.j.karten.length,
@@ -388,6 +391,94 @@ ok(nachher?.merke === "VON HAND GEAENDERT",
`der geaenderte Text steht noch da ("${(nachher?.merke || "").slice(0, 24)}")`);
ok(anzahlNachher === 18, `und es sind keine Karten dazugekommen (${anzahlNachher})`);
/* =====================================================================
ALLE VIER FASSUNGEN — JEDE GEGEN IHRE EIGENEN KACHELN
=====================================================================
Oben ist der Creator Zeile fuer Zeile geprueft. Hier laufen alle vier
durch dieselbe Zuordnung, und die ZAHLEN WERDEN ABGELEITET, nicht
abgeschrieben: Wie viele Karten eine Rolle haben muss, sagt ihre
Kachelliste -- nicht die Abnahmeliste im Bauplan.
Der Bauplan nennt 18/21/22/23. Die stimmen heute. Am Tag, an dem
eine Kachel dazukommt, waere eine feste Zahl hier eine Luege, die
erst auffaellt, wenn jemand sie nachzaehlt. Also zaehlt die
Pruefung selbst -- und meldet die Zahl, damit man sie lesen kann.
===================================================================== */
melde("\n=== Jede Rolle erklaert genau ihre eigenen Kacheln ===");
const FASSUNGEN_HIER = ["creator", "scout", "manager", "spicy"];
for (const rolle of FASSUNGEN_HIER) {
const a = await holen(rolle);
if (a.code !== 200 || !a.j?.hat_fassung) {
ok(false, `${rolle.padEnd(8)} hat keine Fassung (HTTP ${a.code})`);
continue;
}
const soll = kachelnFuer(rolle);
soll.delete("anleitung"); // die Seite erklaert sich nicht selbst
const ist = new Set(a.j.karten.map((k) => k.kachel));
const fehlt = [...soll.keys()].filter((x) => !ist.has(x));
const zuviel = [...ist].filter((x) => !soll.has(x));
ok(soll.size > 0 && fehlt.length === 0 && zuviel.length === 0,
fehlt.length || zuviel.length
? `${rolle.padEnd(8)} stimmt nicht -- ohne Karte: ${fehlt.join(", ") || "nichts"}; `
+ `ohne Kachel: ${zuviel.join(", ") || "nichts"}`
: `${rolle.padEnd(8)} ${soll.size} Kacheln, ${ist.size} Karten, eins zu eins`);
/* Jede Karte vollstaendig. Eine halbe Karte sieht aus wie ein
Ladefehler, und zwar auf jeder der vier Seiten gleich. */
const halb = a.j.karten.filter((k) => !k.wozu || !k.tust || !k.merke);
ok(halb.length === 0,
halb.length ? `${rolle.padEnd(8)} ${halb.length} unvollstaendige Karten: `
+ halb.map((k) => k.kachel).join(", ")
: `${rolle.padEnd(8)} jede Karte hat alle drei Zeilen`);
/* Die Stufen -- gezaehlt, nicht vorgegeben. */
const je = {};
for (const k of a.j.karten) je[k.stufe] = (je[k.stufe] || 0) + 1;
const summe = Object.values(je).reduce((x, y) => x + y, 0);
ok(summe === a.j.karten.length
&& Object.keys(je).every((x) => STUFEN_DA.has(x)),
`${rolle.padEnd(8)} Stufen ${je.muss || 0}/${je.regelmaessig || 0}/${je.bedarf || 0} `
+ `(zusammen ${summe} von ${a.j.karten.length})`);
/* Die Ersten Schritte duerfen nur auf Kacheln dieser Rolle zeigen --
oder auf gar nichts ("Installieren", "Kopfleiste" sind Knoepfe in
der Kopfleiste, keine Seiten). */
const alleKacheln = kachelnFuer(rolle);
const ins_leere = (a.j.schritte || []).filter((x) => x.ziel)
.filter((x) => !alleKacheln.has(B.schluesselVonZiel(x.ziel)));
ok((a.j.schritte || []).length === 5 && ins_leere.length === 0,
ins_leere.length
? `${rolle.padEnd(8)} Schritte ins Leere: ${ins_leere.map((x) => x.ziel).join(", ")}`
: `${rolle.padEnd(8)} fuenf Erste Schritte, alle mit gueltigem Ziel`);
/* Und der Rest der Fassung ist da. Eine Rolle ohne Rhythmus oder
ohne "Nicht deins" waere eine halbe Einweisung. */
ok(!!a.j.leitgedanke && (a.j.saetze || []).length === 3
&& (a.j.nicht || []).length >= 3 && (a.j.takt || []).length >= 3
&& (a.j.fragen || []).length >= 3,
`${rolle.padEnd(8)} Leitgedanke, 3 Saetze, ${(a.j.nicht || []).length} x Nicht deins, `
+ `${(a.j.takt || []).length} Takt-Zeilen, ${(a.j.fragen || []).length} Fragen`);
}
/* GEGENPROBE ZUR SCHLEIFE: Sie darf nicht leer durchgelaufen sein.
Vier Rollen, und jede musste wirklich etwas liefern. */
ok(FASSUNGEN_HIER.length === 4, `vier Fassungen durchgegangen`);
/* Und: Die Fassungen muessen sich UNTERSCHEIDEN. Lieferte der Server
allen dieselbe Liste, waeren alle Zeilen oben trotzdem gruen --
solange die Kachellisten zufaellig passten. */
{
const koepfe = [];
for (const rolle of FASSUNGEN_HIER) {
const a = await holen(rolle);
koepfe.push(a.j?.leitgedanke || "");
}
ok(new Set(koepfe).size === 4,
`Gegenprobe: vier verschiedene Leitgedanken (${new Set(koepfe).size} verschiedene)`);
}
/* =====================================================================
ETAPPE 2 — DIE ERSTEN SCHRITTE ZUM ABHAKEN
===================================================================== */
@@ -522,6 +613,199 @@ ok(hWieder.liste.some((h) => h.art === "anl_schritte" && h.anzahl === 1),
sehen -- der Haken auf Schritt 2 und die vier von eben. */
for (const s of schritte0) await haken("creator", s.id, false);
/* =====================================================================
ETAPPE 4 — DIE PFLEGE
===================================================================== */
melde("\n=== Pflege: wer darf ===");
const pput = (rolle, pfad, rumpf, host = null) =>
roh(pfad, host, rumpf, kekse[rolle], "PUT");
const eineKarte = (await holen("creator")).j.karten.find((k) => k.kachel === "chat");
braucht(!!eineKarte?.id, "keine Karte zum Bearbeiten gefunden");
const pCreator = await pput("creator", `/workspace/api/anleitung/karte/${eineKarte.id}`,
{ stufe: "bedarf", wozu: "x", tust: "y", merke: "z" });
ok(pCreator.code === 403, `ein Creator darf nicht pflegen (HTTP ${pCreator.code}, erwartet 403)`);
const pScout = await pput("scout", `/workspace/api/anleitung/karte/${eineKarte.id}`,
{ stufe: "bedarf", wozu: "x", tust: "y", merke: "z" });
ok(pScout.code === 403, `ein Scout auch nicht (HTTP ${pScout.code}, erwartet 403)`);
const pModi = await pput("modi", `/workspace/api/anleitung/karte/${eineKarte.id}`,
{ stufe: "bedarf", wozu: "x", tust: "y", merke: "z" }, CREW_HOST);
ok(pModi.code === 404, `ein Modi bekommt die Pflege gar nicht (HTTP ${pModi.code}, erwartet 404)`);
melde("\n=== Pflege: Spicy aendert eine Stufe, und sie gilt sofort ===");
const vorher = eineKarte.stufe;
const pSpicy = await pput("spicy", `/workspace/api/anleitung/karte/${eineKarte.id}`,
{ stufe: "bedarf", wozu: "Nachrichten mit deinem Team.",
tust: "Mit „Neu“ ein Gespräch beginnen.", merke: "GEAENDERT VON SPICY" });
ok(pSpicy.code === 200, `Spicy Media darf (HTTP ${pSpicy.code})`);
const nachSpicy = await holen("creator");
const chatNeu = nachSpicy.j.karten.find((k) => k.kachel === "chat");
ok(chatNeu?.stufe === "bedarf",
`die Stufe steht sofort in der Creator-Fassung (${vorher} -> ${chatNeu?.stufe})`);
ok(chatNeu?.merke === "GEAENDERT VON SPICY", "…und der Text auch");
/* DIE MARKE "NEU". Der Creator hat die Seite gerade geladen -- damit
ist sein Besuch juenger als die Aenderung davor, aber AELTER als die
von eben. Die Reihenfolge ist der ganze Beweis. */
ok(chatNeu?.neu === true, "die geaenderte Karte traegt die Marke „Neu“");
const nochmal = await holen("creator");
ok(nochmal.j.karten.find((k) => k.kachel === "chat")?.neu === false,
"…und beim zweiten Hinsehen nicht mehr");
/* Zurueck auf Anfang, damit die Zuordnungspruefung oben weiter stimmt. */
await pput("spicy", `/workspace/api/anleitung/karte/${eineKarte.id}`,
{ stufe: vorher, wozu: "Nachrichten mit deinem Team.",
tust: "Mit „Neu“ ein Gespräch beginnen.",
merke: "Fehler an der Seite gehören in Support, nicht in den Chat." });
melde("\n=== Pflege: was nicht durchgehen darf ===");
const pUnsinn = await pput("admin", `/workspace/api/anleitung/karte/${eineKarte.id}`,
{ stufe: "gibtesnicht", wozu: "", tust: "", merke: "" });
ok(pUnsinn.code === 400, `eine erfundene Stufe wird abgelehnt (HTTP ${pUnsinn.code})`);
const pWeg = await pput("admin", "/workspace/api/anleitung/karte/999999",
{ stufe: "muss", wozu: "", tust: "", merke: "" });
ok(pWeg.code === 404, `eine Karte, die es nicht gibt (HTTP ${pWeg.code})`);
melde("\n=== Pflege: fehlenden Eintrag anlegen und wieder entfernen ===");
/* Erst loeschen, dann ist er "fehlend" -- genau der Fall, den der
Bauplan "Fuer diese Kachel fehlt ein Eintrag" nennt. */
const weg = await roh(`/workspace/api/anleitung/karte/${eineKarte.id}`, null, null,
kekse.admin, "DELETE");
ok(weg.code === 200, `DogFather kann eine Karte entfernen (HTTP ${weg.code})`);
const ohne = await holen("creator");
ok(ohne.j.karten.length === 17 && !ohne.j.karten.some((k) => k.kachel === "chat"),
`danach 17 Karten, die Chat-Karte fehlt (${ohne.j.karten.length})`);
const neu1 = await roh("/workspace/api/anleitung/karte", null,
{ rolle: "creator", kachel: "chat", stufe: "muss",
wozu: "Nachrichten mit deinem Team.", tust: "Mit „Neu“ ein Gespräch beginnen.",
merke: "Fehler an der Seite gehören in Support, nicht in den Chat." },
kekse.admin, "POST");
ok(neu1.code === 200, `…und wieder anlegen (HTTP ${neu1.code})`);
const neu2 = await roh("/workspace/api/anleitung/karte", null,
{ rolle: "creator", kachel: "chat", stufe: "muss", wozu: "", tust: "", merke: "" },
kekse.admin, "POST");
ok(neu2.code === 409,
`ein zweites Mal nicht -- eine Kachel hat genau eine Karte (HTTP ${neu2.code})`);
const zurueck = await holen("creator");
ok(zurueck.j.karten.length === 18,
`wieder 18 Karten (${zurueck.j.karten.length})`);
melde("\n=== Pflege: eine Zeile aendern ===");
const einSchritt = zurueck.j.schritte[0];
const zAend = await pput("admin", `/workspace/api/anleitung/zeile/${einSchritt.id}`,
{ titel: einSchritt.titel, text: "GEAENDERTER TEXT", ziel: einSchritt.ziel });
ok(zAend.code === 200, `eine Listenzeile laesst sich aendern (HTTP ${zAend.code})`);
const nachZeile = await holen("creator");
ok(nachZeile.j.schritte[0]?.text === "GEAENDERTER TEXT", "…und der Text steht da");
await pput("admin", `/workspace/api/anleitung/zeile/${einSchritt.id}`,
{ titel: einSchritt.titel, text: einSchritt.text, ziel: einSchritt.ziel });
melde("\n=== Pflege: wer ist wie weit ===");
const standR = await roh("/workspace/api/anleitung/stand", null, null, kekse.admin);
let standJ = null; try { standJ = JSON.parse(standR.text); } catch { /* bleibt null */ }
ok(standR.code === 200 && Array.isArray(standJ?.leute),
`DogFather sieht den Stand (HTTP ${standR.code}, ${standJ?.leute?.length ?? 0} Leute)`);
ok((standJ?.leute || []).some((p) => p.rolle === "creator" && p.gesamt === 5),
"…und der Creator steht mit fuenf Schritten drin");
const standC = await roh("/workspace/api/anleitung/stand", null, null, kekse.creator);
ok(standC.code === 403, `ein Creator sieht ihn nicht (HTTP ${standC.code}, erwartet 403)`);
/* =====================================================================
ETAPPE 5 — DIE SUCHE
===================================================================== */
melde("\n=== Suche ===");
async function suchen(rolle, wort, host = null) {
const r = await roh(`/workspace/api/suche?q=${encodeURIComponent(wort)}`, host, null, kekse[rolle]);
let j = null; try { j = JSON.parse(r.text); } catch { /* bleibt null */ }
const g = (j?.gruppen || []).find((x) => x.titel === "Anleitung");
return { code: r.code, treffer: g?.treffer || [], gruppen: (j?.gruppen || []).length };
}
/* Ein Wort, das NUR in der Creator-Fassung steht. */
const sCreator = await suchen("creator", "Jemand schaut noch drauf");
ok(sCreator.code === 200 && sCreator.treffer.length > 0,
`der Creator findet seine eigene Karte (${sCreator.treffer.length} Treffer)`);
/* DIE ZAHL GEHOERT IN DIE BEDINGUNG. `every()` liefert auf einer LEEREN
Liste `true` -- diese Zeile war beim ersten Lauf gruen, ohne einen
einzigen Treffer angesehen zu haben. Genau der Fehler vom 01.09.2026
im Shop, nur mit anderen Namen. */
ok(sCreator.treffer.length > 0
&& sCreator.treffer.every((t) => t.ziel && !t.ziel.includes("undefined")),
`…und jeder der ${sCreator.treffer.length} Treffer hat ein Ziel `
+ `(${sCreator.treffer.map((t) => t.ziel).join(", ") || "keine"})`);
/* Ein Wort, das NUR in der Manager-Fassung steht. */
const sFremd = await suchen("creator", "Zuteilen, freigeben");
ok(sFremd.treffer.length === 0,
`der Creator findet die Manager-Karte NICHT (${sFremd.treffer.length} Treffer)`);
const sManager = await suchen("manager", "Zuteilen, freigeben");
ok(sManager.treffer.length > 0,
`Gegenprobe: der Manager findet sie sehr wohl (${sManager.treffer.length} Treffer)`);
const sModi = await suchen("modi", "Freigabe heißt", CREW_HOST);
ok(sModi.code === 200 && sModi.treffer.length === 0,
`ein Modi findet nichts davon (HTTP ${sModi.code}, ${sModi.treffer.length} Treffer)`);
/* Die Adresse im Treffer muss den Zusatz hinter dem Fragezeichen
tragen -- sonst landen fuenf Karten auf derselben Seite. */
const sBereich = await suchen("creator", "Ruhig statt Drama");
ok(sBereich.treffer.some((t) => t.ziel === "bereich.html?b=community"),
`ein Bereichs-Treffer traegt seinen Zusatz (${sBereich.treffer.map((t) => t.ziel).join(", ")})`);
/* =====================================================================
ETAPPE 6 — BEGRUESSUNG UND RUNDGANG
===================================================================== */
melde("\n=== Einweisung beim ersten Anmelden ===");
async function einweisung(rolle, host = null) {
const r = await roh("/workspace/api/anleitung/einweisung", host, null, kekse[rolle]);
let j = null; try { j = JSON.parse(r.text); } catch { /* bleibt null */ }
return { code: r.code, j };
}
const e1 = await einweisung("creator");
ok(e1.code === 200 && e1.j?.zeigen === true,
`beim ersten Mal wird sie gezeigt (HTTP ${e1.code}, zeigen ${e1.j?.zeigen})`);
ok(Array.isArray(e1.j?.muss) && e1.j.muss.length === 5,
`…mit den fuenf Muss-Kacheln (${e1.j?.muss?.length})`);
const gesehen = await roh("/workspace/api/anleitung/einweisung/gesehen", null, {}, kekse.creator,
"POST");
ok(gesehen.code === 200, `„gesehen“ laesst sich merken (HTTP ${gesehen.code})`);
const e2 = await einweisung("creator");
ok(e2.j?.zeigen === false, "beim zweiten Mal nicht mehr");
/* DIE CREW BEKOMMT 200 UND NICHT 404. Das Skript laeuft auf JEDER
Startseite; ein Fehlschlag waere eine rote Zeile in der Konsole bei
jedem Aufruf -- und die verdeckt die naechste, die echt ist. */
const eModi = await einweisung("modi", CREW_HOST);
ok(eModi.code === 200 && eModi.j?.zeigen === false,
`ein Modi bekommt eine ruhige Absage (HTTP ${eModi.code}, zeigen ${eModi.j?.zeigen})`);
const eDogi = await einweisung("admin");
ok(eDogi.code === 200 && eDogi.j?.zeigen === false,
`DogFather auch -- er braucht keine Einweisung (zeigen ${eDogi.j?.zeigen})`);
/* DER ROLLENWECHSEL. Der Bauplan verlangt, dass die Einweisung dann
einmal neu startet. Gebaut ist das NICHT als Sonderregel, sondern
ueber den Schluessel (Person, Rolle) -- die neue Rolle hat schlicht
noch keine Zeile. Genau das wird hier nachgemessen. */
{
const d4 = new DatabaseSync(process.env.WORKSPACE_DB);
d4.prepare("UPDATE personen SET rolle = 'scout' WHERE rolle = 'creator'").run();
d4.close();
const neuAn = await anmelden("scout");
const alt = kekse.scout;
kekse.scout = neuAn || alt;
const eNach = await einweisung("scout");
kekse.scout = alt;
ok(eNach.j?.zeigen === true,
`nach einem Rollenwechsel startet sie einmal neu (zeigen ${eNach.j?.zeigen})`);
const d5 = new DatabaseSync(process.env.WORKSPACE_DB);
d5.prepare("UPDATE personen SET rolle = 'creator' WHERE name = 'Luna'").run();
d5.close();
}
/* ---------- Abschluss ------------------------------------------------ */
try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ }
console.log(`\n${fehler ? "FEHLER: " + fehler : "Alles in Ordnung"} — ${geprueft} Prüfungen`);
+8 -2
View File
@@ -31,6 +31,7 @@
import { mkdtempSync, rmSync, appendFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { tagLokal } from "./helfer-zeit.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-evk-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
@@ -85,8 +86,13 @@ function anlegen(name, rolle, code) {
const idDogi = anlegen("Dogfather", "admin", "CODE-DOGI-0001");
const idLuna = anlegen("Luna", "creator", "CODE-CREA-0001");
const heute = new Date();
const tag = (v) => new Date(heute.getTime() + v * 86400000).toISOString().slice(0, 10);
/* ORTSZEIT, NICHT UTC (berichtigt 06.10.2026, gefunden von pruef-struktur).
Hier stand `toISOString().slice(0, 10)`. Zwischen 00:00 und 02:00
deutscher Zeit liegt UTC noch im Vortag -- ein Lauf um Mitternacht
haette Termine einen Tag zu frueh angelegt und dann an der falschen
Stelle gesucht. `tagLokal` ist die Stelle, an der das Haus das
einmal richtig macht. */
const tag = (v) => tagLokal(v);
function evt(titel, von, bis, auf, reg) {
d.prepare("INSERT INTO eintraege (titel, text, bereich, art, status, datum, event_ende,"
+ " event_aufgaben, event_regeln, dringlichkeit, erstellt, erstellt_von)"
+5 -1
View File
@@ -37,6 +37,7 @@
import { mkdtempSync, rmSync, appendFileSync, readFileSync, readdirSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { heuteLokal } from "./helfer-zeit.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-hl-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
@@ -142,7 +143,10 @@ function anlegen(name, rolle, code) {
return d.prepare("SELECT last_insert_rowid() AS id").get().id;
}
anlegen("Dogfather", "admin", "CODE-DOGI-0001");
const heute = new Date().toISOString().slice(0, 10);
/* ORTSZEIT statt UTC -- siehe helfer-zeit.mjs. Nachts zwischen
00:00 und 02:00 liegt UTC einen Tag zurueck, und dann sucht diese
Pruefung an einem Datum, das sie selbst nicht geschrieben hat. */
const heute = heuteLokal();
/* Drei Marken auf demselben Brett: eine je Haus und eine ohne. */
for (const [titel, haus] of [["Marke-CREW", "crew"], ["Marke-AGENTUR", "agentur"], ["Marke-OHNE", null]]) {
d.prepare("INSERT INTO eintraege (titel, text, bereich, art, status, datum, dringlichkeit, erstellt, erstellt_von, haus)"
+12
View File
@@ -133,6 +133,17 @@ const idDogi = person("Filipe", "admin", "CODE-DOGI-0001");
const idCigdem = person("Cigdem", "manager", "CODE-CIGDEM-01");
const idBen = person("Ben", "scout", "CODE-BEN-00001");
const idTili = person("Tili", "creator", "CODE-TILI-0001");
/* SPICY MEDIA HAT HIER VIER WOCHEN GEFEHLT (06.10.2026).
Von den fuenf Rollen des Agenturhauses liefen fuenf Durchgaenge --
aber zweimal Manager und zweimal Scout, und Spicy Media gar nicht.
Gemerkt habe ich es erst, als die Anleitung ihr eine eigene
Fassung gab und ich wissen wollte, ob die Seite fuer sie aufgeht.
Sie ist nicht "noch eine Rolle": Ihr gehoert die Gruppe "Rund um
das Team" samt Team-Lage, die sonst niemand ausser DogFather hat.
Diese Kachel ist also auf keinem Durchgang je geoeffnet worden. */
person("Spicy", "spicy", "CODE-SPICY-00001");
/* Zwei Neue ohne jede Zuteilung -- der Zustand am ersten Tag. */
person("Neu-Scout", "scout", "CODE-NEU-000001");
person("Neu-Manager", "manager", "CODE-NEUM-00001");
@@ -217,6 +228,7 @@ const ROLLEN = [
{ rolle: "manager", code: "CODE-CIGDEM-01", name: "Manager (mit Creator)" },
{ rolle: "scout", code: "CODE-BEN-00001", name: "Scout (mit Creator)" },
{ rolle: "creator", code: "CODE-TILI-0001", name: "Creator (Tili)" },
{ rolle: "spicy", code: "CODE-SPICY-00001", name: "Spicy Media" },
{ rolle: "scout", code: "CODE-NEU-000001", name: "Scout (OHNE Creator)" },
{ rolle: "manager", code: "CODE-NEUM-00001", name: "Manager (OHNE Creator)" },
/* ==== DIE BEIDEN AUS DEM ANDEREN HAUS (berichtigt 06.10.2026) ====
+306 -5
View File
@@ -110,7 +110,7 @@ anleitungRouter.get("/workspace/api/anleitung", (req, res) => {
"SELECT leitgedanke FROM anl_rolle WHERE haus = ? AND rolle = ?").get(HAUS, rolle);
const karten = d.prepare(
`SELECT kachel, stufe, wozu, tust, merke, reihe, geaendert
`SELECT id, kachel, stufe, wozu, tust, merke, reihe, geaendert
FROM anl_karte WHERE haus = ? AND rolle = ?
ORDER BY reihe, id`).all(HAUS, rolle);
@@ -130,6 +130,32 @@ anleitungRouter.get("/workspace/api/anleitung", (req, res) => {
const schritte = nachArt("schritt");
const fertig = schritte.filter((z) => z.erledigt).length;
/* ==================================================================
DIE MARKE "NEU" -- UND WARUM SIE EIN ENDE BRAUCHT
Der Bauplan sagt: "Aendert DogFather einen Eintrag, traegt er
fuer alle die Marke Neu." Er sagt nicht, wann sie verschwindet.
Ohne Ende ist nach einem halben Jahr alles neu, und die Marke
sagt nichts mehr -- dieselbe Krankheit wie eine Warnung, die
immer kommt.
Sie gilt deshalb, solange BEIDES zutrifft:
* die Aenderung ist hoechstens 14 Tage her, UND
* die Person hat die Seite seit der Aenderung nicht geoeffnet.
Der zweite Teil ist der wichtigere: Wer nachgesehen hat, hat es
gesehen. Der erste faengt den ab, der monatelang nicht
hereinschaut -- fuer den waere nach der Rueckkehr sonst die
halbe Seite "neu", und das hilft niemandem.
`zuletzt` wird NACH dem Rechnen fortgeschrieben, nicht davor --
sonst waere die Marke schon beim ersten Laden weg. */
const besuch = d.prepare(
"SELECT gesehen_am FROM anl_besuch WHERE person_id = ?").get(person?.id ?? 0);
const zuletzt = besuch?.gesehen_am || "";
const FRIST = new Date(Date.now() - 14 * 86400_000).toISOString();
const istNeu = (geaendert) => !!geaendert && geaendert > FRIST && geaendert > zuletzt;
/* DIE ZAHL GEHOERT IN DIE ANTWORT, nicht nur in die Liste. Die
Seite kann damit sagen „18 Karten" — und eine Pruefung kann
nachrechnen, ohne die Liste selbst zu zaehlen. */
@@ -153,12 +179,22 @@ anleitungRouter.get("/workspace/api/anleitung", (req, res) => {
sehen, kann sie aber nicht setzen -- es waere sonst sein
eigener Fortschritt an fremden Schritten. */
darf_abhaken: String(req.person?.rolle || "") === rolle,
karten,
nicht: nachArt("nicht").map((z) => ({ titel: z.titel, text: z.text })),
takt: nachArt("takt").map((z) => ({ titel: z.titel, text: z.text })),
fragen: nachArt("frage").map((z) => ({ titel: z.titel, text: z.text })),
karten: karten.map((k) => ({ ...k, neu: istNeu(k.geaendert) })),
nicht: nachArt("nicht").map((z) => ({ id: z.id, titel: z.titel, text: z.text })),
takt: nachArt("takt").map((z) => ({ id: z.id, titel: z.titel, text: z.text })),
fragen: nachArt("frage").map((z) => ({ id: z.id, titel: z.titel, text: z.text })),
anzahl: karten.length,
});
/* Erst antworten, dann den Besuch vermerken. Haette die Zeile
davor gestanden, waere jede Aenderung schon beim ersten Laden
nicht mehr "neu" gewesen -- die Marke haette nie jemand gesehen. */
if (person?.id) {
d.prepare(
`INSERT INTO anl_besuch (person_id, gesehen_am) VALUES (?,?)
ON CONFLICT(person_id) DO UPDATE SET gesehen_am = excluded.gesehen_am`)
.run(person.id, new Date().toISOString());
}
} catch (fehler) {
console.error("[workspace] Anleitung:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
@@ -279,3 +315,268 @@ export function offeneHinweise(person) {
return [];
}
}
/* =====================================================================
DIE PFLEGE — NUR DOGFATHER UND SPICY (Etappe 4)
=====================================================================
Bauplan Kapitel 11: Rolle waehlen und Vorschau, Stufe aendern, Texte
bearbeiten, Stand je Person, Hinweis bei fehlendem Eintrag.
DIE VORSCHAU IST NICHT GEBAUT WORDEN -- es gibt sie schon. Der
Sicht-Umschalter in der Kopfleiste zeigt jede Seite mit den Augen
einer anderen Person, auch diese. Eine zweite Rollenauswahl waere
dieselbe Funktion an einer Stelle, an der sie niemand sucht.
WER DARF: `PFLEGE_ROLLEN` = admin und spicy. Entscheidung Filipe am
06.10.2026, dieselbe Regel wie bei den Manager-Zielen. Geprueft wird
`req.person`, NICHT `req.sicht`: Wer die Sicht eines Creators
einnimmt, soll sehen, was dieser sieht -- und in dem Moment nichts
aendern koennen, ohne es zu merken.
===================================================================== */
function nurPflege(req, res, next) {
if (req.person?.haus === "crew") return res.status(404).json({ fehler: "nicht_hier" });
if (!PFLEGE_ROLLEN.includes(String(req.person?.rolle || ""))) {
return res.status(403).json({ fehler: "nicht_erlaubt" });
}
next();
}
const text = (v, max) => String(v ?? "").trim().slice(0, max);
/** Eine Karte aendern: Stufe und die drei Saetze. */
anleitungRouter.put("/workspace/api/anleitung/karte/:id", nurPflege, (req, res) => {
try {
const id = Number(req.params.id);
if (!Number.isInteger(id) || id <= 0) return res.status(400).json({ fehler: "keine_nummer" });
const stufe = String(req.body?.stufe ?? "");
if (!STUFEN.some((s) => s.schluessel === stufe)) {
return res.status(400).json({ fehler: "unbekannte_stufe" });
}
const d = db();
const n = d.prepare(
`UPDATE anl_karte SET stufe = ?, wozu = ?, tust = ?, merke = ?,
geaendert = ?, geaendert_von = ?
WHERE id = ? AND haus = ?`)
.run(stufe, text(req.body?.wozu, 300), text(req.body?.tust, 400),
text(req.body?.merke, 400), new Date().toISOString(), req.person.id, id, HAUS);
if (!n.changes) return res.status(404).json({ fehler: "keine_karte" });
res.json({ ok: true });
} catch (fehler) {
console.error("[workspace] Anleitung Karte:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
}
});
/** Eine fehlende Karte anlegen.
*
* Gebraucht fuer genau den Fall, den der Bauplan "Fuer diese Kachel
* fehlt ein Eintrag" nennt: Eine neue Kachel kommt ins Haus, und die
* Anleitung kennt sie noch nicht. Ohne diesen Weg muesste jemand in
* die Datenbank. */
anleitungRouter.post("/workspace/api/anleitung/karte", nurPflege, (req, res) => {
try {
const rolle = String(req.body?.rolle ?? "");
const kachel = text(req.body?.kachel, 80);
const stufe = String(req.body?.stufe ?? "bedarf");
if (!FASSUNGEN.includes(rolle)) return res.status(400).json({ fehler: "unbekannte_rolle" });
if (!kachel) return res.status(400).json({ fehler: "keine_kachel" });
if (!STUFEN.some((s) => s.schluessel === stufe)) {
return res.status(400).json({ fehler: "unbekannte_stufe" });
}
const d = db();
const platz = d.prepare(
"SELECT COALESCE(MAX(reihe), -1) + 1 AS n FROM anl_karte WHERE haus = ? AND rolle = ?")
.get(HAUS, rolle).n;
try {
d.prepare(
`INSERT INTO anl_karte (haus, rolle, kachel, stufe, wozu, tust, merke,
reihe, geaendert, geaendert_von)
VALUES (?,?,?,?,?,?,?,?,?,?)`)
.run(HAUS, rolle, kachel, stufe, text(req.body?.wozu, 300),
text(req.body?.tust, 400), text(req.body?.merke, 400), platz,
new Date().toISOString(), req.person.id);
} catch {
/* Die Tabelle hat UNIQUE(haus, rolle, kachel) -- eine zweite
Karte zur selben Kachel kann es nicht geben, und das ist der
Grund, warum die Zuordnungspruefung "genau eine" sagen darf. */
return res.status(409).json({ fehler: "gibt_es_schon" });
}
res.json({ ok: true });
} catch (fehler) {
console.error("[workspace] Anleitung Karte anlegen:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
}
});
/** Eine Karte entfernen -- fuer Kacheln, die es nicht mehr gibt. */
anleitungRouter.delete("/workspace/api/anleitung/karte/:id", nurPflege, (req, res) => {
try {
const id = Number(req.params.id);
if (!Number.isInteger(id) || id <= 0) return res.status(400).json({ fehler: "keine_nummer" });
const n = db().prepare("DELETE FROM anl_karte WHERE id = ? AND haus = ?").run(id, HAUS);
if (!n.changes) return res.status(404).json({ fehler: "keine_karte" });
res.json({ ok: true });
} catch (fehler) {
console.error("[workspace] Anleitung Karte loeschen:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
}
});
/** Eine Listenzeile aendern (Satz, Schritt, Nicht deins, Takt, Frage). */
anleitungRouter.put("/workspace/api/anleitung/zeile/:id", nurPflege, (req, res) => {
try {
const id = Number(req.params.id);
if (!Number.isInteger(id) || id <= 0) return res.status(400).json({ fehler: "keine_nummer" });
const d = db();
const alt = d.prepare("SELECT art FROM anl_zeile WHERE id = ? AND haus = ?").get(id, HAUS);
if (!alt) return res.status(404).json({ fehler: "keine_zeile" });
/* Ein Ziel gibt es nur beim Schritt. Bei einer Frage waere es ein
Feld, das nirgends angezeigt wird -- und beim naechsten Umbau
haelt es jemand fuer eine Zusage. */
const ziel = alt.art === "schritt" ? (text(req.body?.ziel, 200) || null) : null;
d.prepare(
`UPDATE anl_zeile SET titel = ?, text = ?, ziel = ?, geaendert = ?, geaendert_von = ?
WHERE id = ? AND haus = ?`)
.run(text(req.body?.titel, 200), text(req.body?.text, 600), ziel,
new Date().toISOString(), req.person.id, id, HAUS);
res.json({ ok: true });
} catch (fehler) {
console.error("[workspace] Anleitung Zeile:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
}
});
/** Den Leitgedanken einer Rolle aendern. */
anleitungRouter.put("/workspace/api/anleitung/rolle/:rolle", nurPflege, (req, res) => {
try {
const rolle = String(req.params.rolle || "");
if (!FASSUNGEN.includes(rolle)) return res.status(404).json({ fehler: "unbekannte_rolle" });
db().prepare(
`INSERT INTO anl_rolle (haus, rolle, leitgedanke, geaendert, geaendert_von)
VALUES (?,?,?,?,?)
ON CONFLICT(haus, rolle) DO UPDATE SET leitgedanke = excluded.leitgedanke,
geaendert = excluded.geaendert, geaendert_von = excluded.geaendert_von`)
.run(HAUS, rolle, text(req.body?.leitgedanke, 600),
new Date().toISOString(), req.person.id);
res.json({ ok: true });
} catch (fehler) {
console.error("[workspace] Anleitung Rolle:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
}
});
/** Wer ist wie weit? (Bauplan: "Stand je Person: fertig/offen mit Datum")
*
* Es ist eine ARBEITSLAGE, keine Ueberwachung -- dieselbe
* Unterscheidung wie bei der Team-Lage. Hier steht, wer seine
* Einweisung noch offen hat, damit jemand nachfragen kann. Nicht,
* was er gelesen hat oder wie lange er gebraucht hat. */
anleitungRouter.get("/workspace/api/anleitung/stand", nurPflege, (req, res) => {
try {
const leute = db().prepare(
`SELECT p.id, p.name, p.rolle,
(SELECT COUNT(*) FROM anl_zeile z
WHERE z.haus = ? AND z.rolle = p.rolle AND z.art = 'schritt') AS gesamt,
(SELECT COUNT(*) FROM anl_stand s JOIN anl_zeile z2 ON z2.id = s.zeile_id
WHERE s.person_id = p.id AND z2.art = 'schritt') AS erledigt,
(SELECT MAX(s2.erledigt_am) FROM anl_stand s2 WHERE s2.person_id = p.id) AS zuletzt
FROM personen p
WHERE p.aktiv = 1 AND p.rolle IN (${FASSUNGEN.map(() => "?").join(",")})
ORDER BY p.rolle, p.name`).all(HAUS, ...FASSUNGEN);
res.json({
leute: leute.map((p) => ({
name: p.name, rolle: p.rolle,
erledigt: Number(p.erledigt || 0), gesamt: Number(p.gesamt || 0),
fertig: Number(p.gesamt || 0) > 0 && Number(p.erledigt || 0) >= Number(p.gesamt || 0),
zuletzt: p.zuletzt || null,
})),
});
} catch (fehler) {
console.error("[workspace] Anleitung Stand:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
}
});
/* =====================================================================
DIE EINWEISUNG BEIM ERSTEN ANMELDEN (Etappe 6)
=====================================================================
Zwei Wege, und beide sind klein: "Soll ich?" und "Ich habe sie
gezeigt." Alles andere -- die fuenf Schritte, das Hervorheben, der
Text -- steht im Browser, weil nur er weiss, wo die Dinge auf dem
Bildschirm liegen.
DIE ANTWORT IST IMMER 200, auch fuer die Crew und fuer DogFather --
dann eben mit `zeigen: false`. Ein 404 waere hier das Falsche: Das
Skript laeuft auf JEDER Startseite, und ein Fehlschlag in der
Konsole bei jedem Aufruf ist genau die Meldung, die die naechste
echte verdeckt.
===================================================================== */
anleitungRouter.get("/workspace/api/anleitung/einweisung", (req, res) => {
try {
/* NICHT `req.sicht`: Die Einweisung gehoert der Person, die
angemeldet ist. DogFather, der die Sicht eines Creators
einnimmt, soll nicht dessen Begruessung bekommen -- und erst
recht nicht fuer ihn abhaken, dass sie gezeigt wurde. */
const person = req.person;
const rolle = String(person?.rolle || "");
if (person?.haus === "crew" || !FASSUNGEN.includes(rolle)) {
return res.json({ zeigen: false, rolle });
}
const d = db();
const schon = d.prepare(
"SELECT 1 AS da FROM anl_einweisung WHERE person_id = ? AND rolle = ?")
.get(person.id, rolle);
/* Die Muss-Kacheln als SCHLUESSEL. Die Adressen kennt nur der
Browser (siehe oben); er rechnet sie mit derselben Funktion aus,
mit der auch die Karten verbunden werden. */
const muss = d.prepare(
`SELECT kachel FROM anl_karte
WHERE haus = ? AND rolle = ? AND stufe = 'muss' ORDER BY reihe`)
.all(HAUS, rolle).map((z) => z.kachel);
res.json({
zeigen: !schon,
rolle,
name: person.name || "",
muss,
});
} catch (fehler) {
console.error("[workspace] Einweisung:", fehler?.message);
/* Auch im Fehlerfall kein 500: Eine kaputte Begruessung darf die
Startseite nicht mit einer roten Zeile begruessen. */
res.json({ zeigen: false });
}
});
/** Gezeigt -- egal ob durchgeklickt oder "Spaeter".
*
* BEIDES ZAEHLT, und das ist Absicht. Der Bauplan sagt: "Spaeter ist
* erlaubt. Dann steht unter 'Was ist dran': Erste Schritte noch
* offen." Wer "Spaeter" waehlt, hat die Begruessung gesehen und soll
* sie nicht bei jedem Aufruf wieder bekommen -- der Hinweis
* uebernimmt. Ein Fenster, das so lange wiederkommt, bis man das
* Richtige anklickt, ist keine Einladung, sondern eine Sperre. */
anleitungRouter.post("/workspace/api/anleitung/einweisung/gesehen", (req, res) => {
try {
const person = req.person;
const rolle = String(person?.rolle || "");
if (person?.haus === "crew" || !FASSUNGEN.includes(rolle)) {
return res.json({ ok: true });
}
db().prepare(
`INSERT INTO anl_einweisung (person_id, rolle, gezeigt_am) VALUES (?,?,?)
ON CONFLICT(person_id, rolle) DO NOTHING`)
.run(person.id, rolle, new Date().toISOString());
res.json({ ok: true });
} catch (fehler) {
console.error("[workspace] Einweisung merken:", fehler?.message);
res.status(500).json({ fehler: "serverfehler" });
}
});
+51
View File
@@ -35,6 +35,10 @@ import { sichtbar as sichtbarDateien } from "./workspace-dateien.js";
vor ihm steht. Eine Suche, die weniger findet als die Seite zeigt,
liest sich wie "gibt es nicht". */
import { sichtbarEintrag as sichtbarEintraege, BEREICHE } from "./workspace-bereiche.js";
/* Welche Rollen eine Einweisung haben -- aus dem Fachmodul, nicht
danebengeschrieben. Eine zweite Liste hier waere die, die beim
naechsten Haus-Umbau stehen bleibt. */
import { FASSUNGEN as ANLEITUNG_ROLLEN } from "./anleitung-tabellen.js";
export const sucheRouter = express.Router();
@@ -278,6 +282,53 @@ sucheRouter.get("/workspace/api/suche", (req, res) => {
}
}
/* ---------- Die Anleitung (06.10.2026, Etappe 5) ----------------
NUR DIE EIGENE FASSUNG. Jede Rolle hat ihre eigenen Karten mit
eigenen Texten; faende ein Creator die Karte des Managers,
stuende dort "Zuteilen, freigeben" neben einer Kachel, die er
gar nicht hat. Deshalb `rolle = ?` in der Bedingung und nicht
nur die Adresspruefung weiter unten -- die trennt die Haeuser,
nicht die Rollen.
DER NAME DER KACHEL STEHT NICHT IN DER DATENBANK (siehe
anleitung-tabellen.js), also kann die Suche ihn auch nicht
durchsuchen. Gefunden wird ueber die drei Saetze, und als Titel
steht der Kachel-Schluessel -- aus `bereich:schutz` wird
"Schutz". Das ist ehrlicher, als einen Namen zu erfinden, der
dann nicht mehr zu der Kachel passt, die inzwischen anders
heisst. */
{
const rolle = String(person?.rolle || "");
if (ANLEITUNG_ROLLEN.includes(rolle)) {
quelle("Anleitung", `
SELECT kachel, stufe, wozu, tust, merke
FROM anl_karte
WHERE haus = 'agentur' AND rolle = ?
AND (wozu LIKE ? ESCAPE '\\' OR tust LIKE ? ESCAPE '\\'
OR merke LIKE ? ESCAPE '\\' OR kachel LIKE ? ESCAPE '\\')
ORDER BY reihe LIMIT ${JE_BEREICH}`,
[rolle, m, m, m, m],
(z) => {
const felder = [["Wozu", z.wozu], ["Was du hier tust", z.tust], ["Merke", z.merke]];
const treffer = felder.find(([, w]) => w && w.toLowerCase().includes(q.toLowerCase()));
/* Aus dem Schluessel wieder etwas Lesbares machen:
`bereich:schutz` -> `Schutz`, `manager-ziele` -> `Manager-ziele`. */
const name = String(z.kachel).split(":").pop().replace(/^./, (c) => c.toUpperCase());
return {
titel: name,
text: treffer ? ausschnitt(treffer[1], q) : null,
zusatz: ["Einweisung", treffer ? treffer[0] : null].filter(Boolean).join(" · "),
/* Mit dem Zusatz hinter dem Fragezeichen -- sonst landen
fuenf Karten auf derselben Seite. */
ziel: z.kachel.startsWith("bereich:")
? `bereich.html?b=${z.kachel.slice(8)}`
: `${z.kachel}.html`,
};
});
}
}
/* UND HIER GILT SIE AUCH (15.09.2026).
Ein Suchtreffer ist ein Verweis auf eine Seite. Zeigt er auf eine,
+121 -15
View File
@@ -7,17 +7,17 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/anleitung.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/anleitung.css?v=202610061535" />
<!-- module.css an VORLETZTER, haus.css an LETZTER Stelle. Die
Reihenfolge ist keine Geschmacksfrage: haus.css setzt nur
Variablen, und bei Variablen entscheidet allein, wer zuletzt
kommt. pruef-css-klassen.mjs misst genau dieses Paar nach. -->
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -63,11 +63,49 @@
werden muss. Der Satz daneben steht trotzdem da – eine Zahl,
die man nur sieht, wenn man die Maus darüberhält, ist keine.
================================================================== -->
<!-- Bauplan Kapitel 04: „Knopf ,Rundgang noch einmal starten'".
Er führt auf die Zentrale zurück und startet ihn dort — dort
liegen die fünf Stationen, nicht hier. -->
<p class="an-nochmal">
<a class="an-nochmal__weg" href="start.html#rundgang">Rundgang noch einmal starten</a>
</p>
<div class="an-stand" id="stand" hidden>
<progress class="an-stand__balken" id="stand-balken" max="1" value="0"></progress>
<p class="an-stand__satz" id="stand-satz"></p>
</div>
<!-- ==================================================================
DIE PFLEGE — nur für DogFather und Spicy Media
Sie ist ein SCHALTER und keine zweite Seite. Wer die Texte
ändert, will sie dort ändern, wo er sie sieht – eine getrennte
Verwaltungsansicht hieße, zwischen zwei Fenstern zu vergleichen,
und genau dabei entstehen die Texte, die nicht zusammenpassen.
Die Rolle wird NICHT hier gewählt: Dafür gibt es den
Sicht-Umschalter in der Kopfleiste, der auf jeder Seite des
Hauses dasselbe tut.
================================================================== -->
<div class="an-pflege" id="pflege" hidden>
<button type="button" class="an-pflege__knopf" id="pflege-an" aria-pressed="false">
Texte bearbeiten
</button>
<button type="button" class="an-pflege__knopf" id="pflege-stand">
Wer ist wie weit?
</button>
<span class="an-pflege__satz" id="pflege-satz"></span>
</div>
<!-- Kacheln ohne Karte. Steht nur in der Pflege und nur, wenn es
welche gibt – der Bauplan nennt es „Für diese Kachel fehlt ein
Eintrag". Es ist derselbe Abgleich, den pruef-anleitung in beide
Richtungen prüft; hier als Angebot, ihn zu schließen. -->
<section class="an-block an-fehlend" id="fehlend-block" hidden>
<h2 class="an-block__titel">Für diese Kacheln fehlt ein Eintrag</h2>
<ul class="an-fehlend__liste" id="fehlend"></ul>
</section>
<p class="ladefehler" id="ladefehler" hidden>
<span class="ladefehler__satz">Die Seite konnte nicht geladen werden.</span>
<span class="ladefehler__grund" id="ladefehler-grund"></span>
@@ -89,7 +127,7 @@
<!-- ---------- IN 60 SEKUNDEN -------------------------------------
Steht VOR allem anderen und ist nicht zuklappbar: Drei Sätze
sind kürzer als der Knopf, mit dem man sie aufklappen würde. -->
<section class="an-block an-block--kopf">
<section class="an-block">
<h2 class="an-block__titel">In 60 Sekunden</h2>
<p class="an-leit" id="leitgedanke"></p>
<ul class="an-saetze" id="saetze"></ul>
@@ -148,6 +186,74 @@
</main>
<!-- ==================================================================
BEARBEITEN
Ein echtes <dialog>: Fokusfang, Escape und der abdunkelnde
Hintergrund kommen mit. Ein Fenster für beides – Karten und
Listenzeilen –, weil es dieselbe Handlung ist: Text ändern,
speichern. Zwei Fenster wären zweimal derselbe Knopf an zwei
Stellen, von denen eine irgendwann anders aussieht.
================================================================== -->
<dialog class="dialog" id="aendern">
<form class="an-form" id="aendern-form" method="dialog">
<div>
<h2 class="dialog__titel" id="aendern-titel">Bearbeiten</h2>
<p class="dialog__unter dialog__unter--still" id="aendern-unter"></p>
</div>
<label class="an-feld" id="feld-stufe" hidden>
<span class="an-feld__schild">Stufe</span>
<select id="e-stufe"></select>
</label>
<label class="an-feld" id="feld-a" hidden>
<span class="an-feld__schild" id="schild-a">Titel</span>
<input type="text" id="e-a" maxlength="300" autocomplete="off" />
</label>
<label class="an-feld" id="feld-b" hidden>
<span class="an-feld__schild" id="schild-b">Text</span>
<textarea id="e-b" maxlength="600" rows="2"></textarea>
</label>
<label class="an-feld" id="feld-c" hidden>
<span class="an-feld__schild" id="schild-c">Merke</span>
<textarea id="e-c" maxlength="400" rows="2"></textarea>
</label>
<label class="an-feld" id="feld-ziel" hidden>
<span class="an-feld__schild">Sprung zur Kachel (leer = kein Sprung)</span>
<input type="text" id="e-ziel" maxlength="200" autocomplete="off"
placeholder="z. B. profil.html" />
</label>
<p class="an-form__fehler" id="aendern-fehler" role="alert" aria-live="polite"></p>
<div class="dialog__knoepfe">
<button type="button" class="knopf-still" id="aendern-abbruch">Abbrechen</button>
<button type="submit" class="knopf" id="aendern-speichern">Speichern</button>
</div>
</form>
</dialog>
<!-- Wer ist wie weit. Eine ARBEITSLAGE, keine Überwachung: Hier steht,
wer seine Einweisung noch offen hat – nicht, was er gelesen hat. -->
<dialog class="dialog dialog--breit" id="stand-dialog">
<form class="an-form" method="dialog">
<div>
<h2 class="dialog__titel">Wer ist wie weit?</h2>
<p class="dialog__unter dialog__unter--still">
Nur die Ersten Schritte. Wer durch ist, braucht nichts mehr von dir.
</p>
</div>
<div id="stand-liste"></div>
<div class="dialog__knoepfe">
<button type="button" class="knopf" id="stand-zu">Schließen</button>
</div>
</form>
</dialog>
<!-- bereiche.js VOR kopf.js: Dort steht `window.Bereiche`, und
kopf.js liest daraus die Leitungsrollen. Ohne sie stürzt jede
Seite ab, und zwar nur in der Browserkonsole -- die Kopfleiste
@@ -155,16 +261,16 @@
Und anleitung.js braucht es doppelt: Symbol, Farbe, Name und
Adresse jeder Karte kommen von dort, nicht vom Server. -->
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<!-- wahl.js gehört zu kopf.js: Der Sicht-Umschalter baut daraus seine
Liste. pruef-css-klassen setzt das durch, und zwar auch die
Reihenfolge -- kopf.js fragt beim Aufbau nach dem fertigen
Bedienelement. -->
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/anleitung.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/anleitung.js?v=202610061535" defer></script>
</body>
</html>
+5 -5
View File
@@ -16,8 +16,8 @@
verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
<!-- Ohne diese drei nimmt ein iPhone einen Bildschirmausschnitt als
Symbol, Android zeichnet die Leiste weiss, und die Seite oeffnet
ausserhalb der App -- auf einer Seite, die genau erklaeren soll,
@@ -33,7 +33,7 @@
schreibt jede Seite app.webmanifest -- auch die hier. -->
<link rel="manifest" href="/workspace/app.webmanifest" />
<meta name="theme-color" content="#06090f" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<style>
/* Bewusst in der Seite und nicht in einer eigenen Datei: Diese Seite
soll auch dann noch etwas anzeigen, wenn genau das schiefgeht,
@@ -135,7 +135,7 @@
<script src="assets/js/anruf-probe.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/anruf-probe.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
</body>
</html>
+4 -4
View File
@@ -23,25 +23,25 @@
},
"icons": [
{
"src": "/assets/img/app-symbole/workspace-192.png?v=202610061421",
"src": "/assets/img/app-symbole/workspace-192.png?v=202610061535",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/img/app-symbole/workspace-512.png?v=202610061421",
"src": "/assets/img/app-symbole/workspace-512.png?v=202610061535",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202610061421",
"src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202610061535",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202610061421",
"src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202610061535",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
+291
View File
@@ -45,6 +45,23 @@
max-width: 62ch;
}
.an-nochmal { margin: 16px 0 0; }
.an-nochmal__weg {
display: inline-flex;
align-items: center;
min-height: 40px;
padding: 0 14px;
border-radius: 999px;
border: 1px solid var(--rand);
background: var(--flaeche);
color: var(--text-still);
font-size: .85rem;
font-weight: 650;
text-decoration: none;
}
.an-nochmal__weg:hover { color: var(--text); border-color: var(--akzent); }
.an-nochmal__weg:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* =====================================================================
DER FORTSCHRITT (Etappe 2)
=====================================================================
@@ -603,6 +620,276 @@ a.an-schritt__rumpf:hover .an-schritt__name { text-decoration: underline; }
}
.an-hilfe a { color: var(--akzent); }
/* =====================================================================
DIE PFLEGE (Etappe 4)
=====================================================================
Sie ist LEISE, solange sie aus ist. Wer die Seite liest, soll die
Einweisung sehen und nicht die Werkzeuge -- deshalb trägt der
Schalter keine Farbe, bis er gedrückt ist, und die Stift-Knöpfe
gibt es erst dann überhaupt im Dokument (anleitung.js baut sie nur
im Bearbeiten-Zustand).
===================================================================== */
.an-pflege {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 12px;
margin-top: 16px;
padding: 10px 14px;
border: 1px dashed var(--rand);
background: var(--flaeche);
clip-path: polygon(var(--fase, 18px) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fase, 18px));
}
.an-pflege__knopf {
font: inherit;
font-size: .85rem;
font-weight: 650;
min-height: 40px;
padding: 0 14px;
border-radius: 999px;
border: 1px solid var(--rand);
background: transparent;
color: var(--text-still);
cursor: pointer;
transition: background var(--tempo, .18s), color var(--tempo, .18s);
}
.an-pflege__knopf:hover { color: var(--text); }
.an-pflege__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.an-pflege__knopf[aria-pressed="true"] {
background: color-mix(in srgb, var(--akzent) 22%, var(--flaeche));
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
color: var(--text);
}
.an-pflege__satz {
font-size: .85rem;
color: var(--text-still);
}
/* ---------------------------------------------------------------------
DER STIFT
44 Pixel, wie jedes Berührziel im Haus -- auch wenn das Zeichen
darin klein ist. Ein Knopf, den man dreimal treffen muss, ist auf
einem Telefon kein Knopf. */
.an-aendern {
flex: none;
margin-left: auto;
width: 44px; height: 44px;
display: grid;
place-items: center;
font-size: 1rem;
line-height: 1;
border-radius: 10px;
border: 1px solid var(--rand);
background: var(--flaeche);
color: var(--text-still);
cursor: pointer;
transition: color var(--tempo, .18s), border-color var(--tempo, .18s);
}
.an-aendern:hover { color: var(--akzent); border-color: var(--akzent); }
.an-aendern:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* In einer Frage sitzt er unten statt rechts: Die Zusammenfassung ist
der Schalter zum Aufklappen, und ein Knopf darin wäre ein Knopf im
Knopf. */
.an-frage__aendern { margin: 0 14px 12px; }
/* ---------------------------------------------------------------------
DIE MARKE „NEU"
Ein WORT, kein Punkt. Ein farbiger Punkt ohne Wort ist eine Frage
und keine Auskunft -- und für jemanden, der Farben schlecht
unterscheidet, ist er gar nichts. */
.an-karte__neu {
font-size: .78rem;
font-weight: 700;
letter-spacing: .04em;
text-transform: uppercase;
padding: 1px 7px;
border-radius: 999px;
color: #0a121e;
background: var(--k-gut, #5fc99a);
}
/* ---------------------------------------------------------------------
FEHLENDE EINTRÄGE */
.an-fehlend { border-style: dashed; }
.an-fehlend__liste { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.an-fehlend__zeile {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 12px;
}
.an-fehlend__name { font-weight: 650; color: var(--text); font-size: .95rem; }
.an-fehlend__knopf {
font: inherit;
font-size: .85rem;
font-weight: 650;
min-height: 40px;
padding: 0 14px;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--akzent) 40%, transparent);
background: transparent;
color: var(--akzent);
cursor: pointer;
}
.an-fehlend__knopf:hover { background: color-mix(in srgb, var(--akzent) 12%, transparent); }
.an-fehlend__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.an-fehlend__knopf:disabled { opacity: .5; cursor: default; }
/* ---------------------------------------------------------------------
DAS FENSTER */
.an-form { display: grid; gap: 14px; padding: 20px; }
.an-feld { display: grid; gap: 5px; }
.an-feld__schild {
font-size: .8rem;
font-weight: 700;
letter-spacing: .04em;
text-transform: uppercase;
color: var(--text-still);
}
.an-feld input,
.an-feld textarea,
.an-feld select {
font: inherit;
font-size: .95rem;
/* 44 Pixel: dieselbe Daumenhöhe wie überall. Bei `textarea` wirkt
sie als Mindesthöhe, der Text darf wachsen. */
min-height: 44px;
padding: 9px 12px;
border-radius: var(--radius-klein, 12px);
border: 1px solid var(--rand);
background: color-mix(in srgb, var(--text-still) 8%, transparent);
color: var(--text);
width: 100%;
box-sizing: border-box;
}
.an-feld textarea { resize: vertical; line-height: 1.5; }
.an-feld input:focus-visible,
.an-feld textarea:focus-visible,
.an-feld select:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }
.an-form__fehler {
margin: 0;
min-height: 1.2em;
font-size: .9rem;
color: var(--k-warn, #f0868f);
}
/* ---------------------------------------------------------------------
WER IST WIE WEIT */
.an-wer {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 4px 12px;
padding: 10px 0;
border-bottom: 1px solid var(--rand);
font-size: .92rem;
}
.an-wer:last-child { border-bottom: none; }
.an-wer__name { font-weight: 650; color: var(--text); min-width: 7em; }
.an-wer__rolle { color: var(--text-still); font-size: .85rem; }
.an-wer__stand { margin-left: auto; color: var(--text-leise); font-variant-numeric: tabular-nums; }
.an-wer__wann { color: var(--text-still); font-size: .85rem; font-variant-numeric: tabular-nums; }
/* Fertig ist eine Aussage, kein Haken: Das Wort steht in `__stand`,
die Farbe verstärkt es nur. */
.an-wer[data-fertig="ja"] .an-wer__stand { color: var(--k-gut, #5fc99a); font-weight: 650; }
/* =====================================================================
DER RUNDGANG (Etappe 6)
=====================================================================
KEIN LOCH IN EINER ABDECKUNG. Ein ausgeschnittenes Fenster müsste
bei jedem Scrollen neu gerechnet werden und sitzt beim ersten
Bildaufbau garantiert falsch. Stattdessen: Die ganze Seite wird
leiser (`body[data-rundgang]`), und das Ziel bleibt hell und
bekommt einen Rahmen. Dasselbe Ergebnis, ohne eine einzige
gerechnete Koordinate.
Fällt dieses Skript mittendrin aus, ist die Seite trotzdem heil:
Das Merkmal hängt am `body` und ist beim nächsten Laden weg. */
body[data-rundgang="ja"] main > *,
body[data-rundgang="ja"] .kopfleiste {
opacity: .34;
filter: saturate(.5);
transition: opacity var(--tempo, .18s);
}
body[data-rundgang="ja"] [data-rundgang-ziel="ja"] {
opacity: 1;
filter: none;
position: relative;
z-index: 2;
outline: 2px solid var(--akzent);
outline-offset: 6px;
border-radius: 4px;
}
/* Im letzten Schritt leuchten nur die Muss-Kacheln. Die Gruppe selbst
ist dann das Ziel, die einzelnen Kacheln darin werden gedämpft --
außer diesen. */
body[data-rundgang="ja"] [data-rundgang-ziel="ja"] .kachel { opacity: .3; }
body[data-rundgang="ja"] [data-rundgang-ziel="ja"] .kachel[data-rundgang-muss="ja"] {
opacity: 1;
outline: 2px solid var(--akzent);
outline-offset: 3px;
}
.rg {
position: fixed;
left: 50%;
bottom: max(16px, env(safe-area-inset-bottom));
transform: translateX(-50%);
z-index: 60;
width: min(460px, calc(100vw - 24px));
}
.rg__kasten {
padding: 16px 18px;
border: 1px solid color-mix(in srgb, var(--akzent) 45%, var(--rand));
background: var(--flaeche);
border-radius: var(--radius-klein, 12px);
box-shadow: 0 10px 40px rgba(0, 0, 0, .55);
}
.rg__zaehler {
margin: 0 0 4px;
font-size: .78rem;
font-weight: 700;
letter-spacing: .06em;
text-transform: uppercase;
color: var(--akzent);
}
.rg__titel { margin: 0 0 6px; font-size: 1.1rem; font-weight: 700; color: var(--text); }
.rg__text { margin: 0 0 14px; font-size: .95rem; line-height: 1.55; color: var(--text-leise); }
.rg__knoepfe { display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; }
.rg__still {
font: inherit;
font-size: .9rem;
min-height: 44px;
padding: 0 14px;
border-radius: 999px;
border: 1px solid var(--rand);
background: transparent;
color: var(--text-still);
cursor: pointer;
}
.rg__still:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.rg__weiter { min-height: 44px; }
.rg-gruss__rumpf { padding: 22px; display: grid; gap: 12px; }
.rg-gruss__text {
margin: 0;
font-size: 1rem;
line-height: 1.6;
color: var(--text-leise);
max-width: 44ch;
}
/* =====================================================================
WENIGER BEWEGUNG, WENN JEMAND DAS SO EINGESTELLT HAT
===================================================================== */
@@ -612,6 +899,10 @@ a.an-schritt__rumpf:hover .an-schritt__name { text-decoration: underline; }
.an-stufe__griff::before,
.an-haken__zeichen,
.an-haken__zeichen::after,
.an-pflege__knopf,
.an-aendern,
body[data-rundgang="ja"] main > *,
body[data-rundgang="ja"] .kopfleiste,
.an-stand__balken::-webkit-progress-value,
.an-karte__weg { transition: none; }
}
+202
View File
@@ -21,6 +21,12 @@
const BASIS = '/workspace/api/anleitung';
/* Der zuletzt geladene Stand. Gebraucht, weil die Pflege nach dem
Speichern neu zeichnen muss -- und weil der Schalter "bearbeiten"
dieselben Daten noch einmal braucht, ohne sie erneut zu holen. */
let daten = null;
let pflegeAn = false;
const el = (tag, klasse, text) => {
const k = document.createElement(tag);
if (klasse) k.className = klasse;
@@ -148,7 +154,13 @@
schlecht unterscheidet, läse sonst eine Karte ohne Stufe — und
die Stufe ist das Einzige, was diese Seite überhaupt sortiert. */
namen.append(el('span', 'an-karte__stufe', stufe.name));
/* DIE MARKE "NEU" steht als WORT da, nicht als farbiger Punkt.
Ein Punkt ohne Wort ist eine Frage, keine Auskunft. Sie
verschwindet von selbst: 14 Tage oder bis die Person die Seite
nach der Änderung geöffnet hat -- gerechnet wird das im Server. */
if (eintrag.neu) namen.append(el('span', 'an-karte__neu', 'Neu'));
kopf.append(namen);
if (pflegeAn) kopf.append(aendernKnopf(() => karteOeffnen(eintrag, kachel)));
karte.append(kopf);
const zeilen = el('dl', 'an-karte__zeilen');
@@ -252,8 +264,11 @@
AUFBAUEN
===================================================================== */
function zeigen(d) {
daten = d;
$('ohne-fassung').hidden = true;
$('fassung').hidden = false;
$('pflege').hidden = !d.darf_pflegen;
document.body.dataset.pflege = pflegeAn ? 'ja' : 'nein';
$('leitgedanke').textContent = d.leitgedanke || '';
$('leitgedanke').hidden = !d.leitgedanke;
@@ -295,6 +310,7 @@
rumpf.append(el('span', 'an-schritt__name', s.titel));
rumpf.append(el('span', 'an-schritt__text', s.text));
li.append(rumpf);
if (pflegeAn) li.append(aendernKnopf(() => zeileOeffnen(s, 'schritt')));
return li;
}));
standSetzen(d.fortschritt);
@@ -318,6 +334,7 @@
const li = el('li', 'an-nicht__zeile');
li.append(el('span', 'an-nicht__was', z.titel));
li.append(el('span', 'an-nicht__wer', z.text));
if (pflegeAn) li.append(aendernKnopf(() => zeileOeffnen(z, 'nicht')));
return li;
});
liste('takt', 'takt-block', d.takt || [], (z) => {
@@ -330,8 +347,10 @@
const falte = el('details', 'an-frage');
falte.append(el('summary', 'an-frage__frage', z.titel));
falte.append(el('p', 'an-frage__antwort', z.text));
if (pflegeAn) falte.append(aendernKnopf(() => zeileOeffnen(z, 'frage'), 'an-frage__aendern'));
return falte;
});
fehlendeZeigen(d);
}
function ohneFassung(d) {
@@ -345,6 +364,178 @@
p.hidden = false;
}
/* =====================================================================
DIE PFLEGE (Etappe 4) — nur für DogFather und Spicy Media
=====================================================================
Bearbeitet wird AN ORT UND STELLE. Eine getrennte
Verwaltungsansicht hieße, zwischen zwei Fenstern zu vergleichen –
und genau dabei entstehen Texte, die nicht zueinander passen.
Die Rolle wird nicht hier gewählt: Dafür gibt es den
Sicht-Umschalter in der Kopfleiste.
===================================================================== */
function aendernKnopf(beiKlick, klasse) {
const k = el('button', 'an-aendern' + (klasse ? ' ' + klasse : ''), '✎');
k.type = 'button';
k.title = 'Bearbeiten';
k.setAttribute('aria-label', 'Bearbeiten');
k.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); beiKlick(); });
return k;
}
/* Welche Kacheln dieser Rolle haben noch keine Karte?
Derselbe Abgleich, den pruef-anleitung in beide Richtungen prüft –
hier als Angebot, ihn zu schließen. */
function fehlendeZeigen(d) {
const kasten = $('fehlend-block');
if (!d.darf_pflegen || !pflegeAn) { kasten.hidden = true; return; }
const alle = kachelnFuer(d.rolle);
alle.delete('anleitung');
const haben = new Set((d.karten || []).map((k) => k.kachel));
const fehlt = [...alle.entries()].filter(([s]) => !haben.has(s));
kasten.hidden = !fehlt.length;
$('fehlend').replaceChildren(...fehlt.map(([schluessel, kachel]) => {
const li = el('li', 'an-fehlend__zeile');
li.append(el('span', 'an-fehlend__name', kachel.name));
const k = el('button', 'an-fehlend__knopf', 'Eintrag anlegen');
k.type = 'button';
k.addEventListener('click', async () => {
k.disabled = true;
try {
const a = await hole(`${BASIS}/karte`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ rolle: d.rolle, kachel: schluessel, stufe: 'bedarf',
wozu: '', tust: '', merke: '' }),
});
if (!a.ok) throw new Error('abgelehnt');
await laden();
} catch { melde('Der Eintrag ließ sich nicht anlegen.'); k.disabled = false; }
});
li.append(k);
return li;
}));
}
/* ---- Das Fenster -------------------------------------------------- */
let imFenster = null; // { art: 'karte'|'zeile', id, unterart }
function feld(id, schildId, schild, wert, sichtbar) {
$(id).hidden = !sichtbar;
if (schildId) $(schildId).textContent = schild;
const eingabe = $(id).querySelector('input, textarea, select');
if (eingabe) eingabe.value = wert ?? '';
}
function karteOeffnen(eintrag, kachel) {
imFenster = { art: 'karte', id: eintrag.id };
$('aendern-titel').textContent = kachel.name;
$('aendern-unter').textContent = 'Stufe und die drei Zeilen dieser Karte.';
const wahl = $('e-stufe');
wahl.replaceChildren(...(daten.stufen || []).map((st) => {
const o = document.createElement('option');
o.value = st.schluessel;
o.textContent = st.name;
return o;
}));
wahl.value = eintrag.stufe;
$('feld-stufe').hidden = false;
feld('feld-a', 'schild-a', 'Wozu', eintrag.wozu, true);
feld('feld-b', 'schild-b', 'Was du hier tust', eintrag.tust, true);
feld('feld-c', 'schild-c', 'Merke', eintrag.merke, true);
$('feld-ziel').hidden = true;
$('aendern-fehler').textContent = '';
$('aendern').showModal();
}
const ZEILEN_SCHILD = {
schritt: ['Kachel', 'Was zu tun ist'],
nicht: ['Was du liegen lassen kannst', 'Wer es erledigt'],
takt: ['Wann', 'Was du aufmachst'],
frage: ['Frage', 'Antwort'],
};
function zeileOeffnen(z, art) {
imFenster = { art: 'zeile', id: z.id, unterart: art };
const [a, b] = ZEILEN_SCHILD[art] || ['Titel', 'Text'];
$('aendern-titel').textContent = z.titel || 'Eintrag';
$('aendern-unter').textContent = '';
$('feld-stufe').hidden = true;
feld('feld-a', 'schild-a', a, z.titel, true);
feld('feld-b', 'schild-b', b, z.text, true);
$('feld-c').hidden = true;
/* Ein Ziel gibt es nur beim Schritt -- bei den anderen wäre das
Feld eine Zusage, die nirgends eingelöst wird. */
feld('feld-ziel', null, null, z.ziel, art === 'schritt');
$('aendern-fehler').textContent = '';
$('aendern').showModal();
}
async function aendernSpeichern(e) {
e.preventDefault();
if (!imFenster) return;
const knopf = $('aendern-speichern');
knopf.disabled = true;
try {
const wohin = imFenster.art === 'karte'
? `${BASIS}/karte/${imFenster.id}` : `${BASIS}/zeile/${imFenster.id}`;
const rumpf = imFenster.art === 'karte'
? { stufe: $('e-stufe').value, wozu: $('e-a').value,
tust: $('e-b').value, merke: $('e-c').value }
: { titel: $('e-a').value, text: $('e-b').value,
ziel: imFenster.unterart === 'schritt' ? $('e-ziel').value : null };
const a = await hole(wohin, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(rumpf),
});
if (!a.ok) throw new Error('abgelehnt');
$('aendern').close();
await laden();
} catch {
$('aendern-fehler').textContent = 'Das ließ sich nicht speichern.';
} finally {
knopf.disabled = false;
}
}
/* ---- Wer ist wie weit --------------------------------------------- */
async function standZeigen() {
const ziel = $('stand-liste');
ziel.replaceChildren(el('p', 'leise', 'wird geladen …'));
$('stand-dialog').showModal();
try {
const a = await hole(`${BASIS}/stand`);
if (!a.ok) throw new Error('abgelehnt');
const r = await a.json();
if (!r.leute.length) {
ziel.replaceChildren(el('p', 'leise', 'Noch niemand im Team.'));
return;
}
ziel.replaceChildren(...r.leute.map((p) => {
const zeile = el('div', 'an-wer');
if (p.fertig) zeile.dataset.fertig = 'ja';
zeile.append(el('span', 'an-wer__name', p.name));
zeile.append(el('span', 'an-wer__rolle', p.rolle));
zeile.append(el('span', 'an-wer__stand',
p.gesamt === 0 ? 'keine Schritte hinterlegt'
: p.fertig ? 'fertig' : `${p.erledigt} von ${p.gesamt}`));
/* Das Datum nur, wenn es eines gibt -- „zuletzt: nie" ist eine
Zeile, die nichts sagt und trotzdem Platz braucht. */
if (p.zuletzt) {
zeile.append(el('span', 'an-wer__wann',
new Date(p.zuletzt).toLocaleDateString('de-DE',
{ day: '2-digit', month: '2-digit', year: 'numeric' })));
}
return zeile;
}));
} catch {
ziel.replaceChildren(el('p', 'leise', 'Der Stand ließ sich nicht laden.'));
}
}
function melde(grund) {
$('ladefehler-grund').textContent = grund || '';
$('ladefehler').hidden = false;
@@ -364,6 +555,17 @@
zeigen(d);
}
$('pflege-an').addEventListener('click', () => {
pflegeAn = !pflegeAn;
$('pflege-an').setAttribute('aria-pressed', String(pflegeAn));
$('pflege-satz').textContent = pflegeAn
? 'Änderungen gelten sofort für alle dieser Rolle.' : '';
if (daten) zeigen(daten);
});
$('pflege-stand').addEventListener('click', () => { standZeigen().catch(() => {}); });
$('stand-zu').addEventListener('click', () => $('stand-dialog').close());
$('aendern-form').addEventListener('submit', (e) => { aendernSpeichern(e).catch(() => {}); });
$('aendern-abbruch').addEventListener('click', () => $('aendern').close());
$('nochmal').addEventListener('click', () => { laden().catch(() => {}); });
laden().catch(() => melde('Unerwarteter Fehler.'));
})();
+266
View File
@@ -0,0 +1,266 @@
/* =====================================================================
rundgang.js — Begrüßung und Rundgang beim ersten Anmelden (Etappe 6)
Bauplan Kapitel 10. Fünf Schritte über die Zentrale, im letzten
leuchten nur die Muss-Kacheln, am Ende steht man auf der Anleitung
bei den Ersten Schritten.
---------------------------------------------------------------------
ER DARF DIE SEITE UNTER KEINEN UMSTÄNDEN BLOCKIEREN
Das ist die wichtigste Eigenschaft dieser Datei, und sie ist der
Grund, warum sie eine eigene ist. Sie läuft auf `start.html` —
der meistbenutzten Seite des Hauses, für jede Rolle, bei jedem
Aufruf. Geht hier etwas schief, darf davon nichts anderes betroffen
sein.
Deshalb:
* eigene Datei, eigenes `defer` — kein Platz in start.js, wo ein
Fehler die Kacheln mitnähme;
* alles in `try`, und der Fehlerfall ist „nichts tun";
* der Server antwortet IMMER mit 200 (notfalls `zeigen: false`),
damit in der Konsole nichts Rotes steht;
* wird ein Zielbereich nicht gefunden, wird der Schritt
übersprungen statt auf ihn zu warten. Eine Einweisung, die auf
ein Element wartet, das es nicht gibt, ist genau die Sorte
Stillstand, die schlimmer ist als ein Fehlschlag.
---------------------------------------------------------------------
ER STARTET GENAU EINMAL JE PERSON UND ROLLE
Gemerkt wird das serverseitig (`anl_einweisung`), nicht im Browser:
Wer sich am Telefon anmeldet und später am Rechner, hat sie schon
gesehen. Und weil der Schlüssel (Person, Rolle) ist, startet sie
nach einem Rollenwechsel von selbst noch einmal — ohne dass jemand
daran denken muss.
===================================================================== */
(() => {
'use strict';
const BASIS = '/workspace/api/anleitung';
const el = (tag, klasse, text) => {
const k = document.createElement(tag);
if (klasse) k.className = klasse;
if (text !== undefined) k.textContent = text;
return k;
};
/* Die fünf Stationen. Wird ein Ziel nicht gefunden, fällt der
Schritt weg — die Zentrale sieht je nach Rolle anders aus, und
eine Einweisung, die auf einem fehlenden Kasten stehen bleibt,
wäre schlimmer als eine um einen Schritt kürzere. */
const STATIONEN = [
{ wo: '.willkommen', titel: 'Deine Zentrale',
text: 'Hier siehst du auf einen Blick, wie dein Tag steht: der Ring, '
+ 'der nächste Termin und was offen ist.' },
{ wo: '#dran-seite', titel: 'Was ist dran',
text: 'Die wichtigste Liste des Hauses. Was hier steht, will etwas von dir – '
+ 'und es verschwindet von selbst, sobald es erledigt ist.' },
{ wo: '#heute-seite', titel: 'Heute',
text: 'Deine Termine für heute. Steht nichts da, steht wirklich nichts an.' },
{ wo: '#zahlen-block', titel: 'Deine Aufgaben',
text: 'Offen, in Arbeit, zur Freigabe, erledigt. Ein Tippen bringt dich '
+ 'ins Aufgabenbrett.' },
{ wo: '#bereiche', titel: 'Mit diesen fängst du an',
text: 'Alles andere kannst du erst einmal liegen lassen. Die Anleitung '
+ 'sagt dir zu jeder Kachel, wofür sie da ist.', nurMuss: true },
];
let schritt = 0;
let stationen = [];
let muss = [];
let schale = null;
/* ---------- Das Hervorheben ---------------------------------------
Kein Loch in einer Abdeckung (das müsste bei jedem Scrollen neu
gerechnet werden), sondern ein Rahmen um das Ziel plus ein
Merkmal am Element. Die Abdunklung macht CSS über
`body[data-rundgang]` — damit bleibt die Seite benutzbar, falls
dieses Skript mittendrin stirbt: Ein Attribut am body ist weg,
sobald die Seite neu lädt. */
function hervorheben(ziel) {
for (const e of document.querySelectorAll('[data-rundgang-ziel]')) {
e.removeAttribute('data-rundgang-ziel');
}
for (const e of document.querySelectorAll('[data-rundgang-muss]')) {
e.removeAttribute('data-rundgang-muss');
}
if (ziel) ziel.setAttribute('data-rundgang-ziel', 'ja');
}
/* Nur die Muss-Kacheln leuchten lassen. Der Schlüssel kommt aus
derselben Funktion, mit der auch die Anleitung ihre Karten
verbindet — eine zweite Rechnung hier wäre die, die beim nächsten
Fragezeichen in einer Adresse danebenliegt. */
function mussMarkieren() {
const B = window.Bereiche;
if (!B || typeof B.schluesselVonZiel !== 'function') return 0;
let n = 0;
for (const a of document.querySelectorAll('#bereiche .kachel__link')) {
const s = B.schluesselVonZiel(a.getAttribute('href') || '');
if (muss.includes(s)) {
a.closest('.kachel')?.setAttribute('data-rundgang-muss', 'ja');
n++;
}
}
return n;
}
function zeichnen() {
const st = stationen[schritt];
if (!st) { beenden(true); return; }
const ziel = document.querySelector(st.wo);
hervorheben(ziel);
if (st.nurMuss) mussMarkieren();
schale.querySelector('.rg__zaehler').textContent =
`Schritt ${schritt + 1} von ${stationen.length}`;
schale.querySelector('.rg__titel').textContent = st.titel;
schale.querySelector('.rg__text').textContent = st.text;
schale.querySelector('.rg__weiter').textContent =
schritt === stationen.length - 1 ? 'Zur Anleitung' : 'Weiter';
/* Sanft hinscrollen, aber nur, wenn jemand das möchte. */
try {
ziel?.scrollIntoView({
behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth',
block: 'center',
});
} catch { /* ältere Browser: dann eben ohne */ }
}
async function gesehenMerken() {
try {
await fetch(`${BASIS}/einweisung/gesehen`, {
method: 'POST', credentials: 'same-origin',
});
} catch { /* Beim nächsten Mal eben noch einmal -- kein Schaden. */ }
}
function beenden(zurAnleitung) {
document.body.removeAttribute('data-rundgang');
hervorheben(null);
schale?.remove();
schale = null;
gesehenMerken().finally(() => {
if (zurAnleitung) location.assign('anleitung.html#schritte');
});
}
function rundgangStarten() {
stationen = STATIONEN.filter((s) => document.querySelector(s.wo));
if (!stationen.length) { beenden(false); return; }
schritt = 0;
document.body.dataset.rundgang = 'ja';
schale = el('div', 'rg');
schale.setAttribute('role', 'dialog');
schale.setAttribute('aria-modal', 'false');
schale.setAttribute('aria-label', 'Rundgang');
const kasten = el('div', 'rg__kasten');
kasten.append(el('p', 'rg__zaehler'));
kasten.append(el('h2', 'rg__titel'));
kasten.append(el('p', 'rg__text'));
const knoepfe = el('div', 'rg__knoepfe');
const abbruch = el('button', 'rg__still', 'Abbrechen');
abbruch.type = 'button';
abbruch.addEventListener('click', () => beenden(false));
const weiter = el('button', 'rg__weiter knopf', 'Weiter');
weiter.type = 'button';
weiter.addEventListener('click', () => { schritt++; zeichnen(); });
knoepfe.append(abbruch, weiter);
kasten.append(knoepfe);
schale.append(kasten);
document.body.append(schale);
/* Escape beendet -- wie bei jedem Fenster im Haus. */
document.addEventListener('keydown', function esc(e) {
if (e.key !== 'Escape' || !schale) return;
document.removeEventListener('keydown', esc);
beenden(false);
});
zeichnen();
weiter.focus();
}
/* ---------- Die Begrüßung ------------------------------------------ */
function begruessen(d) {
const fenster = el('dialog', 'dialog rg-gruss');
const rumpf = el('div', 'rg-gruss__rumpf');
rumpf.append(el('h2', 'dialog__titel',
d.name ? `Willkommen, ${d.name}!` : 'Willkommen im Creator Workspace'));
rumpf.append(el('p', 'rg-gruss__text',
'In fünf Minuten zeige ich dir, was für dich wichtig ist und was nicht.'));
const knoepfe = el('div', 'dialog__knoepfe');
const spaeter = el('button', 'knopf-still', 'Später');
spaeter.type = 'button';
const los = el('button', 'knopf', 'Los geht’s');
los.type = 'button';
knoepfe.append(spaeter, los);
rumpf.append(knoepfe);
fenster.append(rumpf);
document.body.append(fenster);
/* „SPÄTER" IST ERLAUBT und zählt trotzdem als gezeigt. Ein
Fenster, das so lange wiederkommt, bis man das Richtige
anklickt, ist keine Einladung. Dass noch etwas offen ist, sagt
danach der Hinweis „Erste Schritte noch offen" — der ist leiser
und steht da, bis er erledigt ist. */
spaeter.addEventListener('click', () => {
fenster.close();
fenster.remove();
gesehenMerken();
});
los.addEventListener('click', () => {
fenster.close();
fenster.remove();
rundgangStarten();
});
/* GEMERKT WIRD BEIM ZEIGEN, NICHT BEIM BEENDEN (06.10.2026).
Zuerst stand das nur in `beenden()`. Gemessen mit
mess-anleitung: Wer "Los geht's" drueckt und dann weggeht --
Seite gewechselt, Telefon weggelegt, Fenster zu --, hat den
Rundgang nie beendet. Beim naechsten Aufruf kam die Begruessung
wieder. Und beim uebernaechsten. Fuer immer.
Die Tatsache, die gespeichert werden soll, ist "sie wurde
gezeigt" -- und die steht in dem Moment fest, in dem das
Fenster aufgeht. Alles andere ist eine Bedingung, die der
Mensch erfuellen muss, damit ihn die Software in Ruhe laesst. */
gesehenMerken();
fenster.showModal();
los.focus();
}
/* ---------- Start --------------------------------------------------- */
async function pruefen() {
let a;
try { a = await fetch(`${BASIS}/einweisung`, { credentials: 'same-origin' }); }
catch { return; }
if (!a.ok) return;
let d;
try { d = await a.json(); } catch { return; }
muss = Array.isArray(d.muss) ? d.muss : [];
/* Der Knopf „Rundgang noch einmal starten" steht auf der
Anleitung; von dort kommt man mit `#rundgang` zurück. Das geht
auch, wenn die Einweisung längst gezeigt wurde — sonst wäre
der Knopf dort einer, der nichts tut. */
if (location.hash === '#rundgang') {
history.replaceState(null, '', location.pathname);
rundgangStarten();
return;
}
if (d.zeigen) begruessen(d);
}
/* Erst wenn die Kacheln stehen: Der letzte Schritt leuchtet sie an,
und vorher gibt es sie nicht. Zwei Sekunden sind gemessen reichlich
(die Kacheln stehen nach rund 300 ms) -- und falls doch nicht,
fällt nur die Markierung weg, nicht der Rundgang. */
if (document.readyState === 'complete') setTimeout(pruefen, 1200);
else window.addEventListener('load', () => setTimeout(pruefen, 1200));
})();
+19 -19
View File
@@ -12,19 +12,19 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -430,22 +430,22 @@
<!-- TEXTFORM ZUERST (21.09.2026): Die Seite fragt beim Zeichnen nach
`window.Textform`. Kaeme sie spaeter, waere der erste Eintrag ohne
Gestaltung. Kein `defer`, damit sie wirklich vorher dasteht. -->
<script src="assets/js/textform.js?v=202610061421"></script>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/hochladen.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/textform.js?v=202610061535"></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/hochladen.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/zuteilung.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/zuteilung.js?v=202610061535" defer></script>
<!-- Der Vorlagenkatalog stand bis zum 23.09.2026 mitten in
aufgaben.js. Er bedient jetzt zwei Seiten und hat deshalb eine
eigene Datei; hier zeigt er den Creator-Katalog.
Vor aufgaben.js, weil die Seite ihn beim Start einrichtet. -->
<script src="assets/js/vorlagenbrett.js?v=202610061421" defer></script>
<script src="assets/js/aufgaben.js?v=202610061421" defer></script>
<script src="assets/js/vorlagenbrett.js?v=202610061535" defer></script>
<script src="assets/js/aufgaben.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/automation.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/automation.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -168,15 +168,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/automation.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/automation.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -7,14 +7,14 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -197,16 +197,16 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/befinden.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<script src="assets/js/befinden.js?v=202610061535" defer></script>
</body>
</html>
+22 -22
View File
@@ -12,24 +12,24 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202610061535" />
<!-- Wegen des Blocks „Willst du dazugehoeren?" auf dem Brett
„Mitmachen". Eine eigene Kopie der Regel hier waere die zweite
Stelle, an der dieselbe Sache anders aussieht. -->
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -318,19 +318,19 @@
<!-- TEXTFORM ZUERST (21.09.2026): Die Seite fragt beim Zeichnen nach
`window.Textform`. Kaeme sie spaeter, waere der erste Eintrag ohne
Gestaltung. Kein `defer`, damit sie wirklich vorher dasteht. -->
<script src="assets/js/textform.js?v=202610061421"></script>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/textform.js?v=202610061535"></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/checkliste.js?v=202610061421" defer></script>
<script src="assets/js/ampel.js?v=202610061421" defer></script>
<script src="assets/js/schulung.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/bereich.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/checkliste.js?v=202610061535" defer></script>
<script src="assets/js/ampel.js?v=202610061535" defer></script>
<script src="assets/js/schulung.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<script src="assets/js/bereich.js?v=202610061535" defer></script>
</body>
</html>
+19 -19
View File
@@ -7,17 +7,17 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein - siehe treff-regeln.html. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -108,15 +108,15 @@
</main>
<!-- Der Fuß gehört zu jeder Seite - siehe pruef-css-klassen. -->
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/auskunft.js?v=202610061421" defer></script>
<script src="assets/js/bewerben.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/auskunft.js?v=202610061535" defer></script>
<script src="assets/js/bewerben.js?v=202610061535" defer></script>
</body>
</html>
+18 -18
View File
@@ -7,16 +7,16 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein - siehe treff-regeln.html. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -80,16 +80,16 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/auskunft.js?v=202610061421" defer></script>
<script src="assets/js/bewerbungen.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/auskunft.js?v=202610061535" defer></script>
<script src="assets/js/bewerbungen.js?v=202610061535" defer></script>
</body>
</html>
+3 -3
View File
@@ -59,11 +59,11 @@
<!-- DIE WERBEEINBLENDUNG. Dieselbe Datei wie in der Reaction-Seite:
Zwei Fassungen altern unterschiedlich, und dann sieht der Stream
anders aus als das, worueber geredet wird. -->
<link rel="stylesheet" href="assets/css/werbung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/werbung.css?v=202610061535" />
</head>
<body class="obs-buehne">
<div id="platz"></div>
<script src="assets/js/werbung.js?v=202610061421" defer></script>
<script src="assets/js/buehne.js?v=202610061421" defer></script>
<script src="assets/js/werbung.js?v=202610061535" defer></script>
<script src="assets/js/buehne.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/calls.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/calls.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -89,15 +89,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/ki.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/calls.js?v=202610061421" defer></script>
<script src="assets/js/ki.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/calls.js?v=202610061535" defer></script>
</body>
</html>
+20 -20
View File
@@ -12,26 +12,26 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
Dialog zu sehen bekam. -->
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/chat.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/chat.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -739,24 +739,24 @@
</form>
</dialog>
<script src="assets/js/bereiche.js?v=202610061421"></script>
<script src="assets/js/bereiche.js?v=202610061535"></script>
<!-- TEXTFORM VOR ALLEM ANDEREN (21.09.2026): chat.js und bereich.js
fragen beim Zeichnen nach `window.Textform`. Kaeme sie spaeter,
waere die erste gezeichnete Nachricht ohne Gestaltung -- und das
faellt nur dem auf, der genau hinsieht. KEIN `defer`, damit sie
wirklich vor den anderen dasteht. -->
<script src="assets/js/textform.js?v=202610061421"></script>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/hochladen.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421"></script>
<script src="assets/js/glocke.js?v=202610061421"></script>
<script src="assets/js/textform.js?v=202610061535"></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/hochladen.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535"></script>
<script src="assets/js/glocke.js?v=202610061535"></script>
<!-- ANRUF VOR CHAT (18.09.2026): anruf.js stellt `window.anrufStarten`
bereit, und chat.js baut die Knoepfe nur, wenn es das gibt.
Andersherum waere die Reihenfolge eine stille Abhaengigkeit --
die Knoepfe fehlten, und niemand wuesste warum. -->
<script src="assets/js/anruf.js?v=202610061421"></script>
<script src="assets/js/anruf.js?v=202610061535"></script>
<!-- DIE BILDSCHAU (25.09.2026). Eigene Datei, weil sie nichts vom
Chat weiss: Sie bekommt einen Weg und einen Namen und zeigt ein
Bild. Jede andere Seite mit Fotos kann sie ebenso benutzen, ohne
@@ -767,8 +767,8 @@
sie beim ersten Foto noch nicht da -- und der erste Klick ginge
wie frueher in den Tab. Ein Fehler, der nur beim ERSTEN Mal
auftritt, ist der, den man nie nachstellen kann. -->
<script src="assets/js/bildschau.js?v=202610061421"></script>
<script src="assets/js/chat.js?v=202610061421"></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/bildschau.js?v=202610061535"></script>
<script src="assets/js/chat.js?v=202610061535"></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/content.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/content.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -179,15 +179,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/checkliste.js?v=202610061421" defer></script>
<script src="assets/js/content.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/checkliste.js?v=202610061535" defer></script>
<script src="assets/js/content.js?v=202610061535" defer></script>
</body>
</html>
+6 -6
View File
@@ -36,15 +36,15 @@
<link rel="preload" as="image" href="assets/img/buehne/crew-gate-hoch-580.webp"
type="image/webp" media="(max-width: 899px)" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/crew-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/crew-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/crew-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/crew-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<!-- Diese Wand steht NUR auf der Adresse von Team Dogi (ueberall sonst
404, siehe crewWeiche). Sie darf das Haus deshalb direkt nennen
statt ueber den Platzhalter haus.css zu gehen -- und sie MUSS es:
Eine Zugangswand, die sich erst nach dem Umbiegen faerbt, waere
die eine Seite, auf der man das Umfaerben sieht. -->
<link rel="stylesheet" href="assets/css/crew-haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/crew-haus.css?v=202610061535" />
</head>
<body class="gate gate--crew">
@@ -459,7 +459,7 @@
<script src="assets/js/gate.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/gate.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
</body>
</html>
+4 -4
View File
@@ -23,25 +23,25 @@
},
"icons": [
{
"src": "/assets/img/app-symbole/crew-192.png?v=202610061421",
"src": "/assets/img/app-symbole/crew-192.png?v=202610061535",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/img/app-symbole/crew-512.png?v=202610061421",
"src": "/assets/img/app-symbole/crew-512.png?v=202610061535",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/img/app-symbole/crew-192-maskable.png?v=202610061421",
"src": "/assets/img/app-symbole/crew-192-maskable.png?v=202610061535",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/assets/img/app-symbole/crew-512-maskable.png?v=202610061421",
"src": "/assets/img/app-symbole/crew-512-maskable.png?v=202610061535",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
+17 -17
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/dateien.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/dateien.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -108,15 +108,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/hochladen.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/hochladen.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/dateien.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/dateien.js?v=202610061535" defer></script>
</body>
</html>
+18 -18
View File
@@ -7,14 +7,14 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -306,20 +306,20 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<!-- VOR entwicklung.js: Die Seite richtet den Katalog beim Start ein,
also muss es ihn zu dem Zeitpunkt geben. Mit "defer" laufen beide
in Dokumentreihenfolge. -->
<script src="assets/js/vorlagenbrett.js?v=202610061421" defer></script>
<script src="assets/js/entwicklung.js?v=202610061421" defer></script>
<script src="assets/js/vorlagenbrett.js?v=202610061535" defer></script>
<script src="assets/js/entwicklung.js?v=202610061535" defer></script>
</body>
</html>
+15 -15
View File
@@ -7,13 +7,13 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/hilfe.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/hilfe.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -146,14 +146,14 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/hilfe.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/hilfe.js?v=202610061535" defer></script>
</body>
</html>
+5 -5
View File
@@ -30,9 +30,9 @@
<link rel="preload" as="image" href="assets/img/buehne/gate-hoch-580.webp"
type="image/webp" media="(max-width: 899px)" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
</head>
<body class="gate">
@@ -427,7 +427,7 @@
<script src="assets/js/gate.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/gate.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/kalender.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/kalender.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -383,15 +383,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/kalender.js?v=202610061421" defer></script>
<script src="assets/js/kalender-abo.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/kalender.js?v=202610061535" defer></script>
<script src="assets/js/kalender-abo.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/leistung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/leistung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -444,13 +444,13 @@
</form>
</dialog>
<script src="assets/js/meldung.js?v=202610061421"></script>
<script src="assets/js/nachfrage.js?v=202610061421"></script>
<script src="assets/js/wahl.js?v=202610061421"></script>
<script src="assets/js/bereiche.js?v=202610061421"></script>
<script src="assets/js/kopf.js?v=202610061421"></script>
<script src="assets/js/glocke.js?v=202610061421"></script>
<script src="assets/js/leistung.js?v=202610061421"></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535"></script>
<script src="assets/js/nachfrage.js?v=202610061535"></script>
<script src="assets/js/wahl.js?v=202610061535"></script>
<script src="assets/js/bereiche.js?v=202610061535"></script>
<script src="assets/js/kopf.js?v=202610061535"></script>
<script src="assets/js/glocke.js?v=202610061535"></script>
<script src="assets/js/leistung.js?v=202610061535"></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
</body>
</html>
+14 -14
View File
@@ -7,17 +7,17 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/manager-ziele.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/manager-ziele.css?v=202610061535" />
<!-- module.css an VORLETZTER, haus.css an LETZTER Stelle. Die
Reihenfolge ist keine Geschmacksfrage: haus.css setzt nur
Variablen, und bei Variablen entscheidet allein, wer zuletzt
kommt. pruef-css-klassen.mjs misst genau dieses Paar nach. -->
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -218,16 +218,16 @@
kopf.js liest daraus die Leitungsrollen. Ohne sie stürzt jede
Seite ab, und zwar nur in der Browserkonsole -- die Kopfleiste
kommt trotzdem. -->
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<!-- wahl.js gehört zu kopf.js: Der Sicht-Umschalter baut daraus seine
Liste. pruef-css-klassen setzt das durch, und zwar auch die
Reihenfolge -- kopf.js fragt beim Aufbau nach dem fertigen
Bedienelement. -->
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/manager-ziele.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/manager-ziele.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -12,13 +12,13 @@
vergessen wird. -->
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/material.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/material.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start" data-ton="42" data-buehne="studio">
@@ -138,14 +138,14 @@
<p class="m-laedt" id="laedt">Einen Moment …</p>
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/hochladen.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/material.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/hochladen.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/material.js?v=202610061535" defer></script>
</body>
</html>
+14 -14
View File
@@ -7,13 +7,13 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/notizen.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/notizen.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start" data-ton="46">
@@ -181,12 +181,12 @@
<!-- bereiche.js VOR kopf.js: Dort steht `window.Bereiche`, und kopf.js
liest daraus die Leitungsrollen. -->
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/notizen.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/notizen.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/personen.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/personen.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -453,14 +453,14 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/personen.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/personen.js?v=202610061535" defer></script>
</body>
</html>
+18 -18
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/profil.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/profil.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -214,16 +214,16 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/hochladen.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/hochladen.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/steckbrief.js?v=202610061421" defer></script>
<script src="assets/js/profil.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/steckbrief.js?v=202610061535" defer></script>
<script src="assets/js/profil.js?v=202610061535" defer></script>
</body>
</html>
+19 -19
View File
@@ -7,15 +7,15 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/reaktion.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/spendenkarte.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/werbung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/reaktion.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/spendenkarte.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/werbung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start reaktion-seite" data-stand="laedt">
@@ -905,15 +905,15 @@
<!-- bereiche.js VOR kopf.js: Dort steht `window.Bereiche`, und kopf.js
liest daraus die Leitungsrollen. -->
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/spendenkarte.js?v=202610061421" defer></script>
<script src="assets/js/werbung.js?v=202610061421" defer></script>
<script src="assets/js/reaktion.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/spendenkarte.js?v=202610061535" defer></script>
<script src="assets/js/werbung.js?v=202610061535" defer></script>
<script src="assets/js/reaktion.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -7,14 +7,14 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -134,14 +134,14 @@
Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen
Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen,
die seit dem 07.09. jede Seite danach absucht. -->
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/rechte.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<script src="assets/js/rechte.js?v=202610061535" defer></script>
</body>
</html>
+18 -18
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/report.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/report.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -106,17 +106,17 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/ki.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/report.js?v=202610061421" defer></script>
<script src="assets/js/ki.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<script src="assets/js/report.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/scouting.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/scouting.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -173,14 +173,14 @@
</div>
</div>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/scouting.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/scouting.js?v=202610061535" defer></script>
</body>
</html>
+26 -16
View File
@@ -12,21 +12,26 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<!-- Nur die Startseite: Begrüßungskachel, Uhr, Glockenmulde. Siehe
den Hinweis in start.css -- dort stand es bis zum 07.09.2026. -->
<link rel="stylesheet" href="assets/css/heim.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/heim.css?v=202610061535" />
<!-- Die Einweisung bringt ihr Aussehen mit. Sie steht in
anleitung.css, weil sie dorthin gehoert -- und nicht in
start.css, wo sie zwischen 48 Kachelfarben verschwinden
wuerde. -->
<link rel="stylesheet" href="assets/css/anleitung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -751,16 +756,21 @@
</p>
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/live.js?v=202610061421" defer></script>
<script src="assets/js/start.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/live.js?v=202610061535" defer></script>
<script src="assets/js/start.js?v=202610061535" defer></script>
<!-- Die Begruessung und der Rundgang beim ersten Anmelden.
EIGENE DATEI und nicht ein Stueck start.js: Sie laeuft auf der
meistbenutzten Seite des Hauses, und wenn hier etwas schiefgeht,
darf davon nichts anderes betroffen sein. -->
<script src="assets/js/rundgang.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/startcheck.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/startcheck.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -85,16 +85,16 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/ki.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/startcheck.js?v=202610061421" defer></script>
<script src="assets/js/ki.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/startcheck.js?v=202610061535" defer></script>
</body>
</html>
+18 -18
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/profil.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/profil.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -150,16 +150,16 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/hochladen.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/hochladen.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/auskunft.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/steckbrief.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/auskunft.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/steckbrief.js?v=202610061535" defer></script>
</body>
</html>
+14 -14
View File
@@ -7,13 +7,13 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/support.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/support.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -154,16 +154,16 @@
(reading 'LEITUNG')" ab -- gemessen am 24.09.2026, als diese
Zeile beim Anlegen der Seite fehlte. Die Kopfleiste kam
trotzdem, deshalb sah man es nur in der Browserkonsole. -->
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<!-- wahl.js gehoert zu kopf.js: Der Sicht-Umschalter in der
Kopfleiste baut daraus seine Liste. pruef-css-klassen setzt das
seit dem 07.09.2026 durch -- damals fehlte es auf chat.html und
uebersicht.html, und heute hier. -->
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/support.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/support.js?v=202610061535" defer></script>
</body>
</html>
+3 -3
View File
@@ -23,7 +23,7 @@
„Eigenes CSS" leer lassen (der Grund ist schon
durchsichtig).
====================================================================== -->
<link rel="stylesheet" href="assets/css/spendenkarte.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/spendenkarte.css?v=202610061535" />
<style>
/* DURCHSICHTIG BIS AUF DIE KARTEN. OBS legt die Quelle über das
Bild; jede Fläche, die hier steht, deckt dort etwas zu. */
@@ -80,7 +80,7 @@
<body>
<div class="obs-tafel spendentafel" id="tafel" aria-live="polite"></div>
<script src="assets/js/spendenkarte.js?v=202610061421" defer></script>
<script src="assets/js/tafel.js?v=202610061421" defer></script>
<script src="assets/js/spendenkarte.js?v=202610061535" defer></script>
<script src="assets/js/tafel.js?v=202610061535" defer></script>
</body>
</html>
+18 -18
View File
@@ -7,18 +7,18 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061535" />
<!-- Wegen des Kastens „Anfragen“ ueber der Liste. Eine eigene Kopie
der Regel hier waere die zweite Stelle, an der dieselbe Sache
anders aussieht. -->
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/bewerbung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -111,15 +111,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/talente.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<script src="assets/js/talente.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -7,20 +7,20 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/team.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/team.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -110,15 +110,15 @@
</main>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/team.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<script src="assets/js/team.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -7,20 +7,20 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/team.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/team.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<!-- `data-buehne` steht hier fest und nicht im Skript: Die Kachel zu
@@ -84,15 +84,15 @@
Kaputt ist dabei nichts -- er funktioniert. Genau deshalb faellt
es niemandem auf, und deshalb prueft pruef-css-klassen die
ABHAENGIGKEIT statt der Optik. Hier hat sie angeschlagen. -->
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/teamlage.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<script src="assets/js/teamlage.js?v=202610061535" defer></script>
</body>
</html>
+15 -15
View File
@@ -7,13 +7,13 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/bereich.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -112,15 +112,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/teilen.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/teilen.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -7,14 +7,14 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -126,14 +126,14 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/treff-moderation.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/treff-moderation.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -7,18 +7,18 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/treff.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein. Auf der Adresse des
Rudels biegt der Server genau diesen Dateinamen auf crew-haus.css
um, und die Seite kommt schon beim ERSTEN Abruf in Lila und
Babyblau an -- ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -248,14 +248,14 @@
Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen
Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen,
die seit dem 07.09. jede Seite danach absucht. -->
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/auskunft.js?v=202610061421" defer></script>
<script src="assets/js/treff-regeln.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/auskunft.js?v=202610061535" defer></script>
<script src="assets/js/treff-regeln.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -12,22 +12,22 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<!-- Formular- und Dialogstile: seit dem 07.09.2026 steht hier der
Dialog "Creator anlegen". -->
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -149,16 +149,16 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/uebersicht.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/uebersicht.js?v=202610061535" defer></script>
</body>
</html>
+15 -15
View File
@@ -7,13 +7,13 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/unsere-seiten.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/unsere-seiten.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -335,14 +335,14 @@
</main>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/live.js?v=202610061421" defer></script>
<script src="assets/js/unsere-seiten.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/live.js?v=202610061535" defer></script>
<script src="assets/js/unsere-seiten.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -7,13 +7,13 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/unterstuetzen.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/unterstuetzen.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -106,17 +106,17 @@
<!-- bereiche.js VOR kopf.js: Dort steht `window.Bereiche`, und kopf.js
liest daraus die Leitungsrollen. Ohne sie stürzt jede Seite mit
„Cannot read properties of undefined (reading 'LEITUNG')" ab. -->
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/holen.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/holen.js?v=202610061535" defer></script>
<!-- Die Satz-Tafel. Ohne sie stand auf dieser Seite das Maschinenwort
des Servers (z.B. "nicht_gefunden") statt eines Satzes -- gemeldet
von pruef-meldungen, nicht beim Ansehen. -->
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/unterstuetzen.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/unterstuetzen.js?v=202610061535" defer></script>
</body>
</html>
+16 -16
View File
@@ -7,15 +7,15 @@
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/werdegang.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/werdegang.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -144,14 +144,14 @@
</main>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/werdegang.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/werdegang.js?v=202610061535" defer></script>
</body>
</html>
+15 -15
View File
@@ -12,13 +12,13 @@
vergessen wird. -->
<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=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/willkommen.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/willkommen.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<!-- KOERPERKLASSE "start", NICHT "gate" (berichtigt 21.09.2026).
`body.gate` ist die Anmeldewand: `display:flex; align-items:center`,
@@ -75,13 +75,13 @@
<p class="fehler" id="fehler" hidden></p>
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/willkommen.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/willkommen.js?v=202610061535" defer></script>
</body>
</html>
+17 -17
View File
@@ -12,20 +12,20 @@
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061421" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061421" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/wissen.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061421" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202610061535" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202610061535" />
<link rel="stylesheet" href="assets/css/gate.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/start.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/wissen.css?v=202610061535" />
<link rel="stylesheet" href="assets/css/module.css?v=202610061535" />
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
genau diesen Dateinamen auf crew-haus.css um, und die Seite
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
ohne Umfaerben im Browser, ohne Flackern. -->
<link rel="stylesheet" href="assets/css/haus.css?v=202610061421" />
<link rel="stylesheet" href="assets/css/haus.css?v=202610061535" />
</head>
<body class="start">
@@ -190,15 +190,15 @@
</main>
<script src="assets/js/meldung.js?v=202610061421" defer></script>
<script src="assets/js/hochladen.js?v=202610061421" defer></script>
<script src="assets/js/nachfrage.js?v=202610061421" defer></script>
<script src="assets/js/meldung.js?v=202610061535" defer></script>
<script src="assets/js/hochladen.js?v=202610061535" defer></script>
<script src="assets/js/nachfrage.js?v=202610061535" defer></script>
<script src="assets/js/wahl.js?v=202610061421" defer></script>
<script src="assets/js/bereiche.js?v=202610061421" defer></script>
<script src="assets/js/installieren.js?v=202610061421" defer></script>
<script src="assets/js/kopf.js?v=202610061421" defer></script>
<script src="assets/js/glocke.js?v=202610061421" defer></script>
<script src="assets/js/wissen.js?v=202610061421" defer></script>
<script src="assets/js/wahl.js?v=202610061535" defer></script>
<script src="assets/js/bereiche.js?v=202610061535" defer></script>
<script src="assets/js/installieren.js?v=202610061535" defer></script>
<script src="assets/js/kopf.js?v=202610061535" defer></script>
<script src="assets/js/glocke.js?v=202610061535" defer></script>
<script src="assets/js/wissen.js?v=202610061535" defer></script>
</body>
</html>