FILIPE, mit Bildschirmfoto der Personenauswahl: "wenn ich da scollen will geht das immer zu"
Er hatte recht, und es war eine einzige Zeile in workspace/assets/js/wahl.js:
addEventListener('scroll', schliessen, true);
Das dritte Argument bedeutet "in der Einfangphase lauschen" -- und damit auf JEDES
Scroll-Ereignis im ganzen Dokument, auch auf das in der Liste selbst. Wer die Namensliste
herunterrollen wollte, schloss sie im selben Moment. Bei acht Eintraegen faellt das kaum
auf; beim ganzen Manager- und Scout-Team ist die Liste unbedienbar.
Zumachen MUSS sie trotzdem, wenn die Seite scrollt: Sie haengt an position:fixed und
schwaemme sonst neben ihrem Knopf davon. Deshalb wird jetzt unterschieden, WO gescrollt
wurde -- ein Scroll-Ereignis der Seite hat document als Ziel, das ist nicht in der Liste
enthalten, also schliesst sie wie bisher.
Dazu overscroll-behavior: contain in gate.css. Ohne das reicht der Browser das Rollen am
Listenende an die Seite weiter, die Seite bewegt sich -- und daran schliesst die Liste zu
Recht. Der Fehler waere zur Haelfte zurueck gewesen.
GEPRUEFT im echten Browser am echten wahl.js und gate.css (pruef-wahl-scrollen.mjs, 7
Pruefungen), und zwar BEIDE Haelften der Zusage: Liste scrollt -> bleibt offen, Seite
scrollt -> geht zu. Eine Reparatur, die nur die eine Richtung sichert, waere die naechste
Ueberraschung.
Gegenprobe: alte Zeile testweise eingesetzt -> 2 Pruefungen fallen durch. Reparatur ->
alle 7 gruen.
Die Pruefung hat sich beim Bauen DREIMAL geweigert, etwas zu bestaetigen, das sie nicht
gemessen hatte -- "die Liste ist gar nicht laenger als ihr Fenster", "scrollTop = 0". Jedes
Mal lag es an meinem Aufbau (zu hohes Fenster, fehlende Stylesheets, Mausrad ohne Wirkung),
nie an der Reparatur. Gruen gemeldet haette sie es nie.
Der Versionsstempel muss mit: Cloudflare haelt JS und CSS vier Stunden im Browser fest.
Ohne neue Adresse saehe Filipe die Reparatur bis zu vier Stunden lang nicht.
HINWEIS ZUM COMMIT: In diesem Verzeichnis lag zum Zeitpunkt der Arbeit fremde,
uncommittete Arbeit -- vier Server-Dateien (heute 16:41-16:53 geaendert), sieben neue
Pruefdateien, ~110 Bildschirmfotos, eine Fokusring-Korrektur in gate.css und eine
Beschriftung in profil.html. Nichts davon ist hier drin. Bereitgestellt wurde ausdruecklich
nach Pfad, und die beiden Dateien mit gemischtem Inhalt (gate.css, profil.html) wurden dafuer
aus HEAD geholt und nur um den eigenen Anteil ergaenzt. Die fremde Arbeit steht unveraendert
im Arbeitsstand.
1043 lines
39 KiB
CSS
1043 lines
39 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. */
|
|
--flaeche: rgba(9, 13, 22, 0.78);
|
|
--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. */
|
|
--text-still: #75859a;
|
|
|
|
--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);
|
|
transform: scale(1.03); /* Reserve für die Parallaxe */
|
|
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);
|
|
}
|
|
|
|
/* ---------- 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; }
|
|
}
|