From cc39552b4f7a5b0d9c74969212b020b37d662538 Mon Sep 17 00:00:00 2001 From: Dogfather Date: Sun, 20 Sep 2026 15:11:25 +0200 Subject: [PATCH] Eine Eingabe geht nicht mehr wortlos verloren Filipe: "Was passiert, wenn jemand eine Funktion abbricht?" GEMESSEN: Acht Dialoge im Workspace enthalten Eingabefelder -- "Aufgabe bearbeiten" (10 Felder), der Tageseintrag in der Leistung (8), Ziele, Netzwerk, Import, ein neuer Chat-Raum, ein Creator. Bei allen galt: Esc, Klick daneben oder "Abbrechen" wirft ALLES weg, wortlos. Wer zehn Felder ausgefuellt hat und mit dem Daumen den Rand trifft, faengt von vorn an. Neu: window.verwurfWache() in nachfrage.js. BEIDE SCHLIESSWEGE, denn sie laufen verschieden: Esc / Klick daneben loest `cancel` aus, close() wird NICHT gerufen "Abbrechen"-Knopf ruft close(), loest kein `cancel` aus Wer nur einen abfaengt, hat eine halbe Sicherung -- und die ist schlimmer als keine, weil man ihr vertraut. NICHT VON HAND VERTEILT: Jeder Dialog mit Feldern bekommt sie automatisch (ausser dem Nachfrage-Dialog selbst -- er wuerde beim Schliessen nach sich selbst fragen, in sich selbst, und haenge fuer immer). Wer morgen einen neunten baut, hat sie, ohne daran zu denken. UND SIE FRAGT NUR BEI WIRKLICHER AENDERUNG. Beim Oeffnen wird ein Abbild der Felder genommen, beim Schliessen verglichen. Wer einen Dialog aufmacht und gleich wieder zu, merkt nichts. ZWEI SACHEN BEIM BAUEN GEMESSEN STATT VERMUTET: MEINE EIGENE "ROBUSTHEIT" HAT DIE WACHE STILL AUSGESCHALTET. Gegen den Fall "Felder werden erst nach dem Oeffnen gefuellt" hatte ich einen zweiten Schnappschuss beim Hineinklicken (`focusin`) eingebaut. Gemessen: Der entstand NACH dem Tippen -- Fokus und Werteingabe passieren im selben Atemzug. `beimOeffnen` war danach gleich dem getippten Text, und der Dialog ging wortlos zu. Die Sicherung sah eingebaut aus und tat nichts. Jetzt wird im naechsten BILD nachgetragen: Was das Skript beim Oeffnen nachtraegt, ist drin; getippt haben kann in derselben Sechzehntelsekunde niemand. (Nachgemessen: Alle acht Dialoge fuellen heute VOR showModal.) ZWEIMAL ESC HINTEREINANDER SCHLIESST TROTZDEM. Das ist Chromiums "close watcher": Eine Seite darf den Nutzer nicht mit Esc einsperren. Die Regel ist richtig; dagegen anzubauen waere falsch. Sie steht deshalb im Code und in der Pruefung -- festgehalten, nicht umgangen. Der Knopf unterliegt ihr nicht, und am Handy gibt es ohnehin kein Esc. Elf Speicherwege rufen `vergessen()`, damit nach erfolgreichem Speichern nicht gefragt wird. Eine Warnung nach dem Speichern waere genau die, die man wegklickt -- und danach auch die echte. pruef-nachfrage 49/0 (war 33), davon zehn am Bildschirm: unberuehrt geht er ohne Nachfrage zu nach einer Aenderung fragt Esc nach, der Dialog bleibt offen "Weiter bearbeiten" laesst ihn offen UND der Text steht noch da auch der Abbrechen-Knopf fragt -- jedes Mal "Verwerfen" schliesst wirklich, und der Text steht nirgends pruef-aufgabenbrett, -leistung, -uebersicht-browser, -chat-optik, -css-klassen gruen, pruef-tippziele 11/0. --- server/pruef-nachfrage.mjs | 168 +++++++++++++++++++++++++++++- workspace/anruf-probe.html | 10 +- workspace/app.webmanifest | 8 +- workspace/assets/js/aufgaben.js | 6 ++ workspace/assets/js/chat.js | 6 ++ workspace/assets/js/leistung.js | 10 ++ workspace/assets/js/nachfrage.js | 171 +++++++++++++++++++++++++++++++ workspace/aufgaben.html | 30 +++--- workspace/automation.html | 30 +++--- workspace/befinden.html | 28 ++--- workspace/bereich.html | 40 ++++---- workspace/bewerben.html | 34 +++--- workspace/bewerbungen.html | 32 +++--- workspace/calls.html | 32 +++--- workspace/chat.html | 34 +++--- workspace/content.html | 34 +++--- workspace/crew-index.html | 12 +-- workspace/crew.webmanifest | 8 +- workspace/dateien.html | 32 +++--- workspace/entwicklung.html | 28 ++--- workspace/hilfe.html | 26 ++--- workspace/index.html | 10 +- workspace/kalender.html | 32 +++--- workspace/leistung.html | 30 +++--- workspace/personen.html | 30 +++--- workspace/profil.html | 34 +++--- workspace/rechte.html | 28 ++--- workspace/report.html | 32 +++--- workspace/scouting.html | 30 +++--- workspace/start.html | 28 ++--- workspace/startcheck.html | 32 +++--- workspace/steckbrief.html | 34 +++--- workspace/talente.html | 30 +++--- workspace/team.html | 30 +++--- workspace/teamlage.html | 28 ++--- workspace/teilen.html | 26 ++--- workspace/treff-moderation.html | 28 ++--- workspace/treff-regeln.html | 30 +++--- workspace/uebersicht.html | 30 +++--- workspace/unsere-seiten.html | 26 ++--- workspace/werdegang.html | 30 +++--- workspace/wissen.html | 32 +++--- 42 files changed, 874 insertions(+), 515 deletions(-) diff --git a/server/pruef-nachfrage.mjs b/server/pruef-nachfrage.mjs index 40898a7f..f6d60e2a 100644 --- a/server/pruef-nachfrage.mjs +++ b/server/pruef-nachfrage.mjs @@ -131,7 +131,16 @@ for (const s of seiten) { const html = lies(join(SEITEN_ORDNER, s)); const geladen = [...html.matchAll(/ + - + diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index 2447a5ee..e9b4e4f7 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609201409", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609201509", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609201409", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609201509", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609201409", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609201509", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609201409", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609201509", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/js/aufgaben.js b/workspace/assets/js/aufgaben.js index 200fa8c2..361504cb 100644 --- a/workspace/assets/js/aufgaben.js +++ b/workspace/assets/js/aufgaben.js @@ -354,6 +354,8 @@ $('abbruch-fehler').textContent = sagWas(d.fehler, 'Hat nicht geklappt.'); return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + dlg.vergessen?.(); dlg.close(); await laden(); } catch { /* umgeleitet */ } finally { knopf.disabled = false; } @@ -996,6 +998,8 @@ $('b-fehler').textContent = sagWas((await a.json().catch(() => ({}))).fehler, 'Speichern ging nicht.'); return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + dialog.vergessen?.(); dialog.close(); await laden(); } catch { /* umgeleitet */ } finally { $('b-speichern').disabled = false; } @@ -1014,6 +1018,8 @@ try { const a = await hole(`/workspace/api/aufgaben/${bearbeitet.id}`, { method: 'DELETE' }); if (!a.ok) { $('b-fehler').textContent = 'Loeschen ging nicht.'; return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + dialog.vergessen?.(); dialog.close(); await laden(); } catch { /* umgeleitet */ } diff --git a/workspace/assets/js/chat.js b/workspace/assets/js/chat.js index cb819e6e..703cc899 100644 --- a/workspace/assets/js/chat.js +++ b/workspace/assets/js/chat.js @@ -1876,6 +1876,8 @@ return; } const raumId = kanalUmbau; + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + $('neu-dialog').vergessen?.(); $('neu-dialog').close(); await raeumeLaden(); await raumOeffnen(raumId, { sanft: true }); @@ -1892,6 +1894,8 @@ return; } const raumId = (await a.json()).raum_id; + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + $('neu-dialog').vergessen?.(); $('neu-dialog').close(); await raeumeLaden(); await raumOeffnen(raumId); @@ -1931,6 +1935,8 @@ } raumId = (await a.json()).raum_id; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + $('neu-dialog').vergessen?.(); $('neu-dialog').close(); await raeumeLaden(); await raumOeffnen(raumId); diff --git a/workspace/assets/js/leistung.js b/workspace/assets/js/leistung.js index da4ab7df..c953d50a 100644 --- a/workspace/assets/js/leistung.js +++ b/workspace/assets/js/leistung.js @@ -397,6 +397,8 @@ $('tag-fehler').textContent = sagWas((await a.json().catch(() => ({}))).fehler, 'Ging nicht.'); return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + d.vergessen?.(); d.close(); await allesLaden(); } catch { /* umgeleitet */ } @@ -415,6 +417,8 @@ const a = await hole(`/workspace/api/leistung/${offenerCreator}/${d.dataset.tag}`, { method: 'DELETE' }); if (!a.ok) { $('tag-fehler').textContent = 'Ging nicht.'; return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + d.vergessen?.(); d.close(); await allesLaden(); } catch { /* umgeleitet */ } @@ -448,6 +452,8 @@ }), }); if (!a.ok) { $('ziele-fehler').textContent = 'Ging nicht.'; return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + $('ziele-dialog').vergessen?.(); $('ziele-dialog').close(); await allesLaden(); } catch { /* umgeleitet */ } @@ -628,6 +634,8 @@ }); const r = await a.json(); if (!a.ok) { $('import-fehler').textContent = sagWas(r.fehler, 'Ging nicht.'); return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + $('import-dialog').vergessen?.(); $('import-dialog').close(); $('datei').value = ''; importText = ''; @@ -970,6 +978,8 @@ $('netz-los').disabled = false; return; } + /* Gespeichert -- die Verwurfwache darf hier nicht fragen. */ + $('netz-dialog').vergessen?.(); $('netz-dialog').close(); melde(`${d.geschrieben} Zeile(n) übernommen` + (d.unbekannt?.length ? ` · ${d.unbekannt.length} nicht zugeordnet` : '')); diff --git a/workspace/assets/js/nachfrage.js b/workspace/assets/js/nachfrage.js index 706fb51b..ea137659 100644 --- a/workspace/assets/js/nachfrage.js +++ b/workspace/assets/js/nachfrage.js @@ -324,3 +324,174 @@ }); }; })(); + +/* ===================================================================== + EINE EINGABE GEHT NICHT WORTLOS VERLOREN — window.verwurfWache() + + Filipe, 19.09.2026: „Was passiert, wenn jemand eine Funktion + abbricht?" + + --------------------------------------------------------------------- + WAS GEMESSEN WURDE + + Acht Dialoge im Workspace enthalten Eingabefelder -- „Aufgabe + bearbeiten" (10 Felder), der Tageseintrag in der Leistung (8), Ziele, + Netzwerk, Import, ein neuer Chat-Raum, ein Creator. + + Bei allen gilt bis heute dasselbe: Esc drücken, daneben klicken oder + auf „Abbrechen" tippen wirft ALLES weg, wortlos. Wer zehn Felder + ausgefüllt hat und mit dem Daumen den Rand trifft, fängt von vorn an. + + --------------------------------------------------------------------- + WARUM BEIDE WEGE ABGEFANGEN WERDEN MÜSSEN + + Ein geht auf ZWEI Arten zu, und sie laufen verschieden: + + Esc / Klick daneben -> löst `cancel` aus, DANN schliesst der + Browser selbst. Die Methode `close()` + wird dabei NICHT aufgerufen. + „Abbrechen"-Knopf -> ruft `close()` auf, ohne `cancel`. + + Wer nur `cancel` abfängt, lässt den Knopf durch. Wer nur `close` + ersetzt, lässt Esc durch. Beides einzeln wäre eine halbe Sicherung + -- und eine halbe Sicherung ist schlimmer als keine, weil man ihr + vertraut. + + --------------------------------------------------------------------- + UND SIE DARF NICHT IMMER FRAGEN + + „Eine Warnung, die immer kommt, ist keine Warnung mehr." Gefragt + wird nur, wenn sich WIRKLICH etwas geändert hat: Beim Öffnen wird + ein Abbild der Felder genommen, beim Schliessen verglichen. Wer + einen Dialog aufmacht und gleich wieder zu, merkt nichts davon. + + AUFRUF (einmal je Dialog, beim Aufbau der Seite): + verwurfWache(document.getElementById('bearbeiten-dialog')); + ===================================================================== */ +(function () { + 'use strict'; + + /** Der Inhalt aller Felder als eine Zeichenkette. Reicht zum + * Vergleichen -- es geht nur um „gleich oder nicht". */ + function abbild(dlg) { + return [...dlg.querySelectorAll('input, textarea, select')] + .map((f) => (f.type === 'checkbox' || f.type === 'radio') + ? (f.checked ? '1' : '0') + : String(f.value ?? '')) + .join('\u0000'); + } + + window.verwurfWache = function verwurfWache(dlg, o) { + if (!dlg || dlg.dataset.wache === 'ja') return; + o = o || {}; + dlg.dataset.wache = 'ja'; + + let beimOeffnen = null; + + /* WANN GEHT ER AUF? Das weiss nur der Browser -- die Seite ruft + `showModal()` an zwanzig Stellen. Ein Beobachter auf dem + `open`-Merkmal braucht dafuer keine einzige Zeile in der Seite. */ + if (window.MutationObserver) { + new MutationObserver(() => { + if (dlg.open) beimOeffnen = abbild(dlg); + }).observe(dlg, { attributes: true, attributeFilter: ['open'] }); + } + if (dlg.open) beimOeffnen = abbild(dlg); + + /* NOCH EINMAL IM NAECHSTEN BILD. + ---------------------------------------------------------------- + Nachgemessen am 20.09.2026: Alle acht Dialoge fuellen ihre + Felder VOR `showModal()`. Der Schnappschuss oben stimmt also. + + Er stimmt aber nur, solange das so bleibt. Fuellt jemand morgen + ein Feld erst NACH dem Oeffnen, waere der Schnappschuss leer, + und die Wache fragte bei JEDEM Schliessen. „Eine Warnung, die + immer kommt, ist keine Warnung mehr." + + ERSTER ANLAUF WAR EIN NEUER SCHNAPPSCHUSS BEIM HINEINKLICKEN + (`focusin`) -- und der hat die Wache still ausgeschaltet. + Gemessen: Der Schnappschuss entstand NACH dem Tippen, weil + Fokus und Werteingabe im selben Atemzug passieren koennen. + `beimOeffnen` war danach gleich dem getippten Text, `geaendert()` + falsch, und der Dialog ging wortlos zu -- die Sicherung sah + eingebaut aus und tat nichts. + + Jetzt wird im NAECHSTEN BILD noch einmal abgebildet. Was das + Skript beim Oeffnen nachtraegt, ist dann drin; getippt haben + kann in derselben Sechzehntelsekunde niemand. */ + const nachtragen = () => { + if (!dlg.open) return; + requestAnimationFrame(() => { if (dlg.open) beimOeffnen = abbild(dlg); }); + }; + nachtragen(); + if (window.MutationObserver) { + new MutationObserver(nachtragen) + .observe(dlg, { attributes: true, attributeFilter: ['open'] }); + } + + const geaendert = () => beimOeffnen !== null && abbild(dlg) !== beimOeffnen; + + function fragen(dann) { + frageNach({ + titel: o.titel || 'Eingaben verwerfen?', + was: o.was || 'Was du hier eingetragen hast, geht verloren.', + bleibt: o.bleibt || 'Der Eintrag selbst bleibt unverändert – ' + + 'es wird nur nichts übernommen.', + ja: o.ja || 'Verwerfen', + nein: 'Weiter bearbeiten', + }).then((ja) => { if (ja) { beimOeffnen = null; dann(); } }); + } + + /* Weg 1: Esc und der Klick daneben. `cancel` ist abbrechbar -- + das ist der einzige Griff, den der Browser dafuer anbietet. */ + dlg.addEventListener('cancel', (e) => { + if (!geaendert()) return; + e.preventDefault(); + fragen(() => dlg.close()); + }); + + /* Weg 2: jeder Aufruf von close() -- also die „Abbrechen"-Knoepfe + und alles, was die Seite sonst tut. Ersetzt wird NUR an diesem + einen Dialog, nicht am Prototyp: Ein globaler Eingriff traefe + auch den Nachfrage-Dialog selbst, und der schlösse sich dann nie. + + Bei unveraendertem Inhalt bleibt es synchron wie vorher -- wer + nichts getippt hat, merkt von der Wache nichts. */ + const echtesSchliessen = dlg.close.bind(dlg); + dlg.close = function (...rest) { + if (!geaendert()) { beimOeffnen = null; return echtesSchliessen(...rest); } + fragen(() => echtesSchliessen(...rest)); + return undefined; + }; + + /* Nach dem Speichern ist nichts mehr zu retten -- dann darf der + Dialog ohne Nachfrage zugehen. Die Seite meldet das, indem sie + `vergessen()` aufruft; ohne Meldung fragt die Wache weiter. */ + dlg.vergessen = () => { beimOeffnen = abbild(dlg); }; + }; + + /* ===================================================================== + UND SIE WIRD NICHT VON HAND VERTEILT + + Jeder Dialog mit Eingabefeldern bekommt die Wache -- abgeleitet, + nicht aufgezaehlt. Wer morgen einen neunten baut, hat sie, ohne + daran zu denken; und genau daran scheitern gepflegte Listen. + + AUSGENOMMEN IST DER NACHFRAGE-DIALOG SELBST. Er hat ein Textfeld + (den Grund), und wuerde er sich selbst bewachen, fragte er beim + Schliessen nach sich selbst -- und zwar in sich selbst. Der + zweite Dialog kann nicht aufgehen, solange der erste offen ist: + Er haenge fuer immer. + ===================================================================== */ + function alleBewachen() { + for (const dlg of document.querySelectorAll('dialog:not(.nachfrage)')) { + if (!dlg.querySelector('input, textarea, select')) continue; + window.verwurfWache(dlg); + } + } + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', alleBewachen); + } else { + alleBewachen(); + } +})(); diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index e4c4ff74..e37b7159 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -12,19 +12,19 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - + @@ -291,14 +291,14 @@ - - - + + + - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index b1a9ce28..9caa6687 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -168,13 +168,13 @@ - - + + - - - - - + + + + + diff --git a/workspace/befinden.html b/workspace/befinden.html index 5b7336ed..71c4cb7a 100644 --- a/workspace/befinden.html +++ b/workspace/befinden.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -130,12 +130,12 @@ - - + + - - - - + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index aebe0bcc..04b472af 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -12,24 +12,24 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - - + + - + @@ -251,17 +251,17 @@ - - + + - - - - - - - - - + + + + + + + + + diff --git a/workspace/bewerben.html b/workspace/bewerben.html index f47372f3..8bf11718 100644 --- a/workspace/bewerben.html +++ b/workspace/bewerben.html @@ -7,17 +7,17 @@ - - - - - - - - - + + + + + + + + + - + @@ -108,12 +108,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/bewerbungen.html b/workspace/bewerbungen.html index 74a0512e..55a60274 100644 --- a/workspace/bewerbungen.html +++ b/workspace/bewerbungen.html @@ -7,16 +7,16 @@ - - - - - - - - + + + + + + + + - + @@ -80,13 +80,13 @@ - - + + - - - - - + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 7d7df257..dd3f09c9 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -89,14 +89,14 @@ - - + + - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index 126eff41..b7519e56 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -12,26 +12,26 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -373,18 +373,18 @@ - - - - - - - + + + + + + + - - + + diff --git a/workspace/content.html b/workspace/content.html index 703e9855..a097f306 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -179,15 +179,15 @@ - - + + - - - - - - - + + + + + + + diff --git a/workspace/crew-index.html b/workspace/crew-index.html index eac380d5..95ebbca7 100644 --- a/workspace/crew-index.html +++ b/workspace/crew-index.html @@ -36,15 +36,15 @@ - - - + + + - + @@ -348,8 +348,8 @@ - + - + diff --git a/workspace/crew.webmanifest b/workspace/crew.webmanifest index fd323af9..df713beb 100644 --- a/workspace/crew.webmanifest +++ b/workspace/crew.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/crew-192.png?v=202609201409", + "src": "/assets/img/app-symbole/crew-192.png?v=202609201509", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-512.png?v=202609201409", + "src": "/assets/img/app-symbole/crew-512.png?v=202609201509", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609201409", + "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609201509", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609201409", + "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609201509", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/dateien.html b/workspace/dateien.html index eeca07dd..cfb76508 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -108,14 +108,14 @@ - - - + + + - - - - - + + + + + diff --git a/workspace/entwicklung.html b/workspace/entwicklung.html index df10adb2..9b071956 100644 --- a/workspace/entwicklung.html +++ b/workspace/entwicklung.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -106,12 +106,12 @@ - - + + - - - - + + + + diff --git a/workspace/hilfe.html b/workspace/hilfe.html index 04e9fb4a..e8482d8c 100644 --- a/workspace/hilfe.html +++ b/workspace/hilfe.html @@ -7,13 +7,13 @@ - - - - - - - + + + + + + + @@ -146,12 +146,12 @@ - - + + - - - - + + + + diff --git a/workspace/index.html b/workspace/index.html index 2f62da34..173ac8d4 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -30,9 +30,9 @@ - - - + + + @@ -410,8 +410,8 @@ - + - + diff --git a/workspace/kalender.html b/workspace/kalender.html index 8177f6c4..f7aa7ff5 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -377,14 +377,14 @@ - - + + - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index b35214cd..942a13c1 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -444,12 +444,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index bc7d5d90..8c15881d 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -449,13 +449,13 @@ - - + + - - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index 24fe5e15..28606b6b 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -214,15 +214,15 @@ - - - + + + - - - - - - + + + + + + diff --git a/workspace/rechte.html b/workspace/rechte.html index cdf6b537..0ce1bd75 100644 --- a/workspace/rechte.html +++ b/workspace/rechte.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -134,11 +134,11 @@ 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. --> - - - - - - + + + + + + diff --git a/workspace/report.html b/workspace/report.html index 27acccb9..453e5b85 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -106,14 +106,14 @@ - - + + - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 2f3e2915..5ee8d252 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -173,13 +173,13 @@ - - + + - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index d6f17e20..a8d9d989 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -12,21 +12,21 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - + + - + @@ -678,13 +678,13 @@

- - + + - - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index ac6bd16f..66a7d3cb 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -85,14 +85,14 @@ - - + + - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index c8025fb9..cdd6319f 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -150,15 +150,15 @@ - - - + + + - - - - - - + + + + + + diff --git a/workspace/talente.html b/workspace/talente.html index d460ff00..ca8cd2ed 100644 --- a/workspace/talente.html +++ b/workspace/talente.html @@ -7,18 +7,18 @@ - - - - - - + + + + + + - - - + + + @@ -111,12 +111,12 @@ - - + + - - - - + + + + diff --git a/workspace/team.html b/workspace/team.html index 4f308561..0a40af94 100644 --- a/workspace/team.html +++ b/workspace/team.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + @@ -110,13 +110,13 @@ - - + + - - - - - + + + + + diff --git a/workspace/teamlage.html b/workspace/teamlage.html index 414099b1..4a4a6dd9 100644 --- a/workspace/teamlage.html +++ b/workspace/teamlage.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + - - - - - - + + + + + + diff --git a/workspace/teilen.html b/workspace/teilen.html index 24d4bea8..bc5f8d4b 100644 --- a/workspace/teilen.html +++ b/workspace/teilen.html @@ -7,13 +7,13 @@ - - - - - - - + + + + + + + @@ -112,12 +112,12 @@ - - + + - - - - + + + + diff --git a/workspace/treff-moderation.html b/workspace/treff-moderation.html index 374fed3b..fd923d2b 100644 --- a/workspace/treff-moderation.html +++ b/workspace/treff-moderation.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -126,12 +126,12 @@ - - + + - - - - + + + + diff --git a/workspace/treff-regeln.html b/workspace/treff-regeln.html index 92c76f2b..c8b5e248 100644 --- a/workspace/treff-regeln.html +++ b/workspace/treff-regeln.html @@ -7,18 +7,18 @@ - - - - - - - + + + + + + + - + @@ -221,12 +221,12 @@ 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. --> - - - - - - - + + + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index 5cf52119..8b3b24ae 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -12,22 +12,22 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -149,14 +149,14 @@ - - + + - + - - - - + + + + diff --git a/workspace/unsere-seiten.html b/workspace/unsere-seiten.html index 793b8464..032ebfc0 100644 --- a/workspace/unsere-seiten.html +++ b/workspace/unsere-seiten.html @@ -7,13 +7,13 @@ - - - - - - - + + + + + + + @@ -217,12 +217,12 @@ - - + + - - - - + + + + diff --git a/workspace/werdegang.html b/workspace/werdegang.html index 528b8666..9f0a2700 100644 --- a/workspace/werdegang.html +++ b/workspace/werdegang.html @@ -7,15 +7,15 @@ - - - - - - - - - + + + + + + + + + @@ -144,12 +144,12 @@ - - + + - - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 31f567c9..0735d9b8 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -190,14 +190,14 @@ - - - + + + - - - - - + + + + +