"wir kommen nicht voran, ich will das viel realistischer."
Berechtigt: Ich habe viermal dieselbe flache Zeichnung anders
BELEUCHTET -- Verlauf, Fuellung, Glanz, Schlagschatten. Das Verfahren
war das Problem, nicht die Einstellungen. Also gewechselt.
JEDES ZEICHEN HAT JETZT EINE HOEHE. Aufbau von hinten nach vorn:
tiefe 3/2/1 dieselbe Silhouette, dreimal, je einen halben
Rasterpunkt nach rechts unten versetzt und heller
werdend. Das Auge liest die drei versetzten Kanten als
EINE schraege Seitenwand -- genau so zeichnet man einen
Quader von Hand. Drei Lagen sind gemessen: bei zwei
sieht es aus wie ein Druckfehler, ab fuenf wie ein
Schlagschatten.
deck die Oberseite: oben fast weiss, unten im Farbton. Die
Flaeche, auf die das Licht faellt.
glanz die Spiegelung darauf.
saum + linie die Details.
Dafuer bekam jedes Zeichen eine SILHOUETTE (KOERPER in bereiche.js) --
den geschlossenen Umriss des Gegenstands, getrennt von den Details.
Die Details bekommen bewusst KEINE Tiefe: Ein aufgedruckter Strich
steht nicht hervor.
DER SAUM ist die Loesung eines Problems, das erst durch die Tiefe
entstand: Dieselbe Linie liegt ueber ZWEI Untergruenden. Der Querstrich
im Kalender liegt auf der hellen Deckflaeche, die Wellen der
LIVE-Analyse frei auf der dunklen Plakette. Eine dunkle Linie
verschwindet dort, eine helle auf dem Deck -- was immer man waehlt, die
Haelfte ist weg. Dunkler Saum plus helle Linie loest beides: auf dem
Deck liest man eine eingravierte Rille, auf der Plakette traegt die
helle Linie. Ein Zeichen, zwei Untergruende, eine Loesung.
GEPRUEFT: Buehne 38 (Textkontrast an echten Bildpunkten), Startansicht
133, Rollen 97, Handy 50, Grosscheck 15, Lesbarkeit 14. Alle gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
662 lines
30 KiB
JavaScript
662 lines
30 KiB
JavaScript
/* ===================================================================
|
||
Die Bereiche -- EINE Quelle für die ganze Anwendung.
|
||
|
||
Zeichen, Farbton, Rolle und Ziel jedes Bereichs standen bis zum
|
||
01.09.2026 nur in start.js. Seit jede Unterseite Zeichen und Farbe
|
||
ihrer Kachel trägt, brauchen sie auch die Kopfleisten -- und eine
|
||
zweite, abgeschriebene Liste wäre der sichere Weg, dass "Aufgaben"
|
||
irgendwann auf der Startseite gelb und auf der Aufgabenseite grün ist.
|
||
|
||
Deshalb liegt beides jetzt hier und wird von start.js UND kopf.js
|
||
benutzt. Wer eine Kachel ändert, ändert damit automatisch auch den
|
||
Kopf der zugehörigen Seite.
|
||
=================================================================== */
|
||
(() => {
|
||
'use strict';
|
||
|
||
/* ---------- Zeichen ------------------------------------------------------
|
||
|
||
Alle im selben Raster (24×24). Seit dem 03.09.2026 besteht jedes
|
||
Zeichen aus ZWEI Teilen:
|
||
|
||
fuellung eine gefüllte Grundform -- der Gegenstand selbst,
|
||
gedeckt hinterlegt
|
||
linien die scharfe Zeichnung darüber
|
||
|
||
Das ist der Unterschied zwischen einem Symbol und einem Piktogramm.
|
||
Eine reine Kontur ist neutral; sobald ein Teil FLÄCHE hat, bekommt
|
||
das Zeichen ein Vorn und ein Hinten, und das Auge erkennt es, ohne
|
||
es zu lesen. Gefüllt wird immer das, worum es geht: beim Kalender
|
||
der Kopf, beim Ordner der Korpus, bei einer Person der Kopf, beim
|
||
Regler die Griffe.
|
||
|
||
WARUM NICHT EINFACH DICKER: Ein früherer Versuch legte eine dicke,
|
||
weichgezeichnete Kopie der LINIE darunter. Das hat die feinen
|
||
Lücken zugeschmiert -- aus dem Kalender wurde ein leerer Kasten
|
||
(siehe start.css). Eine Fläche ist etwas anderes als ein
|
||
aufgeblasener Strich: Sie liegt INNERHALB der Kontur und lässt die
|
||
Zwischenräume unberührt.
|
||
|
||
Eigene Pfade statt einer Fremdbibliothek: siebzehn Zeichen sind
|
||
kleiner als jede Schriftart und kosten keine Lieferkette. */
|
||
|
||
/* ---------- Die Silhouetten -------------------------------------------
|
||
|
||
Der UMRISS jedes Gegenstands als geschlossene Form. Aus ihm entsteht
|
||
die Tiefe: Er wird dreimal übereinander gezeichnet, jedes Mal ein
|
||
Stück versetzt und dunkler -- unten die Grundfläche, darüber die
|
||
Seitenwand, oben die Deckfläche. Das ist dasselbe Verfahren, mit dem
|
||
man einen Körper von Hand zeichnet, und es ist der Grund, warum die
|
||
Zeichen jetzt eine Höhe haben statt nur einen Umriss.
|
||
|
||
Getrennt von den Linien gehalten: Die Linien sind die DETAILS auf der
|
||
Oberfläche (Querstriche, Haken, Wellen). Sie bekommen keine Tiefe --
|
||
ein aufgedruckter Strich steht nicht hervor. */
|
||
const KOERPER = {
|
||
dashboard: [
|
||
'M4 4.5h6.4v6.4H4z',
|
||
'M13.6 4.5h6.4v4.2h-6.4z',
|
||
'M13.6 11.6h6.4v7.9h-6.4z',
|
||
'M4 13.7h6.4v5.8H4z'
|
||
],
|
||
aufgaben: [
|
||
'M4.5 5h4v14h-4z',
|
||
'M10 5h4v9h-4z',
|
||
'M15.5 5h4v11.5h-4z'
|
||
],
|
||
kalender: [
|
||
'M3.5 7h17v12.5h-17z'
|
||
],
|
||
calls: [
|
||
'M3.5 7h11v10h-11z',
|
||
'M14.5 11l6-3.5v9l-6-3.5z'
|
||
],
|
||
dateien: [
|
||
'M3.5 6.5h5.5l2 2h9.5v11h-17z'
|
||
],
|
||
steckbrief: [
|
||
'M3.5 5.5h17v13h-17z'
|
||
],
|
||
profil: [
|
||
'M12 7a3.2 3.2 0 1 0 0 6.4A3.2 3.2 0 0 0 12 7z',
|
||
'M5.5 20c.7-3.3 3.3-5.3 6.5-5.3s5.8 2 6.5 5.3z'
|
||
],
|
||
startcheck: [
|
||
'M6 4.5h12v15H6z'
|
||
],
|
||
live: [
|
||
'M12 10.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z'
|
||
],
|
||
content: [
|
||
'M3.5 6h17v13h-17z'
|
||
],
|
||
technik: [
|
||
'M9 5.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M15 10.4a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M7.5 14.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z'
|
||
],
|
||
community: [
|
||
'M9 8.6a2.7 2.7 0 1 0 0 5.4 2.7 2.7 0 0 0 0-5.4z',
|
||
'M3.5 19.5c.6-2.8 2.8-4.5 5.5-4.5s4.9 1.7 5.5 4.5z'
|
||
],
|
||
schutz: [
|
||
'M12 3.6 5.6 6.3v5.1c0 3.8 2.6 7.2 6.4 8.4 3.8-1.2 6.4-4.6 6.4-8.4V6.3z'
|
||
],
|
||
reports: [
|
||
'M6.6 9.5h1.8v7h-1.8z',
|
||
'M11.1 5.5h1.8v11h-1.8z',
|
||
'M15.6 11.5h1.8v5h-1.8z'
|
||
],
|
||
personen: [
|
||
'M14.4 6.2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z'
|
||
],
|
||
scouting: [
|
||
'M3.5 5.5h17l-6.6 7.6v6.4l-3.8-2.1v-4.3z'
|
||
],
|
||
wissen: [
|
||
'M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z',
|
||
'M20 5h-6.4c-.9 0-1.6.7-1.6 1.6V19c0-.9.7-1.6 1.6-1.6H20z'
|
||
],
|
||
automation: [
|
||
'M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'
|
||
]
|
||
};
|
||
|
||
const ZEICHEN = {
|
||
dashboard: {
|
||
/* Zwei der vier Felder gefüllt, über Eck -- das gibt dem Zeichen
|
||
einen Rhythmus. Alle vier zu füllen wäre ein Klotz. */
|
||
fuellung: ['M4 4.5h6.4v6.4H4z', 'M13.6 11.6h6.4v7.9h-6.4z'],
|
||
linien: ['M4 4.5h6.4v6.4H4z', 'M13.6 4.5h6.4v4.2h-6.4z',
|
||
'M13.6 11.6h6.4v7.9h-6.4z', 'M4 13.7h6.4v5.8H4z'],
|
||
},
|
||
aufgaben: {
|
||
/* Die mittlere Spalte -- "in Arbeit". Das Brett hat drei Spalten,
|
||
und die mittlere ist die, in der gerade etwas passiert. */
|
||
fuellung: ['M10 5h4v9h-4z'],
|
||
linien: ['M4.5 5h4v14h-4z', 'M10 5h4v9h-4z', 'M15.5 5h4v11.5h-4z'],
|
||
},
|
||
kalender: {
|
||
/* Der Kopf des Blattes. Genau der Streifen, an dem man einen
|
||
Kalender auch aus drei Metern erkennt. */
|
||
fuellung: ['M3.5 7h17v4.5h-17z'],
|
||
linien: ['M3.5 7h17v12.5h-17z', 'M3.5 11.5h17', 'M7.5 4v4.6', 'M16.5 4v4.6'],
|
||
},
|
||
calls: {
|
||
/* Das Objektiv. Der Kasten bleibt offen, sonst wird das Zeichen
|
||
schwer. */
|
||
fuellung: ['M14.5 11l6-3.5v9l-6-3.5z'],
|
||
linien: ['M3.5 7h11v10h-11z', 'M14.5 11l6-3.5v9l-6-3.5z'],
|
||
},
|
||
dateien: {
|
||
/* Der Korpus ohne die Lasche -- so bleibt die Stufe oben sichtbar,
|
||
die den Ordner ausmacht. */
|
||
fuellung: ['M3.5 10h17v9.5h-17z'],
|
||
linien: ['M3.5 6.5h5.5l2 2h9.5v11h-17z', 'M3.5 10h17'],
|
||
},
|
||
steckbrief: {
|
||
/* Kopf und Schultern der Person IN der Karte -- unterscheidbar vom
|
||
Profil-Zeichen (nur die Person), damit die beiden Kacheln nicht
|
||
gleich aussehen. */
|
||
fuellung: ['M8.5 11.2a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8z'],
|
||
linien: ['M3.5 5.5h17v13h-17z', 'M8.5 11.2a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8z',
|
||
'M5.6 16.2c0-1.7 1.3-3 2.9-3s2.9 1.3 2.9 3', 'M14.5 9.5h4', 'M14.5 13h4'],
|
||
},
|
||
profil: {
|
||
fuellung: ['M12 7a3.2 3.2 0 1 0 0 6.4A3.2 3.2 0 0 0 12 7z'],
|
||
linien: ['M12 7a3.2 3.2 0 1 0 0 6.4A3.2 3.2 0 0 0 12 7z',
|
||
'M5.5 20c.7-3.3 3.3-5.3 6.5-5.3s5.8 2 6.5 5.3'],
|
||
},
|
||
startcheck: {
|
||
/* Nur der Haken ist gefüllt -- er ist die Aussage des Zeichens.
|
||
Ein gefülltes Klemmbrett wäre ein Kasten. */
|
||
fuellung: ['M9.2 9.6l1.7 1.7 3.6-3.7 1 1-4.6 4.7-2.7-2.7z'],
|
||
linien: ['M6 4.5h12v15H6z', 'M9.2 9.6l1.7 1.7 3.6-3.7', 'M9.2 15.2h5.6'],
|
||
},
|
||
live: {
|
||
/* Der Sender in der Mitte. Die Wellen bleiben Linien -- gefüllte
|
||
Wellen sähen aus wie ein Auge. */
|
||
fuellung: ['M12 10.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z'],
|
||
linien: ['M12 10.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z',
|
||
'M8.2 8.2a5.4 5.4 0 0 0 0 7.6', 'M15.8 15.8a5.4 5.4 0 0 0 0-7.6',
|
||
'M5.4 5.4a9.4 9.4 0 0 0 0 13.2', 'M18.6 18.6a9.4 9.4 0 0 0 0-13.2'],
|
||
},
|
||
content: {
|
||
/* Die Klappe der Filmklappe. */
|
||
fuellung: ['M3.5 6h17v4h-17z'],
|
||
linien: ['M3.5 6h17v13h-17z', 'M3.5 10h17', 'M8 6l-1.4 4', 'M13 6l-1.4 4', 'M18 6l-1.4 4'],
|
||
},
|
||
technik: {
|
||
/* Die drei Griffe. Sie waren bis zum 03.09.2026 Bögen der Länge
|
||
null und wurden nie gezeichnet -- übrig blieben drei nackte
|
||
Striche, die aussahen wie ein Menü-Symbol. */
|
||
fuellung: ['M9 5.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M15 10.4a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M7.5 14.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z'],
|
||
linien: ['M4 7.5h16', 'M4 12h16', 'M4 16.5h16',
|
||
'M9 5.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M15 10.4a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z',
|
||
'M7.5 14.9a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 0 0 0-3.2z'],
|
||
},
|
||
community: {
|
||
/* Der vordere Kopf. Der hintere bleibt Kontur -- dadurch entsteht
|
||
die Tiefe, um die es bei zwei Personen geht. */
|
||
fuellung: ['M9 8.6a2.7 2.7 0 1 0 0 5.4 2.7 2.7 0 0 0 0-5.4z'],
|
||
linien: ['M9 8.6a2.7 2.7 0 1 0 0 5.4 2.7 2.7 0 0 0 0-5.4z',
|
||
'M3.5 19.5c.6-2.8 2.8-4.5 5.5-4.5s4.9 1.7 5.5 4.5',
|
||
'M16 8.8a2.4 2.4 0 1 1 1.6 4.3', 'M17 15.2c2 .5 3.3 2 3.7 4.3'],
|
||
},
|
||
schutz: {
|
||
fuellung: ['M12 3.6 5.6 6.3v5.1c0 3.8 2.6 7.2 6.4 8.4 3.8-1.2 6.4-4.6 6.4-8.4V6.3z'],
|
||
linien: ['M12 3.6 5.6 6.3v5.1c0 3.8 2.6 7.2 6.4 8.4 3.8-1.2 6.4-4.6 6.4-8.4V6.3z',
|
||
'M9.4 11.8l1.9 1.9 3.4-3.6'],
|
||
},
|
||
reports: {
|
||
/* Aus drei Strichen werden drei Säulen -- ein Balkendiagramm hat
|
||
Balken, keine Striche. */
|
||
fuellung: ['M6.6 9.5h1.8v7h-1.8z', 'M11.1 5.5h1.8v11h-1.8z', 'M15.6 11.5h1.8v5h-1.8z'],
|
||
linien: ['M4 19.5h16', 'M6.6 9.5h1.8v7h-1.8z', 'M11.1 5.5h1.8v11h-1.8z',
|
||
'M15.6 11.5h1.8v5h-1.8z'],
|
||
},
|
||
personen: {
|
||
/* Der Bart des Schlüssels bleibt Linie, der Kopf wird Fläche. */
|
||
fuellung: ['M14.4 6.2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z'],
|
||
linien: ['M14.4 6.2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z', 'M11.6 12.2 4 19.8',
|
||
'M6.4 17.4l2 2', 'M8.6 15.2l2 2'],
|
||
},
|
||
scouting: {
|
||
/* Der Trichter, aber nur der obere Teil -- der Stiel bleibt offen,
|
||
sonst kippt das Zeichen optisch nach unten. */
|
||
fuellung: ['M3.5 5.5h17l-6.6 7.6h-3.8z'],
|
||
linien: ['M3.5 5.5h17l-6.6 7.6v6.4l-3.8-2.1v-4.3z'],
|
||
},
|
||
wissen: {
|
||
/* Die linke Seite gefüllt: ein aufgeschlagenes Buch hat eine
|
||
Seite im Licht und eine im Schatten. */
|
||
fuellung: ['M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z'],
|
||
linien: ['M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z',
|
||
'M20 5h-6.4c-.9 0-1.6.7-1.6 1.6V19c0-.9.7-1.6 1.6-1.6H20z'],
|
||
},
|
||
automation: {
|
||
fuellung: ['M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'],
|
||
linien: ['M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'],
|
||
},
|
||
};
|
||
|
||
/* ---------- Die Bereiche -------------------------------------------------
|
||
|
||
`rollen` steuert, wem ein Bereich überhaupt erscheint -- serverseitig
|
||
wird es ohnehin noch einmal geprüft, das hier ist nur Höflichkeit.
|
||
|
||
`ton` ist der Farbplatz 1..17 -- JEDE Kachel hat ihre eigene Farbe.
|
||
|
||
Ein erster Versuch mit frei gewählten Farben ergab Paare mit einem
|
||
Abstand von 1,4: praktisch dieselbe Farbe, das sieht nach Zufall aus
|
||
statt nach Absicht. Deshalb sind Farben UND Zuordnung gerechnet, von
|
||
tools/kachel-farben.mjs. Die Überlegung dahinter: Das Auge vergleicht
|
||
nur, was nebeneinander liegt. Siebzehn Farben müssen sich also nicht
|
||
alle voneinander unterscheiden, sondern nur von ihren Nachbarn im
|
||
Raster -- und da sind es jetzt mindestens 105,9 Grad.
|
||
|
||
Wer hier Kacheln umsortiert oder eine hinzufügt, ändert damit die
|
||
Nachbarschaften. Dann gehört tools/kachel-farben.mjs neu gelaufen
|
||
(dort die Liste NACHBARN anpassen), sonst stimmt der Abstand nicht
|
||
mehr und niemand merkt es. */
|
||
|
||
const GRUPPEN = [
|
||
{
|
||
name: 'Täglich',
|
||
unter: 'Was du sowieso jeden Tag aufmachst',
|
||
bereiche: [
|
||
{ name: 'Dashboard', unter: 'Alle Creator auf einen Blick', zeichen: 'dashboard', ton: 3,
|
||
gross: true, rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'uebersicht.html', szene: 'showbuehne' },
|
||
{ name: 'Aufgaben', unter: 'Offen, in Arbeit, Review', zeichen: 'aufgaben', ton: 11,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'aufgaben.html', szene: 'garage' },
|
||
{ name: 'Kalender', unter: 'Termine und Calls', zeichen: 'kalender', ton: 16,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'kalender.html', szene: 'skyline' },
|
||
{ name: 'Calls & Protokolle', unter: 'Gespräche mit To-dos', zeichen: 'calls', ton: 9,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'calls.html', szene: 'lounge' },
|
||
{ name: 'Dateien', unter: 'Ablage und Freigaben', zeichen: 'dateien', ton: 2,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'dateien.html', szene: 'arena' },
|
||
],
|
||
},
|
||
{
|
||
name: 'Rund um den Creator',
|
||
unter: 'Die Betreuungsakte – Stand, Zahlen, Verlauf',
|
||
bereiche: [
|
||
/* ZWEI VERSCHIEDENE DINGE, zwei Kacheln (01.09.2026).
|
||
|
||
Vorher war beides dieselbe Seite, und das war verwirrend:
|
||
Oben stand "Profil: SpongBobSchwammKopf" und mitten darin
|
||
"MEIN PROFIL - Dogfather". Zwei Personen auf einem Bildschirm,
|
||
ohne dass klar war, welche gerade gemeint ist.
|
||
|
||
Es sind auch wirklich zwei Sachen:
|
||
MEIN STECKBRIEF gehoert MIR -- Bild, ein Satz ueber mich,
|
||
meine Kanaele. Fuehre ich selbst, hat
|
||
jeder (auch Scouts und Manager).
|
||
CREATOR-PROFILE die BETREUUNGSAKTE eines Creators --
|
||
Ziele, 90-Tage-Plan, interne Notizen.
|
||
Fuehren die Betreuer.
|
||
|
||
Ein Creator sieht nur seine eigene Akte (dort steht auch sein
|
||
Steckbrief mit drin, er hat ja nur eine Seite). Alle anderen
|
||
bekommen beide Kacheln getrennt. */
|
||
{ name: 'Mein Steckbrief', unter: 'Dein Bild und deine Kanäle', zeichen: 'steckbrief', ton: 15,
|
||
rollen: ['admin', 'manager', 'scout'], ziel: 'steckbrief.html', szene: 'halle' },
|
||
{ name: 'Creator-Profile', unter: 'Ziele und 90-Tage-Plan', zeichen: 'profil', ton: 8,
|
||
rollen: ['admin', 'manager', 'scout'], ziel: 'profil.html', szene: 'halle' },
|
||
{ name: 'Mein Profil', unter: 'Dein Steckbrief, Ziele und Pläne', zeichen: 'profil', ton: 8,
|
||
rollen: ['creator'], ziel: 'profil.html', szene: 'halle' },
|
||
{ name: 'Start-Check', unter: 'Erstanalyse, 16 Punkte', zeichen: 'startcheck', ton: 18,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'startcheck.html', szene: 'wald' },
|
||
{ name: 'LIVE-Analyse', unter: 'Vorher, während, danach', zeichen: 'live', ton: 7,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=live', szene: 'portal' },
|
||
{ name: 'Content-Ideen', unter: 'Idee bis Upload', zeichen: 'content', ton: 13,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'content.html', szene: 'portal' },
|
||
{ name: 'Community', unter: 'Moderation und Konflikte', zeichen: 'community', ton: 6,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=community', szene: 'lounge' },
|
||
{ name: 'Technik', unter: 'Setup, Fehler, Lösungen', zeichen: 'technik', ton: 12,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=technik', szene: 'garage' },
|
||
{ name: 'Schutz & Regeln', unter: 'Richtlinien und Vorfälle', zeichen: 'schutz', ton: 1,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=schutz', szene: 'halle' },
|
||
{ name: 'Reports & Review', unter: 'Woche und Entscheidung', zeichen: 'reports', ton: 14,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'report.html', szene: 'showbuehne' },
|
||
],
|
||
},
|
||
{
|
||
name: 'Team & System',
|
||
unter: 'Was den Laden am Laufen hält',
|
||
/* Für einen Creator bleibt von dieser Gruppe genau eine Kachel übrig:
|
||
die Wissens-Bibliothek. "Team & System" wäre dann eine Überschrift,
|
||
die etwas verspricht, was gar nicht da ist -- und die klingt, als
|
||
gäbe es dahinter noch einen Bereich, den er nicht sehen darf. Er
|
||
liest stattdessen "Wissen", und das beschreibt genau, was dort
|
||
steht. Der Untertitel wechselt mit. */
|
||
nameCreator: 'Wissen',
|
||
unterCreator: 'Nachschlagen, wenn du etwas brauchst',
|
||
bereiche: [
|
||
/* NUR DogFather (02.09.2026, Wunsch: "die manager sollen diese
|
||
kategorien garnicht sehen").
|
||
|
||
Es war ohnehin ein Widerspruch: In der Rollenauswahl steht seit
|
||
jeher "Manager -- dieselben Rechte wie DogFather, AUSSER der
|
||
Personenverwaltung". Die Kachel stand trotzdem bei ihm, und die
|
||
Seite liess ihn auch hinein. Eine Beschreibung, die etwas
|
||
anderes sagt als die Software, ist schlimmer als beides
|
||
einzeln: Man weiss danach nicht mehr, welcher von beiden man
|
||
glauben soll. */
|
||
{ name: 'Personen & Zugänge', unter: 'Rollen und Codes', zeichen: 'personen', ton: 10,
|
||
rollen: ['admin'], ziel: 'personen.html', szene: 'halle' },
|
||
{ name: 'Scout-Pipeline', unter: 'Entdeckt bis übergeben', zeichen: 'scouting', ton: 17,
|
||
rollen: ['admin', 'manager', 'scout'], ziel: 'scouting.html', szene: 'wald' },
|
||
{ name: 'Wissens-Bibliothek', unter: 'Anleitungen und PDFs', zeichen: 'wissen', ton: 4,
|
||
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'wissen.html', szene: 'arena' },
|
||
/* Ebenfalls nur DogFather (02.09.2026). Was von allein passiert,
|
||
legt fest, was ALLEN anderen automatisch zugeschoben wird --
|
||
das gehört in dieselbe Hand wie die Rollenvergabe. */
|
||
{ name: 'Automationen', unter: 'Was von allein passiert', zeichen: 'automation', ton: 5,
|
||
rollen: ['admin'], ziel: 'automation.html', szene: 'garage' },
|
||
],
|
||
},
|
||
];
|
||
|
||
/* Ein Bereich anhand des Dateinamens finden. Die Bereichsseite
|
||
(bereich.html?b=live) trägt ihren Bereich in der Adresse -- deshalb
|
||
wird auch die Abfrage verglichen, nicht nur der Dateiname. */
|
||
function zuSeite(pfad, abfrage) {
|
||
const datei = String(pfad).split('/').pop() || 'start.html';
|
||
const gesucht = datei + (abfrage || '');
|
||
let treffer = null;
|
||
for (const g of GRUPPEN) {
|
||
for (const b of g.bereiche) {
|
||
if (b.ziel === gesucht) return b;
|
||
/* Ohne Abfrage: der erste Bereich mit passendem Dateinamen.
|
||
"Mein Profil" und "Creator-Profile" zeigen auf dieselbe Datei
|
||
und teilen sich Zeichen und Ton -- da ist beides richtig. */
|
||
if (!treffer && b.ziel.split('?')[0] === datei) treffer = b;
|
||
}
|
||
}
|
||
return treffer;
|
||
}
|
||
|
||
/* Ein SVG mit dem Zeichen eines Bereichs. Klasse frei wählbar, damit
|
||
Kachel, Hinweiszeile und Seitenkopf dieselbe Form in
|
||
unterschiedlicher Größe benutzen können. */
|
||
/* ---------- Die Zeichen (überarbeitet 03.09.2026) ------------------------
|
||
|
||
Wunsch: "ich will dass du die symbole perfektionnierst, ich will
|
||
wirklich dass jeder sich denkt woooow."
|
||
|
||
Vorher war jedes Zeichen eine flache Linie in einer Farbe. Sauber,
|
||
aber leblos -- siebzehn gleich starke Striche nebeneinander.
|
||
|
||
Jetzt besteht jedes Zeichen aus ZWEI übereinanderliegenden Lagen
|
||
derselben Form:
|
||
|
||
SCHEIN dick, weich, halbdurchsichtig -- das Licht, das die
|
||
Linie wirft. Sie liegt darunter und wird nie gelesen,
|
||
aber ohne sie sitzt das Zeichen flach auf der Fläche
|
||
statt darüber zu schweben.
|
||
LINIE die eigentliche Zeichnung, mit einem VERLAUF von oben
|
||
hell nach unten gedämpft.
|
||
|
||
Der Verlauf ist der eigentliche Kniff. Er ist EINMAL im Dokument
|
||
definiert und benutzt `currentColor` -- dadurch passt er sich jeder
|
||
der siebzehn Kachelfarben von selbst an, ohne siebzehn Verläufe.
|
||
Eine Lichtquelle oben, wie in der echten Welt: Genau das lässt eine
|
||
Linie geprägt statt gemalt wirken.
|
||
|
||
Kein zusätzliches Bild, keine Schriftart, kein Nachladen -- alles
|
||
entsteht aus den Pfaden, die ohnehin schon da waren. */
|
||
|
||
const NS = 'http://www.w3.org/2000/svg';
|
||
const VERLAUF_ID = 'zeichen-verlaeufe';
|
||
|
||
/* ---------- Die drei Verläufe ------------------------------------------
|
||
|
||
Ein Zeichen wird aus drei Lagen aufgebaut, und jede hat ihren
|
||
eigenen Verlauf. Alle drei stehen EINMAL im Dokument und arbeiten
|
||
mit currentColor -- dadurch nehmen sie den Ton jeder der siebzehn
|
||
Kacheln an, ohne dass es einundfünfzig Verläufe braucht.
|
||
|
||
flaeche die gefüllte Grundform: oben kräftig, unten fast weg.
|
||
Das ist der Körper des Gegenstands.
|
||
linie die Kontur: oben fast WEISS, unten im Farbton. Genau so
|
||
sieht Metall aus, auf das Licht von oben fällt -- und
|
||
genau das lässt ein Zeichen plastisch wirken statt
|
||
gezeichnet.
|
||
glanz ein schmaler heller Streifen quer über die obere Hälfte.
|
||
Die Spiegelung. Sie ist der Unterschied zwischen "gut
|
||
gemacht" und "das will ich anfassen".
|
||
|
||
ALLE in Benutzerkoordinaten (userSpaceOnUse) über die festen 24
|
||
Einheiten des Rasters. In Objektkoordinaten -- der Vorgabe -- würde
|
||
der Verlauf auf den Umriss JEDES einzelnen Pfades gerechnet, und
|
||
eine waagerechte Linie hat die Höhe null: Der Verlauf wäre entartet
|
||
und der Browser zeichnete den Pfad gar nicht. Genau daran sind am
|
||
03.09.2026 die Querlinie im Kalender, die Regler in Technik und die
|
||
Grundlinie der Berichte verschwunden. */
|
||
function verlaufSicherstellen() {
|
||
if (document.getElementById(VERLAUF_ID)) return;
|
||
const svg = document.createElementNS(NS, 'svg');
|
||
svg.setAttribute('id', VERLAUF_ID);
|
||
svg.setAttribute('aria-hidden', 'true');
|
||
svg.setAttribute('width', '0');
|
||
svg.setAttribute('height', '0');
|
||
svg.style.position = 'absolute';
|
||
const defs = document.createElementNS(NS, 'defs');
|
||
|
||
const bauen = (id, stops, x2 = '0', y1 = '2', y2 = '22') => {
|
||
const lg = document.createElementNS(NS, 'linearGradient');
|
||
lg.setAttribute('id', id);
|
||
lg.setAttribute('gradientUnits', 'userSpaceOnUse');
|
||
lg.setAttribute('x1', '0'); lg.setAttribute('y1', y1);
|
||
lg.setAttribute('x2', x2); lg.setAttribute('y2', y2);
|
||
for (const [pos, farbe, deck] of stops) {
|
||
const st = document.createElementNS(NS, 'stop');
|
||
st.setAttribute('offset', pos);
|
||
st.setAttribute('stop-color', farbe);
|
||
st.setAttribute('stop-opacity', deck);
|
||
lg.append(st);
|
||
}
|
||
defs.append(lg);
|
||
};
|
||
|
||
/* Die Deckfläche: oben fast weiss, unten im Farbton. Das ist die
|
||
Seite, auf die das Licht fällt. */
|
||
bauen('zeichen-deck', [
|
||
['0', '#ffffff', '0.92'],
|
||
['0.4', 'currentColor', '0.95'],
|
||
['1', 'currentColor', '0.72'],
|
||
]);
|
||
/* Die Seitenwand: derselbe Ton, deutlich dunkler -- eine Wand, die
|
||
vom Licht abgewandt ist. */
|
||
bauen('zeichen-wand', [
|
||
['0', 'currentColor', '0.5'],
|
||
['1', 'currentColor', '0.28'],
|
||
]);
|
||
|
||
/* Der Körper: oben satt, unten fast durchsichtig. */
|
||
bauen('zeichen-flaeche', [
|
||
['0', 'currentColor', '0.68'],
|
||
['0.45', 'currentColor', '0.38'],
|
||
['1', 'currentColor', '0.12'],
|
||
]);
|
||
/* Der Eigenschatten: eine zweite Fuellung, die von unten dunkel
|
||
hereinkriecht. Ein Koerper ist unten dunkler als oben -- ohne das
|
||
bleibt jede Flaeche eine Farbflaeche. */
|
||
bauen('zeichen-schatten', [
|
||
['0', '#000000', '0'],
|
||
['0.55', '#000000', '0'],
|
||
['1', '#000000', '0.45'],
|
||
]);
|
||
|
||
/* Die Kontur: Licht von oben. Oben fast weiss, unten im Farbton --
|
||
das ist der Trick, der die Zeichen aus der Fläche hebt. */
|
||
/* Die Kontur bekommt ZWEI Lichtquellen -- so wie ein echter
|
||
Gegenstand auf einem Tisch:
|
||
|
||
oben das Hauptlicht, fast weiss
|
||
Mitte der Eigenton des Gegenstands
|
||
unten STREULICHT, das vom Untergrund zurueckgeworfen wird
|
||
|
||
Der letzte Stopp ist der Unterschied zwischen "Zeichnung" und
|
||
"Ding". Ohne ihn laeuft jede Form nach unten ins Dunkle aus und
|
||
sieht aus wie gemalt; mit ihm bekommt sie unten eine Kante, und
|
||
das Auge liest sie als Koerper im Raum. */
|
||
bauen('zeichen-linie', [
|
||
['0', '#ffffff', '0.98'],
|
||
['0.38', '#ffffff', '0.78'],
|
||
['0.78', 'currentColor', '0.95'],
|
||
['1', '#ffffff', '0.42'],
|
||
]);
|
||
|
||
/* Die Spiegelung, diagonal von links oben nach rechts unten. */
|
||
bauen('zeichen-glanz', [
|
||
['0', '#ffffff', '0.55'],
|
||
['0.45', '#ffffff', '0.12'],
|
||
['0.7', '#ffffff', '0'],
|
||
], '18', '0', '20');
|
||
|
||
svg.append(defs);
|
||
document.body.append(svg);
|
||
}
|
||
|
||
function zeichenBauen(name, klasse = 'kachel__svg') {
|
||
verlaufSicherstellen();
|
||
const svg = document.createElementNS(NS, 'svg');
|
||
svg.setAttribute('viewBox', '0 0 24 24');
|
||
svg.setAttribute('aria-hidden', 'true');
|
||
svg.setAttribute('class', klasse);
|
||
|
||
/* Erst die Fläche, dann die Linie -- in dieser Reihenfolge liegt
|
||
die Zeichnung oben. Ein Zeichen ohne Füllung (ältere Einträge,
|
||
die noch ein reines Feld sind) bekommt einfach keine. */
|
||
const eintrag = ZEICHEN[name] || {};
|
||
const umriss = KOERPER[name] || eintrag.fuellung || [];
|
||
const linien = Array.isArray(eintrag) ? eintrag : (eintrag.linien || []);
|
||
|
||
/* ---- Die Tiefe ----------------------------------------------------
|
||
|
||
Dieselbe Silhouette, dreimal, jedes Mal um einen halben
|
||
Rasterpunkt nach rechts unten versetzt. Von hinten nach vorn wird
|
||
sie heller. Das Auge liest die drei versetzten Kanten als EINE
|
||
schräge Seitenwand -- genau so, wie man einen Quader zeichnet.
|
||
|
||
Drei Lagen sind gemessen: bei zwei wirkt es wie ein
|
||
Druckfehler, ab fünf wie ein Schlagschatten. */
|
||
const tiefen = [
|
||
['zeichen__tiefe3', 'translate(1.5 1.5)'],
|
||
['zeichen__tiefe2', 'translate(1 1)'],
|
||
['zeichen__tiefe1', 'translate(0.5 0.5)'],
|
||
];
|
||
for (const [klasse, versatz] of tiefen) {
|
||
if (!umriss.length) break;
|
||
const g = document.createElementNS(NS, 'g');
|
||
g.setAttribute('class', klasse);
|
||
g.setAttribute('transform', versatz);
|
||
for (const d of umriss) {
|
||
const pfad = document.createElementNS(NS, 'path');
|
||
pfad.setAttribute('d', d);
|
||
g.append(pfad);
|
||
}
|
||
svg.append(g);
|
||
}
|
||
|
||
/* ---- Die Deckfläche und was darauf liegt --------------------------- */
|
||
const lagen = [
|
||
['zeichen__deck', umriss], // die Oberseite, hell
|
||
['zeichen__glanz', umriss], // die Spiegelung darauf
|
||
/* Die Details ZWEIMAL: erst ein dunkler Saum, dann die helle
|
||
Linie darauf.
|
||
|
||
Der Grund ist, dass dieselbe Linie über ZWEI Untergründen
|
||
liegt. Ein Querstrich im Kalender liegt auf der hellen
|
||
Deckfläche, die Wellen der LIVE-Analyse dagegen frei auf der
|
||
dunklen Plakette. Eine dunkle Linie verschwindet dort, eine
|
||
helle auf dem Deck -- was immer man wählt, die Hälfte ist weg.
|
||
|
||
Dunkler Saum plus helle Linie löst beides auf einmal: Auf dem
|
||
hellen Deck sieht man den Saum und liest eine eingravierte
|
||
Rille, auf der dunklen Plakette verschwindet er und die helle
|
||
Linie trägt. Ein Zeichen, zwei Untergründe, eine Lösung. */
|
||
['zeichen__saum', linien],
|
||
['zeichen__linie', linien],
|
||
];
|
||
for (const [klasse, pfade] of lagen) {
|
||
if (!pfade.length) continue;
|
||
const g = document.createElementNS(NS, 'g');
|
||
g.setAttribute('class', klasse);
|
||
for (const d of pfade) {
|
||
const pfad = document.createElementNS(NS, 'path');
|
||
pfad.setAttribute('d', d);
|
||
g.append(pfad);
|
||
}
|
||
svg.append(g);
|
||
}
|
||
return svg;
|
||
}
|
||
|
||
/* ---------- Das Merkzeichen ----------------------------------------------
|
||
|
||
Wunsch vom 01.09.2026: "wenn die Ansprechpartner was markieren, sollen
|
||
die da so ein Zeichen/Symbol haben, so dass die sehen, da ist was --
|
||
und es soll auch oben in der Kachel angezeigt werden."
|
||
|
||
Es ist bewusst das EINZIGE Zeichen der ganzen Anwendung, das eine
|
||
eigene Form hat statt der 24×24-Linienzeichen oben: eine Raute mit
|
||
Ausrufestrich. Der Grund ist nicht Geschmack, sondern Erkennbarkeit --
|
||
alle anderen Zeichen sind Rechtecke und Kreise; eine Raute ist die
|
||
einzige Form auf dem Bildschirm, die spitz nach oben zeigt, und
|
||
genau deshalb findet das Auge sie zwischen zwanzig Kacheln sofort.
|
||
|
||
Und es ist immer DIESELBE Farbe (Bernstein), egal auf welcher Kachel
|
||
es sitzt. Ein Zeichen, das seine Farbe wechselt, muss gelesen werden;
|
||
eines, das immer gleich aussieht, wird erkannt. Rot wäre falsch --
|
||
"verbessern" ist kein Fehler, sondern ein Auftrag.
|
||
|
||
anzahl > 1 schreibt die Zahl daneben, sonst steht nur das Zeichen.
|
||
Der Satz für Vorleseprogramme wird immer gesetzt: Ein Symbol ohne
|
||
Text ist für sie nicht vorhanden. */
|
||
function merkzeichenBauen(anzahl = 0, klasse = 'merk') {
|
||
const s = document.createElement('span');
|
||
s.className = klasse;
|
||
s.setAttribute('role', 'img');
|
||
s.setAttribute('aria-label', anzahl > 0
|
||
? `${anzahl} ${anzahl === 1 ? 'Punkt ist' : 'Punkte sind'} zum Verbessern markiert`
|
||
: 'Zum Verbessern markiert');
|
||
|
||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||
svg.setAttribute('viewBox', '0 0 24 24');
|
||
svg.setAttribute('aria-hidden', 'true');
|
||
svg.setAttribute('class', klasse + '__svg');
|
||
/* Drei Pfade: die gefüllte Raute, der Strich, der Punkt. Getrennt,
|
||
damit die Fläche eine andere Deckkraft bekommen kann als die
|
||
Linie -- eine durchgehend volle Raute wäre auf dunklem Grund ein
|
||
Klecks. */
|
||
const teile = [
|
||
['M12 1.9 22.1 12 12 22.1 1.9 12z', 'flaeche'],
|
||
['M12 7.5v5.6', 'strich'],
|
||
['M12 16.9h.01', 'punkt'],
|
||
];
|
||
for (const [d, art] of teile) {
|
||
const p = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||
p.setAttribute('d', d);
|
||
p.setAttribute('class', `${klasse}__${art}`);
|
||
svg.append(p);
|
||
}
|
||
s.append(svg);
|
||
if (anzahl > 1) {
|
||
const n = document.createElement('span');
|
||
n.className = klasse + '__n';
|
||
n.textContent = String(anzahl);
|
||
n.setAttribute('aria-hidden', 'true');
|
||
s.append(n);
|
||
}
|
||
return s;
|
||
}
|
||
|
||
window.Bereiche = { ZEICHEN, GRUPPEN, zuSeite, zeichenBauen, merkzeichenBauen };
|
||
})();
|