From 6e062b24394a1857cf1731e6518e54d9f9e826ca Mon Sep 17 00:00:00 2001 From: Dogfather Date: Fri, 18 Sep 2026 20:10:38 +0200 Subject: [PATCH] Community: ein Ton je Art -- gesucht, nicht geraten Alle Etiketten trugen denselben blauen Ton. Auf "Regeln & Hilfe" stehen siebzehn Karten untereinander, auf dem Treff acht -- das Auge hatte nichts, woran es sich festhalten konnte. Man liest dann jede Ueberschrift, statt zu ueberfliegen. NACH BEDEUTUNG, NICHT NACH REIHENFOLGE. Lob gruen, "etwas stimmt nicht" warmrot, Fragen blau, Regeln golden. Deshalb traegt die Art "frage" auf drei Brettern denselben Ton: Wer das Muster einmal gelernt hat, soll es wiedererkennen. WARUM EIN WERKZEUG UND KEINE FARBLISTE. Der erste Versuch war von Hand: feste Helligkeit, Buntheit nach Gefuehl. Vier Toene lagen ausserhalb des darstellbaren Bereichs, drei Paare zu nah. Nach dem Nachbessern waren es fuenf zu nahe Paare -- wer die Buntheit eines Violetts senkt, schiebt es naeher an alles andere Gedaempfte. Zwei Zahlen von Hand zu stimmen, waehrend eine dritte Bedingung mitlaeuft, geht nicht auf. Das ist eine Suche, keine Wahl. tools/art-farben.mjs sucht deshalb selbst: Der Farbwinkel steht fest (das ist die Entscheidung), Helligkeit und Buntheit werden gesucht -- unter drei Bedingungen gleichzeitig: in sRGB, Kontrast mindestens 4,5:1 auf dunklem Grund, und mindestens 0,10 OKLab-Abstand zu jeder Art, die auf DEMSELBEN Brett vorkommt. Ueber Bretter hinweg darf sich ein Ton wiederholen -- man sieht nie zwei gleichzeitig. UND ES SUCHT DIE LEISESTE FASSUNG, nicht die kraeftigste. Der erste Durchlauf maximierte die Buntheit; heraus kamen #35f695 und #f584fd -- Neongruen und Neonviolett. Das widerspricht der Hausregel ("gedeckte statt reisserisch-grelle Neon-Optik"), und bei siebzehn Karten waere es eine Leuchtreklame. Jetzt: gerade bunt genug, um sie zu unterscheiden. Buntheit ist eine Kostenstelle, kein Ziel. Ergebnis: 23 Toene, 39 Paare geprueft, engstes Paar je Brett 0,100. DAS WERKZEUG PRUEFT AUCH DAS CSS gegen seine eigene Rechnung. Ohne das misst es nur sich selbst: Wer einen Ton von Hand aendert, bliebe unbemerkt -- genau die Art Pruefung, die immer bestaetigt. Gegenprobe: ein Ton von Hand verstellt -> rot mit Angabe von Soll und Ist. Co-Authored-By: Claude Opus 5 --- tools/art-farben.mjs | 357 +++++++++++++++++++++++++++++++ workspace/app.webmanifest | 8 +- workspace/assets/css/bereich.css | 40 ++++ workspace/assets/js/bereich.js | 7 +- workspace/aufgaben.html | 24 +-- workspace/automation.html | 26 +-- workspace/befinden.html | 24 +-- workspace/bereich.html | 36 ++-- workspace/bewerben.html | 30 +-- workspace/bewerbungen.html | 28 +-- workspace/calls.html | 28 +-- workspace/chat.html | 28 +-- workspace/content.html | 30 +-- workspace/crew-index.html | 10 +- workspace/crew.webmanifest | 8 +- workspace/dateien.html | 26 +-- workspace/entwicklung.html | 24 +-- workspace/index.html | 8 +- workspace/kalender.html | 28 +-- workspace/leistung.html | 26 +-- workspace/personen.html | 26 +-- workspace/profil.html | 28 +-- workspace/rechte.html | 24 +-- workspace/report.html | 28 +-- workspace/scouting.html | 26 +-- workspace/start.html | 24 +-- workspace/startcheck.html | 28 +-- workspace/steckbrief.html | 28 +-- workspace/talente.html | 26 +-- workspace/team.html | 26 +-- workspace/teamlage.html | 24 +-- workspace/teilen.html | 22 +- workspace/treff-moderation.html | 24 +-- workspace/treff-regeln.html | 26 +-- workspace/uebersicht.html | 26 +-- workspace/wissen.html | 26 +-- 36 files changed, 805 insertions(+), 403 deletions(-) create mode 100644 tools/art-farben.mjs diff --git a/tools/art-farben.mjs b/tools/art-farben.mjs new file mode 100644 index 00000000..8a15544f --- /dev/null +++ b/tools/art-farben.mjs @@ -0,0 +1,357 @@ +/* ===================================================================== + EIN TON JE ART -- UND DER BEWEIS, DASS MAN SIE UNTERSCHEIDET + + Aufruf: node tools/art-farben.mjs (nur messen) + node tools/art-farben.mjs schreiben (CSS erzeugen) + + --------------------------------------------------------------------- + WARUM ÜBERHAUPT + + Alle Etiketten trugen denselben blauen Ton. Auf „Regeln & Hilfe" + stehen siebzehn Karten untereinander, auf dem Treff acht -- und das + Auge hatte nichts, woran es sich festhalten konnte. Man liest dann + jede Überschrift, statt die Seite zu überfliegen. + + --------------------------------------------------------------------- + NACH BEDEUTUNG, NICHT NACH REIHENFOLGE + + Der Ton folgt dem, was die Art SAGT: Lob grün, „etwas stimmt nicht" + warmrot, Fragen blau, Regeln golden. Deshalb trägt `frage` auf drei + Brettern denselben Ton -- wer das Muster einmal gelernt hat, soll es + überall wiedererkennen. Eine Vergabe nach Position („die erste Art + wird blau") würde genau das verhindern. + + --------------------------------------------------------------------- + UND DESHALB MISST DIESES WERKZEUG ZWEIERLEI + + 1. ABSTAND: Zwei Arten, die auf DEMSELBEN Brett vorkommen, müssen + im OKLab-Raum weit genug auseinanderliegen. Über Bretter hinweg + ist eine Wiederholung dagegen erlaubt -- man sieht nie zwei + Bretter gleichzeitig. + 2. KONTRAST: Jeder Ton muss auf dem dunklen Grund lesbar sein. + Ein hübscher Ton, den man nicht lesen kann, ist kein Ton. + + Ohne diese Messung wäre die Farbwahl eine Behauptung. Bei den + Kacheln hat genau dieselbe Rechnung sieben Töne aussortiert, die + „eigentlich verschieden aussahen". + ===================================================================== */ +import { readFileSync, writeFileSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const HIER = dirname(fileURLToPath(import.meta.url)); +const CSS = join(HIER, "..", "workspace", "assets", "css", "bereich.css"); + +/* Der Grund, auf dem die Etiketten liegen. */ +const GRUND = "#0a121e"; + +/* ---------- Farbrechnung (aus tools/kachel-farben.mjs) --------------- */ +const linear = (c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4); +const zurueck = (c) => (c <= 0.0031308 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055); +const srgb = (hex) => [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16) / 255); + +function oklab(hex) { + const [r, g, b] = srgb(hex).map(linear); + const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b); + const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b); + const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b); + return [ + 0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s, + 1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s, + 0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s, + ]; +} + +function ausOklch(L, C, Hgrad) { + const h = (Hgrad * Math.PI) / 180; + const a = C * Math.cos(h), b2 = C * Math.sin(h); + const l_ = (L + 0.3963377774 * a + 0.2158037573 * b2) ** 3; + const m_ = (L - 0.1055613458 * a - 0.0638541728 * b2) ** 3; + const s_ = (L - 0.0894841775 * a - 1.2914855480 * b2) ** 3; + const r = +4.0767416621 * l_ - 3.3077115913 * m_ + 0.2309699292 * s_; + const g = -1.2684380046 * l_ + 2.6097574011 * m_ - 0.3413193965 * s_; + const b = -0.0041960863 * l_ - 0.7034186147 * m_ + 1.7076147010 * s_; + const kanal = (x) => { + const v = zurueck(x); + if (v < -0.001 || v > 1.001) return null; + return Math.round(Math.min(1, Math.max(0, v)) * 255); + }; + const [R, G, B] = [kanal(r), kanal(g), kanal(b)]; + if (R === null || G === null || B === null) return null; + return "#" + [R, G, B].map((x) => x.toString(16).padStart(2, "0")).join(""); +} + +const abstand = (a, b) => { + const [x, y] = [oklab(a), oklab(b)]; + return Math.hypot(x[0] - y[0], x[1] - y[1], x[2] - y[2]); +}; + +const leuchte = (hex) => { + const [r, g, b] = srgb(hex).map(linear); + return 0.2126 * r + 0.7152 * g + 0.0722 * b; +}; +const kontrast = (a, b) => { + const [x, y] = [leuchte(a), leuchte(b)].sort((p, q) => q - p); + return (x + 0.05) / (y + 0.05); +}; + +/* ===================================================================== + DIE TÖNE -- hier steht nur die BEDEUTUNG, also der Farbwinkel + + Helligkeit und Buntheit sucht das Werkzeug selbst (siehe unten). + + WARUM NICHT VON HAND: Genau das war der erste Versuch -- feste + Helligkeit 0.80 für alle, Buntheit nach Gefühl. Ergebnis: vier Töne + lagen ausserhalb des darstellbaren Bereichs, drei Paare zu nah + beieinander. Nach dem Nachbessern waren es fünf zu nahe Paare: Wer + die Buntheit eines Violetts senkt, schiebt es näher an alles andere + Gedämpfte heran. Zwei Zahlen von Hand zu stimmen, während eine + dritte Bedingung mitläuft, geht nicht auf -- das ist eine Suche, + keine Wahl. + + Der Farbwinkel dagegen IST die Entscheidung und bleibt von Hand: + Lob grün, „etwas stimmt nicht" warmrot, Fragen blau. + ===================================================================== */ +const TOENE = { + /* Begrüßen, fragen, loben, melden -- der Treff */ + hallo: 200, // Türkis: freundlich, offen + frage: 245, // Blau: die neutrale Frage + lob: 140, // Grün: etwas war gut + problem: 25, // Warmrot: hier stimmt etwas nicht + + /* Das Anschlagbrett -- was gilt */ + ansage: 50, // Gold: eine Ansage des Teams + regel: 100, // Oliv-Gold: was fest gilt + hinweis: 255, // Blaugrau: zur Kenntnis + danke: 340, // Rosé: Dank an die Community + + /* Was ansteht -- Termine */ + stream: 300, // Violett: die Sendung + event: 345, // Magenta: der besondere Abend + turnier: 45, // Orange: Wettkampf + pause: 250, // fast grau: es fällt aus + + /* Die Wunschliste */ + technik: 220, // Stahlblau: Geräte und Ton + gemeinsam: 165, // Grün-Türkis: miteinander + sonstiges: 300, // gedämpft: alles Übrige + + /* Highlights */ + clip: 285, // Violett: bewegtes Bild + bild: 195, // Türkis: Standbild + fanart: 325, // Rosé: selbst gemacht + moment: 60, // Bernstein: der Augenblick + + /* Regeln & Hilfe */ + hilfe: 155, // Grün: hier wird geholfen + folge: 5, // Rot: was passiert, wenn + + /* Mitmachen */ + gesucht: 85, // Gold: wir suchen + lust: 135, // Grün: ich hätte Lust +}; + +/* Welche Arten auf DEMSELBEN Brett stehen -- nur hier muss der + Abstand stimmen. Abgeleitet aus den Brettern selbst, nicht von Hand + gepflegt: eine Liste, die niemand pflegt, kann nicht veralten. */ +const BRETTER = { + treff: ["hallo", "frage", "lob", "problem"], + anschlag: ["ansage", "regel", "hinweis", "danke"], + ansteht: ["stream", "event", "turnier", "pause"], + wunsch: ["stream", "technik", "gemeinsam", "sonstiges"], + highlight: ["clip", "bild", "fanart", "moment"], + regeln: ["regel", "frage", "hilfe", "folge"], + mitmachen: ["gesucht", "lust", "frage"], +}; + +/* Ab hier gilt ein Unterschied als erkennbar. Bei den Kacheln war die + Grenze 0.14; Etiketten sind kleiner und stehen direkt untereinander, + deshalb hier etwas strenger. */ +const MIN_ABSTAND = 0.10; +/* WCAG AA für kleine Schrift. */ +const MIN_KONTRAST = 4.5; + +/* --------------------------------------------------------------------- + MESSEN + --------------------------------------------------------------------- */ +/* --------------------------------------------------------------------- + DIE SUCHE + + Für jede Art steht der Farbwinkel fest. Gesucht werden Helligkeit + und Buntheit -- so bunt wie möglich, aber nur, wenn der Ton + + 1. in sRGB liegt, + 2. auf dunklem Grund lesbar ist und + 3. von jeder Art, die auf DEMSELBEN Brett steht, weit genug + entfernt bleibt. + + Die Arten werden nach Anzahl der Nachbarn sortiert: Wer die meisten + Bedingungen erfüllen muss, wählt zuerst. Umgekehrt bliebe für ihn am + Ende nichts übrig -- dieselbe Überlegung wie bei den Kacheln. + --------------------------------------------------------------------- */ +const nachbarn = {}; +for (const arten of Object.values(BRETTER)) { + for (const a of arten) { + nachbarn[a] = nachbarn[a] || new Set(); + for (const b of arten) if (b !== a) nachbarn[a].add(b); + } +} + +const hex = {}; +let fehlt = 0; +const reihenfolge = Object.keys(TOENE) + .sort((a, b) => (nachbarn[b]?.size || 0) - (nachbarn[a]?.size || 0)); + +for (const art of reihenfolge) { + const H = TOENE[art]; + /* SO GEDECKT WIE MOEGLICH, nicht so bunt wie moeglich. + + Der erste Versuch suchte die kraeftigste Fassung -- heraus kamen + Toene wie #35f695 und #f584fd: Neongruen und Neonviolett. Das + widerspricht der Hausregel („gedeckte statt reisserisch-grelle + Neon-Optik"), und auf einem Brett mit siebzehn Karten waere es + eine Leuchtreklame. + + Gesucht wird deshalb die LEISESTE Farbe, die noch reicht: gerade + bunt genug, um sie von den Nachbarn zu unterscheiden, und gerade + hell genug, um lesbar zu sein. Buntheit ist hier eine Kostenstelle, + kein Ziel. + + Helligkeit von der Mitte aus nach aussen: 0.78 ist die Vorgabe; + nur wo sie nicht reicht, wird abgewichen. */ + let bester = null, besteBuntheit = 9; + const helligkeiten = [0.78]; + for (let d = 0.01; d <= 0.10; d += 0.01) helligkeiten.push(0.78 + d, 0.78 - d); + + for (const Lv of helligkeiten) { + for (let C = 0.03; C <= 0.20; C += 0.005) { + const f = ausOklch(Lv, C, H); + if (!f) continue; + if (kontrast(f, GRUND) < MIN_KONTRAST) continue; + let passt = true; + for (const n of (nachbarn[art] || [])) { + if (hex[n] && abstand(f, hex[n]) < MIN_ABSTAND) { passt = false; break; } + } + if (!passt) continue; + /* Der erste Treffer je Helligkeit ist schon der leiseste. */ + if (C < besteBuntheit) { besteBuntheit = C; bester = f; } + break; + } + /* Reicht die Vorgabe-Helligkeit, wird gar nicht weitergesucht. */ + if (bester && besteBuntheit <= 0.08) break; + } + if (!bester) { + console.log(`FEHL ${art}: kein Ton gefunden, der alle drei Bedingungen erfuellt`); + fehlt++; + continue; + } + hex[art] = bester; +} + +console.log("=== Kontrast auf dunklem Grund ==="); +let zuDunkel = 0; +for (const [art, f] of Object.entries(hex)) { + const k = kontrast(f, GRUND); + if (k < MIN_KONTRAST) { zuDunkel++; console.log(` FEHL ${art.padEnd(10)} ${f} ${k.toFixed(2)}`); } +} +console.log(zuDunkel ? ` ${zuDunkel} Ton/Töne zu dunkel` : ` alle ${Object.keys(hex).length} Töne lesbar`); + +console.log(""); +console.log("=== Abstand INNERHALB eines Bretts ==="); +let zuNah = 0, paare = 0; +for (const [brett, arten] of Object.entries(BRETTER)) { + let kleinster = 9, wo = ""; + for (let i = 0; i < arten.length; i++) { + for (let j = i + 1; j < arten.length; j++) { + if (!hex[arten[i]] || !hex[arten[j]]) continue; + paare++; + const d = abstand(hex[arten[i]], hex[arten[j]]); + if (d < kleinster) { kleinster = d; wo = `${arten[i]}/${arten[j]}`; } + if (d < MIN_ABSTAND) { + zuNah++; + console.log(` FEHL ${brett}: ${arten[i]} und ${arten[j]} nur ${d.toFixed(3)} auseinander`); + } + } + } + console.log(` ${brett.padEnd(11)} engstes Paar ${wo.padEnd(22)} ${kleinster.toFixed(3)}`); +} + +/* --------------------------------------------------------------------- + STIMMT DAS CSS NOCH MIT DIESER RECHNUNG UEBEREIN? + + Ohne diese Frage prueft das Werkzeug nur sich selbst. Jemand aendert + einen Ton von Hand im CSS -- weil er dunkler aussehen soll --, und + die Messung hier bleibt gruen, weil sie ihre eigene Tabelle misst + und nicht das, was ausgeliefert wird. Genau die Art Pruefung, die + immer bestaetigt. + --------------------------------------------------------------------- */ +let abweichend = 0, verglichen = 0; +if (process.argv[2] !== "schreiben") { + let css = ""; + try { css = readFileSync(CSS, "utf8"); } catch { css = ""; } + if (!css) { + console.log(""); + console.log(" -- bereich.css nicht lesbar -- nicht abgeglichen"); + } else { + console.log(""); + console.log("=== Stimmt das CSS mit dieser Rechnung ueberein? ==="); + for (const [art, f] of Object.entries(hex)) { + const treffer = new RegExp( + `\\.marke-art\\[data-art="${art}"\\]\\s*\\{\\s*--art-ton:\\s*(#[0-9a-f]{6})`, "i").exec(css); + verglichen++; + if (!treffer) { + abweichend++; + console.log(` FEHL ${art.padEnd(10)} steht gar nicht im CSS`); + } else if (treffer[1].toLowerCase() !== f.toLowerCase()) { + abweichend++; + console.log(` FEHL ${art.padEnd(10)} CSS ${treffer[1]} statt ${f}`); + } + } + /* Die Anzahl gehoert in die Bedingung -- sonst waere „0 Abweichungen" + auch bei leerer Tabelle wahr. */ + console.log(verglichen >= 20 && abweichend === 0 + ? ` alle ${verglichen} Toene im CSS stimmen` + : ` ${abweichend} von ${verglichen} weichen ab -- „node tools/art-farben.mjs schreiben" hilft`); + } +} + +console.log(""); +if (fehlt || zuDunkel || zuNah || abweichend || (process.argv[2] !== "schreiben" && verglichen < 20)) { + console.log(`NICHT IN ORDNUNG -- ${fehlt} ausserhalb, ${zuDunkel} zu dunkel, ` + + `${zuNah} zu nah, ${abweichend} weichen vom CSS ab`); + process.exit(1); +} +console.log(`ALLES IN ORDNUNG -- ${Object.keys(hex).length} Töne, ${paare} Paare geprüft`); + +/* --------------------------------------------------------------------- + SCHREIBEN + --------------------------------------------------------------------- */ +if (process.argv[2] === "schreiben") { + const zeilen = Object.entries(hex).map(([art, f]) => + `.marke-art[data-art="${art}"] { --art-ton: ${f}; }`); + const block = ` +/* ---- EIN TON JE ART (18.09.2026) ---------------------------------- + Erzeugt von tools/art-farben.mjs -- NICHT von Hand ändern. + Das Werkzeug misst zweierlei und lässt sich nicht überreden: + den Abstand zwischen zwei Arten auf DEMSELBEN Brett (OKLab, ab + ${MIN_ABSTAND}) und den Kontrast auf dunklem Grund (ab ${MIN_KONTRAST}:1). + + Warum überhaupt: Alle Etiketten trugen denselben blauen Ton. Bei + siebzehn Karten untereinander hatte das Auge nichts, woran es sich + festhalten konnte -- man liest dann jede Überschrift, statt zu + überfliegen. Der Ton folgt der BEDEUTUNG, nicht der Reihenfolge: + Lob grün, „etwas stimmt nicht" warmrot, Fragen blau. Deshalb trägt + die Art „frage" auf drei Brettern denselben Ton. */ +.marke-art[data-art] { + background: color-mix(in srgb, var(--art-ton) 16%, transparent); + color: var(--art-ton); +} +${zeilen.join("\n")} +`; + let css = readFileSync(CSS, "utf8"); + const marke = "/* ---- EIN TON JE ART (18.09.2026) ---"; + const i = css.indexOf(marke); + if (i >= 0) css = css.slice(0, i).replace(/\n+$/, "\n"); + writeFileSync(CSS, css + block, "utf8"); + console.log(`\n${zeilen.length} Töne nach bereich.css geschrieben.`); +} diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index 4ab004d7..8375e538 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609181858", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609182010", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609181858", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609182010", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609181858", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609182010", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609181858", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609182010", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/css/bereich.css b/workspace/assets/css/bereich.css index 2bf69abe..c7c8f30e 100644 --- a/workspace/assets/css/bereich.css +++ b/workspace/assets/css/bereich.css @@ -1504,3 +1504,43 @@ } .starthilfe__beispiel:hover { border-color: var(--akzent); } .starthilfe__beispiel:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; } + +/* ---- EIN TON JE ART (18.09.2026) ---------------------------------- + Erzeugt von tools/art-farben.mjs -- NICHT von Hand ändern. + Das Werkzeug misst zweierlei und lässt sich nicht überreden: + den Abstand zwischen zwei Arten auf DEMSELBEN Brett (OKLab, ab + 0.1) und den Kontrast auf dunklem Grund (ab 4.5:1). + + Warum überhaupt: Alle Etiketten trugen denselben blauen Ton. Bei + siebzehn Karten untereinander hatte das Auge nichts, woran es sich + festhalten konnte -- man liest dann jede Überschrift, statt zu + überfliegen. Der Ton folgt der BEDEUTUNG, nicht der Reihenfolge: + Lob grün, „etwas stimmt nicht" warmrot, Fragen blau. Deshalb trägt + die Art „frage" auf drei Brettern denselben Ton. */ +.marke-art[data-art] { + background: color-mix(in srgb, var(--art-ton) 16%, transparent); + color: var(--art-ton); +} +.marke-art[data-art="frage"] { --art-ton: #a8baca; } +.marke-art[data-art="regel"] { --art-ton: #c2b981; } +.marke-art[data-art="stream"] { --art-ton: #bab3c8; } +.marke-art[data-art="hallo"] { --art-ton: #90e1e6; } +.marke-art[data-art="lob"] { --art-ton: #90b888; } +.marke-art[data-art="problem"] { --art-ton: #e4a59f; } +.marke-art[data-art="ansage"] { --art-ton: #e2ccc0; } +.marke-art[data-art="hinweis"] { --art-ton: #a9b9ce; } +.marke-art[data-art="danke"] { --art-ton: #c592b3; } +.marke-art[data-art="event"] { --art-ton: #f8bcdd; } +.marke-art[data-art="turnier"] { --art-ton: #d69b81; } +.marke-art[data-art="pause"] { --art-ton: #7ba2cc; } +.marke-art[data-art="technik"] { --art-ton: #8ed7ef; } +.marke-art[data-art="gemeinsam"] { --art-ton: #86c4a8; } +.marke-art[data-art="sonstiges"] { --art-ton: #dbcaff; } +.marke-art[data-art="clip"] { --art-ton: #b5b5ca; } +.marke-art[data-art="bild"] { --art-ton: #8adbdb; } +.marke-art[data-art="fanart"] { --art-ton: #b88dba; } +.marke-art[data-art="moment"] { --art-ton: #deac83; } +.marke-art[data-art="hilfe"] { --art-ton: #a4deb7; } +.marke-art[data-art="folge"] { --art-ton: #e8a5b4; } +.marke-art[data-art="gesucht"] { --art-ton: #ceb480; } +.marke-art[data-art="lust"] { --art-ton: #bfdbb1; } diff --git a/workspace/assets/js/bereich.js b/workspace/assets/js/bereich.js index 751793f7..68cf7822 100644 --- a/workspace/assets/js/bereich.js +++ b/workspace/assets/js/bereich.js @@ -331,7 +331,12 @@ k.dataset.status = e.status; const kopf = el('div', 'eintrag-kopf'); - kopf.append(el('span', 'marke-art', einstellung.arten[e.art] || e.art)); + const marke = el('span', 'marke-art', einstellung.arten[e.art] || e.art); + /* Die Art als Merkmal am Element -- daran haengt der Ton (siehe + tools/art-farben.mjs). Kein Klassenname je Art: Der waere eine + zweite Liste, die mit der ersten auseinanderlaeuft. */ + if (e.art) marke.dataset.art = e.art; + kopf.append(marke); /* DIE VERTRAULICHE ZEILE SAGT ES SELBST (10.09.2026). Sie kommt ohnehin nur bei DogFather und beim Schreiber an -- der diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 71cb20f2..7e608cc3 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -12,19 +12,19 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - + @@ -291,10 +291,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index 1841414f..b7ed83cc 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -168,10 +168,10 @@ - - - - - + + + + + diff --git a/workspace/befinden.html b/workspace/befinden.html index 70460843..41d97b87 100644 --- a/workspace/befinden.html +++ b/workspace/befinden.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -105,9 +105,9 @@ - - - - + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 3343ba62..4a80cf18 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -12,24 +12,24 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - - + + - + @@ -251,14 +251,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/bewerben.html b/workspace/bewerben.html index feaeea57..80d78e7d 100644 --- a/workspace/bewerben.html +++ b/workspace/bewerben.html @@ -7,17 +7,17 @@ - - - - - - - - - + + + + + + + + + - + @@ -107,10 +107,10 @@ - - - - - + + + + + diff --git a/workspace/bewerbungen.html b/workspace/bewerbungen.html index 3c96b205..8c647944 100644 --- a/workspace/bewerbungen.html +++ b/workspace/bewerbungen.html @@ -7,16 +7,16 @@ - - - - - - - - + + + + + + + + - + @@ -80,10 +80,10 @@ - - - - - + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 82708639..eb18eabe 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -89,11 +89,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index d98148dc..97798eb4 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -12,26 +12,26 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -341,15 +341,15 @@ - - - - + + + + - - + + diff --git a/workspace/content.html b/workspace/content.html index 50cbf5ef..6db56f06 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -179,12 +179,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/crew-index.html b/workspace/crew-index.html index bb564762..b85d942d 100644 --- a/workspace/crew-index.html +++ b/workspace/crew-index.html @@ -36,15 +36,15 @@ - - - + + + - + @@ -339,6 +339,6 @@ - + diff --git a/workspace/crew.webmanifest b/workspace/crew.webmanifest index afeb8a1a..5f241a83 100644 --- a/workspace/crew.webmanifest +++ b/workspace/crew.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/crew-192.png?v=202609181858", + "src": "/assets/img/app-symbole/crew-192.png?v=202609182010", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-512.png?v=202609181858", + "src": "/assets/img/app-symbole/crew-512.png?v=202609182010", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609181858", + "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609182010", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609181858", + "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609182010", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/dateien.html b/workspace/dateien.html index e6889c15..d286c926 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -108,10 +108,10 @@ - - - - - + + + + + diff --git a/workspace/entwicklung.html b/workspace/entwicklung.html index bff39be5..e1e6c3c3 100644 --- a/workspace/entwicklung.html +++ b/workspace/entwicklung.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -102,9 +102,9 @@ - - - - + + + + diff --git a/workspace/index.html b/workspace/index.html index 95dbbec2..fb1b7732 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -30,9 +30,9 @@ - - - + + + @@ -401,6 +401,6 @@ - + diff --git a/workspace/kalender.html b/workspace/kalender.html index 093da072..6656e2f1 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -377,11 +377,11 @@ - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index 1914099c..18b2d5e2 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -444,10 +444,10 @@ - - - - - + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index 477c0863..985be2ac 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -423,10 +423,10 @@ - - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index e1761c4d..cf5902a3 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -214,11 +214,11 @@ - - - - - - + + + + + + diff --git a/workspace/rechte.html b/workspace/rechte.html index 62ea8f17..dfa175fb 100644 --- a/workspace/rechte.html +++ b/workspace/rechte.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -134,9 +134,9 @@ Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen, die seit dem 07.09. jede Seite danach absucht. --> - - - - + + + + diff --git a/workspace/report.html b/workspace/report.html index fa90c1ac..c63ec172 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -106,11 +106,11 @@ - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 8d028e0c..db3c7936 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -173,10 +173,10 @@ - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index 4321ec84..9f3e2ce4 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -12,21 +12,21 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - + + - + @@ -674,10 +674,10 @@

- - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index d3c95338..6c186247 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -85,11 +85,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index ce1a53cc..97e9b3d8 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -146,11 +146,11 @@ - - - - - - + + + + + + diff --git a/workspace/talente.html b/workspace/talente.html index 2864dd42..fd623f76 100644 --- a/workspace/talente.html +++ b/workspace/talente.html @@ -7,18 +7,18 @@ - - - - - - + + + + + + - - - + + + @@ -111,9 +111,9 @@ - - - - + + + + diff --git a/workspace/team.html b/workspace/team.html index 5e5c5a18..02370658 100644 --- a/workspace/team.html +++ b/workspace/team.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + @@ -110,10 +110,10 @@ - - - - - + + + + + diff --git a/workspace/teamlage.html b/workspace/teamlage.html index a94e56f1..7780ca80 100644 --- a/workspace/teamlage.html +++ b/workspace/teamlage.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + - - - - + + + + diff --git a/workspace/teilen.html b/workspace/teilen.html index c138d85a..2871657e 100644 --- a/workspace/teilen.html +++ b/workspace/teilen.html @@ -7,13 +7,13 @@ - - - - - - - + + + + + + + @@ -112,9 +112,9 @@ - - - - + + + + diff --git a/workspace/treff-moderation.html b/workspace/treff-moderation.html index 4a7af4bf..d219df6b 100644 --- a/workspace/treff-moderation.html +++ b/workspace/treff-moderation.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -126,9 +126,9 @@ - - - - + + + + diff --git a/workspace/treff-regeln.html b/workspace/treff-regeln.html index 097c0929..0746cb4f 100644 --- a/workspace/treff-regeln.html +++ b/workspace/treff-regeln.html @@ -7,18 +7,18 @@ - - - - - - - + + + + + + + - + @@ -211,10 +211,10 @@ Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen, die seit dem 07.09. jede Seite danach absucht. --> - - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index de245537..30468f68 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -12,22 +12,22 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -149,11 +149,11 @@ - + - - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index e6438a40..b66b7332 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -190,10 +190,10 @@ - - - - - + + + + +