Files
dogfather-universe/workspace/entwicklung.html
T
DogFatherGit 5d89d108f9 Die Reaction: zusammen schauen, live, mit Kamera und Chat
Filipes Kurznotiz vom 28.09.2026, von links nach rechts:

    Kachel sichtbar -> geschlossen -> Vorbereitung -> Wartebereich/
    Chat -> Countdown -> LIVE -> Reaction + Gaeste + Chat + PayPal
    -> Ende

DREI STAENDE, NICHT SIEBEN

„Wartebereich" und „Countdown" sind keine eigenen Zustaende, sondern
das, was „Vorbereitung" auf dem Bildschirm TUT. Drei Staende, die
sich gegenseitig ausschliessen, sind pruefbar; sieben, von denen sich
vier ueberlappen, sind es nicht.

DAS VIDEO LAEUFT NICHT UEBER DIESEN SERVER

Naheliegend waere: Der Host spielt ab, alle sehen seinen Bildschirm.
Das waere aus zwei Gruenden falsch. Rechtlich ist ein
weitergesendetes YouTube-Video eine oeffentliche Wiedergabe -- genau
die Sache, fuer die Kanaele gesperrt werden. Und technisch kostet es
Bandbreite und Qualitaet.

Jeder Zuschauer laedt das Video deshalb SELBST. Uebertragen wird nur
der Spielstand: Kennung, laeuft/pausiert, Sekunde. Das sind ein paar
Byte, jeder sieht es in voller Qualitaet, und alle sind auf derselben
Sekunde. Nachgefuehrt wird erst ab anderthalb Sekunden Abweichung --
ein Player, dem man jede Sekunde eine neue Position gibt, ruckelt
sichtbar.

DIE KAMERAS LAUFEN DIREKT VON MENSCH ZU MENSCH

Ueber denselben Weg wie die Anrufe im Haus (seit 18.09.), nur mit
mehr Empfaengern. Das hat eine Grenze, und sie ist gerechnet, nicht
geraten: Bei 360p und rund 350 kbit/s sind zwoelf Zuschauer etwa
4 Mbit/s Upload beim Host. Darueber schaltet die Sendung von selbst
auf Ton um -- wer keine Kamera mehr bekommt, hoert alles, sieht das
Video und kann schreiben. Ehrlicher als eine Verbindung, die stockt,
und sichtbar im Regiepult.

Heute sind es elf Menschen im ganzen Haus (gemessen: 1 admin, 1 hand,
1 linke, 4 modi, 4 gast). Die Grenze ist weit weg -- sie steht
trotzdem drin, weil sie sonst erst auffaellt, wenn es zu spaet ist.

DIE SEITE IST ANDERS GEBAUT ALS JEDE ANDERE IM HAUS

Ueberall sonst: Kacheln, Karten, Listen -- man liest, entscheidet,
geht wieder. Hier sitzt man. Eine Stunde, mit anderen, auf EINE
Sache schauend. Deshalb kein Raster, sondern ein SAAL: grosse Flaeche
fuer das Video, Kamerabilder als schwebende Fenster darueber, der
Chat als Schiene daneben. Die Seite scrollt nicht -- ein Video, das
beim Tippen im Chat nach oben rutscht, ist der schnellste Weg, dass
jemand aufhoert zu schreiben.

Fuer den Host ein REGIEPULT: vier senkrechte Regler nebeneinander wie
an einem Mischpult, darueber die Sendung, daneben Gaeste und
Anordnung, unten drei grosse Knoepfe. Es SCHIEBT den Saal, es deckt
ihn nicht zu.

Die Kachel traegt ihren Zustand als Farbe: grau geschlossen,
bernstein in Vorbereitung, rot auf Sendung. Keine Ton-Nummer -- der
Farbraum ist bei 46 voll, und sie braucht auch keine.

PAYPAL: EINE QUELLE

Der Knopf nimmt den Weg, der auf der Unterstuetzen-Seite hinterlegt
ist -- derselbe Eintrag, dieselbe Pflege. Ist dort nichts eingetragen
oder steht er auf unsichtbar, erscheint hier kein Knopf. Eine
geratene Adresse ist an dieser Stelle die gefaehrlichste aller
Abkuerzungen.

=======================================================================
ACHT FEHLER, DIE OHNE MESSUNG LIVE GEGANGEN WAEREN
=======================================================================

1. `data-live` WAR SCHON VERGEBEN. Die Draussen-Kachel bekommt es,
   sobald Filipe auf Twitch sendet. Meine Regel haette ihr waehrend
   jedes Streams die Farbe genommen -- genau dann, wenn sie wichtig
   ist. Heisst jetzt `data-sendung`, und pruef-reaktion haelt beides
   auseinander.

2. DIE INHALTSRICHTLINIE HAETTE YOUTUBE LAUTLOS GESPERRT. Die Datei
   warnt an genau dieser Stelle selbst davor: Am 27.08.2026 hat
   `frame-src 'none'` den Musik-Knopf stillgelegt -- der Knopf
   reagierte, das Feld ging auf, und wo die Player sein sollten,
   blieb es leer. Hier waere das Ergebnis eine schwarze Leinwand vor
   Publikum gewesen. youtube-nocookie.com fuer den Rahmen (setzt keine
   Werbekennungen), www.youtube.com fuer die Einbett-API,
   i.ytimg.com fuer die Vorschaubilder.

3. KAMERA UND MIKROFON WAREN GESPERRT. Dieselbe Falle, vor der
   index.js selbst warnt -- und die am 18.09. schon einmal zugeschlagen
   hat. Die Ausnahme ist jetzt eine benannte MENGE statt eines zweiten
   Sonderfalls, und pruef-kamera-richtlinie.mjs haelt sie GEGEN DEN
   QUELLTEXT: Welche Seite laedt ein Skript, das getUserMedia
   aufruft? Genau die muss drinstehen -- und keine andere. Eine
   Liste, die abgeleitet wird, kann nicht veralten.

4. ZWEI ANRUFE AN DIESELBE PERSON. Zwischen `await kameraHolen()` und
   dem Anlegen der Verbindung laeuft alles andere weiter; jeder Takt
   sagte wieder „den kenne ich noch nicht". Der Empfaenger antwortete
   auf beide Angebote, und die zweite Antwort traf eine Verbindung,
   die laengst stand.

5. DAS ANGEBOT GING HINAUS, BEVOR DER EMPFAENGER ZUHOEREN KONNTE.
   Gemessen:

       [spur] an [3] reaktion_signal | offen: [2,1]
       ...
       [spur] Strom auf fuer 3 Lenny

   Die Anmeldung ist ein gewoehnlicher Abruf und sofort durch, der
   Ereignisstrom eine stehende Verbindung. Der Host erfaehrt vom
   Neuankoemmling also zuverlaessig, BEVOR der zuhoeren kann.
   Die Richtung ist jetzt umgedreht: Wer bereit ist, BITTET um den
   Anruf -- er ist der Einzige, der das sicher weiss. Dazu ein
   eigener, schneller Takt (2,5 s) und eine Ruecknahme, wenn ein
   Angebot bei niemandem ankommt.

6. EIN VIDEO MIT TON STARTET NICHT VON ALLEIN. `videoWidth` war 640,
   das Bild kam also an -- und das Fenster blieb schwarz. Kein
   Fehler, keine Meldung, es passiert einfach nichts. Die Kameras
   starten jetzt stumm (stumm darf losgehen), ein Knopf schaltet den
   Ton frei, und die erste Beruehrung der Seite tut es ohnehin.

7. DIE LADE AM HANDY GING NICHT AUF. Gemessen: ein 390x775 grosser
   Saal mit 219 px Video und 556 px Leere darunter. Statt den Knopf
   zu reparieren, ist die Lade weg -- unter Kopfleiste und Video
   bleiben auf einem Telefon rund 550 px, das ist mehr Chat, als eine
   Lade je zeigen wuerde. Ein Zustand weniger ist besser als ein
   Zustand, der funktioniert.

8. `sendBeacon` KANN NUR POST. Beim Schliessen des Fensters wird ein
   gewoehnlicher Abruf abgebrochen; mein DELETE waere nie angekommen,
   und jeder haette zwei Minuten lang als anwesend gegolten.

Dazu drei Funde der Hauspruefungen, alle von mir verursacht:
17 Schriftgroessen unter der Lesbarkeitsgrenze von 11,5 px, elf
Maschinenworte ohne deutschen Satz, und ein Aufbewahrungseintrag ohne
Rechtsgrundlage.

=======================================================================

GEMESSEN

pruef-reaktion            74 Punkte, 0 Fehler (11 Abschnitte)
pruef-kamera-richtlinie   10 Punkte, 0 Fehler (neu, abgeleitet)
mess-reaktion             beide Kameras kommen an, 640 px, laufen --
                          beim Zuschauer UND beim Host. Diese Messung
                          hat einen Rueckgabewert: Alles andere kann
                          gruen sein, und trotzdem sitzt jeder vor
                          einem schwarzen Rechteck.
pruef-handy               180 (vorher 177), pruef-notizen 79,
pruef-aufbewahrung        45, pruef-meldungen 8, pruef-css-klassen 33,
pruef-struktur            35, pruef-crew-adresse 161,
pruef-haus-trennung       100, pruef-start-ansicht 160 -- alle 0 Fehler.
2026-09-28 01:52:22 +02:00

317 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>Eure Aufgaben · Spicy &amp; Dogi</title>
<meta name="robots" content="noindex, nofollow" />
<link rel="manifest" href="/workspace/app.webmanifest" />
<meta name="theme-color" content="#06090f" />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609280151" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609280151" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609280151" />
<link rel="stylesheet" href="assets/css/start.css?v=202609280151" />
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609280151" />
<link rel="stylesheet" href="assets/css/entwicklung.css?v=202609280151" />
<link rel="stylesheet" href="assets/css/module.css?v=202609280151" />
<link rel="stylesheet" href="assets/css/haus.css?v=202609280151" />
</head>
<body class="start">
<div class="schleier" aria-hidden="true"></div>
<header class="kopfleiste">
<button type="button" class="zurueck-knopf" id="zurueck" hidden>
<svg class="zurueck-knopf__pfeil" viewBox="0 0 24 24" aria-hidden="true">
<path d="M14.5 5.5 8 12l6.5 6.5" />
</svg>
<span class="zurueck-knopf__text">Zurück</span>
</button>
<p class="marke"><span class="marke__text"><a class="zurueck" href="start.html">Team&nbsp;Dogi</a> · Eure Aufgaben</span></p>
<div class="kopfleiste__rechts">
<span class="wer" id="wer">…</span>
<button type="button" class="abmelden" id="abmelden">Abmelden</button>
</div>
</header>
<main class="inhalt inhalt--breit">
<section class="kopf-zeile">
<div>
<p class="marke" id="ober">Entwicklung &amp; Nachwuchs</p>
<!-- UMBENANNT AM 19.09.2026 (siehe workspace.js). Diese Seite ist
der Aufgabenkatalog: was ein Modi koennen soll und wo er
gerade steht. Der Name "Entwicklung" bleibt dem vorbehalten,
was Filipe darunter versteht -- einer Auswertung je Person. -->
<h1 class="titel" id="titel">Eure Aufgaben</h1>
<p class="unterzeile" id="unterzeile">
Anklicken statt tippen. Keine Noten, keine Punktzahl – ein Gesprächsanlass.
</p>
</div>
</section>
<!-- ==================================================================
DIE REIHENFOLGE AUF DIESER SEITE IST DAS EIGENTLICHE DESIGN
1. Die Ampel — sie betrifft Menschen, nicht Prozesse.
2. Die Personen — wen gehe ich heute durch.
3. Was er bekommt — das Formular und der Katalog.
4. Was bei ihm liegt — seine Aufgaben.
5. Die Karte — und darin die ABWEICHUNGEN zuerst.
6. Ganz unten der Weg zu den eigenen sechs Fragen — sie haben
seit dem 15.09.2026 eine eigene Seite.
Wer die Seite öffnet, soll die wichtigste Sache zuerst sehen, und
das ist nicht die Liste. Eine Ampel unter 34 Beobachtungen hätte
niemand je gelesen.
DIESE ORDNUNG WAR ZWISCHENZEITLICH VERLOREN (berichtigt
23.09.2026). Die Punkte 1 bis 3 standen hier schon seit dem
15.09. — nur nicht mehr in dieser Reihenfolge: Am 22.09. kam das
Verteilen auf die Seite, am 23.09. der Katalog, und beide sind
VOR die Ampel und die Personenwahl gerutscht.
Gemessen mit sechs Leuten und offenem Katalog: Am Handy begann
die Personenwahl erst bei Bildschirm 5,3 von 14,9. Man scrollte
also an allem vorbei, um überhaupt anzufangen — und das, was man
dabei überscrollte (Formular, Katalog), betrifft genau die
Person, die man noch gar nicht gewählt hatte.
Filipe: „ich will dass du die so krass übersichtlich machst."
Die Reihenfolge ist jetzt die, in der man denkt: Wie steht das
Team? → Wen nehme ich mir vor? → Was gebe ich ihm? → Was liegt
schon bei ihm? → Wie steht er da?
============================================================== -->
<section id="ampel" class="e-ampel" hidden></section>
<section id="personen-block" hidden>
<h2 class="e-abschnitt">Wen gehst du durch?</h2>
<div id="personen" class="e-personen" role="group" aria-label="Person wählen" aria-busy="true"></div>
</section>
<!-- VERTEILEN GEHOERT HIERHER (22.09.2026).
Filipe, zum wiederholten Mal: "ich will immer noch ... dass man
bei aufgaben nur die aufgaben sieht und bei eure aufgaben die
aufgaben verteilt."
Und so stand es schon im Auftrag vom 21.09. (Abschnitt 2): "Die
Kachel Eure Aufgaben soll erhalten bleiben. Innerhalb dieses
Bereichs soll zusaetzlich eine Funktion integriert werden, mit
der DogFather und die rechte Hand Aufgaben erstellen und
verteilen koennen."
ES IST EIN WEG, KEIN ZWEITES FORMULAR. Zwei Formulare fuer
dieselbe Sache waeren zwei Gelegenheiten, eines davon zu
vergessen -- und man wuesste nie, welches das richtige ist. Der
Knopf nimmt die gerade gewaehlte Person mit. -->
<!-- HIER STAND EIN LINK AUF EINE ANDERE SEITE (bis 22.09.2026).
Filipe: „dieser buttion da soll nicht einen zu der seite
aufgaben fuehren sondern da in dieser seite die aufgaben
erstellen und vergeben koennen. plus man soll die aufgaben hier
in dieser seite auch sehen."
Er hat recht, und der Grund liegt auf der Hand, sobald man es
einmal macht: Wer hier jemanden durchgeht, hat den Menschen vor
sich. Ihn dafuer auf eine andere Seite zu schicken heisst, den
Faden zu verlieren und danach zurueckzusuchen.
ES IST NICHT DAS GROSSE FORMULAR VON aufgaben.html.
Das hat zwoelf Felder -- Prioritaet, Kategorie, Kanal, Bereich,
Mehrfachauswahl. Die braucht man, wenn man eine Aufgabe fuer
irgendwen irgendwo anlegt. Hier steht die Person schon fest,
und was fehlt, sind drei Angaben: was, bis wann, und ob noch
jemand mitmacht. Alles andere waere dieselbe Maske zweimal --
und zwei Masken fuer dieselbe Sache sind zwei Gelegenheiten,
eine davon zu vergessen.
Wer mehr braucht, findet die Aufgabe danach auf dem Brett und
kann sie dort in Ruhe ausbauen. -->
<section class="e-verteilen" id="verteilen-band" hidden>
<div class="e-verteilen__text">
<h2 class="e-verteilen__titel">Aufgabe verteilen</h2>
<p class="e-verteilen__satz" id="verteilen-satz">
Aufgabe anlegen und an eine oder mehrere Personen geben.
</p>
</div>
<button type="button" class="knopf" id="verteilen-knopf">Aufgabe anlegen</button>
<form class="e-neu" id="e-neu" hidden>
<!-- FÜR WEN — DIE ERSTE FRAGE, UND SIE STEHT JETZT HIER.
---------------------------------------------------------
Bis zum 22.09.2026 abends stand oben „Wähl links jemanden
aus", und der Knopf war so lange tot. Gemessen: Die Auswahl
steht gar nicht links, sondern 206 Pixel WEITER UNTEN, bei
genau derselben linken Kante (130 px wie das Band). Links
war nichts. Wer der Anweisung folgte, schaute auf eine
leere Fläche und hatte einen Knopf, der nicht ging.
Filipe: „weil gerade hängt das und weiß nicht wieso."
Ein Knopf, der nichts tut, erklärt sich nie selbst. Also
steht die Frage jetzt dort, wo man sie beantwortet: im
Formular, als erste Zeile. Wer unten schon jemanden
angeklickt hat, findet ihn hier angehakt wieder — beides
führt zum selben Ziel, keins ist Pflicht. -->
<div class="e-neu__zeile" id="e-fuer-block">
<!-- DIE KOPFZEILE DER AUSWAHL (23.09.2026)
---------------------------------------------------------
Filipe: „auch die möglichkeit alle auf einmal auszuwählen
und so. mach es hoch krass profissionel, übersichtlich"
Links die Frage, rechts der Stand („3 von 6") und die
Schnellwahl. Der Zähler ist der Teil, der Übersicht
macht: Bei acht Kästchen sieht man nicht mehr, wie viele
angehakt sind — man zählt nach.
DIE SCHNELLWAHL WIRD GEBAUT, NICHT GESCHRIEBEN: Welche
Gruppen es gibt, steht in den Leuten selbst (regelZeile
in entwicklung.js). Eine Liste hier wäre die, die beim
nächsten Rollenzuschnitt eine Gruppe verschweigt. -->
<div class="e-fuer__kopf">
<p class="feld-schild" id="e-fuer-schild">Für wen ist das?</p>
<div class="e-fuer__rechts">
<span class="e-fuer__zahl" id="e-fuer-zahl" aria-live="polite"></span>
<div class="e-fuer__schnell" id="e-fuer-schnell" role="group"
aria-label="Schnell auswählen"></div>
</div>
</div>
<div id="e-fuer-leute" class="e-fuer__leute" role="group"
aria-labelledby="e-fuer-schild"></div>
<!-- WIE SOLL DAS LAUFEN — nur bei mehr als einer Person.
Bei einer gibt es nichts zu verteilen, dann wäre die
Frage Füllwerk. Der zweite Punkt ist die Bewerbung:
Filipe: „plus die option dass die modis sich für aufgaben
bewerben können." -->
<fieldset id="e-art" class="z-art" hidden>
<legend class="feld-schild">Wie soll das laufen?</legend>
<label class="z-art__wahl">
<input type="radio" name="e-verteilart" value="mehrere" checked />
<span><strong>Jede macht ihren Teil.</strong>
Alle sind gemeint, jede hat ihren eigenen Stand.</span>
</label>
<label class="z-art__wahl">
<input type="radio" name="e-verteilart" value="pool" />
<span><strong>Wer zuerst Zeit hat, übernimmt.</strong>
Sie bewerben sich, du nimmst an oder lehnst ab.</span>
</label>
</fieldset>
</div>
<div class="e-neu__zeile">
<label class="feld-schild" for="e-titel">Was ist zu tun?</label>
<input type="text" id="e-titel" maxlength="200" required
placeholder="z. B. Clips vom Samstag schneiden" />
</div>
<div class="e-neu__zeile">
<label class="feld-schild" for="e-frist">Bis wann? (freiwillig)</label>
<input type="date" id="e-frist" />
</div>
<div class="e-neu__zeile">
<label class="feld-schild" for="e-text">Worum geht es genau? (freiwillig)</label>
<textarea id="e-text" rows="2" maxlength="2000"></textarea>
</div>
<!-- HIER STAND „Noch jemanden dazunehmen" (bis 22.09.2026).
Zwei Personenlisten in einem Formular -- eine Hauptperson
oben, weitere hinter einem Klapp-Knopf -- waren zwei
Bedienungen fuer dieselbe Frage. Und die Bewerbungs-Option
steckte in der zweiten, zugeklappten: Sie war nur zu
finden, wenn man erst „Noch jemanden dazunehmen" oeffnete
UND dort jemanden ankreuzte. Eine Moeglichkeit, die man
nicht findet, gibt es nicht.
Jetzt ist es EINE Liste ganz oben. Wer einen anhakt, gibt
die Aufgabe an ihn; wer mehrere anhakt, wird gefragt, wie
es laufen soll. -->
<p class="fehler" id="e-neu-fehler" role="alert" aria-live="polite"></p>
<p class="e-neu__knoepfe">
<button type="submit" class="knopf knopf--klein" id="e-neu-speichern">Anlegen</button>
<button type="button" class="knopf-still" id="e-neu-abbrechen">Abbrechen</button>
</p>
</form>
</section>
<!-- DIE AUFGABEN DER PERSON, AUF DERSELBEN SEITE.
„plus man soll die aufgaben hier in dieser seite auch sehen."
Ohne sie legt man hier Aufgaben an und weiss nicht, was schon
da ist -- und traegt zum dritten Mal dieselbe ein. -->
<!-- AUFGABEN AUS DER VORLAGE (umgezogen am 23.09.2026)
Filipe: "das soll auch bitte nicht in der kategorie aufgaben
sondern eure aufgaben sein bitte."
ER STEHT ZWISCHEN DEM FORMULAR UND DER AUFGABENLISTE, und das
ist die Reihenfolge, in der man denkt: erst die Person, dann was
sie bekommt -- entweder selbst getippt (das Formular darueber)
oder eines der fertigen (hier) --, und darunter sofort, was
daraufhin bei ihr liegt.
Zwei Wege zur selben Handlung stehen damit nebeneinander, statt
auf zwei Seiten verteilt. -->
<section class="vorlagenbrett" id="vorlagenbrett" hidden></section>
<section class="e-aufgaben" id="e-aufgaben-block" hidden>
<h2 class="e-abschnitt" id="e-aufgaben-titel">Ihre Aufgaben</h2>
<p class="e-aufgaben__satz" id="e-aufgaben-satz"></p>
<div class="e-aufgaben__liste" id="e-aufgaben-liste" aria-live="polite"></div>
</section>
<p class="fehler" id="fehler" role="alert" aria-live="polite"></p>
<section id="karte" class="e-karte" hidden></section>
<!-- DEINE EIGENE KARTE.
Sie steht ÜBER den sechs Fragen und UNTER der Liste der anderen:
Wer diese Seite als DogFather öffnet, kommt zuerst zu seiner
Arbeit; wer beurteilt wird, sieht die Liste gar nicht und
landet direkt hier.
Sie erscheint erst, wenn alle gesetzt haben — eine halbe Karte
ist schlimmer als keine. -->
<section id="karte-block" class="e-meine" hidden>
<h2 class="e-abschnitt">Deine Karte</h2>
<p class="e-meine__satz" id="karte-satz">…</p>
<div id="meine-karte" aria-busy="true"></div>
</section>
<!-- ==== DIE SECHS FRAGEN STEHEN WOANDERS (15.09.2026) ==========
Sie hatten hier ihren Platz, solange es keine eigene Seite gab.
Jetzt gibt es eine – und zwei Stellen für dieselben sechs Fragen
wären zwei Stände, die auseinanderlaufen. Hier bleibt der Weg
dorthin, nicht eine Kopie. -->
<section class="e-meins e-meins--verweis" id="meins-block" hidden>
<h2 class="e-abschnitt">Und wie geht es dir?</h2>
<p class="e-meins__satz">
Ein paar Fragen über dich – die Antworten sieht niemand außer dir.
</p>
<a class="knopf knopf--klein" href="befinden.html">Zu deinen Fragen</a>
</section>
</main>
<script src="assets/js/meldung.js?v=202609280151" defer></script>
<script src="assets/js/nachfrage.js?v=202609280151" defer></script>
<script src="assets/js/wahl.js?v=202609280151" defer></script>
<script src="assets/js/bereiche.js?v=202609280151" defer></script>
<script src="assets/js/installieren.js?v=202609280151" defer></script>
<script src="assets/js/kopf.js?v=202609280151" defer></script>
<script src="assets/js/glocke.js?v=202609280151" defer></script>
<script src="assets/js/holen.js?v=202609280151" 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=202609280151" defer></script>
<script src="assets/js/entwicklung.js?v=202609280151" defer></script>
</body>
</html>