Files
dogfather-universe/workspace/assets/css/gate.css
T
DogFatherGitandClaude Opus 5 8efdb39ce9 Kein Weichzeichner mehr -- die Bilder werden scharf, die Kacheln Lampen
Filipe: "gerade sehen die sogar leicht verschwommen aus ... die sollen
nicht durch die kacheln gehen ... ich wollte eine krasse aenderung."

Drei Ursachen, alle drei von mir eingebaut, alle drei gemessen:

1. ICH HABE 1647-PIXEL-BILDER ALS "uhd" MIT 2400 PIXELN AUSGELIEFERT.
   Am Morgen stand in derselben Datei, sein Schirm sei 2550 px breit und
   das groesste Bild 1600 -- meine "Loesung" war, die Ausgabe
   hochzurechnen. Es gab nie mehr Bildpunkte. Dazu fehlte der Schritt,
   den der Kommentar daneben selbst verlangt ("Verkleinern MITTELT
   Bildpunkte ... deshalb schaerft man danach nach"): Es wurde nie
   nachgeschaerft. Jetzt Unscharfmaske auf der ENDgroesse
   (Ausgabeschaerfung) und ein Glanz-Durchgang: die hellsten Stellen
   weich gezeichnet und additiv dazu -- Licht, das ueber seine Kante
   strahlt. Guete 0,80 -> 0,88, am Gate 0,93.

2. backdrop-filter: blur() UNTER JEDER FLAECHE. 16 px unter siebzehn
   Kacheln, 13 px unter sieben weiteren Flaechen, 26 px unter der
   Anmeldekarte. Ein Weichzeichner mittelt nicht nur, was hinter dem
   Element liegt -- er zieht seinen Radius weit darueber hinaus. Hinter
   der Anmeldetafel ist Schwarz, direkt daneben aber die hellste Stelle
   des Motivs: Die Karte wurde deshalb GRAU, gemessen rgb(46,57,64)
   statt rgb(15,22,34). Je schoener der Rahmen, desto grauer die Karte.
   Alle Weichzeichner raus, --flaeche 0,78 -> 0,89: Durchsicht bleibt,
   aber scharf.

3. DIE TAFELMESSUNG WAR FALSCH, UND ICH HABE SIE VON HAND "KORRIGIERT".
   Sie lief vom Inneren nach aussen und hielt beim ersten farbigen Punkt
   an -- links glueht der Rahmen breiter als rechts, also hielt sie dort
   frueher an (58,59 statt 55,37). Statt den Messfehler zu beheben, habe
   ich in der CSS "um 1,1 % nach links" geschaetzt. Ergebnis: 32 px
   schwarze Tafel blieben links offen. Jetzt wird die einzige
   Eigenschaft gesucht, die nur der Rahmen hat -- kraeftig UND farbig --,
   mit Gegenprobe auf der linken Bildhaelfte (dort muessen es 0 sein).

KACHELN: keine Politur mehr, ein anderes Ding. Jede steckt in einer
LEUCHTSCHIENE ihrer Kategoriefarbe, die Licht in die Platte wirft --
links scharfe Kante, rechts rund. Steiler Abfall (52 % statt 68 %):
beleuchtet, nicht eingefaerbt. Der Glanz wandert beim Ueberfahren
einmal durch. Dieselbe Sprache auf der Anmeldeseite: die vier Rollen
sind Tasten in Schienen (Gold/Bernstein/Gruen/Blau).

Zwei eigene Fehler nebenbei, beide durch das Unveraenderlichkeits-
Zeichen gefunden -- eine Zahl, die sich nach einer Aenderung KEIN Stueck
bewegt, sagt "falsche Stelle", nicht "zu wenig":
  - Dreimal exakt 4,16:1 an "Ueberfaellig". Der Pruefpunkt lag nicht auf
    dem Knopf, sondern in der Luecke daneben auf dem Bild. Ursache war
    das hellere Hochkant-Bild, nicht das Bedienelement -> mehr Schleier
    und weniger Glanz NUR fuer die Handy-Fassung. 4,16 -> 5,10.
  - Die Koernung der Anmeldekarte lag mit 90 % Deckkraft ohne Mischmodus
    ueber allem und hob jeden Bildpunkt um 30 Stufen. Jetzt 4 % mit
    overlay, auf eigener Ebene.
  - --flaeche anzuheben machte die WICHTIGE Anleitung duenner als eine
    gewoehnliche (88 gegen 89) -- feste Zahl neben beweglicher Groesse.
    Gefunden von pruef-lesbarkeit, jetzt an --flaeche gebunden.

Gruen: buehne (38), start-ansicht (136), handy (59), breiten (23),
lesbarkeit (14), css-klassen (15), barrierefrei (18), tempo (8).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-07 03:10:13 +02:00

1682 lines
69 KiB
CSS

/* ===================================================================
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 */
--text-leise: #94a5bb;
/* 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. */
--text-still: #7f8fa6;
--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);
}
*, *::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; }
/* 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; }
.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; }
/* ---------- Rollen --------------------------------------------------- */
.feldschild {
margin: 0 0 10px;
font-size: .78rem; font-weight: 600;
letter-spacing: .06em; text-transform: uppercase;
color: var(--text-still);
}
.rollen { margin-bottom: 22px; }
.rolle {
display: flex; align-items: center; gap: 13px;
width: 100%; margin-bottom: 8px; padding: 11px 14px;
background: rgba(255, 255, 255, .035);
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
color: var(--text);
font: inherit; text-align: left; cursor: pointer;
transition: border-color var(--tempo), background var(--tempo), transform var(--tempo);
}
.rolle:hover { background: rgba(255, 255, 255, .06); border-color: var(--rand-hell); }
.rolle:active { transform: scale(.995); }
.rolle[aria-checked="true"] {
background: linear-gradient(100deg, rgba(63, 189, 245, .14), rgba(138, 118, 255, .10));
border-color: rgba(63, 189, 245, .55);
}
.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; }
.rolle[aria-checked="true"] .rolle__zeichen { stroke: var(--akzent); }
.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; }
.marke { font-size: .68rem; 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; }
.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. */
.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 {
display: block; 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. */
font-size: clamp(12px, 1.50cqh, 16px);
padding: 1.75em 1.6em 1.4em;
/* 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: .74em; margin-bottom: .5em; }
.tafel .titel { font-size: 1.85em; margin-bottom: .3em; }
.tafel .unterzeile { font-size: .92em; margin-bottom: 1.15em; }
.tafel .feldschild { font-size: .76em; margin-bottom: .6em; }
.tafel .rollen { margin-bottom: 1.1em; }
.tafel .rolle { padding: .62em .85em; margin-bottom: .42em; gap: .8em; }
.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: .75em; padding: .7em 1.1em; font-size: .88em; width: 100%; }
.tafel .hinweis,
.tafel .fehler { font-size: .82em; margin-top: .5em; }
.tafel .fuss { margin-top: 1.1em; padding-top: .8em; 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. */
.tafel .rolle[data-rolle="admin"] { --rton: var(--k-gold); }
.tafel .rolle[data-rolle="manager"] { --rton: var(--k-mittel); }
.tafel .rolle[data-rolle="scout"] { --rton: var(--k-gut); }
.tafel .rolle[data-rolle="creator"] { --rton: var(--akzent); }
.tafel .rolle {
position: relative;
overflow: hidden;
/* Links scharf (dort sitzt die Schiene), rechts rund -- genau die
Silhouette der Kacheln. */
border-radius: 3px 13px 13px 3px;
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: 1px solid rgba(150, 186, 220, .13);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .09),
inset 0 -1px 0 rgba(0, 0, 0, .38),
0 1px 2px rgba(0, 0, 0, .35);
transition: border-color var(--tempo), background var(--tempo),
box-shadow var(--tempo), transform .09s ease;
}
/* Die Schiene selbst. */
.tafel .rolle::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
border-radius: 3px 0 0 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));
border-color: rgba(150, 186, 220, .24);
}
.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. */
.tafel .rolle:active {
transform: translateY(1px);
box-shadow: inset 0 2px 4px rgba(0, 0, 0, .5);
}
/* 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));
border-color: color-mix(in srgb, var(--rton, var(--akzent)) 58%, transparent);
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);
}
}