diff --git a/pruef-kalender-computer.png b/pruef-kalender-computer.png index 7a81aa95..500b7b34 100644 Binary files a/pruef-kalender-computer.png and b/pruef-kalender-computer.png differ diff --git a/pruef-kalender-handy.png b/pruef-kalender-handy.png index 7363f5a5..cd8b6edc 100644 Binary files a/pruef-kalender-handy.png and b/pruef-kalender-handy.png differ diff --git a/server/pruef-workspace-seiten.mjs b/server/pruef-workspace-seiten.mjs index 219e379d..47800b14 100644 --- a/server/pruef-workspace-seiten.mjs +++ b/server/pruef-workspace-seiten.mjs @@ -98,12 +98,25 @@ for (const [breite, hoehe, wie] of [[1440, 1000, "Computer"], [390, 844, "Handy" Verweis auf die Startseite? */ rueckweg: document.querySelector(".kopfleiste .marke__haupt")?.tagName === "A" ? document.querySelector(".kopfleiste .marke__haupt").getAttribute("href") : null, + /* Jede Unterseite trägt Zeichen und Farbton ihrer Kachel. Beides + kommt aus bereiche.js, derselben Liste wie die Kachel -- fehlt + eins davon, ist die Zuordnung gerissen und die Seite sieht + wieder aus wie jede andere. */ + ton: document.body.dataset.ton || null, + kopfZeichen: document.querySelectorAll(".kopf-zeichen__svg path").length, + kopfZeichenFarbe: document.querySelector(".kopf-zeichen__svg") + ? getComputedStyle(document.querySelector(".kopf-zeichen__svg")).stroke : null, + wasserzeichen: document.querySelectorAll(".kopf-wasserzeichen__svg path").length, })); const istStart = s === "start.html"; const markeGut = r.markeHaupt && r.markeLeise && r.markeRaute === 1 && (istStart || r.rueckweg === "start.html"); + /* Auf der Startseite gibt es keinen Seitenkopf -- dort sind die + Kacheln selbst der Kopf. Überall sonst ist er Pflicht. */ + const kopfGut = istStart + || (r.ton !== null && r.kopfZeichen > 0 && r.wasserzeichen > 0); const gut = r.ueber <= 0 && konsole.length === 0 && r.abmelden !== false - && markeGut + && markeGut && kopfGut && (r.breit === null || r.breit === "1240px") && (r.kopfzeile === null || r.kopfzeile === "flex"); if (!gut) fehler++; @@ -111,7 +124,8 @@ for (const [breite, hoehe, wie] of [[1440, 1000, "Computer"], [390, 844, "Handy" + `über=${String(r.ueber).padStart(3)}px abmelden=${r.abmelden}` + ` marke=${r.markeHaupt ? `"${r.markeHaupt}"◆"${r.markeLeise}"` : "FEHLT"}` + `${istStart ? "" : ` zurück=${r.rueckweg || "FEHLT"}`}` - + ` breit=${r.breit} kopfzeile=${r.kopfzeile}` + + `${istStart ? "" : ` ton=${r.ton || "FEHLT"} zeichen=${r.kopfZeichen}/${r.wasserzeichen}`}` + + ` breit=${r.breit}` + (konsole.length ? " KONSOLE: " + konsole.join(" | ") : "") + (r.schuld.length ? " -> " + r.schuld.join(" | ") : "")); } diff --git a/workspace/assets/css/kalender.css b/workspace/assets/css/kalender.css index fa9d7826..c687cb5c 100644 --- a/workspace/assets/css/kalender.css +++ b/workspace/assets/css/kalender.css @@ -17,10 +17,21 @@ Man liest zuerst, WO man ist, und bewegt sich dann. Deshalb steht der Monat groß und die Navigation daneben, nicht umgekehrt. */ .k-kopf { + position: relative; overflow: hidden; display: flex; align-items: flex-end; justify-content: space-between; flex-wrap: wrap; gap: 16px; - margin-bottom: 22px; + margin-bottom: 22px; padding-bottom: 18px; + /* Dieselbe auslaufende Trennlinie wie auf allen anderen Seiten -- der + Kalender hat zwar einen eigenen Kopf, gehört aber zur selben + Familie. Die Farbe kommt aus data-ton am body (kopf.js). */ + border-bottom: 1px solid transparent; + border-image: linear-gradient(90deg, + color-mix(in srgb, var(--ton, var(--akzent)) 40%, var(--rand-hell)), + transparent 62%) 1; } +/* Zeichen und Zeitraum nebeneinander (die Plakette setzt kopf.js). */ +.k-kopf .kopf-zeile__marke { align-items: center; } +.k-kopf .k-kopf__titel { min-width: 0; } .k-zeitraum { margin: 0; font-size: clamp(1.7rem, 3.2vw, 2.4rem); diff --git a/workspace/assets/css/start.css b/workspace/assets/css/start.css index 7c07e025..37b38894 100644 --- a/workspace/assets/css/start.css +++ b/workspace/assets/css/start.css @@ -230,11 +230,111 @@ body.start > main { position: relative; z-index: 1; } .zurueck { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; } .zurueck:hover { border-bottom-color: currentColor; } +/* ---------- Der Kopf jeder Unterseite ------------------------------------ + + Bis zum 01.09.2026 war das eine Zeile Text mit einem Knopf daneben -- + auf allen dreizehn Seiten dieselbe, in derselben Farbe, ohne Zeichen. + Wer eine Kachel anklickte, verlor beim Übergang jede Spur davon, + woher er kam. + + Jetzt trägt der Kopf Zeichen UND Farbton seiner Kachel (gesetzt von + kopf.js aus derselben Liste, aus der auch die Kachel kommt) und + bekommt dieselbe Behandlung wie sie: Plakette mit dem Zeichen, ein + leuchtender Strich über der Bereichsangabe, ein sehr schwaches + Wasserzeichen dahinter und eine auslaufende Trennlinie darunter. + + Nichts davon ist Schmuck um seiner selbst willen: Es ist dieselbe + Bildsprache wie auf der Startseite, und dadurch weiß man ohne Lesen, + wo man ist. */ .kopf-zeile { + position: relative; + overflow: hidden; display: flex; align-items: flex-end; justify-content: space-between; - gap: 20px; flex-wrap: wrap; margin-bottom: 24px; + gap: 20px; flex-wrap: wrap; + margin-bottom: 28px; padding: 0 0 20px; + border-bottom: 1px solid transparent; + border-image: linear-gradient(90deg, + color-mix(in srgb, var(--ton, var(--akzent)) 40%, var(--rand-hell)), + transparent 62%) 1; +} +.kopf-zeile .titel { + margin: 0; + font-size: clamp(1.5rem, 2.6vw, 2.1rem); + letter-spacing: -.02em; + color: #f2f7fd; + text-shadow: 0 2px 22px color-mix(in srgb, var(--ton, var(--akzent)) 22%, transparent); +} +.kopf-zeile .unterzeile { margin-bottom: 0; } + +/* Zeichen und Text nebeneinander. Der Block darf schrumpfen (min-width), + sonst drückt er den Knopf rechts aus dem Bild -- derselbe Fehler wie + im August in der Kopfleiste. */ +.kopf-zeile__marke { + display: flex; align-items: center; gap: 16px; + min-width: 0; flex: 1 1 auto; + position: relative; z-index: 1; +} +.kopf-zeichen { + flex: none; + display: grid; place-items: center; + width: 52px; height: 52px; border-radius: 15px; + border: 1px solid color-mix(in srgb, var(--ton, var(--akzent)) 34%, transparent); + background: + radial-gradient(120% 120% at 30% 18%, + color-mix(in srgb, var(--ton, var(--akzent)) 26%, transparent), transparent 72%), + rgba(255, 255, 255, .04); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, .09), + 0 12px 28px -14px color-mix(in srgb, var(--ton, var(--akzent)) 70%, transparent); +} +.kopf-zeichen__svg { + width: 26px; height: 26px; + fill: none; stroke: var(--ton, var(--akzent)); stroke-width: 1.6; + stroke-linecap: round; stroke-linejoin: round; +} + +/* Der Bereichsname über dem Titel bekommt denselben leuchtenden Strich + wie die Abschnitte auf der Startseite -- so gehört sichtbar zusammen, + was zusammengehört. */ +.kopf-zeile .marke { + display: flex; align-items: center; gap: 9px; + margin-bottom: 7px; + color: color-mix(in srgb, var(--ton, var(--akzent)) 62%, #cfe0f0); +} +.kopf-zeile .marke::before { + content: ""; + width: 22px; height: 2px; border-radius: 2px; + background: linear-gradient(90deg, var(--ton, var(--akzent)), transparent); +} + +/* Dasselbe Zeichen noch einmal, riesig und fast unsichtbar. Es liegt im + Kopf (overflow: hidden schneidet es sauber ab) und macht jede Seite + auf den ersten Blick unverwechselbar, ohne dass man es bewusst + wahrnimmt. */ +.kopf-wasserzeichen { + position: absolute; right: -18px; top: 50%; + transform: translateY(-50%) rotate(-8deg); + pointer-events: none; + opacity: .06; + z-index: 0; +} +.kopf-wasserzeichen__svg { + width: 190px; height: 190px; + fill: none; stroke: var(--ton, var(--akzent)); stroke-width: 1; + stroke-linecap: round; stroke-linejoin: round; +} +/* Auf schmalen Bildschirmen läge das Wasserzeichen unter dem Text und + würde ihn unruhig machen -- dort bleibt es weg. */ +@media (max-width: 720px) { + .kopf-wasserzeichen { display: none; } + .kopf-zeichen { width: 42px; height: 42px; border-radius: 12px; } + .kopf-zeichen__svg { width: 21px; height: 21px; } + .kopf-zeile__marke { gap: 12px; } +} +@media (forced-colors: active) { + .kopf-wasserzeichen { display: none; } + .kopf-zeichen__svg { stroke: CanvasText; } } -.kopf-zeile .titel { margin: 0; font-size: clamp(1.4rem, 2.2vw, 1.85rem); } .leise { color: var(--text-still); font-weight: 400; } diff --git a/workspace/assets/js/bereiche.js b/workspace/assets/js/bereiche.js new file mode 100644 index 00000000..2e8383d0 --- /dev/null +++ b/workspace/assets/js/bereiche.js @@ -0,0 +1,175 @@ +/* =================================================================== + 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), alle nur aus Linien -- gefüllte Zeichen + wirken neben Text wie Flecken. Eigene statt einer Fremdbibliothek: + siebzehn Pfade sind kleiner als jede Schriftart und kosten keine + zusätzliche Lieferkette. */ + + const ZEICHEN = { + dashboard: ['M4.5 4.5h6v6h-6z', 'M13.5 4.5h6v4h-6z', 'M13.5 11.5h6v8h-6z', 'M4.5 13.5h6v6h-6z'], + aufgaben: ['M4.5 5h4v14h-4z', 'M10 5h4v9h-4z', 'M15.5 5h4v11.5h-4z'], + kalender: ['M4 6.5h16v13H4z', 'M4 10.5h16', 'M8.5 3.5v4', 'M15.5 3.5v4'], + calls: ['M3.5 7h11v10h-11z', 'M14.5 11l6-3.5v9l-6-3.5z'], + dateien: ['M3.5 6.5h5.5l2 2h9.5v11h-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.3'], + startcheck: ['M6 4.5h12v15H6z', 'M9.2 9.6l1.7 1.7 3.6-3.7', 'M9.2 15.2h5.6'], + live: ['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: ['M3.5 6h17v13h-17z', 'M3.5 10h17', 'M8 6l-1.4 4', 'M13 6l-1.4 4', 'M18 6l-1.4 4'], + technik: ['M4 7.5h16', 'M4 12h16', 'M4 16.5h16', + 'M9 7.5a1.4 1.4 0 1 0 0-.02z', 'M15 12a1.4 1.4 0 1 0 0-.02z', + 'M7.5 16.5a1.4 1.4 0 1 0 0-.02z'], + 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.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: ['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: ['M4 19.5h16', 'M7.5 16.5V9.5', 'M12 16.5V5.5', 'M16.5 16.5v-5'], + personen: ['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: ['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'], + }; + + /* ---------- 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' }, + { name: 'Aufgaben', unter: 'Offen, in Arbeit, Review', zeichen: 'aufgaben', ton: 9, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'aufgaben.html' }, + { name: 'Kalender', unter: 'Termine und Calls', zeichen: 'kalender', ton: 15, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'kalender.html' }, + { name: 'Calls & Protokolle', unter: 'Gespräche mit To-dos', zeichen: 'calls', ton: 8, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'calls.html' }, + { name: 'Dateien', unter: 'Ablage und Freigaben', zeichen: 'dateien', ton: 16, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'dateien.html' }, + ], + }, + { + name: 'Rund um den Creator', + unter: 'Die Betreuungsakte – Stand, Zahlen, Verlauf', + bereiche: [ + { name: 'Creator-Profile', unter: 'Ziele und 90-Tage-Plan', zeichen: 'profil', ton: 4, + rollen: ['admin', 'manager', 'scout'], ziel: 'profil.html' }, + { name: 'Mein Profil', unter: 'Deine Ziele und Pläne', zeichen: 'profil', ton: 4, + rollen: ['creator'], ziel: 'profil.html' }, + { name: 'Start-Check', unter: 'Erstanalyse, 16 Punkte', zeichen: 'startcheck', ton: 14, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'startcheck.html' }, + { name: 'LIVE-Analyse', unter: 'Vorher, während, danach', zeichen: 'live', ton: 6, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=live' }, + { name: 'Content-Planung', unter: 'Idee bis Upload', zeichen: 'content', ton: 10, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'content.html' }, + { name: 'Community', unter: 'Moderation und Konflikte', zeichen: 'community', ton: 5, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=community' }, + { name: 'Technik', unter: 'Setup, Fehler, Lösungen', zeichen: 'technik', ton: 11, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=technik' }, + { name: 'Schutz & Regeln', unter: 'Richtlinien und Vorfälle', zeichen: 'schutz', ton: 1, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=schutz' }, + { name: 'Reports & Review', unter: 'Woche und Entscheidung', zeichen: 'reports', ton: 13, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'report.html' }, + ], + }, + { + 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: [ + { name: 'Personen & Zugänge', unter: 'Rollen und Codes', zeichen: 'personen', ton: 7, + rollen: ['admin', 'manager'], ziel: 'personen.html' }, + { name: 'Scout-Pipeline', unter: 'Entdeckt bis übergeben', zeichen: 'scouting', ton: 12, + rollen: ['admin', 'manager', 'scout'], ziel: 'scouting.html' }, + { name: 'Wissens-Bibliothek', unter: 'Anleitungen und PDFs', zeichen: 'wissen', ton: 2, + rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'wissen.html' }, + { name: 'Automationen', unter: 'Was von allein passiert', zeichen: 'automation', ton: 17, + rollen: ['admin', 'manager'], ziel: 'automation.html' }, + ], + }, + ]; + + /* 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. */ + function zeichenBauen(name, klasse = 'kachel__svg') { + 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); + for (const d of (ZEICHEN[name] || [])) { + const p = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + p.setAttribute('d', d); + svg.append(p); + } + return svg; + } + + window.Bereiche = { ZEICHEN, GRUPPEN, zuSeite, zeichenBauen }; +})(); diff --git a/workspace/assets/js/kopf.js b/workspace/assets/js/kopf.js index b3ac0939..e2e4f70a 100644 --- a/workspace/assets/js/kopf.js +++ b/workspace/assets/js/kopf.js @@ -116,6 +116,70 @@ return true; } + /* ---------- Jede Seite trägt Zeichen und Farbe ihrer Kachel ------------- + + Auf der Startseite hat jeder Bereich sein eigenes Zeichen und seinen + eigenen Farbton. Bisher endete das an der Kachel: Wer sie anklickte, + landete auf einer Seite, der man nicht mehr ansah, woher sie kam -- + dreizehn Seiten, alle in demselben Blau, alle ohne Zeichen. + + Jetzt wird die Kachel weitergereicht. Der Kopf der Seite bekommt + dasselbe Zeichen groß daneben, denselben Farbton für Strich, Zeichen + und Titel, und dasselbe Zeichen noch einmal riesig und fast + unsichtbar als Wasserzeichen -- genau die Behandlung, die auf der + Startseite aus siebzehn Kästen siebzehn unterscheidbare Bereiche + gemacht hat. + + Die Zuordnung kommt aus assets/js/bereiche.js, also aus derselben + Liste wie die Kachel selbst. Wer dort eine Farbe ändert, ändert + Kachel UND Seite -- sie können gar nicht auseinanderlaufen. */ + (function seiteEinfaerben() { + const B = window.Bereiche; + /* Der Kalender hat einen eigenen Kopf (.k-kopf), weil dort der + Zeitraum die Überschrift ist. Er soll sein Zeichen trotzdem + bekommen -- sonst wäre ausgerechnet die aufwendigste Seite die + einzige ohne. */ + const kopf = document.querySelector('.kopf-zeile, .k-kopf'); + if (!B || !kopf) return; + + const bereich = B.zuSeite(location.pathname, location.search); + if (!bereich) return; + + /* Der Ton hängt am body: Damit erreicht er auch Bauteile, die weit + unten auf der Seite stehen (Karten, Knöpfe, Zähler) -- nicht nur + den Kopf. Die 17 Töne selbst stehen in start.css und hängen nur am + Merkmal data-ton, nicht an einer Klasse. */ + document.body.dataset.ton = String(bereich.ton); + + /* Der Kopf ist bisher ein
mit Text. Er bekommt links eine + Plakette mit dem Zeichen -- eingefügt VOR dem vorhandenen Text, + ohne ihn anzufassen. Dadurch funktioniert das auf allen dreizehn + Seiten, ohne dreizehn HTML-Dateien zu ändern. */ + const erstes = kopf.firstElementChild; + if (!erstes) return; + + const plakette = document.createElement('span'); + plakette.className = 'kopf-zeichen'; + plakette.setAttribute('aria-hidden', 'true'); + plakette.append(B.zeichenBauen(bereich.zeichen, 'kopf-zeichen__svg')); + + const reihe = document.createElement('div'); + reihe.className = 'kopf-zeile__marke'; + reihe.append(plakette); + kopf.insertBefore(reihe, erstes); + reihe.append(erstes); + + /* Das Wasserzeichen: dasselbe Zeichen riesig und bei sehr geringer + Deckkraft hinter dem Kopf. Es liegt im Kopf selbst, nicht auf der + Seite -- sonst würde es beim Blättern mitwandern und stören. */ + const schatten = document.createElement('span'); + schatten.className = 'kopf-wasserzeichen'; + schatten.setAttribute('aria-hidden', 'true'); + schatten.append(B.zeichenBauen(bereich.zeichen, 'kopf-wasserzeichen__svg')); + kopf.append(schatten); + kopf.dataset.gezeichnet = 'ja'; + })(); + /* ---------- Der Schriftzug oben links ----------------------------------- Er stand als eine Zeile in einer Farbe da: "DOGFATHER UNIVERSE · diff --git a/workspace/assets/js/start.js b/workspace/assets/js/start.js index 9947bfda..eaa1c456 100644 --- a/workspace/assets/js/start.js +++ b/workspace/assets/js/start.js @@ -33,127 +33,12 @@ scout: 'Scout · deine Pipeline und die Creator, die du betreust', }; - /* ---------- Zeichen ------------------------------------------------------ + /* Zeichen und Bereiche kommen aus assets/js/bereiche.js -- derselben + Quelle, aus der auch die Kopfleisten der Unterseiten ihr Zeichen und + ihre Farbe nehmen. Zwei Listen wären der sichere Weg dazu, dass ein + Bereich hier gelb und dort grün ist. */ + const { ZEICHEN, GRUPPEN, zeichenBauen } = window.Bereiche; - Alle im selben Raster (24×24), alle nur aus Linien -- gefüllte Zeichen - wirken neben Text wie Flecken. Eigene statt einer Fremdbibliothek: - siebzehn Pfade sind kleiner als jede Schriftart und kosten keine - zusätzliche Lieferkette. */ - - const ZEICHEN = { - dashboard: ['M4.5 4.5h6v6h-6z', 'M13.5 4.5h6v4h-6z', 'M13.5 11.5h6v8h-6z', 'M4.5 13.5h6v6h-6z'], - aufgaben: ['M4.5 5h4v14h-4z', 'M10 5h4v9h-4z', 'M15.5 5h4v11.5h-4z'], - kalender: ['M4 6.5h16v13H4z', 'M4 10.5h16', 'M8.5 3.5v4', 'M15.5 3.5v4'], - calls: ['M3.5 7h11v10h-11z', 'M14.5 11l6-3.5v9l-6-3.5z'], - dateien: ['M3.5 6.5h5.5l2 2h9.5v11h-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.3'], - startcheck: ['M6 4.5h12v15H6z', 'M9.2 9.6l1.7 1.7 3.6-3.7', 'M9.2 15.2h5.6'], - live: ['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: ['M3.5 6h17v13h-17z', 'M3.5 10h17', 'M8 6l-1.4 4', 'M13 6l-1.4 4', 'M18 6l-1.4 4'], - technik: ['M4 7.5h16', 'M4 12h16', 'M4 16.5h16', - 'M9 7.5a1.4 1.4 0 1 0 0-.02z', 'M15 12a1.4 1.4 0 1 0 0-.02z', - 'M7.5 16.5a1.4 1.4 0 1 0 0-.02z'], - 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.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: ['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: ['M4 19.5h16', 'M7.5 16.5V9.5', 'M12 16.5V5.5', 'M16.5 16.5v-5'], - personen: ['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: ['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'], - }; - - /* ---------- 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' }, - { name: 'Aufgaben', unter: 'Offen, in Arbeit, Review', zeichen: 'aufgaben', ton: 9, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'aufgaben.html' }, - { name: 'Kalender', unter: 'Termine und Calls', zeichen: 'kalender', ton: 15, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'kalender.html' }, - { name: 'Calls & Protokolle', unter: 'Gespräche mit To-dos', zeichen: 'calls', ton: 8, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'calls.html' }, - { name: 'Dateien', unter: 'Ablage und Freigaben', zeichen: 'dateien', ton: 16, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'dateien.html' }, - ], - }, - { - name: 'Rund um den Creator', - unter: 'Die Betreuungsakte – Stand, Zahlen, Verlauf', - bereiche: [ - { name: 'Creator-Profile', unter: 'Ziele und 90-Tage-Plan', zeichen: 'profil', ton: 4, - rollen: ['admin', 'manager', 'scout'], ziel: 'profil.html' }, - { name: 'Mein Profil', unter: 'Deine Ziele und Pläne', zeichen: 'profil', ton: 4, - rollen: ['creator'], ziel: 'profil.html' }, - { name: 'Start-Check', unter: 'Erstanalyse, 16 Punkte', zeichen: 'startcheck', ton: 14, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'startcheck.html' }, - { name: 'LIVE-Analyse', unter: 'Vorher, während, danach', zeichen: 'live', ton: 6, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=live' }, - { name: 'Content-Planung', unter: 'Idee bis Upload', zeichen: 'content', ton: 10, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'content.html' }, - { name: 'Community', unter: 'Moderation und Konflikte', zeichen: 'community', ton: 5, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=community' }, - { name: 'Technik', unter: 'Setup, Fehler, Lösungen', zeichen: 'technik', ton: 11, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=technik' }, - { name: 'Schutz & Regeln', unter: 'Richtlinien und Vorfälle', zeichen: 'schutz', ton: 1, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=schutz' }, - { name: 'Reports & Review', unter: 'Woche und Entscheidung', zeichen: 'reports', ton: 13, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'report.html' }, - ], - }, - { - 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: [ - { name: 'Personen & Zugänge', unter: 'Rollen und Codes', zeichen: 'personen', ton: 7, - rollen: ['admin', 'manager'], ziel: 'personen.html' }, - { name: 'Scout-Pipeline', unter: 'Entdeckt bis übergeben', zeichen: 'scouting', ton: 12, - rollen: ['admin', 'manager', 'scout'], ziel: 'scouting.html' }, - { name: 'Wissens-Bibliothek', unter: 'Anleitungen und PDFs', zeichen: 'wissen', ton: 2, - rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'wissen.html' }, - { name: 'Automationen', unter: 'Was von allein passiert', zeichen: 'automation', ton: 17, - rollen: ['admin', 'manager'], ziel: 'automation.html' }, - ], - }, - ]; /* Welcher Hinweis gehört auf welche Kachel. Die Zahl auf der Kachel ist damit KEIN neuer Zähler, sondern dieselbe Quelle wie die Liste @@ -197,19 +82,6 @@ return k; }; - function zeichenBauen(name, klasse = 'kachel__svg') { - 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); - for (const d of (ZEICHEN[name] || [])) { - const p = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - p.setAttribute('d', d); - svg.append(p); - } - return svg; - } - let ich = null; let hinweise = []; diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 731378c9..cd1982b4 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -7,9 +7,9 @@ - - - + + + @@ -139,8 +139,9 @@ - - - + + + + diff --git a/workspace/automation.html b/workspace/automation.html index 55cc5288..abdc16bb 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -132,8 +132,9 @@ - - - + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 2791d0af..bef765f0 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -107,8 +107,9 @@ - - - + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 698b9077..a5b8db05 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -54,9 +54,10 @@ - - - - + + + + + diff --git a/workspace/content.html b/workspace/content.html index 873c17f6..dc73a4c4 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -158,8 +158,9 @@ - - - + + + + diff --git a/workspace/dateien.html b/workspace/dateien.html index 7e2c8956..32e081a8 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -93,8 +93,9 @@ - - - + + + + diff --git a/workspace/index.html b/workspace/index.html index 9d57750a..775ae08c 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -25,7 +25,7 @@ type="image/webp" media="(max-width: 899px)" /> - + @@ -143,6 +143,6 @@

- + diff --git a/workspace/kalender.html b/workspace/kalender.html index 94c25fe5..db8b2b88 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -147,8 +147,9 @@ - - - + + + + diff --git a/workspace/personen.html b/workspace/personen.html index ba41cc9d..b6c82510 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -121,8 +121,9 @@ - - - + + + + diff --git a/workspace/profil.html b/workspace/profil.html index 6ca7f621..88516cd4 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -132,8 +132,9 @@ - - - + + + + diff --git a/workspace/report.html b/workspace/report.html index b319ca35..3dc1744e 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -91,9 +91,10 @@ - - - - + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 8168489b..6ac26279 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -124,8 +124,9 @@
- - - + + + + diff --git a/workspace/start.html b/workspace/start.html index d06bcb85..9cb25373 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -7,8 +7,8 @@ - - + + @@ -99,8 +99,9 @@

- - - + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index dd61af63..f63ff6d1 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -70,9 +70,10 @@ - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index 7fa508ce..ec1ec1ca 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -7,9 +7,9 @@ - - - + + + @@ -57,7 +57,9 @@ - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 106e4b0d..a1583263 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -175,8 +175,9 @@ - - - + + + +