Files
dogfather-universe/workspace/crew-index.html
T
DogFatherGitandClaude Opus 5 d6df590224 Telefonieren ging nur ueber UDP -- und die Seite sprang immer hoch
=== 1. WARUM TELEFONIEREN NICHT GING ===

Filipe: "es klingelt erscheint auch alles bei jedem aber telefonieren
klappt immer noch nicht."

GEMESSEN, BEVOR ETWAS GEAENDERT WURDE -- und alles war gruen:

  coturn laeuft                 aktiv
  STUN von aussen               antwortet, nennt meine oeffentliche Adresse
  echte Zuteilung von aussen    7/7, Testpaket kam an (Port 49183)
  Dreier-Anruf im Prueflauf     verbindet, alle hoeren alle

Vier Messungen, vier Mal in Ordnung -- und das Telefon ging trotzdem
nicht. Der Grund: Der Prueflauf faehrt BEIDE Seiten auf demselben
Rechner. Dort finden sie sich ueber die direkte Adresse, und die
Vermittlung wird nie gebraucht. Draussen sitzen sie in verschiedenen
Netzen.

DER FUND: Eingetragen war eine einzige Adresse --

    turn:159.195.212.167:3478

Ein `turn:` OHNE `?transport=` heisst UDP, und nur UDP. Nachgemessen
hoert coturn aber auf beidem: 3478/UDP offen, 3478/TCP offen (5349/TLS
ist zu). Angeboten wurde nur der halbe Server.

Wer in einem Netz sitzt, das UDP nach draussen sperrt -- Mobilfunk mit
strengem Profil, Gast-WLAN, Firmennetz --, bekam damit KEINEN
Vermittlungsweg. Es klingelt (das laeuft ueber die Website, also ueber
443), und danach passiert nichts. Genau das gemeldete Bild.

Aus einem Eintrag werden jetzt drei Wege:
  stun:host:port                die eigene Adresse finden, ohne Vermittlung
  turn:host:port?transport=udp  der schnelle Weg
  turn:host:port?transport=tcp  der Weg durch fast jede Sperre

ABGELEITET, NICHT EINGETRAGEN: Drei Zeilen von Hand waeren drei
Stellen, an die beim naechsten Serverumzug jemand denken muesste --
die abgeschriebene Liste, die hier schon zweimal teuer war. Ein
Eintrag MIT `?transport=` bleibt unangetastet, ein fremder Dienst mit
eigenem Passwort sowieso.

pruef-turn-wege (neu, 15/0) sichert beides: dass jeder Weg herauskommt
UND dass jeder turn:-Weg Zugangsdaten traegt. Das Zweite ist das
wichtigere -- auffaechern ohne anmelden haette den Fehler nur
verschoben.

=== 2. DIE SEITE SPRANG BEIM ZURUECKGEHEN IMMER HOCH ===

Filipe: "das nervt man muss dan immer wieder runter scrollen bis man
da ist wo man vorher war."

Der Browser versucht es sogar -- scrollRestoration steht ab Werk auf
"auto". Nur: Jede Seite hier kommt fast leer an und holt ihren Inhalt
danach per Abruf. In dem Moment, in dem der Browser die alte Position
wiederherstellen will, ist das Dokument ein paar hundert Pixel hoch.
Er kann nicht auf Zeile 900 springen, die es noch nicht gibt -- und er
versucht es kein zweites Mal.

Jetzt macht es kopf.js selbst (gilt damit auf allen 21 Seiten): Stelle
merken beim Verlassen, beim Oeffnen zurueckholen und jeden Bildaufbau
lang versuchen, bis das Dokument hoch genug ist. Nach drei Sekunden
wird aufgegeben.

Drei Dinge sind Absicht:
  - NUR beim Zurueckgehen, nicht bei jedem Oeffnen. Wer eine Kachel
    anklickt, will oben anfangen.
  - WER SELBST SCROLLT, GEWINNT. Rad, Wisch oder Taste beenden das
    Nachspringen sofort.
  - Nach einer Stunde vergessen -- auf Zeile 900 zu landen, weil man
    gestern dort war, ist keine Hilfe.

=== 3. DIE LISTE IST NACH ROLLE GETRENNT ===

Filipe: "die rechte hand rolle immer zuerst und dan die modis. die
sollen auch schoen getrennt sein und verschieden aussehen also die
rechte hand viel spezieller."

Die Reihenfolge macht der Server ueber ROLLEN_SORTIERUNG -- dieselbe
Konstante wie ueberall sonst im Haus, nicht eine zweite. Eine
Sortierung nach ROLLE ist ausdruecklich keine Rangliste: Sie sagt
nichts darueber, wie gut jemand ist, nur welche Aufgabe er hat.
Deshalb steht ueber jeder Gruppe ein Satz und keine Zahl.

"Spezieller" heisst hier Material, nicht Groesse: eigener Farbton als
Kante und Schimmer, hellere Flaeche, kraeftigerer Name. Beide Karten
sind GLEICH GROSS und tragen dieselben Zeilen -- zwei Sorten Aufgabe,
keine Rangfolge. Im Kontrastmodus traegt eine doppelte Kante die
Unterscheidung, weil dort keine Farbe mehr wirkt.

=== 4. DER ANRUFKASTEN ===

Vorher: vier gleich aussehende Pillen nebeneinander, darunter eine
Geraeteauswahl, die das breiteste Element war. Kein Name, keine
Ordnung, und der einzige Knopf mit Folgen sah aus wie die anderen.

  - MAN SAH NICHT, MIT WEM. Der wichtigste Satz eines Telefonats fehlte.
    Der Chat kennt den Namen und gibt ihn jetzt mit; wer rangeht, sieht
    den Anrufer.
  - "MIKRO AN" WAR ZWEIDEUTIG -- "ist an" oder "schalt an"? Wer falsch
    raet, sitzt stumm da. Jetzt traegt ein durchgestrichenes Zeichen
    den Zustand, das Wort nur die Sache. aria-pressed bleibt die
    Wahrheit, auch fuer Vorleseprogramme.
  - DIE GERAETEAUSWAHL liegt hinter einem kleinen Knopf, der nur
    erscheint, wenn es ueberhaupt etwas zu waehlen gibt.
  - AUFLEGEN ist als einziger Knopf farbig und steht immer rechts.
  - Ein ruhiger Puls atmet, solange die Verbindung aufbaut, und haelt
    an, sobald sie steht. Bei prefers-reduced-motion steht er still.

=== NEBENBEFUND, DEN DIE PRUEFUNG GEFUNDEN HAT ===

pruef-anruf wurde durch die Auffaecherung an vier Stellen rot: Sie
griff `adressen[0]` und erwartete dort Zugangsdaten. Das ist jetzt der
STUN-Weg, und der hat richtigerweise keine. Gesucht wird nicht mehr
nach PLATZ, sondern nach ART -- ein Index ist eine Annahme darueber,
wie die Liste aussieht, und die hat sich gerade geaendert.

Dazu angepasst: Die Pruefung "die Uhr laeuft" verlangte, dass die Uhr
schon beim Klingeln zaehlt. Seit heute frueh beginnt sie beim
Rangehen (sonst standen im Kasten und im Chat zwei verschiedene
Zahlen). Sie prueft jetzt das Gegenteil -- statt sie zu streichen,
denn eine Zeile weniger haette den Fehler beim naechsten Umbau wieder
durchgelassen.

GEMESSEN: pruef-anruf 114/0 (vorher 111 -- drei MEHR, weil die
Auffaecherung mitgeprueft wird), pruef-turn-wege 15/0,
pruef-meldungen 8/0, pruef-css-klassen ALLES IN ORDNUNG,
pruef-rechtetafel 19/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 15:23:15 +02:00

356 lines
17 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>Anmeldung · DogFather Universe</title>
<!-- WEDER "Arbeitsbereich" NOCH "die Modis" (11.09.2026).
Seit die Community durch diese Wand kommt, liest sie auch diesen
Satz. "Privater Arbeitsbereich fuer DogFather und die Modis" waere
fuer sie schlicht falsch -- und das Erste, was sie ueber das Haus
erfaehrt. -->
<meta name="description" content="Privater Bereich rund um DogFather. Zugang nur mit persönlichem Code." />
<meta name="robots" content="noindex, nofollow" />
<link rel="manifest" href="/workspace/app.webmanifest" />
<!-- Die Farbe der Fensterleiste, wenn der Workspace als App laeuft.
Stand auf #0674b9 (kraeftiges Blau) und stach damit als einziger
heller Balken ueber einer durchweg dunklen Seite. Jetzt derselbe
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
eine Flaeche sind statt zweier. -->
<meta name="theme-color" content="#06090f" />
<!-- Die Bühne ist der erste Eindruck. Ohne diesen Hinweis lädt der Browser sie erst,
nachdem er das CSS gelesen hat - das kostet spürbar Zeit. Quer- und Hochformat
sind getrennt, damit das Handy nicht die große Fassung zieht.
Hier steht bewusst WebP und nicht AVIF, obwohl die AVIF-Fassungen erzeugt
werden und rund ein Drittel kleiner wären: Der ausliefernde Server läuft auf
Express 4, dessen `send` eine alte MIME-Tabelle ohne AVIF mitbringt. Die
Dateien kämen als application/octet-stream an und würden wegen des
nosniff-Headers vom Browser verweigert - die Bühne bliebe leer. Sobald der
Workspace einen eigenen Server bekommt, kann AVIF wieder eingeschaltet
werden (die Dateien liegen bereit). -->
<link rel="preload" as="image" href="assets/img/buehne/crew-gate-1920.webp"
type="image/webp" media="(min-width: 900px)" />
<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=202609191522" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/crew-180.png?v=202609191522" />
<link rel="stylesheet" href="assets/css/gate.css?v=202609191522" />
<!-- 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=202609191522" />
</head>
<body class="gate gate--crew">
<!-- ====================================================================
DIE DREI ZEICHEN DIESER WAND (10.09.2026)
Filipe: "3 rollen. dogfather. rechte hand und modis."
Von den fuenf Zeichen der anderen Wand bleibt nur der Husky -- die
uebrigen gehoeren zu Rollen, die es hier nicht gibt, und ihre
Namen haetten im Quelltext nichts verloren.
DER HUSKY BEI DOGFATHER UND BEI DER RECHTEN HAND, die Pfote bei
den Modis (Filipe, 10.09.2026, mit Bildschirmfoto: "bei rechte
hand soll der husky sein und bei modis soll die pfote sein").
DAS DREHT EINE FRUEHERE VORGABE UM, und der Grund gehoert dazu: Am
09.09. hiess es "das modi symbol soll das gleiche sein wie bei
dogfather" -- damals gab es hier zwei Rollen, und der Satz
bedeutete "die Modis gehoeren zu Dogi, nicht zur Agentur". Mit
drei Rollen sagt dieselbe Absicht etwas anderes: Der Husky steht
bei den beiden, die den Ueberblick haben, die Pfote bei denen, die
taeglich unterwegs sind. Zwei gleiche Zeichen und ein anderes --
das liest sich als Gruppe, nicht als Reihe.
Die Pfote traegt bei 22 px, weil es fuenf klar getrennte Flaechen
sind und keine Innenzeichnung -- dasselbe Argument, mit dem auf der
anderen Wand eine Silhouette einem geschliffenen Koerper gewichen
ist.
================================================================= -->
<svg width="0" height="0" style="position:absolute;overflow:hidden" aria-hidden="true"><defs>
<!-- Der Husky ist ein FOTO, kein Pfad. Der Filter zieht ihn auf zwei
Toene zusammen (dunkles Blaugrau -> Silber), damit er neben
gezeichneten Zeichen nicht wie ein Fremdkoerper wirkt. -->
<filter id="rs-husky-duo" color-interpolation-filters="sRGB">
<feComponentTransfer>
<feFuncR type="table" tableValues="0.165 0.910"/>
<feFuncG type="table" tableValues="0.212 0.933"/>
<feFuncB type="table" tableValues="0.267 0.965"/>
</feComponentTransfer>
</filter>
<g id="r-husky">
<image href="assets/img/marke-husky.webp" x="0" y="0" width="24" height="24"
preserveAspectRatio="xMidYMid meet" filter="url(#rs-husky-duo)"/>
<circle fill="#7ec8f2" cx="7.73" cy="12.1" r="1.05"/>
<circle fill="#16232f" cx="7.73" cy="12.1" r="0.52"/>
<circle fill="#ffffff" opacity=".85" cx="7.5" cy="11.85" r="0.2"/>
</g>
<!-- Der Ton der Pfote ist der Modi-Ton (#5f8a9f) nach oben
aufgehellt: dasselbe Blau wie das App-Symbol, nur heller, damit
es bei 22 px gegen den dunklen Grund steht. -->
<linearGradient id="rs-pfote" x1="0" y1="0" x2=".35" y2="1">
<stop offset="0" stop-color="#cfe4ef"/>
<stop offset=".55" stop-color="#8fb6c8"/>
<stop offset="1" stop-color="#5f8a9f"/>
</linearGradient>
<g id="r-pfote">
<ellipse fill="url(#rs-pfote)" cx="12" cy="15.9" rx="5.3" ry="4.4"/>
<ellipse fill="url(#rs-pfote)" cx="6.5" cy="10.1" rx="2" ry="2.6"
transform="rotate(-20 6.5 10.1)"/>
<ellipse fill="url(#rs-pfote)" cx="10.1" cy="7.4" rx="2.05" ry="2.7"/>
<ellipse fill="url(#rs-pfote)" cx="13.9" cy="7.4" rx="2.05" ry="2.7"/>
<ellipse fill="url(#rs-pfote)" cx="17.5" cy="10.1" rx="2" ry="2.6"
transform="rotate(20 17.5 10.1)"/>
<!-- Ein Lichtstreifen oben links auf dem Ballen -- ohne ihn ist er
eine flache Flaeche. -->
<path fill="rgba(255,255,255,.32)"
d="M8.4 13.6c1-1.3 2.6-2 4.2-1.9-1.7.5-3 1.6-3.6 2.9z"/>
</g>
<!-- DIE COMMUNITY (11.09.2026).
Zwei Figuren, keine einzelne. Das Zeichen EINER Person ist im
Haus schon vergeben; zwei Rollen mit demselben Zeichen heisst,
dass das Zeichen nichts mehr sagt.
(Und ja: Hier stand zuerst der Name jener anderen Rolle. Diese
Datei wird an jedes Mitglied der Community ausgeliefert, samt
Kommentaren -- eine Rolle der Agentur hat darin nichts verloren.
Gefunden hat das nicht das Auge, sondern pruef-crew-adresse, die
seit dem 10.09. genau danach sucht. Zum zweiten Mal an einem Tag,
und zum zweiten Mal in einem Kommentar, der erklaert, warum man
so etwas nicht schreibt.)
Die hintere Figur ist leiser gesetzt und teilweise verdeckt -- das
ist keine Zierde: Bei 22 px verschmelzen zwei gleich helle Formen
zu einem Klecks. Erst der Helligkeitsunterschied macht daraus zwei
Menschen.
DERSELBE VERLAUF WIE DIE PFOTE, nicht der Husky-Filter: Die Pfote
steht bei denen, die taeglich unterwegs sind, der Husky bei denen
mit dem Ueberblick. Die Community ist weder das eine noch das
andere -- sie bekommt die Farbe der Pfote und eine eigene Form.
Ein drittes Farbsystem auf einer Wand mit vier Kacheln waere
Unruhe ohne Aussage. -->
<g id="r-leute">
<circle fill="url(#rs-pfote)" opacity=".55" cx="15.9" cy="8.1" r="2.9"/>
<path fill="url(#rs-pfote)" opacity=".55"
d="M10.6 20.4v-2.2c0-2.6 2.4-4.3 5.3-4.3s5.3 1.7 5.3 4.3v2.2z"/>
<circle fill="url(#rs-pfote)" cx="9.2" cy="7.4" r="3.4"/>
<path fill="url(#rs-pfote)"
d="M2.8 20.4v-2.5c0-3 2.9-5 6.4-5s6.4 2 6.4 5v2.5z"/>
<path fill="rgba(255,255,255,.3)"
d="M6.6 5.6a3.4 3.4 0 0 1 3.6-1.4c-1.4.3-2.5 1.2-3 2.4z"/>
</g>
</defs></svg>
<!-- ---------- Bühne: Bild + Schleier ---------------------------------- -->
<div class="buehne" aria-hidden="true">
<picture>
<!-- BIS 2560 PIXEL (07.09.2026). Vorher endete die Reihe bei 1600 --
auf einem 2550 px breiten Schirm rechnete der Browser das Bild
also um das 1,6-fache hoch, und jede Kante wurde weich. Genau
das sah man als "nicht hochwertig", ohne es benennen zu koennen.
Eine hoehere Bildguete haette daran nichts geaendert: Man kann
keine Bildpunkte zurueckholen, die nie ausgeliefert wurden.
Ueber srcset laedt trotzdem jeder nur die Stufe, die er
braucht -- ein Handy weiterhin 32 KB. -->
<source media="(min-width: 900px)" type="image/webp"
srcset="assets/img/buehne/crew-gate-960.webp 960w,
assets/img/buehne/crew-gate-1280.webp 1280w,
assets/img/buehne/crew-gate-1600.webp 1600w,
assets/img/buehne/crew-gate-1920.webp 1920w,
assets/img/buehne/crew-gate-2560.webp 2560w" sizes="100vw" />
<source type="image/webp"
srcset="assets/img/buehne/crew-gate-hoch-440.webp 440w,
assets/img/buehne/crew-gate-hoch-580.webp 580w,
assets/img/buehne/crew-gate-hoch-900.webp 900w" sizes="100vw" />
<img class="buehne__bild" src="assets/img/buehne/crew-gate-1280.webp" alt=""
width="1647" height="955" fetchpriority="high" decoding="async" />
</picture>
<div class="buehne__schleier"></div>
</div>
<!-- ---------- Tafel ----------------------------------------------------
DER ANKER (06.09.2026). Im Motiv steht rechts eine LEERE TAFEL mit
Neonrahmen -- dort gehoert die Anmeldekarte hinein, und zwar genau
hinein, nicht ungefaehr.
Das geht nur, wenn man weiss, wo die gemalte Tafel auf dem
Bildschirm landet. Das Bild liegt mit `object-fit: cover` darunter;
je nach Fensterform schneidet der Browser oben/unten oder
links/rechts etwas ab. Dieser Anker rechnet genau dieselbe
Cover-Geometrie noch einmal nach (siehe gate.css) -- er ist damit
deckungsgleich mit dem Bild, und die Karte kann in Prozent des
BILDES sitzen statt in Prozent des Fensters.
Er faengt keine Klicks ab (pointer-events: none); nur die Karte
darin ist bedienbar. -->
<div class="tafel-anker">
<main class="tafel" id="tafel">
<div class="tafel__kante" aria-hidden="true"></div>
<!-- 10.09.2026, Wunsch Filipe: hier soll alles auf DogFather und sein
Team zugeschnitten sein.
Zwei Namen und ein Zeichen dazwischen -- nebeneinander, nicht
uebereinander. Dogi steht hier nicht ueber den Modis, sie machen
das zusammen.
Das "x" steht als eigenes Element, damit es kleiner und in der
Zwischenfarbe gesetzt werden kann -- so liest man zwei Namen und
ein Zeichen dazwischen, nicht drei gleich laute Wörter. Es trägt
aria-hidden nicht: Vorgelesen wird "DogFather x Team Dogi", und
genau so spricht man es auch aus. -->
<header class="kopf">
<p class="marke marke--paar">
<span class="marke__dogi">DogFather</span>
<span class="marke__x">×</span>
<span class="marke__crew">Team&nbsp;Dogi</span>
</p>
<h1 class="titel">Team&nbsp;Dogi</h1>
<p class="unterzeile">Team Dogi und der Treff. Zugang nur mit persönlichem Code.</p>
</header>
<div class="rollen" role="radiogroup" aria-labelledby="rollen-schild">
<p class="feldschild" id="rollen-schild">Womit meldest du dich an?</p>
<button type="button" class="rolle" data-rolle="admin" role="radio" aria-checked="false">
<svg class="rolle__zeichen" viewBox="0 0 24 24" aria-hidden="true"><use href="#r-husky"/></svg>
<span class="rolle__text">
<span class="rolle__name">DogFather</span>
<span class="rolle__zusatz">Überblick &amp; Entscheidungen</span>
</span>
</button>
<!-- Der Untertitel beschreibt eine AUFGABE, kein Recht -- dieselbe
Ueberlegung wie auf der anderen Wand: Wer vor der Auswahl
steht, fragt sich nicht, was er duerfte, sondern was er hier
tut. Und er stellt niemanden ueber jemanden: "vertritt und
koordiniert" ist eine Taetigkeit, kein Rang. -->
<button type="button" class="rolle" data-rolle="hand" role="radio" aria-checked="false">
<svg class="rolle__zeichen" viewBox="0 0 24 24" aria-hidden="true"><use href="#r-husky"/></svg>
<span class="rolle__text">
<span class="rolle__name">Rechte Hand</span>
<span class="rolle__zusatz">Vertritt und koordiniert</span>
</span>
</button>
<button type="button" class="rolle" data-rolle="modi" role="radio" aria-checked="false">
<svg class="rolle__zeichen" viewBox="0 0 24 24" aria-hidden="true"><use href="#r-pfote"/></svg>
<span class="rolle__text">
<span class="rolle__name">Modi</span>
<span class="rolle__zusatz">Chat, Live und eigene Aufgaben</span>
</span>
</button>
<!-- DIE VIERTE KACHEL (Entscheidung Filipe, 11.09.2026).
Der Treff ist kein eigenes Haus mehr, sondern ein Raum in
diesem. Damit kommt die Community durch DIESE Wand, und sie
braucht etwas zum Drauftippen.
SIE STEHT GANZ UNTEN, und das ist nicht Rangfolge, sondern
Haeufigkeit: Die drei darueber melden sich taeglich an, die
Community-Kachel wird von jedem Einzelnen genau einmal
gedrueckt und danach merkt sich der Browser die Wahl
(localStorage, siehe gate.js). Wer taeglich kommt, soll oben
finden, was er taeglich braucht.
DER UNTERTITEL BESCHREIBT EINEN ORT, KEINE RECHTE -- dieselbe
Ueberlegung wie bei den drei anderen: Wer vor der Auswahl
steht, fragt sich nicht, was er duerfte, sondern wo er
hinwill. -->
<button type="button" class="rolle" data-rolle="gast" role="radio" aria-checked="false">
<svg class="rolle__zeichen" viewBox="0 0 24 24" aria-hidden="true"><use href="#r-leute"/></svg>
<span class="rolle__text">
<span class="rolle__name">Community</span>
<span class="rolle__zusatz">Der Treff</span>
</span>
</button>
</div>
<!-- ==== DAS ALTER (15.09.2026) ================================
Auf der Regelseite steht seit dem 11.09. „ab 18". Bis heute war
das ein Satz; jetzt ist es eine Bedingung.
Es erscheint nur bei der Community-Kachel: Wer zum Team gehört,
hat seinen Zugang von DogFather persönlich bekommen – da ist die
Frage vorher geklärt, und ein Häkchen an der Tür wäre nur im Weg.
Das Häkchen ist NICHT die Sicherung, es ist die Frage. Geprüft
und festgehalten wird sie am Server; hier steht sie nur so, dass
man sie liest, bevor man sie setzt. -->
<div class="alterfrage" id="alterfrage" hidden>
<label class="alterfrage__zeile">
<input type="checkbox" id="alter-ok" />
<span class="alterfrage__text">
Ich bin mindestens <strong id="alter-zahl">18</strong> Jahre alt.
</span>
</label>
</div>
<form class="formular" id="formular" novalidate>
<label class="feldschild" for="code">
Persönlicher Zugangscode <span class="fuer" id="fuer" hidden></span>
</label>
<div class="feld">
<input type="password" id="code" name="code" inputmode="text"
autocomplete="current-password" spellcheck="false"
placeholder="Code eingeben" aria-describedby="hinweis fehler" />
<button type="button" class="feld__auge" id="auge"
aria-label="Code anzeigen" aria-pressed="false">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path class="strich" d="M2.5 12S6 5.8 12 5.8 21.5 12 21.5 12 18 18.2 12 18.2 2.5 12 2.5 12Z"/>
<circle class="strich" cx="12" cy="12" r="2.9"/>
<path class="strich durch" d="m4 20 16-16"/>
</svg>
</button>
</div>
<p class="hinweis" id="hinweis" hidden>Feststelltaste ist aktiv.</p>
<p class="fehler" id="fehler" role="alert" aria-live="polite"></p>
<button type="submit" class="knopf" id="knopf">
<span class="knopf__text">Anmelden</span>
<span class="knopf__laden" aria-hidden="true"></span>
</button>
</form>
<!-- EINE TÜR BRAUCHT EINE KLINGEL (ergänzt 19.09.2026).
Hier standen vier Kacheln, ein Feld „Code eingeben" und ein
Knopf. Wer keinen Code hat, fand keinen einzigen Satz, der ihm
sagt, was jetzt zu tun ist. Für die Community ist das besonders
teuer: Sie ist die einzige Rolle, die von außen kommt und
niemanden im Haus kennt. -->
<p class="fuss fuss--woher">Noch keinen Code? Frag im Live nach – Team&nbsp;Dogi gibt ihn dir persönlich.</p>
<p class="fuss">
Verschlüsselte Verbindung · Zugriffe werden protokolliert
</p>
</main>
</div>
<script src="assets/js/meldung.js?v=202609191522" defer></script>
<script src="assets/js/gate.js?v=202609191522" defer></script>
</body>
</html>