/* ===================================================================
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-studio-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. */
/* JEDE SZENE IHR EIGENES MOTIV (07.09.2026).
Hier standen neun Zeilen, die alle auf DIESELBE Datei zeigten.
Die Zuordnung war seit dem 01.09. richtig gedacht und seit dem
03.09. wirkungslos -- neun Regeln, ein Bild. Aufgefallen ist es
niemandem, weil jede einzelne Seite fuer sich stimmig aussah;
man merkt es erst, wenn man zwei nebeneinander haelt.
Welches Bild wohin, steht in tools/gate-bauen.mjs begruendet.
Kurz: Es folgt dem, was auf der Seite passiert -- Spiegelkabinett
fuers Dashboard (viele auf einen Blick), Glut fuer Aufgaben und
Technik (Werkstatt), Ahorn fuer Start-Check und Scout (etwas,
das waechst). */
body.start[data-buehne="studio"]::before { background-image: url("../img/buehne-studio-breit.webp"); }
body.start[data-buehne="showbuehne"]::before { background-image: url("../img/buehne-showbuehne-breit.webp"); }
body.start[data-buehne="garage"]::before { background-image: url("../img/buehne-garage-breit.webp"); }
body.start[data-buehne="skyline"]::before { background-image: url("../img/buehne-skyline-breit.webp"); }
body.start[data-buehne="lounge"]::before { background-image: url("../img/buehne-lounge-breit.webp"); }
body.start[data-buehne="arena"]::before { background-image: url("../img/buehne-arena-breit.webp"); }
body.start[data-buehne="halle"]::before { background-image: url("../img/buehne-halle-breit.webp"); }
body.start[data-buehne="wald"]::before { background-image: url("../img/buehne-wald-breit.webp"); }
body.start[data-buehne="portal"]::before { background-image: url("../img/buehne-portal-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. */
/* SEIT DEM 06.09.2026 DEUTLICH DURCHLAESSIGER (.8/.86 -> .46/.52).
Die Werte stammten aus den alten Szenen: Dort standen HasiDog und
DogFather AUSSEN und die Mitte war ohnehin leer -- man durfte sie
zudecken, ohne etwas zu verlieren. Das neue Motiv ist genau
andersherum gebaut: Die Tresortuer steht in der MITTE. Der
Leseweg loeschte damit ausgerechnet das aus, was man sehen soll.
Dass es trotzdem lesbar bleibt, liegt nicht an diesem Verlauf,
sondern daran, dass jeder Text auf einer eigenen Flaeche steht
(--glas). Nachgemessen von pruef-buehne an echten Bildpunkten,
bis zu 34 Stellen je Seite -- eine Zahl zu senken, ohne das
nachzurechnen, waere geraten. */
linear-gradient(90deg,
rgba(5, 7, 13, 0) 0,
rgba(5, 7, 13, .62) min(22%, 400px),
rgba(5, 7, 13, .68) 50%,
rgba(5, 7, 13, .62) max(78%, calc(100% - 400px)),
rgba(5, 7, 13, 0) 100%);
}
/* GROSSE SCHIRME BEKOMMEN DIE GROSSE FASSUNG (07.09.2026).
Die breite Fassung ist 1600 px. Auf einem 2550 px breiten
Bildschirm rechnet der Browser sie um das 1,6-fache hoch, und
jede Kante wird weich -- dasselbe Problem wie auf der
Anmeldeseite. Ein Hintergrundbild kennt kein `srcset`, deshalb
hier ueber eine Fenstergroesse.
1700 px als Grenze, nicht 1600: Genau bei der eigenen Breite zu
wechseln hiesse, dass ein 1600er Fenster staendig zwischen
beiden Fassungen steht. */
/* ---------- DER EINGANG HAT SEINE EIGENE BUEHNE (10.09.2026) ------------
Filipe zum Bildschirmfoto: "das foto von mir husky hasen und logo
kannst du in den hintergrund setzen aber nicht in die kachel.
hintergrund von der seite bitte."
Die Seite hatte bis eben GAR KEINE Szene -- und das war kein
Versehen im CSS, sondern eine Kette: `zuSeite()` sucht die Kachel
zur Seite in bereiche.js, die Eingangs-Kachel kommt aber vom Server
(damit sie nicht in einer Datei steht, die jeder bekommt). Also fand
sie niemand, `data-buehne` blieb leer, und es griff der Rueckfall --
ausgerechnet der Spicy-Wasserfall.
Deshalb steht `data-buehne="eingang"` fest im HTML der Seite: Sie hat
genau eine Szene, sie wechselt nie, und sie braucht dafuer kein
Skript.
UND ZWAR AUF BEIDEN ADRESSEN. Der Eingang wird von DogFather und
seiner rechten Hand geoeffnet -- er von workspace., sie von crew.
Deshalb steht hier gleich das Team-Dogi-Motiv, nicht der Umweg ueber
die Weiche des Servers: Die greift nur auf crew., und er saehe sonst
weiter das falsche Bild. */
body.start[data-buehne="eingang"]::before {
background-image: url("../img/crew-buehne-studio-breit.webp");
}
@media (min-width: 1700px) {
body.start[data-buehne="eingang"]::before { background-image: url("../img/crew-buehne-studio-uhd.webp"); }
body.start[data-buehne="studio"]::before { background-image: url("../img/buehne-studio-uhd.webp"); }
body.start[data-buehne="showbuehne"]::before { background-image: url("../img/buehne-showbuehne-uhd.webp"); }
body.start[data-buehne="garage"]::before { background-image: url("../img/buehne-garage-uhd.webp"); }
body.start[data-buehne="skyline"]::before { background-image: url("../img/buehne-skyline-uhd.webp"); }
body.start[data-buehne="lounge"]::before { background-image: url("../img/buehne-lounge-uhd.webp"); }
body.start[data-buehne="arena"]::before { background-image: url("../img/buehne-arena-uhd.webp"); }
body.start[data-buehne="halle"]::before { background-image: url("../img/buehne-halle-uhd.webp"); }
body.start[data-buehne="wald"]::before { background-image: url("../img/buehne-wald-uhd.webp"); }
body.start[data-buehne="portal"]::before { background-image: url("../img/buehne-portal-uhd.webp"); }
body.start::before { background-image: url("../img/buehne-studio-uhd.webp"); }
}
/* Alles Bedienbare liegt über der Bühne. Ohne das läge der Inhalt zwar
sichtbar darüber, aber Klicks landeten teils am falschen Ort. */
/* DIE KOPFLEISTE BLEIBT OBEN STEHEN (07.09.2026).
Filipe: "diese leiste soll immer da stehen bleiben, egal ob man die
seite runterscrollt oder nicht, auf allen seiten."
Sie WAR nie klebend, obwohl es zwanzig Zeilen weiter unten so
dasteht (`.kopfleiste { position: sticky; top: 0 }`). Diese Regel
hier hat es ueberschrieben: `body.start > .kopfleiste` ist (0,2,1),
`.kopfleiste` nur (0,1,0) -- die staerkere gewinnt, unabhaengig von
der Reihenfolge. Gemessen im Browser: `position: relative`, und beim
Scrollen um 600 px wanderte die Leiste um 600 px nach oben aus dem
Bild.
Das ist heute die VIERTE Spielart derselben Falle: `:where()` war zu
schwach, `body.start .willkommen` zu stark, die Kachel-Verschachtelung
zu stark -- und hier eine Regel, die etwas ganz anderes wollte (den
Stapelwert ueber der Buehne) und dabei die Positionierung mitnahm.
Wer `position` setzt, nur um `z-index` zu bekommen, greift jedes Mal
daneben.
Der Stapelwert bleibt: 6 statt 1, damit die Leiste ueber den Modulen
liegt -- sie steht ja jetzt auf ihnen. */
/* NICHT MEHR NUR "body.start" (23.09.2026): Es gibt eine Seite mit
Kopfleiste, die "body.haus" traegt (anruf-probe.html). Dort klebte
sie nie -- nicht weil das so gedacht war, sondern weil der
Selektor sie nicht erfasst hat. Die Leiste soll auf ALLEN Seiten
stehen bleiben, also fragt die Regel nicht mehr nach dem Haus. */
body > .kopfleiste {
position: sticky; top: 0; z-index: 6;
}
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-studio-schmal.webp");
background-size: cover;
background-position: 50% 38%;
}
body.start[data-buehne="eingang"]::before { background-image: url("../img/crew-buehne-studio-schmal.webp"); }
body.start[data-buehne="studio"]::before { background-image: url("../img/buehne-studio-schmal.webp"); }
body.start[data-buehne="showbuehne"]::before { background-image: url("../img/buehne-showbuehne-schmal.webp"); }
body.start[data-buehne="garage"]::before { background-image: url("../img/buehne-garage-schmal.webp"); }
body.start[data-buehne="skyline"]::before { background-image: url("../img/buehne-skyline-schmal.webp"); }
body.start[data-buehne="lounge"]::before { background-image: url("../img/buehne-lounge-schmal.webp"); }
body.start[data-buehne="arena"]::before { background-image: url("../img/buehne-arena-schmal.webp"); }
body.start[data-buehne="halle"]::before { background-image: url("../img/buehne-halle-schmal.webp"); }
body.start[data-buehne="wald"]::before { background-image: url("../img/buehne-wald-schmal.webp"); }
body.start[data-buehne="portal"]::before { background-image: url("../img/buehne-portal-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 ------------------------------------------------ */
/* DIE AEUSSERE LEISTE BRICHT NICHT UM -- der Schriftzug gibt nach.
Ein erster Versuch am 06.09.2026 setzte auch hier `flex-wrap: wrap`.
Ergebnis, gemessen: Bei 1280 px brauchte die Leiste 1235 px (Marke
375 + Bedienelemente 844 + Abstand 16) und hatte 1200 -- also brach
sie in zwei Zeilen um, und zwar erst NACHDEM das Skript den
Umschalter und den Chat-Knopf eingehaengt hatte. Die ganze Seite
sprang dabei 52 px nach unten (CLS 0,94).
Flexbox zieht Umbrechen dem Schrumpfen vor. Wer hier `wrap` erlaubt,
bekommt also eine zweite Zeile, obwohl der Schriftzug daneben
bereitwillig kuerzer wuerde -- und ein gekuerzter Schriftzug ist
allemal besser als eine Seite, die beim Laden springt. Umgebrochen
wird nur noch auf sehr schmalen Geraeten (siehe unten), wo es
wirklich keinen anderen Weg gibt. */
.kopfleiste {
position: sticky; top: 0; z-index: 5;
display: flex; align-items: center; justify-content: space-between; gap: 16px;
/* Der sichere Bereich kommt OBEN DRAUF, nicht statt der Polsterung:
Auf einem Geraet ohne Aussparung ist der Wert 0 und es bleibt bei
den 14 px. Seitlich dasselbe -- im Querformat liegt die Aussparung
links oder rechts, und ohne den Zuschlag verschwindet die Marke
halb darunter. `100vw` zaehlt die Aussparung naemlich mit. */
padding: calc(14px + var(--ws-sicher-oben, 0px))
calc(clamp(16px, 4vw, 40px) + var(--ws-sicher-rechts, 0px))
14px
calc(clamp(16px, 4vw, 40px) + var(--ws-sicher-links, 0px));
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; }
}
/* UMBRECHEN IST DIE VORGABE, NICHT DIE AUSNAHME (06.09.2026).
Hier stand `flex-wrap` erst ab 380 px -- und der Kommentar weiter
unten erzaehlt selbst, warum das schon einmal schiefging: "Die
Rechnung ging genau auf, solange rechts VIER Dinge standen. Mit der
Glocke sind es FUENF, und bei 320 px passte es nicht mehr."
Am 06.09.2026 kam der Chat-Knopf dazu. SECHS Dinge, und die Schwelle
blieb bei 380. Ergebnis, von pruef-handy gemessen: Bei 412 px -- der
haeufigsten Android-Breite ueberhaupt -- brach nichts um, der
Umschalter wurde auf 50 px zusammengedrueckt, sein Knopf behielt
seine 104 px und lag damit quer ueber dem Chat-Knopf. Wer auf "Meine
Sicht" tippte, landete im Chat. Auf ZWOELF Seiten.
Die Lehre ist nicht "380 auf 430 erhoehen" -- das waere derselbe
Fehler ein drittes Mal, nur mit einer anderen Zahl. Eine feste
Schwelle ist eine Rechnung, die jemand einmal aufgestellt hat und die
beim naechsten Knopf still falsch wird.
`flex-wrap: wrap` OHNE Schwelle rechnet nicht, sondern misst: Es
bricht genau dann um, wenn der Platz nicht reicht, und sonst nie. Auf
dem Rechner aendert sich dadurch nichts. */
.kopfleiste__rechts {
/* 10 statt 12 px zwischen den Teilen.
Gemessen bei 1280 px: Die Bedienelemente brauchen zusammen 844 px
(784 Inhalt + fuenf Abstaende zu 12), verfuegbar waren nach dem
geschrumpften Schriftzug 843. EIN Pixel -- und die ganze Gruppe
brach in eine zweite Zeile um, was die Seite beim Laden 45 px nach
unten schob. Zwei Pixel weniger Abstand loesen es und sieht niemand;
eine zweite Kopfzeile sieht jeder. */
display: flex; align-items: center; gap: 10px;
/* NICHT SCHRUMPFEN -- die MARKE gibt nach, nicht die Bedienelemente.
Mit `flex: 0 1 auto` wurde dieser Kasten schmaler als sein Inhalt,
und der brach dann schon bei 1280 px in eine zweite Zeile um. Das
war nicht nur haesslich, es war ein Sprung: Die Leiste wuchs, kaum
dass das Skript den Umschalter eingehaengt hatte, und schob die
ganze Seite 52 px nach unten (gemessen von pruef-tempo-workspace,
CLS 1,0). Der Schriftzug daneben darf gekuerzt werden, ein Knopf
nicht. */
/* SCHRUMPFEN DARF ER WIEDER -- aber erst nach dem Schriftzug.
Am 06.09.2026 stand hier zweimal etwas Falsches, an einem Abend:
flex: 0 1 auto -> bei 1280 px wurde der Kasten schmaler als sein
Inhalt, brach in zwei Zeilen um und schob die
Seite 52 px nach unten (CLS 0,94).
flex: 0 0 auto -> bei 390 und 412 px konnte er weder schrumpfen
noch umbrechen und stand 126 px aus dem Bild.
Auf ZWOELF Seiten, gemessen von pruef-handy.
Beide Male habe ich an DIESEM Kasten gedreht -- und beide Male war
die Frage die falsche. Es geht nicht darum, OB er nachgibt, sondern
WER von beiden ZUERST nachgibt. Die Antwort ist eindeutig: der
Schriftzug, denn der darf gekuerzt werden; ein Knopf nicht.
Also bekommt die Marke einen sehr hohen Schrumpf-Faktor (siehe
dort), und dieser Kasten den gewoehnlichen. Flexbox verteilt die
Enge dann fast vollstaendig auf die Marke; erst wenn die am
Anschlag ist, gibt er selbst nach -- und dann brechen seine Kinder
IN IHM um, statt die ganze Leiste zu sprengen.
Damit braucht es keine Bildschirmbreite als Schwelle mehr, in
keiner Richtung. */
flex: 0 1 auto; min-width: 0;
flex-wrap: wrap; row-gap: 6px; justify-content: flex-end;
/* DIE ZEILE HAT IMMER DIESELBE HOEHE (07.09.2026).
Gemessen: Vor dem Skript ist die Leiste 67 px hoch, danach 71 --
der Sicht-Umschalter kommt erst, wenn die Personenliste da ist, und
ist mit 42 px das hoechste Teil hier. Die vier Pixel schieben die
GANZE Seite nach unten; pruef-tempo mass daraus einen Sprung von
0,99. Man sieht es kaum und merkt es doch: Wer beim Laden schon
zielt, klickt daneben.
44 px ist keine gegriffene Zahl, sondern das Mindestmass fuer ein
Fingerziel (WCAG 2.5.8), das hier ohnehin ueberall gilt. Damit ist
die Zeile so hoch wie ihr groesstes zulaessiges Teil -- egal, ob
dieses Teil gerade schon da ist oder erst kommt. Kein reservierter
Platz auf Verdacht, sondern die Hoehe, die sie sowieso haben muss. */
min-height: 44px;
align-content: center;
}
.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;
/* Seitlich und unten der sichere Bereich obendrauf (09.09.2026):
im Querformat liegt die Aussparung seitlich, unten sitzt auf
randlosen Geraeten die Gestenleiste. Ohne Aussparung sind beide 0. */
padding: clamp(28px, 5vw, 56px)
calc(clamp(16px, 4vw, 40px) + var(--ws-sicher-rechts, 0px))
calc(64px + var(--ws-sicher-unten, 0px))
calc(clamp(16px, 4vw, 40px) + var(--ws-sicher-links, 0px));
}
/* 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; }
/* Zwei Knöpfe rechts im Kopf einer Liste: der stille Schalter und die
Hauptaktion. Eigener Behälter, damit sie beim Umbruch ZUSAMMEN
umbrechen -- sonst steht auf schmalen Geräten der Schalter allein in
einer Zeile und die Hauptaktion in der nächsten. */
.klapp-kopf__knoepfe {
display: flex; align-items: center; gap: 10px;
flex-wrap: wrap; justify-content: flex-end;
margin-left: auto;
}
.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; }
/* SIEBEN STATT VIER -- fuer Listen, bei denen die Woche die Einheit ist
(07.09.2026, Wunsch Filipe zur Tagesliste: "man soll immer noch die
letzten 7 tage sehen"). Vier Tage sind kein Zeitraum, ueber den man
etwas sagen kann; sieben sind eine Woche und damit vergleichbar.
Eine zweite Regel und keine gerechnete Zahl: `nth-child` nimmt keine
CSS-Variable. Zwei feste Werte, die beide im Quelltext stehen, sind
ehrlicher als eine Zahl, die man im Stil sucht und im Skript findet. */
[data-klapp="zu7"] > *:nth-child(n+8) { 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);
}
/* --text-leise (#94a5bb) statt --text-still (#7f8fa6), 07.09.2026.
Diese Zeile steht als einzige Beschriftung OHNE Karte direkt auf dem
Buehnenbild. Solange die Gruppen dort standen, wo das Bild dunkel
ist, ging der leiseste Ton gut. Mit der fuenften Rolle (Spicy Media)
rutschte auf personen.html alles eine Zeile nach unten -- und die
DogFather-Beschreibung landete auf rgb(46, 44, 47): 4,21:1 statt der
noetigen 4,5.
Der Ausloeser war also nicht die Farbe, sondern eine Verschiebung.
Genau deshalb bekommt ein Text, dessen Untergrund ein FOTO ist, nicht
den leisesten Ton: Was heute passt, passt nach der naechsten
eingefuegten Zeile nicht mehr. Jetzt 5,5:1 -- mit Luft.
Gemessen von pruef-buehne an echten Bildpunkten. */
.gruppe__unter { font-size: .78rem; color: var(--text-leise); }
.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 120,0 Grad zwischen allen Nachbarn (06.09.2026 mit 21 Kacheln neu gerechnet). 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 einundzwanzig.
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. */
/* NEU GERECHNET AM 08.09.2026 (tools/kachel-farben.mjs).
Filipe: "viele kacheln haben noch fast die gleiche farben, ähneln sich
sehr ... alle seine eigenen farben und so dass sie sich nicht ähneln.
sehr wichtig nicht ähneln!!!!" -- und er hatte recht, es liess sich
messen. Die alte Palette lief um EINEN Farbring mit absichtlich
konstanter Helligkeit; damit blieb als einziger Unterschied der
Farbton, und 360 Grad auf 21 Kacheln sind 17 Grad. So wenig sieht man
nicht.
alt kleinster Abstand 0,033 · 21 von 210 Paaren unter 0,05
· Helligkeitsspanne 0,002
neu kleinster Abstand 0,097 · 0 von 210 Paaren unter 0,05
· Helligkeitsspanne 0,242
Jetzt variieren Helligkeit UND Farbstaerke mit. Zwei Farben mit
aehnlichem Ton stehen dadurch trotzdem weit auseinander, weil die eine
hell und satt und die andere dunkel und ruhig ist.
Gemessen in OKLab (dort entspricht der Zahlenabstand dem empfundenen
Unterschied), und jede Farbe haelt 4,5:1 gegen den dunklen Grund --
sie traegt auch Text. Wer sie neu rechnet: Das Werkzeug bricht ab,
wenn das Ergebnis schlechter waere als der alte Stand. */
[data-ton="1"] { --ton: #0c86af; } /* Dashboard */
[data-ton="2"] { --ton: #fe5e82; } /* Zahlen */
[data-ton="3"] { --ton: #18b803; } /* LIVE */
[data-ton="4"] { --ton: #c16302; } /* Chat */
/* TON 5 IST VON HAND GESETZT (09.09.2026, screen4).
Filipe: "ich will dass die kategorie eine farbe bekommt die extrem
krass auffällt. diese kategorie ist nämlich seeeehr wichtig und so
soll sie auch auffallen." Gemeint ist "Schutz & Regeln" -- die
einzige Kachel mit diesem Ton (nachgesehen in bereiche.js).
MAGENTA, WEIL ES DAS EINZIGE IST, DAS ES HIER SONST NICHT GIBT.
Rot ist im Haus für "überfällig" und für Spicy Media vergeben,
Babyblau für DogFather, Lila für Manager, Grün für Scout, Bronze
für Creator, Bernstein für "dringend". Ein Magenta stößt mit keinem
davon zusammen. Es fällt nicht auf, weil es HELLER ist, sondern
weil es einzigartig ist -- und das ist die verlässlichere Art:
Helligkeit konkurriert mit den Nachbarn, Einzigartigkeit nicht.
NACHGERECHNET WIE BEI TON 21: Der engste Abstand zwischen zwei der
übrigen zwanzig Farben liegt bei 0,0973 (OKLab). #ff2fd0 kommt
seinem nächsten Nachbarn (Ton 8, #c06ad0) auf 0,1305 nahe, ist also
weiter entfernt als das engste vorhandene Paar. Seine Buntheit ist
mit 0,276 die höchste im ganzen Satz -- das alte Gold lag bei
0,170. Kontrast auf dunklem Grund: 6,00:1.
Von sieben geprüften Kandidaten sind drei an der Abstandsgrenze
gescheitert (#ff2f9c, #00ff9d und #ff5ce0 lagen ihren Nachbarn zu
nahe). Unter den bestandenen hat dieser die höchste Buntheit bei
ausreichendem Kontrast. Das Säuregelb #e0ff00 wäre lauter gewesen
(16,86:1), hätte sich aber mit dem Bernstein von "dringend" und dem
Gold der Nachbarkacheln um dieselbe Wirkung gestritten.
Die Kachel bleibt gebaut wie alle anderen -- das war ausdrücklich
gewünscht ("alle kacheln auf der ganzen website sollen sein wie auf
der startseite"). Was sie heraushebt, ist die Farbe, nicht eine
Sonderform. */
[data-ton="5"] { --ton: #ff08d5; } /* Schutz & Regeln -- Wunsch: extrem auffällig */
[data-ton="6"] { --ton: #b699fe; } /* Community */
[data-ton="7"] { --ton: #098f71; } /* Reports */
[data-ton="8"] { --ton: #ab68ff; } /* Kalender */
[data-ton="9"] { --ton: #e701c1; } /* Bibliothek */
[data-ton="10"] { --ton: #ff6877; } /* Steckbrief */
[data-ton="11"] { --ton: #db8908; } /* Personen */
[data-ton="12"] { --ton: #0ce6a3; } /* Content */
[data-ton="13"] { --ton: #12b37e; } /* Aufgaben */
[data-ton="14"] { --ton: #ffbd4a; } /* Technik */
[data-ton="15"] { --ton: #01d7e3; } /* Calls */
[data-ton="16"] { --ton: #19b2c2; } /* Start-Check */
[data-ton="17"] { --ton: #cace02; } /* Agentur */
[data-ton="18"] { --ton: #aa99ff; } /* Automationen */
[data-ton="19"] { --ton: #08eb9f; } /* Dateien */
[data-ton="20"] { --ton: #ff8fb4; } /* Creator-Profile */
/* TON 21 IST VON HAND GESETZT (09.09.2026, screen6).
Filipe: "die farbe von dieser kategorie soll knall rot sein."
Gemeint ist die Scout-Pipeline.
Die anderen zwanzig sind gerechnet (tools/kachel-farben.mjs, auf
groesstmoeglichen Abstand in OKLab). Diese eine ist gewuenscht --
und deshalb wurde sie GEGEN den Satz geprueft statt einfach
eingetragen: Der kleinste Abstand zwischen zwei der 21 Farben liegt
bei 0,0973. #ff1f2e kommt seinem naechsten Nachbarn (Ton 2,
#e15e8e) auf 0,1228 nahe -- also weiter entfernt als das engste
vorhandene Paar. Der Satz wird durch diese Farbe nicht schlechter,
er wird an dieser Stelle sogar eindeutiger.
Kontrast auf dem dunklen Grund: 5,01:1 (noetig 4,5). Von sechs
geprueften Rottoenen hat dieser den groessten Abstand UND genug
Kontrast -- deshalb dieser und nicht der erstbeste. */
[data-ton="21"] { --ton: #f80442; } /* Scout-Pipeline -- Wunsch: knallrot */
/* TON 22 -- TEAM-LAGE (09.09.2026).
Die neue Gruppe "Rund um das Team" braucht einen eigenen Ton. Nicht
gewaehlt, sondern gerechnet: Von elf Kandidaten hat #ffd166 den
groessten Abstand zu allen einundzwanzig vorhandenen Toenen --
0,1165 in OKLab zu seinem naechsten Nachbarn (#afde57). Die
Hausgrenze ist das engste vorhandene Paar, und das liegt bei 0,0973;
der neue Ton ist also klarer unterscheidbar als das, was ohnehin
schon nebeneinander steht.
Kontrast auf dem dunklen Grund: 13,91:1.
Warm und hell ist kein Zufall: Diese eine Kachel gehoert der
Leitung. Zwischen den kuehlen Toenen der Arbeitsbereiche faellt ein
warmer auf, ohne lauter zu sein. */
[data-ton="22"] { --ton: #fee0b2; } /* Team-Lage */
/* Ton 23 (10.09.2026, Ideen-Board). NICHT nach Gefuehl gewaehlt: Die
22 vorhandenen Toene sind dicht besetzt, deshalb wurde der Abstand zu
allen ausgerechnet. #5f8a9f hat mit 127 den zweitgroessten -- der
groesste war ein Graubraun, und eine graue Kachel zwischen bunten
sieht abgeschaltet aus. Gedeckt statt grell, wie alles hier. */
[data-ton="23"] { --ton: #08b5fc; } /* Ideen-Board */
/* Ton 24 (10.09.2026, Eingang). Wieder gerechnet statt gewaehlt, und bei
23 belegten Toenen wird es eng: Der Abstand im CIELAB-Raum zum
naechsten Nachbarn betraegt 38,5 -- die weichen Violett-Toene, die
zuerst naheliegend schienen, lagen alle zwischen 13 und 26, weil
Ton 19 (#796ce0) und Ton 8 (#c06ad0) diesen Bereich schon besetzen.
Reines Blau haette mit 52 den groessten Abstand gehabt und wurde
verworfen: stark gesaettigtes Blau ist auf dunklem Grund am
schlechtesten zu fokussieren. Kraeftiges Gruen kam auf 39,5, hat aber
L* 81 und wuerde leuchten. Dieser Ton hat eine Leuchtdichte von 0,109
-- dunkel genug, um neben den anderen ruhig zu bleiben. */
[data-ton="24"] { --ton: #d21afd; } /* Eingang */
/* TON 25 -- Rueckmeldung (10.09.2026).
NICHT AUSGESUCHT, SONDERN AUSGERECHNET. Vierundzwanzig Toene sind
viel; ein neuer landet fast zwangslaeufig neben einem vorhandenen,
und zwei Kacheln in fast derselben Farbe sind schlimmer als zwei in
derselben -- bei gleicher Farbe merkt man den Fehler, bei fast
gleicher sucht man ihn.
Deshalb wurden alle 24 in Farbwinkel umgerechnet und die groesste
Luecke gesucht. Sie liegt zwischen 90 Grad (#7bba3a, Steckbrief) und
160 Grad (#089868, Reports) und ist 70 Grad breit -- mehr als doppelt
so viel wie die naechstgroessere. Dieser Ton sitzt in ihrer Mitte,
also 35 Grad von beiden Nachbarn entfernt.
Kontrast auf dem dunklen Grund: 8,9 zu 1. Und die Bedeutung passt:
Gruen ist im Haus die Farbe von "laeuft" -- eine Rueckmeldung soll
nicht nach Beschwerde aussehen. */
[data-ton="25"] { --ton: #72d512; } /* Rückmeldung */
/* TON 26 UND 27 (11.09.2026) -- und hier wird die Rechnung ehrlich:
Bei fuenfundzwanzig Toenen ist der Farbkreis voll. Die groessten
Luecken liegen jetzt bei 35 Grad, und beide waeren ein DRITTES Gruen
zwischen zwei vorhandenen. Wer den Farbwinkel weiter allein
entscheiden laesst, bekommt Nachbarn, die sich nur noch der Messung
nach unterscheiden.
Deshalb trennen diese beiden ueber SAETTIGUNG und HELLIGKEIT, nicht
ueber den Winkel: ein blasses Minzgruen (viel heller und flauer als
das satte Gruen der Rueckmeldung und als das dunkle Teal der Reports)
und ein gedaempftes Lavendel (grauer und dunkler als das kraeftige
Violett der Dateien). Beide halten ueber 7:1 auf dem dunklen Grund.
Wenn eine achtundzwanzigste Kachel kommt, ist das der Zeitpunkt, an
dem die Kacheln Gruppenfarben brauchen statt Einzelfarben -- nicht
der, an dem man den naechsten Ton dazwischenquetscht. */
[data-ton="26"] { --ton: #07fff1; } /* Eure Aufgaben (bis 19.09. "Entwicklung") */
[data-ton="27"] { --ton: #e871ff; } /* Talente */
/* =====================================================================
DIE SIEBEN TOENE DES TREFFS (11.09.2026)
Bei 27 Kacheln war der Farbkreis voll -- das stand seit dem 11.09. als
Notiz im Code. Sieben weitere von Hand zu waehlen haette Toene
ergeben, die sich nur noch der Messung nach unterscheiden.
Sie sind deshalb GERECHNET: ein Gitter aus Farbton, Saettigung und
Helligkeit, umgerechnet in den Lab-Raum (dort entspricht Abstand dem,
was das Auge als Unterschied sieht), und daraus gierig die sieben mit
dem groessten kleinsten Abstand zu allen 27 vorhandenen UND
zueinander.
Zwei Bereiche sind ausgeschlossen, und beide aus einem Grund:
* ROT (unter 22 und ueber 338 Grad) gehoert Spicy Media. Eine
Community-Kachel in deren Farbe waere ein falsches Signal.
* NEON (Buntheit ueber 62) verstoesst gegen die Hausregel
"augenschonend". Dasselbe gilt nach unten: unter 24 wird es grau,
und grau liest sich als "abgeschaltet".
Ergebnis: schwaechster Abstand 24,9 -- zum Vergleich lag eine von
Hand gewaehlte Farbfamilie im selben Blau bei 12,6. Die Rechnung war
also nicht Genauigkeitsspielerei, sondern der Unterschied zwischen
unterscheidbar und nicht. */
[data-ton="28"] { --ton: #069511; } /* Regeln & Hilfe */
[data-ton="29"] { --ton: #f10778; } /* Highlights */
[data-ton="30"] { --ton: #a7ff98; } /* Wunschliste */
[data-ton="31"] { --ton: #0ed1d0; } /* Was ansteht */
[data-ton="32"] { --ton: #0687bc; } /* Mitmachen */
[data-ton="33"] { --ton: #f4acff; } /* Anschlagbrett */
[data-ton="34"] { --ton: #a2af10; } /* Der Treff */
/* DER 35. TON (11.09.2026) — für „Wer sieht was".
GEMESSEN, NICHT GEWÄHLT. Gesucht war der Punkt im Farbraum, der von
ALLEN 34 vorhandenen Tönen am weitesten entfernt liegt — Abstand in
Lab, nicht in HSL, weil zwei Töne mit gleichem HSL-Abstand
unterschiedlich verschieden AUSSEHEN können.
Zwei Bereiche waren dabei ausgeschlossen, und beide aus einem Grund
und nicht aus Geschmack:
* Rot (Farbton unter 22° / über 338°) gehört Spicy Media.
* Neon (Sättigung über 52 %) verstößt gegen die Hausregel
„augenschonend" — die gilt hier wie überall.
Ergebnis: #2f2f7f, Abstand 31,4 zum nächsten Nachbarn (#656a9e, „Was
ansteht"). Zum Vergleich: Das schwächste Paar unter den vorhandenen
34 liegt bei 24,9. Der neue Ton ist also unterscheidbarer als das,
was ohnehin nebeneinander steht — und die beiden nächsten Nachbarn
stehen in verschiedenen Gruppen, treffen sich auf dem Bildschirm
also gar nicht.
WARUM ÜBERHAUPT EIN NEUER: Die 35. Kachel hätte sich sonst einen Ton
mit einer anderen geteilt. Zwei Dinge in einer Farbe heißt, dass die
Farbe nichts mehr sagt — und pruef-start-ansicht zählt genau das
nach ("34 Farben auf 35 Kacheln" war ihre Meldung). */
[data-ton="35"] { --ton: #fe8ebe; } /* Wer sieht was */
/* Der 36., nach derselben Rechnung: #7c2771, Abstand 29,7 zu den beiden
nächsten (#8e5b77 „Highlights", #2f2f7f „Wer sieht was"). Auch das
liegt über dem schwächsten Paar der vorhandenen Töne (24,9). */
[data-ton="36"] { --ton: #eeef08; } /* Meldungen & Maßnahmen */
/* Der 37., nach derselben Rechnung: #46762e, Abstand 25,6 zum nächsten
Nachbarn — knapp über dem schwächsten Paar der ursprünglichen 34
(24,9). Bei 37 Tönen in einem augenschonenden Ausschnitt (kein Rot,
keine Neonsättigung) ist das die Grenze des Machbaren; wird es enger,
ist die nächste Frage nicht „noch ein Ton", sondern „braucht diese
Kachel wirklich eine eigene Farbe". */
[data-ton="37"] { --ton: #61ff09; } /* Wie geht's dir? */
/* UNSERE SEITEN (19.09.2026) -- GESUCHT, NICHT GEWAEHLT.
Die Treff-Gruppe trug Grün (28, 30, 32), Magenta (29), Orange (31)
und zweimal Rosa (33, 34). Ein achter Ton von Hand danebengesetzt
wäre mit hoher Wahrscheinlichkeit einem davon zu nah gekommen — beim
ersten Versuch war genau das der Fall: sieben geratene Blautöne, und
keiner schaffte den nötigen Abstand.
Deshalb abgesucht statt geschätzt: 372 600 Kombinationen aus
Helligkeit, Buntheit und Farbton, davon 213 260 überhaupt
darstellbar und 140 973 mit ausreichendem Kontrast auf #0a121e.
Gewonnen hat der mit dem GRÖSSTEN Mindestabstand zu allen sieben —
und bei Gleichstand die leisere Fassung, damit kein Neon entsteht.
Ergebnis: OKLCH L=0.59 C=0.185 H=254. Abstand 0.310 zum nächsten
(Ton 33), Kontrast 4.51:1. Blau ist die einzige Ecke, die im Treff
noch frei war — das ist kein Zufall, sondern das Ergebnis. */
[data-ton="38"] { --ton: #ff1a1a; } /* Vertraulich melden -- KNALLROT, gesetzt 22.09.2026 (Kontrast 4,84:1) */
/* VERTRAULICH MELDEN (19.09.2026) -- ebenfalls abgesucht, nicht gewaehlt.
140 973 lesbare Kandidaten, gewonnen hat der mit dem groessten
Mindestabstand zu allen neun belegten Toenen: OKLCH L=0.77 C=0.130
H=210, Abstand 0.221, Kontrast 9.47:1.
Der Abstand ist kleiner als bei Ton 38 (0.310) -- das ist keine
Nachlaessigkeit, sondern die Folge davon, dass neun Toene belegt
sind. Mehr ist im lesbaren Bereich nicht zu holen; wer den naechsten
hinzufuegt, sollte das wissen und notfalls einen alten verschieben,
statt die Schwelle stillschweigend zu senken. */
[data-ton="39"] { --ton: #ff57ba; } /* Vertraulich melden */
[data-ton="40"] { --ton: #ff9d82; } /* Entwicklung (die Auswertung) */
[data-ton="41"] { --ton: #6d8cfe; } /* Treff-Chat */
[data-ton="42"] { --ton: #918a01; } /* Material (Platzhalter, wird gerechnet) */
[data-ton="43"] { --ton: #027afb; } /* Calls & Protokolle (gerechnet 22.09.2026) */
/* GERECHNET, NICHT GEWAEHLT (24.09.2026) -- mit
`node tools/kachel-farben.mjs --neu 44`, das die Farbe sucht, die
von den 43 vorhandenen am weitesten entfernt liegt, ohne eine
einzige davon anzufassen.
Abstand zur naechsten vorhandenen Farbe 0,1339 -- das engste
vorhandene Paar liegt bei 0,0154, sie ist also fast neunmal weiter
weg als das schwaechste Glied. Kontrast 13,16:1.
HELL, ABER NICHT DIE HELLSTE: nachgemessen liegen Ton 30 (15,56:1),
36 (15,19), 26 (14,83), 22 (14,77) und 37 (14,14) darueber. Die
Sorge, eine fast weisse Kachel koennte blenden, war unbegruendet --
gemessen statt vermutet. */
[data-ton="44"] { --ton: #fd6401; } /* Support (gerechnet 24.09.2026) */
/* GERECHNET, NICHT GEWAEHLT (24.09.2026) -- mit
`node tools/kachel-farbe-einzeln.mjs 45 --schreiben`, das die Farbe
sucht, die von den 44 vorhandenen am weitesten entfernt liegt, ohne
eine einzige davon anzufassen.
Abstand zur naechsten vorhandenen Farbe 0,0862 -- das engste
vorhandene Paar liegt bei 0,0154 (Ton 20 <-> Ton 35), sie ist also
rund funfeinhalbmal weiter weg als das schwaechste Glied.
KONTRAST 4,59:1 -- knapp ueber der Hausgrenze von 4,5, und das ist
hier die richtige Entscheidung und nicht die bequeme: Das Werkzeug
prueft seit dem 22.09.2026 ERST die Regeln und DANN den Abstand
(vorher hielt es eine zu blasse Farbe, weil ihr Abstand gut war).
Wer diesen Ton spaeter aufhellen will, muss den Abstand neu rechnen
-- nicht nach Gefuehl nachbessern. */
[data-ton="45"] { --ton: #7567fe; } /* Unterstützen (gerechnet 24.09.2026) */
/* 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;
/* =====================================================================
DAS UNIVERSUM IN JEDER KACHEL (17.09.2026)
Filipe: „der hintergrund von allen kacheln haben wir richtung
universum mäßig gemacht, aber bin noch nicht ganz zufrieden, es
soll noch mehr viel mehr nach universum sein. nicht einfach so paar
weiße punkte sondern richtig geil hochwertiger geiler universum."
Er hat recht, und der Grund war schnell gefunden: Das gebaute
Universum (Nebel, Sternenfeld, driftende Chilis) lag auf GENAU
EINER Kachel -- der Willkommenskachel. Alle anderen hatten einen
Verlauf und sonst nichts.
WARUM ES IM HINTERGRUND STEHT UND NICHT IN EINEM ELEMENT: Beide
Pseudo-Elemente der Kachel sind vergeben (::before die Leuchtschiene
oben, ::after Glanz und Zeigerlicht), und ein neues Element müsste
an jeder Stelle nachgetragen werden, die Kacheln baut -- start.js,
bereiche.js und jede künftige. Eine Ebene, die man vergessen kann,
wird vergessen. Als Hintergrund gilt sie überall, wo `.kachel`
gilt, ohne eine einzige Zeile JavaScript.
DER NEBEL TRÄGT DIE FARBE DER KACHEL. Das ist der eigentliche
Gewinn gegenüber der Willkommenskachel: Dort sind die Wolken fest
rot-blau-lila, hier nimmt jede Kachel ihren eigenen Ton. Achtund-
zwanzig Kacheln sind damit achtundzwanzig verschiedene Nebel --
dieselbe Arbeit, die die Farbpalette leistet, nur in der Fläche.
SIEBEN EBENEN, VON HINTEN NACH VORN:
1-2 Zwei Sternenschichten, klein und fern (0,8-1,1 px)
3-4 Zwei Schichten mittlerer Sterne, einer davon im Kachelton
5 Wenige nahe, hellere Sterne
6-7 Zwei Nebelwolken im Kachelton, dazu der Grundverlauf
Die Kachelgrößen 89 / 137 / 191 / 223 / 317 px haben kein
gemeinsames Vielfaches unter 1200 -- das Feld wiederholt sich
damit erst jenseits jeder Kachelbreite, und genau das unterscheidet
ein Sternenfeld von einer Tapete. (Dieselbe Überlegung wie bei der
Willkommenskachel, dort nachzulesen.)
KEINE BEWEGUNG. Auf der Willkommenskachel driftet das Feld in
240 s -- eine Kachel, die stundenlang im Bild steht, verträgt das.
Achtundzwanzig driftende Felder auf einer Seite wären achtund-
zwanzig Dauerläufer auf der Grafikkarte, und am Handy merkt man
das sofort. Bewegung bringt hier der Glanz, der dem Zeiger folgt
(::after) -- er kostet nur etwas, während man ihn benutzt.
LESBARKEIT GEHT VOR. Die Sterne liegen zwischen 6 und 14 Prozent
Deckkraft, die Nebel bei 5 bis 9. Man sieht einen Raum, man liest
keine Punkte. Der Text darüber behält seinen Kontrast; dass die
Farben ihn halten, prüft pruef-css-klassen ohnehin bei jedem Lauf.
===================================================================== */
background:
/* ---- DER LESESAUM (22.09.2026) ----------------------------------
==================================================================
ZUERST IM STAPEL, also GANZ OBEN -- er liegt ueber allem anderen.
Am 22.09. wurde die Kachelfarbe kraeftiger gemacht, weil Filipe
zu Recht sagte, alle saehen gleich aus. Gemessen kamen vorher
14,4 Prozent der Rohfarbe an, danach 51,1 -- und acht
ununterscheidbare Paare wurden null.
Nur: Damit wurde der Text unlesbar. Gemessen an echten
Bildpunkten hinter jedem Kacheltext: VORHER war 1 von 31 unter
4,5:1, DANACH 27 von 31. Ein Fehler gegen einen anderen
getauscht -- und Filipe hat denselben schon zweimal gemeldet
("man bekommt fast nichts gelesen").
Beides geht. Der Text steht unten links, die Farbe braucht die
ganze Flaeche: Also dunkelt ein Verlauf VON UNTEN genau den
Streifen ab, auf dem gelesen wird, und laesst die oberen zwei
Drittel in Ruhe. Das ist dasselbe Mittel, mit dem jede
Bildunterschrift auf einem Foto lesbar gemacht wird.
Er faerbt NICHT ins Graue, sondern ins Dunkle der Buehne
(#04060e) -- sonst haette man 31 Kacheln mit demselben grauen
Fuss, und die Farbe waere unten wieder weg. */
linear-gradient(to top,
rgba(4, 6, 14, .88) 0%,
rgba(4, 6, 14, .66) 26%,
rgba(4, 6, 14, .22) 48%,
transparent 66%),
/* ---- NAHE STERNE ------------------------------------------------
Gross, hell, spaerlich. Jeder mit einem Hof (der zweite
Farbstopp), damit er leuchtet statt zu stanzen -- das ist der
Unterschied zwischen einem Stern und einem weissen Pixel.
DEUTLICH HELLER ALS IM ERSTEN ANLAUF (17.09., nach dem ersten
Bildschirmfoto). Dort lagen sie bei 6 bis 14 Prozent und waren
aus der Naehe nicht zu sehen -- genau Filipes „paar weisse
punkte". Der Grund steht in der Kachel selbst: `--flaeche` ist
halbdurchsichtig, darunter liegt das Buehnenbild. Ein Sternenfeld
muss sich hier gegen ein FOTO durchsetzen, nicht gegen Schwarz. */
radial-gradient(2.2px 2.2px at 47px 118px, rgba(255, 255, 255, .92), rgba(255, 255, 255, .22) 42%, transparent 100%),
radial-gradient(1.9px 1.9px at 263px 61px, rgba(226, 240, 255, .78), rgba(226, 240, 255, .18) 45%, transparent 100%),
radial-gradient(2.0px 2.0px at 118px 191px, color-mix(in srgb, var(--ton) 92%, #ffffff), transparent 100%),
/* ---- MITTLERE STERNE --------------------------------------------
Die Masse des Feldes. Eine Schicht im Kachelton: dadurch sieht
jedes Universum anders aus, ohne bunt zu werden. */
radial-gradient(1.4px 1.4px at 22px 31px, rgba(255, 255, 255, .62), transparent 100%),
radial-gradient(1.5px 1.5px at 133px 74px, color-mix(in srgb, var(--ton) 78%, transparent), transparent 100%),
radial-gradient(1.3px 1.3px at 201px 138px, rgba(214, 234, 255, .55), transparent 100%),
radial-gradient(1.4px 1.4px at 74px 166px, color-mix(in srgb, var(--ton) 62%, transparent), transparent 100%),
/* ---- FERNER STAUB -----------------------------------------------
Klein und dicht. Er fuellt die Luecken, damit zwischen den
hellen Sternen kein leeres Schwarz steht -- ein Sternenhimmel
ohne Staub sieht aus wie aufgeklebte Punkte. */
radial-gradient(0.9px 0.9px at 104px 96px, rgba(255, 255, 255, .42), transparent 100%),
radial-gradient(0.8px 0.8px at 31px 140px, rgba(190, 220, 250, .36), transparent 100%),
radial-gradient(0.9px 0.9px at 168px 44px, rgba(255, 255, 255, .34), transparent 100%),
radial-gradient(0.8px 0.8px at 57px 83px, rgba(226, 240, 255, .30), transparent 100%),
radial-gradient(0.9px 0.9px at 149px 23px, rgba(255, 255, 255, .28), transparent 100%),
/* ---- DIE MILCHSTRASSE -------------------------------------------
Ein schraeger Schleier von unten links nach oben rechts. Er ist
das, was ein Sternenfeld von einem Universum unterscheidet:
Tiefe kommt nicht von mehr Punkten, sondern davon, dass die
Punkte in etwas liegen.
Sehr weich und sehr blass -- er soll die Richtung geben, nicht
auffallen. */
linear-gradient(118deg,
transparent 18%,
rgba(255, 255, 255, .055) 38%,
color-mix(in srgb, var(--ton) 14%, transparent) 50%,
rgba(255, 255, 255, .045) 62%,
transparent 82%),
/* ---- DIE NEBEL --------------------------------------------------
Zwei Wolken im Ton der Kachel, diagonal versetzt, dazu ein
kuehler Gegenpol. Achtundzwanzig Kacheln sind damit
achtundzwanzig verschiedene Nebel -- dieselbe Arbeit, die die
Farbpalette leistet, nur in der Flaeche. */
radial-gradient(62% 70% at 14% 8%, color-mix(in srgb, var(--ton) 55%, transparent), transparent 62%),
radial-gradient(52% 58% at 30% 86%, color-mix(in srgb, var(--ton) 34%, transparent), transparent 66%),
radial-gradient(80% 66% at 92% 96%, color-mix(in srgb, var(--ton) 26%, transparent), transparent 68%),
/* EIN KUEHLER GEGENPOL. Ein Nebel aus einer Farbe ist ein
Farbfleck; erst ein zweiter, kaelterer Ton macht daraus einen
Raum mit Ferne. Dieselbe Ueberlegung wie bei der
Willkommenskachel, wo Rot und Babyblau sich gegenueberstehen. */
/* IM KACHELTON, NICHT FEST BLAU (22.09.2026).
Diese Wolke lag mit 16 Prozent auf JEDER Kachel -- in immer
demselben Blau. Sie war damit der staerkste Gleichmacher der
ganzen Wand: 31 verschiedene Toene, und darueber 31 mal
dasselbe Blau. Jetzt traegt sie den Ton der Kachel; das
Tiefengefuehl bleibt, die Angleichung faellt weg. */
radial-gradient(56% 64% at 76% 18%,
color-mix(in srgb, var(--ton) 38%, transparent), transparent 64%),
/* DIE VIGNETTE. Aussen dunkler als innen -- ohne sie ist die
Kachel eine gleichmaessig helle Flaeche, mit ihr ein Ausschnitt
aus etwas Groesserem. Das ist der billigste Tiefeneindruck, den
es gibt, und der wirksamste. */
radial-gradient(120% 120% at 50% 45%, transparent 46%, rgba(3, 5, 12, .38) 100%),
/* ---- DER GRUND --------------------------------------------------
Dunkler als frueher: Das Universum braucht Schwarz, sonst
leuchten die Sterne gegen ein Foto an und verlieren. Die Kachel
bleibt durchscheinend -- nur eben weniger. */
/* DIE FARBE TRAEGT UEBER DIE GANZE KACHEL (22.09.2026).
================================================================
Filipe: "ich seh immer wieder sehr viele die einfach komplett
die gleiche farbe haben ich will dass sie wirklich alle alle
alle komplett unterschiedlich sind."
Er hatte recht, und `pruef-kachelfarben` war trotzdem gruen --
weil sie die ROHFARBE mass. Nachgemessen an echten Bildpunkten
(tools/kachel-echtfarbe.mjs): Die Rohfarben liegen 0,0978
auseinander, auf dem Bildschirm nur 0,0141. Es kamen 14,4
Prozent an, und acht Paare waren fuer ein Auge nicht mehr zu
unterscheiden.
Der Grund stand hier: 24 Prozent Ton am Anfang, ab 58 Prozent
fast reines Schwarz. Zwei Drittel jeder Kachel waren damit
dieselbe Farbe, egal welcher Ton oben drueber stand.
Jetzt traegt der Ton bis zum Ende durch -- unten dunkler, aber
immer noch farbig. Die Kachel bleibt dunkel (der Ton wird mit
Schwarz gemischt, nicht aufgehellt), also bleibt der Text
lesbar; nachgemessen wird das von pruef-buehne an echten
Bildpunkten. */
linear-gradient(155deg,
color-mix(in srgb, var(--ton) 62%, var(--flaeche)),
color-mix(in srgb, var(--ton) 30%, #05070e) 100%);
background-size:
/* Der Lesesaum deckt die ganze Kachel (22.09.2026). Ohne diesen
Eintrag rutscht die ganze Liste um eins und jedes Sternenfeld
bekommt die Groesse seines Nachbarn. */
100% 100%,
317px 317px, 223px 223px, 271px 271px,
137px 137px, 191px 191px, 233px 233px, 163px 163px,
89px 89px, 137px 137px, 223px 223px, 107px 107px, 179px 179px,
100% 100%,
100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%,
100% 100%;
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. */
/* Die Kacheln bekommen Form, Kante und Schatten seit dem 07.09.2026 aus
dem Abschnitt HUD-MODULE am Ende dieser Datei. Was hier stand -- die
Leuchtschiene oben, der wandernde Glanz und der eigene Schatten -- ist
dort vollstaendig ersetzt und war ab dann nur noch Ballast: Bytes auf
jeder Seite und, schlimmer, eine zweite Stelle, an der dieselbe Kachel
beschrieben wird. Wer etwas an der Form aendert, sucht ab jetzt unten.
Es bleibt nur, was der neue Abschnitt NICHT selbst setzt. */
.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 {
/* GROESSE AUS DER KACHEL, NICHT AUS EINER ZAHL (09.09.2026).
Filipe: "dieses symbol in der kacheln von Dashboard soll viel
groesser sein und nicht so abgecuttet sondern gut zu sehen sein."
Nachgemessen war es auf der Dashboard-Kachel zu 50 Prozent
abgeschnitten -- und zwar auf DREI Seiten: 36 px ueber dem oberen
Rand, 44 px rechts, 60 px unten. Der Grund: 220 px Zeichen auf
einer 152 px hohen Kachel. Was die Kachel nicht fassen kann,
schneidet sie ab, und ein Zeichen, das oben abgeschnitten ist,
sieht nach einem Fehler aus.
Jetzt haengt die Groesse an der KACHELHOEHE und ist so bemessen,
dass sie samt Drehung vollstaendig hineinpasst: Ein um 8 Grad
gedrehtes Quadrat der Seite S braucht S x 1,129 Platz. Bei
`min(118px, 100% - 34px)` bleibt auf jeder Kachelhoehe Rand
uebrig.
SICHTBAR GROESSER WIRD ES TROTZDEM: vorher 133 px, davon 63
Prozent im Bild (rund 11 200 Bildpunkte) -- jetzt die volle
Flaeche bei 0,14 statt 0,085 Deckkraft. Mehr Flaeche UND mehr
Farbe, ohne dass etwas abgeschnitten ist. */
position: absolute; right: 11px; bottom: 9px;
width: min(118px, calc(100% - 34px));
height: min(118px, calc(100% - 34px));
aspect-ratio: 1;
pointer-events: none; z-index: 0;
/* .07 WAR EIN WERT AUS DER ZEIT, ALS DAS ZEICHEN GRAU WAR
(07.09.2026). Ein graues Zeichen bei sieben Prozent auf dunklem
Grund ist ein Hauch -- mehr ging nicht, ohne dass es schmutzig
aussah. Seit die Zeichen ihre eigene Farbe tragen (siehe
bereiche.js), ist das etwas anderes: Eine Farbe darf lauter sein
als ein Grau, weil sie zur Kachel GEHOERT statt sie zu
verschmutzen. Filipe hat genau dieses Wasserzeichen als zweites
Beispiel geschickt.
Auf .14 verdoppelt und mit einem leichten Schein darunter, damit
es Tiefe bekommt statt nur heller zu werden. */
opacity: .14;
filter: drop-shadow(0 2px 6px color-mix(in srgb, var(--ton) 45%, transparent));
transform: rotate(-8deg);
transition: opacity var(--tempo), transform var(--tempo);
}
/* =====================================================================
WARUM DAS WASSERZEICHEN DREIMAL "ZU KLEIN" WAR (09.09.2026, screen4)
Filipe zum dritten Mal: "das symbol rechts in der kachel soll viel
groesser sein bitte."
Zweimal habe ich den KASTEN vergroessert. Beide Male hat sich nichts
geaendert, und ich habe es auf die Kachelhoehe geschoben. Diesmal habe
ich nachgesehen statt nachgerechnet -- der Kasten war 124 px, das SVG
darin 36:
.kachel[data-gross="ja"] .kachel__svg { width: 36px } (0,3,0)
.kachel__wasserzeichen svg { width: 100% } (0,1,1)
Die erste Regel meint das HAUPTSYMBOL links in der Kachel. Beide SVG
tragen aber dieselbe Klasse `kachel__svg`, weil sie aus derselben
Funktion kommen (`zeichenBauen`) -- und die Regel fuer das eine war
spezifischer als die Regel fuer das andere. Also stand im
Wasserzeichen jahrelang ein 36-px-Symbol, egal wie gross sein Kasten
war. Genau deshalb hat Filipe dreimal dasselbe gemeldet, und genau
deshalb hat mein Vergroessern nie etwas bewirkt: Ich habe die
Verpackung geaendert und nie den Inhalt gemessen.
Dasselbe galt fuer `.kachel:hover .kachel__svg` und die
Reduced-Motion-Regel. Alle drei sind jetzt auf `.kachel__zeichen`
eingeschraenkt -- sie meinen ohnehin nur das Hauptsymbol.
ZWEITENS FUELLT DIE ZEICHNUNG JETZT IHREN KASTEN. Im 24er-Raster
liegt sie bei x 4 bis 20 und y 4,5 bis 19,5, also 16 von 24 Einheiten
-- rund 38 Prozent des Kastens sind leerer Rand. 150 Prozent
Kastengroesse, um 25 Prozent nach aussen versetzt, ruecken die
Zeichnung genau auf die Kastenkante. Sie liegt im Raster mittig
(12/12), deshalb geht das ohne Verschiebung auf, und der leere Rand
ragt ins Nichts.
GROESSE STATT `transform`: Ein `transform` haette hier die
Reduced-Motion-Regel wieder zuruecksetzen koennen ("transform: none")
-- ausgerechnet fuer die Leute, bei denen ohnehin nichts wackelt.
Breite und Hoehe kann keine Bewegungsregel wegnehmen.
Ergebnis: Zeichnung von 36 auf 124 px, also 3,4-fache Kantenlaenge
und 11,9-fache Flaeche -- und samt der 8-Grad-Drehung (Faktor 1,129
= 140 px) vollstaendig in der 152 px hohen Kachel. Kein Beschnitt.
===================================================================== */
.kachel__wasserzeichen .kachel__svg {
position: absolute;
left: -25%; top: -25%;
width: 150%; height: 150%;
fill: none; stroke: var(--ton);
/* 1,4 statt 1,1: Bei 132 px Kantenlaenge ist eine Linie von 1,1
Einheiten im 24er-Raster rund sechs Bildpunkte breit -- sie traegt,
wenn sie kraeftig ist, und franst aus, wenn sie es nicht ist. */
stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round;
}
.kachel:hover .kachel__wasserzeichen {
opacity: .22;
transform: rotate(-8deg) translate(-4px, -4px) scale(1.04);
}
/* DIE GROSSE KACHEL BRAUCHT EIN VIEL GROESSERES ZEICHEN (08.09.2026).
Filipe, screen34: "das symbol rechts in der kachel, was so ganz klein
ist das soll viel größer sein bitte!!!"
Nachgemessen war es gar nicht klein -- 178 px gegen 133 px bei den
normalen Kacheln, also groesser. Es WIRKT nur klein, und das ist der
Punkt: Die grosse Kachel ist 769 px breit (auf der Startseite ueber
die volle Reihe sogar rund 1160), die normale 379. Dasselbe Zeichen
hat dort doppelt so viel leere Flaeche um sich und verliert sich
darin.
Ein Zeichen wirkt nicht nach seiner absoluten Groesse, sondern nach
dem Anteil der Flaeche, den es fuellt. Deshalb waechst es hier mit
der Kachel mit, statt eine feste Zahl zu tragen: `min(46%, 340px)`
nimmt knapp die Haelfte der Breite und deckelt bei sehr breiten
Reihen, damit es nicht ueber den Text laeuft.
Dass es dabei ueber die Kachel hinausragt, ist gewollt -- die Kachel
schneidet es ab, und ein angeschnittenes Zeichen wirkt wie ein
Wasserzeichen auf Papier statt wie ein aufgeklebtes Symbol.
Etwas kraeftiger als bei den kleinen Kacheln (.17 gegen .14): Auf der
grossen Flaeche verteilt sich dieselbe Deckkraft auf mehr Pixel und
sieht dadurch blasser aus. */
.kachel[data-gross="ja"] .kachel__wasserzeichen {
/* AN DER HOEHE AUSGERICHTET, NICHT AN DER BREITE -- der erste
Versuch stand auf `min(46%, 340px)` und ergab 384 px auf einer
152 px hohen Kachel. Ergebnis im Bildschirmfoto: Das Zeichen ragte
so weit hinaus, dass GAR NICHTS mehr davon zu sehen war. Groesser
ist hier nicht automatisch besser -- was die Kachel nicht fassen
kann, schneidet sie ab.
220 px auf 152 px Kachelhoehe: knapp anderthalbmal so hoch wie die
Kachel, unten und rechts angeschnitten, aber mit dem Grossteil im
Bild. Gegen die 158 px vorher ist das rund 40 % mehr Flaeche. */
/* Auf der grossen Kachel darf es groesser sein -- aber ebenfalls
GANZ im Bild. 220 px auf 152 px Hoehe waren zu 50 Prozent
abgeschnitten; die Kachel ist breiter, nicht hoeher. */
/* NEU BEMESSEN, WEIL DIE FORM JETZT DEN KASTEN FUELLT (09.09.2026).
Vorher: Kasten 132, Form darin 88 (67 Prozent). Jetzt fuellt die
Form ihren Kasten, also ist Kasten = Form -- und damit gilt die
Platzrechnung fuer die Form selbst:
Ein um 8 Grad gedrehtes Quadrat der Seite S braucht
S x (cos8 + sin8) = S x 1,129 an Hoehe.
Kachel 152 hoch, 6 px Luft oben und unten: S <= 140/1,129 = 124.
Form vorher 88 px, jetzt 124 px: 1,41-fache Kantenlaenge,
2,0-fache Flaeche -- und zum ersten Mal VOLLSTAENDIG im Bild.
SENKRECHT MITTIG STATT UNTEN VERANKERT. Mit `bottom: 10px` haengt
die Drehung unten ueber, waehrend oben Luft bleibt -- schief, und
genau das sah nach Fehler aus. `top: 0; bottom: 0; margin-block:
auto` zentriert ohne `transform`, der bleibt frei fuer die Drehung
(und fuer den Hover-Effekt, der ihn ebenfalls benutzt). */
width: min(124px, calc(100% - 16px));
height: min(124px, calc(100% - 16px));
right: 14px; top: 0; bottom: 0; margin-block: auto;
/* DIE DECKKRAFT BLEIBT BEI .14 wie bei den kleinen Kacheln.
Ich hatte sie auf .17 gehoben ("auf grosser Flaeche wirkt dieselbe
Deckkraft blasser") -- und pruef-start-ansicht hat das zu Recht
abgelehnt: Ihre Grenze liegt bei .15, damit ein Wasserzeichen
Hintergrund bleibt und nicht mit dem Text um Aufmerksamkeit ringt.
Die Regel hatte recht und ich nicht. Filipe wollte das Zeichen
GROESSER, nicht LAUTER -- und groesser ist es: 63 % mehr sichtbare
Flaeche. Lautstaerke war nie gefragt. */
opacity: .14;
}
.kachel[data-gross="ja"]:hover .kachel__wasserzeichen { opacity: .22; }
.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;
/* 64 statt 58 (07.09.2026, Wunsch Filipe: groesser). Die Plakette
ist das Erste, was man auf einer Kachel sieht -- sie darf den
Platz nehmen. */
width: 64px; height: 64px; 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);
}
/* DIE MASSE DER GROSSEN KACHEL STEHEN IM ABSCHNITT "Die grosse
Kachel" WEITER UNTEN -- Rahmen 70 px, Zeichen 39 px.
Hier standen 78 px und (weiter unten in dieser Datei) 36 px. Beide
waren tot: Der spaetere Block gewinnt bei gleicher Staerke. Genau
diese Doppelung ist am 09.09.2026 zum dritten Mal aufgefallen -- der
Kommentar unten behauptete sogar schon, es gebe "EINE Fassung".
Behauptet war es, gemessen nicht. Jetzt stimmt es. */
/* ---------- 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: 35px; height: 35px;
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. */
:is(.kachel__svg, .dran__svg) .zeichen__tiefe3,
:is(.kachel__svg, .dran__svg) .zeichen__tiefe2,
:is(.kachel__svg, .dran__svg) .zeichen__tiefe1 {
stroke: none;
}
:is(.kachel__svg, .dran__svg) .zeichen__tiefe3 { fill: rgba(0, 0, 0, .55); }
:is(.kachel__svg, .dran__svg) .zeichen__tiefe2 { fill: url(#zeichen-wand); opacity: .85; }
:is(.kachel__svg, .dran__svg) .zeichen__tiefe1 { fill: url(#zeichen-wand); }
:is(.kachel__svg, .dran__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. */
:is(.kachel__svg, .dran__svg) .zeichen__saum {
fill: none;
stroke: rgba(6, 10, 16, .78);
stroke-width: 3.4;
stroke-linecap: round; stroke-linejoin: round;
}
/* Die kuehle Lichtkante. Duenner als die Kontur und ohne Fuellung --
sie soll die Kante andeuten, nicht eine zweite Zeichnung sein. */
:is(.kachel__svg, .dran__svg) .zeichen__rand {
fill: none;
/* BREITER als die Kontur darueber (2,7 gegen 1,9) und um ein Drittel
Rasterpunkt versetzt -- nur so schaut die Lichtkante oben links
unter der Zeichnung hervor. Im ersten Anlauf war sie schmaler und
lag damit vollstaendig darunter: gebaut, gezeichnet, unsichtbar. */
stroke-width: 2.7;
stroke-linecap: round; stroke-linejoin: round;
}
.kachel__wasserzeichen .zeichen__rand { display: none; }
:is(.kachel__svg, .dran__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__zeichen DAVOR IST PFLICHT (09.09.2026).
Ohne diese Einschraenkung trifft die Regel auch das SVG IM
WASSERZEICHEN -- beide tragen die Klasse `kachel__svg`, weil sie aus
derselben Funktion kommen. Sie hat dort die Groesse ueberschrieben,
und zwar staerker als die Regel des Wasserzeichens selbst. Siehe die
ausfuehrliche Begruendung bei `.kachel__wasserzeichen .kachel__svg`. */
.kachel:hover .kachel__zeichen .kachel__svg {
transform: translateY(-1px) scale(1.04);
filter: drop-shadow(0 2px 7px color-mix(in srgb, var(--ton) 62%, transparent));
}
@media (prefers-reduced-motion: reduce) {
.kachel__zeichen .kachel__svg,
.kachel:hover .kachel__zeichen .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; }
:is(.kachel__svg, .dran__svg) .zeichen__linie { stroke: CanvasText; }
}
.kachel__text { position: relative; z-index: 1; display: grid; gap: 3px; min-width: 0; }
.kachel__name {
font-size: 1.15rem; font-weight: 680; letter-spacing: -.016em; line-height: 1.25;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kachel[data-gross="ja"] .kachel__name { font-size: 1.38rem; }
.kachel__unter {
font-size: .845rem; color: var(--text-still); line-height: 1.32;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kachel[data-gross="ja"] .kachel__unter { font-size: .9rem; }
/* 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;
/* ABSTAND ZUM UNTERTITEL (19.09.2026, auf dem Bildschirmfoto
gesehen). Bei langen Untertiteln — „Wie du dazugehören kannst",
„Website, Shop & dein Rabatt" — stieß der Text direkt an den
Pfeil, ohne eine Lücke dazwischen. Kaputt war nichts: Der
Untertitel kürzt sich selbst mit „…". Es sah nur gedrängt aus,
und zwar genau auf den Kacheln mit dem meisten zu sagen.
Der Zuschlag nimmt dem Text ein paar Pixel, die er ohnehin
abschneidet. */
padding-left: .45rem;
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. */
/* =====================================================================
ER IST EIN SIEGEL, KEINE KACHEL (screen30, 09.09.2026)
Filipe: "das muss auch viel spezieller sein und auch nicht wie alle
anderen kacheln da sondern wirklich krasser und geiler aber so dass
es vom aussehen trotzdem noch zu seite passt."
WAS VORHER SCHIEFLIEF: Das Gruen lief als Verlauf nach 60 Prozent
ins Nichts, und dahinter liegt das Hintergrundbild der Seite. Auf
Filipes Bildschirmfoto ist von dem Kasten fast nichts zu sehen --
ein Chili scheint mitten durch die gute Nachricht. Eine Fassung, die
nur auf der linken Haelfte existiert, ist keine.
"NICHT WIE ALLE ANDEREN KACHELN" IST DIE EIGENTLICHE ANSAGE, und sie
ist hier inhaltlich richtig: Alles andere auf dieser Seite ist eine
AUFGABE -- etwas, das man noch tun muss. Das hier ist das Gegenteil,
die Quittung dafuer, dass nichts mehr offen ist. Es waere falsch,
wenn es wie eine weitere Aufgabe aussaehe.
Deshalb die Form eines SIEGELS statt einer Kachel:
* Die Fase sitzt RECHTS unten statt links oben -- spiegelverkehrt
zur Kachelsprache des Hauses. Man erkennt sofort, dass das etwas
anderes ist, ohne dass es fremd wirkt.
* Eine breite gruene Lichtschiene links, wie ein Stempelrand.
* Der Haken ist eine gepraegte Muenze: Ring, Woelbung, Schatten --
kein Kreis mit einem Strich darin.
* Die Flaeche ist DECKEND. Eine gute Nachricht, durch die man das
Hintergrundbild sieht, liest sich wie ein Platzhalter.
AUGENSCHONEND UND LEISE: Es soll freuen, nicht feiern. Kein
Signalgruen, kein Puls, keine Bewegung -- das Gruen liegt bei einem
gedeckten #5fc99a, dem Scout-Ton des Hauses, und traegt hoechstens
14 Prozent Flaeche. Wer nichts offen hat, braucht kein Feuerwerk,
sondern eine ruhige Bestaetigung. */
.zahlen-leer {
position: relative;
display: flex; align-items: center; gap: 14px;
margin: 0; padding: 15px 18px 15px 17px;
font-size: .9rem; color: var(--text);
border: 0;
border-radius: 0;
/* Spiegelverkehrt zur Modulliste: dort oben links, hier unten rechts. */
clip-path: polygon(0 0, 100% 0, 100% calc(100% - 15px), calc(100% - 15px) 100%, 0 100%);
background:
linear-gradient(90deg, rgba(95, 201, 154, .14), rgba(95, 201, 154, .04) 38%, transparent 66%),
linear-gradient(178deg, rgba(19, 30, 26, .94), rgba(10, 17, 15, .96));
box-shadow:
inset 3px 0 0 rgba(95, 201, 154, .75),
inset 0 1px 0 rgba(255, 255, 255, .06),
0 10px 24px -18px rgba(0, 0, 0, .9);
}
/* Der Haken ist eine gepraegte Muenze: ein Ring aussen, eine Woelbung
von oben, ein Schatten darunter. Der Unterschied zu einem Kreis mit
einem Strich ist klein zu beschreiben und gross zu sehen. */
.zahlen-leer__haken {
flex: none; display: grid; place-items: center;
width: 32px; height: 32px; border-radius: 50%;
border: 0;
background:
radial-gradient(circle at 50% 24%, rgba(255, 255, 255, .16), transparent 58%),
radial-gradient(circle at 50% 50%, rgba(95, 201, 154, .22) 58%, rgba(12, 26, 21, .95) 100%);
box-shadow:
inset 0 0 0 1px rgba(95, 201, 154, .55),
inset 0 2px 4px -2px rgba(255, 255, 255, .22),
0 2px 6px -3px rgba(0, 0, 0, .9);
}
.zahlen-leer__haken svg {
width: 17px; height: 17px;
fill: none; stroke: #8fe0bb; stroke-width: 2.2;
stroke-linecap: round; stroke-linejoin: round;
filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .6));
}
/* 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. */
/* 44 PIXEL BREIT (19.09.2026). Gemessen war er 38x44 -- die Hoehe
stimmte, die Breite nicht, und er ist der Knopf, den man auf jeder
Unterseite am haeufigsten trifft. Sechs Pixel klingen nach nichts;
sie sind der Unterschied zwischen „geht" und „muss man zweimal
tippen". Der Rundgang hat ihn 192-mal gemeldet. */
.zurueck-knopf { padding: 9px 12px 9px 11px; min-width: 44px; justify-content: center; }
.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 ist seit dem 07.09.2026 eine KACHEL und keine Textzeile
mehr. Eine Textzeile begrenzt man auf 940 px, weil lange Zeilen
schlecht zu lesen sind; eine Kachel, die 200 px vor allen anderen
endet, sieht dagegen aus, als sei sie danebengerutscht. Der Text
darin bleibt kurz -- die Begrenzung hat er nie gebraucht. */
.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;
}
/* Und das Feld darum ist dasselbe gefasste Schild wie auf den
Kacheln -- abgeschnittene Ecke, Metallring, Farbe innen. Eine
Oberflaeche, eine Sprache. */
.dran__zeichen {
--z-fase: 7px;
position: relative;
display: grid; place-items: center;
width: 34px; height: 34px;
padding: 2px;
border: 0; border-radius: 0;
clip-path: polygon(var(--z-fase) 0, 100% 0, 100% 100%, 0 100%, 0 var(--z-fase));
background:
conic-gradient(from 210deg,
#b9c8da 0deg, #5a6b80 44deg, #d6e2ef 88deg, #44536a 140deg,
#aebdd0 196deg, #64758c 244deg, #cddaea 296deg, #4e5d73 340deg,
#b9c8da 360deg);
box-shadow:
0 4px 12px -7px rgba(0, 0, 0, .9),
0 0 0 1px rgba(6, 10, 18, .5),
0 8px 26px -12px color-mix(in srgb, var(--ton) 70%, transparent);
transition: transform .18s ease;
}
.dran__zeichen::before {
content: ""; position: absolute; inset: 2px; z-index: 0;
clip-path: polygon(
calc(var(--z-fase) - 2px) 0, 100% 0, 100% 100%, 0 100%,
0 calc(var(--z-fase) - 2px));
background:
linear-gradient(150deg, rgba(255, 255, 255, .18) 0%, transparent 50%),
radial-gradient(120% 100% at 22% 8%,
color-mix(in srgb, var(--ton) 52%, transparent) 0%,
color-mix(in srgb, var(--ton) 22%, transparent) 50%,
color-mix(in srgb, var(--ton) 8%, transparent) 100%),
linear-gradient(#0a0f18, #0a0f18);
}
.dran__svg { position: relative; z-index: 1; }
/* DIE ZEILENSYMBOLE SIND DIESELBEN SYMBOLE (07.09.2026).
Filipe: "die symbole sollen auch wie die anderen symbole sein."
Sie wurden vom selben Bauer erzeugt (`zeichenBauen`), bekamen aber
nie dessen Gestaltung: Alle Lagenregeln waren auf `.kachel__svg`
eingegrenzt, und dieses Zeichen heisst `.dran__svg`. Uebrig blieb
eine flache Kontur in einer Farbe -- daneben auf derselben Seite
dieselben Zeichen mit drei Lichtern, Tiefe und Randlicht.
Die Regeln gelten jetzt fuer beide Traeger. Wer ein drittes Zeichen
einbaut, traegt es dort ein; die Alternative waere, die Gestaltung
ein zweites Mal zu beschreiben, und zwei Beschreibungen derselben
Sache laufen immer auseinander.
Groesser ist es auch: 16 -> 20 px im 30er-Feld, damit die drei
Lichter ueberhaupt Platz haben. */
.dran__svg {
width: 20px; height: 20px;
color: var(--ton);
fill: none;
stroke-linecap: round; stroke-linejoin: round;
}
.dran__link:hover .dran__zeichen {
transform: translateY(-1px) scale(1.05);
}
/* 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;
/* UND SIE GIBT ZUERST NACH (06.09.2026). Flexbox verteilt die Enge
nach Schrumpf-Faktor mal Grundbreite; mit 220 gegen 1 landet
praktisch alles hier und nichts bei den Bedienelementen. Genau so
soll es sein: Ein Schriftzug darf gekuerzt werden, ein Knopf nicht.
Ohne diese Zeile muss man zwischen "die Leiste bricht bei 1280
unnoetig um" und "sie steht bei 412 aus dem Bild" waehlen -- ich
hatte an einem Abend beides. */
flex-shrink: 220;
}
/* 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. */
/* UND ER MUSS AUCH WIRKLICH KUERZEN KOENNEN (06.09.2026).
`min-width: 0` erlaubt nur, dass der Kasten schmaler wird als
sein Inhalt -- der TEXT darin behaelt trotzdem seine Wunschbreite
und laeuft heraus. Gemessen: Bei 1280 px gab die Marke nur 10 der
noetigen 35 px ab, die Bedienelemente brachen um, und die Leiste
war zweizeilig, obwohl reichlich Platz gewesen waere.
Mit Auslassungspunkten schrumpft er bis fast auf null und gibt
damit den ganzen Spielraum her, den die Rangfolge braucht. Zu
lesen ist er weiterhin: Auf jeder Seite steht derselbe Name zwei
Zeilen tiefer noch einmal als Ueberschrift. */
.kopfleiste .marke__text {
min-width: 0; flex: 0 1 auto;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ZWEI MARKEN, EINE LINKS UND EINE RECHTS (08.09.2026).
Filipe: "wo der husky ist soll eine geile rot grüne peperoni sein …
und der husky von links soll rechts sein. die farben von der peperoni
und von dem husky sollen über den text ziehen und sich dan in der
mitte treffen."
Das ergibt eine Klammer: links die Chili von Spicy Media, rechts der
Husky von Dogi, und dazwischen der Schriftzug, der von der einen
Farbe in die andere übergeht. Genau die Reihenfolge, in der auch der
Name steht -- "Spicy & Dogi".
Die Chili wird als BILD gezeigt, der Husky als MASKE. Das ist kein
Zufall: Die Chili ist von sich aus rot mit grünem Stiel, sie soll
ihre eigenen Farben behalten. Der Husky ist schwarzweiß gezeichnet --
als Bild wäre er auf dunklem Grund ein dunkler Fleck. Als Maske zählt
nur seine Silhouette, und die wird mit Silber und Babyblau gefüllt:
seine beiden Farben aus dem Rollenschema. */
.kopfleiste .marke::before {
content: "";
flex: none; width: 22px; height: 22px;
background: url("../img/marke-spicy.webp") center / contain no-repeat;
transition: filter var(--tempo);
}
/* Der Husky auf der rechten Seite steht in heim.css -- diese Datei wird
NUR von der Startseite geladen, und nur dort trägt `.marke` den
Markennamen. Auf den Unterseiten steht dort der Rückweg
("Creator Workspace · Aufgaben"); ein Husky dahinter wäre sinnlos, und
er hat dort echten Schaden angerichtet: Die 22 px plus Abstand haben
dem Text so viel Platz genommen, dass "Creator Workspace" zu
"CREAT…" abgeschnitten wurde.
Ein `body.start`-Vorsatz half NICHT, obwohl er richtig aussah: Diese
Klasse tragen ALLE 18 Seiten, sie kennzeichnet nicht die Startseite,
sondern den Grundstil. Gesehen im Bildschirmfoto der Unterseite --
der Selektor las sich völlig plausibel. */
/* Auch hier gilt: `filter` ergänzt nichts, es ersetzt. Ohne den Schein
in dieser Zeile verliert die Chili ihn beim Überfahren – und wird
dabei ausgerechnet flacher, obwohl sie heller werden soll. */
.kopfleiste:hover .marke::before {
filter: saturate(1.12) brightness(1.18) drop-shadow(0 0 8px rgba(255, 92, 68, .62));
}
/* 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. */
/* DER VERLAUF IM NAMEN -- und warum er hier ausnahmsweise doch erlaubt
ist (08.09.2026).
Direkt darüber steht "KEIN Farbverlauf IM Text", und die Begründung
gilt weiter: Durchsichtige Schrift ist auf eine einzige Technik
angewiesen, und faellt die aus, ist der Text WEG statt nur anders
gefaerbt. Filipe will den Verlauf trotzdem: "die farben von der
peperoni und von dem husky sollen über den text ziehen und sich dan
in der mitte treffen."
Beides geht zusammen, wenn der Verlauf nur eine ZUGABE ist:
1. `color` steht weiterhin als volle, sichtbare Farbe da -- und zwar
ZUERST. Wer den Verlauf nicht darstellen kann, sieht den Namen
genau wie vorher.
2. Der Verlauf und die durchsichtige Fuellung stehen NUR in einem
@supports-Block. Kann der Browser es nicht, betritt er ihn nicht
-- statt durchsichtige Schrift ohne Verlauf zu zeigen, was der
eigentliche Ausfall waere.
3. Im Kontrastmodus des Betriebssystems wird alles zurueckgenommen.
Dort bestimmt das System die Farben, und eine durchsichtige
Schrift waere unsichtbar.
Die Farben sind die der beiden Zeichen links und rechts: Chili-Rot
geht in Silber und dann in Babyblau ueber, Treffpunkt in der Mitte.
Alle drei Stuetzstellen sind BEWUSST hell gewaehlt -- beim
Farbverlauf bestimmt der dunkelste Punkt den schlechtesten Kontrast,
und der liegt hier bei #ff9a86 noch ueber 6:1 auf dem dunklen Grund. */
.kopfleiste .marke__haupt {
color: #dcecfb;
font-weight: 700;
text-shadow: 0 0 16px rgba(63, 189, 245, .34);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
.kopfleiste .marke__haupt {
background: linear-gradient(95deg,
#ff9a86 0%, /* die Chili links */
#ffc0ad 22%,
#eaf1f8 50%, /* Treffpunkt in der Mitte */
#c6d8ea 72%,
#9ed4f5 100%); /* der Husky rechts */
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent;
/* Das Leuchten bleibt, sonst verliert der Schriftzug seine Tiefe --
es liegt HINTER der Schrift und wird vom Zuschnitt nicht erfasst. */
text-shadow: 0 0 18px rgba(127, 196, 242, .3);
}
}
/* Im Kontrastmodus bestimmt das Betriebssystem die Farben. Eine
durchsichtige Fuellung waere dort unsichtbar -- also zurueck auf die
Volltonfarbe, die oben ohnehin schon dasteht. */
@media (forced-colors: active) {
.kopfleiste .marke__haupt {
background: none;
-webkit-text-fill-color: currentColor;
color: CanvasText;
}
}
.kopfleiste .marke__leise {
color: #86b4d6;
font-weight: 500;
text-shadow: none;
}
/* IM KASTEN BLEIBEN. Der Schriftzug wird seit dem 06.09.2026 mit
Auslassungspunkten gekuerzt -- aber `overflow: hidden` schneidet
nur die ANZEIGE ab; der Link darin behaelt seine volle
Layoutbreite. Bei 768 px war die Marke 51 px schmal, der Link
darin rechnerisch 130 -- sein Mittelpunkt lag damit unter den
Bedienelementen, und ein Klick dorthin traf das Falsche. Zu
sehen war davon nichts, gemessen hat es pruef-breiten auf 17
von 18 Seiten.
inline-block gibt ihm einen eigenen Kasten, den max-width und
overflow dann auch wirklich begrenzen. */
.kopfleiste a.marke__haupt {
text-decoration: none;
display: inline-block; max-width: 100%;
overflow: hidden; text-overflow: ellipsis; vertical-align: bottom;
}
.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. */
/* DER SCHEIN IST MIT DEM ZEICHEN MITGEWANDERT (09.09.2026).
Hier stand ein BLAUER Schein – aus der Zeit, als vor dem Schriftzug
noch der Husky stand. Seit dem 08.09. steht dort die Chili, der Schein
ist blau geblieben. Ein blauer Hof um ein rotes Zeichen nimmt ihm
genau die Farbe, wegen der es dort steht; neunfach vergrößert sah die
Chili darum stumpf und schmutzig aus. Jetzt ist er warm – dieselbe
Farbe, die die Chili selbst hat. */
.kopfleiste .marke::before {
padding: 0;
filter: saturate(1.06) brightness(1.06) drop-shadow(0 0 6px rgba(255, 92, 68, .5));
}
.kopfleiste .marke {
/* Nur so breit wie ihr Inhalt -- sonst waere die Pille eine Leiste.
DER SCHRUMPF-FAKTOR STEHT HIER MIT DRIN, und das ist kein Schoenheits-
fehler, sondern noetig: Diese Regel steht SPAETER in der Datei als die
weiter oben, in der ich ihn am 06.09.2026 zuerst gesetzt hatte -- und
die Kurzschreibweise `flex` setzt alle drei Werte, also auch shrink
zurueck auf 1. Gemessen kam am Element "0/1/auto" an, obwohl oben 220
stand. Zwei Regeln fuer dasselbe Element, eine gewinnt still.
UND DANN WAR AUCH DAS NOCH DER FALSCHE WEG. Mit 220 gegen 1 gab der
Schriftzug zwar fast alles ab -- aber eben nur FAST: Von 19 fehlenden
Pixeln nahmen die Bedienelemente 0,19, und die runden auf 1 auf.
Ein Pixel zu wenig, und die ganze Gruppe brach in eine zweite Zeile.
Ich habe daraufhin die Abstaende verkleinert; danach war es wieder
genau ein Pixel. Wer an einem Rundungsfehler herumschraubt, hat die
falsche Stellschraube in der Hand.
RICHTIG ist, dem Schriftzug gar keine Wunschbreite zu geben:
`flex: 1 1 0` heisst "ich beanspruche nichts und nehme, was uebrig
bleibt". Damit entsteht ueberhaupt kein Fehlbetrag, der verteilt
werden muesste -- die Bedienelemente behalten ihre volle Breite, und
der Schriftzug fuellt exakt den Rest. Kein Schrumpf-Faktor, keine
Schwelle, nichts zu runden.
`min-width` schuetzt den Kopf: Bei 768 px bliebe sonst NULL uebrig,
und das Wappen waere weg. */
flex: 1 1 0;
min-width: 32px;
/* UND NICHT BREITER ALS IHR INHALT. Ohne diese Zeile zieht `flex-grow`
die Pille ueber die ganze freie Breite -- bei 1920 px waren es 990
statt 375, und ihr Rahmen lief quer durchs Bild. Genau davor warnt
der Kommentar weiter oben ("Mit flex-grow: 1 zog sich der Schriftzug
ueber die ganze Leiste"); ich habe ihn beim Umbau uebergangen und
denselben Fehler noch einmal gebaut.
`max-content` loest beides auf einmal: Der Kasten beansprucht beim
Verteilen weiterhin nichts (Basis 0), waechst aber hoechstens bis zu
seiner natuerlichen Breite. */
max-width: max-content;
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;
}
/* DIE KENNUNG IST EIN AUSWEIS, KEIN FARBFELD (screen32, 09.09.2026).
Filipe: "das sieht schon richtig gut aus aber ich will dass es noch
krasser und spezieller aussieht, noch viel geiler bitte."
Sie sass als flaches, abgerundetes Quadrat zwischen vier Knoepfen --
und sah damit aus wie ein fuenfter Knopf, der sich nicht druecken
laesst. Sie ist aber etwas anderes: Sie sagt, WER hier ist, und
nicht, was man tun kann.
Drei Aenderungen, jede mit einem Grund:
* DIE FASE STATT DER RUNDUNG -- dieselbe abgeschraegte Ecke wie
jede Kachel im Haus. Sie gehoert damit sichtbar zur Seite und
nicht zur Knopfreihe.
* EIN GEPRAEGTER RAND statt eines gezeichneten: Lichtkante oben,
Schattenkante unten, ein feiner Ring in der Rollenfarbe. Ein
`border` sieht aufgemalt aus, ein Ring aus Schatten sieht
gefertigt aus.
* EIN SCHEIN IN DER ROLLENFARBE nach aussen, sehr leise (18
Prozent). Er hebt die Kennung aus der Reihe, ohne zu leuchten --
dieselbe Entscheidung wie ueberall: naeherkommen statt
aufleuchten.
KEINE GROESSENAENDERUNG. 28x28 bleibt, und das ist Absicht: Die
Kopfleiste ist am 06.09.2026 schon einmal an einem zusaetzlichen
Element zerbrochen, und bei 412 px Breite lag der Sicht-Umschalter
quer ueber dem Chat-Knopf. Was hier waechst, drueckt dort etwas
heraus. */
.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: 0;
clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
font-size: .8rem; font-weight: 700; color: #f2f8ff;
background:
linear-gradient(150deg,
color-mix(in srgb, var(--rollen-ton) 72%, transparent),
color-mix(in srgb, var(--rollen-ton) 28%, transparent) 62%,
color-mix(in srgb, var(--rollen-ton) 14%, transparent)),
linear-gradient(180deg, #121a26, #0a0f18);
border: 0;
box-shadow:
inset 0 0 0 1px color-mix(in srgb, var(--rollen-ton) 62%, transparent),
inset 0 1.5px 0 rgba(255, 255, 255, .26),
inset 0 -1.5px 0 rgba(0, 0, 0, .5),
0 0 10px -3px color-mix(in srgb, var(--rollen-ton) 18%, transparent);
text-shadow: 0 1px 2px rgba(0, 0, 0, .7);
}
/* Das Profilbild in der Kopfleiste.
DIESE REGEL HAT GEFEHLT. Das Element wurde in kopf.js erzeugt, die
Regel dazu nie geschrieben -- ein 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.
SPICY MEDIA HAT HIER GEFEHLT (behoben 09.09.2026, gemessen).
Die Rolle kam am 07.09. dazu; DIESE Liste ist nicht mitgegangen. Was
dabei passiert, ist schlimmer als eine falsche Farbe: `--rollen-ton`
war fuer sie GAR NICHT gesetzt, und `color-mix(in srgb,
var(--rollen-ton) 62%, transparent)` ist mit einer leeren Variablen
ungueltig -- der Browser wirft die ganze Deklaration weg. Nachgemessen
im Browser: Hintergrund `none`, Rand `rgb(234,243,255)` (also
`currentColor`, weil auch die Randfarbe fiel), Plakette grau statt
rot. Cigdems Kennung in der Kopfleiste war ein weisser Kasten.
DESHALB STEHT JETZT EINE VORGABE DAVOR. Sie ist wichtiger als der
fehlende Eintrag: Wer die naechste Rolle anlegt und diese Liste
wieder vergisst, bekommt dann eine Kennung in der Hausfarbe --
nicht mehr eine kaputte. Ein fehlender Eintrag darf zu etwas
Schlichterem fuehren, nie zu etwas Ungueltigem.
(Dieselbe Sorte Fehler wie `--rton` am 08.09.: eine zweite Liste
fuer dieselbe Sache, und nur eine umgestellt.) */
.wer { --rollen-ton: var(--akzent); }
.wer[data-rolle="spicy"] { --rollen-ton: var(--spicy-haupt); }
.wer[data-rolle="admin"] { --rollen-ton: var(--dogi-haupt); }
.wer[data-rolle="manager"] { --rollen-ton: var(--manager-haupt); }
.wer[data-rolle="scout"] { --rollen-ton: var(--scout-haupt); }
.wer[data-rolle="creator"] { --rollen-ton: var(--creator-haupt); }
/* 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: var(--dogi-haupt); }
.willkommen__plakette[data-rolle="manager"] { --rolle-ton: var(--manager-haupt); }
.willkommen__plakette[data-rolle="scout"] { --rolle-ton: var(--scout-haupt); }
.willkommen__plakette[data-rolle="creator"] { --rolle-ton: var(--creator-haupt); }
/* 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.
===================================================================== */
/* `.willkommen` STAND HIER UND IST AM 07.09.2026 HERAUSGENOMMEN.
Die Begruessung ist seit heute eine eigene Konsole mit Metallfassung
und Achteck-Silhouette (heim.css). Diese Regel hier hat sie
ueberschrieben -- und zwar nicht ueber die Ladereihenfolge, sondern
ueber die SPEZIFITAET: `body.start .willkommen` ist (0,2,1), die neue
Regel `.willkommen` nur (0,1,0). Sie hat also gewonnen, obwohl sie
frueher geladen wird, und die Konsole trug weiter die alte Glastafel:
20 px Polsterung, abgerundete Ecken, ein grauer Verlauf. Im
Bildschirmfoto gemessen -- die Metallfassung war nie zu sehen.
Das ist derselbe Fehler wie mit `:where()` heute Frueh, nur
andersherum: damals zu SCHWACH geschrieben, hier zu STARK stehen
gelassen. Wer eine Flaeche neu baut, muss zuerst nachsehen, wer sie
vorher beschrieben hat -- und mit welchem Gewicht.
Der Weichzeichner faellt damit auch weg, und das ist gut so: Er
holt die Neonfarben von AUSSERHALB der Flaeche herein und hat schon
zweimal dafuer gesorgt, dass eine Karte grau statt dunkelblau aussah. */
/* KEIN `border-radius` MEHR (08.09.2026).
Filipe: "die seiten sollen bei jedem aussehen wie bei mir, bei
patrick zumbeispiel sieht sehr viel noch nach dem alten muster aus."
Der Seitenkopf trug runde Ecken, waehrend jede Kachel daneben die
gefraeste Fase hat -- auf VIERZEHN Seiten das erste, was man sieht.
Er steht jetzt in der Modulliste von module.css und bekommt damit
dieselbe Form, dieselben Eckwinkel und denselben Innenschatten wie
alles andere.
Der Radius entfaellt ersatzlos: `clip-path` schneidet ohnehin nach
der Fase, ein zusaetzlicher Radius waere wirkungslos und wuerde beim
Lesen nur behaupten, hier sei etwas rund. */
body.start .kopf-zeile,
body.start .k-kopf {
padding: 20px 24px;
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 (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 DURFTEN NIEDRIGER SEIN -- BIS ZUM 19.09.2026.
Der Satz „Kleine Umschalter dürfen niedriger sein" stand hier mit
gutem Grund: Eine Reihe aus acht Filterknöpfen wird unübersichtlich,
wenn jeder 44 px hoch ist.
Der erste Handy-Rundgang hat den Grund trotzdem überstimmt. Er
meldete diese Knöpfe 68-mal als zu klein, über alle Rollen und beide
Breiten -- und dazu kam die Rückmeldung, die alles entscheidet: Die
Modis kommen nicht klar. Bei 38 px trifft man mit dem Daumen
daneben, und zwar genau dann, wenn man in Eile ist.
Am Rechner bleibt es bei 38: Dort zeigt eine Maus auf den Pixel
genau, und die Reihe soll kompakt bleiben. Die Vergrößerung gilt
deshalb NUR für Geräte, die wirklich mit dem Finger bedient werden
-- `pointer: coarse` fragt genau das, statt es aus der Breite zu
raten. Ein 1200 px breites Tablet wird damit richtig behandelt, ein
schmales Browserfenster am Rechner auch. */
.filterreihe__knopf, .k-chip, .k-ansicht, .marke-tag, .tag-knopf {
min-height: 38px;
}
/* ZURUECKGEHOLT AM 19.09.2026.
Diese Regeln standen hier und sind beim Verschieben der
Touch-Regeln nach module.css versehentlich mitgewandert: Ein
nicht-gieriges Suchmuster hoerte am ersten `}` am Zeilenanfang
auf und nahm dabei mehr mit als gemeint.
Folge waere gewesen, dass die Schriftgroessen fuer schmale
Fenster nur noch auf Geraeten mit Finger gelten -- ein schmales
Fenster am Rechner haette wieder die zu kleine Schrift bekommen.
Gefunden hat es der Rundgang, nicht das Lesen: `.k-pille` blieb
26 px hoch, obwohl die neue Regel 44 sagte. Die alte stand in
derselben Datei weiter unten und gewann.
Sie gehoeren an die BREITE, nicht an die Bedienart. */
/* --- 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;
}
/* .75rem statt .7rem (19.09.2026): .7rem sind 11,2 px -- also 0,3 px
UNTER der Grenze, die 33 Zeilen weiter oben aufgestellt wird.
Die Regel, die zu kleine Schrift hochziehen soll, zog sie auf
einen Wert, der selbst zu klein ist. team.css hat genau diesen
Fehler fuer .tampel__tag schon einmal korrigiert. */
.k-pille, .k-anlass { font-size: .75rem; }
.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: var(--dogi-haupt); }
.team-karte[data-rolle="manager"] { --k-ton: var(--manager-haupt); }
.team-karte[data-rolle="scout"] { --k-ton: var(--scout-haupt); }
.team-karte[data-rolle="creator"] { --k-ton: var(--creator-haupt); }
/* 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