diff --git a/tools/kachel-regenbogen.mjs b/tools/kachel-regenbogen.mjs
index 0ce3369b..c9fd3ea4 100644
--- a/tools/kachel-regenbogen.mjs
+++ b/tools/kachel-regenbogen.mjs
@@ -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).");
diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html
index 976d4c6b..1aa65f65 100644
--- a/workspace/anruf-probe.html
+++ b/workspace/anruf-probe.html
@@ -16,15 +16,15 @@
verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
-
-
+
+
-
+