/* ===================================================================== HELLER UND DUNKLER (25.09.2026) ===================================================================== Filipe: „dieser kreis muss viel perfekter sein. ich will dass die leute auch heller und dunkler aussuchen koennen. perfektionier das bitte viel krasser. viel profissioneller. so dass die leute viel krassere moeglichkeiten haben." --------------------------------------------------------------------- WARUM DAS BIS HEUTE NICHT GING Die 360 Toene in chat-kreis.js liegen ALLE auf derselben Leuchtdichte. Das war kein Zufall und keine Bequemlichkeit: Solange die Blase in der gewaehlten Farbe stand, musste jede dieser Flaechen dieselbe Schrift tragen -- „gleiche Leuchtdichte heisst gleicher Kontrast fuer alle". Eine hellere Farbe zuzulassen hiesse damals: irgendwo im Haus wird eine Nachricht unlesbar. SEIT DEM 25.09.2026 IST DAS ANDERS. Die Blase ist fuer alle dunkles Glas (`--blasengrund`); der gewaehlte Ton ist KANTE und NAME. Damit faellt die alte Bedingung weg -- und eine neue tritt an ihre Stelle: Der Ton muss als NAME auf dem Blasengrund lesbar bleiben. Die Oberflaeche hellt ihn dafuer mit Weiss auf (`--namen-anteil`, 50 %). Genau diese Rechnung prueft pruef-chat-neu fuer alle Toene. --------------------------------------------------------------------- DIE ZAHLEN SIND GEMESSEN, NICHT GEWAEHLT Nachgerechnet ueber alle 360 Winkel, jeweils der schlechteste: 40 % schwarz 4,468 -- unter der Schwelle, faellt raus 34 % schwarz 4,555 -- ginge, aber ohne Reserve 30 % schwarz 4,619 <- die dunkelste Stufe 20 % schwarz 4,7 10 % schwarz 4,9 0 % 5,12 <- die Mitte, der alte Kreis 18 % weiss 6,4 36 % weiss 7,9 55 % weiss 9,6 <- die hellste Stufe Noetig sind 4,5. Die dunkelste Stufe hat also 0,12 Reserve, die hellste mehr als das Doppelte. Wer hier eine Stufe hinzufuegt, misst nach -- pruef-chat-neu rechnet jede Stufe an jedem der 360 Winkel nach und wird rot, bevor es jemand auf dem Bildschirm sieht. --------------------------------------------------------------------- WARUM SIEBEN UND NICHT DREI Drei (dunkel / normal / hell) waere die bequeme Zahl. Sieben sind der Punkt, an dem zwei benachbarte Stufen noch unterscheidbar sind und man trotzdem das Gefuehl hat, etwas einstellen zu koennen -- Filipes „viel krassere moeglichkeiten" heisst nicht „zwei mehr". Zusammen mit 360 Winkeln sind es 2520 Farben statt 360. --------------------------------------------------------------------- WARUM EINE EIGENE DATEI chat-kreis.js wird von tools/chat-kacheln-rechnen.mjs ERZEUGT und traegt oben „NICHT VON HAND AENDERN". Etwas hineinzuschreiben waere beim naechsten Lauf des Werkzeugs weg. Die Stufen sind ausserdem keine Tabelle, sondern eine Rechnung -- sie gehoeren nicht in eine erzeugte Liste. ===================================================================== */ import { KREIS } from "./chat-kreis.js"; /** Die sieben Stufen. Minus heisst dunkler, Plus heller. * * `wert` ist der Teil, der im Schluessel steht ("ton-214-s2"). * `misch` ist der Anteil, mit dem der Grundton nach Schwarz (negativ) * oder nach Weiss (positiv) gezogen wird. * `name` ist das, was ein Vorleseprogramm sagt -- eine Zahl von 1 bis * 7 saehe aus wie eine Note. */ export const KREIS_STUFEN = [ { wert: "s1", misch: -0.30, name: "sehr dunkel" }, { wert: "s2", misch: -0.20, name: "dunkler" }, { wert: "s3", misch: -0.10, name: "leicht dunkel" }, { wert: "s4", misch: 0, name: "normal" }, { wert: "s5", misch: 0.18, name: "leicht hell" }, { wert: "s6", misch: 0.36, name: "heller" }, { wert: "s7", misch: 0.55, name: "sehr hell" }, ]; /** Welche Stufe ist die Mitte -- und damit das, was "ton-214" ohne * Zusatz bedeutet. Abgeleitet aus `misch === 0` und nicht als Index * hingeschrieben: Wer eine Stufe vorn einfuegt, verschiebt sonst * stillschweigend die Bedeutung aller alten Schluessel. */ export const KREIS_MITTE = KREIS_STUFEN.find((s) => s.misch === 0)?.wert || "s4"; /** Zerlegt einen Schluessel in Winkel und Stufe. * * "ton-214" -> { winkel: 214, stufe: "s4" } (die Mitte) * "ton-214-s6" -> { winkel: 214, stufe: "s6" } * alles andere -> null * * DIE ALTEN SCHLUESSEL BLEIBEN GUELTIG, und zwar ohne Umstellung in * der Datenbank. Wer seit dem 23.09. "ton-214" traegt, traegt danach * genau dieselbe Farbe -- eine Umstellung, die stillschweigend die * Wahl von fuenfzehn Leuten verschiebt, waere kein Fortschritt. */ export function tonAus(wert) { const t = /^ton-(\d{1,3})(?:-(s[1-7]))?$/.exec(String(wert ?? "")); if (!t) return null; const winkel = Number(t[1]); if (!(winkel >= 0 && winkel < KREIS.length)) return null; const stufe = t[2] || KREIS_MITTE; if (!KREIS_STUFEN.some((s) => s.wert === stufe)) return null; return { winkel, stufe }; } /** Zwei Farben mischen, wie `color-mix(in srgb, a p%, b)` es tut. */ function mischen(a, b, anteilB) { const z = (h) => { const s = String(h).replace("#", ""); return [0, 2, 4].map((i) => parseInt(s.slice(i, i + 2), 16)); }; const [ar, ag, ab] = z(a), [br, bg, bb] = z(b); const m = (x, y) => Math.round(x * (1 - anteilB) + y * anteilB); return "#" + [m(ar, br), m(ag, bg), m(ab, bb)] .map((v) => v.toString(16).padStart(2, "0")).join(""); } /** Die fertige Farbe zu Winkel und Stufe. */ export function tonFarbe(winkel, stufe) { const grund = KREIS[winkel]; if (!grund) return null; const s = KREIS_STUFEN.find((x) => x.wert === stufe) || { misch: 0 }; if (!s.misch) return grund; return s.misch < 0 ? mischen(grund, "#000000", -s.misch) : mischen(grund, "#ffffff", s.misch); } /** Die Farbe zu einem ganzen Schluessel, oder null. */ export function farbeZuSchluessel(wert) { const t = tonAus(wert); return t ? tonFarbe(t.winkel, t.stufe) : null; }