Die Willkommens-Kachel: bunte Punkte statt Balken

Filipe, 22.09.2026: „Ja ist cool mit den ganzen farben, aber ich finde
das passt nicht so gut zum eigentlichen Stil. Würde glaube ich schöner
wirken, wenn die Farben als bunte Punkte auf der gesamten Kachel wären,
vielleicht auch eng an eng und größere und kleinere Punkte, damit es vom
Stil her die Punkte der anderen Kacheln aufgreift, aber trotzdem extrem
heraussticht. Das mit den Farben ist mega. Aber irgendwie passen die
balken/streifen nicht."

ER HAT DEN STIL DES HAUSES GENAUER GELESEN ALS ICH. Jede Kachel der
Startseite ist ein Sternenfeld -- nahe Sterne mit Hof, mittlere Sterne,
ferner Staub, dazu ein schraeger Schleier. Steht so in start.css unter
"NAHE STERNE", seit dem 17.09. Die Streifen waren die einzige Flaeche
weit und breit mit harten Kanten: richtig in der Farbe, falsch in der
Form.

Jetzt 93 Punkte in drei Groessen, jede Groesse einmal alle 31 benutzten
Kacheltoene. Dieselbe Bauart wie ueberall, nur bunt statt weiss -- die
Kachel greift den Stil auf und ist trotzdem die einzige, deren Sterne
Farbe haben.

ABGELEITET, NICHT EINGETRAGEN: Punktzahl, Rasterweite und Reihenfolge
folgen aus der Anzahl der Farben. Der Sprung durch die Farbliste wird
so gewaehlt, dass er teilerfremd zur Laenge ist -- sonst laegen
Nachbarpunkte auf benachbarten Farbwinkeln und es entstuenden Flecken
aus fast gleichen Toenen. Eine feste Zahl wie 7 versagt still, sobald
die Anzahl ein Vielfaches davon ist. Die drei Rasterweiten (197/131/83)
haben bewusst keinen gemeinsamen Teiler; sonst faellt das Feld
regelmaessig aufeinander und man sieht ein Muster.

Der Zufall der Streuung ist ein fester: `Math.random` haette bei jedem
Lauf einen anderen Block ergeben, und jeder Vergleich "hat sich etwas
geaendert?" waere wertlos.

VIER ANLAEUFE FUER DEN LESBAREN TEXT, drei davon falsch:

1. Der Lesesaum der Streifenfassung blieb stehen. Gemessen: 8,27:1 bei
   einer Grenze von 4,5. Das war kein Saum, das war ein Deckel -- er
   verschluckte die untere Haelfte der Kachel, und genau dort sollten
   Punkte sein ("auf der gesamten kachel"). Zurueckgenommen.
2. Danach sass auf dem Handybild ein heller Punkt mitten unter dem Wort
   "gibt". Die Messung sagte weiter 8,2:1 und hatte recht: Sie mittelt
   ueber die Textflaeche. Ein Punkt hinter einem duennen Buchstaben
   verschwindet in diesem Mittel -- im Auge nicht.
3. Also ein dunkler Teich im Kachelhintergrund, 400 px breit. Auf dem
   grossen Bildschirm sass er richtig; die Kachel auf dem Handy ist
   aber selbst nur 366 px breit, und er hat fast alle Farben
   geschluckt. Eine Pixelzahl, die auf einem Geraet passt, ist auf dem
   naechsten falsch.
4. Richtig: der dunkle Grund haengt am TEXT, nicht an der Kachel. Dann
   ist er immer genau so breit wie das, was er lesbar machen soll --
   auf jedem Geraet, ohne eine einzige Schwelle. Und der Verlauf darin
   laeuft vor allen vier Kanten aus, sonst sieht man das Rechteck und
   es steht eine Karte in der Karte.

Nebenbei die alte Falle wieder getreten und behoben: Ein Backtick in
einem Kommentar, der INNERHALB einer Vorlagenzeichenkette steht,
beendet sie. Steht seit heute als Hinweis daneben.

Gemessen: Willkommen 8,36:1 (Grenze 4,5), schlechteste Kachel im Haus
unveraendert "Aufgaben" mit 4,80:1. pruef-kachelfarben 22/0,
pruef-willkommen, pruef-buehne (Kontrast an echten Bildpunkten, alle
Seiten) -- alle gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-22 14:43:56 +02:00
co-authored by Claude Opus 5
parent 25de892fdb
commit beb6bc2d62
41 changed files with 986 additions and 724 deletions
+220 -56
View File
@@ -10,10 +10,21 @@
„NICHT GEMISCHT" IST DIE EIGENTLICHE ANSAGE.
Ein Verlauf über alle Töne wäre ein Brei: Zwischen zwei Nachbarfarben
entstehen Zwischentöne, die es im Haus gar nicht gibt, und die
einzelne Farbe ist nicht mehr zu erkennen. Deshalb harte Kanten —
jede Farbe bekommt ihren eigenen Streifen und bleibt sie selbst.
Man kann die Kachel ablaufen und jede Kachel der Wand darin
wiederfinden.
einzelne Farbe ist nicht mehr zu erkennen. Jede Farbe bleibt deshalb
für sich — man kann die Kachel ablaufen und jede Kachel der Wand
darin wiederfinden.
ZWEITER ANLAUF AM 22.09.2026: PUNKTE STATT STREIFEN.
Der erste Entwurf gab jeder Farbe einen eigenen Streifen. Filipe:
„Das mit den Farben ist mega. Aber irgendwie passen die
balken/streifen nicht … schöner wirken, wenn die Farben als bunte
Punkte auf der gesamten Kachel wären."
Er hat recht, und der Grund steht in start.css: Jede Kachel des
Hauses ist ein Sternenfeld. Die Streifen waren die einzige Fläche
weit und breit mit harten Kanten — richtig in der Farbe, falsch in
der Form. Jetzt sind es Punkte in derselben Bauart wie überall, nur
bunt statt weiß.
WARUM DAS EIN WERKZEUG IST UND KEINE HANDARBEIT
Die Liste der Farben steht nicht hier, sie wird ABGELEITET — aus
@@ -132,72 +143,225 @@ for (const e of liste) {
+ " " + String(Math.round(farbwinkel(e.farbe))).padStart(4) + " Grad " + e.wer);
}
/* ---- Den Streifenverlauf bauen -------------------------------------- */
/* Jede Farbe bekommt genau denselben Anteil. Die Breite ist damit eine
Rechnung aus der Anzahl, keine eingetragene Zahl — kommt eine Kachel
dazu, rücken alle zusammen, und es bleibt lückenlos. */
const anteil = 100 / liste.length;
const streifen = liste.map((e, i) => {
const von = (i * anteil).toFixed(3);
const bis = ((i + 1) * anteil).toFixed(3);
/* GEGEN EINEN DECKENDEN GRUND, NICHT GEGEN --flaeche.
Erster Lauf nahm `var(--flaeche)` -- dieselbe Mischung wie auf
jeder anderen Kachel. Am Bildschirm sahen die Baender dadurch
milchig aus: --flaeche ist halbdurchsichtig (Alpha 0,89), und
durch jedes Band schien das Buehnenbild. Auf einer einfarbigen
Kachel faellt das nicht auf, bei 31 schmalen Streifen nebeneinander
schon -- sie verlieren genau das, wofuer sie da sind.
/* ---- Das Punktfeld bauen --------------------------------------------
UMGEBAUT AM 22.09.2026, von Streifen auf Punkte.
Diese eine Kachel deckt deshalb. Das ist auch inhaltlich richtig:
Sie soll die Farben des Hauses ZEIGEN, nicht durch sie hindurch
etwas anderes. */
const f = `color-mix(in srgb, ${e.farbe} 72%, #070b14)`;
return ` ${f} ${von}%,\n ${f} ${bis}%`;
}).join(",\n");
Filipe, nach dem ersten Bildschirmfoto: „Ja ist cool mit den ganzen
farben, aber ich finde das passt nicht so gut zum eigentlichen Stil.
Würde glaube ich schöner wirken, wenn die Farben als bunte Punkte auf
der gesamten Kachel wären, vielleicht auch eng an eng und größere und
kleinere Punkte, damit es vom Stil her die Punkte der anderen Kacheln
aufgreift, aber trotzdem extrem heraussticht. Das mit den Farben ist
mega. Aber irgendwie passen die balken/streifen nicht."
ER HAT DEN STIL DES HAUSES GENAUER GELESEN ALS ICH. Jede Kachel der
Startseite ist ein STERNENFELD: nahe Sterne mit Hof, mittlere Sterne,
ferner Staub, dazu ein schräger Schleier. Nachzulesen weiter oben in
start.css unter „NAHE STERNE". Die Streifen waren ein Fremdkörper --
sie waren die einzige Fläche im Haus mit harten Kanten.
Das Punktfeld ist dieselbe Bauart wie überall, nur trägt hier JEDER
Punkt eine der Hausfarben statt Weiß. Damit greift die Kachel den
Stil auf und sticht trotzdem heraus: Sie ist die einzige, deren
Sterne bunt sind.
DREI GRÖSSEN, DREI EIGENE RASTER. Jede Ebene enthält ALLE Farben --
sonst wäre „alle Farben" davon abhängig, welche Größe man gerade
ansieht. Die drei Rasterweiten sind teilerfremd zueinander gewählt;
dadurch überlagern sie sich nie regelmäßig und das Feld sieht
gestreut aus statt gerastert.
NICHTS DAVON IST GERATEN: Zahl der Punkte, Rasterweite und Reihung
folgen aus der Anzahl der Farben. Kommt eine Kachel dazu, rückt alles
von selbst zusammen.
--------------------------------------------------------------------- */
/* Ein Sprung durch die Farbliste, der teilerfremd zu ihrer Länge ist.
Damit liegen Nachbarpunkte nie auf benachbarten Farbwinkeln -- sonst
entstünden Flecken aus fast gleichen Tönen, und die Kachel sähe
wieder nach Verlauf aus. Abgeleitet, nicht eingetragen: eine feste
Zahl wie 7 versagt still, sobald die Anzahl ein Vielfaches davon ist. */
function sprungFuer(n, teiler) {
const ggt = (a, b) => (b ? ggt(b, a % b) : a);
for (let s = Math.max(2, Math.round(n / teiler)); s < n; s++) {
if (ggt(s, n) === 1) return s;
}
return 1;
}
/* Ein Zufall, der immer derselbe ist. `Math.random` wäre hier falsch:
Zwei Läufe ergäben zwei verschiedene Blöcke, und jeder Vergleich
(„hat sich etwas geändert?") wäre wertlos. */
function streu(i, salz) {
const x = Math.sin((i + 1) * 12.9898 + salz * 78.233) * 43758.5453;
return x - Math.floor(x);
}
/* Eine Ebene: alle Farben einmal, auf ein verwackeltes Raster verteilt. */
function ebene({ zelle, radius, hof, deckung, salz, teiler }) {
const n = liste.length;
const sprung = sprungFuer(n, teiler);
const spalten = Math.ceil(Math.sqrt(n));
const reihen = Math.ceil(n / spalten);
const bx = zelle / spalten;
const by = zelle / reihen;
/* Rand frei halten: Ein Punkt, der über die Kachelkante ragt, wird
beim Wiederholen abgeschnitten -- und die abgeschnittene Hälfte
taucht auf der anderen Seite NICHT auf. Das sieht man sofort. */
const luft = radius + 1;
const punkte = [];
for (let i = 0; i < n; i++) {
const e = liste[(i * sprung) % n];
const sp = i % spalten;
const re = Math.floor(i / spalten);
const mx = sp * bx + bx / 2;
const my = re * by + by / 2;
const jx = (streu(i, salz) - 0.5) * bx * 0.62;
const jy = (streu(i, salz + 5) - 0.5) * by * 0.62;
const x = Math.min(zelle - luft, Math.max(luft, mx + jx));
const y = Math.min(zelle - luft, Math.max(luft, my + jy));
/* Etwas Größenstreuung innerhalb der Ebene -- sonst sind es drei
Sorten gleicher Kreise statt eines gewachsenen Feldes. */
const r = (radius * (0.78 + 0.44 * streu(i, salz + 11))).toFixed(2);
const f = `color-mix(in srgb, ${e.farbe} ${deckung}%, #ffffff)`;
const kern = `${f}, ${f} 34%`;
const aussen = hof
? `, color-mix(in srgb, ${e.farbe} 55%, transparent) 52%`
: "";
punkte.push(` radial-gradient(${r}px ${r}px at ${x.toFixed(1)}px ${y.toFixed(1)}px,`
+ ` ${kern}${aussen}, transparent 100%)`);
}
return { punkte, zelle };
}
/* Drei Rasterweiten, absichtlich ohne gemeinsamen Teiler. Lägen sie
z. B. bei 200/100/50, fielen alle drei Ebenen alle 200 px wieder
aufeinander -- und das Auge sieht ein Muster, wo Streuung sein soll. */
const EBENEN = [
{ zelle: 197, radius: 5.4, hof: true, deckung: 88, salz: 1, teiler: 3 },
{ zelle: 131, radius: 3.0, hof: false, deckung: 82, salz: 2, teiler: 4 },
{ zelle: 83, radius: 1.7, hof: false, deckung: 74, salz: 3, teiler: 5 },
];
const gebaut = EBENEN.map(ebene);
const punktGroessen = gebaut
.map((g) => g.punkte.map(() => `${g.zelle}px ${g.zelle}px`).join(", "))
.join(", ");
const anzahlPunkte = gebaut.reduce((s2, g) => s2 + g.punkte.length, 0);
const block = `${ANFANG}
/* ERZEUGT VON tools/kachel-regenbogen.mjs — NICHT VON HAND ÄNDERN.
${liste.length} Streifen, einer je benutztem Kachelton, sortiert nach
Farbwinkel. Die Liste ist aus den Kachellisten abgeleitet; wer eine
Kachel hinzufügt, lässt das Werkzeug erneut laufen. Die Prüfung
pruef-willkommen zählt nach, ob beides noch zusammenpasst. */
${anzahlPunkte} Punkte in drei Größen, jede Größe einmal alle
${liste.length} 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.
STAERKER ALS AUF DEN ANDEREN KACHELN, und zwar gemessen:
Mit den Werten der normalen Kachel (.90/.70/.24) kam der
Text hier auf 4,45:1 -- fuenf Hundertstel unter der Grenze.
Kein Wunder: Dort liegt EIN dunkler Ton unter der Schrift,
hier liegen deckende Farbbaender. Ein heller Untergrund
braucht einen dunkleren Saum, sonst ist die Kachel schoen
und der Text weg. Gefunden hat das pruef-kachelfarben, nicht
der Blick -- 4,45 gegen 4,50 sieht man nicht. */
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, .95) 0%, rgba(4, 6, 14, .82) 26%,
rgba(4, 6, 14, .32) 48%, transparent 66%),
/* 2. DIE VIGNETTE — aussen dunkler als innen. Ohne sie wäre die
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% 45%, transparent 44%, rgba(3, 5, 12, .42) 100%),
/* 3. EIN SCHRÄGER GLANZ quer über die Streifen. Er bindet die
${liste.length} Bänder zu einer Fläche zusammen — ohne ihn sieht es
aus wie ein Farbmuster, mit ihm wie ein Gegenstand. */
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. */
${gebaut[0].punkte.join(",\n")},
/* 4. DIE MITTLEREN — die Masse des Feldes. */
${gebaut[1].punkte.join(",\n")},
/* 5. DER FEINE STAUB. Er füllt die Lücken: Ein Feld aus nur
großen Punkten sieht aus wie aufgeklebt. */
${gebaut[2].punkte.join(",\n")},
/* 6. EIN SCHRÄGER SCHLEIER quer über das Feld. Er bindet die
${anzahlPunkte} 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, .10) 0%,
rgba(255, 255, 255, .02) 34%,
rgba(0, 0, 0, .10) 68%,
rgba(0, 0, 0, .26) 100%),
/* 4. DIE FARBEN DES HAUSES, harte Kanten, kein Verlauf dazwischen.
Jede Farbe bleibt sie selbst — genau das war die Ansage. */
linear-gradient(100deg,
${streifen});
background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%;
/* Die Kante links trägt alle Farben mit, in derselben Reihenfolge —
sonst wäre ausgerechnet der farbigste Streifen der Kachel einfarbig. */
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%,
${punktGroessen},
100% 100%, 100% 100%;
background-repeat:
no-repeat, no-repeat,
${gebaut.flatMap((g) => g.punkte.map(() => "repeat")).join(", ")},
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}`;
if (!process.argv.includes("--schreiben")) {
@@ -217,4 +381,4 @@ if (css.includes(ANFANG) && css.includes(ENDE)) {
}
writeFileSync(CSS, neu, "utf8");
console.log("\nEingetragen in workspace/assets/css/start.css ("
+ liste.length + " Streifen).");
+ anzahlPunkte + " Punkte in drei Groessen, je " + liste.length + " Farben).");