Files
dogfather-universe/workspace/assets/css/gate.css
T
DogFatherGit 7351820c55 Der Waechter gegen Namensstreit gilt jetzt fuer das ganze Haus
Er wurde gestern fuer `reaktion.css` gebaut, nachdem `.stufen` dort
zweimal stand und die Stufenleiter der Spenden dadurch das Aussehen
der Chat-Leiste bekam -- drei Stufen nebeneinander, 572 Pixel in
einer 327 Pixel schmalen Spalte, mit der waagerechten Rollleiste auf
Filipes Bildschirmfoto.

Eine Wache, die nur eine Datei ansieht, findet genau die Fehler
dieser einen Datei. Auf alle 36 Stilvorlagen angewandt fand sie
GENAU EINE weitere Stelle.

DER FUND: `.wahl2__eintrag` in gate.css

    Zeile 1584  display: block   (mit text-overflow: ellipsis)
    Zeile 2634  display: flex    (fuer Personenbilder, 08.09.2026)

Kein Streit zweier Bauteile, sondern eine spaetere Erweiterung --
und trotzdem ein echter Fehler: `text-overflow: ellipsis` wirkt bei
`display: flex` NICHT auf ein anonymes Flex-Kind. Der Knopf
„… eintragen" in jeder Auswahl des Hauses hat langen Text seither
HART abgeschnitten statt mit „…" gekuerzt.

GEMESSEN -- und nur im Bild zu sehen: `scrollWidth` ist in beiden
Faellen gleich (364 px bei 200 px Breite). Die Zahlen sagten
„kein Unterschied", das Bildschirmfoto zeigte einen. Ein Beleg mehr
dafuer, dass zwei gleiche Zahlen nicht dasselbe Ergebnis bedeuten.

REPARIERT
  - Der eigene Eintrag bekommt einen `.wahl2__name`-Span, wie jeder
    andere Eintrag auch. Damit kuerzt er wieder mit „…".
  - Die zwei Grundregeln sind eine. Wer die erste las, glaubte an
    `display: block` -- 1050 Zeilen weiter stand das Gegenteil.

DIE WACHE
  923 Grundregeln in 36 Stilvorlagen, keine Klasse zweimal
  verschieden gebaut. Gezaehlt wird nur, was sich widersprechen
  kann: nicht dieselbe Klasse in einem Zusammenhang (`.saal .pult`),
  nicht eine Variante in einer Medienabfrage, nicht
  „erst versteckt, dann gezeigt". Sechs Gegenproben, darunter der
  echte Fall vom 28.09. und eine Klasse im Kommentar.

GEPRUEFT: css-klassen, freie-namen, suchfeld, tippziele alle EXIT 0.
2026-09-29 13:45:02 +02:00

3235 lines
138 KiB
CSS
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.
/* ===================================================================
Creator Workspace - Anmeldeseite
-------------------------------------------------------------------
Grundsatz: dunkel und ruhig. Die Farben stammen aus dem Motiv, sind
aber bewusst entsättigt - Neon als Stimmung, nicht als Blendung.
Kein reines Weiss auf Schwarz, keine harten Kanten, keine Blinker.
=================================================================== */
:root {
--tinte: #05070d;
--glas: rgba(10, 14, 23, 0.74);
--glas-tief: rgba(6, 9, 16, 0.86);
/* Die Flaeche jeder Kachel, Karte und Spalte -- an EINER Stelle.
Vorher stand in jeder Datei ein eigener Wert zwischen .02 und .032
WEISS, also praktisch durchsichtig. Solange der Hintergrund fast
schwarz war, fiel das nicht auf. Seit die Buehnen hell sind, kam das
Bild mitten durch den Text.
Jetzt eine deckende dunkle Flaeche: Der Hintergrund bleibt sichtbar,
aber DAZWISCHEN -- nicht hinter der Schrift. Genau das macht den
Unterschied zwischen "hat einen Hintergrund" und "ist unlesbar".
Wer die Kacheln durchsichtiger oder dichter will, aendert nur diese
eine Zeile. */
/* 0,89 statt 0,78 (07.09.2026). Die Flächen der Seite lagen bisher
hinter einem Weichzeichner -- 22 % Durchsicht auf ein VERWISCHTES
Bild fallen nicht auf. Ohne ihn liegt dahinter jetzt ein scharfes,
kontrastreiches Motiv, und dieselben 22 % machen aus einer ruhigen
Fläche eine unruhige. Die Durchsicht bleibt (Filipe: "vielleicht
ganz ganz ganz leicht durch zu sehen sein"), aber als Andeutung,
nicht als Muster. */
--flaeche: rgba(9, 13, 22, 0.89);
--rand: rgba(150, 186, 220, 0.16);
--rand-hell: rgba(150, 186, 220, 0.30);
--text: #dbe4ef; /* kein reines Weiss - schont die Augen */
/* 25.09.2026 von #94a5bb auf #9fb0c6.
Gemessen an echten Bildpunkten stand dieser Ton auf hilfe.html bei
4,90:1 und auf teamlage.html bei 4,98:1 -- ueber der Grenze, aber
mit weniger Luft, als die beiden letzten Rutscher gross waren
(jeweils rund zehn Prozent). Er waere also beim naechsten helleren
Untergrund derselbe Fall gewesen wie der Ton darunter, nur ein
paar Wochen spaeter. */
--text-leise: #9fb0c6;
/* Von #6d7d92 auf #75859a angehoben (01.09.2026).
Aufgefallen erst, als die Buehne im Hintergrund dazukam und der
Kontrast an echten BILDPUNKTEN gemessen wurde statt an der
Farbangabe: Der leiseste Grauton lag bei 4,43:1 -- knapp unter den
geforderten 4,5:1. Das war schon vorher so, nur hatte es nie jemand
nachgerechnet. Jetzt 4,95:1 auf dem hellsten Untergrund, 5,35:1 auf
reiner Tinte. Immer noch deutlich leiser als der Haupttext, aber
lesbar -- und das gilt jetzt fuer JEDE Seite, nicht nur fuer die
mit dem Hintergrundbild. */
/* 07.09.2026: #75859a -> #7f8fa6.
Der alte Wert war am 01.09. gegen die DAMALIGE Buehne gemessen
und lag dort bei 4,95:1. Seit die Hintergruende Kontrast,
Saettigung und eine Vignette statt eines flachen Schleiers
bekommen haben, sind sie heller -- und derselbe Ton fiel auf
4,50:1, also genau auf die Grenze. Gemessen von pruef-buehne
an echten Bildpunkten, nicht an der Farbangabe.
Das ist der Preis dafuer, dass das Motiv jetzt zu sehen ist:
Wer den Hintergrund heller macht, muss die leiseste Schrift
nachziehen. Die Alternative waere gewesen, das Bild wieder
zuzudecken -- dann haette man den Aufwand auch lassen koennen. */
/* 25.09.2026: #7f8fa6 -> #95a4ba. DAS DRITTE MAL DERSELBE GRIFF --
und deshalb diesmal nicht wieder auf Kante.
Die drei Staende nebeneinander, alle an echten Bildpunkten
gemessen, alle vom selben Werkzeug (pruef-buehne):
01.09. #6d7d92 -> #75859a gemessen 4,43 -> 4,95
07.09. #75859a -> #7f8fa6 gemessen 4,50 -> rund 4,9
25.09. #7f8fa6 -> #95a4ba gemessen 4,42 -> 5,75
Zweimal wurde auf „gerade eben ueber 4,5" eingestellt, und
zweimal hat der naechste hellere Untergrund es wieder
unterschritten. Der Fehler war nie die Farbe, sondern die
Bezugsgroesse: Gemessen wurde jedes Mal gegen den hellsten
Untergrund, den man GERADE KANNTE. Der Hintergrund ist aber ein
Bild, und Bilder haben helle Stellen an wechselnden Orten -- wer
dagegen auf zwei Kommastellen einstellt, stellt auf den naechsten
Fehlschlag ein.
DIESMAL IST DER BEZUG DIE HELLSTE FLAECHE IM GANZEN HAUS:
rgb(51,53,56) auf hilfe.html, gefunden, indem die Werte ALLER
vierzehn Seiten nebeneinandergelegt wurden statt nur die der
einen, die rot war. Gegen sie haelt der neue Ton 4,86:1, gegen
reine Tinte 7,68:1, an der Stelle des Befundes 5,75:1.
Leiser als der Haupttext bleibt er deutlich -- der steht bei
11,8:1, also mehr als doppelt so hoch.
Und damit es nicht ein viertes Mal so weit kommt, prueft
pruef-buehne jetzt nicht mehr nur „ueber 4,5", sondern auch, ob
der schlechteste Wert einer Seite noch 5,0 erreicht. Die Zahl ist
gemessen und nicht gewaehlt: Beide Rutscher oben waren rund elf
Prozent gross, und 4,5 mal 1,11 ist 5,0. Eine Seite, die darunter
liegt, ist noch in Ordnung und schon in Gefahr -- genau das soll
sie sagen. */
--text-still: #95a4ba;
--akzent: #3fbdf5; /* aus dem Neon des Motivs, entsättigt */
--akzent-tief: #1f7fb0;
--violett: #8a76ff;
--warn: #ff9aa2; /* weiches Rot statt Signalrot */
--radius: 18px;
--radius-klein: 12px;
--schatten: 0 24px 60px -20px rgba(0, 0, 0, 0.75);
--tempo: .22s cubic-bezier(.4, 0, .2, 1);
/* ================================================================
DIE FARBEN DER FÜNF ROLLEN — an EINER Stelle (08.09.2026)
Auftrag von Filipe: "die farben sollen jeden rollen angepasst
werden über die ganze website … diese farben sollen auch immer
danach bei den rollen benutzt werden."
Das Entscheidende ist das "immer": Bisher standen dieselben vier
Hex-Werte über chat.css, personen.css und ein Dutzend weiterer
Dateien verstreut — allein in chat.css sechzehnmal. Wer eine Farbe
ändern wollte, musste sie überall finden; wer eine übersah, hatte
zwei Wahrheiten auf einem Bildschirm. Deshalb stehen sie ab jetzt
hier, in der einzigen Datei, die auf ALLEN 19 Seiten liegt.
Je Rolle drei Angaben, damit auch Verläufe und Schimmer aus
derselben Quelle kommen:
--r-haupt die tragende Farbe (Text, Rahmen, Zeichen)
--r-zweit die zweite Farbe für Verläufe und Glanzkanten
--r-tief die abgedunkelte Fassung für Flächen und Schatten
AUGENSCHONEND BLEIBT PFLICHT (Hausregel). "Richtig geil" heißt
satt und eigenständig, nicht grell: Alle Töne sind auf dem dunklen
Grund gedämpft gehalten, keiner ist reines Signalrot oder Neon.
Gegen #0a121e liegt jeder Haupt-Ton über 4,5:1. */
/* SPICY — rot. Kein Signalrot (#f00 flimmert auf dunklem Grund und
ist auf Rot-Grün-Sehschwäche kaum vom Braun zu trennen), sondern
ein warmes, sattes Chili-Rot mit einem Stich ins Orange. */
--spicy-haupt: #ef5f57;
--spicy-zweit: #ff8a6b;
--spicy-tief: #8c2f2b;
/* DOGFATHER (admin) — SILBER, mit Babyblau als Auge (09.09.2026).
Filipe: "die farbe von der rolle und die barre soll so richtig
geil silber sein. so wie mit sternen, also es soll nicht zu viel
sein aber geil sein und der husky soll eine geile babyblau
[Auge] haben ... es soll jetzt nicht viel mehr farbe haben."
Damit kehrt die Rolle zu dem zurueck, was im allerersten Auftrag
stand ("husky: silber und blaue augen") -- unterwegs war daraus
Babyblau als Traegerfarbe geworden.
NACHGERECHNET, WEIL SILBER GEFAEHRLICH IST: Es hat kaum Buntheit
und koennte deshalb neben einer anderen Rolle verschwinden. In
OKLab liegt #d8e0ec 0,1901 von seinem naechsten Nachbarn (Scout)
entfernt -- das BISHERIGE Babyblau lag bei 0,1349. Die fuenf
Rollen sind dadurch besser auseinanderzuhalten als vorher, nicht
schlechter. Kontrast auf dunklem Grund: 14,41:1.
Creators Silber ist nur sein ZWEITTON neben Bronze; sein Traeger
bleibt warm, dieser hier ist kuehl. Die beiden stossen sich
nicht.
"wie mit sternen" ist als GLANZ gebaut, nicht als Funken: ein
schmales Spitzlicht, das ueber das Silber laeuft (siehe
`.rolle[data-rolle="admin"]` weiter unten). Kein Blinken -- die
Anmeldeseite ist das Erste, was jemand sieht, und augenschonend
bleibt Vorgabe. */
/* SILBER MIT BABYBLAU GEMISCHT (09.09.2026, Wunsch Filipe: "ich
will dass diese farbe gemischt wird mit babyblau, es soll richtig
geil sein").
Das reine Silber von gestern (#d8e0ec) war kuehl, aber neutral --
es haette zu jeder Marke gepasst. Jetzt traegt es den Babyblau-
Stich von DogFather selbst: #c7dcf4 ist dieselbe Helligkeit,
nur mit einer Blaurichtung. Nachgerechnet bleibt der Abstand zur
naechsten Rolle bei 0,1790 -- immer noch deutlich weiter als das
frueher benutzte Babyblau (0,1349) und weit ueber der Grenze im
Satz (0,0973). Kontrast 13,66:1.
Gemischt ist es nicht nur im Farbwert, sondern SICHTBAR: Die
Schiene links laeuft von Silber nach Babyblau, und der Glanz auf
der Zeile traegt beide Toene. Eine Mischung, die man nur im
Hexwert findet, ist keine. */
/* NACHGESCHAERFT AM 09.09.2026 (screen1). Filipe: "da muss mehr
babyblau zu sehen sein. da ist ja fast nichts."
Er hatte recht, und es war messbar: In der DogFather-Zeile waren
nur 5,9 Prozent der hellen Bildpunkte babyblau. #c7dcf4 traegt
zwischen Rot- und Blaukanal nur 45 Stufen Unterschied -- im Hexwert
ist das ein Blau, auf dem Bildschirm ein Weiss.
#9ed3f4 hat 86 Stufen, also fast das Doppelte, und bleibt trotzdem
hell genug fuer Metall: Kontrast 12,41:1 auf dem Untergrund
(vorher 14,21:1), Abstand zur naechsten Rollenfarbe 0,1295 in
OKLab -- die Hausgrenze liegt bei 0,0973. Es ist also weiterhin
eindeutig DogFather und faellt nicht in Richtung Creator.
Silber bleibt es durch die HELLIGKEIT, blau wird es durch den
Kanalabstand. Beides zugleich geht nur so; ein saettigeres Blau
waere Farbe statt Material. */
/* ---------------------------------------------------------------
DRITTER SCHRITT, 09.09.2026. Filipe: "die rolle dogfather soll
eine uebertrieben geile babyblau haben."
Zweimal habe ich hier den ABSTAND zwischen Rot- und Blaukanal
erhoeht (45 Stufen -> 86) und zweimal war es zu wenig. Diesmal
erst gemessen, was am Bildschirm ankommt, statt den Hexwert
anzusehen:
Die DogFather-Zeile traegt 98,7 % farbige Bildpunkte -- MEHR als
jede andere Rolle. An der Menge lag es also nie.
Ihr Mittelwert war aber rgb(43,62,78): zwischen Rot und Blau
liegen 35 Stufen, und das ist Stahlgrau, kein Babyblau.
Die richtige Groesse ist die SAETTIGUNG, nicht der Kanalabstand im
Hexwert. In OKLab gemessen hatte #9ed3f4 eine Buntheit von 0,0718
-- der blasseste Wert aller fuenf Rollen. #5fbdff hat 0,1303, also
81 Prozent mehr, und die Zeile kommt damit auf rgb(28,55,76):
48 Stufen zwischen Rot und Blau statt 28.
Was dabei NICHT verlorengeht, nachgerechnet:
* Kontrast auf dem Grund 9,75:1 (vorher 12,49) -- weit ueber den
4,5, die fuer Text gelten, und ueber den 7 fuer AAA.
* Abstand zur naechsten Rollenfarbe (Scout) 0,1608 in OKLab,
vorher 0,1466. Die Hausgrenze liegt bei 0,0973 -- DogFather
ist also SICHERER unterscheidbar als vorher, nicht weniger.
Silber bleibt es durch die Helligkeit des Spitzlichts auf der
Schiene (#f2f8ff an ihrem oberen Ende) -- das ist die Stelle, an
der Metall entsteht. Die Flaeche darunter darf Farbe sein. */
--dogi-haupt: #5fbdff;
/* Der Begleitton geht mit: Er traegt die untere Haelfte der Schiene.
Bliebe er auf #6dc2f2, waere die Schiene oben satter als unten --
ein Verlauf, der in die falsche Richtung laeuft. */
--dogi-zweit: #2fa9f2;
/* Und die Tiefe wird ein echtes Blau statt eines Schiefergraus. */
--dogi-tief: #14496f;
/* MANAGER — lila, bleibt (Wunsch: "manager bleibt lila"). */
--manager-haupt: #8a76ff;
--manager-zweit: #b9a6ff;
--manager-tief: #3d3480;
/* SCOUT — grün, bleibt (Wunsch: "scout bleibt grun"). */
--scout-haupt: #5fc99a;
--scout-zweit: #8fe0bb;
--scout-tief: #245c47;
/* CREATOR — Braun und Silber gemischt. Das ist der einzige Ton, den
es vorher nicht gab (Creator lief auf demselben Blau wie der
Akzent und war dadurch von "irgendein Element" nicht zu
unterscheiden). Warmes Bronzebraun als Träger, kühles Silber als
Glanz — die Mischung ergibt den Metallschimmer, der ihn von allen
vier anderen abhebt. */
--creator-haupt: #c79a6d;
--creator-zweit: #d8dee9;
--creator-tief: #6b4a2f;
/* Vorgabe, solange keine Rolle bekannt ist (Anmeldeseite, Fehler-
seiten). Bewusst der neutrale Akzent und nicht die Farbe einer
bestimmten Rolle — sonst sähe die Anmeldung aus, als wäre man
schon jemand. */
--r-haupt: var(--akzent);
--r-zweit: var(--violett);
--r-tief: var(--akzent-tief);
/* ---- DER SICHERE BEREICH (09.09.2026) --------------------------
Jede der 20 Workspace-Seiten sagt `viewport-fit=cover` -- die Seite
wird also bis unter Statusleiste, Aussparung und Gestenleiste
gezeichnet. Das ist gewollt (randloser Hintergrund), verlangt aber,
dass man den belegten Rand wieder abzieht. Genau das fehlte hier:
im ganzen Workspace stand kein einziges `env(safe-area-inset-*)`,
waehrend die Webdesign-Seiten es laengst haben.
Im Browser faellt es nicht auf, weil die Adresszeile die Seite nach
unten schiebt. INSTALLIERT gibt es die nicht mehr -- dann liegt die
Kopfleiste auf einem iPhone hinter der Uhr, und von einem 36-px-Knopf
bleiben rechnerisch 5 px zum Antippen uebrig.
Filipes Android ist NICHT betroffen (nachgesehen im Bildschirmfoto,
die App beginnt dort sauber unter der Statusleiste) -- das hier ist
fuer die iPhones im Team.
Einmal zentral benannt statt an fuenfzehn Stellen einzeln
geschrieben: Wer sie einzeln schreibt, vergisst eine, und dann liegt
genau ein Knopf unter der Gestenleiste. Auf Geraeten ohne
Aussparung sind alle vier 0 -- dort aendert sich nichts. */
--ws-sicher-oben: env(safe-area-inset-top, 0px);
--ws-sicher-unten: env(safe-area-inset-bottom, 0px);
--ws-sicher-links: env(safe-area-inset-left, 0px);
--ws-sicher-rechts: env(safe-area-inset-right, 0px);
}
/* Die Rolle steht am <html> (gesetzt in kopf.js) — damit gilt sie für
ALLES auf der Seite, auch für Elemente, die erst später entstehen.
Ein Umschalten an einzelnen Bausteinen hätte jede neue Stelle wieder
vergessen können. */
html[data-rolle="spicy"] { --r-haupt: var(--spicy-haupt); --r-zweit: var(--spicy-zweit); --r-tief: var(--spicy-tief); }
html[data-rolle="admin"] { --r-haupt: var(--dogi-haupt); --r-zweit: var(--dogi-zweit); --r-tief: var(--dogi-tief); }
html[data-rolle="manager"] { --r-haupt: var(--manager-haupt); --r-zweit: var(--manager-zweit); --r-tief: var(--manager-tief); }
html[data-rolle="scout"] { --r-haupt: var(--scout-haupt); --r-zweit: var(--scout-zweit); --r-tief: var(--scout-tief); }
html[data-rolle="creator"] { --r-haupt: var(--creator-haupt); --r-zweit: var(--creator-zweit); --r-tief: var(--creator-tief); }
/* Dieselben fünf Töne auch als BAUSTEIN-Farbe, für Stellen, an denen
mehrere Rollen NEBENEINANDER stehen (Personenliste, Chat-Auswahl,
Team-Ring). Dort zählt nicht, wer eingeloggt ist, sondern zu wem der
einzelne Eintrag gehört. */
[data-rolle="spicy"] { --rolle-haupt: var(--spicy-haupt); --rolle-zweit: var(--spicy-zweit); --rolle-tief: var(--spicy-tief); }
[data-rolle="admin"] { --rolle-haupt: var(--dogi-haupt); --rolle-zweit: var(--dogi-zweit); --rolle-tief: var(--dogi-tief); }
[data-rolle="manager"] { --rolle-haupt: var(--manager-haupt); --rolle-zweit: var(--manager-zweit); --rolle-tief: var(--manager-tief); }
[data-rolle="scout"] { --rolle-haupt: var(--scout-haupt); --rolle-zweit: var(--scout-zweit); --rolle-tief: var(--scout-tief); }
[data-rolle="creator"] { --rolle-haupt: var(--creator-haupt); --rolle-zweit: var(--creator-zweit); --rolle-tief: var(--creator-tief); }
*, *::before, *::after { box-sizing: border-box; }
/* `color-scheme: dark` ist der eigentliche Schalter für alles, was der
Browser selbst zeichnet und was CSS nicht erreicht: die aufgeklappte
Liste eines <select>, den Kalender eines Datumsfeldes, Bildlaufleisten,
die Textmarkierung. Ohne diese Zeile geht der Browser von einer hellen
Seite aus und malt die Auswahlliste weiss -- die helle Schrift darauf
war dann praktisch unlesbar. */
html { -webkit-text-size-adjust: 100%; color-scheme: dark; }
/* WOHIN EIN SPRUNG FUEHRT, WENN OBEN ETWAS FESTKLEBT (23.09.2026)
---------------------------------------------------------------
Seit die Kopfleiste auf JEDER Seite stehen bleibt, liegt sie
auch dann oben, wenn der Browser zu einer Marke springt --
etwa von "Eure Aufgaben" auf eine einzelne Aufgabe
(aufgaben.html#a123). Ohne diese Zeile landet das Sprungziel
exakt am oberen Rand und damit HINTER der Leiste: Die Seite
springt, und die gesuchte Karte ist trotzdem nicht zu sehen.
Das sieht aus wie ein kaputter Link.
`--kopf-hoehe` misst kopf.js selbst und zaehlt dabei auch das
Band mit der fremden Sicht mit. Eine feste Zahl waere hier
falsch: Die Leiste ist am Rechner 73 px hoch und auf einem
390-px-Schirm 115 px, und mit dem Band noch mehr. Der
Rueckfallwert gilt nur fuer die Augenblicke vor der ersten
Messung.
Die 12 px obendrauf sind Luft, kein Rateergebnis: Ein Ziel, das
die Leiste exakt beruehrt, sieht aus wie abgeschnitten. */
html { scroll-padding-top: calc(var(--kopf-hoehe, 80px) + 12px); }
/* Zusätzlich die Einträge selbst setzen. Ältere Browser und Linux-
Oberflächen ignorieren color-scheme teilweise; diese beiden Zeilen
wirken auch dort. */
option {
background-color: #0d131d;
color: var(--text);
}
/* WICHTIG. Das hidden-Attribut blendet ein Element nur über eine sehr
schwache Browserregel aus -- JEDE eigene display-Angabe schlägt sie.
Ohne diese Zeile blieben Elemente sichtbar, die per JavaScript
ausgeblendet wurden: das Ablegefeld für Dateien (display: grid) und
die Verwaltungsfelder im Creator-Profil (ebenfalls grid). Aufgefallen
erst im Screenshot -- eine Prüfung auf das Attribut allein hätte den
Fehler nie gezeigt, denn gesetzt war es ja. */
[hidden] { display: none !important; }
body.gate {
margin: 0;
min-height: 100svh;
display: flex;
align-items: center;
background: var(--tinte);
color: var(--text);
font-family: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
font-size: 16px;
line-height: 1.55;
letter-spacing: .01em;
overflow-x: hidden;
}
/* ---------- Bühne ---------------------------------------------------- */
.buehne { position: fixed; inset: 0; z-index: 0; }
/* DAS <picture> BEKOMMT EINE EIGENE GRÖSSE (19.09.2026)
`<picture>` ist von Haus aus ein INLINE-Element ohne eigene Breite --
es richtet sich nach seinem Inhalt. Das `width: 100%` am Bild bezieht
sich damit auf etwas, das sich selbst nach dem Bild richtet. Als
Block mit `inset: 0` sitzt es dagegen sauber im Rahmen der Bühne,
und `object-fit: cover` schneidet den Ausschnitt zu, der gemeint ist.
---------------------------------------------------------------------
EHRLICHKEIT ZUR HERKUNFT DIESER REGEL
Hier stand zuerst eine lange Begründung mit einer Messung: „1647 px
breites Bild auf einem 390 px breiten Schirm". Diese Messung war
FALSCH -- sie stammte aus einem Prüflauf, in dem wegen einer
erzwungenen https-Umleitung überhaupt keine Stilvorlage geladen
wurde. Gemessen wurde eine Seite ganz ohne CSS.
Die Regel selbst bleibt trotzdem richtig, und sie bleibt deshalb
stehen. Aber die Begründung ist ausgetauscht: Ein Kommentar, der eine
Zahl nennt, die nie stimmte, ist schlimmer als keiner -- der Nächste
liest ihn und glaubt ihm. */
.buehne picture {
display: block;
position: absolute; inset: 0;
}
.buehne__bild {
width: 100%; height: 100%;
object-fit: cover;
object-position: center;
/* Minimal abgedunkelt und entsättigt, damit der Text darüber ruhig liegt. */
filter: saturate(.92) brightness(.9);
/* Die Reserve fuer die Parallaxe -- und die Bewegung selbst, die
gate.js als zwei Groessen am <body> setzt. Frueher schrieb das
Skript hier direkt `style.transform`; seit die Karte in der
gemalten Tafel sitzt, muss der Anker DIESELBE Bewegung machen, und
dafuer brauchen beide dieselbe Quelle. */
transform: scale(1.03)
translate3d(var(--parallax-x, 0px), var(--parallax-y, 0px), 0);
transition: transform 1.4s cubic-bezier(.2, .7, .2, 1);
will-change: transform;
}
/* Der Schleier macht die linke Seite lesbar, ohne das Motiv zu erschlagen.
Rechts bleibt er fast durchsichtig - dort stehen Dogfather und Hasi Dog. */
.buehne__schleier {
position: absolute; inset: 0;
/* Viele weiche Stufen statt weniger harter - sonst zeichnet sich die Kante
des Verlaufs als sichtbare Diagonale quer durchs Bild. */
background:
linear-gradient(96deg,
rgba(3, 5, 10, 0.93) 0%,
rgba(3, 5, 10, 0.90) 18%,
rgba(3, 5, 10, 0.82) 28%,
rgba(4, 6, 12, 0.68) 36%,
rgba(4, 6, 12, 0.50) 44%,
rgba(4, 6, 12, 0.33) 52%,
rgba(4, 6, 12, 0.19) 60%,
rgba(4, 6, 12, 0.09) 68%,
rgba(4, 6, 12, 0.03) 78%,
rgba(4, 6, 12, 0.00) 88%),
radial-gradient(120% 90% at 50% 120%, rgba(0, 0, 0, .42), transparent 62%);
}
/* ---------- Tafel ---------------------------------------------------- */
.tafel {
position: relative;
z-index: 1;
margin-left: clamp(24px, 7vw, 104px);
width: min(452px, 44vw);
padding: clamp(28px, 3vw, 40px) clamp(24px, 2.6vw, 36px) clamp(24px, 2.6vw, 32px);
background: var(--glas);
backdrop-filter: blur(22px) saturate(115%);
-webkit-backdrop-filter: blur(22px) saturate(115%);
border: 1px solid var(--rand);
border-radius: var(--radius);
box-shadow: var(--schatten);
animation: auftauchen .7s cubic-bezier(.2, .7, .2, 1) both;
}
/* Feine Lichtkante links - nimmt das Neon des Motivs auf, ohne zu leuchten. */
.tafel__kante {
position: absolute; left: -1px; top: 16%; bottom: 16%;
width: 2px; border-radius: 2px;
background: linear-gradient(180deg,
transparent, var(--akzent) 22%, var(--violett) 72%, transparent);
opacity: .55;
}
@keyframes auftauchen {
from { opacity: 0; transform: translateY(14px); }
to { opacity: 1; transform: none; }
}
/* ---------- Kopf ----------------------------------------------------- */
.marke {
margin: 0 0 6px;
font-size: .74rem; font-weight: 700;
letter-spacing: .18em; text-transform: uppercase;
color: var(--akzent);
}
.titel {
margin: 0 0 8px;
font-size: clamp(1.6rem, 2.5vw, 2rem);
font-weight: 700; line-height: 1.15;
letter-spacing: -.01em;
}
.unterzeile { margin: 0 0 26px; color: var(--text-leise); font-size: .94rem; }
/* DER NACHSATZ, DER EINE EINSCHRÄNKUNG TRÄGT (19.09.2026).
Eine Zeile unter der Unterzeile, ruhiger gesetzt und mit einem
Strich links: Sie widerspricht dem Satz darüber nicht, sie
vervollständigt ihn. Deshalb tritt sie zurück, statt zu warnen —
augenschonend heißt hier ausdrücklich auch: keine Signalfarbe für
etwas, das keine Warnung ist. */
/* ---- DER ABSTAND IST EINE REGEL, KEINE ZAHL (korrigiert 20.09.2026) --
Hier stand `margin: -18px 0 26px`. Die -18 waren gegen die 26 px
gerechnet, die `.unterzeile` darueber mitbringt -- Netto acht Pixel
Abstand, und auf der Torseite sah das richtig aus.
AUF DER BEFINDENS-SEITE UEBERLAGERTEN SICH DIE BEIDEN ABSAETZE UM
GENAU 18 PIXEL. Dort steht die Unterzeile in einer Kopfzeile, und
`start.css` setzt deren `margin-bottom` auf 0. Aus 26 minus 18 wurde
0 minus 18. Zwei fuer sich richtige Regeln, und dazwischen Text ueber
Text -- ausgerechnet im Satz „Deine Antworten liest niemand ausser
dir", also dort, wo Vertrauen entsteht.
Gefunden hat es ein Bildschirmfoto, nicht das Lesen: Beide Regeln
sehen einzeln vernuenftig aus.
DIE LEHRE IST NICHT „-18 auf -8 aendern" -- das waere dieselbe Zahl
mit einem anderen Wert und beim naechsten Zusammentreffen wieder
falsch. Stattdessen bestimmt der Absatz DAVOR seinen Abstand selbst,
und zwar nur dann, wenn der Zusatz wirklich folgt (`:has`). Damit
sind es IMMER acht Pixel, egal in welcher Umgebung.
Die Klasse steht doppelt (`.unterzeile.unterzeile`), um dieselbe
Staerke wie `.willkommen .unterzeile` zu uebertreffen -- sonst
entschiede die Ladereihenfolge, und gate.css laedt zuerst. */
.unterzeile.unterzeile:has(+ .unterzeile--zusatz) { margin-bottom: 8px; }
.unterzeile--zusatz {
margin: 0 0 26px;
padding-left: 11px;
border-left: 2px solid var(--rand);
max-width: 62ch;
font-size: .86rem;
line-height: 1.6;
color: var(--text-still);
}
.unterzeile--zusatz em { font-style: normal; color: var(--text-leise); font-weight: 600; }
/* ---------- Rollen --------------------------------------------------- */
.feldschild {
margin: 0 0 10px;
font-size: .78rem; font-weight: 600;
letter-spacing: .06em; text-transform: uppercase;
color: var(--text-still);
}
/* =====================================================================
DIE FUENF ROLLEN IN EINER KACHEL (screen20, 08.09.2026)
Filipe: "ich will dass die rollen auch alle in einer grossen kacheln
sind, die soll richtig krass sein, richtig speziell."
VORHER WAREN ES FUENF EINZELNE KAESTEN mit je eigenem Rand und
8 px Luft dazwischen -- und der Hintergrund des Motivs schien
ueberall durch. Das las sich als fuenf Dinge, die zufaellig
untereinander stehen. Es ist aber EINE Frage mit fuenf Antworten,
und genau so sieht es jetzt aus: ein Koerper, in den fuenf Felder
eingelassen sind.
DIE FUGE MACHT DIE KACHEL. Nicht der Rand aussen -- der ist Fassung
--, sondern die dunkle Linie ZWISCHEN den Feldern. Ein Spalt, durch
den der Untergrund scheint, trennt; eine dunkle Fuge verbindet, weil
sie zum selben Koerper gehoert. Deshalb `#05070c` und nicht
`transparent`. Dieselbe Entscheidung wie beim Kalender.
ABGESCHRAEGTE ECKEN wie ueberall im Haus. Auf dieser Seite gibt es
die Modulliste aus module.css nicht (die Anmeldeseite laedt
absichtlich nur gate.css -- sie ist die erste Seite, die jemand
sieht, und soll schnell da sein). Das Polygon steht deshalb hier,
einmal, in einer Variablen.
================================================================== */
.rollen {
--r-fase: 16px;
--r-rand: 2px;
--r-form: polygon(
var(--r-fase) 0, calc(100% - var(--r-fase)) 0,
100% var(--r-fase), 100% calc(100% - var(--r-fase)),
calc(100% - var(--r-fase)) 100%, var(--r-fase) 100%,
0 calc(100% - var(--r-fase)), 0 var(--r-fase));
position: relative;
margin-bottom: 22px;
padding: var(--r-rand);
clip-path: var(--r-form);
/* DIE FASSUNG: dieselben vier Farben wie am Rand der Zentrale --
links Rot, rechts Babyblau, Silber als Treffpunkt, Schwarz als
Fuge. Wer sich anmeldet, sieht damit schon hier die Handschrift
der Seite, die dahinter liegt. */
background: linear-gradient(96deg,
#20060b 0%, #c8323f 6%, #ff5f6d 14%, #ffd9dd 20%,
#b3242f 30%, #0a0c12 40%, #f4faff 50%, #0a0c12 60%,
#4f95bd 70%, #8fd8ff 78%, #dff2ff 84%, #3f7fa3 92%, #06080f 100%);
box-shadow: 0 14px 30px -18px rgba(0, 0, 0, .9);
}
/* Das Innenglas. Eigene Ebene, damit die Fassung ringsum stehen
bleibt, mit dem feinen Messraster des Hauses darauf. */
.rollen::before {
content: ""; position: absolute; inset: var(--r-rand);
z-index: 0; pointer-events: none;
clip-path: var(--r-form);
background:
linear-gradient(180deg, rgba(255, 255, 255, .05), transparent 34%),
repeating-linear-gradient(0deg, rgba(150, 186, 220, .05) 0 1px, transparent 1px 22px),
repeating-linear-gradient(90deg, rgba(150, 186, 220, .05) 0 1px, transparent 1px 22px),
radial-gradient(120% 80% at 12% 100%, rgba(255, 74, 92, .10), transparent 62%),
radial-gradient(110% 75% at 88% 0%, rgba(126, 200, 242, .09), transparent 60%),
linear-gradient(180deg, #0b111c, #070b13);
}
.rollen > * { position: relative; z-index: 1; }
/* Die Frage sitzt als Kopfzeile IN der Kachel, nicht darueber --
sonst waere die Kachel eine Liste ohne Titel und der Titel ein
Satz ohne Bezug. */
/* =====================================================================
DIE FRAGE UEBER DEN ROLLEN (09.09.2026, screen1 Punkt 4)
Filipe: "dieser text soll bitte bissl geiler sein."
"Womit meldest du dich an?" ist der einzige Satz auf dieser Seite,
der eine FRAGE stellt -- alles andere ist Marke, Titel oder
Antwort. Er stand als kleine graue Grossbuchstabenzeile da, wie ein
Feldname in einem Formular.
DREI SACHEN, DIESELBE SPRACHE WIE DIE TYPENSCHILDER IM WORKSPACE:
1. GEBUERSTETES METALL statt Grau -- oben hell, in der Mitte
dunkler, unten wieder hell. Ein Verlauf von hell nach dunkel
waere eine Faerbung; erst der WECHSEL liest sich als Material.
2. EIN ANSCHLAG LINKS aus drei Kerben, in den beiden Hausfarben
(rot oben, babyblau unten) -- dieselbe Richtung wie die
Fassung der Kachel und wie der Schriftzug im Kopf.
3. EINE AUSLAUFENDE LINIE nach rechts, die die Zeile gliedert,
ohne sie zu zerschneiden.
DER RUECKFALL IST VOLLWERTIG: `color` bleibt gesetzt, den Verlauf
schaltet erst ein `@supports` dazu. Faellt `background-clip: text`
aus, steht dort heller Text -- nicht unsichtbarer. Das ist die
erste Seite, die jemand sieht; sie darf an keiner Technik haengen.
===================================================================== */
.rollen .feldschild {
position: relative;
display: flex; align-items: center; gap: 11px;
margin: 0;
padding: 13px 34px 11px 15px;
border-bottom: 1px solid #05070c;
box-shadow: 0 1px 0 rgba(255, 255, 255, .045);
color: #e6eef8;
letter-spacing: .1em;
}
/* Der Anschlag: drei Kerben, oben rot, unten babyblau. */
.rollen .feldschild::before {
content: "";
width: 13px; height: 13px; flex: none;
background:
repeating-linear-gradient(180deg,
currentColor 0 2px, transparent 2px 5px);
color: transparent;
background-image: repeating-linear-gradient(180deg,
#ff5f6d 0 2px, transparent 2px 5px);
-webkit-mask: linear-gradient(180deg, #000 0 45%, rgba(0, 0, 0, .55) 100%);
mask: linear-gradient(180deg, #000 0 45%, rgba(0, 0, 0, .55) 100%);
}
/* Die untere Haelfte des Anschlags in Babyblau -- zwei Ebenen, damit
die Kerben oben rot und unten blau sind, ohne ein zweites Element. */
.rollen .feldschild::before {
background-image:
linear-gradient(180deg, transparent 0 46%, rgba(143, 216, 255, .95) 46%),
repeating-linear-gradient(180deg, #ff5f6d 0 2px, transparent 2px 5px);
background-blend-mode: multiply, normal;
}
.rollen .feldschild::after {
content: "";
position: absolute; right: 12px; top: 50%;
width: 16px; height: 1px;
transform: translateY(-.5px);
background: linear-gradient(90deg, rgba(143, 216, 255, .55), transparent);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
.rollen .feldschild {
background: linear-gradient(178deg,
#ffffff 0%, #dfeaf6 32%, #93a8bf 60%, #d7e6f5 86%, #ffffff 100%) text;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.rolle {
display: flex; align-items: center; gap: 13px;
width: 100%; margin: 0; padding: 12px 16px;
background: transparent;
border: 0;
/* Die Fuge nach unten, ausser beim letzten -- sonst laege eine
Linie auf der Fassung. */
border-bottom: 1px solid #05070c;
box-shadow: 0 1px 0 rgba(255, 255, 255, .035);
color: var(--text);
font: inherit; text-align: left; cursor: pointer;
transition: background var(--tempo), box-shadow var(--tempo), padding-left var(--tempo);
}
.rolle:last-child { border-bottom: 0; box-shadow: none; }
/* BEIM ZEIGEN RUECKT DAS FELD AUF, statt aufzuleuchten -- dieselbe
Sprache wie ueberall ("naeherkommen statt aufleuchten"). Der schmale
Streifen links traegt die Farbe DIESER Rolle. */
.rolle:hover {
background: linear-gradient(90deg,
color-mix(in srgb, var(--rf) 14%, transparent), transparent 46%);
padding-left: 20px;
}
.rolle:active { padding-left: 18px; }
/* AUSGEWAEHLT LEUCHTET IN DER FARBE DER ROLLE, nicht in Blau.
Hier stand fuer alle fuenf derselbe blau-violette Verlauf -- wer
"Scout" waehlte, bekam Blau, obwohl Scout gruen ist, und die
Rollenfarbe `--rf` direkt darueber wurde ignoriert. Die Farben sind
seit dem 08.09. zentral gesetzt und ueberall im Haus gueltig; genau
hier, bei der Wahl der Rolle, wurden sie nicht benutzt.
`color-mix` statt fuenf ausgeschriebener Verlaeufe: Die Farbe kommt
aus `--rf`, und `--rf` kommt aus den Hausfarben. Eine Aenderung
dort wirkt bis hierher. */
.rolle[aria-checked="true"] {
background: linear-gradient(96deg,
color-mix(in srgb, var(--rf) 26%, transparent),
color-mix(in srgb, var(--rf) 9%, transparent) 62%,
transparent);
padding-left: 20px;
box-shadow:
inset 3px 0 0 var(--rf),
0 1px 0 rgba(255, 255, 255, .035);
}
.rolle[aria-checked="true"]:last-child { box-shadow: inset 3px 0 0 var(--rf); }
@media (prefers-reduced-motion: reduce) {
.rolle, .rolle:hover, .rolle:active { transition: none; padding-left: 16px; }
.rolle[aria-checked="true"] { padding-left: 16px; }
}
.rolle__zeichen {
flex: 0 0 auto; width: 21px; height: 21px;
fill: none; stroke: var(--text-still);
stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
transition: stroke var(--tempo);
}
.rolle__zeichen .strich { fill: none; }
/* =====================================================================
DIE ROLLENZEICHEN SIND KOERPER, KEINE UMRISSE (07.09.2026)
Filipe: "die symbole sollen doch alle viel krasser, geiler und
spezieller sein."
Sie waren feine Konturen in EINER Farbe -- und zwar in derselben fuer
alle fuenf. Jetzt tragen sie eine gefuellte Flaeche in der Farbe
IHRER Rolle, die Zeichnung hell darauf und einen leichten Schatten
darunter. Dieselbe Sprache wie die Rollenknoepfe auf der
Personenseite; wer die eine Seite kennt, erkennt die andere wieder.
`--rf` ist die Rollenfarbe. Sie steht hier und nicht im Zeichen,
damit die Farbe eines Tages nur an EINER Stelle geaendert werden
muss -- die Zeichen selbst wissen nichts von Rollen. */
.rolle { --rf: var(--text-still); }
/* Seit dem 08.09.2026 aus den zentralen Rollenfarben oben, nicht mehr
als eigene Hex-Werte. Zwei davon waren inhaltlich falsch geworden:
`admin` stand auf Gold (Filipe will Babyblau/Lila) und `creator` auf
demselben Blau wie der allgemeine Akzent -- die Rolle war dadurch
optisch nicht von "irgendein Bedienelement" zu unterscheiden. */
.rolle[data-rolle="spicy"] { --rf: var(--spicy-haupt); }
.rolle[data-rolle="admin"] { --rf: var(--dogi-haupt); }
.rolle[data-rolle="manager"] { --rf: var(--manager-haupt); }
.rolle[data-rolle="scout"] { --rf: var(--scout-haupt); }
.rolle[data-rolle="creator"] { --rf: var(--creator-haupt); }
.rolle__zeichen {
stroke: color-mix(in srgb, var(--rf) 88%, #ffffff);
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .65));
}
/* DIE KRONE BRINGT IHRE EIGENEN FARBEN MIT (22.09.2026).
Die Regel darueber faerbt jedes Rollenzeichen mit dem Ton der
Rolle ein -- gedacht fuer gezeichnete Striche. Die Krone besteht
aus gefuellten Flaechen mit eigenen Verlaeufen; ein Strich in
Rollenfarbe daraufgelegt waere ein blauer Rand um eine goldene
Krone.
Derselbe Grund, aus dem der Husky (ein Foto) und die Pfote (eigene
Verlaeufe) von der Regel nichts merken -- nur dass eine Flaeche
ohne `stroke` sie stillschweigend ignoriert, waehrend die Krone
sie sichtbar abbekommen haette. Also ausdruecklich abbestellt.
Der Schatten BLEIBT: Er hebt das Zeichen vom dunklen Grund ab, und
das gilt fuer Gold genauso. */
.rolle__zeichen--krone { stroke: none; }
.rolle[aria-checked="true"] .rolle__zeichen--krone { stroke: none; }
/* Im Kontrastmodus gibt es keine Verlaeufe -- dort traegt die Form
allein. Ein Umriss macht sie sichtbar. */
@media (forced-colors: active) {
.rolle__zeichen--krone { forced-color-adjust: auto; }
}
.rolle__zeichen .fuell {
stroke: none;
fill: color-mix(in srgb, var(--rf) 52%, transparent);
}
/* HIER STANDEN DREI REGELN FUER EIN ZEICHEN, DAS ES NICHT MEHR GIBT
(16.09.2026).
`.auge`, `.nase` und `.hell` gehoerten zu einem Rollenzeichen, das
aus SVG-Pfaden gezeichnet war. Heute ist es ein Bild plus drei
Kreise mit festen Farben (`#r-husky`) -- kein Element im Haus traegt
diese Klassen noch. Nachgemessen ueber alle HTML- und JS-Dateien:
als Klasse null Vorkommen.
`.fuell` BLEIBT: die wird an einer Stelle wirklich benutzt.
WARUM NUR EINE DAVON GEMELDET WURDE: Die Suche nach totem CSS
vergleicht den Klassennamen als Teilzeichenkette gegen den gesamten
Quelltext. „auge" steckt in „Auge", „hell" in „hell" und
„hellster" -- beide kamen im Fliesstext deutscher Kommentare
dutzendfach vor und galten damit als benutzt. Nur „nase" kam
nirgends vor. Die beiden anderen waren genauso tot, nur unsichtbar.
Das ist eine offene Schwaeche der Pruefung, kein Befund gegen das
Haus -- sie steht hier notiert, damit sie nicht wieder verlorengeht. */
/* Gewaehlt: mehr Licht auf demselben Gegenstand -- kein anderer
Gegenstand. */
.rolle[aria-checked="true"] .rolle__zeichen {
stroke: color-mix(in srgb, var(--rf) 40%, #ffffff);
}
.rolle[aria-checked="true"] .rolle__zeichen .fuell {
fill: color-mix(in srgb, var(--rf) 78%, transparent);
}
.rolle__text { display: flex; flex-direction: column; min-width: 0; }
.rolle__name { font-weight: 600; font-size: .95rem; }
.rolle__zusatz { font-size: .8rem; color: var(--text-still); }
/* ---------- Formular ------------------------------------------------- */
.fuer { color: var(--akzent); text-transform: none; letter-spacing: normal; }
.feld { position: relative; }
#code {
width: 100%; padding: 13px 46px 13px 15px;
background: rgba(255, 255, 255, .045);
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
color: var(--text);
font: inherit; letter-spacing: .06em;
transition: border-color var(--tempo), background var(--tempo), box-shadow var(--tempo);
}
#code::placeholder { color: var(--text-still); letter-spacing: normal; }
#code:hover { border-color: var(--rand-hell); }
#code:focus {
outline: none;
border-color: rgba(63, 189, 245, .7);
background: rgba(255, 255, 255, .065);
box-shadow: 0 0 0 3px rgba(63, 189, 245, .16);
}
.feld__auge {
position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
width: 36px; height: 36px; padding: 8px;
background: none; border: 0; border-radius: 9px;
cursor: pointer; color: var(--text-still);
transition: color var(--tempo), background var(--tempo);
}
.feld__auge:hover { color: var(--text-leise); background: rgba(255, 255, 255, .06); }
.feld__auge svg { width: 100%; height: 100%; fill: none; stroke: currentColor;
stroke-width: 1.7; stroke-linecap: round; }
.feld__auge .durch { opacity: 0; transition: opacity var(--tempo); }
.feld__auge[aria-pressed="true"] .durch { opacity: 1; }
.hinweis, .fehler {
margin: 9px 2px 0; font-size: .84rem; min-height: 0;
}
.hinweis { color: var(--text-leise); }
.fehler { color: var(--warn); }
.fehler:empty { margin: 0; }
.knopf__laden {
position: absolute; right: 16px; top: 50%; margin-top: -8px;
width: 16px; height: 16px; border-radius: 50%;
border: 2px solid rgba(255, 255, 255, .35);
border-top-color: #fff;
opacity: 0;
animation: dreh .8s linear infinite;
}
.knopf[disabled] .knopf__laden { opacity: 1; }
@keyframes dreh { to { transform: rotate(360deg); } }
.fuss {
margin: 22px 0 0; padding-top: 16px;
border-top: 1px solid var(--rand);
font-size: .78rem; color: var(--text-still); text-align: center;
}
/* ---------- Übergang beim erfolgreichen Anmelden ---------------------
Die Tafel tritt zurück, das Motiv wird kurz frei - als würde sich das
Tor öffnen. Bewusst kurz und ohne Aufblitzen. */
body.oeffnet .tafel {
opacity: 0; transform: translateY(-8px) scale(.985);
transition: opacity .26s ease, transform .26s ease;
}
body.oeffnet .buehne__schleier { opacity: .35; transition: opacity .26s ease; }
body.oeffnet .buehne__bild { filter: saturate(1) brightness(1); transition: filter .26s ease; }
/* ---------- Tastatur-Bedienung --------------------------------------- */
:where(button, input):focus-visible {
outline: 2px solid var(--akzent);
outline-offset: 2px;
}
/* ---------- Schmale oder hohe Fenster --------------------------------
Sobald das Fenster nicht mehr deutlich breiter als hoch ist, würde die
Tafel den Figuren zu nahe kommen. Dann wechselt die Seite auf das
Hochformat-Motiv und die Tafel rückt nach unten - die beiden bleiben
oben im Bild sichtbar. */
/* Gemeinsam: Tafel wandert nach unten, Motiv bleibt darüber frei. */
@media (max-width: 899px), (max-aspect-ratio: 7/5) {
body.gate { align-items: flex-end; justify-content: center; }
.tafel {
margin: 0 0 max(18px, env(safe-area-inset-bottom));
width: min(520px, calc(100vw - 32px));
}
.tafel__kante { display: none; }
}
/* Schmale Geräte: Hochformat-Ausschnitt. Die Bildfläche endet oberhalb der
Tafel - dadurch liegt ihr Seitenverhältnis nah am Ausschnitt und der
Browser muss seitlich kaum etwas wegschneiden. Beide Figuren bleiben ganz
im Bild, der Verlauf blendet nach unten ins Dunkle. */
@media (max-width: 899px) {
.buehne { bottom: auto; height: 66svh; }
.buehne__bild { object-position: center top; }
.buehne__schleier {
background:
linear-gradient(180deg,
rgba(3, 5, 10, 0.30) 0%,
rgba(3, 5, 10, 0.10) 20%,
rgba(3, 5, 10, 0.22) 46%,
rgba(3, 5, 10, 0.55) 66%,
rgba(5, 7, 13, 0.88) 82%,
/* Muss vor der Unterkante voll deckend sein und exakt der Seitenfarbe
entsprechen - sonst zeichnet sich dort eine feine Kante ab. */
rgba(5, 7, 13, 1.00) 94%);
}
}
/* Breite, aber hohe Fenster (z. B. 1100x980): Querformat bleibt und füllt die
ganze Fläche - sonst entsteht unten eine tote dunkle Zone. Weil hier
seitlich beschnitten wird, rückt das Motiv nach rechts, damit Dogfather und
Hasi Dog vollständig im Bild bleiben. */
@media (min-width: 900px) and (max-aspect-ratio: 7/5) {
.buehne__bild { object-position: 82% center; }
.buehne__schleier {
background:
linear-gradient(180deg,
rgba(3, 5, 10, 0.12) 0%,
rgba(3, 5, 10, 0.20) 34%,
rgba(3, 5, 10, 0.48) 56%,
rgba(3, 5, 10, 0.82) 74%,
rgba(3, 5, 10, 0.95) 90%);
}
}
@media (max-width: 420px) {
.tafel { padding: 22px 18px 20px; border-radius: 16px; }
.rolle__zusatz { display: none; }
}
/* Niedrige Bildschirme (iPhone 13 hat nur 664 px nutzbare Höhe): Die Tafel
würde fast alles verdecken. Sie wird kompakter, und die Bildfläche wird
flacher - dadurch skaliert der Ausschnitt nach BREITE statt nach Höhe und
zeigt genau den oberen Teil mit den Gesichtern. */
@media (max-width: 899px) and (max-height: 760px) {
.buehne { height: 46svh; }
.tafel { padding: 16px 18px 14px; }
.titel { font-size: 1.42rem; margin-bottom: 4px; }
.unterzeile { margin-bottom: 16px; font-size: .88rem; }
/* .72rem = 11,52 px. Vorher .68rem = 10,88 px und damit unter der
Hausuntergrenze von 11,5 px -- gefunden von pruef-handy auf der
Zugangswand von Team Dogi ("DogFather", "Team Dogi"). Das ist die
erste Seite, die jemand aus dem Team ueberhaupt sieht, und sie wird mit
dem Daumen bedient. Dieselbe Hebung wie seinerzeit in heim.css. */
.marke { font-size: .72rem; margin-bottom: 3px; }
.feldschild { margin-bottom: 7px; font-size: .74rem; }
.rollen { margin-bottom: 14px; }
.rolle { padding: 8px 13px; margin-bottom: 6px; }
.rolle__name { font-size: .9rem; }
#code { padding: 11px 44px 11px 14px; }
.knopf { margin-top: 12px; padding: 11px 18px; }
.fuss { margin-top: 14px; padding-top: 10px; font-size: .73rem; }
}
/* ---------- Weniger Bewegung ----------------------------------------- */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: .001ms !important;
animation-iteration-count: 1 !important;
transition-duration: .001ms !important;
}
.buehne__bild { transform: none; transition: none; }
}
/* ===================================================================
Suche über alle Bereiche.
Liegt bewusst hier und nicht in einer Seiten-Datei: kopf.js baut die
Suche auf JEDER Workspace-Seite ein, also muss auch das Aussehen
überall geladen sein. gate.css ist die einzige Datei, die das
erfüllt. (Genau der Fehler, der bei .knopf-still schon einmal
passiert ist -- Baustein in einer Seiten-Datei, prompt fehlte er
woanders.)
=================================================================== */
.suche-knopf__lupe {
width: 15px; height: 15px; flex: none;
fill: none; stroke: currentColor; stroke-width: 1.8;
stroke-linecap: round;
}
@media (max-width: 620px) { .suche-knopf__text { display: none; } }
.suche-schleier {
position: fixed; inset: 0; z-index: 80;
/* flex-start, nicht das voreingestellte stretch -- sonst zieht sich
das Fenster auf volle Hoehe, auch bei zwei Treffern. */
display: flex; justify-content: center; align-items: flex-start;
padding: 9vh 18px 18px;
background: rgba(3, 5, 10, .74);
backdrop-filter: blur(5px);
}
body.suche-offen { overflow: hidden; }
.suche-fenster {
width: min(680px, 100%); max-height: 78vh;
display: flex; flex-direction: column;
background: #0b111b;
border: 1px solid rgba(63, 189, 245, .26);
border-radius: var(--radius);
box-shadow: 0 28px 70px -22px rgba(0, 0, 0, .85);
overflow: hidden;
}
.suche-zeile {
display: flex; align-items: center; gap: 10px;
padding: 14px 16px;
border-bottom: 1px solid var(--rand);
}
.suche-feld {
flex: 1; min-width: 0; padding: 6px 2px;
background: transparent; border: 0;
color: var(--text); font: inherit; font-size: 1.02rem;
}
.suche-feld:focus { outline: none; }
.suche-feld::placeholder { color: var(--text-still); }
/* Das eingebaute Kreuz von type="search" steht sonst direkt neben dem
Esc-Knopf -- zwei Wege, dasselbe zu tun, dicht nebeneinander. */
.suche-feld::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.suche-ergebnis { overflow-y: auto; padding: 6px 10px 12px; }
.suche-hinweis {
margin: 0; padding: 26px 8px; text-align: center;
color: var(--text-still); font-size: .88rem;
}
.suche-gruppe { margin-top: 10px; }
.suche-gruppe__titel {
margin: 0 0 5px; padding: 0 8px;
font-size: .71rem; font-weight: 700;
letter-spacing: .08em; text-transform: uppercase; color: var(--akzent);
}
.suche-treffer {
display: block; padding: 9px 11px; margin-bottom: 3px;
border-radius: var(--radius-klein);
color: var(--text); text-decoration: none;
border: 1px solid transparent;
}
.suche-treffer:hover, .suche-treffer:focus-visible {
background: rgba(255, 255, 255, .05);
border-color: var(--rand);
outline: none;
}
.suche-treffer__titel { display: block; font-size: .92rem; font-weight: 600; }
.suche-treffer__zusatz {
display: block; margin-top: 1px;
font-size: .74rem; color: var(--text-still);
}
.suche-treffer__text {
display: block; margin-top: 3px;
font-size: .81rem; color: var(--text-leise); line-height: 1.45;
}
@media (prefers-reduced-motion: reduce) { .suche-knopf { transition: none; } }
/* ===================================================================
KNOPF-SYSTEM „GESCHLIFFEN“ (von Filipe gewählt, 28.08.2026)
DAS IST DIE EINZIGE STELLE, AN DER KNÖPFE GESTALTET WERDEN.
Vorher standen sie in neun Dateien verstreut -- und prompt sahen
dieselben Knöpfe auf verschiedenen Seiten verschieden aus. Wer einen
neuen Knopf braucht, nimmt hier eine Farbklasse, schreibt kein CSS.
Der Aufbau: ein farbiger Verlaufsrand (padding-box/border-box) und
ein feiner heller Streifen obenauf -- wie eine angeschliffene Kante.
Die Farbe sitzt im Rand und in der Schrift, die Fläche bleibt dunkel.
Beim Zeigen hebt sich der Knopf einen Pixel an und bekommt einen
weichen farbigen Schein darunter.
JEDE AKTION HAT IHRE EIGENE FARBE. Alle Töne sind bewusst gedeckt,
nicht neon: augenschonend ist Vorgabe, nicht Geschmack. Der
schwächste Kontrast im ganzen System liegt bei 9,2:1 -- die
Barrierefreiheits-Schwelle wäre 4,5:1.
=================================================================== */
:root {
--k-gut: #5fc99a; /* passt, erledigt, freigegeben */
--k-mittel: #e8b877; /* ausbaufähig, wartet */
--k-warn: #f0868f; /* Handlungsbedarf, löschen */
--k-gold: #e8c07d; /* Onboarding -- legt eine Person an */
--k-neutral: #8e9cb0; /* abbrechen, schließen */
/* Neutral braucht einen echten Farbwert. Halbdurchsichtiges Weiß
ergab in der Messung 1,1:1 -- praktisch unlesbar. */
}
.knopf,
.knopf-still,
.schritt,
.abmelden,
.stufe-knopf,
.suche-knopf,
.suche-zu,
.todo__weg,
.karte__stift {
--f: var(--akzent);
position: relative;
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
padding: 10px 17px;
border: 1px solid transparent;
border-radius: 11px;
background:
linear-gradient(#121926, #0d1420) padding-box,
linear-gradient(150deg,
color-mix(in srgb, var(--f) 75%, transparent),
rgba(255, 255, 255, .07) 52%,
color-mix(in srgb, var(--f) 30%, transparent)) border-box;
color: color-mix(in srgb, var(--f) 55%, #ffffff);
font: inherit; font-size: .85rem; font-weight: 600;
cursor: pointer;
transition: transform .16s ease, box-shadow .2s ease, color .16s ease;
}
/* Der helle Streifen obenauf -- die „geschliffene“ Kante. */
.knopf::after,
.knopf-still::after,
.schritt::after,
.abmelden::after,
.stufe-knopf::after,
.suche-knopf::after,
.suche-zu::after,
.todo__weg::after,
.karte__stift::after {
content: ""; position: absolute; left: 11px; right: 11px; top: 1px; height: 1px;
border-radius: 1px; pointer-events: none;
background: linear-gradient(90deg, transparent,
color-mix(in srgb, var(--f) 55%, transparent), transparent);
opacity: .75;
}
.knopf:hover,
.knopf-still:hover,
.schritt:hover:not([disabled]),
.abmelden:hover,
.stufe-knopf:hover,
.suche-knopf:hover,
.suche-zu:hover,
.todo__weg:hover,
.karte__stift:hover {
transform: translateY(-1px);
color: #fff;
box-shadow: 0 5px 18px -8px color-mix(in srgb, var(--f) 85%, transparent),
inset 0 0 22px -14px var(--f);
}
.knopf:active, .knopf-still:active, .schritt:active,
.abmelden:active, .stufe-knopf:active { transform: translateY(0); }
.knopf:focus-visible,
.knopf-still:focus-visible,
.schritt:focus-visible,
.abmelden:focus-visible,
.stufe-knopf:focus-visible,
.suche-knopf:focus-visible,
.suche-zu:focus-visible,
.todo__weg:focus-visible,
.karte__stift:focus-visible {
outline: none;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--f) 32%, transparent);
}
/* DER GEDRUECKTE KNOPF BRAUCHT DEN FOKUSRING GENAUSO (Befund 04.09.2026,
Audit).
Gemessen an 961 bedienbaren Elementen: Genau einer aenderte beim
Fokussieren sein Aussehen nicht -- der AKTIVE Filter ("Alle" auf
dateien.html und bereich.html). Wer mit der Tastatur durch die Filter
geht, verliert dort seine Position; der eine Knopf, auf dem man
steht, ist der einzige unsichtbare.
Ursache ist ein Wettstreit der Regeln, kein fehlender Stil:
.schritt:focus-visible -> 0,2,0
.filter .schritt[aria-pressed="true"] -> 0,3,0 (gewinnt)
Die Aktiv-Regel in dateien.css/bereich.css setzt einen eigenen
box-shadow und ueberschreibt damit den Fokusring. Das ist derselbe
Konflikt, der beim Umbau auf "Geschliffen" schon einmal auffiel --
damals fuer den RAND ("Die Filter-Knoepfe hatten eine eigene
gedrueckt-Regel mit flaechiger Farbe, die den geschliffenen Rand
ueberschrieb"). Der Fokus blieb dabei uebersehen.
Die doppelte Klasse (.schritt.schritt) hebt die Spezifitaet auf
0,4,0 -- damit gewinnt diese Regel unabhaengig davon, in welcher
Reihenfolge die Dateien geladen werden. Kein !important: das waere
eine Tuer, die man spaeter nicht mehr zubekommt.
Der Aktiv-Glanz BLEIBT (zweiter Schatten), der Ring kommt darueber --
sonst saehe ein gedrueckter Knopf im Fokus aus wie ein ungedrueckter.
45 % statt 32 %, weil der Ring auf der gefuellten Flaeche sonst
untergeht. */
.schritt.schritt[aria-pressed="true"]:focus-visible,
.schritt.schritt[data-an]:focus-visible,
.stufe-knopf.stufe-knopf[data-aktiv="ja"]:focus-visible {
outline: none;
box-shadow:
0 0 0 3px color-mix(in srgb, var(--f) 45%, transparent),
0 4px 16px -9px var(--f);
}
/* ---------- Gewählt / aktiv ----------------------------------------
Die Fläche nimmt die Farbe auf, der Rand wird voll. Das ist auch der
Auftritt für den wichtigsten Knopf einer Seite. */
.knopf,
.stufe-knopf[data-aktiv="ja"],
[data-an] {
color: #fff;
background:
linear-gradient(color-mix(in srgb, var(--f) 20%, #121926),
color-mix(in srgb, var(--f) 12%, #0d1420)) padding-box,
linear-gradient(150deg, var(--f),
color-mix(in srgb, var(--f) 45%, transparent)) border-box;
box-shadow: 0 4px 16px -9px var(--f);
}
/* ---------- Farbe je Aktion --------------------------------------- */
.knopf--gut, .stufe-knopf[data-wert="ok"] { --f: var(--k-gut); }
.knopf--mittel, .stufe-knopf[data-wert="mittel"] { --f: var(--k-mittel); }
.knopf--warn, .stufe-knopf[data-wert="handlung"],
.knopf-still--warn, .todo__weg { --f: var(--k-warn); }
.knopf--gold { --f: var(--k-gold); }
.knopf--violett { --f: var(--violett); }
.knopf-still, .schritt, .abmelden, .suche-zu,
.karte__stift { --f: var(--k-neutral); }
/* Der Weiter-Knopf der Scout-Pipeline trägt die Farbe seiner Stufe --
bleibt aber bewusst ungefüllt. Er wiederholt sich auf jeder Karte;
als volle Fläche wäre die Seite ein Streifenmuster. */
.knopf--weiter {
--f: var(--stufe-farbe, var(--akzent));
color: color-mix(in srgb, var(--stufe-farbe) 55%, #ffffff);
background:
linear-gradient(#121926, #0d1420) padding-box,
linear-gradient(150deg,
color-mix(in srgb, var(--f) 75%, transparent),
rgba(255, 255, 255, .07) 52%,
color-mix(in srgb, var(--f) 30%, transparent)) border-box;
box-shadow: none;
}
/* ---------- Größen ------------------------------------------------- */
.knopf--klein { padding: 8px 15px; font-size: .82rem; }
.schritt { padding: 6px 12px; font-size: .76rem; border-radius: 9px; }
.abmelden { padding: 8px 15px; font-size: .82rem; }
.suche-zu { padding: 5px 10px; font-size: .74rem; letter-spacing: .04em; border-radius: 9px; }
.suche-knopf { padding: 8px 15px; font-size: .82rem; }
.stufe-knopf { padding: 7px 13px; font-size: .78rem; }
.todo__weg { width: 36px; padding: 0; font-size: 1.05rem; line-height: 1; }
.karte__stift { padding: 4px 10px; font-size: .74rem; border-radius: 8px; }
/* Der Anmeldeknopf ist der einzige, der die ganze Breite bekommt --
auf der Anmeldeseite gibt es nichts anderes zu tun. */
.gate .knopf { width: 100%; margin-top: 18px; padding: 13px 18px; font-size: .95rem; }
/* ---- Der Installieren-Knopf (20.09.2026, hierher am 22.09.2026) ----
Er sieht aus wie die anderen Knöpfe der Kopfleiste -- mit einem
Unterschied: ein leiser Akzentrand. Er ist ein Angebot, keine
Warnung, und er verschwindet, sobald er überflüssig ist. Deshalb
darf er auffallen, ohne zu drängen. */
.install-knopf {
appearance: none;
display: inline-flex; align-items: center; gap: 7px;
min-height: 44px; padding: 0 13px;
border-radius: var(--radius-klein);
border: 1px solid color-mix(in srgb, var(--akzent) 45%, transparent);
background: color-mix(in srgb, var(--akzent) 12%, transparent);
color: var(--text);
font: inherit; font-size: .86rem; font-weight: 600;
cursor: pointer; white-space: nowrap;
transition: background var(--tempo), border-color var(--tempo);
}
.install-knopf:hover {
background: color-mix(in srgb, var(--akzent) 22%, transparent);
border-color: color-mix(in srgb, var(--akzent) 70%, transparent);
}
.install-knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.install-knopf__zeichen {
flex: none; width: 17px; height: 17px;
fill: none; stroke: currentColor; stroke-width: 1.8;
stroke-linecap: round; stroke-linejoin: round;
}
/* AM HANDY NUR DAS ZEICHEN -- ABER NUR IN DER KOPFLEISTE.
Dort ist es eng, und ein Pfeil in eine Ablage wird als
"herunterladen/installieren" verstanden; das Wort kostet 90 px, die
woanders fehlen. Der `aria-label` sagt es weiterhin vollständig.
Auf der Anmeldewand gilt das NICHT: Dort ist Platz, dort kennt
niemand das Zeichen aus dem Zusammenhang, und dort ist der Knopf
ein Angebot an Leute, die die Seite zum ersten Mal sehen. Ein
nacktes Symbol wäre da ein Rätsel.
(Vorher stand die Regel ohne Einschränkung. Das wäre genau der
Fehler gewesen, den sie auf der Leiste vermeidet: eine Entscheidung
aus einem Zusammenhang in einen anderen mitgenommen.) */
@media (max-width: 760px) {
.kopfleiste__rechts .install-knopf__text { display: none; }
.kopfleiste__rechts .install-knopf { padding: 0; width: 44px; justify-content: center; }
}
@media (forced-colors: active) {
.install-knopf { border: 1px solid CanvasText; }
}
/* ---- Auf der Anmeldewand -------------------------------------------
Eine eigene Zeile, mittig, mit Luft nach oben. Der Knopf ist hier
das zweite Anliegen -- wer herkommt, will sich anmelden. */
.gate-install {
display: flex; flex-direction: column; align-items: center;
gap: 10px;
margin: 22px 0 6px;
}
.gate-install:empty { display: none; }
/* Die Erklärung für den Fall ohne Dialogbaustein (iPhone, und überall
dort, wo `nachfrage.js` nicht geladen ist). Sie klappt unter dem
Knopf auf und beim zweiten Antippen wieder zu. */
.install-hinweis {
display: grid; gap: 6px;
max-width: 34rem;
margin: 0;
padding: 13px 15px;
border: 1px solid var(--rand-hell);
border-radius: var(--radius-klein, 12px);
background: color-mix(in srgb, var(--tinte) 88%, #ffffff 12%);
font-size: .86rem; line-height: 1.55;
text-align: left;
}
.install-hinweis__titel { font-size: .92rem; color: var(--text); }
.install-hinweis__weg { color: var(--text); }
.install-hinweis__dazu { color: var(--text-leise); }
@media (forced-colors: active) {
.install-hinweis { border: 1px solid CanvasText; }
}
/* ---------- Filterleiste --------------------------------------------
Eine Reihe von `.schritt`-Knoepfen, von denen genau einer gedrueckt
ist. Stand bis 22.09.2026 doppelt in dateien.css und bereich.css --
Zeichen fuer Zeichen gleich. Als Dogi-Media die dritte Seite wurde,
die sie braucht, waere es die dritte Kopie geworden.
-------------------------------------------------------------------- */
.filter { display: flex; gap: 8px; margin: 0 0 20px; flex-wrap: wrap; }
.filter .schritt[aria-pressed="true"] {
/* Gedrueckt = der "voll"-Auftritt des Knopf-Systems. Vorher stand
hier eine eigene Flaeche, die den geschliffenen Rand ueberschrieb. */
--f: var(--akzent);
color: #fff;
background:
linear-gradient(color-mix(in srgb, var(--f) 20%, #121926),
color-mix(in srgb, var(--f) 12%, #0d1420)) padding-box,
linear-gradient(150deg, var(--f),
color-mix(in srgb, var(--f) 45%, transparent)) border-box;
box-shadow: 0 4px 16px -9px var(--f);
}
.schritt[disabled], .knopf[disabled] { opacity: .45; cursor: default; box-shadow: none; }
.knopf[disabled] { cursor: progress; }
.knopf[disabled]:hover { transform: none; }
.suche-knopf__lupe { width: 15px; height: 15px; flex: none; }
@media (prefers-reduced-motion: reduce) {
.knopf, .knopf-still, .schritt, .abmelden,
.stufe-knopf, .suche-knopf, .suche-zu, .todo__weg,
.karte__stift { transition: none; }
.knopf:hover, .knopf-still:hover, .schritt:hover, .abmelden:hover,
.stufe-knopf:hover, .suche-knopf:hover, .suche-zu:hover,
.todo__weg:hover, .karte__stift:hover { transform: none; }
}
/* ===================================================================
KI-Vorschläge (28.08.2026).
Bewusst ANDERS als die normalen Knöpfe: Ein KI-Knopf tut nichts
Endgültiges, er schlägt vor. Deshalb gestrichelter Rand statt
geschliffener Kante -- man soll auf den ersten Blick sehen, dass hier
etwas Unverbindliches passiert.
Liegt in gate.css, weil drei Seiten ihn benutzen.
=================================================================== */
.ki-knopf {
display: inline-flex; align-items: center; gap: 8px;
padding: 8px 15px; cursor: pointer;
background: rgba(138, 118, 255, .07);
border: 1px dashed rgba(138, 118, 255, .45);
border-radius: 999px;
color: #b6a9ff; font: inherit; font-size: .82rem; font-weight: 600;
transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.ki-knopf:hover:not([disabled]) {
color: #fff;
border-color: rgba(138, 118, 255, .8);
background: rgba(138, 118, 255, .16);
}
.ki-knopf:focus-visible {
outline: none; box-shadow: 0 0 0 3px rgba(138, 118, 255, .3);
}
.ki-knopf[disabled] { cursor: progress; }
.ki-knopf__funke {
width: 15px; height: 15px; flex: none;
fill: currentColor; stroke: none;
}
/* Denkt gerade: der Funke pulst langsam. Zwölf Sekunden ohne
Rückmeldung fühlen sich sonst an wie ein Fehler. */
.ki-knopf[data-denkt="ja"] { border-style: solid; }
.ki-knopf[data-denkt="ja"] .ki-knopf__funke { animation: ki-puls 1.6s ease-in-out infinite; }
@keyframes ki-puls { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
.ki-fehler, .ki-hinweis {
display: block; margin-top: 7px;
font-size: .8rem; color: var(--text-still);
}
.ki-fehler { color: var(--warn); }
.ki-reihe { margin-top: 22px; }
.ki-text {
margin: 10px 0 0; padding: 13px 15px;
background: rgba(138, 118, 255, .06);
border: 1px solid rgba(138, 118, 255, .28);
border-left-width: 3px;
border-radius: var(--radius-klein);
font-size: .9rem; color: var(--text-leise); line-height: 1.6;
max-width: 80ch;
}
.todo-knoepfe { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
@media (prefers-reduced-motion: reduce) {
.ki-knopf { transition: none; }
.ki-knopf[data-denkt="ja"] .ki-knopf__funke { animation: none; opacity: .7; }
}
/* ===================================================================
Auswahlfelder (31.08.2026).
Das echte <select> bleibt im Dokument -- es haelt den Wert und macht
jedes vorhandene `feld.value` weiter richtig. Es wird nur unsichtbar
gemacht; sichtbar ist der Knopf darueber.
Bewusst NICHT display:none: Ein so verstecktes Feld faellt aus der
Formularpruefung des Browsers heraus, und `required` wuerde stumm
nicht mehr greifen.
=================================================================== */
.wahl2 { position: relative; display: block; }
.wahl2__echt {
position: absolute; inset: 0;
opacity: 0; pointer-events: none;
/* Nur ein Pixel gross, damit ein Fehlerhinweis des Browsers noch am
richtigen Ort erscheint. */
width: 1px; height: 1px;
}
.wahl2__knopf {
display: flex; align-items: center; justify-content: space-between; gap: 10px;
width: 100%; padding: 10px 12px; cursor: pointer;
background: linear-gradient(#141c28, #101722);
border: 1px solid var(--rand); border-radius: var(--radius-klein);
color: var(--text); font: inherit; text-align: left;
transition: border-color .16s ease, background .16s ease;
}
.wahl2__knopf:hover:not([disabled]) {
border-color: rgba(255, 255, 255, .24);
background: linear-gradient(#18212f, #141b27);
}
.wahl2__knopf:focus-visible,
.wahl2__knopf[aria-expanded="true"] {
outline: none;
border-color: rgba(63, 189, 245, .65);
box-shadow: 0 0 0 3px rgba(63, 189, 245, .16);
}
.wahl2__knopf[disabled] { opacity: .5; cursor: default; }
.wahl2__knopf[data-leer="ja"] .wahl2__text { color: var(--text-still); }
.wahl2__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wahl2__pfeil {
width: 16px; height: 16px; flex: none;
fill: none; stroke: var(--text-still); stroke-width: 1.8;
stroke-linecap: round; stroke-linejoin: round;
transition: transform .18s ease;
}
.wahl2__knopf[aria-expanded="true"] .wahl2__pfeil { transform: rotate(180deg); }
/* Die Liste haengt am Fenster, nicht am Elternelement -- in einer Karte
mit overflow: hidden waere sie sonst abgeschnitten. */
/* ALS POPOVER GELTEN ANDERE VORGABEN (23.09.2026).
In einem Dialog wird die Liste ueber die Popover-Ebene gezeigt --
sonst laege sie dahinter (Top Layer) oder wuerde vom clip-path der
abgeschraegten Ecke beschnitten. Ein Popover bringt aber eigene
Vorgaben mit: Rahmen, Innenabstand, und "inset: 0" plus "margin:
auto", was ihn in die Bildmitte stellt.
Die drei Zeilen nehmen genau das zurueck. Sie stehen HIER und nicht
als Inline-Stil, weil sie zur Gestaltung der Liste gehoeren und
nicht zu ihrem Verhalten -- und weil eine Regel, die man sieht,
beim naechsten Umbau mitgelesen wird. */
.wahl2__liste:popover-open {
inset: auto; margin: 0; padding: 5px;
border: 1px solid var(--rand, rgba(150, 186, 220, .18));
overflow-y: auto;
}
.wahl2__liste {
position: fixed; z-index: 90;
min-width: 180px; max-width: min(420px, calc(100vw - 24px));
overflow-y: auto; padding: 5px;
/* Am Ende der Liste NICHT weiterrollen: Ohne das gibt der Browser das Scrollen an
die Seite weiter (Scroll-Verkettung), die Seite bewegt sich -- und genau daran
schliesst die Liste zu Recht. Damit waere der Fehler von oben zur Haelfte zurueck. */
overscroll-behavior: contain;
background: #0d1420;
border: 1px solid rgba(63, 189, 245, .3);
border-radius: 11px;
box-shadow: 0 18px 44px -16px rgba(0, 0, 0, .85);
}
.wahl2__gruppe {
margin: 7px 8px 3px; font-size: .68rem; font-weight: 700;
letter-spacing: .08em; text-transform: uppercase; color: var(--akzent);
}
.wahl2__gruppe:first-child { margin-top: 3px; }
.wahl2__eintrag {
/* `flex` UND NICHT `block`. Bis zum 29.09.2026 stand hier
`display: block` und 1050 Zeilen weiter unten noch einmal
`.wahl2__eintrag { display: flex; … }` -- die spaetere gewann,
und wer diese Regel las, glaubte an `block`. Zusammengefuehrt,
damit an einer Stelle steht, wie das Ding gebaut ist.
`align-items` und `gap` stehen unten bei den Personenbildern,
wo sie hingehoeren. */
display: flex; width: 100%; padding: 8px 11px; cursor: pointer;
background: transparent; border: 0; border-radius: 7px;
color: var(--text-leise); font: inherit; font-size: .88rem; text-align: left;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wahl2__eintrag:hover:not([disabled]) { background: rgba(255, 255, 255, .06); color: var(--text); }
.wahl2__eintrag:focus-visible {
outline: none; background: rgba(63, 189, 245, .16); color: #fff;
}
.wahl2__eintrag[data-an="ja"] {
color: #fff; font-weight: 600;
background: rgba(63, 189, 245, .12);
}
.wahl2__eintrag[disabled], .wahl2__eintrag[data-aus="ja"] {
color: var(--text-still); cursor: default;
}
/* ---------- Suchen und selbst eintragen (02.09.2026) --------------------
Das Suchfeld sitzt fest oben in der Liste, die Eintraege scrollen
darunter weg -- sonst waere es beim Scrollen weg, und man wuesste
nicht mehr, wonach gerade gefiltert wird. */
.wahl2__suche {
display: block; width: 100%;
margin: 0 0 5px; padding: 8px 11px;
box-sizing: border-box;
background: rgba(255, 255, 255, .04);
border: 1px solid var(--rand); border-radius: 8px;
color: var(--text); font: inherit; font-size: .88rem;
}
.wahl2__suche::placeholder { color: var(--text-still); }
.wahl2__suche:focus-visible {
outline: none;
border-color: rgba(63, 189, 245, .6);
box-shadow: 0 0 0 3px rgba(63, 189, 245, .14);
}
/* Nur die Eintraege scrollen, nicht das Suchfeld mit. */
.wahl2__zeilen { max-height: min(46vh, 320px); overflow-y: auto; }
/* Der getippte Name als eigener Eintrag. Gedeckt abgesetzt, nicht
grell -- er ist eine Moeglichkeit, keine Warnung. */
.wahl2__eintrag--eigen {
color: #e8c07a;
border: 1px dashed rgba(216, 161, 58, .45);
margin-bottom: 4px;
}
.wahl2__eintrag--eigen:hover:not([disabled]) {
background: rgba(216, 161, 58, .12); color: #f4dcb0;
}
.wahl2__leer {
margin: 0; padding: 9px 11px;
color: var(--text-still); font-size: .82rem;
}
/* Steht ein freier Name im Feld, sagt der Rand es leise mit. */
.wahl2__knopf[data-extern="ja"] {
border-color: color-mix(in srgb, #d8a13a 45%, var(--rand));
}
.wahl2__hinweis {
margin: 6px 0 0;
font-size: .78rem; line-height: 1.45;
color: var(--text-leise);
}
.wahl2__hinweis::before {
content: "↯"; margin-right: 6px; color: #d8a13a;
}
@media (prefers-reduced-motion: reduce) {
.wahl2__knopf, .wahl2__pfeil { transition: none; }
}
@media (forced-colors: active) {
/* Ohne Farben traegt der gestrichelte Rand die Unterscheidung. */
.wahl2__eintrag--eigen { border: 1px dashed CanvasText; }
.wahl2__knopf[data-extern="ja"] { border: 2px solid CanvasText; }
}
/* ===================================================================
Schalter (31.08.2026).
Lag zuerst in wissen.css -- und fehlte prompt auf der Automationen-
Seite, wo er als nacktes Kaestchen erschien. Genau derselbe Fehler
wie damals bei .knopf-still: Ein gemeinsamer Baustein in einer
Seiten-Datei fehlt irgendwann dort, wo die Datei nicht geladen wird.
=================================================================== */
/* ---------- Schalter „besonders wichtig“ ---------------------------------
Ein Kästchen von 17 Pixeln ist auf dem Handy kaum zu treffen und sagt
nicht, was passiert. Der Schalter ist groß, zeigt seinen Zustand und
erklärt sich in einer Zeile. */
.schalter {
display: flex; align-items: flex-start; gap: 14px;
margin-top: 18px; padding: 14px 16px; cursor: pointer;
border: 1px solid var(--rand); border-radius: var(--radius);
background: var(--flaeche);
transition: border-color .18s ease, background .18s ease;
}
.schalter:hover { border-color: rgba(255, 255, 255, .2); }
.schalter input { position: absolute; opacity: 0; width: 0; height: 0; }
.schalter__gleis {
flex: none; position: relative; width: 42px; height: 24px; margin-top: 1px;
border-radius: 999px;
background: rgba(255, 255, 255, .1);
border: 1px solid var(--rand);
transition: background .2s ease, border-color .2s ease;
}
.schalter__punkt {
position: absolute; left: 3px; top: 3px; width: 16px; height: 16px;
border-radius: 50%; background: var(--text-still);
transition: transform .2s ease, background .2s ease;
}
.schalter input:checked + .schalter__gleis {
background: rgba(232, 192, 125, .3);
border-color: rgba(232, 192, 125, .6);
}
.schalter input:checked + .schalter__gleis .schalter__punkt {
transform: translateX(18px); background: #e8c07d;
}
.schalter input:focus-visible + .schalter__gleis {
box-shadow: 0 0 0 3px rgba(232, 192, 125, .28);
}
.schalter:has(input:checked) {
border-color: rgba(232, 192, 125, .35);
background: rgba(232, 192, 125, .05);
}
.schalter__text { display: grid; gap: 2px; font-size: .88rem; }
.schalter__text .leise { font-size: .79rem; }
/* =====================================================================
MATERIAL — die ganze Oberfläche auf einer Sprache (03.09.2026)
Die Kachelzeichen sind Körper geworden. Alles andere war noch flach,
und das fiel dadurch erst richtig auf: ein plastisches Zeichen neben
einem gemalten Knopf sieht nicht nach "teilweise gut" aus, sondern
nach Versehen.
Deshalb gelten ab hier für JEDES Bauteil dieselben drei Regeln --
dieselben, nach denen auch die Zeichen gebaut sind:
1. LICHT VON OBEN. Eine helle Kante an der Oberkante, in der Mitte
am stärksten, nach aussen auslaufend. Echtes Licht auf einer
Kante sieht so aus; eine durchgehend gleich helle Linie ist ein
Strich.
2. TIEFE NACH UNTEN. Ein Schatten, der nach unten versetzt liegt --
wie bei jedem Gegenstand, der auf etwas liegt. Ohne ihn klebt
ein Element auf der Seite, statt darauf zu liegen.
3. VERLAUF STATT FLÄCHE. Oben eine Spur heller als unten. Kaum zu
sehen, aber ohne ihn bleibt jede Fläche tot.
Und eine vierte, die nur für Bedienbares gilt:
4. WAS MAN DRÜCKT, GEHT HINEIN. Beim Klick kehrt sich die Wölbung
um: Licht nach unten, Schatten nach oben. Das ist der
Unterschied zwischen "es passiert etwas" und "ich habe etwas
gedrückt".
Alles bleibt gedeckt. Diese Bauteile stehen zu Dutzenden auf einer
Seite -- was einzeln beeindruckt, blendet im Dutzend.
===================================================================== */
/* ---------- 1. Knöpfe: Körper statt Fläche ---------------------------- */
.knopf, .knopf-still, .schritt, .abmelden,
.stufe-knopf, .suche-knopf, .suche-zu, .todo__weg, .karte__stift {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .09),
inset 0 -2px 5px -3px rgba(0, 0, 0, .6),
0 3px 8px -5px rgba(0, 0, 0, .8);
}
.knopf:hover, .knopf-still:hover, .schritt:hover:not([disabled]),
.abmelden:hover, .stufe-knopf:hover, .suche-knopf:hover,
.suche-zu:hover, .todo__weg:hover, .karte__stift:hover {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .14),
inset 0 -2px 5px -3px rgba(0, 0, 0, .6),
0 8px 20px -9px color-mix(in srgb, var(--f) 85%, transparent),
inset 0 0 22px -14px var(--f);
}
/* Gedrückt: die Wölbung kehrt sich um. */
.knopf:active, .knopf-still:active, .schritt:active:not([disabled]),
.abmelden:active, .stufe-knopf:active, .suche-knopf:active,
.suche-zu:active, .todo__weg:active, .karte__stift:active {
transform: translateY(1px);
box-shadow:
inset 0 2px 6px -2px rgba(0, 0, 0, .75),
inset 0 -1px 0 rgba(255, 255, 255, .07);
}
/* ---------- 2. Eingabefelder: vertieft statt aufgesetzt ---------------- */
.neu input, .neu select, .neu textarea,
.wahl2__knopf, .wahl2__suche, .betreuung__wahl, .code-feld {
box-shadow:
inset 0 2px 5px -3px rgba(0, 0, 0, .75),
inset 0 1px 0 rgba(255, 255, 255, .05);
}
/* Ein Feld, in das man schreibt, ist eine Mulde -- kein Knopf. Deshalb
liegt das Licht hier UNTEN und der Schatten oben: genau umgekehrt. */
.neu input:focus, .neu select:focus, .neu textarea:focus,
.wahl2__suche:focus, .betreuung__wahl:focus {
box-shadow:
inset 0 2px 5px -3px rgba(0, 0, 0, .75),
0 0 0 3px rgba(63, 189, 245, .16);
}
/* ---------- 3. Marken und Zähler: kleine Plaketten --------------------- */
.marke, .marke-still, .marke-rolle, .marke-art, .marke-fehlt,
.stufe__zahl, .gruppe__zahl, .k-chip, .kk__marken > * {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .1),
0 2px 5px -4px rgba(0, 0, 0, .9);
}
/* ---------- 4. Hinweisflächen: Licht auf der Oberkante ----------------- */
.leer-hinweis, .hinweis, .kk__notiz, .call-raum, .code-kasten {
position: relative;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .06),
0 8px 22px -16px rgba(0, 0, 0, .9);
}
.leer-hinweis::after, .call-raum::after, .code-kasten::after {
content: "";
position: absolute; top: 0; left: 18%; right: 18%; height: 1px;
background: linear-gradient(90deg, transparent,
color-mix(in srgb, var(--ton, var(--akzent)) 70%, #fff), transparent);
opacity: .5; pointer-events: none;
}
/* ---------- 5. Überschriften: Gewicht statt Größe ---------------------- */
/* Ein sehr weicher dunkler Schatten unter der Schrift. Er ändert die
Farbe nicht (die Kontrastprüfung misst weiter dasselbe), gibt der
Zeile aber eine Kante gegen den Hintergrund -- Text auf einem Foto
wirkt dadurch aufgelegt statt hineingemischt. */
.titel, .gruppe__name, .stufe__titel, .kk__name, h1, h2 {
text-shadow: 0 1px 2px rgba(0, 0, 0, .55);
}
/* Die kleinen Schilder darüber: mehr Abstand zwischen den Buchstaben,
damit sie als Beschriftung gelesen werden und nicht als Wort. */
.feldschild, .kk__schild, .gruppe__unter {
text-shadow: 0 1px 1px rgba(0, 0, 0, .4);
}
@media (prefers-reduced-motion: reduce) {
.knopf:active, .knopf-still:active, .schritt:active,
.abmelden:active, .stufe-knopf:active { transform: none; }
}
@media (forced-colors: active) {
/* Im Kontrastmodus trägt allein die Kante. Schatten und Lichtsäume
würden dort zu grauen Flecken. */
.knopf, .knopf-still, .schritt, .abmelden, .stufe-knopf,
.marke, .marke-rolle, .leer-hinweis, .hinweis, .code-kasten,
.neu input, .neu select, .neu textarea, .wahl2__knopf { box-shadow: none; }
.leer-hinweis::after, .call-raum::after, .code-kasten::after { display: none; }
.titel, .gruppe__name, h1, h2, .feldschild { text-shadow: none; }
}
/* =====================================================================
DIE KARTE SITZT IN DER TAFEL (06.09.2026)
Wunsch Filipe: "integriere die zugangskachel links nach rechts und
passe sie perfekt an damit sie in dem neuen bild rechts perfekt und
die vorgemachte kachel passt."
Im neuen Motiv steht rechts eine leere Tafel mit Neonrahmen. Die
Anmeldekarte gehoert dort hinein -- und "hinein" heisst hier wirklich
hinein, nicht ungefaehr in die Gegend.
---------------------------------------------------------------------
DAS PROBLEM, DAS MAN LEICHT UEBERSIEHT
Das Bild liegt mit `object-fit: cover` unter der Seite. Je nach
Fensterform schneidet der Browser oben und unten etwas ab -- oder
links und rechts. Ein Wert wie `left: 58 %` bezieht sich aber auf das
FENSTER, nicht auf das Bild. Sobald jemand das Fenster schmaler
zieht, wandert die gemalte Tafel unter der Karte weg, und die Karte
steht daneben. Auf genau einer Bildschirmgroesse saehe es perfekt aus
und ueberall sonst falsch.
Deshalb rechnet `.tafel-anker` die Cover-Geometrie noch einmal nach:
Breite = max(100vw, 100svh * Bildseitenverhaeltnis)
Hoehe = max(100svh, 100vw / Bildseitenverhaeltnis)
Das ist exakt die Formel, nach der auch der Browser das Bild
aufzieht. Der Anker ist damit deckungsgleich mit dem Bild -- und
Prozentwerte darin sind Prozent DES BILDES.
---------------------------------------------------------------------
DIE VIER ZAHLEN SIND GEMESSEN, NICHT GESCHAETZT
tools/gate-bauen.mjs sucht den Rahmen im Quellbild: vom Mittelpunkt
der Tafel nach aussen, bis es hell oder farbig wird. Zwei fruehere
Anlaeufe standen daneben und haben sich selbst verraten -- der erste
fand den Mond und die Spiegelungen, der zweite die halbe Bildhoehe,
weil oberhalb der Tafel alles genauso schwarz ist. Die Begruendung
steht dort im Quelltext.
Wer das Bild austauscht, laesst das Werkzeug neu laufen und traegt
die vier Zeilen hier ein. Sie stehen bewusst als eigene Groessen und
nicht verstreut in den Regeln: So ist es EIN Handgriff.
===================================================================== */
body.gate {
--gate-b: 1647; /* Masse des Quellbildes */
--gate-h: 955;
/* Gemessen von tools/gate-bauen.mjs, danach EINMAL nachjustiert --
und der Grund gehoert dazu, sonst sieht es nach Willkuer aus:
Die Suche laeuft vom Tafelinneren nach aussen und haelt beim ersten
farbigen Punkt an. Der linke Rand des Rahmens glueht im Motiv aber
viel breiter als der rechte (rot gegen duennes Blau) -- sie haelt
links also frueher an. Im Bildschirmfoto bei 1280 px waren es links
44 px Luft und rechts 12: die Karte sass 16 px zu weit rechts, und
genau so sah sie auch aus.
Korrigiert um 1,1 % nach links und 0,7 % nach unten, danach im
Bildschirmfoto bei 1280, 1440 und 1920 nachgesehen. Die Rohwerte
der Messung stehen daneben, damit man den Unterschied sieht.
gemessen hier */
/* 07.09.2026 -- Wunsch Filipe: "so dass der komplette von der kachel
vom hintergrund bild komplett bedeckt ist."
Bis hierher sass die Karte MIT ABSTAND in der Tafel: Der gemalte
Rahmen blieb rundum sichtbar, und dazwischen schimmerte die leere
schwarze Flaeche durch. Das sah aus wie ein Bild in einem Rahmen --
zwei Dinge. Gewollt ist EINS: Die Karte IST die Tafel, ihr Rand
liegt genau auf der Innenkante des Neonrahmens.
Deshalb wird jetzt bis an die Kante gegangen, plus einen halben
Prozentpunkt darueber hinaus: Der Rahmen ist im Bild weich (er
glueht), und eine Karte, die genau an der Messkante endet, laesst
dort einen dunklen Saum stehen. Ein halber Prozentpunkt Ueberlappung
schiebt ihre Kante unter das Glühen -- man sieht nur noch Rahmen und
Karte, nichts dazwischen. */
/* 07.09.2026, ZWEITER ANLAUF -- diesmal GEMESSEN statt nachjustiert.
Der Anlauf davor hat die Werte "um 1,1 % nach links" von Hand
korrigiert, nach Augenschein im Bildschirmfoto. Das Ergebnis war
immer noch falsch, und Filipe hat es sofort gesehen: links stand
ein schwarzer Streifen der gemalten Tafel offen.
Der Grund war die Messung selbst. Sie laeuft vom Tafelinneren nach
aussen und haelt beim ersten FARBIGEN Punkt an -- der linke Rahmen
glueht im Motiv aber viel breiter als der rechte (breites Rot gegen
duennes Blau). Sie hielt links also frueher an, und ich habe den
Fehler mit einer geschaetzten Verschiebung zugedeckt, statt ihn zu
beheben. Eine Korrektur nach Gefuehl auf eine Messung, die man fuer
falsch haelt, ist keine Messung mehr.
Jetzt anders gemessen, und zwar auf das, was man wirklich sucht:
Die vier Neonlinien sind die einzigen Stellen im ganzen Bild, die
KRAEFTIG UND FARBIG zugleich sind (max > 150 und Spanne > 60). Je
Spalte und je Zeile gezaehlt, wie viele Punkte das erfuellen --
die Linien stehen als klare Spitzen heraus, nichts sonst kommt in
die Naehe:
senkrecht 55,37 % (rot) 94,17 % (blau)
waagerecht 13,19 % (rot) 76,96 % (blau)
Die Oberkante brauchte eine zweite Messung: Sie ist dunkelrot und
faellt unter die Neonschwelle. Ueber das Helligkeitsprofil in der
Tafelbreite ist sie trotzdem eindeutig -- 136 gegen 20 daneben.
Die Karte geht 0,4 Prozentpunkte UEBER jede Linie hinaus. Filipe
ausdruecklich: "wenn es leicht groesser ist ist egal aber die
kachel vom hintergrund bild muss bedeckt sein". Die Linien gluehen
weich; endete die Karte genau auf der Messkante, bliebe ein
dunkler Saum. So liegt ihr Rand UNTER dem Leuchten -- man sieht
Rahmen und Karte, nichts dazwischen.
Die Karte reicht BIS AN die Linien, nicht darueber hinaus. Der
Neonrahmen ist das Beste am Bild -- wuerde die Karte ihn ueberdecken,
waere die Tafel zwar bedeckt und die Seite auf einen Schlag
langweilig. Gedeckt werden muss das SCHWARZ dazwischen, und genau
das war offen: 55,37 gemessen, 57,00 eingetragen -- bei einem
1978 px breiten Rahmen sind das 32 px schwarze Flaeche, die links
stehen blieb. Rechts fehlten 0,6 %.
gemessen hier */
--tafel-links: 55.45%; /* 55,37 -- Kante liegt auf dem Licht */
--tafel-oben: 13.15%; /* 13,19 */
--tafel-breite: 38.65%; /* bis 94,10 %, Linie bei 94,17 */
--tafel-hoehe: 63.85%; /* bis 77,00 %, Linie bei 76,96 */
}
/* Vorgabe: Der Anker tut nichts. Er wird erst dort zur Schablone, wo
die Tafel im Bild auch wirklich zu sehen ist (siehe unten). So bleibt
das bisherige Verhalten auf schmalen Geraeten unangetastet. */
.tafel-anker { display: contents; }
/* ---------------------------------------------------------------------
NUR WO DIE TAFEL AUCH HINPASST.
Drei Bedingungen, jede mit Grund:
min-width 1100px darunter ist die Tafel im Ausschnitt zu schmal
min-height 620px darunter muesste die Karte unter 12 px schrumpfen
min-aspect 7/5 bei hohen Fenstern schneidet cover die Tafel an
Trifft eine nicht zu, gilt weiter die alte Anordnung (Karte unten
mittig, Hochformat-Motiv). Lieber eine ehrliche zweite Anordnung als
eine erzwungene erste, die niemand mehr lesen kann.
--------------------------------------------------------------------- */
@media (min-width: 1100px) and (min-height: 620px) and (min-aspect-ratio: 7/5) {
body.gate { align-items: flex-start; }
.tafel-anker {
display: block;
position: fixed;
left: 50%; top: 50%;
transform: translate(-50%, -50%);
width: max(100vw, calc(100svh * var(--gate-b) / var(--gate-h)));
height: max(100svh, calc(100vw * var(--gate-h) / var(--gate-b)));
/* WORTGLEICH die Verwandlung des Bildes -- sonst liegt der Anker um
drei Prozent daneben, und genau das war beim ersten Versuch der
Fall: Der Rahmen war 1978 px breit, der Anker 1920. */
transform: translate(-50%, -50%) scale(1.03)
translate3d(var(--parallax-x, 0px), var(--parallax-y, 0px), 0);
z-index: 1;
/* Der Anker selbst ist nur eine Schablone -- Klicks gehen durch ihn
hindurch, sonst laege eine unsichtbare Flaeche ueber dem ganzen
Bild. */
pointer-events: none;
/* Damit die Karte ihre Schriftgroesse an der HOEHE der Tafel
ausrichten kann (cqh weiter unten). */
container-type: size;
}
.tafel {
position: absolute;
pointer-events: auto;
left: var(--tafel-links);
width: var(--tafel-breite);
/* DIE KARTE IST DIE TAFEL, nicht ein Kaestchen darin. Sie nimmt
deren Rechteck ein und zentriert ihren Inhalt darin.
Der erste Versuch setzte `top: Mitte` und `translateY(-50%)` --
und die Karte hing 300 px unter dem Bildschirmrand. Grund: Auf
`.tafel` liegt die Einblend-Animation `auftauchen`, deren
Endbild `transform: none` ist. Eine Animation mit `both` gewinnt
gegen die Regel; mein translateY war damit wirkungslos. Zwei
Wege, dasselbe Element zu verschieben, vertragen sich nicht --
also gar keine Verschiebung, sondern ein Kasten mit Hoehe. */
top: var(--tafel-oben);
height: var(--tafel-hoehe);
display: flex; flex-direction: column; justify-content: center;
margin: 0;
/* ALLES SKALIERT MIT DER TAFEL.
1 cqh ist ein Prozent der Ankerhoehe -- also des BILDES. Wird das
Fenster kleiner, wird die Tafel kleiner, und die Karte darin
genauso. Nach unten bei 12 px abgefangen: Darunter ist es keine
Anmeldemaske mehr, sondern ein Bild von einer. */
/* 1,50 statt 1,59: Bei 1280x800 ist die Tafel 512 px hoch, der
Karteninhalt bei 1,59 aber 536 -- gemessen, nicht geschaetzt.
24 px Ueberstand sieht man an einem Neonrahmen sofort. */
/* NACHGEMESSEN, WEIL EINE ROLLE DAZUKAM (07.09.2026).
Der Kommentar darueber warnt woertlich davor -- und ich habe
genau das gemacht, wovor er warnt: eine fuenfte Rolle eingefuegt
und die Zahl daneben nicht angefasst. Gemessen bei fuenf Rollen:
Der Inhalt war bei 1280x800 573 px hoch in einer 526 px hohen
Tafel, bei 1600x1000 712 in 658 -- die Fusszeile stand jedes Mal
unter dem Rahmen.
Die Schrift kleiner zu machen half nicht: Bei 1280 lag sie mit
12 px schon auf dem unteren Anschlag. Also sind die ABSTAENDE
enger geworden -- an neun Stellen ein bis zwei Zehntel, das
ergibt zusammen rund 4 em. Die Schrift bleibt lesbar, die Karte
passt wieder.
Wer eine SECHSTE Rolle einbaut, misst hier neu. Die Zahl gehoert
zu dem, was sie zaehlt. */
font-size: clamp(12px, 1.42cqh, 15.5px);
padding: 1.35em 1.5em 1.05em;
/* Die Tafel im Bild ist schon dunkel und hat ihren eigenen Rahmen.
Die Karte legt sich deshalb NUR noch als leichter Schleier
darueber, statt einen zweiten Kasten mit zweitem Rand zu bauen --
zwei Rahmen ineinander saehen nach Versehen aus. */
background: rgba(6, 9, 16, .58);
border-color: rgba(150, 186, 220, .10);
box-shadow: none;
backdrop-filter: blur(9px) saturate(112%);
-webkit-backdrop-filter: blur(9px) saturate(112%);
}
/* Die Lichtkante entfaellt -- der Neonrahmen des Bildes macht das
bereits, und zwar besser. */
.tafel__kante { display: none; }
/* ---- Alles Innere in em, damit es mitskaliert ----------------------
Die Karte traegt eine eigene Schriftgroesse; rem wuerde sich
weiterhin am Dokument orientieren und die Abstaende blieben stehen,
waehrend die Schrift schrumpft. Genau daran erkennt man eine
schlecht skalierte Oberflaeche. */
.tafel .marke { font-size: .78em; margin-bottom: .35em; }
.tafel .titel { font-size: 1.78em; margin-bottom: .22em; }
.tafel .unterzeile { font-size: .9em; margin-bottom: .85em; }
.tafel .feldschild { font-size: .76em; margin-bottom: .45em; }
.tafel .rollen { margin-bottom: .8em; }
.tafel .rolle { padding: .50em .8em; margin-bottom: .30em; gap: .75em; }
.tafel .rolle__zeichen { width: 1.32em; height: 1.32em; }
.tafel .rolle__name { font-size: .94em; }
.tafel .rolle__zusatz { font-size: .79em; }
.tafel #code { padding: .72em 2.7em .72em .9em; }
.tafel .feld__auge { width: 2.2em; height: 2.2em; padding: .5em; right: .35em; }
.tafel .knopf { margin-top: .6em; padding: .62em 1.1em; font-size: .88em; width: 100%; }
.tafel .hinweis,
.tafel .fehler { font-size: .82em; margin-top: .5em; }
.tafel .fuss { margin-top: .75em; padding-top: .6em; font-size: .76em; }
/* ---- Der Schleier ------------------------------------------------
Er verlief bisher von links dunkel nach rechts klar -- dort stand
die Karte. Jetzt ist es andersherum, und beide Seiten haben eine
Aufgabe: links das Logo (soll leuchten), rechts die Tafel (soll
ruhig sein). Also nur noch ein sanftes Abdunkeln ueber allem, etwas
mehr auf der rechten Haelfte, und ein Hauch Vignette. Kein harter
Verlauf mehr -- der haette quer durch das Motiv geschnitten. */
.buehne__schleier {
background:
linear-gradient(96deg,
rgba(3, 5, 10, 0.30) 0%,
rgba(3, 5, 10, 0.20) 30%,
rgba(3, 5, 10, 0.16) 48%,
rgba(3, 5, 10, 0.26) 66%,
rgba(3, 5, 10, 0.34) 100%),
radial-gradient(130% 100% at 50% 120%, rgba(0, 0, 0, .34), transparent 62%);
}
/* Das Motiv darf heller bleiben: Die Karte bringt jetzt ihren eigenen
Untergrund mit, und das Bild ist der Grund, warum die Seite gut
aussieht. */
.buehne__bild { filter: saturate(1) brightness(.97); }
}
/* Sehr breite Schirme: Die Tafel waechst mit dem Bild, die Schrift ist
aber bei 16 px gedeckelt. Damit die Karte darin nicht verloren wirkt,
bekommt sie dort etwas mehr Innenabstand. */
@media (min-width: 1700px) and (min-height: 900px) {
.tafel { padding: 2.2em 2em 1.8em; }
}
/* Dieselbe Koernung wie auf der Startseite -- sie steht dort in
start.css, und die Anmeldeseite laedt start.css nicht. Ein SVG-
Filter als Adresse: keine Datei, keine zusaetzliche Anfrage. */
:root {
--koernung:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='r'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23r)' opacity='0.55'/%3E%3C/svg%3E");
}
/* =====================================================================
DIE KARTE ALS BILDSCHIRM IM RAHMEN (07.09.2026)
Wunsch Filipe: "veränder auch die kachel. mach sie viel geiler und
viel krasser. mit allen infos die da sind aber mach sie richtig hoch
profissionel, hochwertig und ultra geil aber so dass der komplette von
der kachel vom hintergrund bild komplett bedeckt ist."
---------------------------------------------------------------------
DIE IDEE
Im Motiv steht ein leerer Rahmen mit Neonkante -- rot oben links,
blau unten rechts. Bisher lag darin eine Karte mit eigenem Rand: zwei
Rahmen ineinander, und dazwischen schwarze Leere. Das liest sich als
"Bild an einer Wand".
Gewollt ist ein GERÄT: Der Rahmen im Bild ist das Gehäuse, die Karte
ist der eingeschaltete Bildschirm darin. Ein Bildschirm hat drei
Eigenschaften, die ein Kasten nicht hat, und alle drei sind hier
gebaut:
1. ER LEUCHTET VON INNEN. Nicht gleichmäßig -- oben mehr, weil dort
die Anzeige beginnt. Ein schwacher Schein in der Rahmenfarbe
kriecht von den Kanten herein, so wie Licht aus einem Panel in
sein Gehäuse fällt.
2. ER HAT EINE SCHEIBE. Über allem liegt eine sehr schwache,
diagonale Spiegelung -- die Glasscheibe davor. Sie ist der
Unterschied zwischen "Fläche mit Farbe" und "etwas hinter Glas".
3. ER HAT STRUKTUR. Dieselbe Körnung wie die Kacheln der Startseite
(siehe start.css). Ohne sie bleibt jeder Verlauf zu glatt für
eine echte Oberfläche.
Die Rollen-Knöpfe werden dabei zu TASTEN: Materialstärke oben hell,
unten dunkel, beim Drücken sinken sie ein. Die gewählte Taste ist
nicht nur eingefärbt, sondern beleuchtet -- sie hat einen Lichtrand
nach innen, als läge eine Diode darunter.
---------------------------------------------------------------------
WAS DABEI NICHT VERLOREN GEHT
Alle Angaben bleiben, wie sie waren: die vier Rollen mit ihren
Beschreibungen, das Codefeld mit dem Auge, der Hinweis, welche Rolle
gewählt ist, und die Fußzeile zur Verschlüsselung. "Hochwertiger"
heißt hier nicht "weniger drin" -- eine Anmeldemaske, die etwas
verschweigt, ist keine bessere, sondern eine unvollständige.
===================================================================== */
@media (min-width: 1100px) and (min-height: 620px) and (min-aspect-ratio: 7/5) {
.tafel {
/* KEIN EIGENER RAHMEN MEHR. Das Gehäuse ist im Bild; ein zweiter
Rand daneben wäre genau der Doppelrahmen, der weg soll. Was
bleibt, ist eine hauchfeine Innenkante -- die Fuge zwischen
Scheibe und Gehäuse. */
border: 0;
border-radius: 22px;
/* DER WEICHZEICHNER MUSSTE WEG (07.09.2026, abends).
Hier stand `backdrop-filter: blur(26px)`, und das war der Grund,
warum die Karte im Bildschirmfoto GRAU aussah statt tief.
Ein Weichzeichner mittelt nicht nur, was HINTER dem Element liegt
-- er zieht seinen Radius weit über dessen Kanten hinaus in die
Umgebung. Hinter der Tafel ist zwar Schwarz, direkt daneben aber
die hellste Stelle des ganzen Motivs: der rote und der blaue
Neonstrich. 26 px Radius holen genau die herein und rechnen sie
zu einem gleichmäßigen Grau. Je schöner der Rahmen, desto grauer
die Karte -- man baut sich das Problem mit dem Schmuckstück
selbst.
Jetzt ist die Karte eine eigene, fast deckende Scheibe (93 %) und
holt sich die Rahmenfarben ABSICHTLICH herein, an denselben
Ecken, an denen sie im Bild sitzen -- kräftiger als vorher, weil
sie jetzt gegen Schwarz und nicht gegen Grau arbeiten. */
background:
/* Der Schein von den Kanten herein, in den Farben des Rahmens:
rot oben links, blau unten rechts. Er ist das, was die Karte
mit dem Bild verbindet, statt sie davorzusetzen. */
radial-gradient(135% 100% at 0% 0%, rgba(232, 62, 62, .26), transparent 55%),
radial-gradient(135% 100% at 100% 100%, rgba(56, 158, 246, .30), transparent 58%),
/* Die Anzeige selbst: oben eine Spur heller, unten fast schwarz. */
linear-gradient(176deg,
rgba(16, 23, 36, .93) 0%,
rgba(9, 13, 21, .95) 46%,
rgba(5, 7, 13, .96) 100%);
backdrop-filter: none;
-webkit-backdrop-filter: none;
box-shadow:
/* Die Fuge: innen ein feiner heller Strich oben, dunkel unten. */
inset 0 1px 0 rgba(255, 255, 255, .11),
inset 0 -1px 0 rgba(0, 0, 0, .5),
/* Die beiden Rahmenfarben laufen als hauchdünner Saum INNEN an
den Kanten weiter -- der Übergang vom Gehäuse zur Scheibe. */
inset 2px 2px 0 -1px rgba(232, 62, 62, .34),
inset -2px -2px 0 -1px rgba(56, 158, 246, .38),
/* Und ein sehr weicher Schein nach innen, damit die Kante nicht
hart abbricht, sondern ins Gehäuse übergeht. */
inset 0 0 54px -20px rgba(0, 0, 0, .92);
overflow: hidden;
}
/* DIE SCHEIBE. Ein einziger, sehr weicher Streifen von links oben --
kaum zu sehen, aber ohne ihn wirkt die Fläche wie Papier. */
.tafel::after {
content: ""; position: absolute; inset: 0; z-index: 0;
pointer-events: none; border-radius: inherit;
background:
linear-gradient(122deg,
rgba(255, 255, 255, .075) 0%,
rgba(255, 255, 255, .020) 14%,
rgba(255, 255, 255, 0) 32%);
opacity: .9;
}
/* DIE KÖRNUNG BRAUCHT EINE EIGENE EBENE (07.09.2026, abends).
Sie stand als zweite Schicht in der Spiegelung oben -- mit deren
Deckkraft von 90 % und ohne Mischmodus. Die Körnung ist aber ein
mittelgraues Rauschen: 90 % davon über der Karte heben JEDEN
Bildpunkt um rund 30 Stufen an. Gemessen im Bildschirmfoto:
rgb(46, 57, 64) statt der berechneten rgb(15, 22, 34). Die Karte
war deshalb grau, egal wie tief der Verlauf darunter eingestellt
war -- ich habe zweimal an der falschen Zahl gedreht.
Auf der Startseite steht dieselbe Körnung richtig: 3,5 % und
`mix-blend-mode: overlay`, also "hell machen, wo es hell ist,
dunkel, wo es dunkel ist". Genau das hier auch.
Als Träger dient `.tafel__kante` -- das Element gibt es im HTML
bereits, es war in dieser Ansicht nur abgeschaltet. Ein weiteres
Pseudo-Element gibt es nicht: `::before` und `::after` sind
vergeben. */
.tafel__kante {
display: block;
position: absolute; inset: 0; z-index: 0;
pointer-events: none; border-radius: inherit;
background-image: var(--koernung);
background-size: 140px 140px;
opacity: .04;
mix-blend-mode: overlay;
}
/* Der Inhalt liegt über der Scheibe -- Schrift durch eine Spiegelung
zu lesen wäre anstrengend. */
.tafel > * { position: relative; z-index: 1; }
/* ---- Die Rollen als Tasten in einer Leuchtschiene ------------------
DIESELBE SPRACHE WIE DIE KACHELN DER STARTSEITE (07.09.2026).
Auf der Startseite steckt jede Kachel in einer Schiene, die in der
Farbe ihrer Kategorie leuchtet. Hier passiert dasselbe mit den
Rollen -- und das ist mehr als eine Wiederholung: Wer sich als
Manager anmeldet, sieht dabei schon das Gold, in dem ihm gleich
seine Kacheln begegnen. Zwei Bildschirme, eine Sprache.
Vier Farben, aus dem Knopfsystem oben (--k-*), nicht neu erfunden:
DogFather Gold -- Krone
Manager Bernstein -- Stern
Scout Grün -- Schild
Creator Blau -- Person
Alle gedeckt, keine davon neon: augenschonend bleibt Vorgabe. */
/* Spicy Media traegt das Rot der Marke -- dieselbe Farbe wie ihr Name
im Kopf der Karte darueber. */
/* EINE ZWEITE VARIABLE, DIE ICH UEBERSEHEN HATTE (08.09.2026).
Beim Umstellen auf die zentralen Rollenfarben habe ich `--rf`
erwischt, aber nicht `--rton` -- und DIESE hier faerbt die
GEWAEHLTE Rolle in der Tafel. Ergebnis auf Filipes Bildschirmfoto:
DogFather und Manager leuchteten goldbraun, weil `--k-gold` und
`--k-mittel` stehen geblieben waren. Zwei Variablen fuer dieselbe
Sache, und nur eine umgestellt -- dieselbe Sorte Fehler wie die
doppelte Groessenangabe beim Wasserzeichen.
Jetzt kommen beide aus derselben Quelle. Wer eine Rollenfarbe
aendert, aendert damit auch die Tafel. */
.tafel .rolle[data-rolle="spicy"] { --rton: var(--spicy-haupt); }
.tafel .rolle[data-rolle="admin"] { --rton: var(--dogi-haupt); }
.tafel .rolle[data-rolle="manager"] { --rton: var(--manager-haupt); }
.tafel .rolle[data-rolle="scout"] { --rton: var(--scout-haupt); }
.tafel .rolle[data-rolle="creator"] { --rton: var(--creator-haupt); }
/* SEIT screen20 SIND ES FELDER IN EINEM KOERPER, KEINE FUENF KARTEN.
Filipe: "ich will dass die rollen auch alle in einer grossen
kacheln sind." Vorher hatte jede Rolle einen eigenen Rand, eigene
runde Ecken und 8 px Luft zur naechsten -- das las sich als fuenf
Dinge, die zufaellig untereinander stehen. Es ist aber EINE Frage
mit fuenf Antworten.
WAS BLEIBT, IST DIE SCHIENE. Sie war und ist das Beste an diesem
Entwurf: Wer sich als Manager anmeldet, sieht schon hier das Lila,
in dem ihm gleich seine Kacheln begegnen. Sie sitzt jetzt buendig
an der Innenkante der Kachel statt am Rand einer eigenen Karte --
dieselbe Wirkung, ein Koerper weniger.
WAS GEHT, SIND RAND UND RUNDUNG. An ihre Stelle tritt die dunkle
Fuge nach unten. Ein Spalt, durch den der Untergrund scheint,
trennt; eine dunkle Fuge verbindet, weil sie zum selben Koerper
gehoert. */
.tafel .rolle {
position: relative;
overflow: hidden;
border-radius: 0;
background:
linear-gradient(90deg,
color-mix(in srgb, var(--rton, var(--akzent)) 20%, transparent) 0%,
color-mix(in srgb, var(--rton, var(--akzent)) 6%, transparent) 22%,
transparent 58%),
linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .012));
border: 0;
border-bottom: 1px solid #05070c;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
0 1px 0 rgba(255, 255, 255, .035);
transition: background var(--tempo), box-shadow var(--tempo);
}
.tafel .rolle:last-child { border-bottom: 0; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07); }
/* Die Schiene selbst. */
.tafel .rolle::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
background: linear-gradient(180deg,
color-mix(in srgb, var(--rton, var(--akzent)) 55%, #fff) 0%,
var(--rton, var(--akzent)) 34%,
color-mix(in srgb, var(--rton, var(--akzent)) 55%, transparent) 100%);
box-shadow: 2px 0 14px -3px color-mix(in srgb, var(--rton, var(--akzent)) 55%, transparent);
opacity: .72;
transition: opacity var(--tempo), box-shadow var(--tempo);
}
.tafel .rolle:hover {
background:
linear-gradient(90deg,
color-mix(in srgb, var(--rton, var(--akzent)) 26%, transparent) 0%,
color-mix(in srgb, var(--rton, var(--akzent)) 8%, transparent) 24%,
transparent 60%),
linear-gradient(180deg, rgba(255, 255, 255, .085), rgba(255, 255, 255, .022));
}
.tafel .rolle:hover::before { opacity: 1; }
/* Beim Drücken sinkt die Taste ein: Der Schatten unter ihr
verschwindet, der innere kommt von oben. Genau das macht ein
echter Knopf. */
/* GEDRUECKT SINKT DAS FELD EIN -- ohne sich zu VERSCHIEBEN.
Hier stand `transform: translateY(1px)`. Bei fuenf einzelnen Karten
war das richtig: eine Taste, die nachgibt. In einem geschlossenen
Koerper ist es falsch -- ein Feld, das sich um einen Pixel aus der
Kachel herausschiebt, reisst die Fuge auf und sieht nach einem
Fehler aus. Der eingelassene Schatten allein sagt dasselbe. */
.tafel .rolle:active {
box-shadow: inset 0 2px 5px rgba(0, 0, 0, .55);
}
/* DIE GEWÄHLTE TASTE IST BELEUCHTET, nicht nur eingefärbt. Der
Lichtrand nach innen liest sich wie eine Diode darunter -- und er
sagt deutlicher als jede Farbe, welche gerade aktiv ist. */
.tafel .rolle[aria-checked="true"] {
background:
linear-gradient(90deg,
color-mix(in srgb, var(--rton, var(--akzent)) 42%, transparent) 0%,
color-mix(in srgb, var(--rton, var(--akzent)) 16%, transparent) 34%,
color-mix(in srgb, var(--rton, var(--akzent)) 5%, transparent) 72%),
linear-gradient(180deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, .02));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .18),
inset 0 0 24px -9px color-mix(in srgb, var(--rton, var(--akzent)) 92%, transparent),
0 0 24px -11px color-mix(in srgb, var(--rton, var(--akzent)) 78%, transparent);
}
/* Die Schiene der gewählten Rolle brennt voll -- das ist die
deutlichste Anzeige, die es gibt, und sie kommt ohne ein weiteres
Zeichen aus. */
.tafel .rolle[aria-checked="true"]::before {
opacity: 1;
width: 4px;
box-shadow: 4px 0 26px -3px color-mix(in srgb, var(--rton, var(--akzent)) 78%, transparent);
}
/* ---- Das Codefeld: eine eingelassene Rinne ------------------------- */
.tafel #code {
background: rgba(0, 0, 0, .34);
border-color: rgba(150, 186, 220, .14);
border-radius: 12px;
/* Eingelassen statt aufgesetzt: Schatten von oben INNEN. Das ist
dasselbe Licht wie überall, nur eine Vertiefung statt einer
Erhebung -- und deshalb erkennt man sofort, dass man hier
hineinschreibt. */
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .7),
inset 0 -1px 0 rgba(255, 255, 255, .05);
}
.tafel #code:focus {
background: rgba(0, 0, 0, .28);
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .7),
0 0 0 3px color-mix(in srgb, var(--akzent) 22%, transparent);
}
/* ---- Der Anmelde-Knopf: die Haupttaste ----------------------------- */
.tafel .knopf {
border-radius: 12px;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .14),
inset 0 -1px 0 rgba(0, 0, 0, .35),
0 6px 18px -10px color-mix(in srgb, var(--akzent) 85%, transparent);
}
.tafel .knopf:active { transform: translateY(1px); }
/* ---- Der Kopf bekommt Luft nach unten ------------------------------ */
/* Eine feine Trennlinie unter dem Titel: Sie gliedert die Karte in
"wer sind wir" und "was tust du hier", ohne ein Wort dafür zu
brauchen. */
.tafel .unterzeile {
padding-bottom: 1em;
border-bottom: 1px solid rgba(150, 186, 220, .10);
margin-bottom: 1.1em;
}
@media (prefers-reduced-motion: reduce) {
.tafel .rolle:active, .tafel .knopf:active { transform: none; }
}
}
/* Auf schmalen Geräten liegt die Karte VOR dem Bild statt darin -- dort
bleibt der eigene Rahmen richtig, denn es gibt kein Gehäuse, in das
sie sich einfügen könnte. Nur Körnung und Tastenwirkung übernimmt sie:
Die gehören zum Material, nicht zur Anordnung. */
@media (max-width: 1099px), (max-height: 619px), (max-aspect-ratio: 7/5) {
.tafel .rolle:active { transform: translateY(1px); }
.tafel .rolle[aria-checked="true"] {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .14),
inset 0 0 18px -8px color-mix(in srgb, var(--akzent) 85%, transparent);
}
}
/* =====================================================================
DER TEILEN-KNOPF (07.09.2026)
Er sitzt links in der rechten Knopfgruppe und sieht aus wie ihre
Nachbarn -- dieselbe Höhe, derselbe geschliffene Rand, dieselbe
Schrift. Ein Knopf, der aus der Reihe tanzt, sagt "nachträglich
eingebaut", und genau das soll er nicht sagen.
Der einzige Unterschied ist die Farbe: --f wird auf Violett gesetzt.
Alle anderen Knöpfe der Leiste tragen den Hausakzent; ein zweiter
Ton macht diesen einen auffindbar, ohne ihn lauter zu machen.
BEIM GELINGEN WECHSELT DER TEXT, NICHT DIE FARBE ALLEIN. "Kopiert"
steht als Wort da -- eine Rückmeldung, die nur aus einem Farbwechsel
besteht, kommt bei niemandem an, der Farben schlecht unterscheidet.
===================================================================== */
.teilen {
--f: var(--violett);
position: relative;
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
min-height: 38px; padding: 8px 14px;
border: 1px solid transparent;
border-radius: 11px;
background:
linear-gradient(#121926, #0d1420) padding-box,
linear-gradient(150deg,
color-mix(in srgb, var(--f) 70%, transparent),
rgba(255, 255, 255, .07) 52%,
color-mix(in srgb, var(--f) 28%, transparent)) border-box;
color: color-mix(in srgb, var(--f) 45%, #ffffff);
font: inherit; font-size: .85rem; font-weight: 600;
cursor: pointer;
transition: transform .16s ease, box-shadow .2s ease, color .16s ease;
}
.teilen:hover {
color: #fff;
transform: translateY(-1px);
box-shadow: 0 8px 20px -12px color-mix(in srgb, var(--f) 85%, transparent);
}
.teilen:active { transform: translateY(0); }
.teilen:focus-visible { outline: 2px solid var(--f); outline-offset: 2px; }
/* Geschafft: der Rand wird grün, das Wort sagt es zusätzlich. */
.teilen[data-fertig="ja"] {
--f: var(--k-gut);
color: color-mix(in srgb, var(--k-gut) 40%, #ffffff);
}
.teilen__zeichen {
width: 16px; height: 16px; flex: none;
fill: none; stroke: currentColor;
stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}
@media (max-width: 720px) {
/* Auf schmalen Geräten nur das Zeichen. Die Kopfleiste ist am
06.09.2026 schon einmal an einem Element zu viel zerbrochen --
dieser Knopf kommt deshalb von vornherein mit 38 px aus, statt
eine feste Umbruchschwelle noch einmal zu verschieben. */
.teilen { padding: 8px 10px; }
.teilen__text {
position: absolute;
width: 1px; height: 1px; margin: -1px; padding: 0;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
}
@media (prefers-reduced-motion: reduce) {
.teilen, .teilen:hover, .teilen:active { transform: none; }
}
@media (forced-colors: active) {
.teilen { border: 1px solid ButtonText; background: ButtonFace; color: ButtonText; }
}
/* =====================================================================
„SpicyMedia × DogFather" im Kopf der Anmeldekarte (07.09.2026)
Zwei Marken und ein Zeichen dazwischen. Drei gleich laute Wörter
nebeneinander liest niemand als Paar -- das Kreuz muss kleiner und
leiser sein als die Namen, sonst wird aus einer Kooperation eine
Aufzählung.
Das Zeichen ist ein echtes Multiplikationszeichen (×, U+00D7), kein
kleines x: Das x einer Schrift steht auf der Grundlinie und sitzt
dadurch optisch zu tief zwischen zwei Versalien.
Die Farben nehmen die beiden Seiten des Neonrahmens auf, in dem die
Karte steckt: Spicy Media rot, DogFather blau. Beide gedeckt und
gegen den dunklen Grund gemessen -- augenschonend bleibt Vorgabe.
===================================================================== */
.marke--paar {
display: flex; align-items: baseline; gap: .42em;
flex-wrap: wrap;
}
/* KRAEFTIGER (07.09.2026, Wunsch Filipe: "spicy x dogfather sieht man
nicht richtig"). Die beiden Namen standen in gedeckten Toenen auf der
hellsten Stelle der Karte -- dort, wo der rote Schein von oben links
hereinkommt. Gedeckt ist auf dunklem Grund richtig und auf hellem zu
wenig. Jetzt heller, etwas groesser und mit einem eigenen Schatten,
der sie vom Untergrund abhebt statt sie zu ueberstrahlen. */
.marke--paar { letter-spacing: .13em; }
.marke--paar .marke__spicy {
color: #ffb3b9;
text-shadow: 0 1px 10px rgba(255, 95, 109, .45);
}
.marke--paar .marke__dogi {
color: #a9dcff;
text-shadow: 0 1px 10px rgba(99, 184, 238, .45);
}
/* TEAM DOGI (10.09.2026, nur auf der zweiten Zugangswand).
Bewusst NICHT .marke__spicy mitbenutzt, obwohl es dieselbe Stelle im
Satz ist: Die Klasse ist rosarot, weil dort "SpicyMedia" steht. Auf
dieser Seite waere das der einzige warme Fleck auf einer durchweg
blauen Seite -- und er saesse ausgerechnet auf dem Namen, der dort
NICHT hingehoert.
Silbrig wie der Schriftzug im Hintergrundbild, damit beide dasselbe
sagen. */
.marke--paar .marke__crew {
color: #dce9f3;
text-shadow: 0 1px 10px rgba(150, 190, 220, .45);
}
.marke--paar .marke__x {
/* Kleiner, leiser, und mit etwas Luft -- es verbindet, es benennt
nicht. */
font-size: .82em;
font-weight: 500;
color: var(--text-still);
transform: translateY(-.02em);
}
/* =====================================================================
DAS GESICHT IN DER PERSONENAUSWAHL (07.09.2026)
Wunsch Filipe: "jeder soll auch immer das profilbild von denen sehen
mit denen sie verbunden sind."
Ein rundes Bild in einer Auswahlliste ist der billigste und stärkste
Zugewinn, den eine solche Liste haben kann: Man trifft den richtigen
Namen, ohne ihn zu lesen. Und wer kein Bild hat, bekommt seinen
Anfangsbuchstaben -- kein leerer Kreis, kein Platzhaltersymbol.
Der Buchstabe bleibt beim Laden des Bildes LIEGEN und wird nicht
ersetzt. Lädt das Bild nicht (Verbindung weg, Datei gelöscht), steht
dort weiterhin etwas Sinnvolles statt eines zerbrochenen Bildsymbols.
===================================================================== */
.wahl2__bild {
position: relative;
flex: none;
width: 26px; height: 26px;
border-radius: 50%;
display: inline-flex; align-items: center; justify-content: center;
background: linear-gradient(150deg, rgba(63, 189, 245, .22), rgba(138, 118, 255, .18));
box-shadow: inset 0 0 0 1px rgba(150, 186, 220, .22);
color: #dbe4ef;
/* .76rem = 12,16 px. Bei .7rem waren es 11,2 -- unter der Grenze von
11,5, die pruef-css-klassen zieht. Ein einzelner Grossbuchstabe in
einem 26-px-Kreis wirkt ohnehin kleiner, als die Zahl sagt. */
font-size: .76rem; font-weight: 700; line-height: 1;
overflow: hidden;
}
.wahl2__bild img {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: cover;
border-radius: 50%;
}
/* Der Name bekommt den restlichen Platz und wird gekürzt statt zu
umbrechen -- eine zweizeilige Zeile in einer Auswahlliste zerreißt
den Rhythmus, an dem das Auge entlangläuft. */
.wahl2__name {
min-width: 0;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wahl2__eintrag { align-items: center; gap: 10px; }
/* ===================================================================
DER ANMELDE-KNOPF (08.09.2026)
Filipe, screen28: "dieser anmelde button soll noch viel spezieller
sein bitte. und viel geiler."
NUR DIESER EINE. Er traegt die Klasse `.knopf`, die im ganzen
Workspace an Dutzenden Stellen haengt -- wer sie aendert, aendert
jeden Knopf im Haus. Deshalb greift diese Regel ueber `#knopf`, die
Kennung des Anmelde-Knopfes, und laesst alle anderen in Ruhe.
ER TRAEGT BEIDE MARKEN. Der Verlauf laeuft vom Chili-Rot von Spicy
Media in das Babyblau von Dogi -- dieselbe Klammer wie im Schriftzug
der Kopfleiste, und hier ist sie besonders am Platz: Dieser Knopf ist
die Tuer ins Haus. Wer ihn drueckt, betritt "Spicy & Dogi".
Der Text bleibt WEISS und bekommt keinen Verlauf. Auf einer farbigen
Flaeche ist durchsichtige Schrift doppelt riskant -- sie haengt an
einer Technik UND steht auf wechselndem Untergrund.
DIE FARBEN SIND ABGEDUNKELT, und das war eine Korrektur an mir
selbst. Der erste Entwurf nahm die Marken-Toene direkt: #d94a3f bis
#7ec8f2. Er sah gut aus, und genau das ist die Falle -- nachgerechnet
lag weisser Text darauf bei 4,20 / 3,37 / 2,55 / 1,84 zu 1. Auf dem
hellsten Punkt also nicht einmal beim halben Mindestwert. Ich hatte
an dieser Stelle "ueber 4,5:1 an jeder Stelle" behauptet, ohne es
nachzurechnen; die Zahl hat mich widerlegt.
Jeder Stuetzpunkt ist deshalb so weit abgedunkelt, bis weisser Text
4,6:1 erreicht -- knapp ueber der Grenze, damit Rundungen nicht
darunter rutschen. Die Farben bleiben erkennbar Rot und Blau, sie
sind nur tiefer. Ein Verlauf ist so lesbar wie sein HELLSTER Punkt,
nicht wie sein Durchschnitt.
Der Glanz wandert beim Ueberfahren, statt zu pulsieren -- derselbe
Grund wie beim Manager-Stern und beim Kalender-Knopf: Glanz ist
etwas, das sich bewegt. Bei `prefers-reduced-motion` entfaellt er;
der Knopf bleibt kraeftig, er glaenzt nur nicht. */
#knopf {
position: relative; overflow: hidden;
width: 100%;
padding: 15px 22px;
font-size: 1.02rem; font-weight: 750; letter-spacing: .015em;
color: #fff;
border: 0;
border-radius: 14px;
background:
linear-gradient(100deg, #cc463b 0%, #bc553d 34%, #4e799c 74%, #4d7a94 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .28),
inset 0 -2px 0 rgba(0, 0, 0, .22),
0 10px 26px -14px rgba(217, 74, 63, .9),
0 10px 26px -16px rgba(126, 200, 242, .8);
transition: transform var(--tempo), box-shadow var(--tempo), filter var(--tempo);
}
#knopf:hover:not([disabled]) {
transform: translateY(-1px);
filter: saturate(1.08) brightness(1.04);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .34),
inset 0 -2px 0 rgba(0, 0, 0, .22),
0 14px 30px -12px rgba(217, 74, 63, .95),
0 14px 30px -14px rgba(126, 200, 242, .85);
}
#knopf:active:not([disabled]) { transform: translateY(0); }
#knopf::after {
content: "";
position: absolute; inset: 0;
background: linear-gradient(105deg, transparent 40%,
rgba(255, 255, 255, .3) 50%, transparent 60%);
transform: translateX(-130%);
transition: transform .6s cubic-bezier(.4, 0, .2, 1);
pointer-events: none;
}
#knopf:hover:not([disabled])::after { transform: translateX(130%); }
@media (prefers-reduced-motion: reduce) {
#knopf::after { display: none; }
#knopf:hover:not([disabled]) { transform: none; }
}
/* Waehrend der Anmeldung: ruhig stellen, damit der Ladepunkt die
Aufmerksamkeit bekommt und nicht der Glanz. */
#knopf[disabled] { filter: saturate(.7) brightness(.85); box-shadow: none; }
/* ===================================================================
DIE ROLLENZEICHEN AUF DER ANMELDESEITE (08.09.2026)
SIE WAREN VERGESSEN WORDEN, und Filipe hat es im Bildschirmfoto
gesehen: Auf der Anmeldeseite standen weiter die alten, einfarbigen
Zeichen -- rosa Chili, GELBER Husky, violetter Stern, Schild mit
Haken, Person-Silhouette. Die neuen lagen zu dem Zeitpunkt seit
Stunden im Haus, nur eben in `personen.html`.
DER GRUND ist eine Doppelung, die man dem Code nicht ansieht: Diese
Seite hatte die Zeichen als EIGENE Kopien im Quelltext stehen, nicht
als Verweis auf das gemeinsame Sprite. Wer eines von beiden aendert,
aendert das andere nicht -- und merkt es nicht, weil beide Stellen
fuer sich richtig aussehen. Jetzt traegt `index.html` dasselbe Sprite
und verweist mit `<use>` darauf; es gibt die Zeichen nur noch einmal.
Die Regeln unten mussten mit: Wie bei `.rollenwahl__symbol` setzte
`.rolle__zeichen` ein `fill: none` und ein `stroke` in der
Rollenfarbe. Beides wird an die Pfade VERERBT -- jedes Zeichen waere
von einem 1,7 px dicken Rand ueberzogen und seine Verlaeufe
uebermalt worden. Die Zeichen bringen ihre Farben selbst mit; von
aussen kommt nur noch Groesse und Schatten. */
.rolle__zeichen {
fill: none; stroke: none;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .65));
}
/* Die gewaehlte Rolle hebt sich weiterhin ab -- aber ueber Groesse und
Schein statt ueber die Farbe, denn die gehoert jetzt dem Zeichen. */
.rolle[aria-checked="true"] .rolle__zeichen {
transform: scale(1.06);
filter: drop-shadow(0 2px 5px color-mix(in srgb, var(--rf) 60%, transparent));
}
/* GROESSERE ROLLENZEICHEN (08.09.2026). Filipe: "der husky soll viel
besser aussehen und zu sehen sein." 21 px waren fuer ein Zeichen mit
Gesicht schlicht zu wenig -- Ohren, Maske und Augen lagen dort auf
drei bis vier Bildpunkten. 27 px sind rund 65 % mehr Flaeche, ohne
dass die Zeile ihre Hoehe aendert. */
.rolle__zeichen { width: 27px; height: 27px; }
/* VON personen.css HIERHER GEZOGEN (08.09.2026).
Das Rollen-Sprite steht seit heute auf ZWEI Seiten (personen.html und
index.html). Die Gestaltung dazu lag aber nur in personen.css -- die
Anmeldeseite laedt die gar nicht. Der Stern stand dort also ohne
seinen Glanz, und `pruef-css-klassen` hat es gemeldet: ".rs-funkel --
fehlt auf 1 Seite (index.html)".
Das ist derselbe Fehler wie beim Sprite selbst, nur eine Ebene
hoeher: Wer etwas verdoppelt, muss auch alles mitnehmen, was daran
haengt. gate.css liegt auf allen 19 Seiten -- hier kann es nicht
wieder auseinanderlaufen.
*/
/* DAS FUNKELN DES MANAGER-STERNS.
Ein heller Streifen wandert einmal quer ueber den Stern. Bewusst
langsam (4,5 s) und mit langer Pause: Ein schnelles Blinken waere
genau die aggressive Optik, die hier nicht sein soll -- und in einer
Liste mit fuenf Rollen zoege ein zappelndes Zeichen den Blick
dauerhaft von allem anderen ab.
Gemacht ueber eine wandernde Maske, nicht ueber die Deckkraft: Ein
Auf- und Abblenden des ganzen Sterns waere ein Pulsieren, kein
Glitzern. Glanz ist etwas, das sich BEWEGT. */
.rs-funkel {
-webkit-mask: linear-gradient(105deg, transparent 42%, #000 50%, transparent 58%) center / 260% 100% no-repeat;
mask: linear-gradient(105deg, transparent 42%, #000 50%, transparent 58%) center / 260% 100% no-repeat;
animation: rs-glitzer 4.5s cubic-bezier(.5, 0, .5, 1) infinite;
}
@keyframes rs-glitzer {
0%, 62% { -webkit-mask-position: 145% 0; mask-position: 145% 0; }
100% { -webkit-mask-position: -45% 0; mask-position: -45% 0; }
}
/* Hausregel: Wer weniger Bewegung eingestellt hat, bekommt keine.
Uebrig bleibt ein ruhiger goldener Stern -- nicht ein unsichtbarer. */
@media (prefers-reduced-motion: reduce) {
.rs-funkel { animation: none; -webkit-mask: none; mask: none; opacity: .25; }
}
/* =====================================================================
DER TITEL IST IN DIE PLATTE GRAVIERT (screen29, 09.09.2026)
Filipe: "sehr gut aber ich will es noch viel geiler bitte."
"Creator Workspace" stand als flaches Weiss ueber der Karte --
richtig gesetzt, aber ohne Material. Darunter liegt eine Karte aus
Glas und Metall, darum ein Rahmen aus Rot und Babyblau; nur die
Ueberschrift selbst gehoerte zu nichts davon.
ZWEI SACHEN MACHEN AUS SCHRIFT EIN WERKSTUECK:
1. EIN VERLAUF VON OBEN NACH UNTEN, nicht von links nach rechts.
Gebuerstetes Metall ist oben hell, in der Mitte dunkel und
unten wieder hell -- weil es sich woelbt. Ein Verlauf, der nur
von hell nach dunkel laeuft, ist eine Flaeche mit Farbverlauf;
erst der WECHSEL liest sich als Metall. Dieselbe Ueberlegung
wie bei der Fassung der Zentrale, nur hochkant.
2. EIN HARTER SCHATTEN DIREKT DARUNTER, ein Pixel. Er macht aus
aufgelegter Schrift eingelassene: Das Auge liest die dunkle
Linie als Kante der Vertiefung. Weich waere es ein Schlagschatten
und damit das Gegenteil.
DER RUECKFALL STEHT ZUERST UND IST VOLLWERTIG. `background-clip:
text` ist die Technik, die hier die Farbe traegt -- faellt sie aus,
waere durchsichtiger Text auf durchsichtigem Grund die Ueberschrift
der wichtigsten Seite des Hauses. Also: `color` bleibt gesetzt, und
erst ein `@supports` schaltet den Verlauf dazu. Dieselbe Vorsicht
wie beim Anmelde-Knopf, wo der Text aus genau diesem Grund weiss
geblieben ist.
`filter: drop-shadow` UND NICHT `text-shadow`: Bei durchsichtigem
Text scheint ein Textschatten DURCH die Buchstaben hindurch -- man
saehe den Schatten im Buchstaben stehen. `drop-shadow` legt ihn um
die sichtbare Form, und die ist hier der Verlauf.
AUGENSCHONEND UND NACHGERECHNET: Der dunkelste Punkt des Verlaufs ist
#9fb3c8. Gegen den Kartengrund kommt er auf 8,97:1 (bei #0a0e17),
8,41:1 (#12161f) und im schlechtesten angenommenen Fall 7,54:1
(#1a2030) -- grosse Schrift braucht 3:1, normale 4,5:1. Er liegt
ueber beidem. Die Zahlen stehen hier, weil ich an dieser Stelle
schon einmal "liegt weit darueber" geschrieben hatte, ohne es
auszurechnen, und beim Anmelde-Knopf damit danebenlag (4,20:1 statt
der behaupteten 4,5+). Eine Behauptung ueber Kontrast ohne Zahl ist
eine Vermutung.
Nichts glaenzt, nichts wandert -- es ist Material, keine Animation. */
.tafel .titel {
color: #eef5fd;
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
.tafel .titel {
background: linear-gradient(178deg,
#ffffff 0%,
#e6eef8 26%,
#9fb3c8 56%,
#dceaf7 78%,
#ffffff 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
filter: drop-shadow(0 1px 0 rgba(3, 6, 12, .85));
}
}
/* Ein feiner Lichtstrich unter der Markenzeile -- er trennt "wer sind
wir" von "was ist das hier", ohne ein Wort dafuer zu brauchen, und
nimmt die beiden Hausfarben in derselben Richtung auf wie der Rahmen:
Rot links, Babyblau rechts, Treffpunkt in der Mitte. */
.tafel .marke--paar {
position: relative;
padding-bottom: .5em;
margin-bottom: .35em;
}
.tafel .marke--paar::after {
content: "";
position: absolute; left: 0; right: 0; bottom: 0;
height: 1px;
background: linear-gradient(90deg,
rgba(255, 95, 109, .55) 0%,
rgba(226, 236, 248, .40) 46%,
rgba(143, 216, 255, .55) 78%,
transparent 100%);
}
/* =====================================================================
DER SILBERGLANZ AUF DER DOGFATHER-ZEILE (screen3, 09.09.2026)
Filipe: "so richtig geil silber ... so wie mit sternen, also es soll
nicht zu viel sein aber geil sein."
"Wie mit Sternen" ist als GLANZ gebaut, nicht als Funkeln: ein
schmales Spitzlicht, das schraeg ueber die Zeile laeuft, plus drei
winzige Lichtpunkte. Zusammen ergibt das den Eindruck von poliertem
Metall, auf dem sich etwas spiegelt.
NICHTS BEWEGT SICH. Ein wanderndes Glitzern auf der Anmeldeseite
waere genau das, was die Hausregel verbietet -- und diese Zeile ist
das Erste, was jemand von der Seite sieht. Der Glanz steht still;
er lebt davon, dass er schraeg liegt und nicht mittig.
ER GILT NUR FUER DIESE EINE ROLLE. Die anderen vier bleiben, wie sie
sind: "immer noch im stil von den anderen kategorien". Der
Unterschied ist das Material, nicht die Lautstaerke.
===================================================================== */
.rolle[data-rolle="admin"] {
position: relative;
}
/* DER NAME TRAEGT DIE MISCHUNG (09.09.2026, screen1).
Filipe: "... die dogfather soll." -- der Name selbst soll das
Babyblau tragen, nicht nur die Zierde darum herum.
Von Silber nach Babyblau, in derselben Richtung wie die Schiene
links: Das Wort liest sich als ein Stueck Metall, auf das von oben
links Licht faellt. Der dunkelste Punkt des Verlaufs ist #7fc9f2 --
Kontrast 10,8:1 auf dem Untergrund der Zeile, also weit ueber den
noetigen 4,5:1. (pruef-buehne liest bei `color: transparent` den
dunkelsten Stopp eines Verlaufs aus, genau fuer solche Faelle.)
`-webkit-` steht dabei, weil `background-clip: text` ohne das
Praefix in aelteren WebKit-Fassungen nichts tut -- und "nichts tut"
heisst hier: unsichtbarer Text, nicht schwarzer. */
.rolle[data-rolle="admin"] .rolle__name {
background: linear-gradient(102deg,
#f4f9ff 0%, #cfe6fa 26%, #9ed3f4 58%, #7fc9f2 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
/* Ohne einen Schatten steht heller Text auf hellem Verlauf ohne
Kante. Der Schatten liegt HINTER der Schrift, nicht darauf. */
filter: drop-shadow(0 1px 1px rgba(3, 8, 16, .8));
}
/* Ein Verlauf auf Text hat keinen erhoehten Kontrast beim Ueberfahren
-- die Zeile hebt sich sonst nur noch am Untergrund. Deshalb wird der
Verlauf beim Zeigen einen Hauch heller, nicht anders. */
.rolle[data-rolle="admin"]:hover .rolle__name,
.rolle[data-rolle="admin"][aria-checked="true"] .rolle__name {
background: linear-gradient(102deg,
#ffffff 0%, #e2f1fd 26%, #b6e0f8 58%, #93d2f5 100%);
-webkit-background-clip: text;
background-clip: text;
}
/* Erzwungene Farben (Windows-Kontrastmodus): Ein Verlauf auf Text wird
dort zu einer leeren Flaeche. Zurueck auf die Systemfarbe. */
@media (forced-colors: active) {
.rolle[data-rolle="admin"] .rolle__name,
.rolle[data-rolle="admin"]:hover .rolle__name {
background: none; color: CanvasText; filter: none;
}
}
/* DIE SCHIENE LAEUFT VON SILBER NACH BABYBLAU (09.09.2026).
Die Rollenschiene links wird sonst aus einer einzigen Farbe gebaut
(`--rf`/`--rton`). Fuer DogFather ist das jetzt zu wenig: Seine
Farbe IST eine Mischung, und die sieht man nur, wenn beide Toene
nebeneinander liegen. Oben Silber, unten Babyblau -- dieselbe
Richtung wie das Licht auf der Kachel. */
.tafel .rolle[data-rolle="admin"]::before,
.rolle[data-rolle="admin"]::before {
/* DAS SILBER SITZT NUR NOCH OBEN (09.09.2026, screen1).
Vorher lief die Schiene bis 42 Prozent im hellen Silberton und
erreichte das Babyblau erst ganz unten -- auf 3 px Breite blieb
davon fast nichts uebrig. Jetzt ist der Silberkamm ein SPITZLICHT
am oberen Ende (die ersten 18 Prozent), darunter Babyblau ueber
die ganze restliche Laenge. Das ist dieselbe Verteilung, die eine
angestrahlte Metallkante wirklich hat: ein schmaler Glanz, viel
Eigenfarbe. */
background: linear-gradient(180deg,
#f2f8ff 0%,
var(--dogi-haupt) 18%,
var(--dogi-zweit) 62%,
#4fb3e8 100%) !important;
}
.rolle[data-rolle="admin"]::after {
content: "";
position: absolute; inset: 0;
pointer-events: none;
background:
/* Das Spitzlicht -- schmal, schraeg, und weit vor der Mitte.
Es traegt jetzt beide Toene: weiss am Kamm, babyblau im
Auslauf. So liest man die Mischung auch dort, wo keine Schiene
ist. */
/* EIN ZWEITER, BREITER SCHIMMER IN BABYBLAU (09.09.2026, screen1).
Der schmale weisse Kamm allein war Silber ohne Ton -- er sass auf
16 Prozent der Breite und war damit auf einer 900 px langen Zeile
ein Strich. Der neue Schimmer liegt darunter, ist viel breiter und
viel schwaecher: Er faerbt die Flaeche, statt sie zu streifen. */
linear-gradient(104deg,
transparent 4%,
rgba(120, 195, 240, .10) 30%,
rgba(120, 195, 240, .13) 58%,
rgba(120, 195, 240, .05) 82%,
transparent 96%),
linear-gradient(104deg,
transparent 8%,
rgba(255, 255, 255, .12) 16%,
rgba(174, 218, 248, .09) 22%,
transparent 32%),
/* Drei Lichtpunkte, unregelmaessig gesetzt. Regelmaessig waeren sie
ein Muster; unregelmaessig sind sie Zufall auf einer Oberflaeche. */
radial-gradient(1.4px 1.4px at 22% 30%, rgba(255, 255, 255, .5), transparent),
radial-gradient(1.1px 1.1px at 63% 72%, rgba(226, 238, 250, .38), transparent),
radial-gradient(1.6px 1.6px at 84% 26%, rgba(255, 255, 255, .3), transparent);
}
/* =====================================================================
DIE ZWEITE ZUGANGSWAND (10.09.2026)
Nur die zweite Wand traegt `gate--crew`. Hier stehen die wenigen
Stellen, an denen die gemeinsame Gestaltung nicht passt -- und zwar
NUR die.
WARUM HIER WEDER IHRE ADRESSE NOCH IHR DATEINAME STEHT (21.09.2026):
Diese Stilvorlage wird von BEIDEN Adressen ausgeliefert, und zwar
ohne Anmeldung -- jeder im Netz kann sie herunterladen und lesen.
Bis heute stand die Adresse der zweiten Wand hier im Klartext. Das
war die eigentliche Auskunft: Die Rollennamen stehen auf jener Wand
ohnehin offen, WO sie liegt dagegen nicht.
Der Dateiname der Wand steht seit demselben Tag in der Tafel
GEHOERT_ZU_ADRESSE (crew-adresse.js) -- dort gehoert er hin, denn
dort wird er auch durchgesetzt. Hier waere er nur eine Notiz, die
jeder mitliest.
ES GEHT NICHT UM GESCHMACK, SONDERN UM DAS BILD DAHINTER.
Die Karte holt sich absichtlich die Farben des gemalten Rahmens
herein: rot oben links, blau unten rechts, "das, was die Karte mit
dem Bild verbindet, statt sie davorzusetzen" (Begruendung weiter
oben). Auf der zweiten Buehne ist der Rahmen aber RINGSUM blau -- die
Szene wurde umgefaerbt. Das Rot verbindet dort also nichts mehr,
sondern widerspricht dem Bild.
Dieselbe Ueberlegung beim Anmeldeknopf: Sein Verlauf lief von Rot
nach Blau, weil er die beiden Marken aufnahm. Auf dieser Seite gibt
es nur eine.
===================================================================== */
/* Der Knopf: von Lila nach Babyblau (10.09.2026).
Filipe: "richtig geiles lila und babyblau mischung überall." Er lief
bis eben von tiefem zu hellerem Blau -- richtig, solange die Wand
einfarbig blau war; jetzt fehlte ihm die Haelfte der Mischung.
DIE HELLIGKEIT IST NACHGERECHNET, NICHT GEWAEHLT. Der erste Entwurf
der blauen Fassung endete bei #4aa4cf -- huebsch, und weisse Schrift
darauf haette nur 2,8 zu 1 gehabt. Ein hellerer Knopf sieht
kraeftiger aus und ist schlechter zu lesen; das ist kein Tausch, den
man nebenbei macht.
Jede Stufe hier liegt gegen Weiss bei mindestens 5 zu 1 (gerechnet:
10,7 / 8,8 / 6,6 / 5,9). Der Verlauf beginnt dadurch dunkler als
vorher und endet heller -- die schlechteste Stelle ist damit besser
als die schlechteste der blauen Fassung. Gemessen wird das in
pruef-crew-wand-bild.mjs am fertigen Bildschirmfoto, denn ein Verlauf
laesst sich nicht aus einer einzelnen Farbe beurteilen. */
body.gate--crew #knopf {
background:
linear-gradient(100deg, #3a2b7d 0%, #4a3a9c 34%, #46589f 74%, #37688f 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .28),
inset 0 -2px 0 rgba(0, 0, 0, .22),
0 10px 26px -14px rgba(130, 104, 220, .9),
0 10px 26px -16px rgba(126, 200, 242, .8);
}
body.gate--crew #knopf:hover:not([disabled]) {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .34),
inset 0 -2px 0 rgba(0, 0, 0, .22),
0 14px 30px -12px rgba(130, 104, 220, .95),
0 14px 30px -14px rgba(126, 200, 242, .85);
}
/* DIE KACHELREIHE. Ihre Fassung laeuft im Original von Rot ueber
Silber nach Babyblau -- sie zitiert damit den Rand der Zentrale
("Wer sich anmeldet, sieht damit schon hier die Handschrift der
Seite, die dahinter liegt", Begruendung weiter oben). Hinter DIESER
Wand liegt aber eine durchweg blaue Seite; das Rot zitiert dort
nichts mehr.
Die Form bleibt Stufe fuer Stufe gleich -- dunkel, Farbe, hell,
dunkel, Silber in der Mitte, dann dasselbe gespiegelt. Nur die
linke Farbe wechselt von Rot nach Blau. Wer die Fassung spaeter
umbaut, sieht an den gleichen Prozentzahlen sofort, dass beide
zusammengehoeren. */
body.gate--crew .rollen {
/* LINKS LILA, RECHTS BABYBLAU (10.09.2026). Die Prozentzahlen sind
Stufe fuer Stufe dieselben wie im Original -- getauscht wird nur
die linke Farbfamilie, damit die beiden Fassungen nebeneinander
lesbar bleiben. Rechts stand Babyblau schon immer; das war nie das
Problem. */
background: linear-gradient(96deg,
#06040f 0%, #3a2b7d 6%, #7a63d8 14%, #ded3ff 20%,
#35276f 30%, #0a0c12 40%, #f4faff 50%, #0a0c12 60%,
#4f95bd 70%, #8fd8ff 78%, #dff2ff 84%, #3f7fa3 92%, #06080f 100%);
}
/* Das Innenglas: unten links glueht es rot. Dieselbe Stelle, kaltes
Licht. Der Rest der Ebene (Messraster, Verlauf) bleibt unangetastet
-- deshalb wird die ganze Liste noch einmal geschrieben und nicht
nur eine Zeile: `background` ist eine Kurzschreibweise, eine einzelne
Lage laesst sich nicht ersetzen. */
body.gate--crew .rollen::before {
background:
linear-gradient(180deg, rgba(255, 255, 255, .05), transparent 34%),
repeating-linear-gradient(0deg, rgba(150, 186, 220, .05) 0 1px, transparent 1px 22px),
repeating-linear-gradient(90deg, rgba(150, 186, 220, .05) 0 1px, transparent 1px 22px),
radial-gradient(120% 80% at 12% 100%, rgba(150, 122, 255, .13), transparent 62%),
radial-gradient(110% 75% at 88% 0%, rgba(126, 200, 242, .09), transparent 60%),
linear-gradient(180deg, #0c0b1c, #080714);
}
/* Der kleine Anschlag neben "Womit meldest du dich an?" -- oben rot,
unten babyblau. Hier oben im Ton von Team Dogi, unten babyblau: derselbe
Zweifarbenaufbau, beide Haelften kalt. */
body.gate--crew .rollen .feldschild::before {
background-image:
linear-gradient(180deg, transparent 0 46%, rgba(143, 216, 255, .95) 46%),
repeating-linear-gradient(180deg, #6b5fa8 0 2px, transparent 2px 5px);
}
/* Die Karte in der gemalten Tafel. WORTGLEICH dieselbe Bedingung wie
oben -- nicht global: Auf schmalen Geraeten hat die Karte einen
anderen Aufbau, und ein globales `background` haette den ueberschrieben.
Nur die zwei roten Werte werden blau, alles andere bleibt Zeile fuer
Zeile wie es war. */
@media (min-width: 1100px) and (min-height: 620px) and (min-aspect-ratio: 7/5) {
body.gate--crew .tafel {
background:
radial-gradient(135% 100% at 0% 0%, rgba(150, 122, 255, .26), transparent 55%),
radial-gradient(135% 100% at 100% 100%, rgba(56, 158, 246, .30), transparent 58%),
linear-gradient(176deg,
rgba(16, 23, 36, .93) 0%,
rgba(9, 13, 21, .95) 46%,
rgba(5, 7, 13, .96) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .11),
inset 0 -1px 0 rgba(0, 0, 0, .5),
inset 2px 2px 0 -1px rgba(120, 190, 240, .32),
inset -2px -2px 0 -1px rgba(56, 158, 246, .38),
inset 0 0 54px -20px rgba(0, 0, 0, .92);
}
}
/* =====================================================================
DIE ALTERSFRAGE AN DER ZUGANGSWAND (15.09.2026)
Sie darf nicht wie ein Kleingedrucktes aussehen -- wer sie setzt,
soll sie gelesen haben. Also lesbare Groesse, ein Beruehrziel, das
den Namen verdient, und keine graue Fussnotenfarbe.
===================================================================== */
.alterfrage { margin: 0 0 16px; }
.alterfrage__zeile {
display: flex; align-items: flex-start; gap: 11px;
padding: 11px 13px;
cursor: pointer;
border: 1px solid var(--rand);
border-radius: var(--radius);
background: rgba(0, 0, 0, .22);
}
.alterfrage__zeile:hover { border-color: var(--rand-hell); }
.alterfrage__zeile input {
/* 20 px plus die Polsterung ringsum ergeben ein Ziel, das ein Daumen
trifft -- das Kaestchen allein waere 13 px. */
width: 20px; height: 20px; margin: 1px 0 0; flex: 0 0 auto;
accent-color: var(--akzent);
}
.alterfrage__text {
font-size: .88rem; line-height: 1.5; color: var(--text-leise);
}
.alterfrage__text strong { color: var(--text); }
/* DER SATZ, DER SAGT, WOHER MAN EINEN CODE BEKOMMT (19.09.2026).
Er steht ÜBER der Fußzeile mit der Verschlüsselungszusage, nicht
darunter: Wer keinen Code hat, soll ihn lesen, bevor er aufgibt.
Etwas heller gesetzt als der Fuß — er ist eine Auskunft, kein
Kleingedrucktes. */
.fuss--woher {
color: var(--text-leise);
margin-bottom: 6px;
}
/* =====================================================================
KONTRASTMODUS: EIN GEDRÜCKTER SCHALTER MUSS GEDRÜCKT AUSSEHEN
(19.09.2026)
In Windows' Kontrastmodus (`forced-colors: active`) ersetzt das
System alle Farben und entfernt `box-shadow` ganz. Was seinen
Zustand NUR über Hintergrundfarbe oder einen Schatten-Rand zeigt,
sieht danach aus wie jeder andere Schalter.
Gemessen am 19.09.2026: **68 Regeln** im Haus zeigen einen Zustand
so -- 35× `[aria-pressed="true"]`, 33× `[data-an="ja"]`. Betroffen
sind Filterreihen, Empfängerauswahl, Merkmale, Stufen.
VIERZEHN CSS-DATEIEN hatten gar keinen Kontrastmodus-Block. Die
naheliegende Reaktion wäre gewesen, vierzehn Blöcke anzuhängen --
und damit eine Liste zu pflegen, die beim fünfzehnten Bereich
wieder unvollständig ist. Eine Regel, die den ZUSTAND trifft statt
die Datei, kann nicht veralten.
NICHT über die Hintergrundfarbe (die darf das System ersetzen),
sondern über eine Kante aus einer SYSTEMFARBE: `Highlight` ist die
Farbe, die der Nutzer selbst für „ausgewählt" eingestellt hat.
ABSICHTLICH KEIN `forced-color-adjust: none` -- damit bliebe unsere
eigene Farbe stehen, und genau die kann der Nutzer ja nicht lesen.
Das wäre, als würde man die Barrierefreiheit wegoptimieren, um die
Gestaltung zu retten.
Was seinen Zustand ohnehin als WORT trägt, braucht hier nichts:
`.marke-status` schreibt „Entwurf"/„Freigegeben" hin, `.t-stufe`
hat `.t-stufe__name`, jede `.spalte` hat ihre Überschrift. Dort ist
die Farbe Zierde, nicht Aussage -- nachgesehen, nicht vermutet.
===================================================================== */
@media (forced-colors: active) {
[aria-pressed="true"],
[data-an="ja"],
[data-anders="ja"],
[aria-current="page"],
[aria-current="true"] {
outline: 2px solid Highlight;
/* Nach INNEN, damit die Kante nichts überdeckt und das Element
nicht springt, wenn es gedrückt wird. */
outline-offset: -2px;
}
}