Files
dogfather-universe/workspace/assets/css/start.css
T
DogFatherGitandClaude Opus 5 17157b4f18 Sicht-Umschalter: ein Auge statt des Wortes "SICHT"
Filipe zu dem Feld in der Kopfleiste: "das soll viel besser aussehen
viel geiler aber nicht so eine scheisse."

Er hatte recht. Da stand ein Etikett mit dem Wort SICHT und daneben ein
Auswahlfeld -- ein Formular, das in die Kopfleiste gerutscht war. Drei
Aenderungen:

  * DAS AUGE ersetzt das Wort. Es sagt dasselbe in einem Zeichen und
    laesst dem NAMEN den Platz, um den es eigentlich geht. Fuer
    Vorleseprogramme bleibt die Beschriftung erhalten, nur unsichtbar --
    sie ersatzlos zu loeschen haette das Feld unbeschriftet gelassen.

  * "Meine Sicht" statt "Alles (meine Sicht)". Der Zusatz erklaerte
    nichts und machte den Knopf so breit, dass am Handy nichts anderes
    mehr danebenpasste.

  * EIN KREUZ statt "zurueck zu mir". Der Satz brauchte mehr Platz als
    der Name daneben, und was ein Kreuz an einer aktiven Auswahl tut,
    weiss jeder. Die Worte bleiben im aria-label und im Titel.

DIE EIGENTLICHE VERBESSERUNG ist aber die Hierarchie: Im Normalfall
ist der Umschalter still (graues Auge, ruhiger Rand). Sobald eine
FREMDE Sicht laeuft, traegt er ganz Farbe -- nicht nur ein
Zusatzknopf am Rand.

Das ist der gefaehrlichste Zustand dieser Funktion: Wer sie vergisst,
sieht am naechsten Tag drei Aufgaben statt dreissig und haelt das fuer
den Bestand. Ein Zustand, der Schaden anrichtet, muss lauter sein als
einer, der nichts tut.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 17:48:03 +02:00

3689 lines
149 KiB
CSS

/* ===================================================================
Startseite nach dem Anmelden. Baut auf den Farben und Bausteinen von
gate.css auf, damit beides wie eine Anwendung wirkt und nicht wie zwei
verschiedene Seiten.
=================================================================== */
/* Grundschrift und Grundfarbe stehen in gate.css auf `body.gate` und
greifen hier deshalb NICHT. Ohne diese Wiederholung fällt die Seite auf
die Browservorgaben zurück: schwarze Serifenschrift auf dunklem Grund,
praktisch unlesbar. */
body.start {
display: block;
min-height: 100svh;
margin: 0;
padding: 0;
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;
background:
radial-gradient(120% 80% at 12% -10%, rgba(63, 189, 245, .10), transparent 58%),
radial-gradient(100% 70% at 92% 8%, rgba(138, 118, 255, .10), transparent 60%),
var(--tinte);
}
/* ---------- Die Bühne ----------------------------------------------------
HasiDog und DogFather im Studio -- das echte Marken-Bild, nicht
irgendein Husky aus dem alten Bilderordner. Über die ganze Fläche und
FEST an der Scheibe: Es scrollt nicht mit, sondern steht da wie ein
Bühnenbild, vor dem gearbeitet wird.
Warum genau dieses von den fünf: Die beiden stehen weit AUSSEN, die
Mitte ist dunkel -- und dort steht der Inhalt. Ein Bild mit Figuren in
der Mitte wäre hinter dem Text gelandet.
Aufbereitet in tools/buehne-bauen.mjs: abgedunkelt, Mitte zusätzlich
verdunkelt, weiche Kante oben. 1,9 MB PNG -> 28 KB WebP.
138 % breit und nach unten ausgerichtet: Bei 100 % ständen die beiden
bei 20 % und 78 % der Breite -- also mitten unter der Textspalte.
Vergrößert man das Bild über die Scheibe hinaus, wandern sie nach
außen (auf rund 9 % und 88 %) und der leere Hallenboden liegt dort,
wo gelesen wird. Ein Bild größer zu machen, damit WENIGER davon im
Weg ist, klingt verkehrt und ist genau richtig. */
body.start::before {
content: "";
position: fixed; inset: 0; z-index: 0;
pointer-events: none;
background-repeat: no-repeat;
/* cover statt "138% auto". Der alte Wert war der eigentliche Fehler:
Bei 138 % Fensterbreite wurde das Bild auf einem 2540 px breiten
Schirm 3500 px breit und knapp 2000 px hoch -- in einem 1300 px
hohen Fenster fehlten damit 700 px, und zwar oben. Genau deshalb
waren die Figuren riesig und ihre Koepfe abgeschnitten.
cover fuellt die Flaeche IMMER vollstaendig und skaliert dabei so
wenig wie noetig. Die Verankerung liegt auf 50 % 42 %: etwas ueber
der Mitte, weil dort in allen neun Szenen die Gesichter sitzen --
wenn etwas beschnitten werden muss, dann Fussboden und Decke. */
background-position: 50% 42%;
background-size: cover;
/* Rueckfall, falls eine Seite keine eigene Szene hat. */
background-image: url("../img/buehne-dogfather-breit.webp");
}
/* ---------- Neun Buehnen, nicht eine ------------------------------------
Filipe hat neun Bilder geschickt, damit es VERSCHIEDENE Hintergruende
gibt -- benutzt wurde davon lange nur das Studio. Jetzt hat jede Seite
ihre eigene Szene, ausgewaehlt ueber data-buehne am body (gesetzt von
kopf.js aus bereiche.js):
Aufgaben Werkstatt Kalender Nachtstadt Calls Sitzecke
Dateien Portal-Archiv Profil Halle Scout Wald
Dashboard grosse Buehne Content Durchgang Start Studio
Alle sind gleich abgedunkelt und tragen dieselbe Vignette -- sie sehen
verschieden aus und verhalten sich gleich. Eine Buehne, die je Seite
anders hell waere, waere Unruhe statt Vielfalt. */
body.start[data-buehne="studio"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="showbuehne"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="garage"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="skyline"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="lounge"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="arena"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="halle"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="wald"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
body.start[data-buehne="portal"]::before { background-image: url("../img/buehne-dogfather-breit.webp"); }
/* Der Schleier. Er ist der Grund, warum Text über einem Foto unverändert
lesbar bleibt -- oben dicht für die Kopfleiste, in der Mitte dicht für
den Inhalt, an den Rändern offen, damit die beiden sichtbar bleiben.
Gemessen statt geschätzt: server/pruef-buehne.mjs rechnet den Kontrast
an echten Bildpunkten nach, an bis zu 34 Stellen je Seite. */
/* Der Schleier ist am 01.09.2026 spürbar durchlässiger geworden (Wunsch:
"den Hintergrund auch bisschen heller überall"). Er liegt jetzt bei
.86/.58/.44/.66 statt .95/.72/.60/.80 -- die Bühne kommt dadurch
deutlich durch, ohne dass sie den Text stört, weil die Inhalte auf
eigenen, kräftigeren Flächen liegen (siehe --glas in gate.css).
Ein zweiter, sehr weicher Farbschimmer in Blau-Violett legt sich
darüber. Er nimmt dem Bild das reine Schwarz und gibt der Seite
dieselbe Tiefe wie VanVans Hub -- ohne eine einzige Farbe zu
verfälschen, weil er nur 4-6 % beiträgt. */
body.start > .schleier {
position: fixed; inset: 0; z-index: 0; pointer-events: none;
background:
/* NUR NOCH DIE RAENDER. Der Schleier legte vorher .86/.58/.44
Schwarz ueber das ganze Bild -- also auch ueber die Mitte, in der
die Szene steht, und das ZUSAETZLICH zur Vignette, die dort
ebenfalls dunkel war. Zwei Schichten Dunkelheit uebereinander,
genau an der Stelle, die man sehen will.
Jetzt: oben ein Streifen (dort sitzt die Kopfleiste), unten ein
Streifen (dort laeuft die Seite aus), die Mitte fast frei. Der
Text braucht das nicht mehr -- er steht auf eigenen Flaechen. */
linear-gradient(180deg,
rgba(5, 7, 13, .82) 0%,
rgba(5, 7, 13, .34) 12%,
rgba(5, 7, 13, .12) 40%,
rgba(5, 7, 13, .12) 62%,
rgba(5, 7, 13, .52) 100%),
/* Zwei sehr weiche Farbschimmer in den gegenueberliegenden Ecken.
Sie nehmen dem Bild das reine Schwarz und geben ihm Tiefe, ohne
eine einzige Farbe zu verfaelschen -- 5 bis 7 Prozent. */
radial-gradient(75% 60% at 12% 4%, rgba(63, 189, 245, .07), transparent 70%),
radial-gradient(75% 65% at 90% 98%, rgba(138, 118, 255, .08), transparent 72%),
/* DIE LESESPUR — und der eigentliche Kniff.
In allen neun Szenen stehen HasiDog und DogFather AUSSEN, die
Mitte ist frei. Genau danach wurden die Bilder ausgesucht. Diese
Aufteilung wird jetzt benutzt, statt gegen sie zu arbeiten:
aussen das Bild bleibt hell und scharf -- dort stehen die
Figuren, und die sollen zu sehen sein
mitte gedaempft -- dort steht der Text
Vorher wurde entweder alles abgedunkelt (dann war das Bild
Nebel) oder gar nichts (dann war Schrift auf einer hellen Stelle
unlesbar, gemessene 1,08:1). Beides falsch. Der Rand bleibt in
jedem Fenster mindestens 380 px breit klar -- genug fuer die
Figuren, egal wie breit der Schirm ist. */
linear-gradient(90deg,
rgba(5, 7, 13, 0) 0,
rgba(5, 7, 13, .8) min(22%, 400px),
rgba(5, 7, 13, .86) 50%,
rgba(5, 7, 13, .8) max(78%, calc(100% - 400px)),
rgba(5, 7, 13, 0) 100%);
}
/* Alles Bedienbare liegt über der Bühne. Ohne das läge der Inhalt zwar
sichtbar darüber, aber Klicks landeten teils am falschen Ort. */
body.start > .kopfleiste,
body.start > .inhalt,
body.start > main { position: relative; z-index: 1; }
/* Auf schmalen Schirmen ein hochkant-Ausschnitt derselben Szene -- ein
auf 9:16 gequetschtes Breitbild zeigt nur noch Wand. */
@media (max-width: 760px) {
body.start::before {
background-image: url("../img/buehne-dogfather-schmal.webp");
background-size: cover;
background-position: 50% 38%;
}
body.start[data-buehne="studio"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="showbuehne"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="garage"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="skyline"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="lounge"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="arena"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="halle"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="wald"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start[data-buehne="portal"]::before { background-image: url("../img/buehne-dogfather-schmal.webp"); }
body.start > .schleier {
background:
linear-gradient(180deg, rgba(5, 7, 13, .86) 0%, rgba(5, 7, 13, .48) 14%,
rgba(5, 7, 13, .3) 55%, rgba(5, 7, 13, .66) 100%),
radial-gradient(90% 40% at 20% 4%, rgba(63, 189, 245, .06), transparent 70%),
radial-gradient(90% 40% at 85% 98%, rgba(138, 118, 255, .07), transparent 72%);
}
}
/* ---------- Kopfleiste ------------------------------------------------ */
.kopfleiste {
position: sticky; top: 0; z-index: 5;
display: flex; align-items: center; justify-content: space-between; gap: 16px;
padding: 14px clamp(16px, 4vw, 40px);
background: rgba(6, 9, 16, .82);
backdrop-filter: blur(18px);
-webkit-backdrop-filter: blur(18px);
border-bottom: 1px solid var(--rand);
}
/* Damit in einer Flex-Zeile ueberhaupt etwas schrumpfen KANN, braucht es
min-width: 0. Ohne diese eine Zeile behielt jedes Teil seine volle
Wunschbreite -- Zurueck (118) + Marke (141) + rechte Gruppe (297)
ergaben 556 px auf einem 390 px breiten Handy. Die Kopfleiste schob
214 px aus dem Bild und der Abmelden-Knopf war dort nicht mehr zu
erreichen. Auf JEDER Seite, seit es die Kopfleiste gibt; aufgefallen
erst beim Messen, weil man am Rechner nie danebengreift. */
.kopfleiste > * { min-width: 0; }
.kopfleiste .marke {
margin: 0; font-size: .72rem;
/* Die Marke gibt als Erstes nach: Ihr Inhalt steht direkt darunter
noch einmal als Ueberschrift, der Abmelden-Knopf dagegen nirgends. */
flex: 1 1 auto;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Zurück-Knopf. Steht ganz links, weil dort jeder ihn erwartet -- gleiche
Stelle wie im Browser. Auf der Startseite gibt es ihn gar nicht: Dort
ist kein "davor", und ein Knopf, der nichts tut, ist schlimmer als
keiner. Auf den übrigen Seiten entscheidet kopf.js, ob er erscheint. */
/* Entwurf "Neon-Kante": Der senkrechte Lichtstrich links ist dasselbe
Motiv wie die Kante der Anmelde-Tafel (.tafel__kante in gate.css).
Dadurch wirkt der Workspace wie ein Stück und nicht wie zusammen-
gesetzte Teile. */
.zurueck-knopf {
position: relative;
flex: 0 0 auto;
display: inline-flex; align-items: center; gap: 10px;
padding: 9px 18px 9px 17px;
border: 0;
/* Links flach, rechts rund: Die gerade Kante gehört dem Lichtstrich,
nach rechts läuft der Knopf weich aus. */
border-radius: 4px 999px 999px 4px;
background: linear-gradient(100deg,
rgba(63, 189, 245, .10), rgba(138, 118, 255, .05) 60%, transparent);
color: var(--text-leise);
font: inherit; font-size: .84rem; font-weight: 600;
cursor: pointer; white-space: nowrap;
transition: color var(--tempo), background var(--tempo);
}
/* Der Lichtstrich. Ruht etwas kürzer als der Knopf und wächst beim
Überfahren auf volle Höhe -- die Bewegung ersetzt jedes Aufblitzen. */
.zurueck-knopf::before {
content: "";
position: absolute; left: 0; top: 6px; bottom: 6px; width: 2px;
border-radius: 2px;
background: linear-gradient(180deg, var(--akzent), var(--violett));
box-shadow: 0 0 8px -1px rgba(63, 189, 245, .55);
transition: top var(--tempo), bottom var(--tempo), box-shadow var(--tempo);
}
.zurueck-knopf__pfeil {
width: 15px; height: 15px; flex: 0 0 auto;
fill: none; stroke: currentColor;
stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
transition: transform var(--tempo);
}
.zurueck-knopf:hover {
color: #fff;
background: linear-gradient(100deg,
rgba(63, 189, 245, .18), rgba(138, 118, 255, .09) 60%, transparent);
}
.zurueck-knopf:hover::before {
top: 0; bottom: 0;
box-shadow: 0 0 14px 0 rgba(63, 189, 245, .75);
}
/* Der Pfeil rückt nach links -- sagt die Richtung ohne zusätzlichen Text. */
.zurueck-knopf:hover .zurueck-knopf__pfeil { transform: translateX(-3px); }
.zurueck-knopf:active { transform: translateY(1px); }
.zurueck-knopf:focus-visible {
outline: 2px solid var(--akzent);
outline-offset: 3px;
border-radius: 4px 999px 999px 4px;
}
@media (prefers-reduced-motion: reduce) {
.zurueck-knopf, .zurueck-knopf::before, .zurueck-knopf__pfeil { transition: none; }
.zurueck-knopf:hover .zurueck-knopf__pfeil { transform: none; }
}
.kopfleiste__rechts { display: flex; align-items: center; gap: 12px; flex: 0 1 auto; min-width: 0; }
.kopfleiste__rechts > * { flex: 0 0 auto; }
.wer {
font-size: .86rem; color: var(--text-leise);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 46vw;
/* Der Name darf kuerzer werden -- der Knopf daneben nicht. */
flex: 0 1 auto; min-width: 0;
}
/* ---------- Inhalt ---------------------------------------------------- */
.inhalt {
max-width: 880px;
margin: 0 auto;
padding: clamp(28px, 5vw, 56px) clamp(16px, 4vw, 40px) 64px;
}
/* Diese vier standen bis zum 31.08.2026 in aufgaben.css -- also in einer
Datei, die eine neue Seite gar nicht laden muss. Genau dadurch war das
Dashboard beim ersten Aufbau schmal und ohne Kopfzeilen-Layout: die
Klassen im HTML gab es, die Regeln dazu nicht. Derselbe Fehler ist
vorher schon zweimal passiert (.knopf-still, .schalter). Was auf
mehreren Seiten benutzt wird, gehoert hierher, wo jede Seite es hat. */
.inhalt--breit { max-width: 1240px; }
.zurueck { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
.zurueck:hover { border-bottom-color: currentColor; }
/* ---------- Der Kopf jeder Unterseite ------------------------------------
Bis zum 01.09.2026 war das eine Zeile Text mit einem Knopf daneben --
auf allen dreizehn Seiten dieselbe, in derselben Farbe, ohne Zeichen.
Wer eine Kachel anklickte, verlor beim Übergang jede Spur davon,
woher er kam.
Jetzt trägt der Kopf Zeichen UND Farbton seiner Kachel (gesetzt von
kopf.js aus derselben Liste, aus der auch die Kachel kommt) und
bekommt dieselbe Behandlung wie sie: Plakette mit dem Zeichen, ein
leuchtender Strich über der Bereichsangabe, ein sehr schwaches
Wasserzeichen dahinter und eine auslaufende Trennlinie darunter.
Nichts davon ist Schmuck um seiner selbst willen: Es ist dieselbe
Bildsprache wie auf der Startseite, und dadurch weiß man ohne Lesen,
wo man ist. */
.kopf-zeile {
position: relative;
overflow: hidden;
display: flex; align-items: flex-end; justify-content: space-between;
gap: 20px; flex-wrap: wrap;
margin-bottom: 28px; padding: 0 0 20px;
border-bottom: 1px solid transparent;
border-image: linear-gradient(90deg,
color-mix(in srgb, var(--ton, var(--akzent)) 40%, var(--rand-hell)),
transparent 62%) 1;
}
.kopf-zeile .titel {
margin: 0;
font-size: clamp(1.5rem, 2.6vw, 2.1rem);
letter-spacing: -.02em;
color: #f2f7fd;
text-shadow: 0 2px 22px color-mix(in srgb, var(--ton, var(--akzent)) 22%, transparent);
}
.kopf-zeile .unterzeile { margin-bottom: 0; }
/* Zeichen und Text nebeneinander. Der Block darf schrumpfen (min-width),
sonst drückt er den Knopf rechts aus dem Bild -- derselbe Fehler wie
im August in der Kopfleiste. */
.kopf-zeile__marke {
display: flex; align-items: center; gap: 16px;
min-width: 0; flex: 1 1 auto;
position: relative; z-index: 1;
}
.kopf-zeichen {
flex: none;
display: grid; place-items: center;
width: 52px; height: 52px; border-radius: 15px;
border: 1px solid color-mix(in srgb, var(--ton, var(--akzent)) 34%, transparent);
background:
radial-gradient(120% 120% at 30% 18%,
color-mix(in srgb, var(--ton, var(--akzent)) 26%, transparent), transparent 72%),
rgba(255, 255, 255, .04);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .09),
0 12px 28px -14px color-mix(in srgb, var(--ton, var(--akzent)) 70%, transparent);
}
.kopf-zeichen__svg {
width: 26px; height: 26px;
fill: none; stroke: var(--ton, var(--akzent)); stroke-width: 1.6;
stroke-linecap: round; stroke-linejoin: round;
}
/* Der Bereichsname über dem Titel bekommt denselben leuchtenden Strich
wie die Abschnitte auf der Startseite -- so gehört sichtbar zusammen,
was zusammengehört. */
.kopf-zeile .marke {
display: flex; align-items: center; gap: 9px;
margin-bottom: 7px;
color: color-mix(in srgb, var(--ton, var(--akzent)) 62%, #cfe0f0);
}
.kopf-zeile .marke::before {
content: "";
width: 22px; height: 2px; border-radius: 2px;
background: linear-gradient(90deg, var(--ton, var(--akzent)), transparent);
}
/* Dasselbe Zeichen noch einmal, riesig und fast unsichtbar. Es liegt im
Kopf (overflow: hidden schneidet es sauber ab) und macht jede Seite
auf den ersten Blick unverwechselbar, ohne dass man es bewusst
wahrnimmt. */
.kopf-wasserzeichen {
position: absolute; right: -18px; top: 50%;
transform: translateY(-50%) rotate(-8deg);
pointer-events: none;
opacity: .06;
z-index: 0;
}
.kopf-wasserzeichen__svg {
width: 190px; height: 190px;
fill: none; stroke: var(--ton, var(--akzent)); stroke-width: 1;
stroke-linecap: round; stroke-linejoin: round;
}
/* Auf schmalen Bildschirmen läge das Wasserzeichen unter dem Text und
würde ihn unruhig machen -- dort bleibt es weg. */
@media (max-width: 720px) {
.kopf-wasserzeichen { display: none; }
.kopf-zeichen { width: 42px; height: 42px; border-radius: 12px; }
.kopf-zeichen__svg { width: 21px; height: 21px; }
.kopf-zeile__marke { gap: 12px; }
}
@media (forced-colors: active) {
.kopf-wasserzeichen { display: none; }
.kopf-zeichen__svg { stroke: CanvasText; }
}
.leise { color: var(--text-still); font-weight: 400; }
/* ---------- Wenn nichts da ist -------------------------------------------
Diese Regel stand in NEUN Dateien -- neunmal fast dasselbe, mit
Abständen von 22, 26 und 30 px, weil beim Kopieren jedes Mal etwas
anders wurde. Genau davor warnt der Kommentar weiter oben. Jetzt
einmal hier, und jede Seite hat sie.
Wichtiger als das Aufräumen ist aber, WIE der leere Zustand aussieht.
Vorher: ein gestrichelter Kasten mit einem grauen Satz. Gestrichelte
Ränder sagen "hier fehlt etwas", und grau auf grau sagt "unwichtig" --
zusammen also: eine kaputt wirkende Seite, obwohl gar nichts kaputt
ist. Eine leere Liste ist ein normaler Zustand, oft sogar ein guter.
Jetzt: eine ruhige, geschlossene Fläche im Farbton der Seite (der
kommt aus data-ton am body, gesetzt von kopf.js), mit einem
leuchtenden Ring darüber. Sie sieht aus wie ein fertiges Bauteil und
nicht wie ein Loch. */
.leer-hinweis {
position: relative; overflow: hidden;
padding: 34px 26px 32px;
text-align: center;
color: var(--text-leise); font-size: .92rem; line-height: 1.6;
border: 1px solid color-mix(in srgb, var(--ton, var(--akzent)) 20%, var(--rand));
border-radius: var(--radius);
/* Ein Stueck dichter als die uebrige Flaeche (0,88 statt 0,78) --
Wunsch vom 01.09.2026: "ganz leicht noch dunkler, so dass man den
Text besser gelesen bekommt, aber auch nicht zu viel, so dass man
den Hasen noch sieht."
Diese Kaesten tragen mehr zusammenhaengenden Text als jede andere
Flaeche im Workspace (der Erklaerkasten im Scouting sind acht
Absaetze). Zehn Punkte mehr Deckung sind gemessen der Unterschied
zwischen muehsam und ruhig lesbar -- und lassen zwoelf Prozent Bild
durch, das Motiv bleibt also sichtbar. Mehr waere ein Kasten mit
einem Bild dahinter, das man nur noch erahnt. */
background:
radial-gradient(120% 90% at 50% -10%,
color-mix(in srgb, var(--ton, var(--akzent)) 9%, transparent), transparent 68%),
rgba(9, 13, 22, .88);
}
/* Der Ring: ein Kreis in der Seitenfarbe, hohl, weich leuchtend. Ein
Zeichen wäre hier zu laut -- es geht ja gerade darum, dass NICHTS da
ist. Der Ring markiert die Stelle, ohne etwas zu behaupten. */
.leer-hinweis::before {
content: "";
display: block;
width: 34px; height: 34px;
margin: 0 auto 14px;
border-radius: 50%;
border: 1.5px solid color-mix(in srgb, var(--ton, var(--akzent)) 40%, transparent);
background: radial-gradient(circle,
color-mix(in srgb, var(--ton, var(--akzent)) 22%, transparent), transparent 70%);
box-shadow: 0 0 22px -6px color-mix(in srgb, var(--ton, var(--akzent)) 60%, transparent);
}
/* Ein zweiter Satz darin ist der Tipp, was man jetzt tun kann. Wenn
schon nichts dasteht, soll wenigstens dastehen, wie etwas hinkommt. */
.leer-hinweis__tipp {
display: block; margin-top: 7px;
font-size: .82rem; color: var(--text-still);
}
@media (forced-colors: active) {
.leer-hinweis::before { border-color: CanvasText; background: none; }
}
/* ---------- Auf- und Zuklappen ------------------------------------------
Lange Listen (Protokoll, Verlauf) stehen zugeklappt da und zeigen nur
die neuesten Zeilen. Der Pfeil dreht sich beim Aufklappen -- er zeigt
die Richtung, der Text daneben sagt, was der Knopf TUT.
Steht hier und nicht in einer Seiten-Datei: Er wird an mehreren
Stellen gebraucht, und genau so sind schon dreimal Regeln dort
gelandet, wo eine Seite sie gar nicht laedt. */
.klapp-kopf {
display: flex; align-items: center; justify-content: space-between;
gap: 12px; flex-wrap: wrap; margin-bottom: 8px;
}
.klapp-kopf > .feldschild, .klapp-kopf > .block__titel { margin: 0; }
.klapp-pfeil {
width: 14px; height: 14px; flex: 0 0 auto;
fill: none; stroke: currentColor;
stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
transition: transform var(--tempo);
}
[aria-expanded="true"] > .klapp-pfeil { transform: rotate(180deg); }
/* Zugeklappt bleiben die vier neuesten Zeilen stehen. Bewusst ueber CSS
statt ueber das Entfernen von Zeilen: Das Aufklappen braucht dann
weder einen neuen Aufbau noch eine zweite Abfrage. */
[data-klapp="zu"] > *:nth-child(n+5) { display: none; }
.willkommen { margin-bottom: 38px; }
.willkommen .titel { margin-bottom: 6px; }
/* ---------- Zahlen ---------------------------------------------------- */
.zahlen-block { margin-bottom: 34px; }
.zahlen {
list-style: none; margin: 0; padding: 0;
display: grid; gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(min(122px, 100%), 1fr));
}
.zahl {
padding: 14px 16px;
background: var(--flaeche);
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
}
.zahl__wert { display: block; font-size: 1.7rem; font-weight: 700; line-height: 1.1; }
.zahl__name { display: block; margin-top: 2px; font-size: .78rem; color: var(--text-still); }
/* Nur wenn wirklich etwas überfällig ist, wird die Kachel hervorgehoben --
sonst stumpft die Farbe ab und man übersieht sie im Ernstfall. */
.zahl[data-warn="ja"] { border-color: rgba(255, 154, 162, .42); background: rgba(255, 154, 162, .07); }
.zahl[data-warn="ja"] .zahl__wert { color: var(--warn); }
/* ---------- Bereiche: Gruppen und Kacheln --------------------------------
Vorher: siebzehn gleiche Rechtecke mit "ÖFFNEN" darauf. Wenn alles
gleich aussieht, ist alles gleich wichtig -- also nichts.
Drei Dinge tragen jetzt die Gestaltung:
1. Die Kachel ist ruhig, bis man sie ansieht. Der Farbton sitzt im
Zeichen und in einer schmalen Kante -- nicht als Fläche. Siebzehn
farbige Flächen wären ein Bonbonglas, kein Werkzeug.
2. Beim Überfahren geht ein sehr weicher Schimmer aus der oberen
linken Ecke an. Kein Blitzen, kein Springen: Alphawerte unter 0.25,
Bewegung unter einem Pixel.
3. Der Einlauf ist gestaffelt -- genau EINE Bewegung beim Aufbau,
danach Ruhe. Bei "weniger Bewegung" fällt sie ersatzlos weg.
Die acht Farbtöne sind gegen genau diesen Hintergrund gerechnet:
Helligkeitsband, Farbstärke, Abstand bei Farbfehlsichtigkeit
(schlechtestes Paar dE 8.4), Normalsicht-Abstand (19.3) und Kontrast
-- alle Prüfungen bestanden. Warum acht und nicht siebzehn: Siebzehn
unterscheidbare Farben gibt es nicht; ein Versuch mit einer eigenen
Farbe je Kachel ergab Paare mit Abstand 1.4, also praktisch dieselbe
Farbe. Sie stützen nur -- WAS eine Kachel ist, sagen Zeichen und Name.
------------------------------------------------------------------------- */
.gruppe { margin-bottom: 34px; }
.gruppe:last-child { margin-bottom: 0; }
.gruppe__kopf {
position: relative;
display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
margin-bottom: 14px; padding-bottom: 10px;
/* Die Trennlinie läuft nach rechts aus, statt hart abzubrechen --
eine durchgezogene Linie über die ganze Breite zerschneidet die
Seite, eine auslaufende gliedert sie nur. */
border-bottom: 1px solid transparent;
border-image: linear-gradient(90deg, var(--rand-hell), transparent 70%) 1;
}
.gruppe__name {
margin: 0; font-size: .76rem; font-weight: 700;
letter-spacing: .1em; text-transform: uppercase; color: var(--text-leise);
}
.gruppe__unter { font-size: .78rem; color: var(--text-still); }
.kacheln {
list-style: none; margin: 0; padding: 0;
display: grid; gap: 12px;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
/* Siebzehn eigene Töne -- einer je Kachel. Nicht gewählt, sondern
gerechnet: gleichmäßig um den Farbkreis verteilt, in OKLCH bei
konstanter Helligkeit und Farbstärke, damit keine sich vordrängt.
Erzeugt von tools/kachel-farben.mjs; dort steht auch, warum.
Die ZUORDNUNG ist ebenfalls gerechnet. Das Auge vergleicht nur, was
NEBENEINANDER liegt -- gesucht wurde deshalb die Anordnung mit dem
größtmöglichen kleinsten Abstand zweier Nachbarn im Raster. Ergebnis:
mindestens 105,9 Grad zwischen allen Nachbarn. Zum Vergleich: Der
erste Versuch mit frei gewählten Farben hatte Paare bei 1,4 Grad.
Unter allen Anordnungen, die das schaffen, wurde die passendste
genommen -- LIVE rot, Technik gelb, Reports grün, Personen rot-gold.
Geprüft gegen genau diesen Hintergrund: Helligkeitsband, Farbstärke
und Kontrast bestehen für alle siebzehn.
Die Töne hängen bewusst NICHT an .kachel, sondern nur am Merkmal
data-ton: Dieselbe Nummer färbt die Kachel und die Hinweiszeile, die
dorthin führt. Eine Farbe gehört hier zu einem Bereich, nicht zu einem
Bauteil. */
[data-ton="1"] { --ton: #3e95e7; }
[data-ton="2"] { --ton: #6e89eb; }
[data-ton="3"] { --ton: #917ee4; }
[data-ton="4"] { --ton: #ac74d3; }
[data-ton="5"] { --ton: #c26cbb; }
[data-ton="6"] { --ton: #d1679d; }
[data-ton="7"] { --ton: #da657c; }
[data-ton="8"] { --ton: #dc6958; }
[data-ton="9"] { --ton: #d67130; }
[data-ton="10"] { --ton: #c67f09; }
[data-ton="11"] { --ton: #b08c09; }
[data-ton="12"] { --ton: #97970e; }
[data-ton="13"] { --ton: #72a234; }
[data-ton="14"] { --ton: #3ea95e; }
[data-ton="15"] { --ton: #0ba985; }
[data-ton="16"] { --ton: #08a6a0; }
[data-ton="17"] { --ton: #0aa3b6; }
[data-ton="18"] { --ton: #0f9ecf; } /* Start-Check */
/* Rückfallwert für alles, was einen Ton braucht, aber keine Nummer hat.
Steht bewusst in :where() -- damit zählt die Zeile beim Wettstreit der
Regeln als NICHT vorhanden und die Nummer oben gewinnt immer. Ohne
das Kniff hätte diese Zeile (eine Klasse, weiter unten in der Datei)
alle siebzehn Töne überstimmt und jede Kachel wäre blau gewesen. */
:where(.kachel, .dran__punkt) { --ton: var(--akzent); }
.kachel {
/* Wo der Zeiger steht. Wird von start.js gesetzt; die Mitte ist der
Rückfallwert, damit ohne Zeiger nichts springt. */
--mx: 50%;
--my: 0%;
position: relative;
border-radius: 18px;
background:
linear-gradient(155deg,
color-mix(in srgb, var(--ton) 26%, var(--flaeche)),
var(--flaeche) 62%);
border: 1px solid var(--rand);
/* Die feine helle Linie an der Oberkante. Ein Pixel, kaum sichtbar --
aber die Kachel wirkt dadurch von oben beleuchtet statt aufgeklebt.
Das ist der Unterschied zwischen "Kasten" und "Objekt". */
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .055);
overflow: hidden;
transition: border-color var(--tempo), transform var(--tempo), box-shadow var(--tempo);
}
.kachel[data-gross="ja"] { grid-column: span 2; }
/* Die farbige Kante links. Sie ist das Einzige, was den Ton kräftig
zeigt -- drei Pixel reichen, um eine Kachel wiederzuerkennen. */
.kachel::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
background: linear-gradient(180deg, var(--ton), transparent 92%);
opacity: .55;
transition: opacity var(--tempo), width var(--tempo);
}
/* Das Licht. Es liegt schwach auf der Kachel und FOLGT beim Überfahren
dem Zeiger -- das ist die Kleinigkeit, die man nicht sieht, sondern
erst beim Benutzen merkt. Kein Blinken, keine Bewegung des Inhalts:
Es wird nur an einer anderen Stelle heller.
Ruhend sitzt es in der oberen linken Ecke (--my: 0%), damit die
Kacheln auch ohne Zeiger von einer Seite beleuchtet wirken. */
.kachel::after {
content: ""; position: absolute; inset: 0; pointer-events: none;
background: radial-gradient(130% 150% at var(--mx) var(--my),
color-mix(in srgb, var(--ton) 20%, transparent), transparent 60%);
opacity: .38;
transition: opacity var(--tempo);
}
.kachel:hover {
border-color: color-mix(in srgb, var(--ton) 45%, var(--rand));
transform: translateY(-2px);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .09),
0 10px 26px -14px color-mix(in srgb, var(--ton) 55%, transparent);
}
.kachel:hover::before { opacity: 1; width: 4px; }
.kachel:hover::after { opacity: 1; }
.kachel:has(:focus-visible) { border-color: var(--ton); }
.kachel__link {
position: relative; z-index: 1;
display: flex; align-items: center; gap: 15px;
padding: 21px 20px 21px 23px;
color: inherit; text-decoration: none;
}
/* Das Wasserzeichen. Dasselbe Zeichen wie im Feld links, aber riesig,
angeschnitten und fast unsichtbar in der rechten unteren Ecke.
Es ist der Grund, warum siebzehn Kacheln nicht mehr wie siebzehn
Kästen aussehen: Jede bekommt eine eigene große Form, ohne dass ein
einziges zusätzliches Bild geladen wird. Bewusst so schwach, dass man
es nicht liest, sondern nur spürt -- eine Kachel soll ihren Namen
tragen, nicht ihr Zeichen. */
.kachel__wasserzeichen {
position: absolute; right: -14px; bottom: -26px;
width: 132px; height: 132px;
pointer-events: none; z-index: 0;
opacity: .07;
transform: rotate(-8deg);
transition: opacity var(--tempo), transform var(--tempo);
}
.kachel__wasserzeichen svg {
width: 100%; height: 100%;
fill: none; stroke: var(--ton);
stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round;
}
.kachel:hover .kachel__wasserzeichen {
opacity: .13;
transform: rotate(-8deg) translate(-4px, -4px) scale(1.04);
}
.kachel[data-gross="ja"] .kachel__wasserzeichen {
width: 168px; height: 168px; right: -18px; bottom: -34px;
}
.kachel__link:focus-visible {
outline: 2px solid var(--ton); outline-offset: -4px; border-radius: 15px;
}
/* Das Zeichen sitzt in einem eigenen Feld -- dadurch bekommt der Ton
eine Fläche, ohne dass die ganze Kachel farbig wird. Der Verlauf und
der innere Lichtrand darin lassen es geprägt statt gemalt wirken. */
/* ---------- Die Plakette (neu gebaut 03.09.2026) -------------------------
Sie war ein leicht getöntes Quadrat. Jetzt ist sie ein KÖRPER:
* ein Verlauf über die Diagonale statt einer flachen Tönung
* eine Lichtkante oben INNEN und eine Schattenkante unten innen --
zusammen ergibt das eine Wölbung, das Feld wirkt geprägt
* ein Hof in der eigenen Farbe darunter, der die Plakette von der
Kachel abhebt
* darüber ein Glanzbogen (::before), der von links oben einfällt
Alles bleibt gedeckt. Ein leuchtender Kasten wäre in einer dunklen
Oberfläche eine Lampe -- und Lampen schaut man nicht stundenlang an. */
.kachel__zeichen {
position: relative; z-index: 1;
flex: none; overflow: hidden;
display: grid; place-items: center;
width: 58px; height: 58px; border-radius: 17px;
background:
radial-gradient(120% 100% at 22% 8%,
color-mix(in srgb, var(--ton) 46%, transparent) 0%,
color-mix(in srgb, var(--ton) 22%, transparent) 46%,
color-mix(in srgb, var(--ton) 8%, transparent) 100%);
border: 1px solid color-mix(in srgb, var(--ton) 40%, transparent);
box-shadow:
/* Wölbung: Licht oben innen, Schatten unten innen. */
inset 0 1.5px 0 color-mix(in srgb, #fff 26%, transparent),
inset 0 -2px 6px -3px color-mix(in srgb, #000 55%, transparent),
/* Der Hof -- er trägt die Plakette, ohne zu leuchten. */
0 6px 18px -9px color-mix(in srgb, var(--ton) 85%, transparent),
0 0 0 1px color-mix(in srgb, var(--ton) 10%, transparent);
transition: background var(--tempo), border-color var(--tempo),
transform var(--tempo), box-shadow var(--tempo);
}
/* Der Glanzbogen. Ein schmaler heller Streifen, der von links oben über
die Plakette läuft -- dasselbe Licht, das auch die Zeichen von oben
trifft. Er liegt UNTER dem Zeichen (z-index 0 gegen 1), damit er es
nicht überstrahlt. */
.kachel__zeichen::before {
content: "";
position: absolute; inset: 0;
background: linear-gradient(150deg,
rgba(255, 255, 255, .22) 0%,
rgba(255, 255, 255, .07) 28%,
rgba(255, 255, 255, 0) 55%);
pointer-events: none;
transition: opacity var(--tempo);
}
.kachel:hover .kachel__zeichen {
transform: translateY(-1px);
border-color: color-mix(in srgb, var(--ton) 62%, transparent);
box-shadow:
inset 0 1.5px 0 color-mix(in srgb, #fff 34%, transparent),
inset 0 -2px 6px -3px color-mix(in srgb, #000 55%, transparent),
0 10px 24px -10px color-mix(in srgb, var(--ton) 95%, transparent),
0 0 0 1px color-mix(in srgb, var(--ton) 18%, transparent);
}
@media (prefers-reduced-motion: reduce) {
.kachel__zeichen, .kachel:hover .kachel__zeichen { transition: none; transform: none; }
}
@media (forced-colors: active) {
.kachel__zeichen::before { display: none; }
}
.kachel:hover .kachel__zeichen {
background:
linear-gradient(160deg,
color-mix(in srgb, var(--ton) 46%, transparent),
color-mix(in srgb, var(--ton) 16%, transparent));
border-color: color-mix(in srgb, var(--ton) 62%, transparent);
transform: scale(1.05);
box-shadow:
inset 0 1px 0 color-mix(in srgb, var(--ton) 55%, transparent),
0 6px 20px -8px color-mix(in srgb, var(--ton) 85%, transparent);
}
.kachel[data-gross="ja"] .kachel__zeichen { width: 70px; height: 70px; border-radius: 21px; }
/* ---------- Die Zeichen (überarbeitet 03.09.2026) ------------------------
Vorher: eine flache Linie in einer Farbe, siebzehnmal nebeneinander.
Sauber, aber leblos.
Jetzt zweierlei, und beides berührt die Zwischenräume nicht:
VERLAUF Die Linie ist oben hell und wird nach unten gedämpft
-- eine Lichtquelle über dem Zeichen, wie in der
echten Welt. Genau das lässt eine Linie geprägt statt
gemalt wirken.
SCHLAGSCHATTEN Ein weicher Schein um das GANZE Zeichen, in seiner
eigenen Farbe. Er hebt es von der Kachelfläche ab.
Der Verlauf ist EINMAL im Dokument definiert (bereiche.js) und
arbeitet mit currentColor. `color: var(--ton)` steht deshalb hier am
SVG -- so nimmt derselbe eine Verlauf den Ton jeder der siebzehn
Kacheln an. Siebzehn Farben, ein Verlauf. */
.kachel__svg {
/* 29 statt 25: Zusammen mit der kräftigeren Linie ist das der
sichtbarste Teil der Überarbeitung. */
width: 29px; height: 29px;
color: var(--ton);
fill: none;
stroke-linecap: round; stroke-linejoin: round;
/* Ein sehr weicher Schein um das ganze Zeichen. Gedeckt gehalten:
Er soll Tiefe geben, nicht leuchten. */
filter: drop-shadow(0 1px 3px color-mix(in srgb, var(--ton) 45%, transparent));
transition: transform var(--tempo), filter var(--tempo);
}
/* ---------- Der Körper (03.09.2026, dritte Stufe) ------------------------
Die Zeichen sind keine Zeichnungen mehr, sondern KÖRPER. Aufbau von
hinten nach vorn:
tiefe3/2/1 dieselbe Silhouette, je einen halben Rasterpunkt
versetzt und heller werdend. Das Auge liest die drei
Kanten als EINE schräge Seitenwand -- so zeichnet man
einen Quader von Hand.
deck die Oberseite: oben fast weiss, unten im Farbton.
Die Fläche, auf die das Licht fällt.
glanz die Spiegelung darauf.
linie die Details -- Querstriche, Haken, Wellen. Sie liegen
AUF der Deckfläche und bekommen keine Tiefe: Ein
aufgedruckter Strich steht nicht hervor.
Drei Tiefenlagen sind gemessen: bei zwei sieht es aus wie ein
Druckfehler, ab fünf wie ein Schlagschatten. */
.kachel__svg .zeichen__tiefe3,
.kachel__svg .zeichen__tiefe2,
.kachel__svg .zeichen__tiefe1 {
stroke: none;
}
.kachel__svg .zeichen__tiefe3 { fill: rgba(0, 0, 0, .55); }
.kachel__svg .zeichen__tiefe2 { fill: url(#zeichen-wand); opacity: .85; }
.kachel__svg .zeichen__tiefe1 { fill: url(#zeichen-wand); }
.kachel__svg .zeichen__deck {
fill: url(#zeichen-deck);
stroke: none;
}
/* Der Saum: dunkel und breiter, liegt UNTER der hellen Linie. Auf der
hellen Deckfläche liest man beide zusammen als eingravierte Rille,
auf der dunklen Plakette verschwindet er und nur die helle Linie
bleibt. */
.kachel__svg .zeichen__saum {
fill: none;
stroke: rgba(6, 10, 16, .78);
stroke-width: 3.4;
stroke-linecap: round; stroke-linejoin: round;
}
.kachel__svg .zeichen__linie {
stroke: url(#zeichen-linie);
/* 2,05 statt 1,65: Die Zeichen sollen TRAGEN, nicht andeuten. Eine
dünne Linie wirkt neben kräftigem Text zaghaft -- und zaghaft war
genau das Problem. */
stroke-width: 1.9;
paint-order: stroke fill;
}
/* DIE SCHEIN-LAGE IST WIEDER WEG (03.09.2026) -- und der Weg dorthin
gehört aufgeschrieben, damit sie niemand ein zweites Mal einbaut.
Die Idee war gut: eine dicke, weiche Kopie unter der Linie, damit das
Zeichen schwebt statt flach aufzuliegen. Bei einem grossen Symbol
funktioniert das. Hier nicht.
Ein Zeichen ist 24 Einheiten breit und 25 px gross -- eine Einheit ist
also ein Pixel. Die Querlinie im Kalender sitzt vier Einheiten unter
der Oberkante, die Striche im Technik-Zeichen 4,5 auseinander. Eine
Linie von 1,65 plus ein Schein von 2,5 füllt davon so viel, dass die
Lücke verschwindet: Aus dem Kalender wurde ein leerer Kasten, aus den
Reglern drei Punkte ohne Striche.
Gesehen habe ich das erst bei dreifacher Vergrösserung -- auf dem
normalen Schirm sah es nur "etwas satter" aus. Wer kleine Zeichen
nach dem Gesamteindruck beurteilt, übersieht genau das.
Was bleibt, wirkt ohne die Lücken zu fressen: der VERLAUF in der
Linie (Licht von oben) und ein weicher Schlagschatten um das ganze
Zeichen. Beides berührt die Zwischenräume nicht. */
/* Beim Überfahren rückt das Zeichen einen Hauch nach vorn und der
Schein wird kräftiger -- als käme die Lichtquelle näher. Ein Hauch:
Zwei Pixel sind zu sehen, acht wären Zappeln. */
.kachel:hover .kachel__svg {
transform: translateY(-1px) scale(1.04);
filter: drop-shadow(0 2px 7px color-mix(in srgb, var(--ton) 62%, transparent));
}
.kachel[data-gross="ja"] .kachel__svg { width: 36px; height: 36px; }
@media (prefers-reduced-motion: reduce) {
.kachel__svg, .kachel:hover .kachel__svg { transition: none; transform: none; }
}
@media (forced-colors: active) {
/* Ohne Farben trägt allein die Linie. Der Schein wäre dort ein
grauer Klecks über der Zeichnung. */
.kachel__svg { filter: none; }
.kachel__svg .zeichen__linie { stroke: CanvasText; }
}
.kachel__text { position: relative; z-index: 1; display: grid; gap: 3px; min-width: 0; }
.kachel__name {
font-size: 1.06rem; font-weight: 650; letter-spacing: -.014em; line-height: 1.25;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kachel[data-gross="ja"] .kachel__name { font-size: 1.24rem; }
.kachel__unter {
font-size: .78rem; color: var(--text-still); line-height: 1.3;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kachel[data-gross="ja"] .kachel__unter { font-size: .83rem; }
/* Die Zahl auf der Kachel. Sie ersetzt den Pfeil, wenn dort Arbeit
liegt -- eine Kachel, die "3" sagt, ist zehnmal mehr wert als eine,
die "öffnen" sagt. */
.kachel__zahl {
position: relative; z-index: 1;
flex: none; margin-left: auto;
min-width: 32px; padding: 5px 11px;
text-align: center; font-size: .9rem; font-weight: 700;
font-variant-numeric: tabular-nums;
color: var(--ton);
background: color-mix(in srgb, var(--ton) 15%, transparent);
border: 1px solid color-mix(in srgb, var(--ton) 36%, transparent);
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--ton) 26%, transparent);
border-radius: 999px;
transition: background var(--tempo), border-color var(--tempo);
}
.kachel:hover .kachel__zahl {
background: color-mix(in srgb, var(--ton) 24%, transparent);
border-color: color-mix(in srgb, var(--ton) 55%, transparent);
}
.kachel__zahl[data-warn="ja"] {
color: var(--warn);
background: rgba(255, 154, 162, .13);
border-color: rgba(255, 154, 162, .44);
box-shadow: inset 0 1px 0 rgba(255, 154, 162, .28);
}
.kachel:hover .kachel__zahl[data-warn="ja"] {
background: rgba(255, 154, 162, .2); border-color: rgba(255, 154, 162, .62);
}
.kachel__pfeil {
position: relative; z-index: 1;
flex: none; margin-left: auto;
color: var(--text-still); font-size: 1rem;
transition: color var(--tempo), transform var(--tempo);
}
.kachel:hover .kachel__pfeil { color: var(--ton); transform: translateX(4px); }
/* Gestaffelter Einlauf. Die Verzögerung kommt aus --nr, das start.js je
Kachel setzt. Steht in einer no-preference-Abfrage, damit bei
"weniger Bewegung" gar keine Animation entsteht -- nicht nur eine
ohne Dauer. */
@media (prefers-reduced-motion: no-preference) {
.kachel {
animation: kachel-ein .38s cubic-bezier(.32, 0, .2, 1) backwards;
animation-delay: calc(var(--nr, 0) * 26ms);
}
@keyframes kachel-ein {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: none; }
}
}
/* Der leere Zustand ist kein Fehler, sondern das Ziel -- deshalb ein
ruhiges Gruen statt gestrichelter Leere. Gedeckt gehalten, kein
Signalgruen: Es soll freuen, nicht blenden. */
.zahlen-leer {
display: flex; align-items: center; gap: 13px;
margin: 0; padding: 14px 17px;
font-size: .9rem; color: var(--text);
border: 1px solid rgba(80, 167, 130, .28);
border-radius: var(--radius-klein);
background: linear-gradient(90deg, rgba(80, 167, 130, .1), transparent 60%);
}
.zahlen-leer__haken {
flex: none; display: grid; place-items: center;
width: 30px; height: 30px; border-radius: 50%;
border: 1px solid rgba(80, 167, 130, .38);
background: rgba(80, 167, 130, .14);
}
.zahlen-leer__haken svg {
width: 16px; height: 16px;
fill: none; stroke: #6fbd95; stroke-width: 2;
stroke-linecap: round; stroke-linejoin: round;
}
/* Pflicht, sobald hier ein display steht: Das display der Klasse ist
staerker als das hidden des Browsers -- ohne diese Zeile stuende der
Satz IMMER da, auch wenn Aufgaben offen sind. */
.zahlen-leer[hidden] { display: none; }
.zahlen-leer__still { color: var(--text-leise); }
.zahlen-leer strong { font-weight: 650; }
.zahlen-leer strong::after { content: " "; }
@media (max-width: 900px) {
.kacheln { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kachel[data-gross="ja"] { grid-column: span 2; }
}
@media (max-width: 560px) {
.kacheln { grid-template-columns: 1fr; }
.kachel[data-gross="ja"] { grid-column: span 1; }
.gruppe__kopf { gap: 4px; }
.gruppe__unter { flex-basis: 100%; }
}
.inhalt .fuss { margin-top: 40px; text-align: left; }
@media (max-width: 520px) {
.kopfleiste { padding: 12px 16px; gap: 10px; }
/* Die Marke wich zwar zurueck, nahm aber immer noch so viel Platz,
dass vom Namen nur noch drei Pixel uebrig blieben. Auf dem Handy
verschwindet sie deshalb -- genau derselbe Text steht zwei Zeilen
tiefer als Ueberschrift, der Name des Angemeldeten dagegen
nirgends sonst.
Aber nur dort, wo der Zurueck-Knopf sichtbar ist: Auf der
Startseite gibt es ihn nicht, dort waere die linke Haelfte sonst
leer und die Leiste saehe kaputt aus. */
.kopfleiste:has(.zurueck-knopf:not([hidden])) .marke { display: none; }
.kopfleiste__rechts { margin-left: auto; }
.wer { max-width: none; }
/* Der Pfeil allein sagt "zurueck" -- das Wort daneben kostet auf dem
Handy 65 px, die dem Abmelden-Knopf fehlen. Vorlesende Programme
verlieren nichts: Der Text bleibt im Dokument und wird nur
unsichtbar gerechnet. */
.zurueck-knopf { padding: 9px 12px 9px 11px; }
.zurueck-knopf__text {
position: absolute; width: 1px; height: 1px;
margin: -1px; padding: 0; overflow: hidden;
clip-path: inset(50%); white-space: nowrap;
}
.zurueck-knopf { gap: 0; }
}
/* Zurueckhaltender Zweitknopf. Gehoert bewusst hierher und nicht in eine
einzelne Seite: Er wird ueberall gebraucht, und als Seiten-CSS fehlte er
prompt dort, wo die Datei nicht geladen war -- dann standen nackte
Systemknoepfe in der Oberflaeche. */
/* ---------- Was ist dran ------------------------------------------------
Steht vor den Zahlen. Zahlen sagen, WIE VIEL anliegt -- diese Liste
sagt, WAS zu tun ist. Nur drei Stufen, und nur die oberste ist farbig:
Waere alles hervorgehoben, waere nichts hervorgehoben. */
/* Die Seite ist breit, damit die Kacheln Platz haben. Eine Zeile Text
ueber 1240 px zu ziehen macht sie aber nicht lesbarer, sondern
anstrengender -- Hinweise und Begruessung behalten deshalb ihr Mass. */
.willkommen, .dran__liste, .inhalt .fuss { max-width: 940px; }
.dran { margin-bottom: 30px; }
.dran__liste { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
/* Jede Zeile traegt Zeichen und Farbe ihrer Kachel (data-ton kommt aus
start.js). Ohne Zuordnung bleibt der Hausakzent -- eine Zeile ohne
Farbe gibt es nicht. */
.dran__punkt {
/* --ton kommt aus data-ton bzw. dem Rückfallwert in :where() oben. */
position: relative;
overflow: hidden;
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
background:
linear-gradient(90deg, color-mix(in srgb, var(--ton) 9%, transparent), transparent 46%),
var(--flaeche);
transition: border-color .18s ease, background .18s ease, transform .18s ease;
}
/* Der Streifen links ist die Farbe der Kachel, zu der es geht -- oben
kraeftig, unten auslaufend, damit er nicht wie ein Balken wirkt. */
.dran__punkt::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
background: linear-gradient(180deg,
var(--ton),
color-mix(in srgb, var(--ton) 35%, transparent));
}
/* Ueberfaellig schlaegt Bereichsfarbe: Wenn etwas brennt, zaehlt zuerst
DASS es brennt. Das Zeichen sagt weiterhin, wo. */
.dran__punkt[data-stufe="warnung"] {
--ton: var(--warn);
border-color: rgba(255, 154, 162, .3);
}
.dran__punkt[data-stufe="ruhig"] { opacity: .8; }
.dran__punkt:hover {
border-color: color-mix(in srgb, var(--ton) 42%, var(--rand));
background:
linear-gradient(90deg, color-mix(in srgb, var(--ton) 15%, transparent), transparent 52%),
rgba(255, 255, 255, .05);
}
.dran__punkt[data-stufe="ruhig"]:hover { opacity: 1; }
.dran__link {
display: grid;
grid-template-columns: auto auto 1fr auto;
align-items: center; gap: 13px;
padding: 11px 15px 11px 17px;
color: var(--text); text-decoration: none; font-size: .9rem;
}
.dran__zeichen {
display: grid; place-items: center;
width: 30px; height: 30px; border-radius: 9px;
border: 1px solid color-mix(in srgb, var(--ton) 30%, transparent);
background: color-mix(in srgb, var(--ton) 13%, transparent);
transition: transform .18s ease, background .18s ease;
}
.dran__svg {
width: 16px; height: 16px;
fill: none; stroke: var(--ton); stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
.dran__link:hover .dran__zeichen {
transform: scale(1.07);
background: color-mix(in srgb, var(--ton) 20%, transparent);
}
/* Die Zahl steht vorn und in gleicher Zeichenbreite: Beim Ueberfliegen
von sieben Zeilen liest man sie zuerst, und sie sollen untereinander
stehen, nicht huepfen. */
.dran__zahl {
font-size: 1.15rem; font-weight: 700; line-height: 1;
font-variant-numeric: tabular-nums;
color: var(--ton);
min-width: 1.6ch; text-align: right;
}
.dran__text { color: var(--text-leise); }
.dran__punkt[data-stufe="warnung"] .dran__text { color: var(--text); font-weight: 600; }
.dran__pfeil {
color: var(--text-still); font-size: .95rem;
transition: transform .18s ease, color .18s ease;
}
.dran__link:hover .dran__pfeil { color: var(--ton); transform: translateX(3px); }
/* Auf dem Handy ist Platz das knappste Gut: Zeichen und Pfeil weichen,
Zahl und Satz bleiben -- die tragen die Aussage. */
@media (max-width: 460px) {
.dran__link { grid-template-columns: auto 1fr; gap: 10px; padding: 11px 13px 11px 15px; }
.dran__zeichen, .dran__pfeil { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.kachel__wasserzeichen, .kachel__zeichen { transition: none; }
.kachel:hover .kachel__wasserzeichen { transform: rotate(-8deg); }
.kachel:hover .kachel__zeichen { transform: none; }
.dran__punkt, .dran__pfeil, .dran__zeichen { transition: none; }
.dran__link:hover .dran__pfeil { transform: none; }
.dran__link:hover .dran__zeichen { transform: none; }
}
/* Ohne Farbverlaeufe (Kontrastmodus, Druck) bleibt der Streifen als
einfarbige Kante -- sonst waere die Zuordnung dort ganz weg. */
@media (forced-colors: active) {
.dran__punkt::before { background: CanvasText; }
.dran__svg { stroke: CanvasText; }
.dran__zahl { color: CanvasText; }
}
/* =====================================================================
Kopfleiste, Begrüßung, Hinweise -- der Feinschliff vom 01.09.2026.
Vorher waren das vier Stellen mit reinem Systemtext: eine Marke in
Großbuchstaben, eine Überschrift, ein Name, eine Liste. Alles
funktionierte, nichts sagte etwas über den Ort, an dem man ist.
===================================================================== */
/* ---------- Die Marke oben links ----------------------------------------
Der DogFather-Kopf davor. Als MASKE, nicht als Bild: Die Form wird im
Stil eingefärbt (siehe tools/buehne-bauen.mjs). Ein fertig
eingefärbtes Bild müsste man für jede Farbe neu bauen -- und beim
Überfahren wechselt die Farbe. */
.kopfleiste .marke {
display: flex; align-items: center; gap: 9px;
letter-spacing: .14em;
/* min-width: 0 muss auch INNEN gelten. Die Marke ist jetzt selbst eine
Flex-Zeile (Zeichen + Text); ohne diese Angabe behaelt ihr Text seine
volle Wunschbreite und die Marke schrumpft nicht mehr -- der
Abmelden-Knopf stand dadurch auf dem Handy 9 px aus dem Bild.
Derselbe Fehler wie im August, eine Ebene tiefer. */
min-width: 0;
}
/* flex: 0 1 auto, NICHT 1 1 auto. Mit flex-grow: 1 zog sich der
Schriftzug ueber die ganze Leiste -- unsichtbar, solange er nur Text
war, aber seit er einen Rahmen traegt (die Pille), lief der Rahmen
quer durch das ganze Bild, obwohl der Text kurz ist. Schrumpfen darf
er weiterhin (das braucht die Kuerzung auf dem Handy), wachsen nicht. */
.kopfleiste .marke__text { min-width: 0; flex: 0 1 auto; }
.kopfleiste .marke::before {
content: "";
flex: none; width: 22px; height: 22px;
background: linear-gradient(150deg, var(--akzent), var(--violett));
-webkit-mask: url("../img/marke-husky.webp") center / contain no-repeat;
mask: url("../img/marke-husky.webp") center / contain no-repeat;
transition: filter var(--tempo);
}
.kopfleiste:hover .marke::before { filter: brightness(1.25); }
/* KEIN Farbverlauf IM Text.
Ich hatte das zuerst gebaut (background-clip: text mit durchsichtiger
Schrift) -- es sah gut aus, und der eigene Kontrasttest schlug sofort
Alarm: 1,05:1. Zu Recht. Durchsichtige Schrift ist auf eine einzige
Technik angewiesen; faellt sie aus (Kontrastmodus des Betriebssystems,
Druck, aeltere Browser), ist der Text UNSICHTBAR statt nur anders
gefaerbt. Das ist kein Schoenheitsfehler, das ist ein Ausfall.
Stattdessen: feste Farbe, ein Hauch Leuchten. Sieht fast gleich aus
und kann nicht verschwinden. */
.kopfleiste .marke__text {
color: #a8dbfb;
text-shadow: 0 0 14px rgba(63, 189, 245, .28);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
display: flex; align-items: center; gap: 9px;
}
/* Der Rang im Schriftzug (aufgeteilt von kopf.js).
Vorher war alles gleich laut. Jetzt trägt der vordere Teil den Namen
und steht kräftig; was dahinter kommt, sagt nur, wo man gerade ist,
und tritt zurück. Beide bleiben eigenständig lesbar -- der leise Teil
liegt bei 5,2:1 und damit deutlich über der Norm. */
.kopfleiste .marke__haupt {
color: #dcecfb;
font-weight: 700;
text-shadow: 0 0 16px rgba(63, 189, 245, .34);
}
.kopfleiste .marke__leise {
color: #86b4d6;
font-weight: 500;
text-shadow: none;
}
.kopfleiste a.marke__haupt { text-decoration: none; }
.kopfleiste a.marke__haupt:hover { color: #fff; }
/* Der Trenner ist kein Satzzeichen mehr, sondern eine kleine, auf die
Spitze gestellte Raute in der Hausfarbe -- dieselbe Form wie die
Ecken der Bühne. Ein Punkt zwischen zwei Wörtern liest sich wie ein
Tippfehler; eine Raute liest sich als Gestaltung. */
.kopfleiste .marke__raute {
flex: none;
width: 5px; height: 5px;
transform: rotate(45deg);
border-radius: 1px;
background: var(--akzent);
box-shadow: 0 0 9px rgba(63, 189, 245, .65);
opacity: .85;
}
/* Das Zeichen davor bekommt einen eigenen Träger: runder Rahmen, ein
Hauch Fläche, weicher Schein. Aus einer aufgeklebten Form wird damit
ein Wappen. */
.kopfleiste .marke::before {
padding: 0;
filter: drop-shadow(0 0 7px rgba(63, 189, 245, .45));
}
.kopfleiste .marke {
/* Nur so breit wie ihr Inhalt -- sonst waere die Pille eine Leiste. */
flex: 0 1 auto;
padding: 4px 13px 4px 5px;
border-radius: 999px;
border: 1px solid transparent;
transition: border-color var(--tempo), background var(--tempo);
}
.kopfleiste .marke:hover {
border-color: color-mix(in srgb, var(--akzent) 26%, transparent);
background: rgba(255, 255, 255, .035);
}
@media (prefers-reduced-motion: reduce) {
.kopfleiste .marke { transition: none; }
}
/* Im Kontrastmodus gibt es keine Farbverläufe und keine Schatten -- dort
muss der Rang über die Schriftstärke allein tragen. */
@media (forced-colors: active) {
.kopfleiste .marke__raute { background: CanvasText; }
.kopfleiste .marke__haupt, .kopfleiste .marke__leise { color: CanvasText; }
}
/* ---------- Wer angemeldet ist ------------------------------------------
Vorher stand da "Dogfather · DogFather" -- Name und Rolle lasen sich
gleich und es sah nach einem Fehler aus. Jetzt: ein Zeichen mit dem
Anfangsbuchstaben, der Name, und die Rolle als eigene Marke in ihrer
Farbe. Drei verschiedene Dinge sehen jetzt auch verschieden aus. */
.wer {
display: flex; align-items: center; gap: 9px;
max-width: none; overflow: visible;
}
.wer__zeichen {
flex: none;
/* overflow: hidden ist hier PFLICHT, nicht Kosmetik: Darin liegt das
Profilbild, und ohne diese Zeile stand es in seiner Originalgroesse
ueber der halben Seite. Genau das ist am 01.09.2026 passiert, als
Patrick sein Bild hochgeladen hat -- ein roter Balken quer ueber die
Startseite. */
overflow: hidden;
position: relative;
display: grid; place-items: center;
width: 28px; height: 28px; border-radius: 9px;
font-size: .8rem; font-weight: 700; color: #eaf3ff;
background: linear-gradient(150deg,
color-mix(in srgb, var(--rollen-ton) 62%, transparent),
color-mix(in srgb, var(--rollen-ton) 24%, transparent));
border: 1px solid color-mix(in srgb, var(--rollen-ton) 55%, transparent);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .16);
}
/* Das Profilbild in der Kopfleiste.
DIESE REGEL HAT GEFEHLT. Das Element wurde in kopf.js erzeugt, die
Regel dazu nie geschrieben -- ein <img> ohne Groessenangabe nimmt
seine natuerliche Groesse an, bei einem Handyfoto also mehrere
tausend Pixel. Es lag damit ueber der ganzen Seite.
Warum es keine Pruefung gefunden hat: Sie lud ein 1x1-Pixel-PNG
hoch. Ein Bild dieser Groesse kann nichts ueberdecken. Die Pruefung
arbeitet jetzt mit einem 1200x1200-Bild -- so gross wie das, was
wirklich hochgeladen wird. */
.wer__bild {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: cover;
display: block;
border-radius: inherit;
}
.wer__name {
font-size: .88rem; font-weight: 600; color: var(--text);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
min-width: 0;
}
.wer__rolle {
flex: none;
padding: 2px 9px; border-radius: 999px;
font-size: .66rem; font-weight: 700;
letter-spacing: .08em; text-transform: uppercase;
color: color-mix(in srgb, var(--rollen-ton) 75%, #ffffff);
background: color-mix(in srgb, var(--rollen-ton) 15%, transparent);
border: 1px solid color-mix(in srgb, var(--rollen-ton) 38%, transparent);
}
/* Eine Farbe je Rolle -- dieselbe Sprache wie in der Personenliste. */
.wer[data-rolle="admin"] { --rollen-ton: #e8c07d; }
.wer[data-rolle="manager"] { --rollen-ton: #9085e9; }
.wer[data-rolle="scout"] { --rollen-ton: #4fc38f; }
.wer[data-rolle="creator"] { --rollen-ton: #3fbdf5; }
/* Auf dem Handy faellt die Rollen-Marke weg und der Name darf schrumpfen.
Ohne das schob die neue Kennung die Kopfleiste um 8 px aus dem Bild --
gemessen, nicht vermutet: Der Pruefflauf zaehlt den waagerechten
Ueberstand auf jeder Seite mit.
Die Rolle wegzulassen kostet hier nichts: Wer angemeldet ist, weiss,
welche Rolle er hat -- und auf der Startseite steht sie zwei Zeilen
tiefer noch einmal ausgeschrieben. */
@media (max-width: 620px) {
.wer__rolle { display: none; }
.wer { min-width: 0; gap: 7px; }
.wer__name { max-width: 34vw; }
/* Auf dem Handy bleibt vom Markenzug nur der Kopf stehen. Gemessen:
Marke 209 px + rechte Gruppe 139 px + Polsterung passten nicht in
390 px, der Abmelden-Knopf stand 9 px aus dem Bild. Schrumpfen
allein reichte nicht.
Der Text kostet hier nichts: Er steht auf jeder Seite zwei Zeilen
tiefer noch einmal als Ueberschrift. Der Kopf dagegen sagt in 22 px,
wo man ist -- und bleibt.
Vorlesende Programme verlieren nichts: Der Text bleibt im Dokument
und wird nur unsichtbar gerechnet. */
.kopfleiste .marke__text {
position: absolute; width: 1px; height: 1px;
margin: -1px; padding: 0; overflow: hidden;
clip-path: inset(50%); white-space: nowrap;
}
.kopfleiste .marke { flex: none; }
}
/* ---------- Die Begrüßung ------------------------------------------------
Aus drei gestapelten Zeilen wird ein Kopf: ein leuchtender Strich, die
Zeile "ANGEMELDET" daneben, darunter der Gruß mit einem sehr sanften
Verlauf. Kein zusätzliches Element -- der Strich ist ein
Pseudo-Element der Marke. */
.willkommen .marke {
display: flex; align-items: center; gap: 10px;
margin-bottom: 10px;
}
.willkommen .marke::before {
content: "";
width: 26px; height: 2px; border-radius: 2px;
background: linear-gradient(90deg, var(--akzent), transparent);
}
.willkommen .titel {
font-size: clamp(1.9rem, 3.4vw, 2.6rem);
letter-spacing: -.025em;
/* Auch hier bewusst eine feste Farbe statt eines Verlaufs im Text --
siehe die Begruendung bei .marke__text. Die Wirkung kommt aus
Groesse, engerem Satz und dem Leuchten, nicht aus einem Kniff, der
im Kontrastmodus zu unsichtbarer Schrift wird. */
color: #f2f7fd;
text-shadow: 0 2px 26px rgba(63, 189, 245, .18);
}
.willkommen .unterzeile { margin-bottom: 0; }
/* Datumszeile: Tag, Datum und Kalenderwoche. Die Ziffern in gleicher
Zeichenbreite, damit die Zeile über die Tage hinweg ruhig bleibt. */
.willkommen__datum { font-variant-numeric: tabular-nums; }
/* Das kleine Wort zum Tag ("Neue Woche", "Endspurt", "Wochenende").
Steht nur an Tagen, die wirklich einen Charakter haben -- ein Wort,
das jeden Tag dasteht, liest nach drei Tagen niemand mehr. */
.willkommen__marker {
margin-left: 10px; padding: 3px 9px;
border: 1px solid color-mix(in srgb, var(--akzent) 32%, transparent);
border-radius: 999px;
background: color-mix(in srgb, var(--akzent) 12%, transparent);
color: var(--akzent);
font-size: .68rem; letter-spacing: .1em;
}
.willkommen__marker[hidden] { display: none; }
/* Der Gruß in zwei Stimmen: das Grußwort leiser, der Name kräftig.
Man liest den eigenen Namen, nicht die Höflichkeitsfloskel. */
.gruss__wort { color: #c3d2e4; font-weight: 600; }
/* DER NAME MUSS UMBRECHEN DUERFEN.
Gefunden am 02.09.2026 vom Rundgang: "SpongBobSchwammKopf" schob die
Startseite auf dem Handy um 48 Pixel aus dem Bild -- ein einziges
langes Wort ohne Trennstelle, und die ganze Seite laesst sich seitlich
schieben.
Genau dieser Fall trifft echte Namen: Creator heissen selten "Tim".
overflow-wrap: anywhere bricht auch mitten im Wort, wenn es sonst
nicht passt -- haesslicher als eine saubere Trennung, aber immer noch
weit besser als eine Seite, die man seitlich wegschieben kann. */
.gruss__name {
color: #f2f7fd;
overflow-wrap: anywhere;
min-width: 0;
}
.gruss { min-width: 0; overflow-wrap: anywhere; }
/* Plakette und Text nebeneinander. Die Plakette ist der einzige runde
Körper auf der Seite -- dadurch ist sofort klar, dass sie zu einer
PERSON gehört und nicht zu einem Bereich. */
.willkommen__reihe { display: flex; align-items: center; gap: 18px; }
.willkommen__text { min-width: 0; }
.willkommen__plakette {
--rolle-ton: var(--akzent);
flex: none;
display: grid; place-items: center;
width: 58px; height: 58px; border-radius: 50%;
font-size: 1.6rem; font-weight: 700; line-height: 1;
color: #f2f7fd;
border: 1px solid color-mix(in srgb, var(--rolle-ton) 42%, transparent);
background:
radial-gradient(120% 120% at 30% 20%,
color-mix(in srgb, var(--rolle-ton) 34%, transparent), transparent 70%),
rgba(255, 255, 255, .045);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .1),
0 10px 26px -12px color-mix(in srgb, var(--rolle-ton) 60%, transparent);
}
/* Das eigene Bild füllt die Plakette ganz aus. `overflow: hidden` gehört
dazu -- ohne das ragt ein quadratisches Bild aus dem runden Rahmen und
sieht aus wie ein Fehler. `object-fit: cover` schneidet mittig zu statt
zu verzerren: Ein in die Breite gezogenes Gesicht ist schlimmer als
ein knapper Ausschnitt. */
.willkommen__plakette { overflow: hidden; }
.willkommen__foto {
width: 100%; height: 100%;
object-fit: cover; display: block;
border-radius: 50%;
}
/* Dieselben vier Rollentöne wie im Kopf der Seite und auf der
Zugangsseite -- eine Rolle hat überall dieselbe Farbe. */
.willkommen__plakette[data-rolle="admin"] { --rolle-ton: #d8a13a; }
.willkommen__plakette[data-rolle="manager"] { --rolle-ton: #8a76ff; }
.willkommen__plakette[data-rolle="scout"] { --rolle-ton: #12a69b; }
.willkommen__plakette[data-rolle="creator"] { --rolle-ton: #3fbdf5; }
/* Die Lage in einem Satz, abgesetzt hinter der Rolle. Auf dem Handy
rutscht sie in die zweite Zeile, statt den Text zu quetschen. */
.willkommen .unterzeile { display: flex; flex-wrap: wrap; gap: 6px 12px; }
.willkommen__lage { position: relative; padding-left: 14px; color: var(--text-leise); }
.willkommen__lage::before {
content: ""; position: absolute; left: 0; top: 50%;
width: 5px; height: 5px; margin-top: -2.5px; border-radius: 50%;
background: currentColor; opacity: .55;
}
.willkommen__lage[data-stufe="warnung"] { color: var(--warn); }
.willkommen__lage[hidden] { display: none; }
@media (max-width: 560px) {
.willkommen__plakette { width: 46px; height: 46px; font-size: 1.25rem; }
.willkommen__reihe { gap: 13px; }
}
/* Die Trennlinie unter der Begrüßung. Läuft nach rechts aus, statt hart
abzubrechen -- eine durchgezogene Linie zerschneidet die Seite. */
.willkommen {
padding-bottom: 22px; margin-bottom: 30px;
border-bottom: 1px solid transparent;
border-image: linear-gradient(90deg, var(--rand-hell), transparent 62%) 1;
}
/* ---------- Abschnittsschilder ------------------------------------------
"WAS IST DRAN" und "DEINE AUFGABEN" bekommen denselben leuchtenden
Strich wie die Begrüßung -- so gehört sichtbar zusammen, was
zusammengehört. */
.dran .feldschild,
.zahlen-block .feldschild {
display: flex; align-items: center; gap: 9px;
}
.dran .feldschild::before,
.zahlen-block .feldschild::before {
content: "";
width: 18px; height: 2px; border-radius: 2px;
background: linear-gradient(90deg, var(--akzent), transparent);
opacity: .8;
}
/* =====================================================================
LESEZONEN — Text auf einem hellen Bild
Seit die Buehnen wirklich hell sind, reicht "dunkler Text auf dunklem
Grund" nicht mehr: Wo kein Kasten liegt, steht Schrift direkt auf dem
Bild. Die Kontrastmessung an echten Bildpunkten hat das sofort
gemeldet -- 1,08:1 an einer hellen Stelle. Unlesbar.
Die billige Loesung waere, das Bild wieder abzudunkeln. Damit waere
man aber wieder da, wo man angefangen hat.
Die richtige: Der Untergrund wird NUR DORT abgedunkelt, wo Text
steht -- und zwar mit backdrop-filter. Der Hintergrund bleibt in
Farbe und Form sichtbar, wird an dieser Stelle aber weichgezeichnet
und gedimmt. Das ist dieselbe Technik, die hochwertige Oberflaechen
fuer ihre Leisten benutzen: Man sieht, dass da etwas ist, aber es
stoert nicht mehr.
Faellt backdrop-filter aus (aeltere Browser), traegt der Verlauf
darunter die Lesbarkeit allein -- deshalb steht er da und ist nicht
nur Beiwerk.
===================================================================== */
body.start .willkommen,
body.start .kopf-zeile,
body.start .k-kopf {
padding: 20px 24px;
border-radius: var(--radius);
background: linear-gradient(180deg, rgba(6, 9, 16, .74), rgba(6, 9, 16, .58));
backdrop-filter: blur(14px) saturate(.9);
-webkit-backdrop-filter: blur(14px) saturate(.9);
}
/* Die Trennlinie darunter war fuer eine Zeile ohne Flaeche gedacht.
Auf einer eigenen Flaeche waere sie eine Kante zu viel. */
body.start .willkommen { border-bottom: 0; margin-bottom: 26px; }
body.start .kopf-zeile,
body.start .k-kopf { border-bottom: 0; }
/* Die Gruppenueberschriften auf der Startseite stehen frei zwischen den
Kacheln. Sie bekommen keinen Kasten (das waeren drei weitere Kaesten),
sondern nur einen schmalen, weich auslaufenden Traeger. */
body.start .gruppe__kopf {
position: relative;
padding: 7px 14px;
margin-left: -14px;
border-radius: 999px;
width: fit-content; max-width: 100%;
background: linear-gradient(90deg, rgba(6, 9, 16, .72), rgba(6, 9, 16, .3) 82%, transparent);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* Der Fusstext und freistehende Hinweise brauchen dasselbe. */
body.start .inhalt .fuss,
body.start .leer-hinweis,
body.start .protokoll-block,
body.start .zahlen-block,
body.start .dran {
position: relative;
}
body.start .inhalt .fuss {
padding: 14px 16px;
border-radius: var(--radius-klein);
background: rgba(6, 9, 16, .6);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* Listen und Bloecke, die bisher gar keine Flaeche hatten (Protokolle,
Verlaeufe, Tabellenzeilen) -- sie liegen jetzt auf --flaeche wie
alles andere. */
body.start #protokoll,
body.start #liste > .leise,
body.start .verlauf {
border-radius: var(--radius-klein);
}
@media (max-width: 620px) {
body.start .willkommen,
body.start .kopf-zeile,
body.start .k-kopf { padding: 16px 15px; }
body.start .gruppe__kopf { margin-left: -10px; padding: 6px 11px; }
}
/* Ohne backdrop-filter (Kontrastmodus, aeltere Browser) muss der
Verlauf allein tragen -- deshalb wird er dort deckend. */
@media (forced-colors: active) {
body.start .willkommen,
body.start .kopf-zeile,
body.start .k-kopf,
body.start .gruppe__kopf { background: Canvas; }
}
/* Die letzten drei freistehenden Textstellen, die die Kontrastmessung
nach dem Aufhellen noch gefunden hat. Alle drei sind Beschriftungen
ohne eigene Flaeche -- sie bekommen dieselbe schmale Lesezone wie die
Gruppenueberschriften. */
body.start .dran .feldschild,
body.start .zahlen-block .feldschild,
body.start .protokoll-block .feldschild,
body.start .k-leiste .feldschild {
padding: 6px 13px 6px 11px;
margin-left: -11px;
border-radius: 999px;
width: fit-content; max-width: 100%;
background: linear-gradient(90deg, rgba(6, 9, 16, .74), rgba(6, 9, 16, .32) 84%, transparent);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* Das Ereignisprotokoll auf der Personenseite stand als einziges ganz
ohne Traeger da -- IP-Adressen und Zeitstempel direkt auf dem Bild. */
body.start #protokoll {
padding: 4px 14px;
border-radius: var(--radius-klein);
background: rgba(6, 9, 16, .66);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
/* Auf dem Handy gibt es keinen Platz fuer Figuren neben dem Text --
dort darf die Lesespur ueber die ganze Breite gehen. Das Bild bleibt
oben und unten sichtbar, wo der Inhalt nicht steht. */
@media (max-width: 760px) {
body.start > .schleier {
background:
linear-gradient(180deg, rgba(5, 7, 13, .88) 0%, rgba(5, 7, 13, .6) 12%,
rgba(5, 7, 13, .5) 55%, rgba(5, 7, 13, .72) 100%),
radial-gradient(90% 40% at 20% 4%, rgba(63, 189, 245, .06), transparent 70%),
radial-gradient(90% 40% at 85% 98%, rgba(138, 118, 255, .07), transparent 72%);
}
}
/* =====================================================================
DAS LICHT FOLGT DEM ZEIGER — auf jeder Karte, im ganzen Workspace
Zwei Schichten in einem eingefuegten <span class="licht"> (siehe
kopf.js, dort steht auch, warum ein eigenes Element und nicht
::before am Kasten selbst):
::before der FLECK — ein weicher Schein unter dem Zeiger
::after der RAND — eine helle Stelle, die auf der KANTE
mitwandert
Der Rand ist der Teil, der es besonders macht. Er entsteht aus einem
Farbverlauf, von dem eine Maske nur den ein Pixel breiten Saum stehen
laesst: zwei Ebenen, eine ueber die Innenflaeche, eine ueber den
ganzen Kasten, und "exclude" laesst genau die Differenz uebrig — den
Rahmen. Dadurch leuchtet wirklich die Kante an der Stelle, an der der
Zeiger ist, statt eines Rechtecks, das so tut als ob.
Die Farbe kommt aus --ton, also aus der Kachelfarbe des Bereichs.
Eine Aufgabenkarte leuchtet orange, eine Kalenderkarte tuerkis.
===================================================================== */
.licht {
position: absolute; inset: 0;
border-radius: inherit;
pointer-events: none;
z-index: 0;
opacity: 0;
transition: opacity .28s ease;
}
[data-licht="an"] > .licht { opacity: 1; }
/* Der Fleck. Bewusst gross und sehr weich — ein kleiner harter Kreis
sieht nach Taschenlampe aus, ein grosser weicher nach Beleuchtung. */
.licht::before {
content: "";
position: absolute; inset: 0;
border-radius: inherit;
background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 0%),
color-mix(in srgb, var(--ton, var(--akzent)) 20%, transparent),
transparent 68%);
}
/* Der Rand. Etwas kleiner im Radius als der Fleck, dafuer kraeftiger --
so wirkt er wie eine Reflexion auf einer Kante, nicht wie ein zweiter
Schein. */
.licht::after {
content: "";
position: absolute; inset: 0;
border-radius: inherit;
padding: 1px;
background: radial-gradient(170px circle at var(--mx, 50%) var(--my, 0%),
color-mix(in srgb, var(--ton, var(--akzent)) 85%, #ffffff 15%),
color-mix(in srgb, var(--ton, var(--akzent)) 30%, transparent) 45%,
transparent 72%);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
mask-composite: exclude;
}
/* Alles, was Licht bekommen soll, braucht einen eigenen Bezugspunkt --
sonst legt sich der Schein ueber die halbe Seite statt ueber die
Karte. Die meisten haben ihn schon; diese Zeile ist die Versicherung
fuer die uebrigen. */
.kachel, .karte, .spalte, .k-anlasskarte, .k-tag, .k-wochentag,
.dran__punkt, .zahl, .datei, .person, .eintrag, .thema,
.k-listentag, .steckbrief, .leer-hinweis, .block {
position: relative;
}
/* Inhalt ueber das Licht. Die Karten setzen ihre Kinder meist nicht
ausdruecklich; bei gleichem Stapelwert gewinnt das spaetere Element,
und .licht wird als erstes Kind eingefuegt. Fuer die Faelle, in denen
ein Kind selbst positioniert ist, hier die Zusicherung. */
.kachel__link, .kachel__text, .karte__titel, .spalte__kopf,
.k-anlasskarte__txt, .dran__link, .steckbrief__kopf { position: relative; z-index: 1; }
/* Ohne feinen Zeiger oder bei "weniger Bewegung" wird gar kein
Licht-Element eingefuegt (kopf.js). Diese Regel ist die zweite
Sicherung, falls doch eines im Dokument steht. */
@media (prefers-reduced-motion: reduce) {
.licht { display: none; }
}
@media (hover: none), (pointer: coarse) {
.licht { display: none; }
}
/* Im Kontrastmodus gibt es keine Farbverlaeufe -- ein Licht, das dort
als Flaeche erscheint, wuerde den Text verdecken. */
@media (forced-colors: active) {
.licht { display: none; }
}
/* =====================================================================
HANDY — was die Geraetepruefung gefunden hat (01.09.2026)
Geprueft wurde auf 320, 390 und 412 px, auf allen fuenfzehn Seiten.
Drei Arten von Fehlern kamen heraus, und alle drei sind am Rechner
unsichtbar:
1. Raster, die nicht schrumpfen konnten. minmax(280px, 1fr) ist ein
MINDESTmass -- passt es nicht, laeuft die Seite ueber statt
umzubrechen. Behoben an zwoelf Stellen mit min(280px, 100%).
2. Beruehrziele unter 24 px. Auswahlfelder waren 18 bis 22 px hoch;
mit dem Daumen trifft man daneben. WCAG 2.2 nennt 24x24 als
Mindestmass (Kriterium 2.5.8), und das ist knapp bemessen.
3. Schrift unter 11,5 px. Auf einem Telefon ist das keine
Beschriftung mehr, sondern ein Muster.
===================================================================== */
@media (max-width: 760px) {
/* --- Beruehrziele ---------------------------------------------------
Auswahlfelder, Eingaben und kleine Knoepfe bekommen ein Mindestmass.
44 px ist die Empfehlung von Apple und Google und deutlich ueber der
Norm -- der Daumen ist nun einmal breiter als ein Mauszeiger. */
select, input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
textarea, button, .schritt, .knopf-still, .abmelden {
min-height: 44px;
}
select, input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) {
/* 16 px verhindert nebenbei, dass iOS beim Antippen hineinzoomt --
jeder kleinere Wert loest das aus, und danach steht die Seite
schief. */
font-size: 16px;
padding: 10px 12px;
}
/* Kleine Umschalter dürfen niedriger sein, brauchen aber Breite. */
.filterreihe__knopf, .k-chip, .k-ansicht, .marke-tag, .tag-knopf {
min-height: 38px;
}
/* --- Schriftgroessen ------------------------------------------------
Alles unter 11,5 px hochgezogen. Die Rollenmarke in der Kopfleiste
lag bei 10,56 px, die Bereichszeile bei 10,88 px, die Uhrzeiten im
Kalender bei 9,6 px. */
.wer__rolle, .kopf-zeile .marke, .willkommen .marke,
.feldschild, .marke, .gruppe__unter, .kachel__unter {
font-size: .75rem;
}
.k-pille, .k-anlass { font-size: .7rem; }
.k-tag__heute, .k-anlasskarte__rest small,
.k-anlasskarte__rest, .zahl__schild, .karte__zeile {
font-size: .72rem;
}
small, .leise { font-size: .78rem; }
/* --- Kalenderpillen -------------------------------------------------
Sie waren 15 px hoch -- als Ziel zu klein und als Text zu eng. Auf
dem Handy bekommen sie Luft; dass dann weniger in eine Zelle passt,
ist richtig so: Der volle Tag steht im Tagesdialog. */
.k-pille, .k-anlass {
min-height: 26px;
display: flex; align-items: center;
padding: 3px 6px;
}
.k-tag { min-height: 92px; }
}
/* Auf sehr schmalen Geraeten (320 px, iPhone SE) wird zusaetzlich alles
Mehrspaltige einspaltig. Zwei Spalten auf 288 px Inhaltsbreite sind
keine zwei Spalten mehr, sondern zwei Streifen. */
@media (max-width: 380px) {
.neu__raster, .gruppe__raster, .zahlen, .kacheln,
.feld-block__punkte, .zustand__daten, .ki-kasten__daten, .regeln {
grid-template-columns: 1fr !important;
}
.inhalt { padding-left: 13px; padding-right: 13px; }
.kopfleiste { padding-left: 13px; padding-right: 13px; }
}
/* --- Feste Mindestbreiten aufheben -----------------------------------
Zwoelf Stellen im Stil setzen eine feste Mindestbreite (Auswahlfelder
170 bis 240 px, Beschriftungsspalten 74 bis 128 px). Am Rechner ist
das richtig -- ein Auswahlfeld, das mit seinem Inhalt schrumpft,
springt bei jeder Aenderung in der Breite.
Auf einem 320-px-Geraet bleiben nach Polsterung 294 px uebrig. Ein
Feld mit 240 px Mindestbreite plus Beschriftung passt da nicht mehr,
und die Seite laesst sich waagerecht schieben. Genau das waren die
letzten 24 und 30 px auf startcheck.html und automation.html.
Auf dem Handy nehmen die Felder deshalb die volle Breite -- was
ohnehin die bessere Bedienung ist. */
@media (max-width: 760px) {
.steuerung select, .steuerung input,
.wahl2, .wahl2 select,
.betreuung__wahl, .filterreihe select, .kopf-knoepfe select,
select, input[type="search"], input[type="text"] {
min-width: 0;
max-width: 100%;
}
.steuerung, .kopf-zeile, .kopf-knoepfe { flex-wrap: wrap; }
.steuerung > *, .kopf-knoepfe > * { min-width: 0; }
/* Beschriftungsspalten in Datenlisten: nebeneinander wird zu
untereinander. 128 px Beschriftung plus Wert gehen auf 294 px nicht
mehr nebeneinander, ohne dass eines von beiden abbricht. */
.ki-kasten__schild, .zustand__daten .ki-kasten__schild {
min-width: 0;
}
.ki-kasten__daten li, .zustand__daten li {
flex-direction: column; gap: 2px;
}
/* Alles im Inhalt bleibt in seinem Kasten. Die Zeile ist die letzte
Sicherung: Sie faengt auch das ab, was kuenftig dazukommt, ohne dass
jemand daran denkt. */
.inhalt img, .inhalt table, .inhalt pre, .inhalt input,
.inhalt select, .inhalt textarea { max-width: 100%; }
}
/* --- Mindestschriftgroesse auf dem Handy -----------------------------
Achtundvierzig Regeln im Stil setzen eine Schrift unter 11,7 px --
Marken, Zaehler, Uhrzeiten, Spaltenkoepfe. Am Rechner ist das
angenehm: kleine Beschriftungen treten zurueck und lassen dem Inhalt
den Vortritt.
Auf einem Telefon ist dieselbe Groesse kein Text mehr, sondern ein
Muster. Die Geraetepruefung hat sie einzeln aufgelistet -- 9,6 px bei
den Uhrzeiten im Kalender, 10,56 px bei der Rollenmarke.
Gesucht wurden sie nicht von Hand (das waere ein Ratespiel gewesen
und haette die Haelfte uebersehen), sondern durch Durchsuchen der
Stildateien nach font-size unter 0,73rem. Alle Fundstellen stehen
hier und werden auf 0,75rem = 12 px angehoben.
Wer kuenftig eine neue kleine Marke baut, faellt der Handypruefung
auf und landet ebenfalls hier.
JEDER Selektor traegt body.start davor. Ohne das griff die Regel
nicht: start.css wird VOR den Seitenstilen geladen, und bei gleicher
Staerke gewinnt die spaetere Regel -- kalender.css setzte die Pille
also weiterhin auf 0,6rem. Der erste Anlauf sah im Quelltext richtig
aus und aenderte nichts. */
@media (max-width: 760px) {
body.start .balance__zahl, body.start .betreuung__schild, body.start .datei__schild,
body.start .filtergruppe__schild, body.start .fortschritt__schild, body.start .fortschritt__warn,
body.start .gruppe__zahl, body.start .k-anlass, body.start .k-anlasskarte__rest,
body.start .k-anlasskarte__rest small, body.start .k-kw, body.start .k-listentag__kw,
body.start .k-listentag__marke, body.start .k-pille, body.start .k-spaltenkopf,
body.start .k-strahl__kw, body.start .k-tag__heute, body.start .k-tag__monat,
body.start .k-wochentag__name, body.start .k-zeile__art, body.start .kachel__name,
body.start .karte__zeile, body.start .katwahl__weltname, body.start .ki-kasten__schild,
body.start .kk__schild, body.start .kopfleiste .marke, body.start .marke,
body.start .marke-art, body.start .marke-fehlt, body.start .marke-fertig,
body.start .marke-geraet, body.start .marke-neu, body.start .marke-punkt,
body.start .marke-rolle, body.start .marke-saeule, body.start .marke-status,
body.start .marke-still, body.start .marke-stufe, body.start .marke-tag,
body.start .marke-wichtig, body.start .naechstes__schild, body.start .rueck__wann,
body.start .spalte__zahl, body.start .suche-gruppe__titel, body.start .summe__name,
body.start .tu-knopf, body.start .wahl2__gruppe, body.start .wahl__rolle,
body.start .wer__rolle, body.start .wert__name, body.start .willkommen__marker,
body.start .zahl__schild
{
font-size: .75rem;
}
}
/* Der Verweis auf den naechsten Termin im Dashboard war 24 px hoch --
genau an der Grenze und damit darunter, sobald der Browser rundet.
Ein Ziel, das man mit dem Daumen nur knapp trifft, ist kein Ziel. */
@media (max-width: 760px) {
body.start .naechstes__wert,
body.start a.naechstes__wert {
display: inline-flex; align-items: center;
min-height: 32px;
padding: 4px 2px;
}
}
/* --- Der Aktionsknopf steht IMMER oben rechts -------------------------
Beanstandet am 01.09.2026: "einmal rechts, einmal links". Der Knopf
sprang, und zwar abhaengig von der TEXTLAENGE: Die Kopfzeile ist eine
umbrechende Flex-Zeile, und der Textblock daneben durfte wachsen. Auf
der Bibliotheks-Startseite ist die Unterzeile kurz -- der Knopf blieb
rechts. Auf einer Kategorieseite ("Community-Richtlinien, erlaubte
und verbotene Inhalte, Altersprüfung, Sperren, Verwarnungen,
Datenschutz, Jugendschutz und sicheres Verhalten") war sie lang, der
Textblock nahm die ganze Breite, und der Knopf rutschte darunter.
Es sah aus wie zwei verschiedene Seiten und war doch dieselbe Regel.
Jetzt: Der Textblock schrumpft (min-width: 0), der Knopf schrumpft
NICHT (flex: none) und wird nach rechts geschoben. Damit steht er auf
jeder Seite an derselben Stelle -- unabhaengig davon, wie lang der
Text daneben ist. Erst auf dem Handy rutscht er bewusst darunter,
dort ist nebeneinander kein Platz. */
.kopf-zeile > .steuerung,
.kopf-zeile > .kopf-knoepfe,
.kopf-zeile > .knopf,
.kopf-zeile > button,
.kopf-zeile > #auswahl-block {
flex: none;
margin-left: auto;
align-self: flex-start;
}
.kopf-zeile > .kopf-zeile__marke,
.kopf-zeile > div:first-child {
min-width: 0;
flex: 1 1 auto;
}
/* Die Unterzeile darf dabei umbrechen statt den Knopf wegzudruecken. */
.kopf-zeile .unterzeile { overflow-wrap: anywhere; }
@media (max-width: 700px) {
/* Auf dem Handy unter den Titel -- und ueber die volle Breite, damit
er ein ordentliches Beruehrziel ist. */
.kopf-zeile { flex-direction: column; align-items: stretch; }
.kopf-zeile > .steuerung,
.kopf-zeile > .kopf-knoepfe,
.kopf-zeile > .knopf,
.kopf-zeile > button,
.kopf-zeile > #auswahl-block { margin-left: 0; width: 100%; }
.kopf-zeile > .steuerung > .knopf,
.kopf-zeile > .kopf-knoepfe > .knopf { width: 100%; justify-content: center; }
}
/* Der leise Zusatz in einer Feldbeschriftung ("Dauer Minuten"). Vorher
stand dort "DAUER (MINUTEN)" -- in einer schmalen Spalte brach das
um, und das Feld darunter sass tiefer als seine Nachbarn. */
.feld-schild__still {
text-transform: none; letter-spacing: normal;
font-weight: 400; color: var(--text-still);
}
/* Die Checkliste steht auf VIER Seiten (LIVE, Community, Technik,
Content-Ideen). Ihr Stil gehoert deshalb hierher und nicht in eine
Seitendatei -- genau diesen Fehler habe ich beim ersten Anlauf
gemacht: Der Block lag in content.css, und bereich.html laedt die
gar nicht. Die Punkte standen dort nackt und ohne Flaeche da.
Es ist derselbe Fehler wie im August bei .knopf-still, .schalter und
.kopf-zeile. Deshalb steht die Warnung weiter oben in dieser Datei --
und deshalb hat sie nichts genutzt, solange keine Pruefung sie
nachhaelt. Jetzt gibt es eine (pruef-checkliste.mjs misst, ob die
Punkte wirklich eine Kante haben). */
/* =====================================================================
DIE FESTE CHECKLISTE
Steht auf jeder der vier Seiten (LIVE, Community, Technik,
Content-Ideen) und sieht ueberall gleich aus -- es ist dieselbe Sache.
Drei Zustaende, drei Farben. "Verbessern" ist bewusst warnend und
nicht rot: Es ist eine Aufgabe, kein Fehler. Rot waere eine
Beschuldigung.
===================================================================== */
.liste-fest { margin: 20px 0 30px; }
.liste-fest__kopf {
display: flex; align-items: flex-end; justify-content: space-between;
gap: 16px; flex-wrap: wrap; margin-bottom: 14px;
}
.liste-fest__unter {
margin: 4px 0 0; max-width: 70ch;
font-size: .87rem; line-height: 1.55; color: var(--text-leise);
}
.liste-fest__wahl { display: grid; gap: 4px; min-width: 0; }
/* ---------- Die Bilanz oben ---------------------------------------------
Wie viele Punkte passen, wie viele sind zu verbessern, wie viele hat
noch niemand angesehen. Das ist die Frage, die beide Seiten zuerst
haben -- deshalb steht sie vor der Liste und nicht darunter. */
.liste-fest__bilanz {
display: grid; gap: 9px;
grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
margin-bottom: 20px;
}
.bilanz-zahl {
--b-ton: #6f89a8;
display: flex; align-items: baseline; gap: 9px;
padding: 12px 15px;
border: 1px solid color-mix(in srgb, var(--b-ton) 26%, var(--rand));
border-radius: var(--radius-klein);
background:
linear-gradient(180deg, color-mix(in srgb, var(--b-ton) 9%, transparent), transparent 60%),
var(--flaeche);
}
.bilanz-zahl[data-stufe="gut"] { --b-ton: #4dab77; }
.bilanz-zahl[data-stufe="verbessern"] { --b-ton: #e0a33c; }
.bilanz-zahl[data-stufe="offen"] { --b-ton: #6f89a8; }
.bilanz-zahl__n {
font-size: 1.6rem; font-weight: 700; line-height: 1;
color: var(--b-ton); font-variant-numeric: tabular-nums;
}
.bilanz-zahl__text { font-size: .82rem; color: var(--text-leise); }
/* Die Zahl "zu verbessern" führt zu den markierten Gruppen. Sie sieht
deshalb anfassbar aus -- ein Klickziel, das aussieht wie Text, findet
niemand. */
.bilanz-zahl[data-klickbar="ja"] {
cursor: pointer;
transition: border-color var(--tempo), background var(--tempo),
transform var(--tempo);
}
.bilanz-zahl[data-klickbar="ja"]:hover,
.bilanz-zahl[data-klickbar="ja"]:focus-visible {
border-color: color-mix(in srgb, var(--b-ton) 55%, var(--rand));
background:
linear-gradient(180deg, color-mix(in srgb, var(--b-ton) 16%, transparent), transparent 60%),
var(--flaeche);
}
.bilanz-zahl[data-klickbar="ja"]:focus-visible {
outline: 2px solid var(--b-ton); outline-offset: 2px;
}
.bilanz-zahl[data-klickbar="ja"]::after {
content: '→'; margin-left: auto;
color: var(--b-ton); font-size: .9rem;
transition: transform var(--tempo);
}
.bilanz-zahl[data-klickbar="ja"]:hover::after { transform: translateX(3px); }
/* ---------- Die Gruppen --------------------------------------------------
Zugeklappt als Standard (Wunsch 01.09.2026: "die sollen auch zu machen,
damit die Seiten nicht so lang sind"). Vier Bereiche mit je rund
zwanzig Punkten sind aufgeklappt eine Seite, die niemand zu Ende
scrollt -- und was niemand zu Ende scrollt, wird auch nicht gelesen.
Der Kopf ist ein Knopf über die ganze Breite, kein Pfeilchen daneben:
ein Ziel von 46 Pixeln Höhe trifft man auch mit dem Daumen. */
.fest-gruppe { margin-bottom: 14px; }
.fest-gruppe__kopf {
display: flex; align-items: center; gap: 10px;
width: 100%; margin: 0; padding: 11px 14px;
text-align: left; font: inherit; cursor: pointer;
color: var(--text);
background: linear-gradient(180deg,
color-mix(in srgb, var(--ton, var(--akzent)) 7%, transparent), transparent 70%),
var(--flaeche);
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
transition: border-color var(--tempo), background var(--tempo);
}
.fest-gruppe__kopf:hover {
border-color: color-mix(in srgb, var(--ton, var(--akzent)) 40%, var(--rand));
}
.fest-gruppe__kopf:focus-visible {
outline: 2px solid var(--ton, var(--akzent)); outline-offset: 2px;
}
/* Offen: der Kopf wächst optisch mit dem Körper zusammen, sonst sähen es
aus wie zwei Kästen ohne Zusammenhang. */
.fest-gruppe[data-auf="ja"] .fest-gruppe__kopf {
border-bottom-left-radius: 0; border-bottom-right-radius: 0;
border-bottom-color: transparent;
}
/* Der Pfeil ist aus Rändern gebaut statt ein Zeichen -- ein ">" wird von
Vorleseprogrammen mitgelesen und richtet sich nach der Schriftart. */
.fest-gruppe__pfeil {
flex: none; width: 8px; height: 8px;
border-right: 2px solid var(--text-still);
border-bottom: 2px solid var(--text-still);
transform: rotate(-45deg); margin-left: 2px;
transition: transform var(--tempo), border-color var(--tempo);
}
.fest-gruppe[data-auf="ja"] .fest-gruppe__pfeil { transform: rotate(45deg); }
.fest-gruppe__kopf:hover .fest-gruppe__pfeil {
border-color: var(--ton, var(--akzent));
}
@media (prefers-reduced-motion: reduce) {
.fest-gruppe__pfeil { transition: none; }
}
.fest-gruppe__name {
margin: 0; font-size: .96rem; font-weight: 650; color: var(--text);
}
.fest-gruppe__zahl {
padding: 1px 8px;
border: 1px solid var(--rand); border-radius: 999px;
font-size: .72rem; color: var(--text-still);
font-variant-numeric: tabular-nums;
}
/* Das Merkzeichen steht ganz rechts -- der Platz, an dem das Auge beim
Überfliegen einer Liste von Köpfen zuletzt hängenbleibt. */
.fest-gruppe__kopf .merk { margin-left: auto; }
.fest-gruppe__koerper {
padding: 14px;
border: 1px solid var(--rand); border-top: 0;
border-bottom-left-radius: var(--radius-klein);
border-bottom-right-radius: var(--radius-klein);
background: color-mix(in srgb, var(--flaeche) 62%, transparent);
}
.fest-gruppe__koerper[hidden] { display: none; }
.fest-gruppe__text {
margin: 0 0 12px; max-width: 68ch;
font-size: .84rem; line-height: 1.5; color: var(--text-still);
}
.fest-punkte { display: grid; gap: 9px; }
/* ---------- Das Merkzeichen ----------------------------------------------
Der Wunsch war ein Zeichen, "so dass die sehen, da ist was". Drei
Entscheidungen stecken darin, und keine ist Geschmack:
FORM. Eine Raute. Alles andere auf dem Bildschirm ist rund oder eckig;
eine Spitze nach oben gibt es sonst nirgends. Das Auge findet sie
zwischen zwanzig Kacheln, ohne dass jemand hinsehen muss.
FARBE. Immer Bernstein, nie die Farbe der Kachel darunter. Ein Zeichen,
das die Farbe wechselt, muss gelesen werden; eines, das immer gleich
aussieht, wird erkannt. Rot wäre falsch: "verbessern" ist ein Auftrag,
kein Fehler -- und eine Seite voller roter Zeichen liest niemand mehr.
BEWEGUNG. Ein sehr langsames Atmen des Scheins (3,2 s), kein Blinken.
Bei "weniger Bewegung" bleibt der Schein stehen statt zu verschwinden --
sonst wäre das Zeichen genau für die Leute schwächer, die
Aufmerksamkeitsreize ohnehin schlechter verarbeiten. */
.merk {
--merk-ton: #e8b45a;
position: relative;
/* Erzeugt einen eigenen Stapelraum. Nur dadurch landet der Schein
(::before, z-index -1) ÜBER dem eigenen Hintergrund und UNTER dem
Zeichen. Ohne das rutscht er hinter den Hintergrund der Gruppenzeile
und ist schlicht weg -- ein Fehler, den man nicht sieht, weil das
Zeichen ja trotzdem da ist. */
isolation: isolate;
display: inline-flex; align-items: center; gap: 5px;
flex: none;
padding: 3px 7px 3px 4px;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--merk-ton) 42%, transparent);
background: color-mix(in srgb, var(--merk-ton) 13%, transparent);
color: var(--merk-ton);
line-height: 1;
}
.merk__svg { width: 17px; height: 17px; flex: none; }
.merk__flaeche {
fill: color-mix(in srgb, var(--merk-ton) 22%, transparent);
stroke: var(--merk-ton); stroke-width: 1.5; stroke-linejoin: round;
}
.merk__strich, .merk__punkt {
fill: none; stroke: var(--merk-ton);
stroke-width: 2.1; stroke-linecap: round;
}
.merk__n {
font-size: .76rem; font-weight: 700;
font-variant-numeric: tabular-nums;
}
/* Der Schein liegt HINTER dem Zeichen und ist unscharf -- er macht die
Stelle heller, ohne selbst als Form sichtbar zu werden. */
.merk::before {
content: ''; position: absolute; inset: -5px;
border-radius: inherit;
background: radial-gradient(circle at 22% 50%,
color-mix(in srgb, var(--merk-ton) 40%, transparent), transparent 70%);
filter: blur(6px);
opacity: .5;
pointer-events: none;
z-index: -1;
}
@media (prefers-reduced-motion: no-preference) {
.merk::before { animation: merk-atmen 3.2s ease-in-out infinite; }
@keyframes merk-atmen {
0%, 100% { opacity: .34; transform: scale(.94); }
50% { opacity: .72; transform: scale(1.06); }
}
}
/* Im Kontrastmodus von Windows werden Farben ersetzt -- dann trägt das
Zeichen die Bedeutung allein über seine Form, und der Schein stört. */
@media (forced-colors: active) {
.merk { border-color: CanvasText; color: CanvasText; }
.merk::before { display: none; }
.merk__flaeche, .merk__strich, .merk__punkt { stroke: CanvasText; }
.merk__flaeche { fill: none; }
}
/* ---------- Ein Punkt ---------------------------------------------------- */
.fest-punkt {
--p-ton: #6f89a8;
position: relative; overflow: hidden;
padding: 13px 15px 12px;
border: 1px solid color-mix(in srgb, var(--p-ton) 22%, var(--rand));
border-radius: var(--radius-klein);
background:
linear-gradient(90deg, color-mix(in srgb, var(--p-ton) 7%, transparent), transparent 52%),
var(--flaeche);
}
.fest-punkt::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
background: linear-gradient(180deg, var(--p-ton),
color-mix(in srgb, var(--p-ton) 30%, transparent));
}
.fest-punkt[data-stufe="gut"] { --p-ton: #4dab77; }
/* Warnend, nicht rot: Es ist eine Aufgabe, kein Fehler. Rot waere eine
Beschuldigung. */
.fest-punkt[data-stufe="verbessern"] { --p-ton: #e0a33c; }
.fest-punkt[data-stufe="offen"] { --p-ton: #6f89a8; }
.fest-punkt__kopf {
display: flex; align-items: flex-start; justify-content: space-between;
gap: 13px;
}
/* Zeichen und Wort stehen zusammen, nicht übereinander -- sonst wandert
die Marke bei markierten Punkten nach unten und die Liste wirkt, als
wären die Zeilen unterschiedlich hoch. */
.fest-punkt__stufe {
display: flex; align-items: center; gap: 7px; flex: none;
}
.fest-punkt__text { min-width: 0; }
.fest-punkt__titel {
margin: 0 0 5px; font-size: .93rem; font-weight: 650; color: var(--text);
}
.fest-punkt__beschreibung {
margin: 0; font-size: .84rem; line-height: 1.5; color: var(--text-leise);
}
/* Der Aufhaenger bei Content-Ideen -- die ersten Sekunden entscheiden,
deshalb steht er hervorgehoben und nicht im Fliesstext. */
.fest-punkt__hook {
margin: 0 0 7px; padding: 8px 11px;
border-left: 2px solid var(--ton, var(--akzent));
border-radius: 0 6px 6px 0;
background: color-mix(in srgb, var(--ton, var(--akzent)) 9%, transparent);
font-size: .87rem; line-height: 1.45; color: var(--text);
}
.fest-punkt__hookschild {
display: block; margin-bottom: 2px;
font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
color: var(--ton, var(--akzent));
}
.fest-punkt__marke {
display: inline-block; margin-top: 8px; padding: 2px 9px;
border: 1px solid var(--rand); border-radius: 999px;
font-size: .72rem; color: var(--text-still);
}
.fest-punkt__marke-stufe {
flex: none; padding: 3px 11px;
border: 1px solid color-mix(in srgb, var(--p-ton) 36%, transparent);
border-radius: 999px;
background: color-mix(in srgb, var(--p-ton) 12%, transparent);
color: var(--p-ton);
font-size: .73rem; font-weight: 600; white-space: nowrap;
}
/* Der Grund in voller Breite -- "verbessern" ohne Grund ist nicht
umsetzbar, nur entmutigend. Er darf nicht in eine Ecke. */
.fest-punkt__grund {
margin-top: 10px; padding: 9px 12px;
border-left: 2px solid var(--p-ton);
border-radius: 0 6px 6px 0;
background: color-mix(in srgb, var(--p-ton) 9%, transparent);
}
.fest-punkt__grund p { margin: 0; font-size: .86rem; line-height: 1.5; color: var(--text); }
.fest-punkt__von {
display: block; margin-top: 4px;
font-size: .74rem; color: var(--text-still);
}
.fest-punkt__fuss {
display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
margin-top: 11px;
}
.stufe-knopf {
padding: 6px 13px;
border: 1px solid var(--rand); border-radius: 999px;
background: rgba(0, 0, 0, .2);
color: var(--text-still);
font: inherit; font-size: .8rem; cursor: pointer;
transition: border-color .18s ease, color .18s ease, background .18s ease;
}
.stufe-knopf[data-stufe="gut"]:hover,
.stufe-knopf[data-stufe="gut"][data-an="ja"] {
border-color: rgba(77, 171, 119, .5); color: #6fbd95;
background: rgba(77, 171, 119, .13);
}
.stufe-knopf[data-stufe="verbessern"]:hover,
.stufe-knopf[data-stufe="verbessern"][data-an="ja"] {
border-color: rgba(224, 163, 60, .5); color: #e0b45c;
background: rgba(224, 163, 60, .13);
}
.fest-punkt__fuss .schritt { margin-left: auto; }
.punkt-gespraech {
margin-top: 11px; padding: 12px 13px;
border: 1px solid var(--rand); border-radius: var(--radius-klein);
background: rgba(0, 0, 0, .2);
}
@media (max-width: 560px) {
.liste-fest__kopf { flex-direction: column; align-items: stretch; }
.fest-punkt__kopf { flex-direction: column; }
.fest-punkt__stufe { align-self: flex-start; }
.fest-punkt__fuss .schritt { margin-left: 0; }
.stufe-knopf { flex: 1 1 auto; text-align: center; }
/* Auf einem schmalen Bildschirm bleibt vom Gruppenkopf nur wenig
Breite. Die reine Anzahl der Punkte ist dort das Erste, was gehen
darf -- das Merkzeichen ist das Letzte. */
.fest-gruppe__zahl { display: none; }
.fest-gruppe__name { min-width: 0; overflow-wrap: anywhere; }
}
/* Die neuen Klassen der festen Checkliste in der Mindestgroesse fuer
das Handy -- gemeldet von der Geraetepruefung (10,56 px beim
Aufhaenger-Schild). Wer kuenftig eine kleine Marke baut, faellt ihr
ebenfalls auf und landet hier. */
@media (max-width: 760px) {
body.start .fest-punkt__hookschild,
body.start .fest-punkt__marke,
body.start .fest-punkt__von,
body.start .merk__n,
body.start .fest-gruppe__zahl { font-size: .75rem; }
}
/* ---------- Das Merkzeichen auf der Kachel -------------------------------
"und es soll auch oben in der Kachel angezeigt werden."
Oben rechts, INNERHALB der Kachel. Ein überhängendes Zeichen sähe
besser aus, wäre hier aber unsichtbar: `.kachel` trägt `overflow:
hidden` (für das angeschnittene Wasserzeichen), und alles, was über
den Rand ragt, wird abgeschnitten. Genau so eine Änderung sieht im
Quelltext richtig aus und ist auf dem Bildschirm weg.
Die Zahl der Kachel sitzt senkrecht mittig, das Merkzeichen oben --
sie kommen sich deshalb nicht ins Gehege. */
.kachel__merk {
position: absolute; top: 9px; right: 11px;
z-index: 3;
padding: 2px 6px 2px 3px;
background: color-mix(in srgb, var(--merk-ton) 15%, var(--flaeche));
box-shadow: 0 2px 10px rgba(0, 0, 0, .45);
}
.kachel__merk .merk__svg { width: 16px; height: 16px; }
/* Zahl und Pfeil sitzen sonst senkrecht mittig -- auf einer 78 Pixel
hohen Kachel stossen sie damit oben an das Merkzeichen. Sie ruecken
deshalb nach unten, sobald eines da ist. */
.kachel[data-merk="ja"] .kachel__zahl,
.kachel[data-merk="ja"] .kachel__pfeil { align-self: flex-end; }
@media (max-width: 560px) {
.kachel__merk { right: 10px; }
}
/* ---------- Das Team -----------------------------------------------------
"ich will, dass wir Manager, Scouts, DogFather auch die Fotos, Namen
und so alles sehen, alles was die in ihrem Profil eintragen."
(01.09.2026)
Steht bewusst HIER und nicht in profil.css: steckbrief.html lädt
profil.css zwar, profil.html aber ebenfalls -- und die nächste Seite,
die das Team zeigen soll, vielleicht nicht mehr. In start.css gilt es
überall. Genau an dieser Stelle sind hier schon zweimal fertige Stile
ins Leere gelaufen (August: .knopf-still, .schalter, .kopf-zeile;
01.09.: die ganze Checkliste in content.css). */
.team-block { margin: 34px 0 30px; }
.team-block__kopf {
display: flex; align-items: center; gap: 10px; margin-bottom: 6px;
}
.team-block__titel {
margin: 0; font-size: 1.16rem; font-weight: 650; color: var(--text);
letter-spacing: -.01em;
}
.team-block__zahl {
padding: 2px 9px;
border: 1px solid var(--rand); border-radius: 999px;
font-size: .74rem; color: var(--text-still);
font-variant-numeric: tabular-nums;
}
.team-block__text {
margin: 0 0 18px; max-width: 74ch;
font-size: .87rem; line-height: 1.55; color: var(--text-still);
}
.team-gruppe { margin: 22px 0 10px; }
.team-gruppe:first-child { margin-top: 0; }
.team-gruppe__name {
margin: 0; font-size: .82rem; font-weight: 650;
letter-spacing: .08em; text-transform: uppercase;
color: var(--text-leise);
}
.team-gruppe__text {
margin: 3px 0 0; font-size: .83rem; line-height: 1.5;
color: var(--text-still);
}
/* minmax(min(300px,100%),1fr): Ohne das min() kann das Raster auf einem
schmalen Bildschirm nicht unter 300px schrumpfen und schiebt die Seite
seitlich hinaus -- ein Fehler, der auf dem Rechner unsichtbar ist. */
.team-reihe {
display: grid; gap: 12px;
grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
}
.team-karte {
--k-ton: var(--akzent);
display: flex; align-items: flex-start; gap: 14px;
padding: 15px 16px;
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
background:
linear-gradient(150deg, color-mix(in srgb, var(--k-ton) 9%, transparent), transparent 58%),
var(--flaeche);
transition: border-color var(--tempo), transform var(--tempo);
}
.team-karte:hover {
border-color: color-mix(in srgb, var(--k-ton) 40%, var(--rand));
}
/* Dieselben vier Rollentöne wie in der Begrüßung, im Seitenkopf und auf
der Zugangsseite. Eine Rolle hat überall dieselbe Farbe -- sonst muss
man jede Ansicht neu lernen. */
.team-karte[data-rolle="admin"] { --k-ton: #d8a13a; }
.team-karte[data-rolle="manager"] { --k-ton: #8a76ff; }
.team-karte[data-rolle="scout"] { --k-ton: #12a69b; }
.team-karte[data-rolle="creator"] { --k-ton: #3fbdf5; }
/* Die eigene Karte: ein Rand in der eigenen Rollenfarbe. Ohne das sucht
man sich zwischen zwanzig Gesichtern selbst. */
.team-karte[data-ich="ja"] {
border-color: color-mix(in srgb, var(--k-ton) 52%, var(--rand));
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--k-ton) 18%, transparent);
}
.team-karte__bild {
flex: none; overflow: hidden;
display: grid; place-items: center;
width: 54px; height: 54px; border-radius: 50%;
font-size: 1.35rem; font-weight: 700; line-height: 1;
color: #f2f7fd;
border: 1px solid color-mix(in srgb, var(--k-ton) 42%, transparent);
background:
radial-gradient(120% 120% at 30% 20%,
color-mix(in srgb, var(--k-ton) 32%, transparent), transparent 70%),
rgba(255, 255, 255, .04);
}
/* object-fit: cover schneidet mittig zu statt zu verzerren -- ein in die
Breite gezogenes Gesicht ist schlimmer als ein knapper Ausschnitt. */
.team-karte__bild img {
width: 100%; height: 100%; object-fit: cover; display: block;
}
.team-karte__text { min-width: 0; flex: 1; }
.team-karte__zeile { display: flex; align-items: baseline; gap: 8px; }
.team-karte__name {
margin: 0; font-size: 1rem; font-weight: 650; color: var(--text);
min-width: 0; overflow-wrap: anywhere;
}
.team-karte__ich {
flex: none; padding: 1px 7px;
border: 1px solid color-mix(in srgb, var(--k-ton) 45%, transparent);
border-radius: 999px;
font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
color: var(--k-ton);
}
.team-karte__rolle {
margin: 2px 0 0; font-size: .78rem; color: var(--k-ton);
letter-spacing: .04em;
}
.team-karte__ueber {
margin: 9px 0 0; font-size: .87rem; line-height: 1.55;
color: var(--text-still); overflow-wrap: anywhere;
}
.team-karte__kanaele {
display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px;
}
.team-kanal {
/* 30px hoch plus Abstand -- ein Ziel, das man mit dem Daumen trifft. */
display: inline-flex; align-items: center;
min-height: 30px; padding: 4px 11px;
border: 1px solid var(--rand); border-radius: 999px;
font-size: .78rem; color: var(--text-leise); text-decoration: none;
transition: border-color var(--tempo), color var(--tempo), background var(--tempo);
}
.team-kanal:hover, .team-kanal:focus-visible {
color: var(--text);
border-color: color-mix(in srgb, var(--k-ton) 50%, var(--rand));
background: color-mix(in srgb, var(--k-ton) 12%, transparent);
}
.team-kanal:focus-visible { outline: 2px solid var(--k-ton); outline-offset: 2px; }
@media (max-width: 560px) {
.team-karte { padding: 13px 14px; gap: 12px; }
.team-karte__bild { width: 46px; height: 46px; font-size: 1.15rem; }
}
@media (forced-colors: active) {
.team-karte { border-color: CanvasText; }
}
/* ---------- "Zeig mir genau das" ------------------------------------------
Die Leiste, die nach einem Sprung vom Bericht erscheint, und die
Hervorhebung der gemeinten Elemente. (01.09.2026)
Die Hervorhebung ist ein RAND und keine Hintergrundfarbe: Auf den
Karten liegen bereits Verläufe in der Bereichsfarbe; eine zweite
Fläche darüber macht den Text schlechter lesbar. Ein Rand plus ein
ruhiger Schein zeigt dasselbe, ohne dem Inhalt etwas wegzunehmen. */
.ziel-leiste {
--z-ton: #e8b45a;
display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
margin: 0 0 20px; padding: 11px 14px;
border: 1px solid color-mix(in srgb, var(--z-ton) 38%, var(--rand));
border-radius: var(--radius-klein);
background:
linear-gradient(180deg, color-mix(in srgb, var(--z-ton) 11%, transparent), transparent 70%),
var(--flaeche);
}
.ziel-leiste__marke {
flex: none; min-width: 26px; padding: 3px 9px;
text-align: center;
border: 1px solid color-mix(in srgb, var(--z-ton) 42%, transparent);
border-radius: 999px;
background: color-mix(in srgb, var(--z-ton) 14%, transparent);
color: var(--z-ton); font-weight: 700; font-size: .86rem;
font-variant-numeric: tabular-nums;
}
.ziel-leiste__text {
flex: 1; min-width: 0;
font-size: .88rem; line-height: 1.5; color: var(--text);
overflow-wrap: anywhere;
}
.ziel-leiste__weg {
flex: none; min-height: 34px; padding: 6px 13px;
border: 1px solid var(--rand); border-radius: 999px;
background: transparent; color: var(--text-leise);
font: inherit; font-size: .82rem; cursor: pointer;
transition: border-color var(--tempo), color var(--tempo);
}
.ziel-leiste__weg:hover { color: var(--text); border-color: var(--z-ton); }
.ziel-leiste__weg:focus-visible { outline: 2px solid var(--z-ton); outline-offset: 2px; }
/* Der Treffer selbst. Gilt für JEDE Karte im Workspace, damit nicht
jede Seite ihre eigene Hervorhebung erfindet. */
[data-treffer="ja"] {
border-color: #e8b45a !important;
box-shadow: 0 0 0 1px rgba(232, 180, 90, .35),
0 0 22px -6px rgba(232, 180, 90, .5);
}
/* Ein einmaliges, langsames Aufleuchten beim Ankommen -- damit das Auge
die Stelle findet, ohne dass etwas blinkt. Läuft genau einmal. */
@media (prefers-reduced-motion: no-preference) {
[data-treffer="ja"] { animation: treffer-an 1.1s ease-out 1; }
@keyframes treffer-an {
0% { box-shadow: 0 0 0 1px rgba(232, 180, 90, .8),
0 0 30px -2px rgba(232, 180, 90, .75); }
100% { box-shadow: 0 0 0 1px rgba(232, 180, 90, .35),
0 0 22px -6px rgba(232, 180, 90, .5); }
}
}
@media (forced-colors: active) {
[data-treffer="ja"] { outline: 3px solid Highlight; }
}
/* ---------- Die Kisten im Bericht sind Wege ------------------------------
Eine Zahl, die man anklicken kann, muss auch aussehen wie etwas zum
Anklicken -- sonst probiert es niemand. */
.kachel--weg {
display: block; color: inherit; text-decoration: none;
cursor: pointer;
transition: border-color var(--tempo), transform var(--tempo);
}
.kachel--weg:hover { transform: translateY(-1px); }
.kachel--weg:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.kachel--weg .kachel__name { display: flex; align-items: center; gap: 6px; }
.kachel--weg .kachel__name::after {
content: '→'; color: var(--text-still); font-size: .9rem;
transition: transform var(--tempo), color var(--tempo);
}
.kachel--weg:hover .kachel__name::after {
color: var(--akzent); transform: translateX(3px);
}
@media (prefers-reduced-motion: reduce) {
.kachel--weg:hover { transform: none; }
.kachel--weg:hover .kachel__name::after { transform: none; }
}
/* ---------- Eingabefelder: EINE Grundlage für alle ------------------------
Wunsch vom 01.09.2026: "ich will, dass das alles richtig geil aussieht
und nicht so einfach, auch die Schrift."
DIE URSACHE war nicht Geschmack, sondern ein Loch im Aufbau. Jede
Seite gestaltete ihre Felder mit einem EIGENEN Selektor (.gruppe
textarea, .neu input, .nachricht-neu textarea …). Wer ein Feld
irgendwo anders hinsetzt, fällt durch alle Netze und bekommt den
nackten Kasten des Browsers. Genau das war beim Feld "Ein Satz über
dich" passiert: grauer Kasten, eckig -- und in MONOSPACE, weil
<textarea> ohne `font: inherit` auf Schreibmaschinenschrift
zurückfällt. Neben den gestalteten Kanalfeldern darunter sah es aus
wie ein Fehler, und es war auch einer.
Deshalb steht hier eine Grundlage, die JEDES Feld im Inhalt erfasst.
Sie kann keine bestehende Seite kaputtmachen: `:where()` hat die
Stärke null, also gewinnt jede vorhandene Regel weiterhin. Sie greift
nur dort, wo sonst gar nichts stünde -- ein Netz unter dem Netz.
(Der umgekehrte Weg wäre gewesen, alle Einzelregeln zu vereinheitlichen.
Das hätte fünf Seiten auf einmal verändert, ohne dass jemand danach
gefragt hat.) */
/* OHNE `width` -- und das ist eine Lehre aus dem ersten Anlauf. Er setzte
hier `width: 100%`, und die Formularpruefung meldete sofort Felder von
28 statt 362 Pixeln: Breite ist LAYOUT und gehoert der Seite, nicht dem
Aussehen. Eine Grundlage mit der Staerke null verliert jeden
Breitenstreit, den eine Seite fuehrt -- also darf sie ihn gar nicht
erst anfangen. Hier steht nur, WIE ein Feld aussieht; WO es steht und
wie breit es ist, entscheidet weiterhin die Seite. */
:where(.inhalt) :where(input:not([type="file"]):not([type="checkbox"]):not([type="radio"]),
textarea, select) {
padding: 10px 13px;
/* font: inherit ist die eigentliche Reparatur -- ohne das schreibt
der Browser in <textarea> in Monospace und in <select> in seiner
Systemschrift. */
font: inherit;
font-size: .92rem;
line-height: 1.5;
color: var(--text);
background:
linear-gradient(180deg, rgba(255, 255, 255, .035), rgba(255, 255, 255, .012)),
rgba(0, 0, 0, .2);
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
/* Die feine helle Kante oben -- derselbe Griff wie bei den Kacheln.
Sie lässt das Feld eingelassen wirken statt aufgemalt. */
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
transition: border-color var(--tempo), box-shadow var(--tempo), background var(--tempo);
}
:where(.inhalt) :where(textarea) {
resize: vertical; min-height: 52px;
}
:where(.inhalt) :where(input, textarea, select):hover {
border-color: color-mix(in srgb, var(--akzent) 26%, var(--rand));
}
:where(.inhalt) :where(input, textarea, select):focus {
outline: none;
border-color: color-mix(in srgb, var(--akzent) 62%, transparent);
background:
linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .02)),
rgba(0, 0, 0, .12);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05),
0 0 0 3px color-mix(in srgb, var(--akzent) 17%, transparent);
}
/* Der Platzhalter darf NICHT wie ein ausgefülltes Feld aussehen -- sonst
hält man ihn für den eigenen Text und schreibt nichts hinein. Deutlich
leiser als der Inhalt, aber noch lesbar (nicht unter 45 % Deckung). */
.inhalt input::placeholder,
.inhalt textarea::placeholder {
color: var(--text-still);
opacity: .85;
}
/* Feldbeschriftungen -- gilt für beide Schreibweisen, die es hier
historisch gibt. Kleiner, gesperrt und leise: Die Beschriftung soll
den Blick führen, nicht mit dem Inhalt konkurrieren. */
.inhalt .feld-schild,
.inhalt .feldschild {
display: block;
font-size: .74rem; font-weight: 600;
letter-spacing: .1em; text-transform: uppercase;
color: var(--text-leise);
}
/* AUF DEM HANDY 16 PIXEL. Das ist keine Geschmacksfrage: Safari auf dem
iPhone zoomt beim Antippen automatisch in die Seite hinein, sobald ein
Feld kleiner als 16px schreibt -- und zoomt danach NICHT von selbst
wieder heraus. Man tippt einmal in ein Feld und der Rest der Seite ist
für immer zu groß. */
@media (max-width: 760px) {
.inhalt input:not([type="file"]):not([type="checkbox"]):not([type="radio"]),
.inhalt textarea,
.inhalt select { font-size: 16px; }
}
/* ---------- Die Sicht eines anderen (nur DogFather) -----------------------
Der Umschalter steht im Seitenkopf, links neben dem eigenen Namen --
also genau dort, wo ohnehin steht, WER man gerade ist. Beides gehoert
zusammen: "ich, und wessen Arbeitsplatz ich gerade ansehe."
Solange eine fremde Sicht aktiv ist, faellt das deutlich auf. Das ist
der wichtigste Teil dieser ganzen Funktion: Der gefaehrlichste Fall
ist nicht, dass man die Sicht nicht wechseln kann, sondern dass man
vergisst, dass man sie gewechselt hat -- und am naechsten Tag drei
Aufgaben statt dreissig sieht und das fuer den Bestand haelt. */
.sicht {
--s-ton: #d8a13a; /* die Rollenfarbe von DogFather */
display: flex; align-items: center; gap: 8px;
padding: 4px 6px 4px 11px;
border: 1px solid var(--rand); border-radius: 999px;
background: rgba(0, 0, 0, .25);
/* SCHRUMPFEN MUSS ERLAUBT SEIN. In der Kopfleiste steht
`.kopfleiste__rechts > * { flex: 0 0 auto; }` -- jedes Teil dort
behaelt also seine Wunschbreite. Der Umschalter schob die Seite
dadurch um 46 px (Rechner) bis 117 px (Handy) aus dem Bild, und der
Abmelden-Knopf war nicht mehr erreichbar. Gemeldet von
pruef-workspace-seiten und pruef-handy, bevor es jemand gesehen hat.
Diese Regel steht spaeter in der Datei und gewinnt deshalb. */
flex: 0 1 auto;
min-width: 0;
}
/* DAS WORT "SICHT" IST WEG (06.09.2026, Wunsch Filipe: "das soll viel
besser aussehen").
Es stand als Etikett vor einem Auswahlfeld -- ein Formular, das in
die Kopfleiste gerutscht war. An seiner Stelle steht jetzt ein Auge,
das dasselbe in einem Zeichen sagt und dem NAMEN den Platz laesst,
um den es geht.
Fuer Vorleseprogramme bleibt die Beschriftung erhalten; sie ist nur
nicht mehr zu sehen. Sie ersatzlos zu loeschen haette das
Auswahlfeld unbeschriftet zurueckgelassen. */
.sicht__schild {
position: absolute;
width: 1px; height: 1px; margin: -1px; padding: 0;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.sicht__schild--alt {
flex: none;
/* 0,75 rem = 12 px. Nicht kleiner: Unter 11,5 px meldet die
Geraetepruefung zu Recht "zu kleine Schrift" -- und was auf dem
Handy niemand liest, ist auf dem Rechner auch nur Zierde. */
font-size: .75rem; font-weight: 600;
letter-spacing: .1em; text-transform: uppercase;
color: var(--text-still);
}
/* Kein `width: 100%` wie bei den Feldern im Inhalt -- hier gehoert das
Feld in eine Zeile und darf nicht die halbe Kopfleiste einnehmen. */
/* NICHT das <select> selbst gestalten -- das waere hier ein Fehler mit
Ansage. wahl.js ersetzt jedes Auswahlfeld im Workspace durch ein
eigenes Bedienelement: Das echte <select> bleibt im Dokument, wird
aber auf einen Pixel geschrumpft und unsichtbar gemacht; sichtbar ist
ein Knopf darueber (.wahl2__knopf).
Der erste Anlauf gab dem <select> Breite und Polsterung. Ergebnis:
Das versteckte Feld wurde wieder 20 x 44 Pixel gross und lag als
unsichtbares Hindernis ueber dem Knopf -- die Geraetepruefung meldete
es als "Beruehrziel zu klein", und getroffen haette man damit gar
nichts. Gestaltet wird deshalb der Knopf.
Falls wahl.js einmal nicht laeuft (Skript blockiert), traegt das
nackte <select> nichts Eigenes -- es sieht dann schlicht aus, ist
aber vollstaendig bedienbar. Das ist die richtige Reihenfolge. */
.sicht .wahl2 { flex: 0 1 auto; min-width: 0; max-width: 180px; }
.sicht .wahl2__knopf {
padding: 5px 10px;
font-size: .82rem;
border-radius: 999px;
background: rgba(255, 255, 255, .04);
}
.sicht .wahl2__knopf:hover:not([disabled]) {
background: rgba(255, 255, 255, .07);
}
/* Der Name darf gekuerzt werden, statt den Knopf aufzublaehen. */
.sicht .wahl2__text {
min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* FREMDE SICHT AKTIV -- deutlich, aber nicht schreiend. */
.sicht[data-fremd="ja"] {
border-color: color-mix(in srgb, var(--s-ton) 55%, transparent);
background:
linear-gradient(rgba(216, 161, 58, .12), rgba(216, 161, 58, .12)),
rgba(0, 0, 0, .3);
}
.sicht[data-fremd="ja"] .sicht__schild { color: var(--s-ton); }
/* Das Auge. Im Normalfall still, bei fremder Sicht in der Rollenfarbe
-- es ist dann das Erste, was auffaellt. */
.sicht__auge {
flex: none;
width: 16px; height: 16px;
fill: none; stroke: var(--text-still); stroke-width: 1.6;
transition: stroke .18s ease;
}
.sicht[data-fremd="ja"] .sicht__auge { stroke: var(--s-ton); }
/* FREMDE SICHT MUSS AUFFALLEN. Der gefaehrlichste Fall dieser Funktion
ist, dass man sie vergisst -- man sieht am naechsten Tag drei
Aufgaben statt dreissig und haelt das fuer den Bestand. Deshalb
traegt der ganze Umschalter dann Farbe, nicht nur ein Zusatzknopf. */
.sicht[data-fremd="ja"] {
border-color: color-mix(in srgb, var(--s-ton) 50%, transparent);
background: color-mix(in srgb, var(--s-ton) 12%, rgba(0, 0, 0, .25));
}
.sicht__weg {
flex: none; min-height: 28px;
/* Ein Kreuz braucht keine Wortbreite mehr. */
width: 28px; padding: 0;
display: grid; place-items: center;
border: 1px solid color-mix(in srgb, var(--s-ton) 45%, transparent);
border-radius: 999px;
background: transparent; color: var(--s-ton);
font: inherit; font-size: .76rem; cursor: pointer;
transition: background var(--tempo);
}
.sicht__weg svg {
width: 14px; height: 14px;
fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}
.sicht__weg:hover { background: color-mix(in srgb, var(--s-ton) 16%, transparent); }
.sicht__weg:focus-visible { outline: 2px solid var(--s-ton); outline-offset: 2px; }
/* Ein feiner Rahmen um die ganze Seite, solange eine fremde Sicht laeuft.
Er kostet keinen Platz, laesst sich nicht wegscrollen und ist damit die
einzige Anzeige, die man wirklich nicht uebersehen kann. */
body[data-fremde-sicht="ja"]::after {
content: "";
position: fixed; inset: 0;
border: 2px solid rgba(216, 161, 58, .38);
pointer-events: none;
z-index: 60;
}
/* Ab hier wird die Kopfleiste eng. Das Schild "SICHT" entfaellt als
Erstes -- das Feld selbst sagt bereits, wessen Sicht laeuft, und der
Rahmen um die Seite sagt DASS eine fremde laeuft. */
@media (max-width: 1180px) {
.sicht__schild { display: none; }
.sicht { padding-left: 6px; }
.sicht .wahl2 { max-width: 150px; }
}
@media (max-width: 900px) {
.sicht .wahl2 { max-width: 128px; }
/* Der Knopf "zurueck zu mir" entfaellt -- "Alles (meine Sicht)" steht
ganz oben in der Auswahl und tut dasselbe. */
.sicht__weg { display: none; }
}
@media (max-width: 620px) {
/* MINDESTBREITE, nicht nur Hoechstbreite: Ein Knopf, der auf zwanzig
Pixel zusammenfaellt, ist mit dem Daumen nicht zu treffen.
Den Platz gibt der eigene Name daneben ab -- er steht ohnehin als
Plakette da, und wessen Sicht laeuft, ist die wichtigere Auskunft. */
.sicht .wahl2 { min-width: 104px; max-width: 118px; }
.sicht { padding: 3px 4px; }
.wer__name { display: none; }
}
/* SEHR SCHMAL: die Kopfleiste darf umbrechen (05.09.2026).
Die Rechnung darueber ging genau auf, solange rechts vier Dinge
standen. Mit der Glocke sind es fuenf, und bei 320 px (iPhone SE)
passte es nicht mehr: Die Lupe des Suchknopfes lag danach mitten auf
dem Sicht-Umschalter -- ein Knopf, der auf zwoelf Seiten ins Leere
tippt. Gemeldet von pruef-handy, bevor es jemand gesehen hat.
WARUM UMBRECHEN und nicht weiter schrumpfen: Jedes Stueck hier hat
seine Mindestgroesse aus einem guten Grund -- 104 px, damit der
Umschalter mit dem Daumen zu treffen ist, und die Glocke ist bereits
auf das blosse Zeichen zusammengefallen. Wer hier weiter kuerzt,
tauscht ein sichtbares Problem gegen ein unsichtbares: Knoepfe, die
zwar nebeneinander liegen, aber zu klein zum Treffen sind.
Eine zweite Zeile auf einem 320-Pixel-Schirm kostet 44 Pixel Hoehe.
Das ist der guenstigste Preis, der hier zu haben ist -- und er faellt
nur auf Geraeten an, die wirklich so schmal sind. */
@media (max-width: 380px) {
.kopfleiste { flex-wrap: wrap; row-gap: 8px; }
/* Die Marke nimmt die erste Zeile ganz ein, die Bedienelemente
ruecken geschlossen in die zweite. Ohne das brechen sie mitten
zwischen Suche und Glocke um. */
.kopfleiste > .marke { flex: 1 0 100%; }
.kopfleiste__rechts {
width: 100%; justify-content: flex-end;
/* AUCH DIE ZWEITE ZEILE DARF UMBRECHEN. Ohne das reichten die
294 Pixel weiterhin nicht: Umschalter (104) + Suche (47) +
Glocke (37) + Plakette + Abmelden sind zusammen mehr. Die
Elemente wurden dann zwar nicht mehr ueberdeckt, aber der
Umschalter ragte aus seinem eigenen Kasten heraus -- ein
stilles Ueberlaufen, das keine Pruefung meldet und trotzdem
falsch aussieht. */
flex-wrap: wrap; row-gap: 6px;
}
/* Und der Umschalter behaelt seine Breite, statt gequetscht zu
werden: Sein Inhalt kann ohnehin nicht unter 104 px, also waere
jedes Schrumpfen nur ein Ueberlauf mit anderem Namen. */
.sicht { flex: 0 0 auto; }
}
@media (forced-colors: active) {
body[data-fremde-sicht="ja"]::after { border-color: Highlight; }
}
/* Das Wasserzeichen in der Ecke bekommt die neue Behandlung NICHT.
Es ist bewusst eine ganz dünne, fast unsichtbare Kontur; ein Schein
darunter würde daraus einen grauen Fleck machen -- und zwar genau
dort, wo er den Text der Kachel hinterlegt. (03.09.2026) */
.kachel__wasserzeichen .kachel__svg { filter: none; }
.kachel__wasserzeichen .zeichen__linie { stroke: var(--ton); stroke-width: 1.1; }
/* ---------- Die gefüllte Grundform (03.09.2026) --------------------------
Jedes Zeichen hat jetzt eine Fläche unter der Linie (siehe
bereiche.js). Sie ist bewusst schwach: Sie soll dem Zeichen ein Vorn
und ein Hinten geben, nicht mit der Linie um Aufmerksamkeit streiten.
20 % sind gemessen, nicht geraten -- darüber wird das Zeichen zum
Fleck und die Linie darin unsichtbar, darunter sieht man die Fläche
gar nicht mehr. Beim Überfahren geht sie auf 30 %, so als käme Licht
dazu. */
/* Die Spiegelung liegt auf demselben Körper -- ein schmaler heller
Streifen quer über die obere Hälfte, wie Licht auf gewölbtem Glas. */
.kachel__svg .zeichen__glanz {
fill: url(#zeichen-glanz);
stroke: none;
transition: opacity var(--tempo);
}
.kachel:hover .kachel__svg .zeichen__glanz { opacity: 1.35; }
/* Im Wasserzeichen NICHT -- dort liegt das Zeichen riesig hinter dem
Text der Kachel. Eine Fläche würde ihn hinterlegen. */
.kachel__wasserzeichen .zeichen__fuellung,
.kachel__wasserzeichen .zeichen__glanz { display: none; }
@media (prefers-reduced-motion: reduce) {
}
@media (forced-colors: active) {
/* Ohne Farben würde die Fläche zu einem massiven Block. */
.kachel__svg .zeichen__fuellung,
.kachel__svg .zeichen__glanz { display: none; }
}
/* ---------- Material statt Zeichnung (03.09.2026, zweite Stufe) ----------
Der Eigenschatten des Zeichens: eine dunkle Lage auf dem Körper, die
von unten hereinkriecht. Zusammen mit dem Streulicht in der Kontur
ergibt das die Beleuchtung, die man aus der Wirklichkeit kennt --
Hauptlicht oben, Schatten unten, Aufheller an der Unterkante. */
/* Der Schlagschatten AUF die Plakette. Er ist der eigentliche Grund,
warum das Zeichen über der Fläche zu schweben scheint statt darauf zu
liegen: Er sitzt versetzt nach unten, nicht mittig. Dazu der farbige
Hof von vorher -- Schatten UND Licht, wie bei jedem Gegenstand, der
auf etwas liegt. */
.kachel__svg {
filter:
drop-shadow(0 1.5px 1.5px rgba(0, 0, 0, .55))
drop-shadow(0 1px 4px color-mix(in srgb, var(--ton) 50%, transparent));
}
.kachel:hover .kachel__svg {
filter:
drop-shadow(0 2px 2px rgba(0, 0, 0, .6))
drop-shadow(0 2px 8px color-mix(in srgb, var(--ton) 70%, transparent));
}
/* ---------- Die Körnung ---------------------------------------------------
Eine sehr feine, unregelmäßige Struktur auf der Plakette. Sie ist der
Unterschied zwischen "am Rechner gemacht" und "Gegenstand": Eine
makellos glatte Farbfläche gibt es in der Wirklichkeit nicht, und das
Auge erkennt das sofort -- auch wenn niemand sagen könnte, woran es
liegt.
Als eingebettetes Rauschen, keine Bilddatei: kostet nichts zu laden
und kann nicht fehlen. */
.kachel__zeichen::after {
content: "";
position: absolute; inset: 0;
pointer-events: none;
opacity: .5;
mix-blend-mode: overlay;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='k'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23k)' opacity='0.35'/%3E%3C/svg%3E");
}
@media (forced-colors: active) {
.kachel__svg .zeichen__eigenschatten,
.kachel__zeichen::after { display: none; }
.kachel__svg { filter: none; }
}
/* ---------- Die Kachel als Gegenstand (03.09.2026, zweite Stufe) ---------
Die Kachel hatte schon eine Lichtkante -- aber eine durchgehend
gleich helle, über die volle Breite. Das ist ein Strich, kein Licht.
Echtes Licht auf einer Kante ist in der Mitte am stärksten und läuft
nach aussen aus.
Dazu kommt, was einer Kachel bisher ganz fehlte: TIEFE nach unten.
Ein Gegenstand, der auf etwas liegt, wirft einen Schatten -- ohne ihn
klebt die Kachel auf dem Hintergrund, statt darauf zu liegen. */
.kachel {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .04),
0 10px 26px -18px rgba(0, 0, 0, .9),
0 2px 6px -4px rgba(0, 0, 0, .5);
}
.kachel::after {
content: "";
position: absolute; top: 0; left: 14%; right: 14%; height: 1px;
background: linear-gradient(90deg,
transparent,
color-mix(in srgb, var(--ton) 75%, #fff) 50%,
transparent);
opacity: .5;
pointer-events: none;
z-index: 2;
transition: opacity var(--tempo);
}
.kachel:hover {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
0 18px 40px -20px rgba(0, 0, 0, .95),
0 3px 10px -5px color-mix(in srgb, var(--ton) 45%, transparent);
}
.kachel:hover::after { opacity: .95; }
@media (forced-colors: active) {
.kachel::after { display: none; }
}
/* ---------- Der Benachrichtigungs-Knopf ------------------------------
Wunsch Filipe (05.09.2026): ein Knopf wie "Benachrichtigungen aus",
auf jeder Seite erreichbar.
Gebaut wie `.abmelden` daneben, damit die Kopfleiste eine Sprache
spricht -- und mit denselben Umbruchregeln: Auf schmalen Schirmen
bleibt nur die Glocke stehen, der Text weicht. Genau daran ist die
Kopfleiste am 31.08.2026 schon einmal gescheitert (214 px aus dem
Bild); deshalb hier von vornherein `min-width: 0` und ein Text, der
verschwinden darf. */
.glocke {
display: inline-flex; align-items: center; gap: 7px;
min-width: 0; flex: none;
padding: 7px 13px;
background: rgba(255, 255, 255, .04);
border: 1px solid var(--rand);
border-radius: 999px;
color: var(--text-leise);
font: inherit; font-size: .82rem;
cursor: pointer;
transition: border-color var(--tempo), background var(--tempo), color var(--tempo);
}
.glocke:hover:not(:disabled) { background: rgba(255, 255, 255, .07); border-color: var(--rand-hell); }
.glocke:disabled { opacity: .55; cursor: not-allowed; }
.glocke__zeichen { width: 17px; height: 17px; flex: none; }
.glocke__zeichen path {
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
.glocke__strich { opacity: 0; }
/* AN: die Glocke bekommt Farbe, der Strich bleibt weg. */
.glocke[data-lage="an"] {
color: var(--akzent);
border-color: color-mix(in srgb, var(--akzent) 42%, transparent);
background: color-mix(in srgb, var(--akzent) 10%, transparent);
}
/* AUS: durchgestrichene Glocke -- man sieht auf einen Blick, dass
nichts kommt, ohne den Text zu lesen. */
.glocke[data-lage="aus"] .glocke__strich { opacity: .85; }
/* Die drei Faelle, in denen der Knopf nichts schalten kann, sind
gedaempft und tragen ebenfalls den Strich: Sie sind naeher an "aus"
als an "an", und genau so soll es aussehen. */
.glocke[data-lage="iphone"], .glocke[data-lage="verboten"],
.glocke[data-lage="geht-nicht"] {
color: var(--text-still);
}
.glocke[data-lage="iphone"] .glocke__strich,
.glocke[data-lage="verboten"] .glocke__strich,
.glocke[data-lage="geht-nicht"] .glocke__strich { opacity: .7; }
/* Schmale Schirme: nur die Glocke. Der Text steht weiterhin im
aria-label, Vorleseprogramme verlieren also nichts.
900 PIXEL, NICHT 760 (korrigiert 05.09.2026). Die erste Fassung
nahm 760 -- und ein Tablet hochkant hat 768. Dort stand der Text
also noch, die Glocke war rund 200 statt 37 Pixel breit, und der
Abmelden-Knopf wurde um bis zu 15 Pixel aus dem Bild geschoben. Auf
vier Seiten, gemeldet von pruef-breiten.
Die Grenze liegt jetzt auf derselben Stufe wie die uebrigen Regeln
fuer die enge Kopfleiste (der Sicht-Umschalter wird ab 900 px
ebenfalls schmaler). Eine eigene Schwelle daneben waere genau die
Art Zahl, die beim naechsten Mal wieder knapp danebenliegt. */
@media (max-width: 900px) {
.glocke { padding: 7px 9px; }
.glocke__text { display: none; }
}
/* ERKLÄRSATZ UNTER EINER ÜBERSCHRIFT — der Grundwert.
Gefunden am 05.09.2026 von pruef-css-klassen.mjs, beim allerersten
Lauf. `.block__frage` war viermal fast gleich definiert -- in
automation.css, calls.css, report.css und wissen.css -- und wurde
auf content.html benutzt, das keine dieser vier Dateien lädt. Der
Absatz stand dort seit jeher unformatiert.
Genau dasselbe Muster wie bei der Teilnehmerwahl am selben Tag:
Das CSS existiert, es sieht im Editor richtig aus, und auf der Seite
kommt nichts an. Solange es nur in Seiten-Stylesheets steht, findet
es niemand.
Hier steht deshalb der Grundwert, den jede Seite bekommt. Die vier
Seiten-Stylesheets werden NACH start.css geladen und behalten damit
ihre Feinheiten (12, 13 oder 14 Pixel Abstand) -- sie bleiben
unverändert. Neu ist nur, dass eine Seite ohne eigene Fassung nicht
mehr leer ausgeht. */
.block__frage {
margin: 0 0 13px;
font-size: .85rem;
color: var(--text-still);
max-width: 76ch;
}
/* =====================================================================
DER TAGESBLICK — eine Kachel, in der Mitte geteilt
=====================================================================
Wunsch Filipe, 05.09.2026: eine ganze Kachel, links die Hinweise,
rechts die Termine des Tages, in der Mitte geteilt -- "richtig geil
und hochwertig".
WAS "HOCHWERTIG" HIER HEISST — und was nicht:
Nicht mehr Effekte. Der Eindruck entsteht aus drei Dingen, die man
einzeln kaum bemerkt und zusammen sofort:
1. EINE Kante um beides statt zwei Kacheln nebeneinander. Zwei
Rahmen lesen sich als zwei Themen; einer sagt "zwei Seiten
derselben Sache".
2. Ein Trenner, der oben und unten AUSLÄUFT statt durchzuschneiden.
Eine harte Linie zerteilt die Kachel, ein Verlauf gliedert sie.
3. Ruhe. Der Hintergrund bleibt fast schwarz, die Farbe steckt in
wenigen kleinen Flächen -- den Punkten auf dem Zeitstrahl. Wo
alles leuchtet, leuchtet nichts.
Augenschonend ist Hausregel: keine harten Weißflächen, keine
Neonränder, Bewegung nur als kurze Blende.
AUFBAU: ein Raster mit drei Spalten -- Inhalt, Trenner, Inhalt. Der
Trenner ist eine eigene Spalte und kein Rand, damit er unabhängig von
der Höhe beider Seiten auf voller Länge sitzt und auslaufen kann. */
.tagesblick {
display: grid;
grid-template-columns: 1fr 1px 1fr;
gap: 0;
margin-bottom: 30px;
border: 1px solid var(--rand);
border-radius: var(--radius);
background:
/* Ein sehr flacher Schein von links oben -- er gibt der Fläche
Tiefe, ohne als Farbe aufzufallen. */
radial-gradient(120% 90% at 0% 0%,
rgba(255, 255, 255, .035), transparent 58%),
var(--flaeche);
overflow: hidden;
}
/* Die Überschrift der ganzen Kachel ist für Vorleseprogramme da --
auf dem Schirm sagen die beiden Schilder schon alles, und eine
dritte Überschrift darüber wäre eine Zeile ohne Inhalt. */
.tagesblick__titel {
position: absolute;
width: 1px; height: 1px; margin: -1px; padding: 0;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* DIE SPALTEN WERDEN AUSDRÜCKLICH ZUGEWIESEN (05.09.2026).
Ohne das rutschte die rechte Hälfte in die 1-Pixel-Spalte des
Trenners und war 38 statt 579 Pixel breit. Grund: Die Kachel hat drei
Kinder -- die versteckte Überschrift, links, rechts -- und ein Raster
verteilt sie der Reihe nach. `position: absolute` an der Überschrift
nimmt sie zwar aus dem Fluss, aber verlassen sollte man sich darauf
nicht: Wer später ein viertes Kind einfügt (einen Ladebalken, einen
Hinweis), verschiebt sonst wieder alles um eine Spalte, ohne dass
irgendwo ein Fehler erscheint.
Mit `grid-column` ist die Zuordnung an die Sache gebunden statt an
die Reihenfolge im Dokument. */
.tagesblick__seite--dran { grid-column: 1; }
.tagesblick__seite--heute { grid-column: 3; }
/* SOLANGE GELADEN WIRD, hält die Kachel ihre Höhe. Ohne das sprang
alles darunter nach unten, sobald die Daten ankamen -- gemessen als
Layout-Sprung 0,96 auf der Startseite. Der Wert entspricht ungefähr
einer Kachel mit zwei bis drei Einträgen je Seite. Gemessen: ein
Termin ergibt 169 px, drei ergeben 327 px -- 280 liegt dazwischen,
der Rest-Sprung ist damit in beide Richtungen klein. */
.tagesblick[data-laedt="ja"] { min-height: 280px; }
/* Die Überschriften stehen schon da, der Rest bleibt ruhig leer. Ein
zappelndes Skelett wäre hier Selbstzweck -- die Wartezeit ist der
eine Moment, in dem die Daten aus der Datenbank kommen. */
.tagesblick[data-laedt="ja"] .tagesblick__leer { visibility: hidden; }
.tagesblick__seite {
display: flex; flex-direction: column;
padding: 17px 19px 19px;
min-width: 0; /* sonst sprengt ein langer Titel die Spalte */
}
/* DER TRENNER. Oben und unten durchsichtig: Eine Linie, die die Kachel
von Kante zu Kante durchschneidet, macht aus einer Kachel zwei. Eine,
die ausläuft, gliedert sie nur. */
.tagesblick__seite--heute { position: relative; }
.tagesblick__seite--heute::before {
content: "";
position: absolute; left: -1px; top: 14px; bottom: 14px; width: 1px;
background: linear-gradient(180deg,
transparent,
var(--rand-hell) 18%,
var(--rand-hell) 82%,
transparent);
}
.tagesblick__kopf { margin-bottom: 12px; }
/* Der Kalender-Verweis rechts oben. Still, bis man ihn braucht. */
.tagesblick__mehr {
display: inline-flex; align-items: center; gap: 5px;
font-size: .78rem;
text-decoration: none;
}
.tagesblick__mehr-pfeil { width: 14px; height: 14px; }
.tagesblick__mehr:hover .tagesblick__mehr-pfeil { transform: translateX(2px); }
/* Der Satz, wenn eine Hälfte nichts zu zeigen hat. Er steht in der
Fläche, die sonst die Liste füllt -- ohne ihn sähe die Seite aus,
als hätte sie nicht geladen. */
.tagesblick__leer {
flex: 1;
display: flex; align-items: center;
margin: 0; padding: 14px 0;
font-size: .84rem; color: var(--text-still);
}
/* ---------- Die Termine des Tages ---------------------------------------
ZWEITER ANLAUF (05.09.2026). Der erste war eine Liste mit einem
dünnen Strich dahinter. Filipes Urteil an einem Tag mit EINEM
Termin: *"das soll viel geiler und krasser aussehen."*
Er hatte recht, und der Grund ist der Einzelfall: Ein Zeitstrahl
lebt davon, dass er etwas VERBINDET. Bei einem einzigen Eintrag
verbindet er nichts -- übrig bleiben eine magere Zeile, ein Strich
ins Leere und viel Weißraum bis zur Plakette am rechten Rand.
WAS SICH ÄNDERT: Jeder Termin ist jetzt eine eigene Fläche mit
farbiger Kante statt einer nackten Zeile. Das trägt auch allein.
Dazu drei Dinge, die vorher fehlten:
* Die Uhrzeit ist groß und trägt die Farbe der Terminart. Sie ist
die Auskunft, die man sucht -- vorher war sie kleiner als der
Titel.
* Ein Balken zeigt die DAUER. Aus "30 min" als Text wird etwas,
das man sieht, ohne zu lesen: Ein Zweistundenblock ist ein
anderer Tag als vier Viertelstunden.
* Der nächste Termin bekommt einen Ring und die Marke "JETZT" --
nicht bloß einen helleren Hintergrund.
WAS SICH NICHT ÄNDERT: kein Neon, keine harten Weißflächen, keine
Bewegung. "Krass" entsteht hier aus Kontrast und Hierarchie, nicht
aus Leuchtkraft -- augenschonend bleibt Hausregel. Die Farbe steckt
weiterhin in wenigen kleinen Flächen; sie wirkt nur stärker, weil
drumherum mehr Ruhe ist. */
.tagesliste {
display: grid; gap: 8px;
margin: 0; padding: 0; list-style: none;
}
.tagesliste__punkt {
--ton: #8a76ff;
position: relative;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 14px;
padding: 13px 15px 13px 17px;
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
/* Ein Hauch der Terminfarbe von links, dann nichts mehr. Die Fläche
bleibt fast schwarz -- die Farbe soll die Kante betonen, nicht die
Karte einfärben. */
background:
linear-gradient(90deg,
color-mix(in srgb, var(--ton) 8%, transparent),
transparent 42%),
rgba(255, 255, 255, .022);
transition: border-color .18s ease, background .18s ease, transform .18s ease;
overflow: hidden;
}
/* DIE KANTE LINKS ist der eigentliche Träger der Farbe. Oben kräftig,
unten auslaufend -- ein durchgehender Balken wirkt wie ein Etikett,
ein auslaufender wie Licht. */
.tagesliste__punkt::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
background: linear-gradient(180deg,
var(--ton), color-mix(in srgb, var(--ton) 30%, transparent));
}
.tagesliste__punkt[data-art="call"] { --ton: #3fbdf5; }
.tagesliste__punkt[data-art="termin"] { --ton: #8a76ff; }
.tagesliste__punkt[data-art="review"] { --ton: #50a752; }
.tagesliste__punkt[data-art="frist"] { --ton: #d17717; }
.tagesliste__punkt:hover {
border-color: color-mix(in srgb, var(--ton) 40%, var(--rand));
background:
linear-gradient(90deg,
color-mix(in srgb, var(--ton) 13%, transparent),
transparent 48%),
rgba(255, 255, 255, .045);
}
/* ---- Die Zeit: groß, farbig, mit Dauerbalken ---- */
.tagesliste__zeit {
display: flex; flex-direction: column; align-items: flex-start;
gap: 7px;
min-width: 92px;
}
/* Balken und Minutenzahl stehen NEBENEINANDER, nicht übereinander.
Untereinander lag der Balken direkt unter der Uhrzeit und las sich
als deren Unterstreichung -- er sah aus wie Deko und nicht wie eine
Angabe. Nebeneinander ist klar, dass die Länge etwas bedeutet, und
die linke Spalte wird eine Zeile flacher. */
.tagesliste__laenge {
display: flex; align-items: center; gap: 8px;
width: 100%;
}
.tagesliste__stunde {
font-size: 1.12rem; font-weight: 700;
letter-spacing: -.01em; line-height: 1;
color: color-mix(in srgb, var(--ton) 62%, #ffffff);
font-variant-numeric: tabular-nums;
}
/* DER DAUERBALKEN. Seine Breite kommt aus --laenge (in start.js
gesetzt): 30 Minuten sind kurz, zwei Stunden füllen ihn. Damit sieht
man die Länge, statt sie zu lesen.
Gedeckelt bei 100 %, weil ein Ganztagestermin den Balken sonst aus
der Karte schöbe. */
.tagesliste__balken {
position: relative; flex: none;
/* Feste Breite statt 100 %: Die Spur ist der Maßstab, an dem man die
Füllung abliest. Wäre sie mal breiter, mal schmaler, sagte die
Füllung nichts mehr. */
width: 40px; height: 4px;
border-radius: 999px;
background: rgba(255, 255, 255, .08);
overflow: hidden;
}
.tagesliste__balken::after {
content: ""; position: absolute; inset: 0;
width: var(--laenge, 30%);
border-radius: 999px;
background: linear-gradient(90deg,
var(--ton), color-mix(in srgb, var(--ton) 45%, transparent));
}
.tagesliste__dauer {
font-size: .74rem; color: var(--text-still);
font-variant-numeric: tabular-nums;
}
/* ---- Text ---- */
.tagesliste__text { min-width: 0; }
.tagesliste__titel {
margin: 0;
font-size: .96rem; font-weight: 620; color: var(--text);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tagesliste__unter {
margin: 3px 0 0;
font-size: .78rem; color: var(--text-still);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ---- Rechte Seite: Art und Zustand ---- */
.tagesliste__rechts {
display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
}
.tagesliste__art {
padding: 3px 10px; border-radius: 999px;
/* 11,84 px. Unter 11,5 meldet die Geräteprüfung zu Recht "zu kleine
Schrift" -- und Großbuchstaben mit Sperrung wirken kleiner, als
sie sind. */
font-size: .74rem; font-weight: 700;
letter-spacing: .06em; text-transform: uppercase;
color: color-mix(in srgb, var(--ton) 78%, #ffffff);
background: color-mix(in srgb, var(--ton) 13%, transparent);
border: 1px solid color-mix(in srgb, var(--ton) 30%, transparent);
white-space: nowrap;
}
/* DIE JETZT-MARKE. Sie sagt in einem Wort, was der hellere Hintergrund
vorher nur andeutete. */
.tagesliste__jetzt {
display: none;
align-items: center; gap: 5px;
/* 11,84 px. Zum ZWEITEN Mal an dieser Kachel korrigiert -- erst die
Art-Plaketten, jetzt diese Marke. Unter 11,5 px meldet die
Geraetepruefung zu Recht "zu kleine Schrift", und Grossbuchstaben
mit weiter Sperrung wirken noch kleiner, als sie sind. */
font-size: .74rem; font-weight: 800;
letter-spacing: .1em; text-transform: uppercase;
color: var(--ton);
}
.tagesliste__jetzt::before {
content: ""; width: 6px; height: 6px; border-radius: 50%;
background: var(--ton);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--ton) 22%, transparent);
}
.tagesliste__punkt[data-naechster="ja"] .tagesliste__jetzt { display: inline-flex; }
/* ---- Als Nächstes dran ---- */
.tagesliste__punkt[data-naechster="ja"] {
border-color: color-mix(in srgb, var(--ton) 45%, transparent);
background:
linear-gradient(90deg,
color-mix(in srgb, var(--ton) 15%, transparent),
transparent 55%),
rgba(255, 255, 255, .04);
}
.tagesliste__punkt[data-naechster="ja"]::before { width: 4px; }
.tagesliste__punkt[data-naechster="ja"] .tagesliste__stunde {
color: color-mix(in srgb, var(--ton) 40%, #ffffff);
}
/* ---- Vorbei ----
Zurücktreten, nicht verschwinden: Man will sehen, was man heute
schon hinter sich hat. Statt alles blass zu machen (dann leidet die
Lesbarkeit), verliert nur die FARBE an Kraft -- der Text bleibt. */
.tagesliste__punkt[data-vorbei="ja"] {
--ton: #75859a;
background: rgba(255, 255, 255, .015);
}
.tagesliste__punkt[data-vorbei="ja"] .tagesliste__titel { color: var(--text-leise); }
.tagesliste__punkt[data-vorbei="ja"]::before { opacity: .5; }
.tagesliste__punkt[data-vorbei="ja"]:hover { background: rgba(255, 255, 255, .04); }
/* Der Haken sagt "erledigt" schneller als jede Farbe. */
.tagesliste__punkt[data-vorbei="ja"] .tagesliste__art::before {
content: "✓ ";
font-weight: 700;
}
/* ---- Der ganze Eintrag ist anklickbar ----
Ein <a> um alles herum läse sich für ein Vorleseprogramm als ein
einziger langer Name. So bleibt die Struktur erhalten, und das
aria-label sagt den ganzen Satz. */
.tagesliste__link {
position: absolute; inset: 0;
border-radius: var(--radius-klein);
}
/* "3 weitere Termine heute" -- der Hinweis auf das, was nicht mehr
in die Kachel passte. Still gehalten: Er ist ein Wegweiser, keine
sechste Karte. */
.tagesliste__mehr {
padding: 4px 0 0 2px;
}
.tagesliste__mehr-link {
font-size: .8rem; color: var(--text-still);
text-decoration: none;
transition: color .16s ease;
}
.tagesliste__mehr-link:hover { color: var(--text-leise); }
.tagesliste__link:focus-visible {
outline: 2px solid var(--ton); outline-offset: -3px;
}
/* ---------- Schmale Schirme --------------------------------------------
Untereinander statt nebeneinander -- und der Trenner wird waagerecht.
Zwei Spalten auf einem Handy hieße zwei halbe Zeilen, in denen jeder
Titel abgeschnitten ist. */
@media (max-width: 900px) {
.tagesblick { grid-template-columns: 1fr; }
/* Die feste Spaltenzuweisung von oben muss hier zurückgenommen
werden -- "Spalte 3" gibt es in einem einspaltigen Raster nicht,
und der Browser legt dann stillschweigend zwei leere Spalten an. */
.tagesblick__seite--dran,
.tagesblick__seite--heute { grid-column: 1; }
.tagesblick__seite--heute::before {
left: 14px; right: 14px; top: -1px; bottom: auto;
width: auto; height: 1px;
background: linear-gradient(90deg,
transparent, var(--rand-hell) 18%, var(--rand-hell) 82%, transparent);
}
.tagesblick__seite { padding: 15px 16px 17px; }
.tagesblick__seite--heute { padding-top: 17px; }
}
@media (max-width: 460px) {
.tagesliste__punkt {
/* Die Uhrzeitspalte wird schmaler, der Rest bleibt. Die Plakette
nach unten zu schieben wäre der naheliegende Griff -- sie steht
dann aber unter dem Titel und macht jede Karte fünfzig Pixel
höher, ohne etwas zu gewinnen. */
gap: 11px;
padding: 12px 13px 12px 15px;
/* OBEN AUSRICHTEN: Bricht der Titel auf zwei Zeilen, stünde eine
mittig gesetzte Uhrzeit auf Höhe der zweiten und fluchtete mit
nichts. Am Rechner bleibt es mittig, dort ist alles einzeilig. */
align-items: start;
}
.tagesliste__zeit { min-width: 78px; }
.tagesliste__stunde { font-size: 1.02rem; }
/* Der Balken entfaellt am Handy -- neben ihm bliebe fuer den Titel
zu wenig. Die Zahl sagt es weiterhin. */
.tagesliste__balken { display: none; }
.tagesliste__titel { font-size: .92rem; white-space: normal; }
.tagesliste__rechts { padding-top: 2px; }
}
@media (prefers-reduced-motion: reduce) {
.tagesliste__punkt, .tagesblick__mehr-pfeil { transition: none; }
}
/* Ohne Farbverläufe trägt die Kante allein -- und die ist hier ein
Verlauf, also muss sie zur echten Fläche werden. Sonst verschwindet
ausgerechnet das Merkmal, das die Terminart anzeigt. */
@media (forced-colors: active) {
.tagesblick { border: 1px solid CanvasText; }
.tagesblick__seite--heute::before { background: CanvasText; }
.tagesliste__punkt { border: 1px solid CanvasText; }
.tagesliste__punkt::before { background: CanvasText; }
.tagesliste__punkt[data-naechster="ja"] { border-width: 2px; }
.tagesliste__balken::after { background: CanvasText; }
.tagesliste__art { border: 1px solid CanvasText; }
.tagesliste__jetzt::before { background: CanvasText; box-shadow: none; }
/* Im Kontrastmodus gibt es keine gedämpften Töne -- der Haken vor
der Art bleibt das Merkmal für "vorbei". */
.tagesliste__punkt[data-vorbei="ja"] { opacity: 1; }
}
/* ---------- Der Chat-Knopf in der Kopfleiste ----------------------------
Steht auf JEDER Seite (kopf.js), nur nicht auf der Chatseite selbst.
Eine Nachricht, die man erst sieht, wenn man den Chat aufmacht, ist
keine Nachricht -- sie ist ein Fundstück. */
.chat-knopf {
display: inline-flex; align-items: center; gap: 7px;
position: relative;
padding: 7px 13px;
border: 1px solid var(--rand); border-radius: 11px;
background: rgba(255, 255, 255, .04);
color: var(--text-leise); font-size: .85rem; font-weight: 600;
text-decoration: none;
transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.chat-knopf:hover {
color: var(--text);
border-color: var(--rand-hell);
background: rgba(255, 255, 255, .07);
}
.chat-knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat-knopf__zeichen {
width: 17px; height: 17px; flex: none;
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linejoin: round;
}
/* Wartet etwas, trägt der Knopf selbst Farbe -- nicht nur die Plakette.
Eine kleine Zahl am Rand übersieht man beim Überfliegen. */
.chat-knopf[data-neu="ja"] {
color: var(--akzent);
border-color: color-mix(in srgb, var(--akzent) 42%, transparent);
background: color-mix(in srgb, var(--akzent) 10%, transparent);
}
.chat-knopf__zahl {
min-width: 19px; height: 19px; padding: 0 5px;
display: grid; place-items: center;
border-radius: 999px;
/* 11,84 px -- unter 11,5 meldet die Geräteprüfung zu Recht "zu kleine
Schrift". */
font-size: .74rem; font-weight: 700;
font-variant-numeric: tabular-nums;
color: #0b0f16;
background: var(--akzent);
}
/* Schmale Schirme: nur das Zeichen. Der Text steht weiterhin im
aria-label. Dieselbe Grenze wie bei der Glocke -- eine eigene Zahl
daneben wäre genau die Art Wert, die beim nächsten Mal knapp
danebenliegt. */
@media (max-width: 900px) {
.chat-knopf { padding: 7px 9px; }
.chat-knopf__text { display: none; }
}
@media (prefers-reduced-motion: reduce) { .chat-knopf { transition: none; } }
@media (forced-colors: active) {
.chat-knopf { border: 1px solid CanvasText; }
.chat-knopf[data-neu="ja"] { border-width: 2px; }
.chat-knopf__zahl { border: 1px solid CanvasText; }
}