Files
dogfather-universe/workspace/assets/css/start.css
T
DogFatherGitandClaude Opus 5 d7bb0f7e60 45 Kachelfarben: acht Paare waren dieselbe Farbe -- und die Pruefung
konnte es nicht sagen

Filipe am 17.09.: „ich will das jede kachel eine andere farbe hat, es
soll keine die gleiche farben haben bitte und auch keine die sich
irgendwie aehnlich sind ... die farben sollen auch richtig geil und
speziell sein."

Gemessen am 25.09.: #ff8fb4 gegen #fe8ebe, Abstand 0,0154 in OKLab.
Das ist mit blossem Auge DIESELBE Farbe. Acht solche Paare gab es.

=== WARUM ES NIEMAND GEMERKT HAT ===

pruef-kachel-universum hat es gesagt. Jede Nacht. Die Zeile stand da:
„kleinster Abstand 0,0154". Gelesen hat sie niemand -- weil direkt
daneben eine zweite Zeile stand, die NIEMALS gruen werden konnte:
„kein Paar unter 0,10".

Nachgerechnet (tools/_toene-packen.mjs, eine echte Kugelpackung ueber
alle sRGB-Farben, die 4,8:1 gegen den Grund halten, nicht blenden und
bunt genug sind):

  30 Farben  ->  0,115        48 Farben  ->  0,0925
  40 Farben  ->  0,103        52 Farben  ->  0,0840
  45 Farben  ->  0,0974       60 Farben  ->  0,0805

Die Forderung war fuer 21 Farben geschrieben. Bei den heutigen 45
liegt die DECKE bei 0,0974 -- „kein Paar unter 0,10" konnte niemand
erfuellen, mit keiner Palette der Welt.

DAS IST DER EIGENTLICHE BEFUND. Eine Bedingung, die niemand erfuellen
kann, macht nicht nur sich selbst wertlos. Sie faerbt die ganze Datei
rot, und ab da liest man die Zeile darueber nicht mehr. Der echte
Mangel lag acht Tage offen da, versteckt hinter einem Fehlalarm.

=== DIE NEUE PALETTE WURDE GERECHNET, NICHT NACHGEBESSERT ===

Von Hand nachbessern hat sie erst dahin gebracht: Am 08.09. waren es
21 Farben, danach kamen sechzehn dazu, jede einzeln gewaehlt, keine
gegen die anderen geprueft. In drei Schritten:

  1. Aus allen erlaubten sRGB-Farben 45 so waehlen, dass der kleinste
     Abstand so gross wie moeglich wird.
  2. Sie den 45 Kachelnummern so zuordnen, dass jede moeglichst nah an
     ihrer bisherigen Farbe bleibt -- eine Kachel soll wiedererkennbar
     sein, sie rueckt, sie wechselt nicht.
  3. Nachziehen: Jeder Ton darf zurueck in Richtung seiner alten Farbe
     wandern, solange der Mindestabstand haelt.

Ergebnis: kleinster Abstand 0,0154 -> 0,0931, kein Paar mehr unter
0,09. Dreissig der 45 Kacheln haben sich um weniger als 0,02 bewegt --
das sieht man nicht. Nur sieben sind sichtbar gewandert, und alle
sieben lagen in dem Gedraenge aus neun fast gleichen Rot- und
Rosatoenen, das den Ausschlag gegeben hat.

„Richtig geil und speziell" bleibt messbar erhalten: Die Buntheit hat
eine Untergrenze von 0,10 in der Rechnung, damit keine Farbe ins Graue
rutscht. Gemessen kostet das nichts -- mit dieser Grenze ist die Decke
sogar minimal hoeher als ohne (0,0974 gegen 0,0973).

=== UND DIE PRUEFUNG SAGT JETZT ETWAS ERFUELLBARES ===

  kleinster Abstand >= 0,09          (Decke fuer 45 Farben: 0,097)
  hoechstens 48 Farben               (darueber ist 0,09 nicht mehr
                                      erreichbar -- gemessen, nicht
                                      gesetzt)
  Gegenprobe: #ff8fb4 gegen #fe8ebe  muss durchfallen

Die zweite Zeile ist die wichtige: Sie bewacht den GRUND. Wer die
46., 47., 48. Kachel anlegt, kommt noch durch; wer die 52. anlegt,
bekommt gesagt, dass jetzt ueber die Palette geredet werden muss,
statt still wieder in zwei gleiche Farben zu rutschen. Genau das ist
zwischen dem 08.09. und dem 17.09. passiert.

GEMESSEN: pruef-kachel-universum 13 Pruefungen, 0 Fehler (vorher 12
mit 2 Fehlern). Schlechtester Textkontrast auf der fertigen Kachel
7,02:1, am Bildschirmfoto gemessen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-25 23:19:29 +02:00

9081 lines
420 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ===================================================================
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: #7b7ec3; } /* Dashboard */
[data-ton="2"] { --ton: #ff6078; } /* Zahlen */
[data-ton="3"] { --ton: #0fba0c; } /* LIVE */
[data-ton="4"] { --ton: #c9691e; } /* 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: #ff09d5; } /* Schutz & Regeln -- Wunsch: extrem auffällig */
[data-ton="6"] { --ton: #b49fff; } /* Community */
[data-ton="7"] { --ton: #2a9375; } /* Reports */
[data-ton="8"] { --ton: #ab69ff; } /* Kalender */
[data-ton="9"] { --ton: #d24bc3; } /* Bibliothek */
[data-ton="10"] { --ton: #ea8d7e; } /* Steckbrief */
[data-ton="11"] { --ton: #d88d18; } /* Personen */
[data-ton="12"] { --ton: #8ae4ae; } /* Content */
[data-ton="13"] { --ton: #0fb47e; } /* Aufgaben */
[data-ton="14"] { --ton: #fcbd3f; } /* Technik */
[data-ton="15"] { --ton: #00dbf9; } /* Calls */
[data-ton="16"] { --ton: #1eb1c0; } /* Start-Check */
[data-ton="17"] { --ton: #c9cf09; } /* Agentur */
[data-ton="18"] { --ton: #b77ecf; } /* Automationen */
[data-ton="19"] { --ton: #06f08a; } /* Dateien */
[data-ton="20"] { --ton: #ff90bd; } /* 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: #cc6372; } /* 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: #ffde93; } /* 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: #15b4ff; } /* 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: #d524ff; } /* 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: #0cfff0; } /* Eure Aufgaben (bis 19.09. "Entwicklung") */
[data-ton="27"] { --ton: #e469ff; } /* 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: #009918; } /* Regeln & Hilfe */
[data-ton="29"] { --ton: #f91e81; } /* Highlights */
[data-ton="30"] { --ton: #a5ff96; } /* Wunschliste */
[data-ton="31"] { --ton: #2dcfb4; } /* Was ansteht */
[data-ton="32"] { --ton: #008dc0; } /* Mitmachen */
[data-ton="33"] { --ton: #f3b7ff; } /* Anschlagbrett */
[data-ton="34"] { --ton: #a2ae0c; } /* 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: #ff8dfc; } /* 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: #edf012; } /* 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: #60ff0c; } /* 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: #ff241e; } /* 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: #ff5aba; } /* Vertraulich melden */
[data-ton="40"] { --ton: #ffb190; } /* Entwicklung (die Auswertung) */
[data-ton="41"] { --ton: #7293ff; } /* Treff-Chat */
[data-ton="42"] { --ton: #908a03; } /* Material (Platzhalter, wird gerechnet) */
[data-ton="43"] { --ton: #0081fc; } /* Calls & Protokolle (gerechnet 22.09.2026) */
/* GEWUENSCHT UND NACHGEMESSEN (25.09.2026)
Filipe zum Bildschirmfoto der Support-Seite: „ich will dass du bitte
diese kachel viel geiler viel profissioneller machst, die soll
koomplett anders aussehen und strukturiert sein ... die hauptfarbe
der kachel soll auch babyblau sein mit bissl lila."
HIER STAND #fd6401, ein Orange, das am 24.09. GERECHNET worden war
(Abstand 0,1339). Diesmal kam die Farbe aus einem Wunsch und nicht
aus einer Rechnung -- also wurde sie nachgemessen, statt sie
einfach einzutragen (`node tools/_kachel-abstand-probe.mjs #a8d8ff 44`):
Kontrast gegen den dunklen Grund 12,46:1 (Hausgrenze 4,5)
Abstand zur naechsten Farbe 0,1125 (Ton 15, #01d7e3)
Engstes Paar im Haus 0,0154 (Ton 20 <-> Ton 35)
-> 7,3-fach weiter weg als das schwaechste Glied
Der Wunsch kostet also 0,0214 Abstand gegenueber dem gerechneten
Orange und bleibt weit ueber allem, was im Haus ohnehin steht. Haette
die Messung etwas anderes gesagt, waere sie die Antwort gewesen --
die Zahl entscheidet, nicht die Reihenfolge der Argumente.
DAS LILA STEHT NICHT HIER, SONDERN IN support.css (`--s-lila`).
Ein Ton ist EINE Farbe: Er faerbt die Kachel auf der Wand, den Kopf
der Seite, das Wasserzeichen und jede Zahl darin. Das Lila ist die
zweite Stimme daneben und gilt nur auf der Support-Seite. */
[data-ton="44"] { --ton: #90c3ff; } /* Support (Wunschfarbe, nachgemessen 25.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: #fc690f; } /* Unterstützen (gerechnet 24.09.2026) */
/* WARUM ES KEINEN TON 46 GIBT (25.09.2026)
Die Tuer ins andere Haus trug bis heute Ton 40 -- dieselbe Nummer
wie „Entwicklung". Auf DogFathers Wand standen damit zwei Kacheln
in derselben Farbe, und er ist der Einzige, der beide sieht (die
Tuer gibt es nur fuer ihn). Deshalb ist es nie jemandem aufgefallen.
DER ERSTE GEDANKE WAR EINE 46. FARBE. Gerechnet kam dabei ein
Abstand von 0,0862 heraus -- UNTER der Hausgrenze von 0,09. Der
Farbraum ist bei 45 Toenen erschoepft: Mehr Farben, die gleichzeitig
4,5:1 Kontrast, Buntheit ueber 0,12 und 0,09 Abstand halten, passen
nicht hinein. Eine zweite benannte Ausnahme am selben Tag waere der
Anfang vom Ende der Regel gewesen.
RICHTIG IST DIE ANDERE ANTWORT: Die Tuer ist gar keine
Bereichskachel. Sie fuehrt aus dem Haus hinaus (`aussen: true`) und
gehoert keinem Bereich an. Sie bekommt deshalb KEINE Nummer und
faellt auf `--akzent` zurueck (die Zeile unten). Damit
unterscheidet sie sich von allen 45 Bereichskacheln -- genau
richtig, denn sie ist etwas anderes als sie.
Nebenwirkung, die gewollt ist: Sie faellt aus beiden Farbrechnungen
heraus. Das ist keine Luecke, sondern die Wahrheit -- man kann eine
Farbe, die es nicht gibt, nicht auf Abstand pruefen. */
/* 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 <img> ohne Groessenangabe nimmt
seine natuerliche Groesse an, bei einem Handyfoto also mehrere
tausend Pixel. Es lag damit ueber der ganzen Seite.
Warum es keine Pruefung gefunden hat: Sie lud ein 1x1-Pixel-PNG
hoch. Ein Bild dieser Groesse kann nichts ueberdecken. Die Pruefung
arbeitet jetzt mit einem 1200x1200-Bild -- so gross wie das, was
wirklich hochgeladen wird. */
.wer__bild {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: cover;
display: block;
border-radius: inherit;
}
.wer__name {
font-size: .88rem; font-weight: 600; color: var(--text);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
min-width: 0;
}
.wer__rolle {
flex: none;
padding: 2px 9px; border-radius: 999px;
font-size: .66rem; font-weight: 700;
letter-spacing: .08em; text-transform: uppercase;
color: color-mix(in srgb, var(--rollen-ton) 75%, #ffffff);
background: color-mix(in srgb, var(--rollen-ton) 15%, transparent);
border: 1px solid color-mix(in srgb, var(--rollen-ton) 38%, transparent);
}
/* Eine Farbe je Rolle -- dieselbe Sprache wie in der Personenliste.
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 <span class="licht"> (siehe
kopf.js, dort steht auch, warum ein eigenes Element und nicht
::before am Kasten selbst):
::before der FLECK — ein weicher Schein unter dem Zeiger
::after der RAND — eine helle Stelle, die auf der KANTE
mitwandert
Der Rand ist der Teil, der es besonders macht. Er entsteht aus einem
Farbverlauf, von dem eine Maske nur den ein Pixel breiten Saum stehen
laesst: zwei Ebenen, eine ueber die Innenflaeche, eine ueber den
ganzen Kasten, und "exclude" laesst genau die Differenz uebrig — den
Rahmen. Dadurch leuchtet wirklich die Kante an der Stelle, an der der
Zeiger ist, statt eines Rechtecks, das so tut als ob.
Die Farbe kommt aus --ton, also aus der Kachelfarbe des Bereichs.
Eine Aufgabenkarte leuchtet orange, eine Kalenderkarte tuerkis.
===================================================================== */
.licht {
position: absolute; inset: 0;
border-radius: inherit;
pointer-events: none;
z-index: 0;
opacity: 0;
transition: opacity .28s ease;
}
[data-licht="an"] > .licht { opacity: 1; }
/* Der Fleck. Bewusst gross und sehr weich — ein kleiner harter Kreis
sieht nach Taschenlampe aus, ein grosser weicher nach Beleuchtung. */
.licht::before {
content: "";
position: absolute; inset: 0;
border-radius: inherit;
background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 0%),
color-mix(in srgb, var(--ton, var(--akzent)) 20%, transparent),
transparent 68%);
}
/* Der Rand. Etwas kleiner im Radius als der Fleck, dafuer kraeftiger --
so wirkt er wie eine Reflexion auf einer Kante, nicht wie ein zweiter
Schein. */
.licht::after {
content: "";
position: absolute; inset: 0;
border-radius: inherit;
padding: 1px;
background: radial-gradient(170px circle at var(--mx, 50%) var(--my, 0%),
color-mix(in srgb, var(--ton, var(--akzent)) 85%, #ffffff 15%),
color-mix(in srgb, var(--ton, var(--akzent)) 30%, transparent) 45%,
transparent 72%);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
mask-composite: exclude;
}
/* Alles, was Licht bekommen soll, braucht einen eigenen Bezugspunkt --
sonst legt sich der Schein ueber die halbe Seite statt ueber die
Karte. Die meisten haben ihn schon; diese Zeile ist die Versicherung
fuer die uebrigen. */
.kachel, .karte, .spalte, .k-anlasskarte, .k-tag, .k-wochentag,
.dran__punkt, .zahl, .datei, .person, .eintrag, .thema,
.k-listentag, .steckbrief, .leer-hinweis, .block {
position: relative;
}
/* Inhalt ueber das Licht. Die Karten setzen ihre Kinder meist nicht
ausdruecklich; bei gleichem Stapelwert gewinnt das spaetere Element,
und .licht wird als erstes Kind eingefuegt. Fuer die Faelle, in denen
ein Kind selbst positioniert ist, hier die Zusicherung. */
.kachel__link, .kachel__text, .karte__titel, .spalte__kopf,
.k-anlasskarte__txt, .dran__link, .steckbrief__kopf { position: relative; z-index: 1; }
/* Ohne feinen Zeiger oder bei "weniger Bewegung" wird gar kein
Licht-Element eingefuegt (kopf.js). Diese Regel ist die zweite
Sicherung, falls doch eines im Dokument steht. */
@media (prefers-reduced-motion: reduce) {
.licht { display: none; }
}
@media (hover: none), (pointer: coarse) {
.licht { display: none; }
}
/* Im Kontrastmodus gibt es keine Farbverlaeufe -- ein Licht, das dort
als Flaeche erscheint, wuerde den Text verdecken. */
@media (forced-colors: active) {
.licht { display: none; }
}
/* =====================================================================
HANDY — was die Geraetepruefung gefunden hat (01.09.2026)
Geprueft wurde auf 320, 390 und 412 px, auf allen fuenfzehn Seiten.
Drei Arten von Fehlern kamen heraus, und alle drei sind am Rechner
unsichtbar:
1. Raster, die nicht schrumpfen konnten. minmax(280px, 1fr) ist ein
MINDESTmass -- passt es nicht, laeuft die Seite ueber statt
umzubrechen. Behoben an zwoelf Stellen mit min(280px, 100%).
2. Beruehrziele unter 24 px. Auswahlfelder waren 18 bis 22 px hoch;
mit dem Daumen trifft man daneben. WCAG 2.2 nennt 24x24 als
Mindestmass (Kriterium 2.5.8), und das ist knapp bemessen.
3. Schrift unter 11,5 px. Auf einem Telefon ist das keine
Beschriftung mehr, sondern ein Muster.
===================================================================== */
@media (max-width: 760px) {
/* --- Beruehrziele ---------------------------------------------------
Auswahlfelder, Eingaben und kleine Knoepfe bekommen ein Mindestmass.
44 px ist die Empfehlung von Apple und Google und deutlich ueber der
Norm -- der Daumen ist nun einmal breiter als ein Mauszeiger. */
select, input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
textarea, button, .schritt, .knopf-still, .abmelden {
min-height: 44px;
}
select, input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) {
/* 16 px verhindert nebenbei, dass iOS beim Antippen hineinzoomt --
jeder kleinere Wert loest das aus, und danach steht die Seite
schief. */
font-size: 16px;
padding: 10px 12px;
}
/* KLEINE UMSCHALTER 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; }
/* "Passt nicht" (24.09.2026, nur im Agenturhaus). Gerechnet und nicht
gegriffen: relative Helligkeit 0,317 -- genau so hell wie das Gruen
daneben (0,320) und deutlich heller als das Blaugrau von "offen"
(0,241), das den Barrierefreiheits-Lauf bereits bestanden hat. Ein
knalliges Rot waere lauter, aber nicht lesbarer; die Bedeutung
traegt ohnehin das Wort auf der Marke und die Raute daneben, nicht
der Farbton. */
.bilanz-zahl[data-stufe="passt_nicht"] { --b-ton: #d97f87; }
/* "Trifft nicht zu" soll RUHIGER wirken als "offen" und trotzdem
lesbar sein -- das ist ein Widerspruch, solange man nur abdunkelt.
Geloest ueber die Saettigung: fast neutral (0,274), aber heller als
"offen". Es faellt damit nicht auf und verschwindet nicht. */
.bilanz-zahl[data-stufe="entfaellt"] { --b-ton: #8a8f9b; }
.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; }
/* UND "Passt nicht"? Auch kein Rot -- aus demselben Grund, nur eine
Stufe deutlicher. Ein gedaempftes Rosé sagt "das gehoert geaendert",
ein Signalrot sagt "du hast versagt". Der Unterschied zwischen den
beiden Saetzen ist der ganze Grund, warum es diese Stufe gibt.
Der Farbwert ist gerechnet, siehe .bilanz-zahl weiter oben. */
.fest-punkt[data-stufe="passt_nicht"] { --p-ton: #d97f87; }
.fest-punkt[data-stufe="entfaellt"] { --p-ton: #8a8f9b; }
.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;
}
/* ---------- Die Stufenknoepfe ------------------------------------------
EINE ZEILE JE STUFE STATT DREI (24.09.2026).
Hier standen je Stufe drei ausgerechnete Farbwerte -- Rand, Schrift,
Flaeche. Bei zwei Stufen ging das; bei vier waeren es zwoelf Werte,
und beim naechsten Knopf haette jemand einen davon vergessen. Genau
diese Bauart hat in diesem Haus schon mehrfach zu einer Stelle
gefuehrt, die nicht mitgewachsen ist, ohne dass etwas auffaellt.
Jetzt nennt jede Stufe nur noch IHREN Ton; die drei Werte rechnet
der Browser daraus. Eine Stufe, die es morgen gibt und die hier
fehlt, sieht dadurch neutral aus statt kaputt -- die Rueckfallwerte
stehen im gemeinsamen Block.
AUSDRUECKLICH AUF [data-stufe] EINGEGRENZT: Dieselbe Klasse
.stufe-knopf benutzt auch die Ampel an den Eintraegen, dort aber mit
[data-wert]. Ein Regelsatz ohne diese Eingrenzung faerbte sie mit
und niemand saehe einen Zusammenhang. */
.stufe-knopf[data-stufe="gut"] { --s-ton: #4dab77; }
.stufe-knopf[data-stufe="verbessern"] { --s-ton: #e0a33c; }
.stufe-knopf[data-stufe="passt_nicht"] { --s-ton: #d97f87; }
.stufe-knopf[data-stufe="entfaellt"] { --s-ton: #8a8f9b; }
.stufe-knopf[data-stufe]:hover,
.stufe-knopf[data-stufe][data-an="ja"] {
border-color: color-mix(in srgb, var(--s-ton, var(--text-still)) 50%, transparent);
color: color-mix(in srgb, var(--s-ton, var(--text-still)) 79%, #ffffff);
background: color-mix(in srgb, var(--s-ton, var(--text-still)) 13%, transparent);
}
.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
<textarea> ohne `font: inherit` auf Schreibmaschinenschrift
zurückfällt. Neben den gestalteten Kanalfeldern darunter sah es aus
wie ein Fehler, und es war auch einer.
Deshalb steht hier eine Grundlage, die JEDES Feld im Inhalt erfasst.
Sie kann keine bestehende Seite kaputtmachen: `:where()` hat die
Stärke null, also gewinnt jede vorhandene Regel weiterhin. Sie greift
nur dort, wo sonst gar nichts stünde -- ein Netz unter dem Netz.
(Der umgekehrte Weg wäre gewesen, alle Einzelregeln zu vereinheitlichen.
Das hätte fünf Seiten auf einmal verändert, ohne dass jemand danach
gefragt hat.) */
/* OHNE `width` -- und das ist eine Lehre aus dem ersten Anlauf. Er setzte
hier `width: 100%`, und die Formularpruefung meldete sofort Felder von
28 statt 362 Pixeln: Breite ist LAYOUT und gehoert der Seite, nicht dem
Aussehen. Eine Grundlage mit der Staerke null verliert jeden
Breitenstreit, den eine Seite fuehrt -- also darf sie ihn gar nicht
erst anfangen. Hier steht nur, WIE ein Feld aussieht; WO es steht und
wie breit es ist, entscheidet weiterhin die Seite. */
:where(.inhalt) :where(input:not([type="file"]):not([type="checkbox"]):not([type="radio"]),
textarea, select) {
padding: 10px 13px;
/* font: inherit ist die eigentliche Reparatur -- ohne das schreibt
der Browser in <textarea> in Monospace und in <select> in seiner
Systemschrift. */
font: inherit;
font-size: .92rem;
line-height: 1.5;
color: var(--text);
background:
linear-gradient(180deg, rgba(255, 255, 255, .035), rgba(255, 255, 255, .012)),
rgba(0, 0, 0, .2);
border: 1px solid var(--rand);
border-radius: var(--radius-klein);
/* Die feine helle Kante oben -- derselbe Griff wie bei den Kacheln.
Sie lässt das Feld eingelassen wirken statt aufgemalt. */
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
transition: border-color var(--tempo), box-shadow var(--tempo), background var(--tempo);
}
:where(.inhalt) :where(textarea) {
resize: vertical; min-height: 52px;
}
/* DATUMS- UND ZEITFELDER MACHEN SICH GROESSER, ALS SIE DUERFEN (20.09.2026).
Gemessen auf aufgaben.html bei 390 px, alle Felder derselben Reihe:
Auswahlfeld 44, Textfeld 44, Datumsfeld 48. Dasselbe auf
kalender.html und bereich.html?b=live -- dreimal dieselbe Ursache.
44 px ist kein Zufallsmass, sondern das Beruehrziel weiter oben.
Jedes andere Feld landet von selbst darauf. Das Datumsfeld nicht:
Chromium rechnet fuer `input[type=date]` eine eigene Mindesthoehe
aus dem Innenleben (`::-webkit-datetime-edit`), und die ueberstimmt
sogar ein gesetztes `height: 44px` -- deshalb half die Regel in
aufgaben.css nicht, die genau das versucht.
Zwei Anteile, einzeln nachgemessen (jeder fuer sich bringt 48 -> 46,
erst beide zusammen 48 -> 44):
1. Der Feldkasten innen hat oben und unten je 1 px Polsterung.
2. Seine Zeilenhoehe folgt unseren 1.5 -- 24 statt der 22 px,
die in ein 44-px-Feld passen.
Vier Pixel klingen nach nichts. In einer Reihe aus fuenf Feldern
steht aber genau eines heraus: zu wenig, um es benennen zu koennen,
genug, damit die Reihe unruhig aussieht. Gefunden hat es
pruef-formulare, nicht das Auge.
KEINE ABGESCHRIEBENE ZAHL: Die Zeilenhoehe wird aus dem Beruehrziel
und der Polsterung GERECHNET. Aendert sich eines von beiden, wandert
das Datumsfeld mit, statt still wieder auszuscheren.
Andere Browser kennen `::-webkit-datetime-edit-fields-wrapper` nicht
und ueberspringen diese eine Zeile -- die Rechnung darueber gilt dort
trotzdem. */
:where(.inhalt) :where(input[type="date"], input[type="time"],
input[type="datetime-local"]) {
--feld-ziel: 44px; /* das Beruehrziel aus dem Handy-Block */
--feld-pad-y: 10px; /* dieselbe Polsterung wie bei allen Feldern */
--feld-rand: 1px;
line-height: calc(var(--feld-ziel) - 2 * var(--feld-pad-y) - 2 * var(--feld-rand));
}
:where(.inhalt) :where(input[type="date"], input[type="time"],
input[type="datetime-local"])::-webkit-datetime-edit-fields-wrapper {
padding: 0;
}
:where(.inhalt) :where(input, textarea, select):hover {
border-color: color-mix(in srgb, var(--akzent) 26%, var(--rand));
}
:where(.inhalt) :where(input, textarea, select):focus {
outline: none;
border-color: color-mix(in srgb, var(--akzent) 62%, transparent);
background:
linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .02)),
rgba(0, 0, 0, .12);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05),
0 0 0 3px color-mix(in srgb, var(--akzent) 17%, transparent);
}
/* Der Platzhalter darf NICHT wie ein ausgefülltes Feld aussehen -- sonst
hält man ihn für den eigenen Text und schreibt nichts hinein. Deutlich
leiser als der Inhalt, aber noch lesbar (nicht unter 45 % Deckung). */
.inhalt input::placeholder,
.inhalt textarea::placeholder {
color: var(--text-still);
opacity: .85;
}
/* Feldbeschriftungen -- gilt für beide Schreibweisen, die es hier
historisch gibt. Kleiner, gesperrt und leise: Die Beschriftung soll
den Blick führen, nicht mit dem Inhalt konkurrieren. */
.inhalt .feld-schild,
.inhalt .feldschild {
display: block;
font-size: .74rem; font-weight: 600;
letter-spacing: .1em; text-transform: uppercase;
color: var(--text-leise);
}
/* Der Hinweis UNTER einem Feld -- erklaert es, statt es kommentarlos
wegzunehmen.
HIERHER GEZOGEN AM 22.09.2026. Er stand doppelt: in aufgaben.css und
in leistung.css, und die beiden waren schon auseinandergelaufen (die
eine hatte `line-height`, die andere nicht). Dogi-Media war die
dritte Seite, die ihn braucht, und laedt keine der beiden -- der
Hinweis stand dort nackt und in voller Textgroesse da.
Es ist derselbe Fehler wie bei `.knopf-still`, beim Schalter und bei
der Filterleiste: ein gemeinsamer Baustein in einer Seitendatei. Er
faellt jedes Mal erst dort auf, wo die Datei nicht geladen wird.
`start.css` laedt jede Seite ausser den zwei Weiterleitungen
(index.html, crew-index.html) -- dort gibt es keine Formulare. */
.feld-hinweis {
margin: 5px 0 0;
font-size: .76rem;
line-height: 1.45;
color: var(--text-still);
}
/* AUF DEM HANDY 16 PIXEL. Das ist keine Geschmacksfrage: Safari auf dem
iPhone zoomt beim Antippen automatisch in die Seite hinein, sobald ein
Feld kleiner als 16px schreibt -- und zoomt danach NICHT von selbst
wieder heraus. Man tippt einmal in ein Feld und der Rest der Seite ist
für immer zu groß. */
@media (max-width: 760px) {
.inhalt input:not([type="file"]):not([type="checkbox"]):not([type="radio"]),
.inhalt textarea,
.inhalt select { font-size: 16px; }
}
/* ---------- Die Sicht eines anderen (nur DogFather) -----------------------
Der Umschalter steht im Seitenkopf, links neben dem eigenen Namen --
also genau dort, wo ohnehin steht, WER man gerade ist. Beides gehoert
zusammen: "ich, und wessen Arbeitsplatz ich gerade ansehe."
Solange eine fremde Sicht aktiv ist, faellt das deutlich auf. Das ist
der wichtigste Teil dieser ganzen Funktion: Der gefaehrlichste Fall
ist nicht, dass man die Sicht nicht wechseln kann, sondern dass man
vergisst, dass man sie gewechselt hat -- und am naechsten Tag drei
Aufgaben statt dreissig sieht und das fuer den Bestand haelt. */
.sicht {
--s-ton: #d8a13a; /* die Rollenfarbe von DogFather */
display: flex; align-items: center; gap: 8px;
padding: 4px 6px 4px 11px;
border: 1px solid var(--rand); border-radius: 999px;
background: rgba(0, 0, 0, .25);
/* SCHRUMPFEN MUSS ERLAUBT SEIN. In der Kopfleiste steht
`.kopfleiste__rechts > * { flex: 0 0 auto; }` -- jedes Teil dort
behaelt also seine Wunschbreite. Der Umschalter schob die Seite
dadurch um 46 px (Rechner) bis 117 px (Handy) aus dem Bild, und der
Abmelden-Knopf war nicht mehr erreichbar. Gemeldet von
pruef-workspace-seiten und pruef-handy, bevor es jemand gesehen hat.
Diese Regel steht spaeter in der Datei und gewinnt deshalb.
NACHTRAG 06.09.2026: Seit die Kopfleiste an JEDER Breite umbrechen
darf (siehe .kopfleiste__rechts oben), ist Schrumpfen der falsche
Ausweg geworden. Ein Umschalter, der auf 50 px zusammenfaellt,
schiebt seinen eigenen Knopf ueber den Nachbarn -- das ist kein
Ueberlauf weniger, sondern einer an unsichtbarer Stelle. Er
behaelt jetzt seine Breite und wandert stattdessen in die zweite
Zeile, wenn es eng wird. */
flex: 0 0 auto;
}
/* DAS WORT "SICHT" IST WEG (06.09.2026, Wunsch Filipe: "das soll viel
besser aussehen").
Es stand als Etikett vor einem Auswahlfeld -- ein Formular, das in
die Kopfleiste gerutscht war. An seiner Stelle steht jetzt ein Auge,
das dasselbe in einem Zeichen sagt und dem NAMEN den Platz laesst,
um den es geht.
Fuer Vorleseprogramme bleibt die Beschriftung erhalten; sie ist nur
nicht mehr zu sehen. Sie ersatzlos zu loeschen haette das
Auswahlfeld unbeschriftet zurueckgelassen. */
.sicht__schild {
position: absolute;
width: 1px; height: 1px; margin: -1px; padding: 0;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.sicht__schild--alt {
flex: none;
/* 0,75 rem = 12 px. Nicht kleiner: Unter 11,5 px meldet die
Geraetepruefung zu Recht "zu kleine Schrift" -- und was auf dem
Handy niemand liest, ist auf dem Rechner auch nur Zierde. */
font-size: .75rem; font-weight: 600;
letter-spacing: .1em; text-transform: uppercase;
color: var(--text-still);
}
/* Kein `width: 100%` wie bei den Feldern im Inhalt -- hier gehoert das
Feld in eine Zeile und darf nicht die halbe Kopfleiste einnehmen. */
/* NICHT das <select> selbst gestalten -- das waere hier ein Fehler mit
Ansage. wahl.js ersetzt jedes Auswahlfeld im Workspace durch ein
eigenes Bedienelement: Das echte <select> bleibt im Dokument, wird
aber auf einen Pixel geschrumpft und unsichtbar gemacht; sichtbar ist
ein Knopf darueber (.wahl2__knopf).
Der erste Anlauf gab dem <select> Breite und Polsterung. Ergebnis:
Das versteckte Feld wurde wieder 20 x 44 Pixel gross und lag als
unsichtbares Hindernis ueber dem Knopf -- die Geraetepruefung meldete
es als "Beruehrziel zu klein", und getroffen haette man damit gar
nichts. Gestaltet wird deshalb der Knopf.
Falls wahl.js einmal nicht laeuft (Skript blockiert), traegt das
nackte <select> nichts Eigenes -- es sieht dann schlicht aus, ist
aber vollstaendig bedienbar. Das ist die richtige Reihenfolge. */
.sicht .wahl2 { flex: 0 1 auto; min-width: 0; max-width: 180px; }
.sicht .wahl2__knopf {
padding: 5px 10px;
font-size: .82rem;
border-radius: 999px;
background: rgba(255, 255, 255, .04);
}
.sicht .wahl2__knopf:hover:not([disabled]) {
background: rgba(255, 255, 255, .07);
}
/* Der Name darf gekuerzt werden, statt den Knopf aufzublaehen. */
.sicht .wahl2__text {
min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* FREMDE SICHT AKTIV -- deutlich, aber nicht schreiend. */
.sicht[data-fremd="ja"] {
border-color: color-mix(in srgb, var(--s-ton) 55%, transparent);
background:
linear-gradient(rgba(216, 161, 58, .12), rgba(216, 161, 58, .12)),
rgba(0, 0, 0, .3);
}
.sicht[data-fremd="ja"] .sicht__schild { color: var(--s-ton); }
/* Das Auge. Im Normalfall still, bei fremder Sicht in der Rollenfarbe
-- es ist dann das Erste, was auffaellt. */
.sicht__auge {
flex: none;
width: 16px; height: 16px;
fill: none; stroke: var(--text-still); stroke-width: 1.6;
transition: stroke .18s ease;
}
.sicht[data-fremd="ja"] .sicht__auge { stroke: var(--s-ton); }
/* FREMDE SICHT MUSS AUFFALLEN. Der gefaehrlichste Fall dieser Funktion
ist, dass man sie vergisst -- man sieht am naechsten Tag drei
Aufgaben statt dreissig und haelt das fuer den Bestand. Deshalb
traegt der ganze Umschalter dann Farbe, nicht nur ein Zusatzknopf. */
.sicht[data-fremd="ja"] {
border-color: color-mix(in srgb, var(--s-ton) 50%, transparent);
background: color-mix(in srgb, var(--s-ton) 12%, rgba(0, 0, 0, .25));
}
.sicht__weg {
flex: none; min-height: 28px;
/* Ein Kreuz braucht keine Wortbreite mehr. */
width: 28px; padding: 0;
display: grid; place-items: center;
border: 1px solid color-mix(in srgb, var(--s-ton) 45%, transparent);
border-radius: 999px;
background: transparent; color: var(--s-ton);
font: inherit; font-size: .76rem; cursor: pointer;
transition: background var(--tempo);
}
.sicht__weg svg {
width: 14px; height: 14px;
fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}
.sicht__weg:hover { background: color-mix(in srgb, var(--s-ton) 16%, transparent); }
.sicht__weg:focus-visible { outline: 2px solid var(--s-ton); outline-offset: 2px; }
/* Ein feiner Rahmen um die ganze Seite, solange eine fremde Sicht laeuft.
Er kostet keinen Platz, laesst sich nicht wegscrollen und ist damit die
einzige Anzeige, die man wirklich nicht uebersehen kann. */
body[data-fremde-sicht="ja"]::after {
content: "";
position: fixed; inset: 0;
/* Der Ton kommt seit dem 09.09.2026 von der Person, deren Sicht
laeuft (kopf.js liest ihn aus dem fertigen Umschalter und setzt ihn
hier). Damit tragen Rahmen, Knopf und Band dieselbe Farbe, und man
sieht auf einen Blick WESSEN Sicht -- nicht nur DASS eine fremde
laeuft. Der Rueckfallwert ist das alte Gold. */
border: 2px solid color-mix(in srgb, var(--fremd-ton, #d8a13a) 40%, transparent);
pointer-events: none;
z-index: 60;
}
/* ===================================================================
DER ANFANGSBUCHSTABE IM UMSCHALTER (09.09.2026)
Nur auf dem Handy sichtbar (siehe Medienabfrage weiter unten): Am
Rechner steht der ganze Name daneben, dort waere ein Buchstabe davor
nur Wiederholung.
=================================================================== */
.sicht__kuerzel {
display: none;
flex: none;
font-size: .78rem; font-weight: 800;
line-height: 1;
letter-spacing: 0;
color: var(--s-ton);
}
/* Der Umschalter traegt in fremder Sicht die Farbe der Rolle, deren
Sicht laeuft -- die Zuordnung steht schon in gate.css
(`[data-rolle="…"] { --rolle-haupt: … }`), sie wird hier nur
ausgelesen. Keine zweite Farbliste. */
.sicht[data-fremd="ja"][data-rolle] { --s-ton: var(--rolle-haupt, #d8a13a); }
/* ===================================================================
DAS BAND UNTER DER LEISTE (09.09.2026)
Es traegt, was aus der Kopfleiste weichen musste: den vollen Namen
und den Weg zurueck. Auf dem Rechner ist es aus -- dort steht der
Name im Umschalter selbst, und zwei Anzeigen fuer dieselbe Sache
sind eine zu viel.
=================================================================== */
.fremd-band {
/* AM 11.09.2026 AUF ALLEN GERAETEN (vorher: nur Handy).
Gestern stand hier `display: none` mit der Begruendung, am Rechner
stehe der Name ja im Umschalter selbst und zwei Anzeigen fuer
dieselbe Sache seien eine zu viel.
Einen Tag spaeter hat Filipe gemeldet, DogFather sehe die Creator
nicht mehr -- und das Bildschirmfoto zeigte einen Umschalter mit
genau einem Eintrag. Nachgestellt: Er war in einer fremden Sicht,
am RECHNER, mit sichtbarem Namen im Umschalter und goldenem Rahmen
um die Seite. Beides hat nicht gereicht.
Damit ist meine Begruendung von gestern widerlegt, und zwar nicht
durch ein Argument, sondern durch den Fall selbst. Der Name im
Umschalter ist eine ANGABE; das Band ist ein SATZ, der sagt, was
gerade gilt und wie man es beendet. Das ist nicht dieselbe Sache
zweimal, sondern zwei verschiedene Dinge -- und der teurere Fehler
ist der, bei dem jemand die halbe Mannschaft fuer verschwunden
haelt. */
display: flex;
align-items: center; gap: 9px;
padding: 8px clamp(14px, 4vw, 20px);
border-bottom: 1px solid color-mix(in srgb, var(--fremd-ton, #d8a13a) 34%, transparent);
background: color-mix(in srgb, var(--fremd-ton, #d8a13a) 13%, rgba(8, 12, 20, .92));
color: var(--text);
font-size: .82rem;
position: relative; z-index: 4; /* unter der Leiste (5/6), ueber dem Inhalt */
}
.fremd-band[data-rolle] { --fremd-ton: var(--rolle-haupt, #d8a13a); }
.fremd-band__auge {
flex: none; width: 16px; height: 16px;
fill: none; stroke: var(--fremd-ton, #d8a13a); stroke-width: 1.6;
}
.fremd-band__text {
margin: 0; min-width: 0;
/* Der Name darf umbrechen statt abzuschneiden -- genau das
Abschneiden ("Miesmus…") war ja der Grund, ihn hierher zu holen. */
overflow-wrap: anywhere;
/* Nicht `--text-leise`: Das Band ist keine Randnotiz, sondern die
Antwort auf "wessen Zahlen sehe ich hier gerade". Der gefaehrlichste
Fall dieser Funktion ist, dass man sie vergisst -- eine leise
Schrift waere genau das Gegenteil davon. */
color: var(--text);
}
.fremd-band__name { color: var(--fremd-ton, #d8a13a); font-weight: 700; }
.fremd-band__weg {
flex: none; margin-left: auto;
min-height: 34px; padding: 0 12px;
border: 1px solid color-mix(in srgb, var(--fremd-ton, #d8a13a) 45%, transparent);
border-radius: 999px;
background: transparent;
color: var(--fremd-ton, #d8a13a);
font: inherit; font-size: .78rem; font-weight: 600;
cursor: pointer;
transition: background var(--tempo);
}
.fremd-band__weg:hover { background: color-mix(in srgb, var(--fremd-ton, #d8a13a) 16%, transparent); }
.fremd-band__weg:focus-visible { outline: 2px solid var(--fremd-ton, #d8a13a); outline-offset: 2px; }
@media (forced-colors: active) {
.fremd-band { border-bottom: 1px solid CanvasText; }
.fremd-band__weg { border: 1px solid ButtonText; color: ButtonText; }
}
/* Ab hier wird die Kopfleiste eng. Das Schild "SICHT" entfaellt als
Erstes -- das Feld selbst sagt bereits, wessen Sicht laeuft, und der
Rahmen um die Seite sagt DASS eine fremde laeuft. */
@media (max-width: 1180px) {
.sicht__schild { display: none; }
.sicht { padding-left: 6px; }
.sicht .wahl2 { max-width: 150px; }
}
@media (max-width: 900px) {
.sicht .wahl2 { max-width: 128px; }
/* Der Knopf "zurueck zu mir" entfaellt -- "Alles (meine Sicht)" steht
ganz oben in der Auswahl und tut dasselbe. */
.sicht__weg { display: none; }
}
@media (max-width: 620px) {
/* MINDESTBREITE, nicht nur Hoechstbreite: Ein Knopf, der auf zwanzig
Pixel zusammenfaellt, ist mit dem Daumen nicht zu treffen.
Den Platz gibt der eigene Name daneben ab -- er steht ohnehin als
Plakette da, und wessen Sicht laeuft, ist die wichtigere Auskunft. */
.sicht .wahl2 { min-width: 104px; max-width: 118px; }
.sicht { padding: 3px 4px; }
.wer__name { display: none; }
}
/* SEHR SCHMAL: die Kopfleiste darf umbrechen (05.09.2026).
Die Rechnung darueber ging genau auf, solange rechts vier Dinge
standen. Mit der Glocke sind es fuenf, und bei 320 px (iPhone SE)
passte es nicht mehr: Die Lupe des Suchknopfes lag danach mitten auf
dem Sicht-Umschalter -- ein Knopf, der auf zwoelf Seiten ins Leere
tippt. Gemeldet von pruef-handy, bevor es jemand gesehen hat.
WARUM UMBRECHEN und nicht weiter schrumpfen: Jedes Stueck hier hat
seine Mindestgroesse aus einem guten Grund -- 104 px, damit der
Umschalter mit dem Daumen zu treffen ist, und die Glocke ist bereits
auf das blosse Zeichen zusammengefallen. Wer hier weiter kuerzt,
tauscht ein sichtbares Problem gegen ein unsichtbares: Knoepfe, die
zwar nebeneinander liegen, aber zu klein zum Treffen sind.
Eine zweite Zeile auf einem 320-Pixel-Schirm kostet 44 Pixel Hoehe.
Das ist der guenstigste Preis, der hier zu haben ist -- und er faellt
nur auf Geraeten an, die wirklich so schmal sind. */
/* DIESE SCHWELLE IST AM 09.09.2026 VON 380 AUF 300 GEFALLEN.
Sie zwang Marke und Bedienelemente ausdruecklich in ZWEI Zeilen --
und war richtig, solange die Bedienelemente 243 bis 393 px brauchten.
Seit sie gleich grosse Zeichen sind, brauchen sie 136 bis 238; bei
360 px stehen 334 zur Verfuegung. Die Regel machte ab da zwei Zeilen
aus etwas, das in eine passt.
300 px und nicht ganz weg: Darunter gibt es Geraete, auf denen es
wirklich nicht reicht, und dort ist die zweite Zeile besser als ein
Ueberstand. Gemessen bei 360, 390, 412 und 430 -- alle einzeilig. */
/* NOCH EINE STUFE ENGER (09.09.2026, gemeldet von pruef-handy).
Bei 320 px hat die Leiste doch umgebrochen -- und zwar nur auf
Unterseiten. Dort steht links der Zurueck-Knopf (55 px), rechts
kommt auf manchen Seiten die Glocke als siebtes Element dazu.
Gerechnet: 55 + 6 + (5 x 36 + 28 + 6 x 6) = 305, verfuegbar 294.
Elf Pixel. Statt die Schwelle wieder hochzusetzen -- was die zweite
Zeile zurueckgebracht haette -- wird hier eine Stufe kleiner
geschaltet: 34 px je Knopf, 4 px Abstand. Macht 283 und passt.
34 px bleiben deutlich ueber den 24 px, die als Mindestmass fuer ein
Beruehrziel gelten (WCAG 2.5.8). */
/* Der Block fuer sehr schmale Geraete ist am 09.09.2026 ans ENDE der
Datei gewandert, direkt hinter den 560er-Block. Grund: Er stand hier,
also VOR ihm, und hat deshalb bei gleicher Spezifitaet verloren --
die 34 px kamen nur an, weil der Selektor zufaellig ein `:not()`
trug und damit staerker war. Wer sich auf so etwas verlaesst, baut
auf Sand: Sobald das `:not()` faellt (und es musste fallen, siehe
dort), gilt wieder der 560er-Block. Zwei Regeln fuer dieselbe Sache
gehoeren nebeneinander, in der Reihenfolge, in der sie greifen. */
@media (max-width: 300px) {
.kopfleiste { flex-wrap: wrap; row-gap: 8px; }
/* Die Marke nimmt die erste Zeile ganz ein, die Bedienelemente
ruecken geschlossen in die zweite. Ohne das brechen sie mitten
zwischen Suche und Glocke um. */
.kopfleiste > .marke { flex: 1 0 100%; }
.kopfleiste__rechts {
width: 100%;
/* AUCH DIE ZWEITE ZEILE DARF UMBRECHEN. Ohne das reichten die
294 Pixel weiterhin nicht: Umschalter (104) + Suche (47) +
Glocke (37) + Plakette + Abmelden sind zusammen mehr. Die
Elemente wurden dann zwar nicht mehr ueberdeckt, aber der
Umschalter ragte aus seinem eigenen Kasten heraus -- ein
stilles Ueberlaufen, das keine Pruefung meldet und trotzdem
falsch aussieht. */
flex-wrap: wrap; row-gap: 6px;
}
/* Der Umschalter behaelt seine Breite -- das gilt seit dem 06.09.2026
an jeder Breite und steht deshalb oben bei .sicht selbst. */
}
@media (forced-colors: active) {
body[data-fremde-sicht="ja"]::after { border-color: Highlight; }
}
/* Das Wasserzeichen in der Ecke bekommt die neue Behandlung NICHT.
Es ist bewusst eine ganz dünne, fast unsichtbare Kontur; ein Schein
darunter würde daraus einen grauen Fleck machen -- und zwar genau
dort, wo er den Text der Kachel hinterlegt. (03.09.2026) */
.kachel__wasserzeichen .kachel__svg { filter: none; }
.kachel__wasserzeichen .zeichen__linie { stroke: var(--ton); stroke-width: 1.1; }
/* ---------- Die gefüllte Grundform (03.09.2026) --------------------------
Jedes Zeichen hat jetzt eine Fläche unter der Linie (siehe
bereiche.js). Sie ist bewusst schwach: Sie soll dem Zeichen ein Vorn
und ein Hinten geben, nicht mit der Linie um Aufmerksamkeit streiten.
20 % sind gemessen, nicht geraten -- darüber wird das Zeichen zum
Fleck und die Linie darin unsichtbar, darunter sieht man die Fläche
gar nicht mehr. Beim Überfahren geht sie auf 30 %, so als käme Licht
dazu. */
/* Die Spiegelung liegt auf demselben Körper -- ein schmaler heller
Streifen quer über die obere Hälfte, wie Licht auf gewölbtem Glas. */
:is(.kachel__svg, .dran__svg) .zeichen__glanz {
fill: url(#zeichen-glanz);
stroke: none;
transition: opacity var(--tempo);
}
.kachel:hover :is(.kachel__svg, .dran__svg) .zeichen__glanz { opacity: 1.35; }
/* Im Wasserzeichen NICHT -- dort liegt das Zeichen riesig hinter dem
Text der Kachel. Eine Fläche würde ihn hinterlegen. */
.kachel__wasserzeichen .zeichen__fuellung,
.kachel__wasserzeichen .zeichen__glanz { display: none; }
@media (prefers-reduced-motion: reduce) {
}
@media (forced-colors: active) {
/* Ohne Farben würde die Fläche zu einem massiven Block. */
:is(.kachel__svg, .dran__svg) .zeichen__fuellung,
:is(.kachel__svg, .dran__svg) .zeichen__glanz { display: none; }
}
/* ---------- Material statt Zeichnung (03.09.2026, zweite Stufe) ----------
Der Eigenschatten des Zeichens: eine dunkle Lage auf dem Körper, die
von unten hereinkriecht. Zusammen mit dem Streulicht in der Kontur
ergibt das die Beleuchtung, die man aus der Wirklichkeit kennt --
Hauptlicht oben, Schatten unten, Aufheller an der Unterkante. */
/* Der Schlagschatten AUF die Plakette. Er ist der eigentliche Grund,
warum das Zeichen über der Fläche zu schweben scheint statt darauf zu
liegen: Er sitzt versetzt nach unten, nicht mittig. Dazu der farbige
Hof von vorher -- Schatten UND Licht, wie bei jedem Gegenstand, der
auf etwas liegt. */
.kachel__svg {
filter:
drop-shadow(0 1.5px 1.5px rgba(0, 0, 0, .55))
drop-shadow(0 1px 4px color-mix(in srgb, var(--ton) 50%, transparent));
}
.kachel:hover .kachel__svg {
filter:
drop-shadow(0 2px 2px rgba(0, 0, 0, .6))
drop-shadow(0 2px 8px color-mix(in srgb, var(--ton) 70%, transparent));
}
/* ---------- Die Körnung ---------------------------------------------------
Eine sehr feine, unregelmäßige Struktur auf der Plakette. Sie ist der
Unterschied zwischen "am Rechner gemacht" und "Gegenstand": Eine
makellos glatte Farbfläche gibt es in der Wirklichkeit nicht, und das
Auge erkennt das sofort -- auch wenn niemand sagen könnte, woran es
liegt.
Als eingebettetes Rauschen, keine Bilddatei: kostet nichts zu laden
und kann nicht fehlen. */
.kachel__zeichen::after {
content: "";
position: absolute; inset: 0;
pointer-events: none;
opacity: .5;
mix-blend-mode: overlay;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='k'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23k)' opacity='0.35'/%3E%3C/svg%3E");
}
@media (forced-colors: active) {
:is(.kachel__svg, .dran__svg) .zeichen__eigenschatten,
.kachel__zeichen::after { display: none; }
.kachel__svg { filter: none; }
}
/* ---------- Die Kachel als Gegenstand (03.09.2026, zweite Stufe) ---------
Die Kachel hatte schon eine Lichtkante -- aber eine durchgehend
gleich helle, über die volle Breite. Das ist ein Strich, kein Licht.
Echtes Licht auf einer Kante ist in der Mitte am stärksten und läuft
nach aussen aus.
Dazu kommt, was einer Kachel bisher ganz fehlte: TIEFE nach unten.
Ein Gegenstand, der auf etwas liegt, wirft einen Schatten -- ohne ihn
klebt die Kachel auf dem Hintergrund, statt darauf zu liegen. */
.kachel {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .04),
0 10px 26px -18px rgba(0, 0, 0, .9),
0 2px 6px -4px rgba(0, 0, 0, .5);
}
/* Lichtkante, Hover-Schatten und Kontrastmodus der Kachel stehen seit
dem 07.09.2026 im Abschnitt HUD-MODULE am Ende dieser Datei. Was hier
stand, war die aelteste von drei Generationen und wurde von jeder
Seite geladen, ohne je zu wirken. */
/* ---------- Der Benachrichtigungs-Knopf ------------------------------
Wunsch Filipe (05.09.2026): ein Knopf wie "Benachrichtigungen aus",
auf jeder Seite erreichbar.
Gebaut wie `.abmelden` daneben, damit die Kopfleiste eine Sprache
spricht -- und mit denselben Umbruchregeln: Auf schmalen Schirmen
bleibt nur die Glocke stehen, der Text weicht. Genau daran ist die
Kopfleiste am 31.08.2026 schon einmal gescheitert (214 px aus dem
Bild); deshalb hier von vornherein `min-width: 0` und ein Text, der
verschwinden darf. */
.glocke {
display: inline-flex; align-items: center; gap: 7px;
min-width: 0; flex: none;
padding: 7px 13px;
background: rgba(255, 255, 255, .04);
border: 1px solid var(--rand);
border-radius: 999px;
color: var(--text-leise);
font: inherit; font-size: .82rem;
cursor: pointer;
transition: border-color var(--tempo), background var(--tempo), color var(--tempo);
}
.glocke:hover:not(:disabled) { background: rgba(255, 255, 255, .07); border-color: var(--rand-hell); }
.glocke:disabled { opacity: .55; cursor: not-allowed; }
.glocke__zeichen { width: 17px; height: 17px; flex: none; }
.glocke__zeichen path {
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linecap: round; stroke-linejoin: round;
}
.glocke__strich { opacity: 0; }
/* AN: die Glocke bekommt Farbe, der Strich bleibt weg. */
.glocke[data-lage="an"] {
color: var(--akzent);
border-color: color-mix(in srgb, var(--akzent) 42%, transparent);
background: color-mix(in srgb, var(--akzent) 10%, transparent);
}
/* AUS: durchgestrichene Glocke -- man sieht auf einen Blick, dass
nichts kommt, ohne den Text zu lesen. */
.glocke[data-lage="aus"] .glocke__strich { opacity: .85; }
/* Die drei Faelle, in denen der Knopf nichts schalten kann, sind
gedaempft und tragen ebenfalls den Strich: Sie sind naeher an "aus"
als an "an", und genau so soll es aussehen. */
.glocke[data-lage="iphone"], .glocke[data-lage="verboten"],
.glocke[data-lage="geht-nicht"] {
color: var(--text-still);
}
.glocke[data-lage="iphone"] .glocke__strich,
.glocke[data-lage="verboten"] .glocke__strich,
.glocke[data-lage="geht-nicht"] .glocke__strich { opacity: .7; }
/* Schmale Schirme: nur die Glocke. Der Text steht weiterhin im
aria-label, Vorleseprogramme verlieren also nichts.
900 PIXEL, NICHT 760 (korrigiert 05.09.2026). Die erste Fassung
nahm 760 -- und ein Tablet hochkant hat 768. Dort stand der Text
also noch, die Glocke war rund 200 statt 37 Pixel breit, und der
Abmelden-Knopf wurde um bis zu 15 Pixel aus dem Bild geschoben. Auf
vier Seiten, gemeldet von pruef-breiten.
Die Grenze liegt jetzt auf derselben Stufe wie die uebrigen Regeln
fuer die enge Kopfleiste (der Sicht-Umschalter wird ab 900 px
ebenfalls schmaler). Eine eigene Schwelle daneben waere genau die
Art Zahl, die beim naechsten Mal wieder knapp danebenliegt. */
@media (max-width: 900px) {
.glocke { padding: 7px 9px; }
.glocke__text { display: none; }
}
/* ERKLÄRSATZ UNTER EINER ÜBERSCHRIFT — der Grundwert.
Gefunden am 05.09.2026 von pruef-css-klassen.mjs, beim allerersten
Lauf. `.block__frage` war viermal fast gleich definiert -- in
automation.css, calls.css, report.css und wissen.css -- und wurde
auf content.html benutzt, das keine dieser vier Dateien lädt. Der
Absatz stand dort seit jeher unformatiert.
Genau dasselbe Muster wie bei der Teilnehmerwahl am selben Tag:
Das CSS existiert, es sieht im Editor richtig aus, und auf der Seite
kommt nichts an. Solange es nur in Seiten-Stylesheets steht, findet
es niemand.
Hier steht deshalb der Grundwert, den jede Seite bekommt. Die vier
Seiten-Stylesheets werden NACH start.css geladen und behalten damit
ihre Feinheiten (12, 13 oder 14 Pixel Abstand) -- sie bleiben
unverändert. Neu ist nur, dass eine Seite ohne eigene Fassung nicht
mehr leer ausgeht. */
.block__frage {
margin: 0 0 13px;
font-size: .85rem;
color: var(--text-still);
max-width: 76ch;
}
/* =====================================================================
DER TAGESBLICK — eine Kachel, in der Mitte geteilt
=====================================================================
Wunsch Filipe, 05.09.2026: eine ganze Kachel, links die Hinweise,
rechts die Termine des Tages, in der Mitte geteilt -- "richtig geil
und hochwertig".
WAS "HOCHWERTIG" HIER HEISST — und was nicht:
Nicht mehr Effekte. Der Eindruck entsteht aus drei Dingen, die man
einzeln kaum bemerkt und zusammen sofort:
1. EINE Kante um beides statt zwei Kacheln nebeneinander. Zwei
Rahmen lesen sich als zwei Themen; einer sagt "zwei Seiten
derselben Sache".
2. Ein Trenner, der oben und unten AUSLÄUFT statt durchzuschneiden.
Eine harte Linie zerteilt die Kachel, ein Verlauf gliedert sie.
3. Ruhe. Der Hintergrund bleibt fast schwarz, die Farbe steckt in
wenigen kleinen Flächen -- den Punkten auf dem Zeitstrahl. Wo
alles leuchtet, leuchtet nichts.
Augenschonend ist Hausregel: keine harten Weißflächen, keine
Neonränder, Bewegung nur als kurze Blende.
AUFBAU: ein Raster mit drei Spalten -- Inhalt, Trenner, Inhalt. Der
Trenner ist eine eigene Spalte und kein Rand, damit er unabhängig von
der Höhe beider Seiten auf voller Länge sitzt und auslaufen kann. */
.tagesblick {
display: grid;
grid-template-columns: 1fr 1px 1fr;
gap: 0;
margin-bottom: 30px;
border: 1px solid var(--rand);
border-radius: var(--radius);
background:
/* Ein sehr flacher Schein von links oben -- er gibt der Fläche
Tiefe, ohne als Farbe aufzufallen. */
radial-gradient(120% 90% at 0% 0%,
rgba(255, 255, 255, .035), transparent 58%),
var(--flaeche);
overflow: hidden;
}
/* Die Überschrift der ganzen Kachel ist für Vorleseprogramme da --
auf dem Schirm sagen die beiden Schilder schon alles, und eine
dritte Überschrift darüber wäre eine Zeile ohne Inhalt. */
.tagesblick__titel {
position: absolute;
width: 1px; height: 1px; margin: -1px; padding: 0;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* DIE SPALTEN WERDEN AUSDRÜCKLICH ZUGEWIESEN (05.09.2026).
Ohne das rutschte die rechte Hälfte in die 1-Pixel-Spalte des
Trenners und war 38 statt 579 Pixel breit. Grund: Die Kachel hat drei
Kinder -- die versteckte Überschrift, links, rechts -- und ein Raster
verteilt sie der Reihe nach. `position: absolute` an der Überschrift
nimmt sie zwar aus dem Fluss, aber verlassen sollte man sich darauf
nicht: Wer später ein viertes Kind einfügt (einen Ladebalken, einen
Hinweis), verschiebt sonst wieder alles um eine Spalte, ohne dass
irgendwo ein Fehler erscheint.
Mit `grid-column` ist die Zuordnung an die Sache gebunden statt an
die Reihenfolge im Dokument. */
.tagesblick__seite--dran { grid-column: 1; }
.tagesblick__seite--heute { grid-column: 3; }
/* SOLANGE GELADEN WIRD, hält die Kachel ihre Höhe. Ohne das sprang
alles darunter nach unten, sobald die Daten ankamen -- gemessen als
Layout-Sprung 0,96 auf der Startseite. Der Wert entspricht ungefähr
einer Kachel mit zwei bis drei Einträgen je Seite. Gemessen: ein
Termin ergibt 169 px, drei ergeben 327 px -- 280 liegt dazwischen,
der Rest-Sprung ist damit in beide Richtungen klein. */
.tagesblick[data-laedt="ja"] { min-height: 280px; }
/* Die Überschriften stehen schon da, der Rest bleibt ruhig leer. Ein
zappelndes Skelett wäre hier Selbstzweck -- die Wartezeit ist der
eine Moment, in dem die Daten aus der Datenbank kommen. */
.tagesblick[data-laedt="ja"] .tagesblick__leer { visibility: hidden; }
.tagesblick__seite {
display: flex; flex-direction: column;
padding: 17px 19px 19px;
min-width: 0; /* sonst sprengt ein langer Titel die Spalte */
}
/* DER TRENNER. Oben und unten durchsichtig: Eine Linie, die die Kachel
von Kante zu Kante durchschneidet, macht aus einer Kachel zwei. Eine,
die ausläuft, gliedert sie nur. */
.tagesblick__seite--heute { position: relative; }
.tagesblick__seite--heute::before {
content: "";
position: absolute; left: -1px; top: 14px; bottom: 14px; width: 1px;
background: linear-gradient(180deg,
transparent,
var(--rand-hell) 18%,
var(--rand-hell) 82%,
transparent);
}
.tagesblick__kopf { margin-bottom: 12px; }
/* Der Kalender-Verweis rechts oben. Still, bis man ihn braucht. */
/* DER WEG IN DEN KALENDER IST EIN KNOPF, KEIN NEBENSATZ (08.09.2026).
Filipe, screen33: "der kalender button da in der kachel oben rechts,
der soll viel auffälliger sein und viel krasser und geiler."
Er sah vorher aus wie ein Verweis im Fliesstext -- kleine Schrift,
kein Rahmen, keine Flaeche. Neben der fetten Ueberschrift "Heute"
verschwand er, obwohl er die einzige Handlung in dieser Zeile ist.
Er traegt jetzt den Kalender-Ton (Nummer 8 aus der Palette), und zwar
als Fassung: eigene Flaeche, farbiger Rahmen, ein Schimmer darunter.
Beim Ueberfahren wandert ein heller Streifen darueber -- derselbe
Kniff wie beim Manager-Stern, weil Glanz etwas ist, das sich BEWEGT.
Warum der Kalender-Ton und nicht das allgemeine Blau: Der Knopf fuehrt
in den Kalender, und die Kachel dort traegt genau diese Farbe. Wer
ihn sieht, weiss ohne zu lesen, wo er landet.
`--f` wird mitgesetzt, damit der Schein beim Ueberfahren (gate.css)
aus derselben Farbe kommt und nicht aus der Vorgabe. */
.tagesblick__mehr {
--f: var(--ton-kalender, #c06ad0);
position: relative; overflow: hidden;
display: inline-flex; align-items: center; gap: 7px;
padding: 7px 13px;
font-size: .82rem; font-weight: 650; letter-spacing: .01em;
text-decoration: none;
color: color-mix(in srgb, var(--f) 30%, #f2f7fd);
background: linear-gradient(180deg,
color-mix(in srgb, var(--f) 17%, transparent),
color-mix(in srgb, var(--f) 7%, transparent));
border: 1px solid color-mix(in srgb, var(--f) 48%, transparent);
border-radius: 999px;
box-shadow:
inset 0 1px 0 color-mix(in srgb, var(--f) 30%, transparent),
0 3px 14px -8px var(--f);
transition: color var(--tempo), border-color var(--tempo),
background var(--tempo), box-shadow var(--tempo);
}
.tagesblick__mehr:hover {
color: #fff;
border-color: color-mix(in srgb, var(--f) 78%, transparent);
box-shadow:
inset 0 1px 0 color-mix(in srgb, var(--f) 45%, transparent),
0 6px 20px -8px var(--f);
}
/* Der Streifen, der beim Ueberfahren darueberwandert. Er liegt in einem
eigenen Element, damit er den Text nicht mitfaerbt. */
.tagesblick__mehr::after {
content: "";
position: absolute; inset: 0;
background: linear-gradient(105deg, transparent 38%,
rgba(255, 255, 255, .22) 50%, transparent 62%);
transform: translateX(-130%);
transition: transform .55s cubic-bezier(.4, 0, .2, 1);
pointer-events: none;
}
.tagesblick__mehr:hover::after { transform: translateX(130%); }
/* Hausregel: Wer weniger Bewegung eingestellt hat, bekommt keinen
Streifen -- der Knopf bleibt trotzdem auffaellig, er glaenzt nur
nicht. */
@media (prefers-reduced-motion: reduce) {
.tagesblick__mehr::after { display: none; }
}
.tagesblick__mehr-pfeil { width: 14px; height: 14px; transition: transform var(--tempo); }
.tagesblick__mehr:hover .tagesblick__mehr-pfeil { transform: translateX(2px); }
/* Der Satz, wenn eine Hälfte nichts zu zeigen hat. Er steht in der
Fläche, die sonst die Liste füllt -- ohne ihn sähe die Seite aus,
als hätte sie nicht geladen. */
.tagesblick__leer {
flex: 1;
display: flex; align-items: center;
margin: 0; padding: 14px 0;
font-size: .84rem; color: var(--text-still);
}
/* ---------- Die Termine des Tages ---------------------------------------
ZWEITER ANLAUF (05.09.2026). Der erste war eine Liste mit einem
dünnen Strich dahinter. Filipes Urteil an einem Tag mit EINEM
Termin: *"das soll viel geiler und krasser aussehen."*
Er hatte recht, und der Grund ist der Einzelfall: Ein Zeitstrahl
lebt davon, dass er etwas VERBINDET. Bei einem einzigen Eintrag
verbindet er nichts -- übrig bleiben eine magere Zeile, ein Strich
ins Leere und viel Weißraum bis zur Plakette am rechten Rand.
WAS SICH ÄNDERT: Jeder Termin ist jetzt eine eigene Fläche mit
farbiger Kante statt einer nackten Zeile. Das trägt auch allein.
Dazu drei Dinge, die vorher fehlten:
* Die Uhrzeit ist groß und trägt die Farbe der Terminart. Sie ist
die Auskunft, die man sucht -- vorher war sie kleiner als der
Titel.
* Ein Balken zeigt die DAUER. Aus "30 min" als Text wird etwas,
das man sieht, ohne zu lesen: Ein Zweistundenblock ist ein
anderer Tag als vier Viertelstunden.
* Der nächste Termin bekommt einen Ring und die Marke "JETZT" --
nicht bloß einen helleren Hintergrund.
WAS SICH NICHT ÄNDERT: kein Neon, keine harten Weißflächen, keine
Bewegung. "Krass" entsteht hier aus Kontrast und Hierarchie, nicht
aus Leuchtkraft -- augenschonend bleibt Hausregel. Die Farbe steckt
weiterhin in wenigen kleinen Flächen; sie wirkt nur stärker, weil
drumherum mehr Ruhe ist. */
.tagesliste {
display: grid; gap: 8px;
margin: 0; padding: 0; list-style: none;
}
.tagesliste__punkt {
--ton: #8a76ff;
position: relative;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 14px;
padding: 13px 15px 13px 17px;
border: 1px solid var(--rand);
/* DIE FASE STATT RUNDER ECKEN (08.09.2026).
Gefunden durch den Formvergleich ueber alle fuenf Rollen: Dieser
Baustein war einer von zweien, die noch runde Ecken trugen -- und
er faellt auf, weil er auf der Startseite direkt unter Kacheln mit
Fase steht.
Nicht ueber die Modulliste, sondern hier: `::before` traegt die
Farbkante links, und die Modulliste braucht dasselbe Pseudo-Element
fuer ihre Eckwinkel. Die Kante ist an einer Terminzeile die
wichtigere Aussage -- sie sagt, um welche Art Termin es geht. */
clip-path: polygon(var(--fase, 18px) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fase, 18px));
border-radius: 0;
/* Ein Hauch der Terminfarbe von links, dann nichts mehr. Die Fläche
bleibt fast schwarz -- die Farbe soll die Kante betonen, nicht die
Karte einfärben. */
background:
linear-gradient(90deg,
color-mix(in srgb, var(--ton) 8%, transparent),
transparent 42%),
rgba(255, 255, 255, .022);
transition: border-color .18s ease, background .18s ease, transform .18s ease;
overflow: hidden;
}
/* DIE KANTE LINKS ist der eigentliche Träger der Farbe. Oben kräftig,
unten auslaufend -- ein durchgehender Balken wirkt wie ein Etikett,
ein auslaufender wie Licht. */
.tagesliste__punkt::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
background: linear-gradient(180deg,
var(--ton), color-mix(in srgb, var(--ton) 30%, transparent));
}
.tagesliste__punkt[data-art="call"] { --ton: #3fbdf5; }
.tagesliste__punkt[data-art="termin"] { --ton: #8a76ff; }
.tagesliste__punkt[data-art="review"] { --ton: #50a752; }
.tagesliste__punkt[data-art="frist"] { --ton: #d17717; }
.tagesliste__punkt:hover {
border-color: color-mix(in srgb, var(--ton) 40%, var(--rand));
background:
linear-gradient(90deg,
color-mix(in srgb, var(--ton) 13%, transparent),
transparent 48%),
rgba(255, 255, 255, .045);
}
/* ---- Die Zeit: groß, farbig, mit Dauerbalken ---- */
.tagesliste__zeit {
display: flex; flex-direction: column; align-items: flex-start;
gap: 7px;
min-width: 92px;
}
/* Balken und Minutenzahl stehen NEBENEINANDER, nicht übereinander.
Untereinander lag der Balken direkt unter der Uhrzeit und las sich
als deren Unterstreichung -- er sah aus wie Deko und nicht wie eine
Angabe. Nebeneinander ist klar, dass die Länge etwas bedeutet, und
die linke Spalte wird eine Zeile flacher. */
.tagesliste__laenge {
display: flex; align-items: center; gap: 8px;
width: 100%;
}
.tagesliste__stunde {
font-size: 1.12rem; font-weight: 700;
letter-spacing: -.01em; line-height: 1;
color: color-mix(in srgb, var(--ton) 62%, #ffffff);
font-variant-numeric: tabular-nums;
}
/* DER DAUERBALKEN. Seine Breite kommt aus --laenge (in start.js
gesetzt): 30 Minuten sind kurz, zwei Stunden füllen ihn. Damit sieht
man die Länge, statt sie zu lesen.
Gedeckelt bei 100 %, weil ein Ganztagestermin den Balken sonst aus
der Karte schöbe. */
.tagesliste__balken {
position: relative; flex: none;
/* Feste Breite statt 100 %: Die Spur ist der Maßstab, an dem man die
Füllung abliest. Wäre sie mal breiter, mal schmaler, sagte die
Füllung nichts mehr. */
width: 40px; height: 4px;
border-radius: 999px;
background: rgba(255, 255, 255, .08);
overflow: hidden;
}
.tagesliste__balken::after {
content: ""; position: absolute; inset: 0;
width: var(--laenge, 30%);
border-radius: 999px;
background: linear-gradient(90deg,
var(--ton), color-mix(in srgb, var(--ton) 45%, transparent));
}
.tagesliste__dauer {
font-size: .74rem; color: var(--text-still);
font-variant-numeric: tabular-nums;
}
/* ---- Text ---- */
.tagesliste__text { min-width: 0; }
.tagesliste__titel {
margin: 0;
font-size: .96rem; font-weight: 620; color: var(--text);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tagesliste__unter {
margin: 3px 0 0;
font-size: .78rem; color: var(--text-still);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ---- Rechte Seite: Art und Zustand ---- */
.tagesliste__rechts {
display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
}
.tagesliste__art {
padding: 3px 10px; border-radius: 999px;
/* 11,84 px. Unter 11,5 meldet die Geräteprüfung zu Recht "zu kleine
Schrift" -- und Großbuchstaben mit Sperrung wirken kleiner, als
sie sind. */
font-size: .74rem; font-weight: 700;
letter-spacing: .06em; text-transform: uppercase;
color: color-mix(in srgb, var(--ton) 78%, #ffffff);
background: color-mix(in srgb, var(--ton) 13%, transparent);
border: 1px solid color-mix(in srgb, var(--ton) 30%, transparent);
white-space: nowrap;
}
/* DIE JETZT-MARKE. Sie sagt in einem Wort, was der hellere Hintergrund
vorher nur andeutete. */
.tagesliste__jetzt {
display: none;
align-items: center; gap: 5px;
/* 11,84 px. Zum ZWEITEN Mal an dieser Kachel korrigiert -- erst die
Art-Plaketten, jetzt diese Marke. Unter 11,5 px meldet die
Geraetepruefung zu Recht "zu kleine Schrift", und Grossbuchstaben
mit weiter Sperrung wirken noch kleiner, als sie sind. */
font-size: .74rem; font-weight: 800;
letter-spacing: .1em; text-transform: uppercase;
color: var(--ton);
}
.tagesliste__jetzt::before {
content: ""; width: 6px; height: 6px; border-radius: 50%;
background: var(--ton);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--ton) 22%, transparent);
}
.tagesliste__punkt[data-naechster="ja"] .tagesliste__jetzt { display: inline-flex; }
/* ---- Als Nächstes dran ---- */
.tagesliste__punkt[data-naechster="ja"] {
border-color: color-mix(in srgb, var(--ton) 45%, transparent);
background:
linear-gradient(90deg,
color-mix(in srgb, var(--ton) 15%, transparent),
transparent 55%),
rgba(255, 255, 255, .04);
}
.tagesliste__punkt[data-naechster="ja"]::before { width: 4px; }
.tagesliste__punkt[data-naechster="ja"] .tagesliste__stunde {
color: color-mix(in srgb, var(--ton) 40%, #ffffff);
}
/* ---- Vorbei ----
Zurücktreten, nicht verschwinden: Man will sehen, was man heute
schon hinter sich hat. Statt alles blass zu machen (dann leidet die
Lesbarkeit), verliert nur die FARBE an Kraft -- der Text bleibt. */
.tagesliste__punkt[data-vorbei="ja"] {
--ton: #75859a;
background: rgba(255, 255, 255, .015);
}
.tagesliste__punkt[data-vorbei="ja"] .tagesliste__titel { color: var(--text-leise); }
.tagesliste__punkt[data-vorbei="ja"]::before { opacity: .5; }
.tagesliste__punkt[data-vorbei="ja"]:hover { background: rgba(255, 255, 255, .04); }
/* Der Haken sagt "erledigt" schneller als jede Farbe. */
.tagesliste__punkt[data-vorbei="ja"] .tagesliste__art::before {
content: "✓ ";
font-weight: 700;
}
/* ---- Der ganze Eintrag ist anklickbar ----
Ein <a> um alles herum läse sich für ein Vorleseprogramm als ein
einziger langer Name. So bleibt die Struktur erhalten, und das
aria-label sagt den ganzen Satz. */
.tagesliste__link {
position: absolute; inset: 0;
/* Kein eigener Radius mehr: Die Zeile darueber traegt seit dem
08.09.2026 die Fase und schneidet mit `overflow: hidden` ohnehin
zu. Ein runder Rand hier wuerde nur beim Lesen behaupten, hier sei
etwas rund -- sichtbar ist er nie. */
border-radius: 0;
}
/* "3 weitere Termine heute" -- der Hinweis auf das, was nicht mehr
in die Kachel passte. Still gehalten: Er ist ein Wegweiser, keine
sechste Karte. */
.tagesliste__mehr {
padding: 4px 0 0 2px;
}
.tagesliste__mehr-link {
font-size: .8rem; color: var(--text-still);
text-decoration: none;
transition: color .16s ease;
}
.tagesliste__mehr-link:hover { color: var(--text-leise); }
.tagesliste__link:focus-visible {
outline: 2px solid var(--ton); outline-offset: -3px;
}
/* ---------- Schmale Schirme --------------------------------------------
Untereinander statt nebeneinander -- und der Trenner wird waagerecht.
Zwei Spalten auf einem Handy hieße zwei halbe Zeilen, in denen jeder
Titel abgeschnitten ist. */
@media (max-width: 900px) {
.tagesblick { grid-template-columns: 1fr; }
/* Die feste Spaltenzuweisung von oben muss hier zurückgenommen
werden -- "Spalte 3" gibt es in einem einspaltigen Raster nicht,
und der Browser legt dann stillschweigend zwei leere Spalten an. */
.tagesblick__seite--dran,
.tagesblick__seite--heute { grid-column: 1; }
.tagesblick__seite--heute::before {
left: 14px; right: 14px; top: -1px; bottom: auto;
width: auto; height: 1px;
background: linear-gradient(90deg,
transparent, var(--rand-hell) 18%, var(--rand-hell) 82%, transparent);
}
.tagesblick__seite { padding: 15px 16px 17px; }
.tagesblick__seite--heute { padding-top: 17px; }
}
@media (max-width: 460px) {
.tagesliste__punkt {
/* Die Uhrzeitspalte wird schmaler, der Rest bleibt. Die Plakette
nach unten zu schieben wäre der naheliegende Griff -- sie steht
dann aber unter dem Titel und macht jede Karte fünfzig Pixel
höher, ohne etwas zu gewinnen. */
gap: 11px;
padding: 12px 13px 12px 15px;
/* OBEN AUSRICHTEN: Bricht der Titel auf zwei Zeilen, stünde eine
mittig gesetzte Uhrzeit auf Höhe der zweiten und fluchtete mit
nichts. Am Rechner bleibt es mittig, dort ist alles einzeilig. */
align-items: start;
}
.tagesliste__zeit { min-width: 78px; }
.tagesliste__stunde { font-size: 1.02rem; }
/* Der Balken entfaellt am Handy -- neben ihm bliebe fuer den Titel
zu wenig. Die Zahl sagt es weiterhin. */
.tagesliste__balken { display: none; }
.tagesliste__titel { font-size: .92rem; white-space: normal; }
.tagesliste__rechts { padding-top: 2px; }
}
@media (prefers-reduced-motion: reduce) {
.tagesliste__punkt, .tagesblick__mehr-pfeil { transition: none; }
}
/* Ohne Farbverläufe trägt die Kante allein -- und die ist hier ein
Verlauf, also muss sie zur echten Fläche werden. Sonst verschwindet
ausgerechnet das Merkmal, das die Terminart anzeigt. */
@media (forced-colors: active) {
.tagesblick { border: 1px solid CanvasText; }
.tagesblick__seite--heute::before { background: CanvasText; }
.tagesliste__punkt { border: 1px solid CanvasText; }
.tagesliste__punkt::before { background: CanvasText; }
.tagesliste__punkt[data-naechster="ja"] { border-width: 2px; }
.tagesliste__balken::after { background: CanvasText; }
.tagesliste__art { border: 1px solid CanvasText; }
.tagesliste__jetzt::before { background: CanvasText; box-shadow: none; }
/* Im Kontrastmodus gibt es keine gedämpften Töne -- der Haken vor
der Art bleibt das Merkmal für "vorbei". */
.tagesliste__punkt[data-vorbei="ja"] { opacity: 1; }
}
/* ---------- Der Chat-Knopf in der Kopfleiste ----------------------------
Steht auf JEDER Seite (kopf.js), nur nicht auf der Chatseite selbst.
Eine Nachricht, die man erst sieht, wenn man den Chat aufmacht, ist
keine Nachricht -- sie ist ein Fundstück. */
.chat-knopf {
display: inline-flex; align-items: center; gap: 7px;
position: relative;
padding: 7px 13px;
border: 1px solid var(--rand); border-radius: 11px;
background: rgba(255, 255, 255, .04);
color: var(--text-leise); font-size: .85rem; font-weight: 600;
text-decoration: none;
transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.chat-knopf:hover {
color: var(--text);
border-color: var(--rand-hell);
background: rgba(255, 255, 255, .07);
}
.chat-knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.chat-knopf__zeichen {
width: 17px; height: 17px; flex: none;
fill: none; stroke: currentColor; stroke-width: 1.7;
stroke-linejoin: round;
}
/* Wartet etwas, trägt der Knopf selbst Farbe -- nicht nur die Plakette.
Eine kleine Zahl am Rand übersieht man beim Überfliegen. */
.chat-knopf[data-neu="ja"] {
color: var(--akzent);
border-color: color-mix(in srgb, var(--akzent) 42%, transparent);
background: color-mix(in srgb, var(--akzent) 10%, transparent);
}
.chat-knopf__zahl {
min-width: 19px; height: 19px; padding: 0 5px;
display: grid; place-items: center;
border-radius: 999px;
/* 11,84 px -- unter 11,5 meldet die Geräteprüfung zu Recht "zu kleine
Schrift". */
font-size: .74rem; font-weight: 700;
font-variant-numeric: tabular-nums;
color: #0b0f16;
background: var(--akzent);
}
/* Schmale Schirme: nur das Zeichen. Der Text steht weiterhin im
aria-label. Dieselbe Grenze wie bei der Glocke -- eine eigene Zahl
daneben wäre genau die Art Wert, die beim nächsten Mal knapp
danebenliegt. */
@media (max-width: 900px) {
.chat-knopf { padding: 7px 9px; }
.chat-knopf__text { display: none; }
}
@media (prefers-reduced-motion: reduce) { .chat-knopf { transition: none; } }
@media (forced-colors: active) {
.chat-knopf { border: 1px solid CanvasText; }
.chat-knopf[data-neu="ja"] { border-width: 2px; }
.chat-knopf__zahl { border: 1px solid CanvasText; }
}
/* =====================================================================
MATERIAL — die Kacheln werden Gegenstände (07.09.2026)
Wunsch Filipe: "ich will dass alle kacheln viel geiler und spezieller
aussehen, viel realistischer. mach da was hoch profissionelles und
hochwertiges."
---------------------------------------------------------------------
WAS EINE FLÄCHE ZU EINEM GEGENSTAND MACHT
Die Kacheln hatten schon einen Farbverlauf, eine Lichtkante oben und
ein Licht, das dem Zeiger folgt. Trotzdem blieben es Rechtecke mit
Farbe darin. Es fehlten genau die vier Dinge, an denen das Auge einen
echten Gegenstand erkennt -- und keines davon ist "mehr Farbe":
1. GEWICHT. Ein Ding, das auf etwas liegt, wirft einen Schatten,
auch wenn es niemand anfasst. Bisher gab es den nur beim
Überfahren; im Ruhezustand schwebte die Kachel im Nichts.
2. EINE KANTE, DIE DICK IST. Ein Blech hat oben eine Lichtkante
UND unten eine Schattenkante. Nur die obere zu setzen ergibt
einen aufgeklebten Strich; erst beide zusammen ergeben eine
Materialstärke.
3. KÖRNUNG. Der eigentliche Unterschied zwischen "am Rechner
gezeichnet" und "fotografiert". Jede echte Oberfläche hat eine
Struktur; perfekt glatte Farbverläufe kommen in der Natur nicht
vor, und das Auge merkt das, ohne es benennen zu können. Drei
Prozent Rauschen genügen.
4. DURCHSICHT. Hinter den Kacheln liegt jetzt ein aufwendiges Bild.
Eine deckende Fläche darüber verdeckt es; eine mattierte lässt
es durch und nimmt seine Farbe auf. Erst dadurch gehören Kachel
und Hintergrund zusammen, statt übereinanderzuliegen.
---------------------------------------------------------------------
DAS RAUSCHEN KOSTET KEINE DATEI
Es entsteht aus einem SVG-Filter, der als Adresse im Stil steht --
kein Bild, keine zusätzliche Anfrage, keine Lieferkette. Der Browser
rechnet es einmal und legt es über die Fläche.
`mix-blend-mode: overlay` sorgt dafür, dass es hell macht, wo es hell
ist, und dunkel, wo es dunkel ist -- ein aufgelegter grauer Schleier
würde die Farben stattdessen ausbleichen.
---------------------------------------------------------------------
WAS DABEI NICHT PASSIEREN DARF
Der Text muss lesbar bleiben. Mattglas macht ihn nicht automatisch
schlechter (der Weichzeichner nimmt dem Untergrund die Struktur, an
der das Auge hängenbleibt), aber es macht ihn auch nicht automatisch
besser. Deshalb ist jede Zahl hier gegen pruef-buehne gemessen, das
den Kontrast an echten Bildpunkten nachrechnet -- nicht an der
Farbangabe im Stil, die über einem Foto nichts aussagt.
===================================================================== */
/* Das Rauschen. Einmal definiert, von allen Flächen benutzt. */
:root {
--koernung:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='r'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23r)' opacity='0.55'/%3E%3C/svg%3E");
}
/* =====================================================================
ZWEITER ANLAUF: MATTGLAS RAUS (07.09.2026)
Die Kacheln lagen hinter `backdrop-filter: blur(16px)`. Auf einer
Seite mit siebzehn Kacheln heisst das: Der groesste Teil des
Hintergrundbildes ist verwaschen -- man sieht ein unscharfes Bild und
haelt das Bild fuer unscharf. Genau das hat Filipe gemeldet ("sehen
die sogar leicht verschwommen aus"), und ich hatte es selbst
eingebaut, mit der Begruendung, Kachel und Bild sollten
"zusammengehoeren". Sie gehoeren auch zusammen, wenn die Kachel ein
eigener Gegenstand ist; Mattglas war die falsche Antwort auf die
richtige Frage.
Seitdem: deckende Platte mit 6 % Durchsicht, und die SCHARF. Die
Form, die daraus wurde, steht weiter unten unter MODULKARTEN -- der
Entwurf von hier (Querformat mit Schiene links) hat nur einen
Nachmittag gehalten und ist dort vollstaendig ersetzt.
===================================================================== */
/* WAS VON DIESEM ENTWURF BLEIBT (aufgeraeumt 07.09.2026).
Form, Flaeche, Schienenrichtung und Schatten stehen jetzt weiter
unten im Abschnitt MODULKARTEN -- die Kachel ist vom Quer- ins
Hochformat gewandert, und dabei hat sich jede einzelne dieser
Angaben geaendert.
Die alten Regeln hier stehen zu lassen waere doppelt schaedlich
gewesen: Sie kosten Bytes auf jeder Seite (die Datei lief in die
200-KB-Grenze von pruef-struktur), und vor allem waeren es ZWEI
Stellen, an denen dieselbe Kachel beschrieben wird. Genau daran
scheitert der Naechste, der etwas aendert: Er trifft die falsche.
Es bleibt, was der neue Entwurf NICHT selbst setzt. */
.kachel {
backdrop-filter: none;
-webkit-backdrop-filter: none;
border-color: color-mix(in srgb, var(--ton) 18%, rgba(150, 186, 220, .13));
transition: border-color var(--tempo), transform var(--tempo), box-shadow var(--tempo);
}
/* Die Körnung. Sie liegt über der Fläche, aber UNTER dem Inhalt --
Schrift durch ein Rauschen zu lesen wäre anstrengend. */
.kachel > .kachel__link::before {
content: ""; position: absolute; inset: 0; z-index: -1;
background-image: var(--koernung);
background-size: 140px 140px;
opacity: .035;
mix-blend-mode: overlay;
pointer-events: none;
border-radius: inherit;
}
/* DER GLANZ, UND ER WANDERT.
Ein breiter, sehr weicher Lichtstreifen schräg über die Platte -- die
Spiegelung einer Lampe, die ausserhalb des Bildschirms steht. Beim
Überfahren zieht er einmal von links nach rechts durch. Das ist der
Unterschied zwischen einer matten und einer lackierten Oberfläche:
Bei Lack wandert die Spiegelung, wenn man den Kopf bewegt.
Gemacht über `background-position`, nicht über eine zweite Ebene mit
`transform`. Grund: Die Kachel hat `overflow: hidden`; eine
verschobene Ebene müsste breiter sein als die Kachel und würde bei
`border-radius` an den Ecken abgeschnitten aussehen. Die Position
eines Verlaufs lässt sich dagegen sauber weich überblenden.
Die zweite Schicht ist das Licht, das dem Zeiger folgt -- sie bleibt
stehen (`background-size` 100 %), nur der Glanz bewegt sich. */
.kachel::after {
background:
linear-gradient(100deg,
transparent 30%,
rgba(255, 255, 255, .045) 42%,
rgba(255, 255, 255, .11) 49%,
rgba(255, 255, 255, .035) 56%,
transparent 68%),
radial-gradient(120% 150% at var(--mx) var(--my),
color-mix(in srgb, var(--ton) 24%, transparent), transparent 62%);
background-size: 260% 100%, 100% 100%;
background-position: -30% 0, 0 0;
background-repeat: no-repeat;
opacity: .58;
transition: opacity var(--tempo), background-position .55s cubic-bezier(.35, 0, .2, 1);
}
/* Die Leuchtschiene und der wandernde Glanz stehen im Abschnitt
MODULKARTEN weiter unten -- dort liegt die Schiene OBEN statt links,
weil die Kachel hochkant ist. Hier bleibt nur, was der neue Entwurf
nicht selbst setzt: die Grunddeckkraft des Glanzes und seine
Ueberblendung. */
.kachel::after {
opacity: .58;
transition: opacity var(--tempo), background-position .55s cubic-bezier(.35, 0, .2, 1);
}
/* DIE SCHIENE — und sie war nicht da (17.09.2026).
Filipe, mit einem Bildschirmfoto der Community: „das wie es jetzt
ist ist es einfach total scheisse". Beim Nachmessen: Die sieben
Bereiche HABEN klar verschiedene Töne (#cc9451 orange, #668e6e grün,
#cc92c6 rosa, #656a9e blau …) — auf dem Schirm kam davon fast
nichts an.
Der Grund stand direkt daneben. Die Regeln `.kachel:hover::before`
und der Kommentar darüber sprechen ausführlich von einer Schiene,
die „heller wird und weiter in die Platte strahlt" — nur hatte
`.kachel::before` ausser einem Übergang KEINEN Inhalt. Das Element
wurde beim Umbau am 07.09. entfernt, seine Hover-Regeln blieben
stehen. Seither trug den Ton nur noch ein Verlauf, der auf den
obersten 12 % der Platte bei 30 % anfängt und bei 58 % verschwunden
ist — unter einem Bühnenbild reicht das nicht.
Das hier ist deshalb kein neuer Einfall, sondern das Wiedereinsetzen
dessen, womit der Rest der Datei ohnehin rechnet.
AUGENSCHONEND: drei Pixel, oben, nach rechts auslaufend. Ein
durchgezogener Balken wirkt wie ein Etikett, ein auslaufender wie
Licht — dieselbe Überlegung wie bei den Spalten des Aufgabenbretts.
Nicht die Fläche einfärben: Farbe an der Kante unterscheidet,
Farbe auf der Fläche blendet. */
.kachel::before {
content: "";
position: absolute; left: 0; right: 0; top: 0; height: 3px;
z-index: 2; pointer-events: none;
border-radius: 16px 16px 0 0;
opacity: .82;
background: linear-gradient(90deg,
var(--ton),
color-mix(in srgb, var(--ton) 38%, transparent) 58%,
color-mix(in srgb, var(--ton) 6%, transparent) 88%,
transparent);
transition: opacity var(--tempo), width var(--tempo), box-shadow var(--tempo);
}
/* Wer weniger Bewegung will, bekommt sie trotzdem in Farbe -- die
Schiene ist Information, keine Animation. */
@media (prefers-reduced-motion: reduce) {
.kachel::before { transition: none; }
}
/* ANHEBEN STATT AUFLEUCHTEN. Beim Überfahren wird die Kachel nicht
heller, sondern sie kommt näher: Sie steigt zwei Pixel, ihr Schatten
wird größer und weicher (weil der Abstand zum Untergrund wächst) und
die Kante wird kräftiger. Genau so verhält sich ein Gegenstand, den
man anhebt -- und deshalb wirkt es echt, ohne dass etwas blinkt. */
.kachel:hover {
transform: translateY(-3px);
border-color: color-mix(in srgb, var(--ton) 42%, rgba(150, 186, 220, .18));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .14),
inset 0 -1px 0 rgba(0, 0, 0, .45),
inset 3px 0 0 -1px color-mix(in srgb, var(--ton) 52%, transparent),
0 4px 10px -4px rgba(0, 0, 0, .6),
0 24px 48px -24px rgba(0, 0, 0, .9),
0 0 30px -14px color-mix(in srgb, var(--ton) 65%, transparent);
}
/* Die Schiene wird heller und strahlt weiter in die Platte -- nicht
breiter. Ein Balken, der beim Zeigen wächst, sieht nach Menü aus;
eine Lampe, die heller wird, nach Gerät. */
.kachel:hover::before {
opacity: 1;
box-shadow:
0 0 14px 0 color-mix(in srgb, var(--ton) 75%, transparent),
5px 0 34px -3px color-mix(in srgb, var(--ton) 58%, transparent);
}
/* Und der Glanz zieht einmal durch. */
.kachel:hover::after { background-position: 130% 0, 0 0; }
/* Beim Drücken sinkt sie zurück -- ohne diesen Gegenweg fühlt sich ein
Knopf an wie ein Bild von einem Knopf. */
.kachel:active {
transform: translateY(-1px);
transition-duration: .07s;
}
/* Die Plakette bekommt dieselbe Behandlung: Körnung und ein tieferer
Schatten, damit sie auf der Kachel LIEGT statt in sie gemalt zu sein. */
.kachel__zeichen::after {
content: ""; position: absolute; inset: 0;
background-image: var(--koernung);
background-size: 140px 140px;
opacity: .05;
mix-blend-mode: overlay;
pointer-events: none;
}
.kachel:hover .kachel__zeichen {
transform: translateY(-1px) scale(1.03);
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) 16%, transparent);
}
/* Auch die übrigen Flächen der Seite bekommen dasselbe Material --
sonst sähen die Kacheln aus wie aus einer anderen Anwendung als der
Kasten daneben. Eine Oberfläche, in der zwei Materialien nebeneinander
liegen, wirkt zusammengesucht.
HIER STAND EBENFALLS MATTGLAS, und es war derselbe Fehler wie bei den
Kacheln: Sieben weitere Flächen, unter denen das Bild verwischt wird.
Zählt man sie zusammen, war auf der Startseite kaum noch eine Stelle
übrig, an der man das Motiv scharf sah -- und ein Bild, das man nur
noch durch Milchglas kennt, hält man für ein schlechtes Bild. */
.tagesblick,
.zahlkarte,
.zielbalken__zeile,
.tagzeile,
.creator,
.warnkarte,
.summe {
backdrop-filter: none;
-webkit-backdrop-filter: none;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
inset 0 -1px 0 rgba(0, 0, 0, .38),
0 2px 4px -2px rgba(0, 0, 0, .45),
0 12px 26px -18px rgba(0, 0, 0, .8);
}
/* WENIGER BEWEGUNG HEISST: KEINE BEWEGUNG.
Der Glanz, die Körnung und die Schatten bleiben -- die sind Aussehen,
nicht Bewegung. Was wegfällt, ist das Anheben. */
@media (prefers-reduced-motion: reduce) {
.kachel, .kachel:hover, .kachel:active { transform: none; }
.kachel:hover .kachel__zeichen { transform: none; }
/* Der wandernde Glanz ist Bewegung und faellt damit weg. Der Glanz
selbst BLEIBT -- er steht dann fest auf der Platte, wie eine
Spiegelung bei ruhigem Kopf. Ihn ganz abzuschalten waere die
bequeme Auslegung: Wer Bewegung meidet, will kein schlechteres
Aussehen, sondern nur keine Bewegung. */
.kachel::after { transition: opacity var(--tempo); background-position: 42% 0, 0 0; }
.kachel:hover::after { background-position: 42% 0, 0 0; }
}
/* Bei erzwungenen Farben (Windows-Kontrastmodus) sind Mattglas und
Körnung nicht nur wirkungslos, sondern schädlich -- dort zählt
ausschliesslich die Kante. */
@media (forced-colors: active) {
.kachel { backdrop-filter: none; box-shadow: none; border: 1px solid CanvasText; }
.kachel > .kachel__link::before,
.kachel__zeichen::after { display: none; }
}
/* Die Begrüßungskachel mit Uhr und Glocke steht seit dem 07.09.2026 in
einer EIGENEN Datei: assets/css/heim.css.
Grund war eine Grenze, die zu Recht anschlug: start.css lief über
200 KB (pruef-struktur). Die Datei wird von DREIZEHN Seiten geladen --
Uhr, Zifferblatt, Glockenmulde und Begrüßungskachel braucht aber
genau EINE. Zwölf Seiten haben also Regeln heruntergeladen, die sie
nie anwenden.
Aufteilen war deshalb die richtige Antwort und nicht Kürzen: Es macht
start.css kleiner UND spart den anderen Seiten Bytes. Gemessen mit
grep, bevor es verschoben wurde: `class="uhr"`, `willkommen` und
`glocke-platz` kommen in keiner anderen HTML-Datei vor. */
/* =====================================================================
MODULKARTEN — die Kacheln sind ein Raster, keine Liste (07.09.2026)
Aus drei breiten Zeilen wurde ein Raster aus sechs Karten. Eine
breite Zeile zwingt das Auge, siebzehnmal von links nach rechts zu
LESEN; eine kompakte Karte erkennt man an Form und Zeichen -- das
Auge springt, statt zu wandern.
Die SILHOUETTE dieser Karten (Schraege, Kantenlicht, Eckwinkel) steht
im Abschnitt HUD-MODULE am Ende der Datei. Hier steht nur noch, wie
der Inhalt darin angeordnet ist.
NACHGETRAGEN AM 22.09.2026: Hier fehlten die zwei Zeichen, die
diesen Kommentar schliessen. CSS-Kommentare schachteln nicht -- der
Block lief deshalb weiter bis zum naechsten `*` mit Schraegstrich,
und der stand MITTEN IN `.kacheln`. Verschluckt wurde damit die
oeffnende Klammer; die Fehlerbehebung des Browsers hat danach auch
noch die naechste Regel (`.kachel`) mitgenommen, weil sie deren
Rumpf als Block einer ungueltigen Auswahl gelesen hat.
Gemessen in Chromium, beide Fassungen nacheinander: 738 statt 740
Regeln. Sichtbar war es als Kachelreihe mit DREI Spalten zu 413 px
statt fuenf zu 243 px -- die Regel von Zeile 836 sprang ein, und
genau deshalb ist es niemandem aufgefallen: Es sah nicht kaputt
aus, nur anders als gemeint.
===================================================================== */
/* ---------------------------------------------------------------------
UND WARUM HIER TROTZDEM KEINE REGEL MEHR STEHT
---------------------------------------------------------------------
Nach dem Schliessen des Kommentars waren die zwei Regeln wieder da --
und `pruef-kachelfarben` wurde sofort rot:
FEHL mindestens ein Drittel der Rohfarbe kommt an (4.1 %)
FEHL kein Paar sieht auf dem Bildschirm gleich aus
(69 von 465 Paaren unter 0,02)
Der Grund steht oben im Quelltext: Die Flaeche mischte den Kachelton
mit 30 / 11 / 3 Prozent ein und lief bei 58 % in Durchsichtigkeit
aus, darunter eine fast deckende dunkle Platte. Von der Farbe kam
damit fast nichts mehr an, und einunddreissig verschiedene Toene
sahen auf dem Bildschirm gleich aus.
Das ist das Gegenteil dessen, was Filipe am 22.09. verlangt hat:
"ich will dass die farben viel klarer und staerker sind" und "soll
komplett farbig sein und ultra geil aussehen".
DIE REGEL IST ALSO KEIN VERLUST, DEN MAN WIEDERHERSTELLT, SONDERN EIN
ENTWURF VOM 07.09., DEN DIE HEUTIGE GESTALTUNG UEBERHOLT HAT. Weil
sie nie gewirkt hat, ist alles, was seither an den Kacheln gebaut
und gemessen wurde, OHNE sie entstanden -- Flaeche, Schatten und
Rundung kommen laengst aus dem Abschnitt HUD-MODULE am Dateiende.
Sie jetzt nachtraeglich einzuschalten hiesse, zwei Wochen Arbeit an
den Farben zurueckzudrehen, und zwar ohne dass jemand darum gebeten
haette.
Sie einfach stehen zu lassen waere aber genauso falsch gewesen: Dann
staende im Quelltext eine Kachelgestaltung, die es auf dem
Bildschirm nicht gibt -- und der Naechste, der die Kacheln aendert,
trifft die falsche Stelle. Genau davor warnt der Abschnitt weiter
oben ("ZWEI Stellen, an denen dieselbe Kachel beschrieben wird").
Deshalb: geloescht, mit dem Grund daneben.
WAS DAMIT OFFEN BLEIBT -- eine Frage an Filipe, keine Entscheidung
von mir: Zur Regel gehoerte auch ein anderes Raster,
`repeat(auto-fill, minmax(214px, 1fr))` statt der festen drei
Spalten aus Zeile 836. Gemessen sind das fuenf bis sechs schmalere
Kacheln pro Reihe statt drei breiten. Auch das hat nie gewirkt, und
auch das aendert das Aussehen der Startseite spuerbar -- deshalb
bleibt es, wie es ist, bis er es gesehen und entschieden hat.
--------------------------------------------------------------------- */
/* Schiene und Glanz stehen im Abschnitt HUD-MODULE. */
/* ---------- Der Aufbau der Karte ------------------------------------- */
.kachel__link {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0;
padding: 15px 15px 14px;
/* Feste Mindesthöhe, damit alle Karten einer Reihe gleich hoch sind,
auch wenn eine Unterzeile fehlt. Ohne sie entsteht genau der
zerfranste Rand, den "übersichtlich" ausschließt. */
min-height: 152px;
}
.kachel__zeichen {
width: 46px; height: 46px;
margin: 0 0 auto; /* schiebt den Text nach unten */
border-radius: 14px;
}
.kachel__svg { width: 30px; height: 30px; }
.kachel__text {
width: 100%;
margin-top: 14px;
gap: 2px;
}
.kachel__name {
font-size: 1.09rem; font-weight: 700; letter-spacing: -.014em;
/* Zwei Zeilen erlaubt: "Calls & Protokolle" passt in einer Spalte von
214 px nicht in eine Zeile, und ein abgeschnittener Name ist auf
einer Übersichtsseite das Gegenteil von übersichtlich. */
white-space: normal;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
overflow: hidden;
}
.kachel__unter {
font-size: .825rem; line-height: 1.35;
color: var(--text-leise);
white-space: normal;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
overflow: hidden;
}
/* Die Zahl als Marke oben rechts -- neben dem Zeichen, nicht im Text.
Vorher stand sie in derselben Zeile wie der Name und hat ihn gekürzt. */
.kachel__zahl {
position: absolute; top: 13px; right: 13px;
margin: 0; z-index: 2;
min-width: 28px; padding: 4px 9px;
font-size: .84rem;
}
/* Der Pfeil rückt in die untere rechte Ecke: Er ist die leiseste
Angabe der Karte und darf keinem Text im Weg stehen. */
.kachel__pfeil {
position: absolute; right: 14px; bottom: 13px;
margin: 0; z-index: 2;
font-size: .95rem; line-height: 1;
color: color-mix(in srgb, var(--ton) 55%, var(--text-still));
transition: transform var(--tempo), color var(--tempo);
}
.kachel:hover .kachel__pfeil {
transform: translateX(3px);
color: color-mix(in srgb, var(--ton) 80%, #ffffff);
}
/* Das Merk-Zeichen (angepinnt) sitzt links neben der Zahl. */
.kachel__merk { position: absolute; top: 15px; right: 52px; margin: 0; z-index: 2; }
/* Das Wasserzeichen füllt die untere Hälfte -- es ist bei sechs Karten
nebeneinander das, was jede von ihnen unterscheidbar macht. */
/* HIER STAND EINE ZWEITE FASSUNG DES WASSERZEICHENS (entfernt am
09.09.2026, screen1 Punkt 2).
Sie setzte 118 px bei 0,085 Deckkraft -- rund 3600 Zeilen NACH der
sorgfaeltig begruendeten Fassung weiter oben (156 px bei 0,14) und
mit derselben Spezifitaet. Also gewann sie, und die ganze
Begruendung dort oben war wirkungslos. Nachgemessen kam am Ende ein
133 px grosses Zeichen bei 8,5 Prozent heraus, von dem 63 Prozent
sichtbar waren.
Genau dieselbe Sorte Fehler wie beim Wasserzeichen am 08.09. (zwei
Groessenangaben 3600 Zeilen auseinander) -- ich habe damals nur die
eine gefunden. Jetzt gibt es EINE Fassung, und die steht oben. */
/* ---------- Die große Kachel ----------------------------------------- */
/* Sie behält das Querformat von früher. Dadurch hebt sie sich WIRKLICH
ab: nicht "dieselbe Karte, nur breiter", sondern eine andere Form. */
.kachel[data-gross="ja"] {
grid-column: span 2;
}
.kachel[data-gross="ja"] .kachel__link {
flex-direction: row;
align-items: center;
gap: 16px;
padding: 18px 18px 18px 20px;
min-height: 152px;
}
.kachel[data-gross="ja"] .kachel__zeichen {
width: 70px; height: 70px; margin: 0; border-radius: 18px;
}
/* `.kachel__zeichen` DAVOR IST PFLICHT (09.09.2026, screen4).
Ohne diese Einschraenkung trifft die Regel auch das SVG im
WASSERZEICHEN -- beide tragen `kachel__svg`, weil sie aus derselben
Funktion kommen. Sie war staerker als die Regel des Wasserzeichens
und hat dessen Zeichnung auf 39 px festgenagelt, egal wie gross sein
Kasten war. Deshalb hat Filipe dreimal "das symbol soll groesser
sein" gemeldet und mein zweimaliges Vergroessern des Kastens nichts
bewirkt: Ich habe die Verpackung geaendert und nie den Inhalt
gemessen. */
.kachel[data-gross="ja"] .kachel__zeichen .kachel__svg { width: 39px; height: 39px; }
.kachel[data-gross="ja"] .kachel__text { margin-top: 0; }
.kachel[data-gross="ja"] .kachel__name { font-size: 1.22rem; -webkit-line-clamp: 1; }
.kachel[data-gross="ja"] .kachel__unter { font-size: .84rem; -webkit-line-clamp: 1; }
/* HIER STAND EINE ZWEITE GROESSE (158 px) -- und sie hat gewonnen,
ohne dass man es sah (08.09.2026).
Die Regel weiter oben in dieser Datei (Abschnitt "Die grosse Kachel
braucht ein viel groesseres Zeichen") setzt dieselbe Eigenschaft.
Beide Selektoren sind gleich stark, also entscheidet die
Reihenfolge -- und die spaetere ist diese hier. Meine Vergroesserung
oben blieb deshalb wirkungslos: gemessen weiterhin 178 px, obwohl
dort 340 stand.
Gefunden nur durch Nachmessen am laufenden Browser. Im Quelltext
sieht jede der beiden Regeln fuer sich richtig aus; erst die Zahl
auf dem Bildschirm verraet, dass eine davon nie zur Wirkung kommt.
Genau derselbe Fall wie bei `.kopfleiste .marke` weiter oben, wo
`flex` den Schrumpf-Faktor still zurueckgesetzt hat.
Die Groesse steht jetzt nur noch an EINER Stelle (oben). Hier bleibt
allein, was diese Regel wirklich beitraegt: nichts -- deshalb ist sie
weg. */
@media (max-width: 560px) {
/* Auf dem Handy zwei Spalten. Eine einzige wäre wieder eine Liste --
und genau davon kommen wir gerade weg. Zwei Karten je Reihe passen
bei 390 px (2 x 172 + 12), und der Name bleibt zweizeilig lesbar. */
.kacheln { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.kachel__link { min-height: 138px; padding: 13px 13px 12px; }
.kachel[data-gross="ja"] { grid-column: span 2; }
.kachel[data-gross="ja"] .kachel__link { flex-direction: row; min-height: 96px; }
.kachel[data-gross="ja"] .kachel__zeichen { width: 48px; height: 48px; }
.kachel__zeichen { width: 40px; height: 40px; border-radius: 12px; }
.kachel__svg { width: 22px; height: 22px; }
.kachel__name { font-size: .93rem; }
.kachel__unter { font-size: .72rem; }
.kachel__wasserzeichen { width: 96px; height: 96px; }
}
/* ---------- Die Glocke, wenn sie in der Kachel sitzt ------------------ */
/* In der Leiste ist sie ein Knopf unter Knöpfen. Hier steht sie allein
neben der Uhr und wird deshalb rund -- sie nimmt die Form ihrer
Nachbarin auf, statt als Rechteck danebenzustehen. */
/* Sie bekommt dieselbe Bauart wie die Uhr daneben: ein Metallrand
aussen, eine vertiefte Scheibe darin. Zwei runde Dinge nebeneinander,
die aus verschiedenem Material sind, sehen zusammengesucht aus --
dasselbe Material macht daraus ein Paar. Kleiner als die Uhr, weil
sie die Nebensache ist. */
.glocke--kachel {
position: relative;
width: 48px; height: 48px; padding: 3px;
border-radius: 50%;
justify-content: center;
border: 0;
background:
linear-gradient(150deg,
rgba(255, 255, 255, .16) 0%,
rgba(255, 120, 132, .13) 28%,
rgba(8, 12, 20, .9) 54%,
rgba(143, 216, 255, .13) 80%,
rgba(255, 255, 255, .08) 100%);
box-shadow:
-2px -2px 16px -11px rgba(255, 95, 109, .5),
2px 2px 16px -11px rgba(143, 216, 255, .5),
0 8px 20px -12px rgba(0, 0, 0, .9);
transition: transform var(--tempo), box-shadow var(--tempo);
}
.glocke--kachel::before {
content: ""; position: absolute; inset: 3px; border-radius: 50%;
background:
radial-gradient(circle at 50% 28%, rgba(255, 255, 255, .05), transparent 58%),
radial-gradient(circle at 50% 50%, #0c121e 58%, #05080e 100%);
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .95),
inset 0 1px 0 rgba(255, 255, 255, .10);
}
/* Beim Zeigen hebt sie sich einen Pixel und ihr Schein wird kraeftiger
-- dieselbe Sprache wie ueberall: naeherkommen statt aufleuchten. */
.glocke--kachel:hover {
transform: translateY(-1px);
box-shadow:
-3px -3px 20px -9px rgba(255, 95, 109, .7),
3px 3px 20px -9px rgba(143, 216, 255, .7),
0 10px 24px -12px rgba(0, 0, 0, .95);
}
.glocke--kachel .glocke__zeichen { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
.glocke--kachel, .glocke--kachel:hover { transform: none; }
}
.glocke--kachel .glocke__text {
/* Der Text bleibt für Vorleseprogramme da, verschwindet aber vom
Bildschirm: Neben einer Uhr ist Platz für ein Zeichen, nicht für
eine Beschriftung. */
position: absolute;
width: 1px; height: 1px; margin: -1px; padding: 0;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.glocke--kachel .glocke__zeichen { width: 20px; height: 20px; }
/* =====================================================================
DER TAGESRUF -- der Wecker fuer offene Aufgaben (screen10)
Filipe: "ich will das neben diesem kreis auch ein kleiner button ist
fuer den wecker von den aufgaben."
ER SIEHT AUS WIE DIE GLOCKE, ABER NICHT GLEICH. Gleiche Groesse,
gleiche Fassung, gleiche Bewegung beim Zeigen -- damit man sieht,
dass die beiden zusammengehoeren. Verschiedenes Zeichen (Wecker
statt Glocke) und, wenn er an ist, ein anderer Ton -- damit man
sieht, dass sie nicht dasselbe tun. Zwei gleich aussehende Knoepfe
nebeneinander sind zwei Knoepfe, von denen man einen falsch
drueckt.
ER STEHT IN start.css, NICHT IN heim.css -- und das ist kein Zufall.
`glocke.js` laeuft auf allen 18 Seiten und baut die Zeichen dort;
heim.css laedt nur die Startseite. Die Klassen waeren damit auf 17
Seiten benutzt und auf keiner davon gestaltet. pruef-css-klassen hat
genau das gemeldet ("gestaltet, aber nicht auf ihrer Seite"), und es
war kein Fehlalarm: Wo der Platz doch einmal woanders auftaucht,
staende ein nackter Knopf. `.glocke--kachel` steht aus demselben
Grund schon hier.
DIE SCHRIFTGROESSEN SIND 12 px, NICHT 10 UND 11. Auch das kam aus
der Pruefung: 45 Stellen unter 11,5 px statt der 43 im Bestand --
die beiden neuen waren meine. Eine Grundlinie, die man beim
Hinzufuegen still ueberschreitet, ist keine.
================================================================== */
.tagesruf {
position: relative;
width: 48px; height: 48px; padding: 3px;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
border: 0; cursor: pointer;
color: #cfe0f2;
background:
linear-gradient(150deg,
rgba(255, 255, 255, .16) 0%,
rgba(255, 120, 132, .13) 28%,
rgba(8, 12, 20, .9) 54%,
rgba(143, 216, 255, .13) 80%,
rgba(255, 255, 255, .08) 100%);
box-shadow:
-2px -2px 16px -11px rgba(255, 95, 109, .5),
2px 2px 16px -11px rgba(143, 216, 255, .5),
0 8px 20px -12px rgba(0, 0, 0, .9);
transition: transform var(--tempo), box-shadow var(--tempo), color var(--tempo);
}
.tagesruf::before {
content: ""; position: absolute; inset: 3px; border-radius: 50%;
background:
radial-gradient(circle at 50% 28%, rgba(255, 255, 255, .05), transparent 58%),
radial-gradient(circle at 50% 50%, #0c121e 58%, #05080e 100%);
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .95),
inset 0 1px 0 rgba(255, 255, 255, .10);
}
.tagesruf:hover:not(:disabled) {
transform: translateY(-1px);
box-shadow:
-3px -3px 20px -9px rgba(255, 95, 109, .7),
3px 3px 20px -9px rgba(143, 216, 255, .7),
0 10px 24px -12px rgba(0, 0, 0, .95);
}
.tagesruf:disabled { opacity: .4; cursor: not-allowed; }
.tagesruf__zeichen {
position: relative; z-index: 1;
width: 21px; height: 21px;
fill: none; stroke: currentColor;
stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
/* EINGESCHALTET: babyblau, nicht rot. Rot heisst in diesem Haus
"ueberfaellig" -- ein roter Wecker saehe aus wie eine Warnung,
dabei ist er eine Einstellung, die man selbst getroffen hat. */
.tagesruf[data-an="ja"] { color: #9fdcff; }
.tagesruf[data-an="ja"]::before {
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .95),
inset 0 1px 0 rgba(255, 255, 255, .10),
inset 0 0 12px -2px rgba(143, 216, 255, .35);
}
/* Der Text ist fuer Vorleseprogramme da, nicht fuer den Bildschirm --
neben einer Uhr ist Platz fuer ein Zeichen, nicht fuer eine
Beschriftung. Gleiche Loesung wie bei der Glocke. */
.tagesruf__text {
position: absolute;
width: 1px; height: 1px; margin: -1px; padding: 0;
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
.tagesruf, .tagesruf:hover { transform: none; }
}
/* DAS ZEITFELD SCHWEBT, ES SCHIEBT NICHT.
Es erscheint und verschwindet mit dem Schalter. Stuende es im
normalen Fluss, wuechse der Platz beim Einschalten um 40 px und die
ganze Kachelreihe darunter rutschte -- derselbe Sprung, gegen den
`.glocke-platz` oben eine feste Hoehe hat. Absolut gesetzt kostet es
keinen Platz und keine Bewegung.
NACH LINKS, NICHT NACH UNTEN: Unter dem Knopf endet die Kachel.
Links davon liegt die Luecke zwischen Text und Uhr -- dort ist Raum,
und das Feld verdeckt nichts. */
.tagesruf__feld {
position: absolute; top: 58px; right: 56px;
z-index: 6;
display: flex; flex-direction: column; gap: 3px;
padding: 7px 9px;
border-radius: 10px;
background: rgba(8, 12, 20, .96);
border: 1px solid rgba(143, 216, 255, .28);
box-shadow: 0 10px 24px -12px rgba(0, 0, 0, .95);
}
.tagesruf__feld[hidden] { display: none; }
.tagesruf__feld-schild {
font-size: .75rem; letter-spacing: .08em; text-transform: uppercase;
color: #8fa6bd;
}
.tagesruf__zeit {
font: inherit; font-size: .82rem;
color: #e8f1fa; background: rgba(255, 255, 255, .06);
border: 1px solid rgba(255, 255, 255, .14); border-radius: 6px;
padding: 3px 5px;
/* Ohne das zeichnet Chrome das Feld hell -- weisses Kaestchen in
einer dunklen Kachel. */
color-scheme: dark;
}
/* ---------- Die Uhr --------------------------------------------------
ROT x BABYBLAU (07.09.2026, zweiter Entwurf).
Filipe: "die uhr rechts soll auch viel viel viel viel viel viel viel
spezieller noch sein und soll eine mischung von rot und babyblau
haben."
WAS EINE UHR TEUER AUSSEHEN LAESST, IST NICHT DIE FARBE, SONDERN DAS
GEHAEUSE. Bei einer echten Uhr sieht man drei Dinge übereinander:
einen METALLRAND, der das Licht von oben fängt; eine VERTIEFTE
Scheibe darin; und ein GLAS darüber, das spiegelt. Genau diese drei
Schichten sind hier gebaut -- und sie sind der Grund, warum das Ding
jetzt wie ein Gegenstand aussieht und nicht wie ein Kreis mit Zahlen.
Die Farben kommen aus dem Haus, nicht aus dem Farbkasten: Rot ist
Spicy Media, Babyblau ist DogFather. Dieselben zwei stehen im Kopf
der Anmeldekarte nebeneinander und bilden im Motiv den Neonrahmen.
Beide Verlaeufe stehen im SVG (siehe start.html) und laufen
GEGENEINANDER -- der Stundenring rot -> blau, der Sekundenring blau
-> rot. Wo der eine warm ist, ist der andere kuehl; so bleiben sie
auseinanderzuhalten, wo sie sich ueberlagern.
-------------------------------------------------------------------- */
/* =====================================================================
DIE UHR — ein Instrument, keine Anzeige (07.09.2026, zweiter Anlauf)
Filipe: "AUCH MIT DER UHR RECHTS; DAS IST VIEL ZU EINFACH; ICH WILL
SIE NOCH VIEEEEEEL KRASSER; WIE IN DER BUISNESS HUB SEITE VON VANVAN,
WIE DIE UHR BEI IHR ABER NOCH KRASSER UND SPEZIELLER."
NACHGESEHEN, NICHT GERATEN. Auf VanVans Business-Hub gibt es keine
Uhr -- gemeint ist das `gate-medaillon` auf der Anmeldeseite: ein
runder Kegelverlauf, der wie gebuerstetes Metall aussieht, gefasst in
zwei eingelassenen Ringen. Genau diese Bauart steht jetzt hier, in
drei Punkten weitergetrieben:
1. FASSUNG STATT RAND. Der Kegelverlauf laeuft rundherum durch
hell/dunkel/hell -- deshalb sieht die Fassung gedreht aus und
nicht bemalt. Sie ist 5 px breit statt 3; darunter liegt ein
zweiter, dunkler Ring, der sie einlaesst.
2. AUFGESETZTE STUNDENMARKEN. Zwoelf kraeftige Striche aus einem
einzigen sich wiederholenden Kegelverlauf, dazu sechzig feine.
Sechzig Elemente im HTML waeren dieselbe Optik mit sechzig
Elementen mehr im Baum.
3. GLASKUPPE. Eine Spiegelung von oben links plus ein heller Bogen
an der Oberkante. Ohne den Bogen wirkt jede runde Flaeche flach.
UND SIE IST GROESSER: 164 statt 124 px. Das ist kein Detail --
"krasser" heisst bei einem Instrument zuerst "lesbar". Auf dem Handy
bleibt sie bei 118 px, dort steht sie unter dem Text statt daneben.
===================================================================== */
/* DIE GROESSE STEHT NICHT MEHR HIER (09.09.2026).
Hier standen `width: 164px; height: 164px` -- und in heim.css stand
der Ring daneben auf 232. Zwei Dateien, zwei Zahlen, und keine
Stelle, an der jemand beide zugleich sieht. Filipe wollte sie gleich
gross; jetzt entscheidet `--instrument` in heim.css ueber BEIDE.
Wer die Uhr groesser machen will, aendert dort eine Zahl -- nicht
hier. Eine zweite Angabe an dieser Stelle waere wirkungslos (heim.css
laedt spaeter) und wuerde trotzdem richtig aussehen. */
.uhr {
position: relative;
flex: none;
display: grid; place-items: center;
border-radius: 50%;
padding: 10px;
/* SCHICHT 1: DIE LUENETTE. Zehn Pixel breit und DECKEND.
Halbdurchsichtig war der Fehler des ersten Anlaufs: Metall, durch
das der Hintergrund scheint, sieht nicht nach Metall aus, sondern
nach grauem Glas -- im Bildschirmfoto gemessen, es las sich als
flacher grauer Ring. Echtes Metall ist undurchsichtig; sein
Aussehen entsteht allein daraus, WIE es das Licht zurueckwirft.
Deshalb hier volle Farben und ein harter Wechsel hell/dunkel. */
background:
conic-gradient(from 208deg,
#eaf2fb 0deg,
#8fa3bd 26deg,
#f6fbff 52deg,
#6f8299 84deg,
#dfe9f5 116deg,
#ff8a94 150deg,
#f4f9ff 176deg,
#5d6f87 214deg,
#e6eff9 246deg,
#8fd8ff 282deg,
#f8fcff 312deg,
#7c8ea6 340deg,
#eaf2fb 360deg);
box-shadow:
/* Der zweifarbige Schein nach aussen, weit unter der Blendschwelle. */
-4px -4px 26px -13px rgba(255, 95, 109, .6),
4px 4px 26px -13px rgba(143, 216, 255, .6),
0 14px 30px -14px rgba(0, 0, 0, .95),
/* DIE MULDE. Zwei Ringe aus Schatten mit Ausdehnung: aussen die
Fraesung selbst (dunkel, 11 px breit), darauf eine haarfeine
helle Kante -- dort trifft das Licht die gegenueberliegende Wand
der Vertiefung. Zusammen macht das aus "davor" ein "darin", und
zwar konzentrisch bei jeder Groesse. */
0 0 0 11px rgba(0, 0, 0, .5),
0 0 0 12px rgba(190, 208, 230, .12),
0 6px 14px 6px rgba(0, 0, 0, .45),
/* Und der dunkle Ring, der die Fassung einlaesst -- ohne ihn liegt
sie auf dem Zifferblatt statt darin. */
inset 0 0 0 1px rgba(6, 10, 18, .85);
}
/* SCHICHT 2: die vertiefte Scheibe. */
.uhr::before {
content: ""; position: absolute; inset: 10px; border-radius: 50%;
/* DAS GUILLOCHIERTE ZIFFERBLATT.
Guillochieren ist das Verfahren, mit dem seit zweihundert Jahren
hochwertige Zifferblaetter gemacht werden: Eine Maschine schneidet
ein feines, regelmaessiges Muster in das Metall, und weil jede
Rille das Licht in einem anderen Winkel zurueckwirft, LEBT die
Flaeche, wenn man den Kopf bewegt. Es ist der Unterschied zwischen
einem lackierten und einem bearbeiteten Blatt -- und der Grund,
warum ein teures Zifferblatt teuer AUSSIEHT, ohne dass eine
einzige Farbe daran teuer waere.
Hier aus zwei Ebenen: STRAHLEN vom Mittelpunkt (der Kegelverlauf,
240 Rillen) und RINGE um den Mittelpunkt (der wiederholte
Radialverlauf, alle 3 px). Beide extrem leise -- bei 4 Prozent
Deckkraft sieht man kein Muster, man sieht eine Oberflaeche. Wer
sie einzeln erkennt, hat sie zu laut gemacht.
`closest-side`, damit die Ringe im Radius rechnen und nicht in der
weitesten Ecke -- derselbe Fehler, der heute die Skala unsichtbar
gemacht hat. */
background:
repeating-conic-gradient(from 0deg,
rgba(255, 255, 255, .045) 0deg 0.75deg,
rgba(0, 0, 0, .05) 0.75deg 1.5deg),
repeating-radial-gradient(circle closest-side at 50% 50%,
rgba(255, 255, 255, .035) 0 1px,
rgba(0, 0, 0, .045) 1px 3px),
radial-gradient(circle at 50% 26%, rgba(255, 255, 255, .06), transparent 56%),
radial-gradient(circle at 50% 50%, #0c121e 56%, #04070d 100%);
box-shadow:
inset 0 2px 7px -2px rgba(0, 0, 0, .95),
inset 0 0 0 1px rgba(190, 205, 225, .16),
inset 0 -1px 0 rgba(255, 255, 255, .05);
}
/* DIE SKALA LIEGT AUF DER LUENETTE, NICHT AUF DEM ZIFFERBLATT.
Im ersten Anlauf lag sie bei 90 bis 99 Prozent des Radius -- und
genau dort laeuft der Sekundenring. Sie war vollstaendig verdeckt,
und zwar so, dass man es nicht merkt: Eine unsichtbare Skala sieht
aus wie gar keine, nicht wie ein Fehler. Im Bildschirmfoto gesehen,
nicht im Kopf ausgerechnet.
Jetzt sitzt sie dort, wo sie bei einer echten Uhr sitzt: eingraviert
in den Metallring. Deshalb sind die Striche DUNKEL -- eine Gravur ist
eine Vertiefung, in der Schatten steht, kein aufgemalter heller
Strich. Zwoelf kraeftige fuer die Stunden, sechzig feine dazwischen,
beide aus je EINEM sich wiederholenden Kegelverlauf. */
.uhr__skala {
position: absolute; inset: 0; border-radius: 50%;
/* NUR die zwoelf Stundenmarken -- lang und kraeftig. Die sechzig
feinen Minutenstriche liegen auf einer eigenen Ebene (.uhr::after),
weil sie eine ANDERE Laenge brauchen: Auf einer echten Luenette
reichen Stundenmarken durch den ganzen Ring, Minutenstriche nur
ein Stueck vom Rand herein. Zwei Laengen heissen zwei Masken, und
zwei Masken heissen zwei Ebenen -- eine Ebene kann nur eine haben.
Beim ersten Anlauf lagen beide hier, gleich lang: Aus der Skala
wurde ein Zahnkranz. Im Bildschirmfoto gesehen. */
background:
/* AUFGESETZTE INDIZES bei 3, 6 und 9 Uhr. Auf einer guten Luenette
sind die Viertelstunden keine Striche wie die anderen, sondern
eigene Marken -- breiter und HELL statt graviert, weil sie
aufgesetzt sind und deshalb Licht fangen statt Schatten zu
halten. Ein Kegelverlauf mit 90-Grad-Takt, um 90 Grad gedreht:
So trifft er 3, 6 und 9 und laesst die 12 der roten Marke. */
repeating-conic-gradient(from 88.6deg,
rgba(244, 250, 255, .92) 0deg 2.8deg,
transparent 2.8deg 90deg),
repeating-conic-gradient(from 0deg,
rgba(6, 10, 18, .85) 0deg 1.5deg,
transparent 1.5deg 30deg);
/* `closest-side` IST HIER PFLICHT, NICHT GESCHMACK.
Ohne Angabe rechnet ein `radial-gradient` seine Prozente auf die
WEITESTE ECKE des Kastens -- bei 164 px Kantenlaenge sind das
116 px, nicht die 82 px des Radius. "89 % bis 99,5 %" lag damit
bei 103 bis 115 px und komplett AUSSERHALB der runden Uhr: Die
Skala war unsichtbar, und zwar seit es sie gibt. Eine unsichtbare
Verzierung sieht aus wie gar keine, nicht wie ein Fehler -- genau
deshalb ist sie nie aufgefallen.
Mit `closest-side` sind 100 % der Radius, und die Prozente
bedeuten das, wonach sie aussehen. */
-webkit-mask: radial-gradient(circle closest-side, transparent 0 88%, #000 88% 99.5%, transparent 99.5%);
mask: radial-gradient(circle closest-side, transparent 0 88%, #000 88% 99.5%, transparent 99.5%);
pointer-events: none; z-index: 4;
}
/* Die sechzig feinen Minutenstriche -- kurz, vom Aussenrand herein,
und deutlich leiser als die Stundenmarken. Das Verhaeltnis der beiden
ist der ganze Unterschied zwischen "Skala" und "Zahnkranz". */
.uhr::after {
content: ""; position: absolute; inset: 0; border-radius: 50%;
z-index: 4; pointer-events: none;
background:
repeating-conic-gradient(from 0deg,
rgba(6, 10, 18, .42) 0deg 0.4deg,
transparent 0.4deg 6deg);
-webkit-mask: radial-gradient(circle closest-side, transparent 0 94%, #000 94% 99.5%, transparent 99.5%);
mask: radial-gradient(circle closest-side, transparent 0 94%, #000 94% 99.5%, transparent 99.5%);
}
/* DER AUFGESETZTE ZWOELF-INDEX. Ein Keil in Hausrot mit heller
Oberkante, gesetzt auf die Luenette. Er beantwortet die Frage "wo ist
oben" ohne eine einzige Ziffer -- und er ist der einzige farbige
Punkt auf dem Metall, also auch der Blickfang. */
.uhr__zwoelf {
position: absolute; top: 3px; left: 50%;
width: 7px; height: 13px; margin-left: -3.5px;
z-index: 5; pointer-events: none;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
background: linear-gradient(180deg, #ffd9dc 0%, #ff5f6d 34%, #b3323e 100%);
filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .8));
}
/* DIE PERLE. Ein Kasten in voller Groesse, der sich dreht -- die Perle
selbst sitzt oben auf dem Radius des Sekundenbogens. So braucht die
Drehung keine Rechnung mit Winkelfunktionen: Der Kasten dreht sich,
die Perle wird mitgenommen. */
/* DER ABSTAND FOLGT DER BAHN, DIE FARBE FOLGT DER BAHN -- und beides
muss beim Farbtausch mitgehen. Am 08.09.2026 habe ich genau das
vergessen: Die drei BOEGEN waren getauscht (Stunde rot, Minute
silber, Sekunde babyblau), die drei KOEPFE trugen weiter die alte
Zuordnung. Im Bildschirmfoto sass dadurch ein roter Kopf auf der
blauen Sekundenreihe und ein silberner auf den roten Stundenbalken
-- es sah nach einem Rechenfehler bei den Winkeln aus, obwohl alle
drei auf die Zehntelgrad genau standen (354 / 161,9 / 343,0 bei
23:26:59, nachgemessen). Wer eine Farbe tauscht, tauscht sie an
ALLEN Stellen, die sie tragen -- Bogen, Kopf, Schein, Kranz. */
/* AUSSEN, BABYBLAU: der Kopf der Sekundenpunkte. Am groessten, weil er
der einzige ist, der sich sichtbar bewegt. */
/* MITTE, SILBER: der Kopf der Minutenbalken. Poliertes Metall, kein
Licht -- er ist der Bezug, an dem man die anderen beiden misst. */
/* INNEN, ROT: der Kopf der Stundenbalken. Der kleinste Punkt in der
kraeftigsten Farbe -- er bewegt sich am wenigsten und darf deshalb
auffallen, ohne zu stoeren. */
@media (prefers-reduced-motion: reduce) {
/* Kein Nachfedern -- der Sprung bleibt, das Schwingen geht. */
}
@media (forced-colors: active) {
.uhr__schatten, .uhr__kante { display: none; }
}
/* SCHICHT 3: DAS GLAS -- ENTSPIEGELTES SAPHIRGLAS (07.09.2026)
Nachgelesen statt geraten. Eine Entspiegelung (Anti-Reflex) wird im
Vakuum aufgedampft und senkt die Spiegelung auf unter ein Prozent;
das Zifferblatt wirkt dadurch SCHAERFER, nicht milchiger. Und das
Erkennungszeichen einer guten Beschichtung ist kein weisser Schleier,
sondern ein **topasblauer Schimmer**, der je nach Lichteinfall ueber
das Glas laeuft -- daran sieht ein Kenner sofort, dass da Saphirglas
sitzt und kein Mineralglas.
Vorher lag hier genau das Gegenteil: ein breiter weisser Verlauf
ueber ein Fuenftel der Scheibe. Das ist die Spiegelung eines
UNBESCHICHTETEN Glases -- also ausgerechnet das Merkmal des
billigeren Materials.
Jetzt drei Dinge, jedes davon aus der Sache begruendet:
1. ein SCHMALER, harter Reflexbogen oben links -- die Kante der
Woelbung, das Einzige, was auch entspiegelt stehen bleibt
2. der topasblaue Schimmer, diagonal, sehr leise
3. die haarfeine helle Linie an der Oberkante -- die Schnittkante
des Glases selbst
Quellen zur Beschichtung: reservoir-watch.com und botta-design.de
(siehe Antwort im Verlauf). */
.uhr__glas {
position: absolute; inset: 10px; border-radius: 50%;
background:
linear-gradient(142deg,
rgba(255, 255, 255, .16) 0%,
rgba(255, 255, 255, .05) 7%,
transparent 15%),
linear-gradient(128deg,
transparent 30%,
rgba(120, 190, 255, .10) 44%,
rgba(150, 130, 255, .07) 52%,
transparent 64%);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22);
pointer-events: none; z-index: 3;
}
.uhr__ring {
position: absolute; inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px);
/* Bei Null soll der Ring OBEN beginnen, nicht rechts. */
transform: rotate(-90deg);
z-index: 2;
overflow: visible;
}
/* DREI RINGE, ALLE SCHARF (07.09.2026).
Filipe: "die minuten blau, [die stunden] schwarzsilber glaenzend und
die sekunden rot ... soll null unscharf sein, sehr schoen praezise."
KEIN blur(), KEIN drop-shadow auf den Boegen. Ein Weichzeichner auf
einer Linie macht sie nicht edler, sondern unscharf -- genau das war
der Vorwurf, und er stimmte: An der alten Uhr lag ein blur(1.2px) auf
dem Schein und ein drop-shadow auf dem Sekundenbogen.
Der GLANZ entsteht stattdessen aus dem Verlauf selbst. Echtes Metall
glaenzt nicht, weil es leuchtet, sondern weil es das Licht an
verschiedenen Stellen verschieden zurueckwirft: hell, dunkel, hell,
dunkel. Genau das machen die fuenf Stopps des Silberverlaufs im SVG.
Ein zweifarbiger Verlauf waere ein Farbverlauf; erst der Wechsel ist
Metall.
Die Kappen sind BUTT und nicht rund. Eine runde Kappe steht ueber das
Ende hinaus -- bei "null Sekunden" saehe man dann trotzdem einen
Punkt, und die Anzeige waere um zwei Grad falsch. Praezise heisst
auch: nichts anzeigen, wo nichts ist. */
.uhr__bahn, .uhr__stunde, .uhr__minute, .uhr__sekunde {
fill: none;
stroke-linecap: butt;
}
/* DIE BAHN IST EINE GEFRAESTE RILLE, kein blasser Kreis.
Ein Zeiger laeuft bei einem guten Instrument IN einer Vertiefung,
nicht auf einer Flaeche. Eine Rille erkennt man an zweierlei: Sie ist
dunkler als ihre Umgebung, und an ihrer unteren Wand steht eine helle
Kante, wo das Licht von oben auftrifft. Beides steht hier -- die
Kante als zweiter, um ein Drittel nach unten versetzter Kreis.
Die Breite folgt dem Ring, der darin laeuft: aussen 3,4 fuer die
Sekunde, in der Mitte 3,8, innen 4,4. Eine Rille, die schmaler ist
als ihr Zeiger, ist keine. */
.uhr__bahn { stroke: rgba(4, 7, 13, .78); stroke-width: 4.4; }
.uhr__bahn:nth-of-type(1) { stroke-width: 3.6; }
.uhr__bahn:nth-of-type(2) { stroke-width: 4; }
.uhr__rillenkante circle {
fill: none;
stroke: rgba(190, 215, 245, .16);
stroke-width: 1;
}
/* AUSSEN: die SEKUNDE in Rot, auf der laengsten Bahn (07.09.2026
gedreht, Wunsch Filipe: "die minuten in der mitte und sekunden
aussen").
Das ist die Anordnung eines Chronographen und nicht die eines
Fortschrittsbalkens: Der schnellste Zeiger laeuft aussen, weil man
Bewegung dort am besten sieht -- und der langsamste innen, wo eine
kleine Drehung schon viel bedeutet.
DIE ZAHLEN GEHOEREN ZUM RADIUS. Ein vertauschter Ring ohne
vertauschte Umfaenge sieht aus wie eine haengende Uhr: Der Bogen
endet dann nie dort, wo er soll. U = 2 * pi * r, ausgerechnet und
nicht geschaetzt. */
/* DIE BREITEN STEHEN NICHT HIER, SONDERN IM ABSCHNITT "Der Ring wird
dunkel" WEITER UNTEN (Sekunde 3,2 / Minute 5 / Stunde 5,8).
Bis zum 09.09.2026 standen an dieser Stelle noch 2,6 / 3 / 3,6 --
Werte, die seit dem Umbau vom selben Tag nie mehr gezeichnet wurden,
weil die spaeteren Regeln bei gleicher Spezifitaet gewinnen. Sie sind
entfernt statt korrigiert: Zwei Zahlen fuer dieselbe Sache sind der
Fehler, nicht die falsche von beiden. Wer die Breite aendert, aendert
sie unten -- und muss dann auch den Kantenversatz oben nachziehen. */
.uhr__sekunde {
stroke: url(#uhr-sekunde-farbe);
stroke-dasharray: 285.88; /* r = 45.5 */
stroke-dashoffset: 285.88;
}
/* MITTE: die MINUTE in Schwarzsilber -- der ruhige Bezug zwischen
den beiden farbigen Bahnen. */
.uhr__minute {
stroke: url(#uhr-minute-farbe);
stroke-dasharray: 241.90; /* r = 38.5 */
stroke-dashoffset: 241.90;
}
/* INNEN: die STUNDE in Rot. Am breitesten und am ruhigsten --
sie bewegt sich in fuenf Minuten um ein halbes Grad. */
.uhr__stunde {
stroke: url(#uhr-stunde-farbe);
stroke-dasharray: 197.92; /* r = 31.5 */
stroke-dashoffset: 197.92;
}
/* DER SCHLAGSCHATTEN JEDES BOGENS. Dieselbe Bahn, schwarz, ein wenig
breiter -- und um ein halbes Rastermass nach unten geschoben (im
HTML). Er macht aus einem aufgemalten Strich einen Koerper, der
ueber dem Zifferblatt liegt. */
.uhr__schatten circle {
stroke: rgba(0, 0, 0, .62) !important;
stroke-width: 4.6;
}
.uhr__schatten .uhr__sekunde { stroke-width: 3.8; }
/* DIE BELEUCHTETE OBERKANTE. Duenner, hell, nach oben versetzt: Sie
schaut oben hervor und verschwindet unten -- genau das tut eine
gewoelbte Kante bei Licht von oben. Das ist der ganze Unterschied
zwischen einem Strich und einem Ring aus Material. */
.uhr__kante circle {
/* NICHT MEHR EINE FESTE FARBE, SONDERN EIN VERLAUF.
Eine gleichmaessig helle Kante rings um den Ring ist kein Licht,
sondern ein aufgemalter Rand -- und an den Seiten war sie sogar ein
Strich MITTEN DURCH den Balken (siehe die Begruendung am Verlauf in
start.html). Der Verlauf blendet sie zu den Seiten hin aus. */
stroke: url(#uhr-kante-licht) !important;
stroke-width: .9;
}
/* DIE KANTE DER STUNDE IST EIN HAUCH, KEIN STRICH (09.09.2026,
screen2 -- "die stunden muss noch perfektionnieren").
Sie stand auf 50 Prozent Weiss bei 0,9 Breite. Auf den schmalen
Sekunden- und Minutenbahnen ist das eine Lichtkante; auf dem 5,8 px
breiten Stundenbalken war es ein zweiter, weisser Balken auf dem
roten -- im vergroesserten Bildschirmfoto sieht es aus wie ein
Kratzer quer durch das Material.
Der Grund ist Verhaeltnis, nicht Farbe: 0,9 von 3,2 (Sekunde) sind
28 Prozent der Breite, 0,9 von 5,8 waeren 16 -- aber die Stunde ist
auch die einzige DECKENDE, kraeftig gefaerbte Bahn. Auf Rot faellt
dasselbe Weiss doppelt so stark auf wie auf Silber.
Jetzt 22 Prozent. Die Kante ist noch da (sie macht aus der Flaeche
ein Werkstueck), aber sie ist wieder eine Kante. */
/* Die Stunde bekommt denselben Verlauf, nur schwaecher -- ueber die
Deckkraft des ganzen Elements statt ueber eine zweite Farbe. Zwei
Verlaeufe fuer dasselbe Licht waeren zwei Sachen zum Pflegen. */
.uhr__kante .uhr__stunde { opacity: .34; }
/* Und schmaler: 0,6 statt 0,9 -- auf dem breitesten Balken darf die
Kante nicht die breiteste sein. */
.uhr__kante .uhr__stunde { stroke-width: .6; }
/* DER VERSATZ MUSS DER BREITE FOLGEN (09.09.2026, screen5).
Die Kantenlage liegt als Gruppe 0,4 Einheiten hoeher als die Bahn
darunter. Das war richtig, solange alle drei Baender aehnlich schmal
waren. Inzwischen sind sie 3,2 / 5 / 5,8 breit -- und ein 0,9
breiter Lichtstrich, der nur 0,4 versetzt ist, liegt auf einem
5,8er Balken nicht auf der KANTE, sondern MITTEN DRIN. Im
Bildschirmfoto lief ein heller Streifen quer durch jeden roten
Stundenbalken; das war der Rest, den Filipe an den Stunden gestoert
hat.
Damit der Strich die Kante gerade noch streift, muss er um
(Bandbreite - Strichbreite) / 2 versetzt sein. Die Gruppe bringt
davon schon 0,4 mit, der Rest kommt hier:
Sekunde (3,2 - 0,9) / 2 = 1,15 -> noch 0,75
Minute (5,0 - 0,9) / 2 = 2,05 -> noch 1,65
Stunde (5,8 - 0,6) / 2 = 2,60 -> noch 2,20
DIE STUNDE RECHNET MIT 0,6, NICHT MIT 0,9 (nachgezogen 09.09.2026).
Ihre Kante wurde weiter oben auf 0,6 verschmaelert ("ein Hauch, kein
Strich") -- der Versatz hier blieb aber auf dem Wert stehen, der zu
0,9 gehoerte. Das ist genau der Fehler, der in dieser Datei schon
mehrfach vorkam: Eine Zahl wird geaendert, die zweite Zahl, die aus
ihr folgt, nicht. Folge waren 0,15 Einheiten (0,37 px) zu wenig
Versatz -- der Lichtstrich lag knapp INNERHALB der Oberkante statt
auf ihr. Wer die Breite der Kante wieder anfasst, aendert diese
Zeile mit.
`px` in einem SVG-Transform sind Einheiten des viewBox, keine
Bildpunkte -- die Uhr skaliert damit mit, ohne dass sich das
Verhaeltnis verschiebt.
Dass die Kante immer NACH OBEN versetzt ist und nicht senkrecht zum
jeweiligen Balken, ist Absicht: Es ist ein Licht von oben, kein
aufgemalter Rand. Oben streift es die Oberkante, unten die
Unterkante -- genau das tut Licht.
ES MUSS translateX SEIN, NICHT translateY (09.09.2026, gemessen).
Das SVG `.uhr__ring` traegt `transform: rotate(-90deg)`, damit die
Ringe oben beginnen und nicht rechts. Diese Drehung gilt fuer ALLES
darin -- auch fuer einen Versatz. Ein `translateY` innerhalb des
SVG erscheint auf dem Bildschirm deshalb nicht als "oben", sondern
als "links".
Nachgemessen an den Kaesten (`getBoundingClientRect`, also in
Bildschirmkoordinaten) stand bei allen vier Lagen dy = 0:
Schatten Stunde dx 1,25 dy 0 -> nach RECHTS
Kante Sekunde dx -2,62 dy 0 -> nach LINKS
Kante Minute dx -4,67 dy 0 -> nach LINKS
Kante Stunde dx -5,93 dy 0 -> nach LINKS
Das Licht kam also von der Seite, waehrend die Kachel selbst ihren
Schlagschatten mit `0px 14px` nach UNTEN wirft -- zwei Lichter in
einem Koerper. Sichtbar war es als heller Strich, der bei den
Balken oben LAENGS durchlief statt auf der Oberkante zu sitzen;
genau der "Kratzer", der an den Stunden gestoert hat. Die
Verschmaelerung der Kante auf 0,6 hat ihn gedaempft, aber nicht
beseitigt -- weil die Ursache die Richtung war, nicht die Breite.
Die Drehung bildet SVG-x auf Bildschirm-"oben" ab, deshalb steht
hier jetzt ein POSITIVES translateX. Die Betraege bleiben, sie
waren nie das Problem. Wer die Drehung des Rings anfasst, muss
diese vier Zeilen und die zwei `transform` im HTML mitdrehen. */
.uhr__kante .uhr__sekunde { transform: translateX(0.75px); }
.uhr__kante .uhr__minute { transform: translateX(1.65px); }
.uhr__kante .uhr__stunde { transform: translateX(2.2px); }
/* DIE ZIFFERNINSEL (07.09.2026).
Seit der Stundenring eine beleuchtete Oberkante hat, laeuft ein
heller Bogen hinter den Ziffern durch. pruef-buehne hat es sofort
gemeldet: schlechtester Kontrast 2,98:1 gegen rgb(125,147,165) --
knapp unter der Grenze von 3:1, und zwar genau bei der Uhrzeit, also
der wichtigsten Angabe der ganzen Flaeche.
Das ist kein Grund, die Kante wieder wegzunehmen. Auf einer echten
Uhr steht eine Anzeige, die ueber Zeigern liegt, auf einer eigenen
Flaeche -- einer vertieften Insel im Zifferblatt. Genau die steht
jetzt hier: dunkel in der Mitte, nach aussen weich auslaufend, damit
sie keine sichtbare Kante bekommt. Der Kontrast ist damit
unabhaengig davon, was hinter ihr vorbeilaeuft.
Die Lehre allgemein: Wenn eine neue Schicht einen Text unlesbar
macht, ist die Antwort selten "Schicht weg" -- meistens fehlt dem
Text sein Untergrund. */
.uhr__mitte {
position: relative; z-index: 4;
display: grid; justify-items: center; gap: 2px; line-height: 1;
padding: 6px 14px;
}
.uhr__mitte::before {
content: ""; position: absolute; inset: -6px -10px;
z-index: -1; pointer-events: none;
border-radius: 50%;
background:
radial-gradient(closest-side, rgba(4, 7, 13, .93) 0%,
rgba(4, 7, 13, .88) 52%, rgba(4, 7, 13, .55) 78%, transparent 100%);
}
.uhr__zeit {
font-size: 1.86rem; font-weight: 700; letter-spacing: -.015em;
/* Gleiche Zifferbreite: Ohne sie zappelt die Anzeige bei jedem
Minutenwechsel, weil die 1 schmaler ist als die 8. */
font-variant-numeric: tabular-nums;
color: #f2f8ff;
/* DIE MISCHUNG IM TEXT, ohne Verlaufsschrift: zwei Schatten, einer
rot von links, einer babyblau von rechts. Ein Verlauf IN der
Schrift (background-clip: text) wuerde im Windows-Kontrastmodus zu
unsichtbarer Schrift -- derselbe Grund, aus dem die Ueberschrift
daneben eine feste Farbe traegt. */
/* GRAVIERT STATT GEDRUCKT. Zwei zusaetzliche Schatten mit einem
halben Pixel Versatz: einer dunkel nach oben, einer hell nach
unten. Das ist genau das Lichtverhalten einer Vertiefung -- oben
faellt Schatten hinein, unten trifft das Licht die
gegenueberliegende Wand. Zusammen mit den beiden farbigen Scheinen
stehen die Ziffern damit IM Blatt statt darauf. */
text-shadow:
0 -.5px 0 rgba(0, 0, 0, .85),
0 .5px 0 rgba(255, 255, 255, .22),
-6px 0 16px rgba(255, 95, 109, .38),
6px 0 16px rgba(143, 216, 255, .42);
}
.uhr__sek {
/* .74rem = 11,84 px. Bei .68rem waren es 10,88 -- unter der Grenze von
11,5, die pruef-css-klassen zieht, und sie hat recht: Diese Ziffern
stehen gesperrt und in Versalhöhe, dadurch wirken sie noch kleiner
als die Zahl sagt. */
font-size: .74rem; font-weight: 700;
font-variant-numeric: tabular-nums;
letter-spacing: .18em; text-indent: .18em;
/* EIN EINGELASSENES FENSTER, kein Etikett.
Auf einer Uhr sitzt eine Zusatzanzeige in einer AUSSPARUNG des
Zifferblatts -- man sieht durch das Blatt hindurch auf die Scheibe
darunter. Das erkennt man an zwei Dingen: der Schatten faellt oben
hinein, und unten steht eine helle Kante, wo das Licht die
gegenueberliegende Wand trifft. Genau diese beiden Schatten stehen
hier. Die abgeschnittene Ecke nimmt die Sprache der Kacheln auf. */
padding: 1px 7px 1px 8px;
border-radius: 0;
clip-path: polygon(4px 0, 100% 0, 100% 100%, 0 100%, 0 4px);
color: #d8ecfb;
background:
linear-gradient(180deg, #05080e 0%, #0a1018 100%);
box-shadow:
inset 0 2px 3px -1px rgba(0, 0, 0, .95),
inset 0 -1px 0 rgba(190, 215, 240, .28),
0 1px 0 rgba(255, 255, 255, .05);
box-shadow: inset 0 0 0 1px rgba(143, 216, 255, .16);
}
/* Die Glocke in der Kachel wird in start.css gestaltet und nicht hier.
Grund (07.09.2026, gefunden von pruef-css-klassen): `glocke.js` laeuft
auf ALLEN siebzehn Seiten und setzt die Klasse `glocke--kachel`,
sobald es einen Platz dafuer gibt. Heute gibt es den nur hier -- aber
die Regel gehoert dorthin, wo das Skript sie brauchen KANN, nicht
dorthin, wo es sie heute zufaellig braucht. Sonst sieht die Glocke
auf der naechsten Seite, die einen Platz bekommt, falsch aus, und
niemand sucht den Fehler in der Aufteilung der Stildateien.
Die Pruefung hat genau das gemeldet: "gestaltet, aber nicht auf ihrer
Seite -- fehlt auf 17 Seiten". */
@media (max-width: 620px) {
/* Die Nuten werden nicht mehr HIER ausgeschaltet, sondern in heim.css
bei 1180 px und 780 px -- jeweils in derselben Regel, die die
zugehoerige Spalte aufloest. Diese Zeile stand bei 620 px und kam
damit 160 px zu spaet: Zwischen 621 und 780 px stand die rechte Nut
als freier senkrechter Strich im Bild, nachgemessen bei 700 px bei
x = 391, wo sie nichts mehr trennte. Entfernt statt korrigiert --
eine zweite Zahl an einem zweiten Ort waere derselbe Fehler noch
einmal. */
/* Auf dem Handy rückt die Gruppe unter den Gruß und die Uhr wird
kleiner -- 108 px neben einer Überschrift lassen für den Namen
keine Zeile mehr übrig. */
.willkommen { padding: 18px 16px; }
.willkommen__rechts { margin-left: 0; width: 100%; justify-content: flex-start; }
/* DER STAND RICHTET SICH NACH DER UHR, NICHT NACH DEM RAND.
Am Rechner sitzt er rechts, weil dort auch die Uhr rechts sitzt.
Auf dem Handy rutscht die Uhr nach LINKS (Zeile darueber) -- der
Stand blieb dabei rechtsbuendig und stand als einziges Bauteil auf
der falschen Seite. Im Bildschirmfoto bei 412 px gesehen, nicht
hergeleitet.
`align-self` statt `margin-left: 0`: Der Kasten soll auf die volle
Breite gehen duerfen, wenn drei Felder nebeneinander nicht mehr
passen -- dann verteilen sie sich, statt sich zu stauchen. */
.willkommen__stand {
/* `margin-left: 0` steht hier nicht mehr: Der `auto`-Rand, den es
zuruecknehmen musste, ist seit dem 08.09.2026 aus der Grundregel
verschwunden. Eine Zeile, die nichts mehr aufhebt, sieht aus wie
eine Absicht und wird beim naechsten Mal mitgeschleppt. */
width: 100%;
justify-content: space-around;
}
.stand { min-width: 0; flex: 1 1 0; padding: 10px 8px 9px; }
/* Die Groesse kommt aus `--instrument` (heim.css), hier bleibt nur
die engere Polsterung fuer schmale Schirme. */
.uhr { padding: 4px; }
.uhr__zeit { font-size: 1.3rem; }
}
@media (prefers-reduced-motion: reduce) {
/* Die Uhr springt ohnehin -- hier gibt es nichts abzuschalten. Die
Zeile steht trotzdem da, damit der nächste, der einen weichen
Zeiger einbaut, sie findet. */
.uhr__stunde, .uhr__minute, .uhr__sekunde { transition: none; }
}
@media (forced-colors: active) {
.uhr { background: Canvas; box-shadow: none; border: 1px solid CanvasText; }
.uhr__skala, .uhr__glas { display: none; }
}
/* =====================================================================
GRUPPEN LASSEN SICH ZUKLAPPEN (07.09.2026)
Wunsch Filipe: "diese kategorien soll man auch zu und aufmachen
koennen so wie es einem lieb ist gerade."
DIE UEBERSCHRIFT IST DER SCHALTER. Ein kleines Dreieck daneben waere
ein Ziel von 14 Pixeln; die ganze Zeile ist eines von 40. Deshalb ist
der Kopf ein <button> und nicht ein <div> mit einem Knopf darin --
damit kommt auch die Tastaturbedienung geschenkt.
Ein Knopf bringt allerdings die Vorgaben des Browsers mit (eigene
Schrift, eigener Rand, zentrierter Text). Die muessen alle
zurueckgesetzt werden, sonst sieht die Ueberschrift wie eine
Schaltflaeche aus -- und genau das soll sie NICHT: Sie soll aussehen
wie vorher und sich nur anders anfuehlen.
===================================================================== */
.gruppe__kopf {
/* Alles, was ein <button> mitbringt, wieder aus. */
appearance: none; -webkit-appearance: none;
width: 100%;
font: inherit; color: inherit; text-align: left;
border: 0; background: none;
cursor: pointer;
/* Und der Aufbau von vorher. */
position: relative;
display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
margin-bottom: 14px; padding: 6px 4px 10px;
border-radius: 10px;
transition: background var(--tempo);
}
.gruppe__kopf:hover { background: rgba(255, 255, 255, .035); }
.gruppe__kopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* Die Zahl sagt, was hinter einer zugeklappten Gruppe steckt. Sie steht
ganz rechts, direkt vor dem Pfeil -- dort sucht man sie. */
.gruppe__zahl {
margin-left: auto;
min-width: 22px; padding: 1px 8px;
border-radius: 999px;
background: rgba(255, 255, 255, .06);
color: var(--text-still);
font-size: .74rem; font-weight: 700;
font-variant-numeric: tabular-nums;
text-align: center;
}
.gruppe__pfeil {
width: 16px; height: 16px; flex: none;
color: var(--text-still);
transition: transform var(--tempo), color var(--tempo);
}
.gruppe__kopf:hover .gruppe__pfeil { color: var(--text); }
/* Zugeklappt zeigt der Pfeil nach rechts -- die Richtung, in die es
geht, wenn man drueckt. */
.gruppe[data-zu="ja"] .gruppe__pfeil { transform: rotate(-90deg); }
/* Eine zugeklappte Gruppe rueckt zusammen: Der Abstand, den die Kacheln
gebraucht haben, gehoert ihnen und nicht der Ueberschrift. */
.gruppe[data-zu="ja"] { margin-bottom: 10px; }
.gruppe[data-zu="ja"] .gruppe__kopf { margin-bottom: 0; }
@media (prefers-reduced-motion: reduce) {
.gruppe__kopf, .gruppe__pfeil { transition: none; }
}
@media (forced-colors: active) {
.gruppe__kopf { border: 1px solid CanvasText; }
}
/* ===================================================================
DER HUSKY RECHTS IN DER KOPFLEISTE (08.09.2026)
Filipe: "wo der husky ist soll eine geile rot grüne peperoni sein …
und der husky von links soll rechts sein."
Zusammen mit der Chili links (start.css) ergibt das eine Klammer um
den Schriftzug: Spicy links, Dogi rechts -- genau die Reihenfolge des
Namens "Spicy & Dogi", und die Farben laufen zwischen beiden über den
Text aufeinander zu.
WARUM DIESE REGEL HIER STEHT UND NICHT IN start.css: heim.css wird
ausschliesslich von der Startseite geladen. Auf den Unterseiten traegt
`.marke` den Rueckweg statt des Markennamens -- dort hat der Husky
nicht nur nichts zu suchen, er hat auch Schaden angerichtet: Seine
22 px plus Abstand nahmen dem Text so viel Platz, dass "Creator
Workspace" zu "CREAT…" abgeschnitten wurde.
Der naheliegende Weg, ein `body.start` davorzusetzen, funktioniert
NICHT: Diese Klasse tragen alle 18 Seiten -- sie kennzeichnet den
Grundstil, nicht die Startseite. Der Selektor las sich richtig und
war es nicht; gesehen erst im Bildschirmfoto der Unterseite.
=================================================================== */
/* ===================================================================
AUS DEM FLECK WIRD WIEDER EIN HUND (09.09.2026)
Filipe: "kannst du bitte das logo wenn man es installiert auf pc oder
handy und oben rechts in der leiste noch perfektionnieren. ich finde
es könnte noch besser aussehen bitte."
ER HATTE RECHT, UND DER GRUND WAR EINE MASKE. Hier lag der Husky als
Maske auf einer Silberfläche. Von einer Maske zählt nur der
Alphakanal, und die Vorlage ist rundum freigestellt: Übrig blieb eine
GESCHLOSSENE FLÄCHE in Hundeform – kein Auge, keine Schnauze, kein
Ohrinneres. Dazu lief der Verlauf unten in volles Babyblau, und weil
die Vorlage am Hals gerade abgeschnitten ist, entstand daraus ein
blauer BALKEN. Zusammen: ein Fleck.
JETZT ZWEI LAGEN IN EINEM ELEMENT. Unten ein stahlblauer Verlauf,
darüber dieselbe Zeichnung im Mischmodus "screen". Screen lässt
Schwarz stehen (das Fell bleibt dunkelblau) und hebt Weiß heraus
(Gesicht, Ohrinneres, Auge). Beides sind HINTERGRUND-Lagen desselben
Elements – ein Pseudo-Element kann kein Kind haben, `background-blend-mode`
dagegen schon. Die Maske klebt weiterhin die Silhouette aus.
DAS IST DASSELBE REZEPT WIE IM APP-SYMBOL (tools/workspace-symbol.mjs,
gleiche Farben, gleicher Dämpfer .88). Genau darum ging es Filipe: das
installierte Symbol UND das Zeichen in der Leiste, ein Zeichen.
WIE ICH MICH DABEI FAST SELBST BETROGEN HÄTTE, zum Merken:
Ich hatte die Entwürfe zuerst mit `transform: scale(12)` vergrößert
angesehen und daraus geschlossen, eine Zweiton-Zeichnung sei bei 22 px
Matsch. Falsch – eine CSS-Vergrößerung lässt den Browser das Zeichen
NEU rechnen; ich habe 264 px beurteilt und geglaubt, es seien 22.
Richtig ist: bei echten 22 px aufnehmen, danach die PNG-Datei
vergrößern (tools/ausschnitt.mjs). So gemessen trägt das Gesicht
sehr wohl – man sieht Schnauze, Ohren und Auge. Eine Lupe, die
nachrechnet, ist keine Lupe.
KEIN AUSLAUF NACH UNTEN, anders als im App-Symbol: Dort blendet eine
zweite Maske den geraden Halsschnitt aus. Bei 22 px frisst derselbe
Verlauf das Kinn weg – nachgemessen und nebeneinandergelegt. Hier
braucht es ihn auch nicht: Das Fell ist jetzt dunkelblau statt
silbern und läuft von selbst in die dunkle Leiste aus.
=================================================================== */
.kopfleiste .marke::after {
content: "";
flex: none; width: 22px; height: 22px;
background-image:
url("../img/marke-husky.webp"),
linear-gradient(162deg, #5486b2 0%, #25507a 44%, #0e2b45 100%);
background-size: contain, auto;
background-position: center;
background-repeat: no-repeat;
background-blend-mode: screen;
-webkit-mask: url("../img/marke-husky.webp") center / contain no-repeat;
mask: url("../img/marke-husky.webp") center / contain no-repeat;
/* Ohne den Dämpfer wird das Weiß der Vorlage zu reinem Weiß – auf
dunklem Grund blendet das. Augenschonend heißt hier: hell genug zum
Erkennen, nicht heller. Der Schein ringsum trägt das Babyblau der
Rolle, das vorher in der Füllung saß. */
filter: brightness(.88) drop-shadow(0 0 6px rgba(95, 189, 255, .5));
transition: filter var(--tempo);
}
/* DER SCHEIN MUSS BEIM ÜBERFAHREN MITGENANNT WERDEN. `filter` ist keine
Liste, die sich ergänzt – wer hier nur `brightness` schreibt, löscht
den Schein. Vorher stand genau das da, und das Zeichen wurde beim
Überfahren flacher statt heller. */
.kopfleiste:hover .marke::after {
filter: brightness(1.02) drop-shadow(0 0 8px rgba(95, 189, 255, .62));
}
/* ===================================================================
DIE BEGRUESSUNG SOLL MOTIVIEREN (08.09.2026)
Filipe, screen35: "die begrüßungen sollen auch viel krasser und geiler
sein, so richtig auffällig. so dass die leute motivation bekommen weil
es so geil aussieht."
NICHT UEBER DIE GROESSE. Genau die habe ich heute frueh von 88 auf
56 px zurueckgenommen, weil in der Pille ein <h1> mit Titelgroesse
steckte und damit ZWEI Ueberschriften uebereinander standen. Das
wieder aufzublasen hiesse, denselben Fehler noch einmal zu machen --
und "auffaellig" heisst ohnehin nicht "gross", sondern "hebt sich ab".
Der Name hebt sich jetzt ueber die FARBE ab: Er traegt einen Verlauf
in der Farbe der eigenen Rolle (`--r-haupt`, gesetzt am <html>). Jeder
sieht dadurch seinen eigenen Namen in seiner eigenen Farbe -- Spicy
rot, Dogi babyblau, ein Manager lila, ein Scout gruen, ein Creator
bronze. Das ist der Unterschied zwischen "da steht mein Name" und "das
hier ist meins".
Der Gruss davor bleibt bewusst leise und ohne Farbe. Wenn beides
leuchtet, leuchtet nichts -- die Betonung liegt auf dem Namen, nicht
auf der Uhrzeit.
MIT SICHERUNG, wie beim Schriftzug in der Kopfleiste: `color` steht
zuerst und sichtbar da, der Verlauf kommt nur im @supports-Block dazu,
und im Kontrastmodus wird alles zurueckgenommen. Durchsichtige Schrift
ohne Rueckfallwert waere ein Ausfall, kein Schoenheitsfehler. */
.zgruss .gruss__wort {
color: rgba(190, 210, 232, .82);
font-weight: 500;
}
.zgruss .gruss__name {
color: #eaf3fc;
font-weight: 800;
letter-spacing: -.01em;
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
.zgruss .gruss__name {
background: linear-gradient(96deg,
color-mix(in srgb, var(--r-haupt) 34%, #ffffff) 0%,
var(--r-haupt) 52%,
color-mix(in srgb, var(--r-haupt) 62%, #ffffff) 100%);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent;
/* Das Leuchten liegt HINTER der Schrift und wird vom Zuschnitt
nicht erfasst -- es gibt dem Namen Tiefe, ohne ihn zu vergroessern. */
filter: drop-shadow(0 0 10px color-mix(in srgb, var(--r-haupt) 45%, transparent));
}
}
@media (forced-colors: active) {
.zgruss .gruss__name {
background: none; -webkit-text-fill-color: currentColor;
color: CanvasText; filter: none;
}
}
/* ===================================================================
DIE DREI BAHNEN DER UHR GLUEHEN VON INNEN (08.09.2026)
Filipe: "die minuten sekunden und stunden soll viel spezieller,
krasser und geiler sein, noch vieeeel mehr."
Die Bahnen waren flache Striche in einem Verlauf -- sauber gebaut,
aber ohne Koerper. Drei Dinge geben ihnen Tiefe, und alle drei
arbeiten mit LICHT statt mit mehr Farbe:
1. EIGENLEUCHTEN. Jede Bahn wirft einen Schein in ihrer eigenen
Farbe. Das ist nicht Deko: Auf einem schwarzen Zifferblatt kann
man einen Strich entweder heller machen (dann blendet er) oder
leuchten lassen (dann wirkt er wie eine Anzeige, die Licht
abgibt). Zwei Schatten je Bahn, ein enger und ein weiter -- der
enge gibt die Kante, der weite die Aura.
2. DIE SPITZE IST HELLER ALS DER REST. `stroke-linecap: round` plus
ein zweiter, kuerzerer Bogen darueber gibt es hier nicht -- statt
dessen leuchtet die PERLE am Ende staerker (siehe unten). Das
Auge sucht bei einer Uhr die Spitze, nicht den Anfang.
3. DIE STUNDE WIRD WARM. Sie lief in Schwarzsilber und war damit
dem Zifferblatt am aehnlichsten -- ausgerechnet die Bahn, die man
am haeufigsten abliest. Sie bekommt jetzt einen Bronzeschimmer:
warm gegen das kalte Blau der Minute und das Rot der Sekunde, und
damit sind alle drei auf einen Blick zu trennen.
AUGENSCHONEND BLEIBT PFLICHT. Die Uhr steht dauerhaft im Bild. Der
Schein liegt deshalb bei 45 bis 55 Prozent Deckkraft und wird NICHT
animiert -- ein pulsierendes Leuchten am Bildrand ist genau das, was
die Hausregel verbietet. */
/* Die Strichbreiten und Scheine der drei Bahnen stehen NICHT hier,
sondern gesammelt am Dateiende unter "DIE DREI FARBEN, NEU VERTEILT".
Hier stand bis zum 08.09.2026 ein zweiter, vollstaendiger Satz davon
(Sekunde rot, Minute blau, Stunde bronze). Er wurde vom spaeteren
Satz ueberschrieben und war damit unsichtbar -- aber wer die Datei
von oben liest, haelt ihn fuer die geltende Regel und aendert die
falsche Stelle. Genau das ist mir heute schon einmal passiert
(zwei Groessenregeln 3600 Zeilen auseinander). Deshalb entfernt
statt stehengelassen: EINE Stelle entscheidet ueber eine Farbe. */
@media (prefers-reduced-motion: reduce) {
/* Kein Leuchten ohne Not: Wer weniger Bewegung will, will meist auch
weniger Reiz. Die Bahnen bleiben in voller Farbe stehen. */
.uhr__sekunde, .uhr__minute, .uhr__stunde { filter: none; }
}
/* ===================================================================
DER KOMETENSCHWEIF (08.09.2026)
Filipe: "auch die lichter von sekunden, minuten und stunden perfekt
anpassen, wie die läuft und aussieht soll wirklich mega perfekt sein
... überrasch mich."
WAS ER LEISTET: Ein Bogen in gleichmaessiger Farbe zeigt einen
STAND. Ein Bogen, der zur Spitze hin heller wird, zeigt eine
RICHTUNG -- man sieht ohne Nachdenken, wo "jetzt" ist und wohin es
laeuft. Bei drei Ringen uebereinander ist das der Unterschied
zwischen Ablesen und Erkennen.
WARUM ZWEI LAGEN UND KEIN VERLAUF: Ein Farbverlauf ENTLANG einer
Kreisbahn geht in SVG nicht -- `linearGradient` folgt einer Geraden,
`radialGradient` einem Radius, keiner einer Bahn. Der ehrliche Weg
ist ein zweites, kuerzeres Segment ueber dem ersten. Es liegt vor
der Oberkante, damit die helle Kante auch auf dem Schweif sitzt.
`stroke-linecap: round` nur hier, nicht am Hauptbogen: Die runde
Kappe markiert die Spitze. Am Hauptbogen wuerde sie auch den ANFANG
runden -- und der liegt bei zwoelf Uhr, wo eine runde Kappe wie ein
Fehler aussieht.
AUGENSCHONEND: Der Schweif ist heller als der Bogen, aber nicht
greller -- er bleibt in derselben Farbfamilie und wird nicht
animiert. Was hier leuchtet, leuchtet ruhig. */
/* KEINE EIGENE DREHUNG (Korrektur nach dem Bildschirmfoto).
Ich hatte hier `transform: rotate(-90deg)` gesetzt, damit der
Schweif wie die Bahnen bei zwoelf Uhr beginnt. Das war doppelt: Das
ganze SVG `.uhr__ring` ist bereits um -90 Grad gedreht (siehe dort,
"Bei Null soll der Ring OBEN beginnen"). Die Schweife standen
dadurch exakt eine Vierteldrehung neben ihren Boegen -- im Bild oben
links, waehrend die Boegen oben rechts endeten. Die Rechnung war
richtig, die Drehung eine zu viel. */
/* DIE KOEPFE GLEITEN, STATT ZU SPRINGEN.
Die Anzeige selbst rechnet weiterhin nur EINMAL je Sekunde -- das
war eine bewusste Entscheidung (sechzig Bildberechnungen je Sekunde
halten auf einer stundenlang offenen Seite den Rechner warm). Die
Bewegung dazwischen uebernimmt der Browser: eine Ueberblendung von
knapp einer Sekunde, die genau bis zum naechsten Takt laeuft.
Damit sieht die Perle aus wie ein gleitender Zeiger und kostet
trotzdem nichts. Voraussetzung ist, dass der Winkel WEITERZAEHLT
statt bei 360 Grad zurueckzuspringen -- sonst liefe die Ueberblendung
einmal je Minute rueckwaerts durch das ganze Zifferblatt. Genau das
macht start.js jetzt (fortlaufende Sekunden statt sk % 60). */
@media (prefers-reduced-motion: reduce) {
}
/* ===================================================================
NACH FILIPES VORBILD: LED-KRANZ, ANKER, ROTE ANZEIGE (08.09.2026)
Er hat eine Sci-Fi-Uhr geschickt (1250 px) und gesagt: "so wie die".
Unsere ist 164 px gross -- Faktor 7,6. Was davon uebernehmbar ist,
entscheidet nicht der Geschmack, sondern die Groesse:
UEBERNOMMEN der blaue LED-Punktkranz aussen (das auffaelligste
Merkmal), die vier Anker bei 12/3/6/9, der rote
Grundton der Digitalanzeige.
NICHT MOEGLICH die Minutenzahlen 00/05/…/55 und die Stundenzahlen
1-12. Im Vorbild sind sie rund 30 px hoch; hier
waeren es VIER. Zahlen, die man nicht lesen kann,
sind kein Zifferblatt, sondern Rauschen -- und sie
wuerden die drei Boegen zudecken, die die eigentliche
Anzeige sind.
AUGENSCHONEND BLEIBT PFLICHT, und das Vorbild ist es nicht: Es lebt
von reinem Neonrot auf Schwarz. Diese Uhr steht dauerhaft im Bild
einer Seite, an der gearbeitet wird. Die Toene sind deshalb
gedaempft: das Blau der LEDs bei rund 60 % Deckkraft, das Rot der
Ziffern als heller Ton MIT rotem Schein statt als reines Rot. Die
Anmutung kommt vom Aufbau, nicht von der Grellheit. */
/* Der Punktkranz. 60 Punkte -- einer je Sekunde, wie im Vorbild.
`repeating-conic-gradient` statt sechzig Elementen: Ein Kegelverlauf
mit 6-Grad-Takt zeichnet sie in einer Ebene, und die Maske schneidet
daraus einen schmalen Ring. Sechzig <span> waeren sechzig Elemente
fuer eine Zierde. */
.uhr__leds {
position: absolute; inset: -7px; border-radius: 50%;
pointer-events: none; z-index: 1;
background: repeating-conic-gradient(from -1.5deg,
rgba(96, 200, 255, .62) 0deg 3deg, transparent 3deg 6deg);
-webkit-mask: radial-gradient(closest-side, transparent 0 93.5%, #000 94% 97.5%, transparent 98%);
mask: radial-gradient(closest-side, transparent 0 93.5%, #000 94% 97.5%, transparent 98%);
filter: drop-shadow(0 0 2px rgba(80, 190, 255, .5));
opacity: .85;
}
/* Die vier Anker bei 12, 3, 6 und 9 Uhr. Im Vorbild sitzen dort
Fassungen mit einem blauen Licht darin -- sie geben dem Ring Halt
und sagen dem Auge, wo oben ist. Ein Kegelverlauf mit 90-Grad-Takt
trifft genau diese vier Stellen. */
.uhr__anker {
position: absolute; inset: -9px; border-radius: 50%;
pointer-events: none; z-index: 1;
background: repeating-conic-gradient(from -3deg,
rgba(150, 225, 255, .95) 0deg 6deg, transparent 6deg 90deg);
-webkit-mask: radial-gradient(closest-side, transparent 0 92%, #000 92.5% 99%, transparent 99.5%);
mask: radial-gradient(closest-side, transparent 0 92%, #000 92.5% 99%, transparent 99.5%);
filter: drop-shadow(0 0 3px rgba(110, 210, 255, .85));
}
/* DIE ANZEIGE BEKOMMT DAS ROT -- aber als Schein, nicht als Farbe.
Im Vorbild sind die Ziffern reines Neonrot. Ich hatte hier zuerst
geschrieben, das reisse den Kontrast -- nachgerechnet stimmt das
NICHT: #ff2b2b auf dem fast schwarzen Zifferblatt liegt bei 5,27:1
und haelt die Grenze von 4,5. Die schoenere Begruendung war die
falsche, also steht hier die echte:
Diese Uhr steht DAUERHAFT im Bild einer Seite, an der gearbeitet
wird. Reines gesaettigtes Rot auf Schwarz ermuedet bei stundenlangem
Nebenherschauen, auch wenn es messbar lesbar ist -- das ist der Punkt
der Hausregel "augenschonend", und der ist von einer Kontrastzahl
nicht abgedeckt. Der Ton hier ist deshalb ein sehr helles Rotweiss
(15,9:1), das seinen ROTEN CHARAKTER aus dem Schein im Textschatten
bekommt. Man liest "rote Digitalanzeige", ohne stundenlang in eine
Leuchtreklame zu sehen. */
.uhr__zeit {
color: #ffe0df;
text-shadow:
0 0 6px rgba(255, 90, 86, .75),
0 0 16px rgba(255, 60, 56, .45),
0 1px 0 rgba(0, 0, 0, .6);
}
.uhr__sek {
color: #ffd2d0;
text-shadow: 0 0 7px rgba(255, 80, 76, .6);
}
/* ===================================================================
DIE UHR, GESCHAERFT (08.09.2026, zweite Runde)
Filipe: "ich will aber dass die sekunden wie punkte sind, die minuten
breiter und die stunden noch breiter … den silbernen rand weg bitte
den will ich nicht … es soll nichts verschwommen aussehen oder so,
im gegenteil, richtig scharf und perfekt."
VIER AENDERUNGEN, und jede hat einen Grund ueber den Wunsch hinaus:
1. DER SILBERNE RING IST WEG. Er war die breiteste Flaeche der ganzen
Uhr und damit das Erste, was das Auge traf -- ausgerechnet der
Teil, der nichts anzeigt. Jetzt traegt dort dunkles Metall, und
die drei Bahnen sind das Hellste im Bild. Die Skalenstriche
bleiben: Sie geben dem Ring Mass, ohne ihn zu fuellen.
2. DIE SEKUNDE IST EINE PUNKTREIHE. Sechzig Punkte, einer je
Sekunde -- der schnellste Wert wird damit zaehlbar statt nur
gewachsen. Das ist auch die ehrlichere Anzeige: Die Sekunde
SPRINGT (die Ziffer daneben tut es auch), ein durchgehender Bogen
behauptet einen fliessenden Wert.
3. DIE BREITEN STAFFELN SICH: Sekunde 3, Minute 5, Stunde 7. Vorher
lagen sie bei 3 / 3,4 / 4 -- rechnerisch verschieden, im Bild
nicht zu unterscheiden. Ein Unterschied unter einem Pixel ist
keiner. Jetzt liest man die Ringe an ihrer STAERKE, nicht nur an
der Farbe: je langsamer, desto schwerer.
4. NICHTS IST MEHR VERSCHWOMMEN. Die weichen Scheine (`drop-shadow`
mit 7 bis 9 px Radius) lagen ueber den Bahnen wie Nebel. Sie sind
auf 2 bis 3 px zurueckgenommen und liegen jetzt ALS KANTE an,
nicht als Wolke. Der Rest der Tiefe kommt aus dem Versatz der
Lagen -- so, wie es im Rest dieser Uhr ohnehin gemacht ist. */
/* ---- 1. Der Ring wird dunkel ------------------------------------- */
.uhr {
background:
conic-gradient(from 210deg,
#171d27 0deg, #10151d 54deg, #1b222d 116deg, #121820 176deg,
#1d242f 246deg, #10161e 312deg, #171d27 360deg);
box-shadow:
0 14px 30px -14px rgba(0, 0, 0, .95),
0 0 0 1px rgba(140, 170, 205, .10),
inset 0 0 0 1px rgba(6, 10, 18, .9);
}
/* ---- 3. Die Breiten, klar gestaffelt ----------------------------- */
.uhr__minute { stroke-width: 5; }
/* 5,8 STATT 7 (09.09.2026, screen5). Zusammen mit der laengeren
Gliedlaenge in start.js (5,5 -> 10) ergibt das ein Verhaeltnis von
1,7:1 statt 0,79:1. Vorher war ein Stundenglied BREITER ALS LANG und
las sich deshalb als Klotz quer auf der Bahn statt als Balken
entlang. Zusaetzlich lief der helle Strich der Kantenlage (0,4 nach
oben versetzt) mitten hindurch statt an der Oberkante -- bei einem
laengeren Glied sitzt er wieder da, wo er hingehoert. */
.uhr__stunde { stroke-width: 5.8; }
.uhr__schatten .uhr__minute { stroke-width: 6; }
.uhr__schatten .uhr__stunde { stroke-width: 6.8; }
/* ---- 2. Die Sekunde als Punktreihe -------------------------------
`stroke-linecap: round` plus eine Strichlaenge nahe null ergibt
einen Kreis vom Durchmesser der Strichbreite. Das Muster selbst
setzt start.js -- es muss mit dem Stand wachsen, und dafuer braucht
es die Zahl der Punkte. */
.uhr__sekunde {
stroke-width: 3.2;
stroke-linecap: round;
}
/* Der Schweif entfaellt bei der Sekunde -- und zwar im HTML, nicht
hier. Eine Punktreihe hat keinen Kometenschweif, sie hat einen
letzten Punkt, und den setzt die Perle. */
/* ---- 4. Schaerfe statt Nebel ------------------------------------- */
/* (Die Scheine selbst: siehe Dateiende, ein Satz fuer alle drei.) */
/* Auch die Perlen: harte Kante, enger Schein. Ein Lichtpunkt ist
scharf -- was leuchtet, hat einen Rand. */
/* ===================================================================
DIE DREI FARBEN, NEU VERTEILT (08.09.2026)
Filipe: "stunden soll rot sein, minuten schwarz/silber und die
sekunden babyblau. die punkte herum sollen eine mischung von rot
schwarz und babyblau sein."
SEIT DEM 19.09.2026 IST DIE STUNDE LILA. Filipe: "die stunden sollen
nicht rot sondern lila sein."
UMGERECHNET, NICHT NEU GEWAEHLT: Jeder der fuenf Verlaufsstopps
wurde nach OKLCH zerlegt, sein Farbton auf 303 Grad gedreht und
zurueckgerechnet -- Helligkeit und Buntheit blieben auf den
Tausendstel gleich. Eine frei gegriffene Lila-Palette waere mit
hoher Wahrscheinlichkeit heller oder bunter geworden, und damit
waere die Uhr unruhiger, obwohl sich "nur die Farbe" geaendert hat.
303 Grad ist der erste Ton im Lila-Bereich, bei dem alle acht Werte
(fuenf Stopps, Kopf, zwei Scheine) noch darstellbar sind.
Die Begruendung darunter gilt unveraendert: Die Stunde bewegt sich
kaum und darf deshalb die kraeftigste Farbe tragen.
Die Zuordnung ist nicht beliebig, sie folgt der Geschwindigkeit:
Die SEKUNDE laeuft dauernd und bekommt das ruhigste Babyblau --
staendige Bewegung in Signalrot ermuedet. Die STUNDE bewegt sich
kaum und darf deshalb die kraeftigste Farbe tragen. Die MINUTE
dazwischen in Schwarzsilber: Sie ist der Bezug, an dem man die
beiden anderen misst, und Metall draengt sich nicht vor.
Die Glieder sind ausserdem verschieden LANG -- Punkt, kurzer Balken,
langer Balken. Damit liest man die drei Bahnen auch dann
auseinander, wenn jemand Farben schlecht unterscheidet. Farbe allein
traegt eine Information nie. */
/* DER SCHEIN GEHOERT AN EINE LAGE, NICHT AN DREI.
Jeder Ring liegt dreifach im SVG: Schattenlage (0,55 nach unten),
Hauptlage, Kantenlage (0,4 nach oben). `.uhr__stunde` trifft alle
drei -- der Schein wurde damit DREIMAL uebereinander gerechnet. Im
Bildschirmfoto lief das rote Leuchten deshalb bis ueber die Ziffern
und liess die ganze Uhr weich aussehen, obwohl in der Regel nur
1,8 px stehen. Genau das, was Filipe nicht will ("es soll nichts
verschwommen aussehen ... im gegenteil, richtig scharf").
Mit `>` bekommt nur die Hauptlage den Schein. Schatten und Kante
bleiben hart -- sie sind Koerper, kein Licht. Das ist derselbe
Gedanke wie im Kommentar oben ("KEIN Weichzeichner, nirgends: Die
Tiefe entsteht aus dem Versatz"), nur war er an dieser Stelle nicht
durchgehalten. */
.uhr__ring > .uhr__sekunde { filter: drop-shadow(0 0 1.4px rgba(126, 200, 242, .85)); }
.uhr__ring > .uhr__minute { filter: drop-shadow(0 0 1.2px rgba(220, 232, 246, .6)); }
.uhr__ring > .uhr__stunde { filter: drop-shadow(0 0 1.4px rgba(182, 119, 255, .8)); }
.uhr__schatten .uhr__sekunde, .uhr__schatten .uhr__minute, .uhr__schatten .uhr__stunde,
.uhr__kante .uhr__sekunde, .uhr__kante .uhr__minute, .uhr__kante .uhr__stunde { filter: none; }
/* Die Koepfe tragen die Farbe ihrer Bahn -- sonst zeigte ein blauer
Punkt auf eine rote Reihe. */
/* ---- Der Punktkranz: rot, schwarz, babyblau im Wechsel -----------
Drei Farben in einem `repeating-conic-gradient`: je 6 Grad ein
Punkt, dazwischen die Luecke. Die Reihenfolge Rot - Blau - Dunkel
wiederholt sich alle 18 Grad, also zwanzigmal auf dem Ring.
Das Dunkel ist kein Loch, sondern ein sehr dunkles Blau: Ein echter
Zwischenraum haette den Kranz in zwei Haelften zerfallen lassen,
sobald man ihn aus dem Augenwinkel sieht. So bleibt der Ring ein
Ring und hat trotzdem drei Toene. */
.uhr__leds {
background: repeating-conic-gradient(from -1.5deg,
rgba(255, 90, 102, .70) 0deg 3deg, transparent 3deg 6deg,
rgba(126, 200, 242, .70) 6deg 9deg, transparent 9deg 12deg,
rgba(120, 150, 185, .34) 12deg 15deg, transparent 15deg 18deg);
filter: drop-shadow(0 0 2px rgba(150, 170, 210, .4));
}
/* =====================================================================
DAS UNIVERSUM HINTER DER KONSOLE (screen21, 08.09.2026)
Filipe: "ich will dass du im hintergrund dieser kachel das logo von
spicy media machst. es soll mega speziell sein, es soll sogar paar
mal zu sehen sein, es soll sich bewegen, schweben ... der ganze
hintergrund soll wie ein universum aussehen bitte."
DIE SCHWIERIGKEIT IST NICHT DAS UNIVERSUM, SONDERN DER TEXT DARAUF.
Auf dieser Kachel stehen Anrede, Titel, drei Zahlen und ein
Lagesatz. Ein Hintergrund, der auffaellt, macht genau das kaputt,
wofuer die Kachel da ist. Deshalb liegt hier alles zwischen 6 und
10 Prozent Deckkraft -- man SIEHT die Chilis, man LIEST sie nicht.
Wer sie sucht, findet fuenf; wer die Uhrzeit sucht, findet die
Uhrzeit.
AUGENSCHONEND HEISST HIER VOR ALLEM: LANGSAM. Die Bahnen dauern 71
bis 118 Sekunden, die Sterne 240. Bei einer Kachel, die stundenlang
im Bild steht, ist eine Bewegung, die man BEMERKT, eine Bewegung,
die stoert. Nichts blinkt, nichts pulsiert, nichts wechselt die
Helligkeit -- es driftet.
NUR `transform` UND `opacity` WERDEN BEWEGT. Beide laufen auf der
Grafikkarte; ein animiertes `background-position` oder `left`
zwingt den Browser bei jedem Bild zum Neuzeichnen der ganzen
Kachel, und diese Kachel hat vierzehn Hintergrundebenen.
===================================================================== */
.willkommen > .zuniversum {
position: absolute; inset: var(--k-rand);
z-index: 0; pointer-events: none; overflow: hidden;
clip-path: var(--k-innenform);
/* DIE NEBEL. Drei Wolken in den Hausfarben: Rot unten links,
Babyblau oben rechts, dazwischen ein Hauch Lila als Uebergang --
dieselbe Anordnung wie in der Fassung ringsum, damit Rand und
Flaeche dieselbe Richtung haben. Ohne den Lila-Hauch stossen Rot
und Blau in der Mitte hart aneinander und sehen aus wie zwei
Scheinwerfer, nicht wie ein Raum. */
background:
radial-gradient(125% 95% at 10% 88%, rgba(255, 74, 92, .115), transparent 62%),
radial-gradient(115% 90% at 90% 12%, rgba(126, 200, 242, .105), transparent 60%),
radial-gradient( 70% 62% at 52% 50%, rgba(167, 139, 250, .055), transparent 68%);
}
/* DAS STERNENFELD. Vier Verlaufsebenen, gekachelt -- keine Elemente.
Sechzig Sterne waeren sechzig Knoten im Baum; vier Ebenen mit
unterschiedlicher Kachelgroesse ergeben ein Feld, in dem sich kein
Muster wiederholt, das man sieht (137 / 191 / 223 / 89 Pixel haben
kein gemeinsames Vielfaches unter 1200 -- die Kachel ist breiter
als jede Wiederholung, die auffallen wuerde).
Die Sterne tragen die drei Hausfarben, nicht nur Weiss: ein paar
rote, ein paar babyblaue, der Rest silbrig. */
.willkommen > .zuniversum::before {
content: ""; position: absolute; inset: -8%;
/* HELLER UND DICHTER ALS IM ERSTEN ANLAUF. Mit .34 bis .50 Deckkraft
und einem Stern je 137 px waren sie da -- aber unter dem
Kohlefasergewebe der Kachel nicht mehr zu sehen. Ein Sternenfeld,
das man nur im Quelltext findet, ist keines. Jetzt zwei Sterne je
Kachel (der zweite versetzt) und .55 bis .8 Deckkraft. Sie
leuchten nicht, sie stehen -- Bewegung kommt allein aus der
langsamen Drift. */
background-image:
radial-gradient(1.4px 1.4px at 22px 31px, rgba(255, 255, 255, .80), transparent 100%),
radial-gradient(1.0px 1.0px at 104px 96px, rgba(226, 240, 255, .55), transparent 100%),
radial-gradient(1.2px 1.2px at 96px 12px, rgba(214, 234, 255, .66), transparent 100%),
radial-gradient(1.0px 1.0px at 31px 140px, rgba(190, 220, 250, .50), transparent 100%),
radial-gradient(1.7px 1.7px at 47px 118px, rgba(255, 150, 162, .62), transparent 100%),
radial-gradient(1.1px 1.1px at 168px 44px, rgba(255, 176, 186, .46), transparent 100%),
radial-gradient(1.3px 1.3px at 133px 74px, rgba(150, 210, 245, .64), transparent 100%),
radial-gradient(1.0px 1.0px at 38px 22px, rgba(126, 200, 242, .48), transparent 100%);
background-size:
137px 137px, 137px 137px, 191px 191px, 191px 191px,
223px 223px, 223px 223px, 89px 89px, 89px 89px;
/* Sehr langsames Wandern des ganzen Feldes -- 240 s fuer 4 Prozent
Weg. Das ist unter der Schwelle, an der man Bewegung bemerkt, und
genau darueber, an der ein Standbild tot wirkt. */
animation: zuni-sterne 240s linear infinite;
will-change: transform;
}
/* DIE CHILIS. Jeder bekommt Ort, Groesse, Tiefe, Dauer, Startversatz
und Neigung vom Element (siehe start.html) -- diese Regel weiss von
keinem einzelnen.
`--tief` steuert Deckkraft UND Unschaerfe zugleich: Was weiter weg
ist, ist blasser und weicher. Das ist der Unterschied zwischen
fuenf Aufklebern und einem Raum mit Tiefe. Die Unschaerfe ist hier
ausdruecklich richtig (Entfernung), waehrend sie an der Uhr
ausdruecklich falsch war (dort ist alles gleich nah). */
.willkommen > .zuniversum .zuniversum__chili,
.willkommen > .zuniversum .zuniversum__husky {
position: absolute;
left: var(--x); top: var(--y);
width: var(--gr); height: var(--gr);
margin: calc(var(--gr) / -2);
opacity: var(--tief);
filter: blur(calc((.11 - var(--tief)) * 22px));
animation: zuni-schweben var(--dauer) ease-in-out var(--ver) infinite;
will-change: transform;
}
.willkommen > .zuniversum .zuniversum__chili {
background: url("../img/marke-spicy.webp") center / contain no-repeat;
}
/* DER HUSKY ALS MASKE (09.09.2026, screen4).
Filipe: "setz in den hintergrund noch 1-2 peperonis und dan das logo
von dogfather, also nur den husky."
Die Datei ist schwarz-weiss und freigestellt (nachgemessen: 49 %
durchsichtig). Als Hintergrundbild bei 15 % Deckkraft verschwaenden
die schwarzen Flaechen im dunklen Grund, uebrig blieben die hellen
Stellen -- ein zerrissener Umriss, kein Hund. Als MASKE ueber einer
Farbflaeche wird daraus eine geschlossene Silhouette, und die traegt
DogFathers Babyblau. Im Universum schweben damit die beiden Marken
des Hauses in ihren beiden Farben.
Er ist eine Spur staerker eingestellt als die Chilis: Eine
geschlossene Silhouette wirkt bei gleicher Deckkraft leiser als eine
mit Aussparungen -- beim Chili fuehrt die Flamme innen den Blick. */
.willkommen > .zuniversum .zuniversum__husky {
background: #7ec8f2;
-webkit-mask: url("../img/marke-husky.webp") center / contain no-repeat;
mask: url("../img/marke-husky.webp") center / contain no-repeat;
}
/* Die Bahn: eine langgezogene Acht statt eines Kreises. Ein Kreis
sieht nach Karussell aus, sobald man ihn zweimal gesehen hat; eine
Acht kommt nie an derselben Stelle mit derselben Richtung vorbei.
Die Neigung `--kipp` kommt oben drauf, damit nicht alle fuenf
dieselbe Lage haben. */
@keyframes zuni-schweben {
0% { transform: translate(0, 0) rotate(var(--kipp)) scale(1); }
25% { transform: translate(14px, -11px) rotate(calc(var(--kipp) + 5deg)) scale(1.05); }
50% { transform: translate(-6px, -20px) rotate(calc(var(--kipp) - 3deg)) scale(.97); }
75% { transform: translate(-16px, -7px) rotate(calc(var(--kipp) + 2deg)) scale(1.03); }
100% { transform: translate(0, 0) rotate(var(--kipp)) scale(1); }
}
@keyframes zuni-sterne {
0% { transform: translate(0, 0); }
100% { transform: translate(-3.2%, 2.4%); }
}
/* WER WENIGER BEWEGUNG WILL, BEKOMMT EIN STANDBILD -- kein leeres
Feld. Die Chilis bleiben stehen, wo sie stehen; der Raum bleibt,
nur die Drift geht weg. Ein `display: none` waere hier die bequeme
und die falsche Antwort: Die Einstellung heisst "weniger Bewegung",
nicht "weniger Gestaltung". */
@media (prefers-reduced-motion: reduce) {
.willkommen > .zuniversum::before,
.willkommen > .zuniversum .zuniversum__chili,
.willkommen > .zuniversum .zuniversum__husky { animation: none; }
}
/* Auf schmalen Bildschirmen wird die Kachel hoch und schmal. Fuenf
Chilis draengen sich dann auf einer Flaeche, auf der auch der Text
steht -- die beiden groessten gehen deshalb. Nicht "weil es besser
aussieht", sondern weil bei 380 px Breite der 122-px-Chili ein
Drittel der Kachel einnimmt und hinter dem Titel steht. */
@media (max-width: 700px) {
/* Auf schmalen Schirmen bleiben vier von acht Motiven. `> :nth-child`
statt `.zuniversum__chili:nth-child` -- die Kinder sind jetzt
zweierlei, und ein Klassenname im Selektor haette beim Zaehlen
trotzdem ALLE Geschwister mitgezaehlt. Das sieht richtig aus und
trifft die falschen. */
.willkommen > .zuniversum > :nth-child(1),
.willkommen > .zuniversum > :nth-child(3),
.willkommen > .zuniversum > :nth-child(7),
.willkommen > .zuniversum > :nth-child(8) { display: none; }
}
/* Wo Benachrichtigungen gar nicht gehen, sieht man das dem Knopf an --
nicht erst nach dem Antippen. Er bleibt bedienbar (der Klick
erklaert, woran es liegt), aber er wirbt nicht mehr. */
.tagesruf[data-lage="verboten"],
.tagesruf[data-lage="iphone"] { opacity: .55; }
.tagesruf__warnung {
display: block; max-width: 190px;
margin-top: 2px;
font-size: .75rem; line-height: 1.4;
/* Bernstein, nicht Rot: Es ist ein Hinweis auf eine Einstellung, die
nichts bewirkt -- kein Fehler und kein Ausfall. Rot ist in diesem
Haus fuer "ueberfaellig" vergeben. */
color: #e8c07a;
}
.tagesruf__warnung[hidden] { display: none; }
/* =====================================================================
EIN MATERIAL FUER DIE GANZE WEBSITE (07.09.2026)
Fuenfundvierzig Stellen benutzten `var(--flaeche)` als Kartenflaeche
-- Seite fuer Seite nachzuziehen war der Grund, warum es nie fertig
wurde. Die Liste unten ist deshalb GEMESSEN und nicht erfunden: Es
sind genau diese Klassen.
`:where()` hat Spezifitaet null -- die Regel legt nur den Boden und
ueberschreibt nichts, was eine Seite selbst festlegt. Eine Warnkarte
bleibt rot, eine Spalte behaelt ihre Statusfarbe.
FORM, KANTE UND SCHATTEN kommen dagegen aus dem Abschnitt HUD-MODULE
am Ende der Datei -- mit voller Spezifitaet, weil sie die aelteren
Regeln ABLOESEN sollen und nicht unter ihnen liegen.
===================================================================== */
:where(
.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand,
.ki-kasten, .hinweis, .k-ansicht, .k-serie, .k-abo, .k-listentag,
.spalte, .balance, .saeulen-kasten, .neu, .call-raum, .schulung__neu,
.nachricht, .creator, .summe, .wert, .pdf, .pdf-ablage, .suchleiste,
.person, .kk, .fortschritt, .punkt, .nur-lesen, .todo-liste li,
.unterweisung, .warnkarte
/* `.profil-gruppe` stand hier und existiert nirgends -- ich hatte den
Namen aus dem Kopf geschrieben statt aus der Datei. pruef-struktur
hat es als totes CSS gemeldet. Die Karten auf profil.html heissen
`.gruppe`, und genau dieser Name gehoert NICHT in diese Liste: Auf
der Startseite heissen die Kachelgruppen ebenso, und die haetten
dann ploetzlich eine Kartenflaeche. Zwei Dinge mit demselben
Klassennamen sind der Grund, warum man solche Listen misst statt
sie zu raten. */
) {
position: relative;
/* DUNKLER ALS DER ERSTE ANLAUF (07.09.2026, gemessen).
Zuerst stand hier rgba(26, 34, 49, .92) -- heller als das
`var(--flaeche)`, das ersetzt wurde. Auf personen.html landete die
Rollenbeschreibung damit auf rgb(46, 44, 47) und kam auf 4,21:1
statt der noetigen 4,5. Ein Material, das die ganze Website
aufhellt, hellt auch jeden Text darauf auf -- und das faellt an der
leisesten Schrift zuerst auf, nicht an der lautesten.
Jetzt derselbe Verlauf wie bei den Kacheln, die gemessen bestehen. */
background:
linear-gradient(168deg,
rgba(20, 27, 40, .94) 0%,
rgba(11, 15, 24, .95) 62%,
rgba(8, 11, 18, .95) 100%);
border: 1px solid rgba(150, 186, 220, .12);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .075),
inset 0 -1px 0 rgba(0, 0, 0, .42),
0 2px 4px -2px rgba(0, 0, 0, .5),
0 12px 28px -18px rgba(0, 0, 0, .85);
}
/* Körnung, Anheben und Schatten stehen im Abschnitt HUD-MODULE am
Ende dieser Datei. Hier bleibt nur die Fläche selbst. */
@media (max-width: 620px) {
/* Flacher auf dem Handy: Nebeneinander liegt dort ohnehin nichts, und
große weiche Schatten kosten bei jedem Scrollen Rechenzeit. Das
Material bleibt -- nur seine Höhe über dem Grund sinkt. */
:where(
.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand,
.ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu,
.call-raum, .creator, .summe, .pdf, .person, .kk, .unterweisung
) {
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
inset 0 -1px 0 rgba(0, 0, 0, .4),
0 4px 12px -8px rgba(0, 0, 0, .8);
}
}
@media (prefers-reduced-motion: reduce) {
:where(.datei, .pdf, .creator, .person, .kk):hover { transform: none; }
}
@media (forced-colors: active) {
/* Im Kontrastmodus zählt ausschließlich die Kante. Verläufe, Schatten
und Körnung sind dort nicht nur wirkungslos, sondern schädlich. */
:where(
.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand,
.ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu,
.call-raum, .creator, .summe, .pdf, .person, .kk, .unterweisung
) { background: Canvas; box-shadow: none; border: 1px solid CanvasText; }
:where(
.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand,
.ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu,
.call-raum, .creator, .summe, .pdf, .person, .kk, .unterweisung
)::after { display: none; }
}
/* Die FORM aller Module -- abgeschnittene Ecke, Kantenlicht, Eckwinkel,
Raster -- steht seit dem 07.09.2026 in einer eigenen Datei:
assets/css/module.css.
Zwei Gruende. Erstens war start.css ueber 200 KB gewachsen und lief in
die Grenze von pruef-struktur -- zu Recht, sie ist ueber Wochen aus
Anbauten entstanden. Zweitens ist die Silhouette eine EIGENE Sache:
Sie gilt fuer jede Karte auf jeder Seite, unabhaengig davon, was die
Seite sonst tut. Wer an der Form etwas aendert, soll eine Datei
oeffnen und nicht in einer von 4900 Zeilen suchen.
module.css wird von JEDER Seite geladen (anders als heim.css, das nur
die Startseite braucht). */
/* ===================================================================
DIE KOPFLEISTE BRENNT (08.09.2026)
Filipe, screen36: "hintergrund dieser leiste soll auch eine richtig
geile mischung von rot schwarz sein, wie wenn es brennen würde."
Und screen5: "die buttons: teilen, suchen und abmelden sollen rot,
alle andere rot töne aber rot. mach was geiles draus."
GLUT KOMMT VON UNTEN, NICHT VON ÜBERALL. Ein gleichmäßig roter
Balken sieht aus wie eine Fehlermeldung. Feuer ist unten heiß und
oben dunkel -- deshalb liegt das Rot als flacher Schein an der
Unterkante, wird nach oben hin schwarz und ist an den Rändern
schwächer als in der Mitte. Zwei übereinanderliegende Verläufe
ergeben das: einer für die Höhe, einer für die Breite.
AUGENSCHONEND BLEIBT PFLICHT (Hausregel). Die Leiste steht auf JEDER
Seite und liegt beim Lesen immer im Bild -- sie darf nicht leuchten,
sondern nur glimmen. Das Rot bleibt deshalb unter 30 % Deckkraft und
wird nie heller als der Text darauf. Kein Flackern: Eine Animation
hier wäre ein Stroboskop am oberen Bildrand.
Der dunkle Grundton bleibt darunter liegen -- er trägt die Lesbarkeit
der Schrift, die Glut liegt nur darüber. */
.kopfleiste {
background:
/* die Glut an der Unterkante */
linear-gradient(180deg,
transparent 34%,
rgba(150, 30, 22, .13) 72%,
rgba(214, 58, 40, .26) 100%),
/* in der Mitte heißer als an den Rändern */
radial-gradient(120% 190% at 50% 118%,
rgba(255, 106, 66, .30) 0%,
rgba(168, 38, 26, .17) 38%,
transparent 72%),
rgba(6, 9, 16, .88);
}
/* Die Kante unten ist die Naht zum Inhalt -- sie glüht mit, sonst
endet das Feuer an einer grauen Linie. */
.kopfleiste::after {
content: "";
position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
background: linear-gradient(90deg,
transparent, rgba(255, 122, 78, .55) 22%, rgba(255, 150, 96, .75) 50%,
rgba(255, 122, 78, .55) 78%, transparent);
pointer-events: none;
}
/* ---- Die Knöpfe: zwei in Jade, zwei in Rot -------------------------
Bis zum 09.09.2026 waren alle vier rot ("alle andere rot töne aber
rot"). Filipe (screen5): "der abmelde button und teilen button sollen
eine richtig geile grün haben bitte und nicht rot. aber soll wirklich
geil sein. richtig speziell. aber so dass es nicht den augen wehtut
aber doch speziell."
ES IST JADE, KEIN SIGNALGRUEN. Nachgerechnet in HSL:
bisher #ff7a5e Saettigung 100 %
Neongruen #00ff88 Saettigung 100 %
jetzt #45d6a6 Saettigung 63 %
#33b394 Saettigung 55 %
Beide neuen Toene sind also WENIGER gesaettigt als das Rot, das
vorher dort stand -- die Leiste wird durch den Wechsel ruhiger, nicht
greller. "Speziell" kommt hier aus der Farbe selbst: Ein Jadegruen
auf einer Leiste, die von unten rot glueht, ist der groesstmoegliche
Gegensatz, und genau deshalb faellt es auf, ohne laut zu sein.
ZWEI VERSCHIEDENE GRUEN, nicht zweimal dasselbe -- dieselbe Regel wie
vorher bei den vier Rottoenen. Teilen ist das hellere (man benutzt es
absichtlich), Abmelden das tiefere und kuehlere: Es soll am wenigsten
locken, und das macht man ueber Helligkeit, nicht ueber Warnfarbe.
Chat und Suchen bleiben rot. Damit teilt die Leiste sich in "das
mache ich mit der Seite" (rot, in der Mitte) und "das mache ich mit
meinem Zugang" (jade, aussen) -- die Farbe sagt etwas, statt nur
verschieden zu sein.
`--f` ist die Knopffarbe aus gate.css; sie färbt Rahmen, Schimmer
und den Schein beim Überfahren gleich mit. Deshalb wird hier nur
diese eine Variable gesetzt statt fünf Eigenschaften je Knopf. */
.kopfleiste .teilen { --f: #45d6a6; --f-tief: #1d8f74; }
.kopfleiste .chat-knopf { --f: #f26a5a; }
.kopfleiste .suche-knopf { --f: #e8734f; }
.kopfleiste .abmelden { --f: #33b394; --f-tief: #17705d; }
/* Die Schrift muss auf dem dunklen Knopf lesbar bleiben: Ein Rot als
Rahmen ist etwas anderes als ein Rot als Schrift. Deshalb steht der
Text weiterhin hell und nimmt nur einen Hauch der Knopffarbe an.
DAS GEMISCHTE WEISS FOLGT DER KNOPFFARBE (09.09.2026). #f4e6e2 ist
ein warmes, leicht rotstichiges Weiss -- richtig unter roten Knoepfen,
falsch unter gruenen: Dort ergab es einen schmutzigen Ton, weil sich
Rotstich und Gruen gegenseitig ausloeschen. Die beiden Jadeknoepfe
bekommen deshalb ein kuehles Weiss. Gemessen auf der Leiste:
15,6:1 und 15,0:1 -- besser als die 13,6:1 und 12,6:1 vorher. */
.kopfleiste .teilen,
.kopfleiste .chat-knopf,
.kopfleiste .suche-knopf,
.kopfleiste .abmelden {
color: color-mix(in srgb, var(--f) 22%, var(--f-weiss, #f4e6e2));
border-color: color-mix(in srgb, var(--f) 42%, transparent);
background: linear-gradient(180deg,
color-mix(in srgb, var(--f) 9%, transparent),
color-mix(in srgb, var(--f) 4%, transparent));
}
.kopfleiste .teilen, .kopfleiste .abmelden { --f-weiss: #e9f7f0; }
/* WARUM HIER KEIN VERLAUFSRAHMEN STEHT (09.09.2026, nach dem ersten
Versuch verworfen).
Ich hatte den beiden Jadeknoepfen einen Rahmen aus drei Toenen gegeben
-- ueber zwei Lagen, `padding-box` fuer die Flaeche und `border-box`
fuer den Rand. Im Bildschirmfoto waren beide Knoepfe daraufhin
FLAECHIG GRUEN und damit doppelt so laut wie Chat und Suchen daneben.
Der Grund ist der Trick selbst: Eine `border-box`-Lage liegt unter der
GANZEN Flaeche, nicht nur unter dem Rand. Sichtbar wird sie nur dort,
weil die `padding-box`-Lage darueber sie ueberall sonst zudeckt. Ich
hatte diese obere Lage durchsichtig gemacht (wie bei den roten
Knoepfen) -- damit deckte sie nichts mehr zu, und der Rahmenverlauf
fuellte den Knopf.
Deckend haette es funktioniert, aber dann waeren die beiden die
einzigen Knoepfe mit undurchsichtigem Koerper. Deshalb der Rueckbau
auf denselben Aufbau wie bei den roten: durchscheinende Flaeche, EIN
Randton. "Speziell" macht hier die Farbe, nicht die Bauart -- ein
Jadegruen auf einer rot gluehenden Leiste faellt von selbst auf, und
zwar ohne lauter zu sein. Zahlen dazu stehen weiter oben: beide neuen
Toene sind WENIGER gesaettigt als das Rot, das vorher dort stand.
Nur der Lichtkamm oben muss mitgeaendert werden -- er kommt aus der
gemeinsamen Regel in gate.css und rechnet dort mit `--f`. */
/* Der Lichtkamm oben nimmt den helleren der beiden Toene -- sonst
liegt auf einem gruenen Knopf ein roter Streifen (er kommt aus der
gemeinsamen Grundregel in gate.css und rechnet dort mit `--f`). */
.kopfleiste .teilen::after,
.kopfleiste .abmelden::after {
background: linear-gradient(90deg, transparent,
color-mix(in srgb, var(--f) 70%, transparent), transparent);
opacity: .85;
}
/* DIE ZAHLENREIHE BLEIBT STEHEN, AUCH WENN ALLES NULL IST (08.09.2026).
Filipe: "diese beiden kategorien sollen bei jedem in jeder rolle
gleich sein". Vorher wurde die Reihe bei lauter Nullen geloescht --
nachgemessen sah Spicy Media als einzige Rolle etwas anderes als die
uebrigen vier. Wer die Rolle wechselt, fand die Seite anders gebaut
vor.
Jetzt bleibt sie und wird nur LEISER: weniger Deckkraft, kein
Warnrot, die Zahlen ohne ihr Leuchten. Die Form der Seite bleibt
damit ueber alle Rollen gleich, und "gerade nichts zu tun" ist
trotzdem auf einen Blick zu sehen -- gedaempft ist auch eine
Antwort, nur eine leise.
Der Satz darunter steht jetzt ZUSAETZLICH statt an ihrer Stelle. */
#zahlen-block[data-leer="ja"] .zahl {
opacity: .45;
filter: saturate(.35);
}
#zahlen-block[data-leer="ja"] .zahl__wert { text-shadow: none; }
/* Auch die Warnfarbe verschwindet: Eine rote Null ist ein Widerspruch. */
#zahlen-block[data-leer="ja"] .zahl[data-warn="ja"] { --warnton: inherit; }
#zahlen-block[data-leer="ja"] .zahl[data-warn="ja"] .zahl__wert { color: inherit; }
#zahlen-block[data-leer="ja"] #zahlen-leer { margin-top: 10px; opacity: .8; }
/* =====================================================================
AUS DEM SIEGEL WIRD EINE URKUNDE (screen1 neu, 09.09.2026)
Filipe: "wenn die kachel da ist soll die viel spezieller und geiler
sein. wirklich speziell machen bitte."
Heute Nacht ist aus dem unsichtbaren Kasten ein Siegel geworden --
Flaeche, gruene Stempelschiene, gepraegte Muenze. Das war die halbe
Antwort. "Wirklich speziell" heisst: Es soll nicht nur ANDERS
aussehen als die Kacheln daneben, sondern nach etwas Bestimmtem.
ES IST EINE QUITTUNG. Alles auf dieser Seite ist eine Aufgabe --
etwas, das noch zu tun ist. Dieses eine Feld sagt das Gegenteil:
erledigt, abgehakt, nichts offen. Die Formensprache dafuer gibt es
seit dreihundert Jahren, und sie ist ueberall dieselbe: Urkunde,
Quittung, Wertpapier. Drei Merkmale machen sie aus, und alle drei
sind hier gebaut:
1. GUILLOCHE -- das feine, sich kreuzende Linienwerk auf
Wertpapieren. Zwei Scharen duenner Linien in flachen,
gegenlaeufigen Winkeln; wo sie sich kreuzen, entsteht das
Moiré, das man von Banknoten kennt. Bei 4 Prozent Deckkraft
sieht man kein Muster, man sieht ein MATERIAL -- genauso wie
das Kohlefasergewebe auf der Zentrale. Ein Muster, das man
BEMERKT, waere Zierrat.
2. DIE MUENZE BEKOMMT EINE RAENDELUNG -- den gekerbten Rand echter
Muenzen. Ein `repeating-conic-gradient` mit 40 Kerben; darueber
liegt die gewoelbte Flaeche, sodass die Kerben nur am Rand
stehen. Das ist der Unterschied zwischen einem gruenen Kreis
und einem gepraegten Stueck Metall.
3. DIE PERFORATION rechts -- die Reisskante eines abgetrennten
Abschnitts. Sie sagt in einem Bild, was der Satz sagt: Der
Vorgang ist abgeschlossen und abgetrennt.
AUGENSCHONEND BLEIBT PFLICHT: Guilloche 4 %, Raendelung 10 %,
Perforation 45 % auf schon dunklem Grund. Nichts bewegt sich,
nichts leuchtet. Das Feld steht auf der Startseite, die stundenlang
offen ist -- eine Urkunde ist still, sonst waere sie ein Plakat.
KEIN EINZIGES NEUES ELEMENT. Guilloche und Perforation liegen auf
den beiden Pseudoelementen des Feldes, die Raendelung auf dem des
Hakens. Fuer eine Zierde gehoert nichts in den Dokumentbaum.
===================================================================== */
.zahlen-leer { isolation: isolate; }
/* 1. Das Linienwerk. Zwei Scharen in 24 und -24 Grad, dazu eine dritte
sehr feine senkrechte -- erst die dritte nimmt dem Kreuzmuster
das Karierte und macht daraus ein Gewebe. */
.zahlen-leer::before {
content: ""; position: absolute; inset: 0;
pointer-events: none; z-index: 0;
clip-path: inherit;
/* LEISER UND NEUTRALER ALS IM ERSTEN ANLAUF. Mit 4,5 Prozent in
Gruen war es kein Material mehr, sondern ein sichtbares
Rautennetz -- und es faerbte die ganze Kachel nach. Jetzt 2
Prozent in Silber: Das Linienwerk gibt der Flaeche eine Struktur,
ohne eine Farbe beizusteuern. Das Gruen soll von der Schiene und
der Muenze kommen, nicht vom Untergrund.
Auch weiter auseinander (9 statt 7 px): Bei dichten Linien
entsteht auf einem Bildschirm ein Moiré mit dem Pixelraster
selbst, und das flimmert beim Rollen. Genau das darf hier nicht
passieren. */
background-image:
repeating-linear-gradient(24deg,
rgba(214, 232, 245, .020) 0 1px, transparent 1px 9px),
repeating-linear-gradient(-24deg,
rgba(214, 232, 245, .020) 0 1px, transparent 1px 9px);
}
/* Alles Sichtbare liegt darueber -- sonst laege das Linienwerk auf der
Schrift statt unter ihr. */
.zahlen-leer > * { position: relative; z-index: 1; }
/* 3. Die Reisskante. Halbkreise, die aus der rechten Kante
herausgestanzt sind -- dieselbe Farbe wie der Untergrund
dahinter, damit es wie Loecher aussieht und nicht wie Punkte. */
.zahlen-leer::after {
content: ""; position: absolute; top: 0; bottom: 0; right: 0;
width: 9px; pointer-events: none; z-index: 2;
/* Die Loecher sitzen AUF der Kante (x = 100 %), also ist nur ihre
linke Haelfte zu sehen -- so sieht eine gestanzte Reisskante aus.
Ein voller Kreis daneben waere eine Punktreihe.
Deutlich dunkler als im ersten Anlauf (.45 -> .85): Auf dem
tiefgruenen Untergrund war der Unterschied nicht zu erkennen, und
eine Perforation, die man nicht sieht, ist keine. */
background-image:
radial-gradient(circle at 100% 50%,
rgba(2, 5, 9, .85) 0 3.2px, transparent 3.8px);
background-size: 100% 12px;
background-repeat: repeat-y;
}
/* 2. Die Raendelung der Muenze. Sie liegt UNTER der gewoelbten
Flaeche, deshalb sieht man sie nur als gekerbten Rand. */
.zahlen-leer__haken { position: relative; }
.zahlen-leer__haken::before {
content: ""; position: absolute; inset: -1px;
border-radius: 50%; z-index: 0;
/* 28 Kerben, nicht 40. Bei einer Muenze von 32 px war jede Kerbe
2,5 px breit und damit auf einem gewoehnlichen Bildschirm nicht
mehr aufzuloesen -- man sah eine Schattierung, keine Riffelung.
Mit 28 sind es 3,6 px, und sie sind zu erkennen, ohne zu zaehlen. */
background: repeating-conic-gradient(
rgba(190, 245, 215, .55) 0deg 6.4deg,
rgba(6, 18, 14, .9) 6.4deg 12.85deg);
/* NUR DER RAND, UND DAS IST DER GANZE PUNKT.
Im ersten Anlauf lag die Raendelung mit `z-index: -1` HINTER der
Muenze -- deren Flaeche ist aber halbdurchsichtig, also schienen
die Kerben ueber die ganze Scheibe durch. Im Bildschirmfoto sah es
aus wie eine Sonne mit Strahlen, nicht wie eine Muenze.
Jetzt liegt sie DAVOR und wird maskiert: Innen durchsichtig, ab 74
Prozent des Radius deckend. Uebrig bleibt ein schmaler gekerbter
Ring genau da, wo bei einem echten Geldstueck die Riffelung
sitzt. */
/* DAS BAND MUSS BREIT GENUG SEIN, UM ES ZU SEHEN. Mit 70..74 %
blieben bei 16 px Radius rund 0,6 px uebrig -- rechnerisch ein
Ring, auf dem Bildschirm ein Hauch. Nachgerechnet: 60..100 % sind
6,4 px, und genau so breit ist die Riffelung an einem echten
Geldstueck im Verhaeltnis zum Durchmesser. */
-webkit-mask: radial-gradient(circle, transparent 0 60%, #000 66% 100%);
mask: radial-gradient(circle, transparent 0 60%, #000 66% 100%);
}
/* Der Haken gehoert ueber die Raendelung -- sonst liegt der Ring auf
ihm. */
.zahlen-leer__haken svg { position: relative; z-index: 1; }
/* =====================================================================
DAS LETZTE GLIED LEUCHTET (screen5, 09.09.2026)
Filipe: "ich will dass du die punkte ersetzt und immer der letzte
soll mehr strahlen oder so, mach das richtig geil."
An dieser Stelle liefen bis heute drei HTML-Perlen auf eigenen
Bahnen. Sie waren ein zweites Ding an einer zweiten Stelle -- mit
eigener Winkelrechnung, eigener Farbe und eigener Groesse. Genau
deshalb standen sie am 08.09. in den falschen Farben, als die Bahnen
getauscht wurden: Wer eine Sache an zwei Orten fuehrt, aendert
irgendwann nur einen.
Jetzt zeichnet eine zweite SVG-Lage dasselbe letzte Glied noch
einmal -- heller, mit engem Schein. Sie kann gar nicht danebenstehen:
Ort und Laenge kommen aus derselben Funktion wie die Reihe darunter.
HELLER STATT GROESSER. Der Kopf hat dieselbe Breite und dieselbe
Laenge wie jedes andere Glied. Waere er groesser, waere er ein
Fremdkoerper in der Reihe; heller ist er dasselbe Glied, nur eben das
aktuelle. Das ist der Unterschied zwischen einem Zeiger, der auf die
Reihe zeigt, und einer Reihe, die selbst sagt, wo sie steht.
AUGENSCHONEND: Der Schein ist ENG (2 bis 3 px) und pulsiert nicht.
Er soll die Stelle markieren, nicht die Aufmerksamkeit fesseln -- die
Uhr steht dauerhaft im Bild. Eine Ueberblendung von .25 s macht den
Sprung von Glied zu Glied weich, ohne dass etwas wandert.
===================================================================== */
.uhr__kopf {
fill: none;
stroke-linecap: inherit;
transition: stroke-dashoffset .25s cubic-bezier(.34, 1.2, .64, 1);
}
.uhr__kopf--sekunde {
stroke: #dff2ff;
stroke-width: 3.6;
stroke-linecap: round;
filter: drop-shadow(0 0 2.4px rgba(150, 215, 250, .95));
}
.uhr__kopf--minute {
stroke: #ffffff;
stroke-width: 5.2;
filter: drop-shadow(0 0 2.2px rgba(226, 238, 250, .9));
}
/* DER KOPF DER STUNDE BLEIBT ROT (09.09.2026, screen2).
Er stand auf #ffd9dd -- fast weiss. Damit war das aktuelle Glied
zwar das hellste, aber es hatte die Farbe seiner Bahn verloren: Im
Bildschirmfoto sah es aus, als staende dort ein Fremdkoerper
zwischen den roten Balken. Bei Sekunde und Minute faellt das nicht
auf, weil Babyblau und Silber ohnehin hell sind.
Jetzt ein helles, aber deutliches Rot. Es hebt sich durch HELLIGKEIT
und Schein von den anderen elf ab, nicht durch eine andere Farbe --
das ist der Unterschied zwischen "das ist die aktuelle Stunde" und
"da stimmt etwas nicht". */
.uhr__kopf--stunde {
stroke: #c59cfc;
stroke-width: 6;
filter: drop-shadow(0 0 3px rgba(187, 132, 254, .95));
}
/* Wer weniger Bewegung will, bekommt den Sprung ohne Ueberblendung --
der Kopf steht dann einfach am richtigen Glied. */
@media (prefers-reduced-motion: reduce) {
.uhr__kopf { transition: none; }
}
/* Die Zahlenkarten fuehren zu ihren Aufgaben (screen1, 09.09.2026).
Der Link fuellt die ganze Kachel -- ein Ziel von 150 x 70 Pixeln
statt eines von der Groesse der Zahl. Die Kachel selbst bleibt das
<li>: Sie traegt die Fase und das Kantenlicht aus der Modulliste,
und die sollen nicht am Link haengen. */
.zahl { position: relative; }
.zahl__link {
display: flex; flex-direction: column; gap: 2px;
color: inherit; text-decoration: none;
}
/* DIE TREFFERFLAECHE WIRD GESTRECKT, NICHT DER LINK GEPOLSTERT.
Im ersten Anlauf stand hier `padding: inherit` -- das haette die
14/16 der Kachel ein ZWEITES Mal aufgetragen, weil `.zahl` sie schon
hat. Die Kachel waere um 28 px gewachsen, und zwar siebenmal
nebeneinander.
Ein durchsichtiges `::after` ueber die ganze Kachel loest dasselbe
ohne eine einzige Groessenangabe: Der Link bleibt, wo er ist, sein
ANKLICKBARER Bereich ist die Kachel. Das ist der uebliche Weg fuer
"die ganze Karte ist ein Link" und braucht kein JavaScript. */
.zahl__link::after {
content: ""; position: absolute; inset: 0;
}
/* Beim Zeigen kommt die Kachel naeher -- dieselbe Sprache wie ueberall,
und der Cursor sagt zusaetzlich, dass es weitergeht. */
.zahl:has(.zahl__link:hover) { background: rgba(255, 255, 255, .045); }
.zahl__link:focus-visible {
outline: 2px solid var(--akzent); outline-offset: -3px;
border-radius: 2px;
}
/* =====================================================================
DIE KATEGORIETITEL WERDEN TYPENSCHILDER (screen2, 09.09.2026)
Filipe: "die titel von den kategorien sollen spezieller und geiler
sein."
Sie waren ein kurzer Farbstrich, Grossbuchstaben und eine runde
Pille als Lesezone. Solide -- aber die runde Pille war inzwischen
das einzige Rund auf einer Seite, die sonst aus abgeschraegten
Platten besteht. Etwas, das als einziges anders geformt ist, sieht
nicht besonders aus, sondern uebriggeblieben.
VIER SACHEN MACHEN AUS EINER BESCHRIFTUNG EIN TYPENSCHILD, und alle
vier gibt es hier schon als Sprache -- sie waren nur an dieser
Stelle nicht benutzt:
1. DIE FASE statt der Rundung. Dieselbe abgeschraegte Ecke wie
jede Kachel; das Schild gehoert damit sichtbar zur Seite.
2. EIN GEPRAEGTER ANSCHLAG links statt des Strichs: drei kurze
Balken uebereinander in der Hausfarbe, wie die Kerbung an
einem Messinstrument. Er sagt "hier beginnt ein Abschnitt",
ohne ein Wort dafuer zu brauchen.
3. GEBUERSTETES METALL in der Schrift -- oben hell, in der Mitte
dunkel, unten hell. Derselbe Verlauf wie auf dem Titel der
Anmeldekarte, nur kleiner. Ein Verlauf von hell nach dunkel
waere eine Faerbung; erst der WECHSEL liest sich als Material.
4. EINE AUSLAUFENDE LINIE nach rechts. Sie gliedert, ohne die
Seite zu zerschneiden -- dieselbe Loesung wie bei den
Gruppenkoepfen.
DIE LESEZONE BLEIBT. Sie ist der Grund, warum diese Schilder auf dem
Hintergrundbild lesbar sind, und sie wurde einmal aus einer
Kontrastmessung heraus eingebaut. Sie wird hier nur umgeformt, nicht
abgeschafft -- und eher dichter als vorher (.74 -> .82), weil die
Fase an den Ecken Flaeche wegnimmt.
DER RUECKFALL IST VOLLWERTIG: `color` bleibt gesetzt, der
Metallverlauf kommt erst in einem `@supports`. Faellt
`background-clip: text` aus, steht dort schlicht heller Text --
nicht unsichtbarer.
===================================================================== */
body.start .dran .feldschild,
body.start .zahlen-block .feldschild,
body.start .protokoll-block .feldschild,
body.start .k-leiste .feldschild {
/* `display: flex` MUSS HIER STEHEN, und das ist ein Fund.
Weiter oben (Abschnitt "Abschnittsschilder") setzt
`.zahlen-block .feldschild` schon `display: flex` -- damit der
Strich davor ueberhaupt eine Box bekommt. Rund 1200 Zeilen
spaeter steht `.inhalt .feldschild { display: block }`. Beide
haben dieselbe Spezifitaet, also gewinnt die spaetere: Die
Schilder waren `block`, das Pseudoelement damit `inline`, und ein
Inline-Kasten ignoriert `width` und `height`.
FOLGE: Der "leuchtende Strich", der weiter oben ausfuehrlich
begruendet ist, wurde nie gezeichnet. Aufgefallen ist es erst,
als mein neuer Anschlag ebenfalls unsichtbar blieb -- und die
Messung sagte, der Text beginne bei x=12, also genau an der
Polsterung, ohne dass davor irgendetwas Platz belegt.
Diese Regel hat mit `body.start` eine Klasse mehr und gewinnt
ueber beide. */
display: flex; align-items: center;
position: relative;
gap: 11px;
padding: 7px 30px 7px 12px;
margin-left: -12px;
border-radius: 0;
clip-path: polygon(9px 0, 100% 0, 100% calc(100% - 9px), calc(100% - 9px) 100%, 0 100%, 0 9px);
background:
linear-gradient(96deg, rgba(6, 9, 16, .82), rgba(6, 9, 16, .42) 78%, transparent),
linear-gradient(180deg, rgba(150, 186, 220, .07), transparent 60%);
box-shadow:
inset 0 1px 0 rgba(170, 205, 240, .10),
inset 0 -1px 0 rgba(0, 0, 0, .45);
}
/* Der Anschlag: drei Kerben statt eines Strichs. Ein
`repeating-linear-gradient` macht sie aus einer Flaeche -- kein
zusaetzliches Element fuer drei Striche. */
body.start .dran .feldschild::before,
body.start .zahlen-block .feldschild::before,
body.start .protokoll-block .feldschild::before,
body.start .k-leiste .feldschild::before {
content: "";
width: 13px; height: 12px;
border-radius: 0;
opacity: 1;
background: repeating-linear-gradient(180deg,
var(--akzent) 0 2px, transparent 2px 5px);
-webkit-mask: linear-gradient(90deg, #000 0 55%, rgba(0, 0, 0, .35) 100%);
mask: linear-gradient(90deg, #000 0 55%, rgba(0, 0, 0, .35) 100%);
}
/* Die auslaufende Linie rechts. Sie beginnt hinter dem Text und
verliert sich -- eine durchgezogene Linie ueber die ganze Breite
zerschneidet die Seite, eine auslaufende gliedert sie nur. */
body.start .dran .feldschild::after,
body.start .zahlen-block .feldschild::after,
body.start .protokoll-block .feldschild::after,
body.start .k-leiste .feldschild::after {
content: "";
position: absolute; right: 8px; top: 50%;
width: 16px; height: 1px;
transform: translateY(-.5px);
background: linear-gradient(90deg,
color-mix(in srgb, var(--akzent) 55%, transparent), transparent);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
body.start .dran .feldschild,
body.start .zahlen-block .feldschild,
body.start .protokoll-block .feldschild,
body.start .k-leiste .feldschild {
/* Der Verlauf faerbt NUR die Schrift. `background-clip: text`
braucht dafuer einen eigenen Hintergrund -- deshalb steht die
Lesezone hier noch einmal darunter, sonst waere sie mit
weggeschnitten. Die Reihenfolge ist entscheidend: erst der
Textverlauf, dann die Flaechen. */
background:
linear-gradient(178deg, #ffffff 0%, #dbe6f2 34%, #91a6bd 62%, #d5e3f2 88%, #ffffff 100%)
text,
linear-gradient(96deg, rgba(6, 9, 16, .82), rgba(6, 9, 16, .42) 78%, transparent),
linear-gradient(180deg, rgba(150, 186, 220, .07), transparent 60%);
-webkit-background-clip: text, border-box, border-box;
background-clip: text, border-box, border-box;
color: transparent;
}
}
/* =====================================================================
DIE STUFENLEITER (screen7, 09.09.2026)
Filipe: "ich will dass es in diesen kategorien ... kategorien gibt
wie jetzt, aber für anfänger, fortgeschrittene, profis .... und dan
will ich dass du das perfekt alles aufbaust ... komplett
profissionell und krasser."
VIER STUFEN, VIER FARBEN -- aber die Farben sind nicht ausgesucht,
sondern geliehen: Es sind dieselben vier, die auf der Übersicht
schon "offen / dringend / läuft / erledigt" tragen. Wer die eine
Seite kennt, liest die andere ohne Legende. Eine fünfte Farbfamilie
hätte niemandem geholfen.
Anfänger Babyblau — das Ruhige, der Anfang
Fortgeschritten Lila — in Bewegung
Profi Bernstein — es wird gemessen
Meister Grün — es läuft auch ohne dich
AUFSTEIGEND HELLER, NICHT LAUTER. Die Stufen sind eine Leiter, keine
Warnstufen -- "Meister" ist kein Alarm. Deshalb tragen alle vier
dieselbe Deckkraft; nur der Farbton wechselt. Wer eine Stufe wählt,
sieht sie kräftig, die anderen bleiben still.
DER GEWÄHLTE KNOPF IST GEDRÜCKT, NICHT NUR GEFÄRBT: eingelassener
Schatten statt Erhebung. Auf einem Farbfeld allein könnte man
("welcher ist jetzt an?") raten -- an einer Vertiefung nicht.
===================================================================== */
.stufenleiter {
display: flex; flex-wrap: wrap; gap: 8px;
margin: 2px 0 14px;
}
.stufenleiter__knopf {
--sf: var(--akzent);
display: inline-flex; align-items: baseline; gap: 8px;
padding: 7px 13px;
border: 0;
clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
background:
linear-gradient(150deg, color-mix(in srgb, var(--sf) 13%, transparent), transparent 62%),
linear-gradient(180deg, rgba(19, 26, 38, .92), rgba(10, 14, 22, .95));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .07),
inset 2px 0 0 color-mix(in srgb, var(--sf) 55%, transparent);
color: var(--text-leise);
font: inherit; font-size: .8rem; font-weight: 600;
cursor: pointer;
transition: color var(--tempo), box-shadow var(--tempo), background var(--tempo);
}
.stufenleiter__knopf[data-stufe="alle"] { --sf: #9fb3c8; }
/* „AN ALLE" bei „An wen" (24.09.2026).
Filipe: „bei an ween fehlt noch die option alle neben den namen
allen."
Derselbe helle, farblose Ton wie die Stufe „Alle" eine Zeile
darueber -- beide bedeuten dasselbe („keine Einschraenkung"), und
zwei verschiedene Farben dafuer waeren zwei Aussagen fuer einen
Gedanken. Der Name steht fett, weil er fuer sechs Menschen gilt
und nicht fuer einen. */
.stufenleiter__knopf[data-alle="ja"] { --sf: #9fb3c8; }
.stufenleiter__knopf[data-alle="ja"] .stufenleiter__name { font-weight: 700; }
.stufenleiter__knopf[data-stufe="anfaenger"] { --sf: #7ec8f2; }
.stufenleiter__knopf[data-stufe="fort"] { --sf: #a78bfa; }
.stufenleiter__knopf[data-stufe="profi"] { --sf: #e8a94e; }
.stufenleiter__knopf[data-stufe="meister"] { --sf: #5fc99a; }
/* DIE DREI STUFEN DES TEAMS (16.09.2026). Dieselbe Reihe, zweite
Ebene: oben die Kategorie, darunter fuer wen die Aufgabe gedacht
ist. Die Toene steigen wie bei den Creator-Stufen -- hell fuer den
Anfang, warm fuer das, was Verantwortung traegt. */
.stufenleiter__knopf[data-stufe="neu"] { --sf: #7ec8f2; }
.stufenleiter__knopf[data-stufe="dabei"] { --sf: #a78bfa; }
.stufenleiter__knopf[data-stufe="erfahren"] { --sf: #e8a94e; }
/* Die zweite Reihe steht dichter unter der ersten und traegt weniger
Gewicht: Sie waehlt innerhalb dessen, was oben schon gewaehlt ist. */
/* DIE DRITTE REIHE: an wen die Aufgabe geht.
Etwas kleiner als die zwei darueber, weil sie etwas anderes waehlt --
keinen Ausschnitt des Katalogs, sondern einen Menschen. */
.stufenleiter--wer { margin: -4px 0 12px; }
.stufenleiter--wer .stufenleiter__knopf { padding: 5px 11px; font-size: .76rem; }
/* WER SCHON ETWAS LIEGEN HAT (16.09.2026).
Beim Vergeben einer Aufgabe steht neben jedem Namen, wie viel offen
ist. Die Zahl allein bekommt KEINE Farbe: Was "zu viel" ist, haengt
vom Menschen ab, und eine feste Grenze waere geraten.
Was nicht geraten ist: dass etwas ueberfaellig liegt. Nur das wird
markiert -- und zwar gedeckt, nicht grell. Ein Warnton an einem
Namen liest sich sonst wie ein Vorwurf gegen die Person, dabei ist
es eine Auskunft ueber die Verteilung. */
.stufenleiter__knopf[data-spaet="ja"] { --sf: #cc9451; }
.stufenleiter__spaet {
font-size: .72rem; color: #d8a76a;
font-variant-numeric: tabular-nums;
}
.stufenleiter__knopf:hover {
color: var(--text);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .11),
inset 3px 0 0 var(--sf);
}
/* Gewählt: die Fläche trägt die Farbe, und der Knopf sitzt tiefer. */
.stufenleiter__knopf[aria-pressed="true"] {
color: color-mix(in srgb, var(--sf) 80%, #ffffff);
background:
linear-gradient(150deg, color-mix(in srgb, var(--sf) 26%, transparent), transparent 70%),
linear-gradient(180deg, rgba(12, 17, 26, .96), rgba(7, 10, 17, .97));
box-shadow:
inset 0 2px 5px -2px rgba(0, 0, 0, .9),
inset 3px 0 0 var(--sf);
}
.stufenleiter__zahl {
font-size: .72rem; font-variant-numeric: tabular-nums;
color: var(--text-still);
}
.stufenleiter__knopf[aria-pressed="true"] .stufenleiter__zahl {
color: color-mix(in srgb, var(--sf) 55%, #cfd9e6);
}
.stufenleiter__hilfe {
margin: -8px 0 14px;
font-size: .82rem; color: var(--text-leise);
max-width: 68ch;
}
/* Die Könnensstufe am einzelnen Punkt -- klein, damit sie den Titel
nicht überstimmt. Sie ist eine Einordnung, keine Überschrift.
Sie heißt `__koennen` und nicht `__stufe`: Letzteres ist hier schon
vergeben und trägt den BEARBEITUNGSstand (Offen / Passt so /
Verbessern). Im ersten Anlauf hatte ich den Namen ein zweites Mal
benutzt -- gemessen standen danach 66 Marken an 33 Punkten. */
.fest-punkt__koennen {
--sf: #9fb3c8;
display: inline-block; margin-top: 6px;
padding: 2px 8px;
/* 0,72 rem = 11,52 px. Mit 0,66 waeren es 10,56 gewesen, und
pruef-css-klassen hat es sofort gemeldet: 44 Stellen unter 11,5 px
statt der Grundlinie 43. Eine Grundlinie, die man beim Hinzufuegen
still ueberschreitet, ist keine. */
font-size: .72rem; font-weight: 700;
letter-spacing: .07em; text-transform: uppercase;
color: color-mix(in srgb, var(--sf) 78%, #ffffff);
background: color-mix(in srgb, var(--sf) 13%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sf) 34%, transparent);
clip-path: polygon(5px 0, 100% 0, 100% calc(100% - 5px), calc(100% - 5px) 100%, 0 100%, 0 5px);
}
.fest-punkt__koennen[data-stufe="anfaenger"] { --sf: #7ec8f2; }
.fest-punkt__koennen[data-stufe="fort"] { --sf: #a78bfa; }
.fest-punkt__koennen[data-stufe="profi"] { --sf: #e8a94e; }
.fest-punkt__koennen[data-stufe="meister"] { --sf: #5fc99a; }
.fest-gruppe__leer {
margin: 4px 0 0; padding: 10px 12px;
font-size: .85rem; color: var(--text-still);
border: 1px dashed rgba(150, 186, 220, .22);
}
/* =====================================================================
DIE KOPFLEISTE BLEIBT AUF DEM HANDY IN EINER REIHE (09.09.2026)
Filipe, mit Bildschirmfoto: "ich will dass es überall perfektionniert
wird. ich will dass du das richtig geil machst es soll alles in einer
reihe sein."
GEMESSEN, BEVOR ETWAS GEÄNDERT WURDE (390 px, alle fünf Rollen):
verfügbar für die rechte Gruppe 275 px
gebraucht als DogFather 393 px (Sicht 150 · Teilen 38 ·
Chat 37 · Suche 47 · Bild 28 ·
Abmelden 93)
gebraucht als Scout/Manager 243 px
gebraucht als Creator 205 px
Der Umbruch war also die richtige Antwort auf ein echtes
Platzproblem -- `flex-wrap` misst und rechnet nicht, das bleibt auch
so. Geändert wird der PLATZBEDARF, nicht die Reaktion darauf. Eine
Schwelle, ab der nicht mehr umgebrochen wird, wäre wieder eine
Rechnung von gestern: Beim nächsten Knopf stünde alles übereinander.
Was schrumpft, und was nicht:
* Die drei Zeichen-Knöpfe werden gleich groß (36 px) -- vorher
waren sie 38, 37 und 47, was nebeneinander unruhig aussah.
* "Abmelden" wird zum Zeichen (93 -> 36). Das Wort bleibt für
Vorleseprogramme im aria-label.
* Der Sicht-Umschalter zeigt nur noch das Auge -- ABER NUR,
solange die eigene Sicht läuft. Bei einer fremden Sicht behält
er den Namen, und dann darf die Leiste auch umbrechen: Dass man
fremde Zahlen ansieht, ist wichtiger als eine gerade Zeile.
Rechnung danach bei 360 px, dem schmalsten Gerät: 36+36+36+28+36
= 172 plus vier Abstände zu 6 = 196, verfügbar 249.
===================================================================== */
@media (max-width: 560px) {
/* DAS SICHERHEITSNETZ (19.09.2026).
Im Haus sind schon zweimal Umbrüche auf eine feste Zahl gerechnet
worden -- und beide Male kam später ein Knopf dazu, den die Zahl
nicht kannte. Beim zweiten Mal lag der Sicht-Umschalter quer über
dem Chat-Knopf, und wer auf „Meine Sicht" tippte, landete im Chat.
Statt einer dritten Zahl hier eine REGEL: Die Reihe darf umbrechen.
Sie tut es genau dann, wenn der Platz wirklich nicht reicht -- und
nie, solange er reicht. Ein Kopf, der eine Zeile höher wird, ist
unangenehm; zwei Knöpfe übereinander sind ein Fehler.
Dazu darf die Marke schrumpfen (min-width: 0), damit die Knöpfe
ihre Größe behalten und nicht sie als Erstes nachgeben. */
.kopfleiste__rechts { gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.kopfleiste .marke { min-width: 0; }
.kopfleiste .marke__text { overflow: hidden; text-overflow: ellipsis; }
/* Alle Zeichen-Knöpfe auf ein Maß. 36 px ist knapp über der Grenze,
ab der man danebentippt, und lässt vier davon nebeneinander. */
.kopfleiste__rechts > .teilen,
.kopfleiste__rechts > .chat-knopf,
.kopfleiste__rechts > .suche-knopf,
/* DIE GLOCKE STAND HIER NICHT (nachgetragen 19.09.2026).
Sie ist ein echtes <button> und wurde damit von der 44-px-Regel
erfasst, waehrend ihre vier Nachbarn durch diesen staerkeren
Selektor auf 36 px gehen. Zwischen 401 und 560 px -- also bei
412 px (haeufigste Android-Breite) und 430 px (iPhone Pro Max) --
stand damit eine 44 px hohe runde Pille zwischen fuenf 36-px-
Quadraten. Der 400er-Block darunter listet sie korrekt; genau
dieses Band fiel durch beide Rechnungen.
Dasselbe Muster wie am 06.09.: eine Liste fuer vier Elemente,
und das fuenfte kam spaeter dazu. */
.kopfleiste__rechts > .glocke,
.kopfleiste__rechts > .abmelden {
/* 44 STATT 36 PIXEL (19.09.2026) — und das ist NACHGEMESSEN, nicht
gerechnet.
Der erste Handy-Rundgang über die Team-Dogi-Adresse meldete auf
JEDER Seite dieselben drei bis fünf Knöpfe als zu klein. Das ist
genau das, was ein Mensch als „der Knopf geht nicht" erlebt: Man
tippt, trifft daneben, und nichts passiert.
Die Verkleinerung war ein Platzsparen, das nie nötig war. Am
echten Aufbau gemessen (Marke, Teilen, Chat, Suche, Wer,
Abmelden):
Breite belegt bei 44px nötig verfügbar
360 px 237 284 328
390 px 237 284 358
412 px 245 284 380
Es passt auf jedem Gerät, mit Luft. Die 36 px waren Vorsicht vor
einem Platzmangel, den es nicht gibt.
44 px ist keine gegriffene Zahl: Es ist das Maß, das ein Daumen
sicher trifft, und der Wert, den die Richtlinie dafür nennt. */
width: 44px; min-width: 44px; height: 44px; min-height: 44px;
padding: 0; gap: 0;
display: inline-grid; place-items: center;
}
.abmelden__text { display: none; }
.abmelden__zeichen {
width: 18px; height: 18px;
fill: none; stroke: currentColor; stroke-width: 1.8;
stroke-linecap: round; stroke-linejoin: round;
}
/* Der Umschalter wird ein Zeichen-Knopf wie die anderen -- aber NUR,
solange die eigene Sicht laeuft. Bei einer fremden behaelt er den
Namen, und dann darf die Leiste auch umbrechen: Dass man fremde
Zahlen ansieht, ist wichtiger als eine gerade Zeile.
Der Knopf liegt unsichtbar UEBER dem Auge, statt daneben. Das
bewahrt die Bedienbarkeit (die ganze Flaeche ist das Ziel) und den
Fokusring, kostet aber keine Breite. */
/* NACHTRAG 09.09.2026 -- DAS `:not()` IST WEG, UND DAS IST DER KERN.
Filipe aus der installierten App: "es ist noch nicht alles in einer
zeile." Gemessen lag es nicht an seinem Geraet, sondern an genau
diesem `:not([data-fremd="ja"])`: In der eigenen Sicht klappte der
Umschalter auf 36 px zusammen, in einer fremden blieb er 152 px
breit. Auf 320, 360, 390, 412 UND 430 px waren es dann zwei Zeilen
-- ausnahmslos.
Der Satz darueber ("dann darf die Leiste auch umbrechen") war ein
Handel, den ich mit mir selbst gemacht habe: Name gegen gerade
Zeile. Beides geht -- der Name muss nur woandershin. Er steht jetzt
vollstaendig im Band unter der Leiste (.fremd-band), und im Knopf
bleiben Farbe und Anfangsbuchstabe.
Eine Regel fuer beide Faelle, nicht zwei nebeneinander: Der
Unterschied ist die Breite und ein Buchstabe, sonst nichts. */
.sicht {
position: relative;
width: 36px; min-width: 36px; height: 36px;
padding: 0; gap: 0; justify-content: center;
}
/* Neben dem Auge steht in fremder Sicht noch der Buchstabe. 48 statt
36 px -- gemessen 12 px mehr gegenueber 116 px vorher. */
.sicht[data-fremd="ja"] {
width: 48px; min-width: 48px;
gap: 2px;
}
.sicht .sicht__auge { position: relative; z-index: 0; }
.sicht .sicht__kuerzel { position: relative; z-index: 0; display: block; }
.sicht .wahl2 { position: absolute; inset: 0; z-index: 1; }
.sicht .wahl2__knopf {
width: 100%; height: 100%; padding: 0;
background: none; border-color: transparent;
}
.sicht .wahl2__knopf svg { display: none; }
/* Das Kreuz entfaellt -- der Weg zurueck steht als ganzer Satz im
Band darunter, und dort ist er leichter zu treffen als ein
28-px-Kreuz zwischen zwei anderen Knoepfen. */
.sicht .sicht__weg { display: none; }
/* DER KNOPF WIRD GEKLAMMERT, NICHT SEIN KASTEN.
Erster Anlauf war `max-width: 30px` am umgebenden .wahl2. Gemessen
stand danach genau das da: berechnete Hoechstbreite 30 px --
tatsaechliche Breite 104. Der Knopf DARIN behielt seine Groesse und
schob den Kasten wieder auf. Wer nur den Rahmen begrenzt, begrenzt
nichts; die Breite kommt vom Inhalt. */
.sicht .wahl2,
.sicht .wahl2__knopf { max-width: none; min-width: 0; }
.sicht .wahl2__text { display: none; }
/* DAS BAND ERSCHEINT GENAU DA, WO DER NAME AUS DER LEISTE WEICHT.
Beide Regeln stehen in derselben Medienabfrage und in derselben
Datei -- sonst waere es wieder die alte Falle: eine Schwelle fuer
"Name weg" und eine zweite fuer "Band da", und beim naechsten
Verschieben stimmt nur noch eine davon. */
/* Das Band steht seit dem 11.09.2026 ohnehin ueberall (siehe oben).
Auf dem Handy bleibt nur die engere Polsterung. */
.fremd-band { padding-inline: clamp(12px, 4vw, 18px); }
}
/* =====================================================================
SEHR SCHMALE GERAETE (bis 400 px) — 09.09.2026
Hier stand einmal 340 px. Gemessen reichte das nicht: Bei 360 px war
die Leiste auf den UNTERSEITEN immer noch zweizeilig, weil dort der
Zurueck-Knopf (38 px) und die Glocke zusaetzlich stehen. Die Rechnung
bei 360 px, Unterseite, fremde Sicht:
zurueck 38 + Umschalter 48 + Teilen 36 + Chat 36 + Suche 36
+ wer 28 + Glocke 37 + Abmelden 36 = 295
dazu 7 Abstaende zu 6 px = 42
dazu der Abstand zur Marke = 16
---
353 bei 328 verfuegbar
25 px zu viel. Mit 34 px je Knopf und 4 px Abstand sind es 24 px
weniger bei den Knoepfen und 14 bei den Abstaenden — es passt mit
Luft, ohne dass eine Funktion verschwindet.
34 px liegt weiterhin deutlich ueber den 24 px, die WCAG 2.5.8 als
Untergrenze nennt. Kleiner sollte es nicht werden; dann waere das
Weglassen eines Knopfes die ehrlichere Loesung als ein Ziel, das man
nicht mehr trifft.
DIESER BLOCK MUSS HINTER DEM 560er STEHEN. Beide setzen `width` am
selben Element mit derselben Spezifitaet — dann entscheidet die
Reihenfolge. Vorher stand er 3600 Zeilen weiter oben und wirkte nur
deshalb, weil sein Selektor zufaellig ein `:not()` enthielt.
===================================================================== */
@media (max-width: 400px) {
.kopfleiste__rechts { gap: 4px; }
.kopfleiste__rechts > .teilen,
.kopfleiste__rechts > .chat-knopf,
.kopfleiste__rechts > .suche-knopf,
.kopfleiste__rechts > .abmelden,
.kopfleiste__rechts > .glocke,
.sicht {
/* AUCH HIER 44 (19.09.2026). Bei 360 px war das der engste Fall
der Messung -- und selbst dort bleiben 44 px übrig. Ein Knopf,
den man nicht trifft, spart keinen Platz, er kostet einen
Versuch. */
width: 44px; min-width: 44px; height: 44px; min-height: 44px;
}
/* Der Buchstabe braucht auch hier seine 12 px daneben. */
.sicht[data-fremd="ja"] { width: 46px; min-width: 46px; }
}
/* Am Rechner bleibt das Wort -- dort ist Platz, und ein Wort ist
eindeutiger als ein Bild. Das Zeichen steht davor. */
.abmelden__zeichen {
width: 16px; height: 16px; flex: none;
fill: none; stroke: currentColor; stroke-width: 1.8;
stroke-linecap: round; stroke-linejoin: round;
}
/* =====================================================================
DIE CODE-ANZEIGE (umgezogen aus personen.css, 11.09.2026)
Ein Zugangscode wird im ganzen Haus nur an zwei Stellen sichtbar:
in "Personen & Zugaenge" und am Ende des Talente-Trichters. Beide
zeigen ihn gleich -- gleiche Kante, gleiche Schrift, gleicher Satz
darunter. Zwei Gestaltungen fuer dasselbe Geheimnis waeren zwei
Gelegenheiten, eine davon zu vergessen.
Er steht hier und nicht in module.css: module.css beschreibt die
Form ALLER Karten, das hier ist ein einzelner Baustein.
===================================================================== */
.code-kasten {
margin: 0 0 26px; padding: 20px 22px;
background: linear-gradient(100deg, rgba(63, 189, 245, .12), rgba(138, 118, 255, .09));
border: 1px solid rgba(63, 189, 245, .5);
border-radius: var(--radius);
}
.code-kasten__schild {
margin: 0 0 8px; font-size: .78rem; font-weight: 600;
letter-spacing: .06em; text-transform: uppercase; color: var(--text-leise);
}
.code-kasten__code {
margin: 0 0 12px;
font-family: "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;
font-size: clamp(1.3rem, 3.4vw, 1.9rem); font-weight: 700;
letter-spacing: .12em; color: #eaf4fd;
user-select: all; /* ein Klick markiert den ganzen Code */
word-break: break-all;
}
.code-kasten__hinweis { margin: 0 0 14px; font-size: .85rem; color: var(--text-leise); }
/* =====================================================================
„WAS IST UEBER MICH GESPEICHERT?" (15.09.2026)
Der Kasten steht auf zwei Seiten, die zu verschiedenen Stilvorlagen
gehoeren -- deshalb hier in start.css, die beide laden. Er soll nicht
um Aufmerksamkeit kaempfen: Wer ihn sucht, findet ihn; wer ihn nicht
braucht, liest darueber hinweg.
===================================================================== */
.meine-daten { margin: 30px 0 34px; }
.meine-daten__kopf {
display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 8px;
}
.meine-daten__titel {
margin: 0; font-size: 1.05rem; font-weight: 640; color: var(--text);
}
.meine-daten__satz {
margin: 0 0 12px; max-width: 74ch;
font-size: .85rem; line-height: 1.6; color: var(--text-still);
}
/* ---- ANFANG GERECHNET: kachel-regenbogen.mjs ---- */
/* ERZEUGT VON tools/kachel-regenbogen.mjs — NICHT VON HAND ÄNDERN.
99 Punkte in drei Größen, jede Größe einmal alle
33 benutzten Kacheltöne. Die Liste ist aus den
Kachellisten abgeleitet; wer eine Kachel hinzufügt, lässt das
Werkzeug erneut laufen. pruef-kachelfarben zählt nach, ob beides
noch zusammenpasst. */
.kachel[data-regenbogen="ja"] {
background-image:
/* 1. DER LESESAUM — er liegt ZUERST, also obenauf, und ist der
Grund, warum diese Kachel bunt sein darf, ohne dass die
Schrift leidet.
ZURUECKGENOMMEN AM 22.09.2026, und zwar auf eine Messung hin:
Mit dem Saum der Streifenfassung kam der Text hier auf
8,27:1 — bei einer Grenze von 4,5. Das war kein sicherer
Saum, das war ein Deckel: Er hat die untere Haelfte der
Kachel verschluckt, und genau dort sollten Punkte sein
(„auf der gesamten kachel"). Jetzt kuerzer und schwaecher,
der Rest der Luft bleibt als Sicherheit stehen.
pruef-kachelfarben misst es nach jedem Lauf neu. */
linear-gradient(to top,
rgba(4, 6, 14, .80) 0%, rgba(4, 6, 14, .48) 24%,
rgba(4, 6, 14, .14) 44%, transparent 60%),
/* 2. DIE VIGNETTE — außen dunkler als innen. Ohne sie wäre die
Kachel eine Fläche, mit ihr ein Ausschnitt. */
radial-gradient(120% 120% at 50% 40%, transparent 46%, rgba(3, 5, 12, .34) 100%),
/* 3. DIE GROSSEN PUNKTE, jeder mit Hof — das ist der Unterschied
zwischen einem Licht und einem gestanzten Kreis. Dieselbe
Bauart wie die „nahen Sterne" auf jeder anderen Kachel. */
radial-gradient(4.82px 4.82px at 21.3px 22.8px, color-mix(in srgb, #07fff1 88%, #ffffff), color-mix(in srgb, #07fff1 88%, #ffffff) 34%, color-mix(in srgb, #07fff1 55%, transparent) 52%, transparent 100%),
radial-gradient(5.48px 5.48px at 50.6px 7.0px, color-mix(in srgb, #fe8ebe 88%, #ffffff), color-mix(in srgb, #fe8ebe 88%, #ffffff) 34%, color-mix(in srgb, #fe8ebe 55%, transparent) 52%, transparent 100%),
radial-gradient(6.57px 6.57px at 81.2px 6.7px, color-mix(in srgb, #72d512 88%, #ffffff), color-mix(in srgb, #72d512 88%, #ffffff) 34%, color-mix(in srgb, #72d512 55%, transparent) 52%, transparent 100%),
radial-gradient(4.71px 4.71px at 110.3px 23.0px, color-mix(in srgb, #6d8cfe 88%, #ffffff), color-mix(in srgb, #6d8cfe 88%, #ffffff) 34%, color-mix(in srgb, #6d8cfe 55%, transparent) 52%, transparent 100%),
radial-gradient(4.88px 4.88px at 154.3px 8.0px, color-mix(in srgb, #c16302 88%, #ffffff), color-mix(in srgb, #c16302 88%, #ffffff) 34%, color-mix(in srgb, #c16302 55%, transparent) 52%, transparent 100%),
radial-gradient(4.83px 4.83px at 185.7px 11.5px, color-mix(in srgb, #12b37e 88%, #ffffff), color-mix(in srgb, #12b37e 88%, #ffffff) 34%, color-mix(in srgb, #12b37e 55%, transparent) 52%, transparent 100%),
radial-gradient(4.33px 4.33px at 16.5px 42.0px, color-mix(in srgb, #ff57ba 88%, #ffffff), color-mix(in srgb, #ff57ba 88%, #ffffff) 34%, color-mix(in srgb, #ff57ba 55%, transparent) 52%, transparent 100%),
radial-gradient(5.17px 5.17px at 49.7px 52.7px, color-mix(in srgb, #a2af10 88%, #ffffff), color-mix(in srgb, #a2af10 88%, #ffffff) 34%, color-mix(in srgb, #a2af10 55%, transparent) 52%, transparent 100%),
radial-gradient(4.63px 4.63px at 82.5px 47.6px, color-mix(in srgb, #027afb 88%, #ffffff), color-mix(in srgb, #027afb 88%, #ffffff) 34%, color-mix(in srgb, #027afb 55%, transparent) 52%, transparent 100%),
radial-gradient(4.55px 4.55px at 105.1px 54.1px, color-mix(in srgb, #fd6401 88%, #ffffff), color-mix(in srgb, #fd6401 88%, #ffffff) 34%, color-mix(in srgb, #fd6401 55%, transparent) 52%, transparent 100%),
radial-gradient(6.07px 6.07px at 149.6px 56.3px, color-mix(in srgb, #08eb9f 88%, #ffffff), color-mix(in srgb, #08eb9f 88%, #ffffff) 34%, color-mix(in srgb, #08eb9f 55%, transparent) 52%, transparent 100%),
radial-gradient(4.34px 4.34px at 182.8px 53.3px, color-mix(in srgb, #f4acff 88%, #ffffff), color-mix(in srgb, #f4acff 88%, #ffffff) 34%, color-mix(in srgb, #f4acff 55%, transparent) 52%, transparent 100%),
radial-gradient(5.58px 5.58px at 14.4px 89.8px, color-mix(in srgb, #cace02 88%, #ffffff), color-mix(in srgb, #cace02 88%, #ffffff) 34%, color-mix(in srgb, #cace02 55%, transparent) 52%, transparent 100%),
radial-gradient(4.55px 4.55px at 56.4px 81.9px, color-mix(in srgb, #a8d8ff 88%, #ffffff), color-mix(in srgb, #a8d8ff 88%, #ffffff) 34%, color-mix(in srgb, #a8d8ff 55%, transparent) 52%, transparent 100%),
radial-gradient(5.65px 5.65px at 78.8px 88.9px, color-mix(in srgb, #ff9d82 88%, #ffffff), color-mix(in srgb, #ff9d82 88%, #ffffff) 34%, color-mix(in srgb, #ff9d82 55%, transparent) 52%, transparent 100%),
radial-gradient(4.85px 4.85px at 113.3px 78.4px, color-mix(in srgb, #069511 88%, #ffffff), color-mix(in srgb, #069511 88%, #ffffff) 34%, color-mix(in srgb, #069511 55%, transparent) 52%, transparent 100%),
radial-gradient(4.40px 4.40px at 142.4px 90.0px, color-mix(in srgb, #e871ff 88%, #ffffff), color-mix(in srgb, #e871ff 88%, #ffffff) 34%, color-mix(in srgb, #e871ff 55%, transparent) 52%, transparent 100%),
radial-gradient(4.65px 4.65px at 190.5px 85.8px, color-mix(in srgb, #eeef08 88%, #ffffff), color-mix(in srgb, #eeef08 88%, #ffffff) 34%, color-mix(in srgb, #eeef08 55%, transparent) 52%, transparent 100%),
radial-gradient(6.19px 6.19px at 20.7px 123.9px, color-mix(in srgb, #08b5fc 88%, #ffffff), color-mix(in srgb, #08b5fc 88%, #ffffff) 34%, color-mix(in srgb, #08b5fc 55%, transparent) 52%, transparent 100%),
radial-gradient(5.44px 5.44px at 56.7px 116.6px, color-mix(in srgb, #ff1a1a 88%, #ffffff), color-mix(in srgb, #ff1a1a 88%, #ffffff) 34%, color-mix(in srgb, #ff1a1a 55%, transparent) 52%, transparent 100%),
radial-gradient(6.28px 6.28px at 89.2px 122.9px, color-mix(in srgb, #18b803 88%, #ffffff), color-mix(in srgb, #18b803 88%, #ffffff) 34%, color-mix(in srgb, #18b803 55%, transparent) 52%, transparent 100%),
radial-gradient(4.52px 4.52px at 105.6px 108.9px, color-mix(in srgb, #d21afd 88%, #ffffff), color-mix(in srgb, #d21afd 88%, #ffffff) 34%, color-mix(in srgb, #d21afd 55%, transparent) 52%, transparent 100%),
radial-gradient(4.31px 4.31px at 150.4px 108.8px, color-mix(in srgb, #918a01 88%, #ffffff), color-mix(in srgb, #918a01 88%, #ffffff) 34%, color-mix(in srgb, #918a01 55%, transparent) 52%, transparent 100%),
radial-gradient(5.83px 5.83px at 189.4px 117.4px, color-mix(in srgb, #0687bc 88%, #ffffff), color-mix(in srgb, #0687bc 88%, #ffffff) 34%, color-mix(in srgb, #0687bc 55%, transparent) 52%, transparent 100%),
radial-gradient(4.38px 4.38px at 10.9px 139.1px, color-mix(in srgb, #ff6877 88%, #ffffff), color-mix(in srgb, #ff6877 88%, #ffffff) 34%, color-mix(in srgb, #ff6877 55%, transparent) 52%, transparent 100%),
radial-gradient(6.29px 6.29px at 54.7px 155.9px, color-mix(in srgb, #a7ff98 88%, #ffffff), color-mix(in srgb, #a7ff98 88%, #ffffff) 34%, color-mix(in srgb, #a7ff98 55%, transparent) 52%, transparent 100%),
radial-gradient(6.12px 6.12px at 75.1px 154.0px, color-mix(in srgb, #ab68ff 88%, #ffffff), color-mix(in srgb, #ab68ff 88%, #ffffff) 34%, color-mix(in srgb, #ab68ff 55%, transparent) 52%, transparent 100%),
radial-gradient(6.08px 6.08px at 123.3px 154.7px, color-mix(in srgb, #ffbd4a 88%, #ffffff), color-mix(in srgb, #ffbd4a 88%, #ffffff) 34%, color-mix(in srgb, #ffbd4a 55%, transparent) 52%, transparent 100%),
radial-gradient(5.81px 5.81px at 141.2px 142.7px, color-mix(in srgb, #0ed1d0 88%, #ffffff), color-mix(in srgb, #0ed1d0 88%, #ffffff) 34%, color-mix(in srgb, #0ed1d0 55%, transparent) 52%, transparent 100%),
radial-gradient(4.42px 4.42px at 177.4px 144.5px, color-mix(in srgb, #f10778 88%, #ffffff), color-mix(in srgb, #f10778 88%, #ffffff) 34%, color-mix(in srgb, #f10778 55%, transparent) 52%, transparent 100%),
radial-gradient(5.16px 5.16px at 17.7px 183.1px, color-mix(in srgb, #61ff09 88%, #ffffff), color-mix(in srgb, #61ff09 88%, #ffffff) 34%, color-mix(in srgb, #61ff09 55%, transparent) 52%, transparent 100%),
radial-gradient(4.80px 4.80px at 46.6px 182.2px, color-mix(in srgb, #b699fe 88%, #ffffff), color-mix(in srgb, #b699fe 88%, #ffffff) 34%, color-mix(in srgb, #b699fe 55%, transparent) 52%, transparent 100%),
radial-gradient(5.00px 5.00px at 80.1px 179.7px, color-mix(in srgb, #db8908 88%, #ffffff), color-mix(in srgb, #db8908 88%, #ffffff) 34%, color-mix(in srgb, #db8908 55%, transparent) 52%, transparent 100%),
/* 4. DIE MITTLEREN — die Masse des Feldes. */
radial-gradient(3.21px 3.21px at 5.1px 5.6px, color-mix(in srgb, #07fff1 82%, #ffffff), color-mix(in srgb, #07fff1 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.60px 3.60px at 30.9px 16.4px, color-mix(in srgb, #ab68ff 82%, #ffffff), color-mix(in srgb, #ab68ff 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.00px 3.00px at 52.4px 11.5px, color-mix(in srgb, #ff1a1a 82%, #ffffff), color-mix(in srgb, #ff1a1a 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.86px 2.86px at 82.4px 14.9px, color-mix(in srgb, #cace02 82%, #ffffff), color-mix(in srgb, #cace02 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.96px 2.96px at 98.8px 9.3px, color-mix(in srgb, #12b37e 82%, #ffffff), color-mix(in srgb, #12b37e 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.65px 2.65px at 121.0px 14.2px, color-mix(in srgb, #b699fe 82%, #ffffff), color-mix(in srgb, #b699fe 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.49px 2.49px at 11.8px 26.8px, color-mix(in srgb, #ff6877 82%, #ffffff), color-mix(in srgb, #ff6877 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.92px 2.92px at 33.8px 37.3px, color-mix(in srgb, #eeef08 82%, #ffffff), color-mix(in srgb, #eeef08 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.47px 2.47px at 55.5px 38.6px, color-mix(in srgb, #08eb9f 82%, #ffffff), color-mix(in srgb, #08eb9f 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.55px 2.55px at 74.8px 28.0px, color-mix(in srgb, #6d8cfe 82%, #ffffff), color-mix(in srgb, #6d8cfe 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.43px 2.43px at 103.9px 38.4px, color-mix(in srgb, #f10778 82%, #ffffff), color-mix(in srgb, #f10778 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.62px 2.62px at 124.3px 27.3px, color-mix(in srgb, #918a01 82%, #ffffff), color-mix(in srgb, #918a01 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.61px 2.61px at 6.8px 55.0px, color-mix(in srgb, #069511 82%, #ffffff), color-mix(in srgb, #069511 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.19px 3.19px at 36.1px 60.1px, color-mix(in srgb, #027afb 82%, #ffffff), color-mix(in srgb, #027afb 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.63px 3.63px at 56.8px 55.5px, color-mix(in srgb, #fe8ebe 82%, #ffffff), color-mix(in srgb, #fe8ebe 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.62px 2.62px at 82.6px 57.2px, color-mix(in srgb, #ffbd4a 82%, #ffffff), color-mix(in srgb, #ffbd4a 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.89px 2.89px at 97.7px 59.0px, color-mix(in srgb, #18b803 82%, #ffffff), color-mix(in srgb, #18b803 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.29px 3.29px at 125.8px 57.6px, color-mix(in srgb, #a8d8ff 82%, #ffffff), color-mix(in srgb, #a8d8ff 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.52px 2.52px at 10.9px 83.0px, color-mix(in srgb, #ff57ba 82%, #ffffff), color-mix(in srgb, #ff57ba 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.37px 2.37px at 33.1px 72.6px, color-mix(in srgb, #db8908 82%, #ffffff), color-mix(in srgb, #db8908 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.21px 3.21px at 54.6px 78.8px, color-mix(in srgb, #a7ff98 82%, #ffffff), color-mix(in srgb, #a7ff98 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.43px 3.43px at 71.0px 71.9px, color-mix(in srgb, #08b5fc 82%, #ffffff), color-mix(in srgb, #08b5fc 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.16px 3.16px at 92.6px 70.6px, color-mix(in srgb, #f4acff 82%, #ffffff), color-mix(in srgb, #f4acff 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.22px 3.22px at 118.9px 78.1px, color-mix(in srgb, #c16302 82%, #ffffff), color-mix(in srgb, #c16302 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.50px 2.50px at 16.0px 101.8px, color-mix(in srgb, #61ff09 82%, #ffffff), color-mix(in srgb, #61ff09 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.80px 2.80px at 33.8px 102.3px, color-mix(in srgb, #0687bc 82%, #ffffff), color-mix(in srgb, #0687bc 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.52px 2.52px at 49.8px 93.9px, color-mix(in srgb, #e871ff 82%, #ffffff), color-mix(in srgb, #e871ff 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.87px 2.87px at 77.0px 95.8px, color-mix(in srgb, #fd6401 82%, #ffffff), color-mix(in srgb, #fd6401 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.37px 2.37px at 101.9px 95.3px, color-mix(in srgb, #72d512 82%, #ffffff), color-mix(in srgb, #72d512 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.42px 3.42px at 113.5px 91.8px, color-mix(in srgb, #0ed1d0 82%, #ffffff), color-mix(in srgb, #0ed1d0 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.22px 3.22px at 12.7px 116.5px, color-mix(in srgb, #d21afd 82%, #ffffff), color-mix(in srgb, #d21afd 82%, #ffffff) 34%, transparent 100%),
radial-gradient(2.35px 2.35px at 26.5px 120.2px, color-mix(in srgb, #ff9d82 82%, #ffffff), color-mix(in srgb, #ff9d82 82%, #ffffff) 34%, transparent 100%),
radial-gradient(3.34px 3.34px at 53.1px 119.0px, color-mix(in srgb, #a2af10 82%, #ffffff), color-mix(in srgb, #a2af10 82%, #ffffff) 34%, transparent 100%),
/* 5. DER FEINE STAUB. Er füllt die Lücken: Ein Feld aus nur
großen Punkten sieht aus wie aufgeklebt. */
radial-gradient(1.70px 1.70px at 6.2px 11.0px, color-mix(in srgb, #07fff1 74%, #ffffff), color-mix(in srgb, #07fff1 74%, #ffffff) 34%, transparent 100%),
radial-gradient(2.00px 2.00px at 19.0px 4.4px, color-mix(in srgb, #b699fe 74%, #ffffff), color-mix(in srgb, #b699fe 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.88px 1.88px at 38.0px 4.6px, color-mix(in srgb, #f10778 74%, #ffffff), color-mix(in srgb, #f10778 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.78px 1.78px at 49.4px 2.8px, color-mix(in srgb, #ffbd4a 74%, #ffffff), color-mix(in srgb, #ffbd4a 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.68px 1.68px at 65.7px 3.2px, color-mix(in srgb, #a7ff98 74%, #ffffff), color-mix(in srgb, #a7ff98 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.75px 1.75px at 77.7px 7.7px, color-mix(in srgb, #0687bc 74%, #ffffff), color-mix(in srgb, #0687bc 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.44px 1.44px at 3.7px 23.9px, color-mix(in srgb, #d21afd 74%, #ffffff), color-mix(in srgb, #d21afd 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.64px 1.64px at 23.7px 21.2px, color-mix(in srgb, #ff1a1a 74%, #ffffff), color-mix(in srgb, #ff1a1a 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.53px 1.53px at 30.8px 17.1px, color-mix(in srgb, #eeef08 74%, #ffffff), color-mix(in srgb, #eeef08 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.69px 1.69px at 46.6px 21.7px, color-mix(in srgb, #069511 74%, #ffffff), color-mix(in srgb, #069511 74%, #ffffff) 34%, transparent 100%),
radial-gradient(2.03px 2.03px at 64.3px 18.5px, color-mix(in srgb, #a8d8ff 74%, #ffffff), color-mix(in srgb, #a8d8ff 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.36px 1.36px at 77.2px 20.7px, color-mix(in srgb, #f4acff 74%, #ffffff), color-mix(in srgb, #f4acff 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.40px 1.40px at 3.8px 31.4px, color-mix(in srgb, #fd6401 74%, #ffffff), color-mix(in srgb, #fd6401 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.36px 1.36px at 17.0px 32.1px, color-mix(in srgb, #a2af10 74%, #ffffff), color-mix(in srgb, #a2af10 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.84px 1.84px at 32.1px 35.9px, color-mix(in srgb, #12b37e 74%, #ffffff), color-mix(in srgb, #12b37e 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.63px 1.63px at 48.3px 34.6px, color-mix(in srgb, #6d8cfe 74%, #ffffff), color-mix(in srgb, #6d8cfe 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.47px 1.47px at 61.7px 38.8px, color-mix(in srgb, #fe8ebe 74%, #ffffff), color-mix(in srgb, #fe8ebe 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.59px 1.59px at 73.2px 36.6px, color-mix(in srgb, #db8908 74%, #ffffff), color-mix(in srgb, #db8908 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.34px 1.34px at 2.9px 51.3px, color-mix(in srgb, #61ff09 74%, #ffffff), color-mix(in srgb, #61ff09 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.78px 1.78px at 17.6px 52.6px, color-mix(in srgb, #0ed1d0 74%, #ffffff), color-mix(in srgb, #0ed1d0 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.72px 1.72px at 35.6px 46.1px, color-mix(in srgb, #ab68ff 74%, #ffffff), color-mix(in srgb, #ab68ff 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.87px 1.87px at 50.9px 49.3px, color-mix(in srgb, #ff6877 74%, #ffffff), color-mix(in srgb, #ff6877 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.44px 1.44px at 59.6px 52.2px, color-mix(in srgb, #918a01 74%, #ffffff), color-mix(in srgb, #918a01 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.77px 1.77px at 73.3px 49.9px, color-mix(in srgb, #18b803 74%, #ffffff), color-mix(in srgb, #18b803 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.76px 1.76px at 3.5px 65.0px, color-mix(in srgb, #08b5fc 74%, #ffffff), color-mix(in srgb, #08b5fc 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.72px 1.72px at 25.0px 58.0px, color-mix(in srgb, #e871ff 74%, #ffffff), color-mix(in srgb, #e871ff 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.77px 1.77px at 30.9px 65.9px, color-mix(in srgb, #ff9d82 74%, #ffffff), color-mix(in srgb, #ff9d82 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.87px 1.87px at 51.0px 65.4px, color-mix(in srgb, #cace02 74%, #ffffff), color-mix(in srgb, #cace02 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.38px 1.38px at 61.3px 65.1px, color-mix(in srgb, #08eb9f 74%, #ffffff), color-mix(in srgb, #08eb9f 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.79px 1.79px at 78.3px 63.7px, color-mix(in srgb, #027afb 74%, #ffffff), color-mix(in srgb, #027afb 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.34px 1.34px at 9.8px 74.9px, color-mix(in srgb, #ff57ba 74%, #ffffff), color-mix(in srgb, #ff57ba 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.54px 1.54px at 20.7px 75.9px, color-mix(in srgb, #c16302 74%, #ffffff), color-mix(in srgb, #c16302 74%, #ffffff) 34%, transparent 100%),
radial-gradient(1.61px 1.61px at 31.6px 74.4px, color-mix(in srgb, #72d512 74%, #ffffff), color-mix(in srgb, #72d512 74%, #ffffff) 34%, transparent 100%),
/* 6. EIN SCHRÄGER SCHLEIER quer über das Feld. Er bindet die
99 Punkte zu einer Fläche zusammen — ohne ihn
schweben sie einzeln. Sehr blass; er soll Richtung geben,
nicht auffallen. */
linear-gradient(104deg,
rgba(255, 255, 255, .085) 0%,
rgba(255, 255, 255, .02) 36%,
rgba(0, 0, 0, .10) 70%,
rgba(0, 0, 0, .24) 100%),
/* 7. DER GRUND. Deckend, nicht durchscheinend: Die Kachel soll die
Farben des Hauses ZEIGEN, nicht durch sie hindurch das
Bühnenbild. */
linear-gradient(180deg, #0b1020 0%, #070b14 100%);
background-size:
100% 100%, 100% 100%,
197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 197px 197px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 131px 131px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px, 83px 83px,
100% 100%, 100% 100%;
background-repeat:
no-repeat, no-repeat,
repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat, repeat,
no-repeat, no-repeat;
/* Die Kante trägt den Kachelton mit — sonst wäre ausgerechnet die
farbigste Kachel der Wand einfarbig umrandet. */
border-color: color-mix(in srgb, var(--ton) 38%, transparent);
}
/* EIN RUHIGER GRUND HINTER DER SCHRIFT — und nur dort.
Beim ersten Blick aufs Handybild sass ein heller Punkt mitten unter
dem Wort „gibt". Die Messung sagte trotzdem 8,2:1 und hatte recht:
Sie mittelt ueber die ganze Textflaeche. Ein einzelner Punkt hinter
einem duennen Buchstaben verschwindet in diesem Mittel — im Auge
nicht.
ZWEI ANLAEUFE, DIE BEIDE FALSCH WAREN:
* Den Lesesaum wieder dunkler machen — dann ist die halbe Kachel
zu, und gewollt waren Punkte auf der GESAMTEN Kachel.
* Ein dunkler Teich im Kachelhintergrund, 400 px breit. Auf dem
grossen Bildschirm sass er richtig; auf dem Handy ist die
Kachel selbst nur 366 px breit, und der Teich hat fast alle
Farben geschluckt. Eine Zahl in Pixeln, die auf einem Geraet
passt, ist auf dem naechsten falsch.
RICHTIG IST, DEN GRUND AN DEN TEXT ZU HAENGEN statt an die Kachel:
Dann ist er immer genau so breit wie das, was er lesbar machen
soll — auf jedem Geraet, ohne eine einzige Schwelle. Gemessen wird
nicht, sondern abgeleitet.
"z-index: -1" legt ihn hinter die Schrift, aber vor die Punkte.
(Ohne Schraegstriche geschrieben: Dieser Kommentar steht INNERHALB
einer Vorlagenzeichenkette, und ein Gegenstrich darin beendet sie.) */
.kachel[data-regenbogen="ja"] .kachel__text { position: relative; }
.kachel[data-regenbogen="ja"] .kachel__text::before {
content: "";
position: absolute;
inset: -16px -34px -18px -22px;
z-index: -1;
/* KEIN RAND UND KEIN ECKRADIUS. Der erste Entwurf hatte beides, und
dann stand eine Karte in der Karte -- man sah den Kasten und nicht
den Text. Der Verlauf laeuft jetzt deutlich vor der Kante aus;
dadurch ist er ein Schatten und keine Flaeche. */
/* MITTIG UND KLEINER ALS DER KASTEN. Der zweite Entwurf sass bei
28 % und war 112 % breit -- am linken Rand war er damit noch fast
deckend, und das Rechteck schnitt ihn hart ab. Man sah die Kante.
Ein Verlauf, der an keiner Seite die Kante erreicht, hat auch
keine. */
background: radial-gradient(74% 90% at 50% 50%,
rgba(4, 6, 14, .86) 0%,
rgba(4, 6, 14, .60) 42%,
rgba(4, 6, 14, .18) 68%,
transparent 88%);
}
/* ---- ENDE GERECHNET ---- */
/* =====================================================================
JEDE SEITE TRAEGT IHRE FARBE -- AUCH GANZ OBEN (22.09.2026)
=====================================================================
Filipe: „je nachdem auf welcher seite ich bin wechseln gaaanz oben
in der leiste gewissene symbole und sachen mit ... ich will das auf
jeder seite ... nicht mehr wie auf screen3 sondern genau gleich wie
da."
---------------------------------------------------------------------
WARUM ES AUF DEN MEISTEN SEITEN NICHT PASSIERTE
Gemessen: `kopf.js` setzt `data-ton` am <body> -- auf JEDER Seite,
seit Langem. Die Regel, die daraus eine Akzentfarbe macht, stand
aber in `bereich.css`, und die laden genau DREI von
fuenfunddreissig Seiten. Auf den anderen zweiunddreissig war die
Farbe da und wurde nicht gelesen.
Genau deshalb war die Highlights-Seite sein Vorbild: Sie ist
`bereich.html`, also eine der drei.
---------------------------------------------------------------------
WARUM NICHT REIN, SONDERN GEMISCHT
Einige der siebzehn Toene sind sehr hell (Ton 30 ist fast
Weissgruen, Ton 36 Zitronengelb). Als Flaeche schoen, als
Akzentfarbe fuer duenne Linien und kleinen Text auf dunklem Grund
blenden sie. Die Beimischung von 12 % des ruhigen Blaugraus nimmt
diese Spitze, ohne die Kategorie unkenntlich zu machen.
Steht kein `data-ton` da (Direktaufruf ohne passende Kachel), bleibt
alles wie bisher. Eine Seite ohne Farbe ist unauffaellig, eine Seite
mit der falschen fuehrt in die Irre.
===================================================================== */
body[data-ton] {
--akzent: color-mix(in srgb, var(--ton) 88%, #6f8cab);
}
/* ---- Und die Leiste ganz oben ---------------------------------------
„gaaanz oben in der leiste" ist woertlich zu nehmen. Bisher war der
Akzent etwas, das WEITER UNTEN wirkte -- Knopfumrandungen,
Fokusringe, Linien an Karten. Die Leiste selbst blieb auf jeder
Seite gleich.
Zwei Mittel, beide leise: eine Kante unter der Leiste, die in der
Farbe der Seite beginnt und nach rechts auslaeuft, und ein Hauch
derselben Farbe hinter der Marke. Kein zweiter Balken, kein
Farbblock -- die Leiste traegt schon den Hausverlauf, und zwei
Verlaeufe uebereinander sind einer zu viel.
`::after` gehoert im Crew-Haus schon der Leiste (crew-haus.css
faerbt die Kante dort). Die Regel hier ist allgemeiner und steht
FRUEHER in der Ladereihenfolge -- das Haus gewinnt also, wenn es
etwas zu sagen hat, und sonst gilt die Farbe der Seite. Genau so
herum ist es richtig: Das Haus ist die Grundstimmung, die Seite der
Akzent darin. */
/* HIER STAND "position: relative" -- UND DAS WAR DER FEHLER
(gefunden 23.09.2026).
Die Zeile war nur dazu da, dem ::before darunter einen Bezugspunkt
zu geben. Das tut sie auch. Sie hat dabei aber das Kleben der
Leiste ueberschrieben: "body[data-ton] .kopfleiste" ist (0,2,1),
genau wie "body > .kopfleiste" -- und bei gleicher Staerke gewinnt
die spaetere Regel. Sie steht 8400 Zeilen weiter unten.
Gemessen am 23.09.: Auf jeder Seite MIT Farbton (aufgaben, chat,
wissen ...) wanderte die Leiste beim Scrollen aus dem Bild, auf
jeder ohne (entwicklung, start) blieb sie stehen. Filipe: "sonnst
muss man immer wieder hoch scrollen um zurueck zu koennen."
"data-ton" setzt kopf.js erst NACH dem Laden -- im Quelltext der
Seite steht es nicht. Deshalb war im HTML nichts zu sehen, was den
Unterschied erklaert haette; erst die Messung im Browser hat ihn
gezeigt.
ERSATZLOS WEG, nicht ersetzt: "position: sticky" ist selbst ein
Bezugspunkt fuer absolut positionierte Kinder, genauso wie
"relative". Das ::before darunter braucht also gar nichts.
Das ist die FUENFTE Spielart derselben Falle (die vier anderen
stehen oben bei Zeile 235). Damit es keine sechste gibt, misst
pruef-kopf-messen seit heute auf sechs Seiten, ob die Leiste beim
Scrollen wirklich stehen bleibt -- der Quelltext sagt es nicht. */
body[data-ton] .kopfleiste::before {
content: "";
position: absolute; left: 0; right: 0; bottom: 0;
height: 2px;
pointer-events: none;
background: linear-gradient(90deg,
color-mix(in srgb, var(--ton) 75%, transparent) 0%,
color-mix(in srgb, var(--ton) 30%, transparent) 38%,
transparent 72%);
}
/* Die Knoepfe rechts nehmen die Farbe beim Beruehren auf. Dauerhaft
eingefaerbt waeren es sechs bunte Knoepfe in derselben Farbe -- dann
traegt nicht mehr die SEITE die Farbe, sondern die Leiste, und man
sieht den Unterschied zwischen zwei Seiten nicht mehr. */
body[data-ton] .kopfleiste__rechts > *:hover {
border-color: color-mix(in srgb, var(--ton) 50%, transparent);
}
@media (forced-colors: active) {
body[data-ton] .kopfleiste::before { display: none; }
}
/* =====================================================================
DIE SILBERNE KACHEL (23.09.2026)
=====================================================================
Filipe: „ich will dass diese kachel einen richtig geilen silber hat
als farbe bitte. mach es richtig geil, ein glitzer silber."
---------------------------------------------------------------------
WARUM DUNKLES SILBER UND KEIN HELLES
„Silber" denkt man sich hell. Auf dieser Wand wäre es das Ende der
Lesbarkeit: Die Beschriftung jeder Kachel ist HELL (`--text`), und
eine helle Fläche darunter lässt davon nichts übrig. Ein zweiter
Satz Schriftfarben nur für diese eine Kachel wäre eine Sonderregel,
die beim nächsten Umbau niemand kennt.
Silber ist deshalb als METALL gebaut, nicht als Farbfläche:
Gunmetal — dunkel, kühl, mit hellen Kanten und einer Glanzbahn. Das
ist genau das, was ein Stück gebürstetes Metall im Halbdunkel
macht, und es liest sich sofort als Silber, ohne zu blenden.
---------------------------------------------------------------------
DER AUFBAU, VON OBEN NACH UNTEN
1. DER LESESAUM liegt ZUERST, also obenauf. Er ist der Grund,
warum die Fläche funkeln darf, ohne dass die Schrift leidet —
dieselbe Bauart wie bei der Regenbogen-Kachel.
2. DAS FUNKELN: feine helle Punkte, jeder mit Hof. STATISCH.
Blinkende Punkte wären genau das, was die Hausregel verbietet
(„keine aggressiven Flacker-/Strobe-Effekte").
3. DIE GLANZBAHN: ein diagonaler heller Streifen, der über das
Metall läuft.
4. DAS GEBÜRSTETE METALL: sehr feine senkrechte Streifen.
5. DER GRUNDVERLAUF: oben heller, unten dunkler — so fällt das
Licht.
===================================================================== */
.kachel[data-silber="ja"] {
/* AUCH DIE KANTEN WERDEN SILBERN (23.09.2026, nach dem ersten Bild).
------------------------------------------------------------------
Zuerst blieb `--ton` auf dem Grün der Kachel stehen -- mit dem
Gedanken „Silber ist die Fläche, nicht der Ton". Im Bildschirmfoto
sah man sofort, dass das nicht stimmt: Kantenlicht, Eckwinkel und
Schiene zogen eine grüne Linie um eine silberne Fläche. Filipe hat
nach einer silbernen KACHEL gefragt, nicht nach einer silbernen
Füllung.
`--ton` wird deshalb hier überschrieben -- NUR für diese Kachel
und NUR in der Anzeige. `data-ton="13"` bleibt am Element stehen;
die Farbwerkzeuge rechnen weiter mit Zahlen, und wer die Kachel
ohne diese Stilvorlage sieht, bekommt wieder ihr Grün. */
--ton: #c3d1e0;
--silber-hell: #e6edf5;
--silber-mittel: #9fb0c4;
--silber-tief: #2b3644;
background-image:
/* 1. LESESAUM */
linear-gradient(to top,
rgba(4, 6, 14, .78) 0%, rgba(4, 6, 14, .46) 26%,
rgba(4, 6, 14, .12) 48%, transparent 64%),
/* 2. DAS FUNKELN. Sechzehn Punkte, unregelmäßig gesetzt — ein
Raster sähe aus wie ein Muster, nicht wie Glitzer. Jeder mit
Hof: Das ist der Unterschied zwischen einem Licht und einem
gestanzten Kreis. */
radial-gradient(2.6px 2.6px at 23px 17px, #ffffff, rgba(255,255,255,.55) 38%, transparent 100%),
radial-gradient(1.8px 1.8px at 61px 34px, #f2f7ff, rgba(242,247,255,.45) 38%, transparent 100%),
radial-gradient(3.1px 3.1px at 104px 13px, #ffffff, rgba(255,255,255,.5) 36%, transparent 100%),
radial-gradient(1.6px 1.6px at 138px 41px, #e8f1ff, rgba(232,241,255,.45) 40%, transparent 100%),
radial-gradient(2.3px 2.3px at 177px 22px, #ffffff, rgba(255,255,255,.5) 38%, transparent 100%),
radial-gradient(1.9px 1.9px at 214px 48px, #f5faff, rgba(245,250,255,.42) 40%, transparent 100%),
radial-gradient(2.8px 2.8px at 259px 15px, #ffffff, rgba(255,255,255,.52) 36%, transparent 100%),
radial-gradient(1.7px 1.7px at 301px 37px, #eaf3ff, rgba(234,243,255,.44) 40%, transparent 100%),
radial-gradient(2.4px 2.4px at 344px 26px, #ffffff, rgba(255,255,255,.5) 38%, transparent 100%),
radial-gradient(1.5px 1.5px at 388px 52px, #f0f6ff, rgba(240,246,255,.4) 42%, transparent 100%),
radial-gradient(2.9px 2.9px at 431px 19px, #ffffff, rgba(255,255,255,.5) 36%, transparent 100%),
radial-gradient(1.8px 1.8px at 474px 44px, #e6f0ff, rgba(230,240,255,.42) 40%, transparent 100%),
radial-gradient(2.2px 2.2px at 47px 63px, #ffffff, rgba(255,255,255,.46) 38%, transparent 100%),
radial-gradient(1.6px 1.6px at 196px 71px, #f2f8ff, rgba(242,248,255,.4) 40%, transparent 100%),
radial-gradient(2.5px 2.5px at 322px 66px, #ffffff, rgba(255,255,255,.46) 37%, transparent 100%),
radial-gradient(1.7px 1.7px at 455px 74px, #edf4ff, rgba(237,244,255,.4) 40%, transparent 100%),
/* 3. DIE GLANZBAHN. Schmal und schräg, wie das Licht auf einer
polierten Kante. */
linear-gradient(108deg,
transparent 18%,
color-mix(in srgb, var(--silber-hell) 16%, transparent) 33%,
color-mix(in srgb, var(--silber-hell) 34%, transparent) 39%,
color-mix(in srgb, var(--silber-hell) 10%, transparent) 46%,
transparent 62%),
/* 4. GEBÜRSTETES METALL. 3 px Teilung, sehr schwach — man sieht
es nicht als Streifen, man sieht es als Oberfläche. */
repeating-linear-gradient(92deg,
rgba(255, 255, 255, .045) 0 1px,
transparent 1px 3px),
/* 5. DER GRUNDVERLAUF */
linear-gradient(163deg,
color-mix(in srgb, var(--silber-mittel) 34%, var(--silber-tief)) 0%,
var(--silber-tief) 46%,
color-mix(in srgb, var(--silber-tief) 82%, #05070d) 100%);
}
/* Die Kante oben hell, unten dunkel -- so liegt Licht auf Metall. */
.kachel[data-silber="ja"] {
box-shadow:
inset 0 1px 0 color-mix(in srgb, var(--silber-hell) 42%, transparent),
inset 0 -1px 0 rgba(0, 0, 0, .5);
}
/* Beim Berühren wandert die Glanzbahn ein Stück -- einmal, sanft, und
nur dort, wo Bewegung erwünscht ist. Kein Dauerflackern. */
@media (prefers-reduced-motion: no-preference) {
.kachel[data-silber="ja"] { transition: background-position .5s ease; }
.kachel[data-silber="ja"]:hover { background-position: 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 18px 0, 0 0, 0 0; }
}
@media (forced-colors: active) {
.kachel[data-silber="ja"] { background-image: none; }
}
/* =====================================================================
DER MEHR-KNOPF IN DER KOPFLEISTE (25.09.2026)
=====================================================================
Filipe, 09.09.2026: „es soll alles in einer reihe sein."
Seither ist die Leiste auf acht Teile gewachsen, und acht
Berührziele zu 44 px passen auf einem Handy nicht nebeneinander.
Statt die Knöpfe zu verkleinern (unter 44 px trifft man sie nicht)
oder eine Schwelle zu setzen (eine Rechnung von gestern), MISST
kopf.js, ob die Leiste einreihig steht — und schiebt sonst den
nächsten Kandidaten hier hinein.
DER KNOPF SIEHT AUS WIE DIE ANDEREN: 44 px, dieselbe Rundung,
dieselbe leise Fläche. Er ist kein Sonderfall, sondern der neunte
Knopf — nur dass hinter ihm die stehen, für die kein Platz war.
DAS FACH HÄNGT UNTER IHM und nicht über der halben Seite: Wer
„Abmelden" sucht, soll es dort finden, wo der Knopf steht. Auf sehr
schmalen Bildschirmen zieht es sich am rechten Rand entlang, damit
es nicht aus dem Bild läuft — `max-width` mit `calc` statt einer
festen Breite, sonst wäre es bei 320 px wieder zu breit. */
.kopf-mehr {
flex: none;
display: inline-flex; align-items: center; justify-content: center;
width: 44px; height: 44px;
padding: 0;
border: 1px solid var(--rand); border-radius: 12px;
background: rgba(255, 255, 255, .04);
color: var(--text-leise);
cursor: pointer;
}
.kopf-mehr:hover { background: rgba(255, 255, 255, .08); color: var(--text); }
.kopf-mehr:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
.kopf-mehr[aria-expanded="true"] {
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
background: color-mix(in srgb, var(--akzent) 12%, transparent);
color: var(--text);
}
/* : Das Zeichen soll keine Klicks abfangen --
sonst ist das Ziel eines Tipps das <svg> und nicht der Knopf, und
jeder Zuhoerer, der auf den Knopf prueft, geht leer aus. */
.kopf-mehr__zeichen {
width: 22px; height: 22px; fill: currentColor; pointer-events: none;
}
/* Das Fach selbst. `position: absolute` an einer Leiste, die selbst
nicht positioniert ist, würde am Dokument kleben — deshalb bekommt
die Leiste hier ihren Bezugspunkt. */
.kopfleiste__rechts { position: relative; }
.kopf-mehr__fach {
position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
display: flex; flex-direction: column; gap: 4px;
min-width: 168px;
max-width: calc(100vw - 24px);
padding: 8px;
border: 1px solid var(--rand); border-radius: 14px;
background: color-mix(in srgb, var(--tinte, #0b1019) 96%, #ffffff 4%);
box-shadow: 0 18px 40px -16px rgba(0, 0, 0, .8);
}
/* Die Knöpfe darin stehen untereinander und tragen ihren Text — in
der Leiste war er aus Platzgründen versteckt, hier ist Platz.
`justify-content: flex-start` sorgt dafür, dass Zeichen und Wort
links anfangen und nicht jeder Eintrag anders eingerückt aussieht. */
.kopf-mehr__fach > * {
width: 100%;
justify-content: flex-start;
min-height: 44px;
}
/* ==== IM FACH IST PLATZ -- ALSO STEHT DA AUCH DAS WORT ============
In der Leiste werden die Woerter auf schmalen Geraeten weggenommen
(gate.css: `.teilen__text` wird auf 1x1 geklemmt, der
Installieren-Text auf `display: none`). Das ist dort richtig: Ein
Knopf mit Wort braucht dreimal so viel Platz wie einer ohne.
IM FACH GILT DAS GEGENTEIL. Ein Menue mit drei namenlosen Symbolen
untereinander ist ein Raetsel -- und die drei, die hier landen
(Teilen, Installieren, Abmelden), sind genau die, die man selten
benutzt und deshalb nicht am Zeichen erkennt.
DIE REGELN MUESSEN STAERKER SEIN ALS DIE, DIE SIE AUFHEBEN: Die in
gate.css stehen in einer `@media`-Abfrage mit einer Klasse
(`.kopfleiste__rechts .install-knopf__text`) -- also (0,2,0). Zwei
Klassen hier reichen dafuer nicht sicher, weil gate.css SPAETER
geladen wird. Drei tun es: `.kopfleiste__rechts .kopf-mehr__fach
.teilen__text` ist (0,3,0) und gewinnt ueber die Staerke statt ueber
die Reihenfolge. Genau diese Rechnung stand beim Chat schon einmal
an; dort war sie (0,2,0) gegen (0,3,0). */
.kopfleiste__rechts .kopf-mehr__fach .teilen__text,
.kopfleiste__rechts .kopf-mehr__fach .install-knopf__text,
.kopfleiste__rechts .kopf-mehr__fach .suche-knopf__text,
.kopfleiste__rechts .kopf-mehr__fach .chat-knopf__text,
.kopfleiste__rechts .kopf-mehr__fach .abmelden__text {
position: static;
display: inline;
width: auto; height: auto; margin: 0; padding: 0;
overflow: visible; clip-path: none; white-space: nowrap;
}
/* Und die Knoepfe selbst duerfen im Fach ihre Breite nehmen -- in der
Leiste sind sie auf 44 px gestaucht. */
.kopfleiste__rechts .kopf-mehr__fach > * {
width: 100%;
padding: 0 12px;
justify-content: flex-start;
gap: 10px;
}
@media (forced-colors: active) {
.kopf-mehr { border: 1px solid CanvasText; }
.kopf-mehr__fach { border: 1px solid CanvasText; background: Canvas; }
}