Personenkachel: Rollenfarben, kein Leerband, dunklerer Grund

Filipe, mit Bildschirmfoto: "mach die ganze kachel perfekter
detailliert schoenes. der hintergrund soll auch bissl dunkler sein von
der kachel."

--- 29 PIXEL NICHTS, FUENFMAL UNTEREINANDER ---

Auf dem Bild stand unter jeder zugeklappten Rolle ein leerer Streifen.
Nachgemessen: Abschnitt 74 px, Zeile darin 45 -- 29 px Leerraum.

Sie kamen aus ZWEI Quellen, und nur eine stand in personen.css:
padding-bottom: 14px am Abschnitt, plus margin-bottom: 14px an
.gruppe__kopf aus start.css Zeile 765. Letzteres ist fuer die
freistehenden Abschnitte der STARTSEITE geschrieben, wo unter der
Ueberschrift wirklich gleich Karten kommen. Zugeklappt kommt hier aber
nichts, und dann ist der Abstand Abstand zu nichts.

Beide haengen jetzt am Zustand: offen -> Luft, zu -> keine. Die Kachel
ist damit 383 px hoch statt 293 -- pardon, 293 statt 383.

--- DIE ROLLEN HABEN FARBEN, NUR HIER NICHT ---

Fuenf Zeilen sahen fuenfmal gleich aus. Das Haus fuehrt fuer jede Rolle
eine Farbe (Anmeldeseite, Marken, Bereiche); ausgerechnet in der Liste,
in der es NUR um Rollen geht, hoerten sie auf.

Jeder Abschnitt traegt jetzt `data-rolle`, setzt daraus EIN --r, und
alles Weitere liest davon: der Streifen links, die Anzahl, die
Namenszeichen, der Pfeil, das Licht beim Aufklappen. Und `--ton`, die
Variable, aus der module.css das Kantenlicht jeder Kachel zieht -- die
Personenkarten in einem Manager-Abschnitt sind damit lila statt orange.
Eine Zeile, und der Abschnitt wird ein Stueck.

NEU: WER DRINSTEHT, OHNE AUFZUKLAPPEN. Vier Namenszeichen, ab dem
fuenften "+n". Zugeklappt sagte die Zeile bisher nur, WIE VIELE es
sind; wer wissen wollte, ob Patrick dabei ist, musste aufklappen.

--- DER STREIFEN, DEN getComputedStyle NICHT SIEHT ---

Erster Anlauf: 3 px breit, left: 0, volle Hoehe. Im Bild war nichts.
getComputedStyle meldete trotzdem "3 px, sichtbar, Deckkraft 0,55".

Der Grund steht in module.css: Jede Kachel traegt auf ::before ein
Kantenlicht mit inset: 0 und z-index: 2 -- eine 1,6 px breite Linie
UEBER allen Kindern. Vom Streifen blieben 1,4 px, und die lagen genau
in der Kante. Er sitzt jetzt bei 3 px, gerundet, mit Luft oben und
unten.

Die Pruefung misst ihn deshalb an echten BILDPUNKTEN, und zwar
dieselbe Stelle zweimal: einmal wie sie ist, einmal mit
ausgeschaltetem Streifen. Was sich aendert, IST der Streifen -- und was
sich nicht aendert, ist die Gegenprobe, ohne dass man sie erfinden
muss.

--- UND EINE PRUEFUNG, DIE GRUEN GELOGEN HAT ---

Die Kontrastmessung las die Textfarbe mit
`getComputedStyle(e).color.match(/\d+/g)`. Das geht, solange dort
"rgb(148, 165, 187)" steht. Alle neuen Stellen kommen aus color-mix(),
und Chromium antwortet darauf mit "color(srgb 0.36 0.51 0.42)". Aus
dem Muster fielen "0", "510588", "0" -- die Pruefung meldete
775929299:1 und war gruen.

Die Farbe wird jetzt in ein Canvas GEMALT und als Punkt zurueckgelesen;
das versteht jede Schreibweise, die der Browser versteht. Davor steht
eine Gegenprobe mit zwei bekannten Farben: Stimmt das Messgeraet nicht,
ist alles darunter wertlos. Echte Werte jetzt: 7,95 bis 15,71:1.

--- AM HANDY STAND DER PFEIL IN EINER DRITTEN ZEILE ---

Der Zusatztext bekommt dort eine eigene Rasterzeile -- richtig, er
passt sonst nicht. Der Pfeil bekam dadurch eine dritte und stand mittig
unter dem Text wie ein vergessenes Zeichen: 106 px je Rolle. Er hat
jetzt eine eigene Spalte und ueberspannt beide Zeilen: 75 px, und er
steht da, wo die Hand ihn sucht.

--- Pruefung ---

server/pruef-personen-kachel.mjs, neu, 43 Pruefungen, alle gruen.
Ausserdem gruen: pruef-personen-liste, pruef-css-klassen (die hat die
Namenszeichen bei 10,56 px erwischt, bevor sie jemand lesen musste).
Angesehen bei 1440 px und 390 px, zu und offen.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-09 13:37:28 +02:00
co-authored by Claude Opus 5
parent 14e9bbf7a5
commit d5570ee501
22 changed files with 986 additions and 203 deletions
+58 -1
View File
@@ -204,6 +204,18 @@
let betreuerListe = [];
/** Ein oder zwei Buchstaben aus einem Namen.
*
* Zwei nur bei einem echten zweiten Wort: Aus "Spicy Media" wird SM,
* aus "BananaStift" ein B -- Binnenversalien als zweiten Namen zu
* lesen ergäbe "BS" für eine Person, die einen Namen hat. */
function initialen(name) {
const teile = String(name || '').trim().split(/[\s._-]+/).filter(Boolean);
if (!teile.length) return '?';
if (teile.length === 1) return teile[0].slice(0, 1).toUpperCase();
return (teile[0][0] + teile[teile.length - 1][0]).toUpperCase();
}
function zeile(p) {
const k = el('div', 'person');
k.dataset.aktiv = p.aktiv ? 'ja' : 'nein';
@@ -599,6 +611,18 @@
const auf = offen.has(abschnitt.rolle);
const block = document.createElement('section');
block.className = 'gruppe';
/* DIE ROLLE STEHT AM ABSCHNITT (09.09.2026).
Ohne sie sehen alle fünf Zeilen gleich aus, und die Farben, die
das Haus für die Rollen ohnehin führt (Anmeldeseite, Marken,
Bereiche), hören ausgerechnet in der Personenliste auf. Das
Merkmal ist die einzige Zeile Skript, die dafür nötig ist --
alles Weitere macht das CSS. */
block.dataset.rolle = abschnitt.rolle;
/* UND DER ZUSTAND, an derselben Stelle. Das CSS fragte ihn bisher
ueber `:has(> .gruppe__kopf[aria-expanded="true"])` ab -- das
geht, ist aber ein zweiter Weg zu einer Auskunft, die hier
ohnehin vorliegt. Ein Merkmal, drei Regeln, kein Suchen. */
block.dataset.auf = auf ? 'ja' : 'nein';
/* Die Überschrift IST der Knopf. Ein eigener kleiner Schalter
daneben wäre ein zweites Ziel für dieselbe Absicht -- und ein
@@ -635,7 +659,40 @@
pfad.setAttribute('d', 'm6 9.5 6 6 6-6');
pfeil.append(pfad);
kopf.append(h, zahl, unter, pfeil);
/* WER DRINSTEHT — SICHTBAR, OHNE AUFZUKLAPPEN.
Zugeklappt sagte die Zeile bisher nur, WIE VIELE es sind. Wer
wissen wollte, ob Patrick dabei ist, musste aufklappen. Vier
Namenszeichen beantworten das im Vorbeigehen; ab dem fünften
steht "+n" dahinter, damit die Zeile nicht wächst.
`aria-hidden`, weil es eine Wiederholung ist: Die Anzahl steht
als Zahl daneben, die Namen stehen beim Aufklappen vollständig
da. Ein Vorleseprogramm würde hier sonst Buchstabenpaare
vorlesen, die niemandem etwas sagen. Für die Maus steht der
volle Name im title. */
const leute = document.createElement('span');
leute.className = 'gruppe__leute';
leute.setAttribute('aria-hidden', 'true');
const ZEIGEN = 4;
for (const p of abschnitt.drin.slice(0, ZEIGEN)) {
const z = document.createElement('span');
z.className = 'gruppe__kopf-zeichen';
z.textContent = initialen(p.name);
z.title = p.aktiv ? p.name : `${p.name} (gesperrt)`;
if (!p.aktiv) z.dataset.gesperrt = 'ja';
leute.append(z);
}
if (abschnitt.drin.length > ZEIGEN) {
const mehr = document.createElement('span');
mehr.className = 'gruppe__kopf-zeichen';
mehr.dataset.mehr = 'ja';
mehr.textContent = `+${abschnitt.drin.length - ZEIGEN}`;
mehr.title = abschnitt.drin.slice(ZEIGEN).map((p) => p.name).join(', ');
leute.append(mehr);
}
kopf.append(h, zahl, unter, leute, pfeil);
kopf.addEventListener('click', () => {
if (offen.has(abschnitt.rolle)) offen.delete(abschnitt.rolle);
else offen.add(abschnitt.rolle);