diff --git a/server/pruef-css-klassen.mjs b/server/pruef-css-klassen.mjs index ae7c5fa3..cdaf1410 100644 --- a/server/pruef-css-klassen.mjs +++ b/server/pruef-css-klassen.mjs @@ -426,6 +426,57 @@ console.log("\n=== Gegenprobe ==="); "aus classList.add(bedingung ? 'a' : 'b') werden beide Klassen gelesen, aber nicht die Variable"); } +/* ======================================================================= + WER kopf.js LAEDT, MUSS AUCH wahl.js LADEN + + Gefunden am 07.09.2026 beim Durchsehen der Seiten, die bis dahin nur + GEPRUEFT und nie ANGESEHEN worden waren -- chat.html und + uebersicht.html luden kopf.js ohne wahl.js. + + Der Umschalter "Meine Sicht" ist auf allen anderen Seiten ein selbst + gebautes Bedienelement (`.wahl2`), hinter dem ein unsichtbares + Systemfeld fuer Vorleseprogramme liegt. Ohne wahl.js faellt kopf.js + auf dieses Systemfeld zurueck: 92 x 19 Pixel, grauer Kasten, weisse + Schrift, Systemschriftgroesse -- gemessen, nicht geschaetzt. Auf den + anderen Seiten misst dasselbe Feld 2 x 2 Pixel bei Deckkraft null, + weil es dort nur noch der Zugaenglichkeit dient. + + KAPUTT WAR NICHTS. Der Umschalter funktionierte auf beiden Seiten -- + er sah nur aus wie aus einem anderen Programm. Genau diese Sorte + Fehler findet keine Pruefung, die auf Fehlermeldungen achtet, und + auch keine, die Klassennamen zaehlt: Die Klasse `.sicht__feld` ist + NIRGENDS gestaltet und gilt deshalb zu Recht als Struktur-Anker. + + Deshalb hier eine Pruefung auf die ABHAENGIGKEIT statt auf die Optik: + Wer das eine laedt, muss das andere laden -- und zwar vorher. */ +console.log("\n=== Wer kopf.js laedt, laedt auch wahl.js"); +{ + const seitenMitKopf = []; + for (const seite of readdirSync(WS).filter((f) => f.endsWith(".html"))) { + const html = readFileSync(join(WS, seite), "utf8"); + const skripte = [...html.matchAll(/]+src="assets\/js\/([a-z0-9-]+)\.js/g)] + .map((m) => m[1]); + if (!skripte.includes("kopf")) continue; + seitenMitKopf.push({ seite, skripte }); + } + ok(seitenMitKopf.length >= 10, + `${seitenMitKopf.length} Seiten laden kopf.js`); + + const ohneWahl = seitenMitKopf.filter((s) => !s.skripte.includes("wahl")).map((s) => s.seite); + ok(ohneWahl.length === 0, ohneWahl.length + ? `ohne wahl.js: ${ohneWahl.join(", ")}` + : "alle davon laden auch wahl.js"); + + /* UND ZWAR VORHER. kopf.js fragt beim Aufbau nach dem fertigen + Bedienelement; kommt wahl.js danach, ist es zu spaet. */ + const zuSpaet = seitenMitKopf + .filter((s) => s.skripte.indexOf("wahl") > s.skripte.indexOf("kopf")) + .map((s) => s.seite); + ok(zuSpaet.length === 0, zuSpaet.length + ? `wahl.js steht zu spaet auf: ${zuSpaet.join(", ")}` + : "und immer VOR kopf.js"); +} + /* ======================================================================= KEIN SKRIPT BAUT SICH SEINE EIGENE ROLLENLISTE diff --git a/server/pruef-spicy.mjs b/server/pruef-spicy.mjs index 09b6053c..6671045b 100644 --- a/server/pruef-spicy.mjs +++ b/server/pruef-spicy.mjs @@ -420,6 +420,29 @@ const ruf = async (art, weg, keks, koerper) => { `DogFather sieht weiterhin beide (${dTitel.length})`); } { + /* DIE ZAHLEN SIEHT SIE NIRGENDS (07.09.2026). + + Zuerst waren nur Kachel und Seite geschlossen -- die Creator-Zahlen + standen damit weiterhin im Dashboard, weil das sie ueber eine + eigene Schnittstelle holt. Filipe hat entschieden, dass auch das + weg soll. + + Geprueft wird die SCHNITTSTELLE und nicht die Oberflaeche: Eine + ausgeblendete Zeile ist keine Sperre. Und mit Gegenprobe, sonst + bewiese die Zeile nur, dass es den Weg gar nicht gibt. */ + const beiIhr = await ruf("GET", "/workspace/api/leistung", keksSpicy); + ok(beiIhr.status === 404, `die Zahlen antworten ihr mit 404 (${beiIhr.status})`); + const beiIhm = await ruf("GET", "/workspace/api/leistung", keksDogi); + ok(beiIhm.status === 200, `DogFather bekommt sie weiterhin (${beiIhm.status})`); + + /* UND DAS DASHBOARD BLEIBT FUER SIE STEHEN. Das ist der eigentliche + Prueffall: Die Uebersicht holt die Zahlen in einer zusaetzlichen + Abfrage. Faengt sie deren Fehlschlag nicht ab, saehe Spicy Media + statt der Karten eine leere Seite -- eine Sperre, die die halbe + Anwendung mitnimmt, waere schlimmer als keine. */ + const dash = await ruf("GET", "/workspace/api/uebersicht", keksSpicy); + ok(dash.status === 200, `ihre Uebersicht kommt trotzdem (${dash.status})`); + /* Und DogFather bleibt der Einzige mit dem letzten Wort. */ const { status } = await ruf("GET", "/workspace/api/verwaltung/personen", keksDogi); ok(status === 200, `DogFather kommt weiterhin in die Verwaltung (HTTP ${status})`); diff --git a/server/pruef-tagesblick.mjs b/server/pruef-tagesblick.mjs index 9efb5fad..8f2699fc 100644 --- a/server/pruef-tagesblick.mjs +++ b/server/pruef-tagesblick.mjs @@ -163,6 +163,19 @@ melde("\n=== Eine Kachel, mittig geteilt ==="); lichtDa: v.content !== "none" && v.position === "absolute", }; }); + /* Ein Bild davon, wie sie wirklich aussieht. Prueflaeufe messen + Zahlen; ob eine Flaeche gut aussieht, sieht man nur. Die Aufnahme + kostet nichts und ist bei jeder Gestaltungsaenderung das Erste, + wonach ich sonst von Hand suchen muesste. */ + try { + const kasten = await seite.locator("#dran-block").boundingBox(); + if (kasten) { + await seite.screenshot({ path: "pruef-tagesblick.png", + clip: { x: kasten.x - 12, y: kasten.y - 12, + width: kasten.width + 24, height: kasten.height + 24 } }); + } + } catch { /* ein fehlendes Bild ist kein Befund */ } + ok(rahmen.anzeige === "grid" && /polygon/.test(rahmen.silhouette) && parseFloat(rahmen.radius) === 0 diff --git a/server/workspace-leistung.js b/server/workspace-leistung.js index 5e917a04..434ab293 100644 --- a/server/workspace-leistung.js +++ b/server/workspace-leistung.js @@ -44,7 +44,7 @@ import express from "express"; import { - db, protokolliere, echteIp, sitzungLesen, istLeitung, + db, protokolliere, echteIp, sitzungLesen, istLeitung, istSpicy, sichtbareCreatorIds, ROLLEN_SORTIERUNG, } from "./workspace.js"; @@ -73,6 +73,33 @@ function gleicheHerkunft(req, res, next) { leistungRouter.use("/workspace/api/leistung", angemeldet); +/* SPICY MEDIA SIEHT DIE ZAHLEN NIRGENDS (07.09.2026). + + Filipe: "bei der spicy rolle, die zahlen diese kategorie nicht + sehen." Zuerst habe ich woertlich nur die KATEGORIE geschlossen -- + Kachel und Seite. Auf Nachfrage, was noch offen sei, habe ich selbst + darauf hingewiesen, dass die Creator-Zahlen damit weiterhin im + Dashboard stehen (Diamanten, LIVE-Tage, Verweildauer je Karte); + Filipe hat entschieden, dass auch das weg soll. + + DIE SPERRE SITZT AM SERVER UND NICHT IN DER OBERFLAECHE. Eine + ausgeblendete Zeile ist keine Sperre: Wer die Adresse kennt, ruft + die Schnittstelle direkt auf. Hier kommt sie gar nicht mehr an + Daten. + + 404 statt 403, wie ueberall in diesem Haus: Wer nicht hierher + gehoert, muss nicht erfahren, dass es diesen Bereich gibt. + + DAS DASHBOARD BRICHT DADURCH NICHT. Es holt die Zahlen in EINER + zusaetzlichen Abfrage und faengt ihren Fehlschlag ausdruecklich ab + ("die Karten stehen auch ohne", uebersicht.js) -- bei ihr fehlen + also die drei Zeilen, alles andere bleibt. Genau deshalb ist diese + eine Zeile hier der ganze Eingriff. */ +leistungRouter.use("/workspace/api/leistung", (req, res, next) => { + if (istSpicy(req.person)) return res.status(404).json({ fehler: "nicht_gefunden" }); + next(); +}); + /* ---------- Wer darf was ------------------------------------------------ */ /** Wessen Zahlen darf ich SEHEN? Dieselbe Regel wie überall sonst -- diff --git a/workspace/assets/css/heim.css b/workspace/assets/css/heim.css index a24b24cc..b8abb8a1 100644 --- a/workspace/assets/css/heim.css +++ b/workspace/assets/css/heim.css @@ -185,10 +185,19 @@ drop-shadow(0 22px 44px rgba(0, 0, 0, .7)); } -/* DAS INNENGLAS. Eigene Ebene, damit die Fassung ringsum stehen bleibt - -- genau wie bei der Uhr und beim Medaillon. Der Horizont unten ist - der einzige farbige Akzent: Rot links, Babyblau rechts, beide weit - unter der Blendschwelle. */ +/* DAS INNENGLAS mit dem Raster. Eigene Ebene, damit die Fassung + ringsum stehen bleibt -- genau wie bei der Uhr und beim Medaillon. + Der Horizont unten ist der einzige farbige Akzent: Rot links, + Babyblau rechts, beide weit unter der Blendschwelle. + + DAS RASTER LIEGT SEIT DEM 07.09.2026 HIER und nicht mehr auf einer + eigenen halbdurchsichtigen Ebene. Grund: Auf dieser Ebene brauchen + die Nieten volle Deckkraft (siehe unten), und eine Ebene hat nur + EINE Deckkraft. Das Raster kommt deshalb als eigene Verlaufsschicht + mit eigener Alpha -- so ist es genauso leise wie vorher, aber die + Nieten sind es nicht. Derselbe Fehler wie mit der Koernung im + August: Wer zwei Dinge auf eine Ebene legt, gibt ihnen dieselbe + Lautstaerke. */ .willkommen::before { content: ""; position: absolute; inset: var(--k-rand); z-index: 0; pointer-events: none; @@ -198,24 +207,71 @@ calc(100% - var(--k-fase) + var(--k-rand)) 100%, calc(var(--k-fase) - var(--k-rand)) 100%, 0 calc(100% - var(--k-fase) + var(--k-rand)), 0 calc(var(--k-fase) - var(--k-rand))); background: + linear-gradient(180deg, rgba(255, 255, 255, .11) 0 1px, transparent 1px), + repeating-linear-gradient(0deg, rgba(150, 186, 220, .085) 0 1px, transparent 1px 16px), + repeating-linear-gradient(90deg, rgba(150, 186, 220, .085) 0 1px, transparent 1px 16px), radial-gradient(120% 90% at 4% 108%, rgba(255, 95, 109, .16), transparent 52%), radial-gradient(120% 90% at 96% 108%, rgba(143, 216, 255, .17), transparent 52%), linear-gradient(168deg, #131a27 0%, #0a0e17 62%, #06090f 100%); } -/* RASTER UND KANTENLICHT auf einer zweiten Ebene. Das Raster ist - feiner als das der Module (16 statt 26 px) -- eine Konsole ist ein - Messgeraet, kein Modul, und der Unterschied soll auch aus der Naehe - tragen. */ +/* ===================================================================== + STUFE 1: VIER NIETEN -- die Konsole ist MONTIERT (07.09.2026) + + Filipe: "noch viel viel viel spezieller, setz noch eine drauf, und + dan noch eine drauf und dan noch eine drauf." + + Das Einzige, was eine Flaeche endgueltig von einem Bildschirmkasten + zu einem GEGENSTAND macht, ist die Frage, wie sie befestigt ist. + Ein Gehaeuse haengt nicht in der Luft -- es ist verschraubt. Vier + Nieten in den vier Fasen beantworten diese Frage, und sie + beantworten sie an genau den Stellen, an denen ein Konstrukteur + sie auch setzen wuerde: dort, wo das Material am dicksten ist. + + Jede Niete ist EIN Kegelverlauf (das gedrehte Metall des Kopfes) und + ein Radialverlauf darueber (die Woelbung: Licht oben links, Schatten + unten rechts). Acht Ebenen fuer vier Nieten, kein einziges Element + mehr im Baum. + ===================================================================== */ .willkommen::after { content: ""; position: absolute; inset: var(--k-rand); z-index: 0; pointer-events: none; clip-path: inherit; + /* RUND, UND ZWAR AUS SICH SELBST HERAUS. + + Der erste Anlauf nahm einen Kegelverlauf fuer das Metall und + schnitt ihn mit `background-size` auf 9x9 Pixel zurecht. Das + Ergebnis waren vier graue QUADRATE: Eine Hintergrundebene laesst + sich nicht runden -- `border-radius` gilt fuer das Element, nicht + fuer eine ihrer Ebenen, und eine Maske haette alle acht Ebenen + zugleich getroffen. + + Ein Radialverlauf dagegen IST rund: Wo sein letzter Stopp + durchsichtig wird, hoert die Form auf. Deshalb bestehen die + Nieten jetzt aus zwei Radialverlaeufen -- einer fuer den Kopf mit + Rand, einer fuer die Woelbung. `closest-side` sorgt dafuer, dass + 100 % der Radius sind und nicht die weiteste Ecke; genau der + Fehler, der heute die Skala der Uhr unsichtbar gemacht hat. */ + --niete-metall: radial-gradient(circle closest-side, + #e6eff9 0%, #b6c6d9 38%, #64758c 74%, + #39465a 90%, rgba(6, 10, 18, .95) 97%, transparent 100%); + --niete-woelbung: radial-gradient(circle closest-side at 34% 30%, + rgba(255, 255, 255, .8) 0%, rgba(255, 255, 255, 0) 46%, + rgba(0, 0, 0, .45) 88%, transparent 100%); background: - linear-gradient(180deg, rgba(255, 255, 255, .12) 0 1px, transparent 1px), - repeating-linear-gradient(0deg, rgba(150, 186, 220, .30) 0 1px, transparent 1px 16px), - repeating-linear-gradient(90deg, rgba(150, 186, 220, .30) 0 1px, transparent 1px 16px); - opacity: .30; + var(--niete-woelbung), var(--niete-metall), + var(--niete-woelbung), var(--niete-metall), + var(--niete-woelbung), var(--niete-metall), + var(--niete-woelbung), var(--niete-metall); + background-repeat: no-repeat; + background-size: 11px 11px, 11px 11px, 11px 11px, 11px 11px, + 11px 11px, 11px 11px, 11px 11px, 11px 11px; + /* In der Fase, nicht in der Ecke: Die Ecke gibt es nicht mehr. */ + background-position: + left 8px top 8px, left 8px top 8px, + right 8px top 8px, right 8px top 8px, + right 8px bottom 8px, right 8px bottom 8px, + left 8px bottom 8px, left 8px bottom 8px; } .willkommen > * { position: relative; z-index: 1; } @@ -229,6 +285,63 @@ /* Rechts: Glocke neben der Uhr, beide rechtsbündig. `margin-left: auto` statt `justify-content: space-between` am Elternteil -- so bleibt die Gruppe auch dann rechts, wenn der Text davor kurz ist. */ +/* ===================================================================== + STUFE 2: EINE GEFRAESTE NUT trennt Text von Instrumenten. + + Auf einer echten Konsole liegen Anzeige und Beschriftung nicht auf + derselben Flaeche -- dazwischen laeuft eine Nut. Sie ist keine Linie, + sondern eine VERTIEFUNG, und daran erkennt man sie: dunkel auf der + Lichtseite, hell auf der Schattenseite. Genau umgekehrt zu einer + aufgemalten Trennlinie, und genau deshalb sieht sie nach Material + aus statt nach Dekoration. + + STUFE 3: DIE UHR SITZT IN EINER MULDE. + + Sie lag bisher AUF der Konsole. Ein Instrument wird aber in eine + Fraesung eingesetzt: eine runde Vertiefung, etwas groesser als das + Gehaeuse, mit Schatten oben (dort faellt kein Licht mehr hinein) und + einem hellen Bogen unten (dort trifft es die gegenueberliegende + Wand). Beides zusammen macht aus "davor" ein "darin". + ===================================================================== */ +.willkommen__rechts { position: relative; } + +/* Die Nut. */ +.willkommen__rechts::before { + content: ""; position: absolute; + left: -18px; top: -14px; bottom: -14px; width: 2px; + pointer-events: none; z-index: 0; + background: linear-gradient(90deg, + rgba(0, 0, 0, .75) 0 1px, + rgba(255, 255, 255, .13) 1px 2px); + border-radius: 1px; +} + +/* DIE INSTRUMENTE LIEGEN UEBER DER MULDE -- und das muss ausdruecklich + dastehen. `::after` wird NACH allen Kindern gezeichnet; bei gleichem + Stapelwert gewinnt das spaetere Element. Die Mulde lag deshalb OBEN + und hat die Luenette der Uhr von poliertem Stahl zu mattem Grau + gedaempft -- im Bildschirmfoto gesehen, im Vergleich mit der Aufnahme + von vorhin. Ein Stapelwert von 1 stellt die Reihenfolge her, die der + Name schon behauptet. */ +.willkommen__rechts > * { position: relative; z-index: 1; } + +/* Die Mulde. Sie liegt HINTER der Uhr (z-index 0 gegen 1) und ist + bewusst 22 px groesser als das Gehaeuse -- eine Fraesung ist immer + etwas weiter als das, was hineinkommt, sonst bekaeme man es nicht + hinein. */ +.willkommen__rechts::after { + content: ""; position: absolute; + right: -11px; top: 50%; width: 186px; height: 186px; + margin-top: -93px; + border-radius: 50%; + pointer-events: none; z-index: 0; + background: + radial-gradient(circle at 50% 50%, rgba(0, 0, 0, .55) 62%, transparent 74%); + box-shadow: + inset 0 6px 10px -6px rgba(0, 0, 0, .95), + inset 0 -3px 0 -1px rgba(190, 208, 230, .16); +} + .willkommen__rechts { display: flex; align-items: center; gap: 14px; margin-left: auto; flex: 0 0 auto; diff --git a/workspace/assets/css/module.css b/workspace/assets/css/module.css index 7d89ffb2..da446479 100644 --- a/workspace/assets/css/module.css +++ b/workspace/assets/css/module.css @@ -89,7 +89,7 @@ } /* MODULLISTE */ -:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { +:is(.eintrag-karte, .call, .chat, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .dran__punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { position: relative; clip-path: polygon(var(--fase) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fase)); border-radius: 0; @@ -117,7 +117,7 @@ was übrig bleibt, ist eine Linie, die exakt der Form folgt, Schräge inklusive. Ein `border` könnte das nicht: Er folgt dem Rechteck. */ /* MODULLISTE */ -:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { +:is(.eintrag-karte, .call, .chat, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .dran__punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { content: ""; position: absolute; inset: 0; pointer-events: none; @@ -140,7 +140,7 @@ /* RASTER UND ECKWINKEL. Beides auf ::after -- ein drittes Element gibt es nicht, und beides ist reine Optik ohne Klicks. */ /* MODULLISTE */ -:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { +:is(.eintrag-karte, .call, .chat, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .dran__punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { content: ""; position: absolute; inset: 0; pointer-events: none; @@ -224,7 +224,7 @@ /* Dieselbe Form, kleiner -- keine zweite Gestaltung. */ :root { --fase: 12px; } /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { + :is(.eintrag-karte, .call, .chat, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .dran__punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { filter: drop-shadow(0 3px 8px rgba(0, 0, 0, .7)); } } @@ -238,15 +238,15 @@ /* Im Kontrastmodus zählt die Kante, und die muss ein echter `border` sein. Die Schräge bleibt: Sie ist Geometrie, keine Farbe. */ /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { + :is(.eintrag-karte, .call, .chat, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .dran__punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { filter: none; border: 1px solid CanvasText; } /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { + :is(.eintrag-karte, .call, .chat, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .dran__punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { display: none; } /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { + :is(.eintrag-karte, .call, .chat, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .dran__punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { display: none; } } @@ -354,3 +354,91 @@ .kachel__zeichen { background: Canvas; border: 1px solid CanvasText; box-shadow: none; } .kachel__zeichen::before { display: none; } } + + +/* ===================================================================== + DIE TAGESKACHEL "WAS IST DRAN" (07.09.2026) + + Filipe: "soll auch besser und auffaelliger aussehen bitte." + + Sie bestand aus drei abgerundeten Zeilen mit einem Farbstreifen + links -- also aus der Form, die es hier bis heute Frueh ueberall + gab. Sie bekommt jetzt dieselbe Behandlung wie alles andere, und + zwar konsequent: + + * Die drei Zeilen sind MODULE. `.dran__punkt` steht seit heute in + der Modulliste oben: abgeschnittene Ecke, Kantenlicht in der + Farbe des Bereichs, Eckwinkel, Fase. Damit sind sie kleine + Ausgaben derselben Bauteile, zu denen sie fuehren -- was sie ja + auch sind. + * Die ZAHL wird zum gefassten Schild, wie das Zeichen auf den + Kacheln. Sie ist die eigentliche Aussage der Zeile ("EINS + wartet"), und sie stand bisher als blosse Ziffer daneben. + * Zwischen den beiden Haelften laeuft eine gefraeste Nut statt + einer Linie -- dieselbe Sprache wie auf der Konsole. + ===================================================================== */ + +/* Der Farbstreifen links entfaellt: Die Zeile hat jetzt ein + Kantenlicht, und beides zusammen waeren zwei Kanten fuer dieselbe + Aussage. */ +.dran__punkt::before { width: 0; } + +.dran__zahl { + --z-fase: 7px; + display: grid; place-items: center; + min-width: 30px; min-height: 26px; + padding: 2px; + font-size: 1.02rem; + /* DIE FARBE BLEIBT IN DER ZIFFER, nicht im Schild. + + Im ersten Anlauf stand hier Weiss, weil das auf Metall gut + aussieht. Damit war die Aussage weg: Die Zahl traegt die Farbe des + Bereichs, zu dem die Zeile fuehrt -- und bei etwas Ueberfaelligem + die Warnfarbe. Das ist kein Schmuck, sondern die schnellste + Auskunft der ganzen Kachel. pruef-start-ansicht hat es sofort + gemeldet ("ueberfaellige Zeilen sind rot": weiss statt rot), und + die Pruefung hatte recht. + + Das Schild darunter bleibt deshalb fast neutral -- nur eine Spur + Farbton, damit die Ziffer nicht auf Grau steht. */ + color: var(--ton, var(--akzent)); + text-align: center; + clip-path: polygon(var(--z-fase) 0, 100% 0, 100% 100%, 0 100%, 0 var(--z-fase)); + background: + conic-gradient(from 210deg, + #b9c8da 0deg, #5a6b80 44deg, #d6e2ef 88deg, #44536a 140deg, + #aebdd0 196deg, #64758c 244deg, #cddaea 296deg, #4e5d73 340deg, + #b9c8da 360deg); + box-shadow: 0 4px 12px -7px rgba(0, 0, 0, .9), 0 0 0 1px rgba(6, 10, 18, .5); +} +/* Das Schild IM Ring traegt die Farbe des Bereichs -- wie bei den + Kacheln liegt die Farbe innen, das Metall bleibt ueberall gleich. */ +.dran__zahl::before { + content: ""; position: absolute; inset: 2px; z-index: -1; + clip-path: polygon( + calc(var(--z-fase) - 2px) 0, 100% 0, 100% 100%, 0 100%, + 0 calc(var(--z-fase) - 2px)); + background: + linear-gradient(150deg, rgba(255, 255, 255, .10) 0%, transparent 48%), + linear-gradient(color-mix(in srgb, var(--ton, var(--akzent)) 14%, #080d15), + color-mix(in srgb, var(--ton, var(--akzent)) 6%, #080d15)); +} +.dran__zahl { position: relative; isolation: isolate; } + +/* Die Nut zwischen "Was ist dran" und "Heute". Dunkel auf der + Lichtseite, hell auf der Schattenseite -- so liest sich eine + Vertiefung. Eine aufgemalte Linie kann das nicht. */ +.tagesblick__seite--heute::before { + content: ""; position: absolute; + left: -21px; top: -6px; bottom: -6px; width: 2px; + pointer-events: none; + background: linear-gradient(90deg, + rgba(0, 0, 0, .75) 0 1px, + rgba(255, 255, 255, .12) 1px 2px); +} + +@media (forced-colors: active) { + .dran__zahl { background: Canvas; box-shadow: none; border: 1px solid CanvasText; } + .dran__zahl::before { display: none; } + .tagesblick__seite--heute::before { background: CanvasText; } +} diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 4075a7a7..1ed6a8b2 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -9,10 +9,10 @@ - - - - + + + + @@ -212,10 +212,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index 8d1febc8..6e6d35b7 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -135,10 +135,10 @@ - - - - - + + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 4c9ec936..58f33a89 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -144,14 +144,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 59e5be56..52c9fdfc 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -77,11 +77,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index a6c3a095..f336b0fe 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -9,17 +9,17 @@ - - + + - - - + + + @@ -155,9 +155,10 @@ - - - - + + + + + diff --git a/workspace/content.html b/workspace/content.html index 830fa757..f2c77440 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -167,12 +167,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/dateien.html b/workspace/dateien.html index 727260f6..0c2d602f 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -96,10 +96,10 @@ - - - - - + + + + + diff --git a/workspace/index.html b/workspace/index.html index 9a427ff6..a58be3ef 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -27,7 +27,7 @@ - + @@ -202,6 +202,6 @@ - + diff --git a/workspace/kalender.html b/workspace/kalender.html index 1016ab73..4f9d0e35 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -258,11 +258,11 @@ - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index fa506846..c04f933b 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -212,10 +212,10 @@ - - - - - + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index 0bd7da92..59696fec 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -137,10 +137,10 @@ - - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index 9258e326..bf2ec229 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -202,11 +202,11 @@ - - - - - - + + + + + + diff --git a/workspace/report.html b/workspace/report.html index 45e9c5cd..5ecf83ec 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -94,11 +94,11 @@ - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 01717b44..ee769d99 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -127,10 +127,10 @@ - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index 7a627b19..a7a8e069 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -9,12 +9,12 @@ - - + + - - + + @@ -264,10 +264,10 @@

- - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index 7decd43e..e261968e 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -73,11 +73,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index 0c141057..0c7adc18 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -114,10 +114,10 @@ - - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index 441b06cb..9a812eda 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -9,13 +9,13 @@ - - + + - - - + + + @@ -137,10 +137,11 @@ - + - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 672b88d4..df26e41d 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -178,10 +178,10 @@ - - - - - + + + + +