Aufgaben abbrechen, Teilnehmerwahl fuer alle, Benachrichtigungen
Zwei Wuensche vom 05.09.2026, dazu drei Fehler, die dabei ans Licht kamen.
ABBRECHEN (Wunsch: "in jedem status die aufgaben auch abbrechen koennen,
nur ich die manager und scouts")
Neuer Status mit Pflicht-Grund, aus jedem der vier Status heraus.
Festgehalten wird auch, WO die Aufgabe stand -- "im Review abgebrochen"
ist eine andere Aussage als "nie angefangen", und das Wiederaufnehmen
geht dorthin zurueck statt nach "offen".
Eigener Weg statt "abgebrochen" in der Statusliste: Dort entscheidet
darfAendern(), und das laesst auch den zustaendigen Creator aendern.
Der gewoehnliche PATCH kann diesen Zustand deshalb gar nicht erreichen
-- auch nicht fuer DogFather, sonst waere die Grund-Pflicht umgehbar.
Abgebrochenes steht in einem zugeklappten Bereich unter dem Brett, nicht
als fuenfte Spalte: Am Handy waeren dann alle fuenf unlesbar schmal.
Verschwinden darf es nicht, sonst waere der Abbruch ein Loeschen mit
Zwischenschritt.
Die Tabelle musste dafuer getauscht werden (SQLite kann CHECK nicht
aendern). Vorher auf einer Kopie durchgespielt: 40 von 40 Aufgaben,
Inhalte, Verweise und Indizes geprueft, Gegenprobe zeigt, dass der CHECK
noch lebt.
TEILNEHMERWAHL (Wunsch: "das soll viel besser aussehen und fuer jeden
verfuegbar sein")
Auf dem Bildschirm klebten die Namen aneinander: "DogfatherDogFather".
Ursache war, dass kalender.html das Stylesheet mit diesen Klassen nie
eingebunden hat -- sie standen in dateien.css. Vierzig gruene Pruefungen
zur Teilnehmerwahl hatten das nicht gemerkt, weil keine je gefragt hat,
ob es AUSSIEHT wie gedacht.
Jetzt eigene Klassen im eigenen Stylesheet, nach Rollen gruppiert: Die
Rolle steht einmal als Ueberschrift statt neunmal am Namen. Damit ist
das Kleben an der Wurzel weg, nicht zugepflastert.
"Fuer jeden" war mehr als ein hidden zu entfernen: darfEintragen() haette
einem Creator nur sich selbst erlaubt. Er haette seinen Scout gesehen,
angeklickt, und der Server haette ihn still weggelassen -- ein Knopf, der
nichts tut. einladbareIds() schaut jetzt in beide Richtungen, bewusst
getrennt von /api/personen: Wer die erweitert, gibt einem Creator
nebenbei die Moeglichkeit, seinem Scout Aufgaben zuzuweisen.
BENACHRICHTIGUNGEN (Wunsch: "sowas, und dass es perfekt funktioniert
fuer jeden")
Web Push nach RFC 8291/8292, ohne fremde Abhaengigkeit. Der Knopf sagt
in jeder Lage die Wahrheit, auch die unbequemen: abgelehnt (mit dem
Hinweis, wo man es zuruecknimmt), iPhone im Reiter (mit Anleitung),
Browser ohne Push. Ein Knopf, der bei abgelehnter Berechtigung nur
nichts tut, ist der sichere Weg zu "das funktioniert nicht".
DREI FEHLER, DIE DABEI AUFFIELEN
1. Ein defekter Zugangsdatensatz sperrte ALLE einer Rolle aus. Wirft
hashe() bei einer Person, flog die ganze Anmeldung in den catch: 503
"nicht verfuegbar" fuer jeden mit dieser Rolle. Aufgefallen durch
einen eigenen Testfehler. Jetzt wird die defekte Person uebersprungen
und laut protokolliert; die Gegenprobe zeigt, dass ein falscher Code
weiterhin abgelehnt wird.
2. Die Glocke sprengte die Kopfleiste -- zweimal. Bei 320 px lag die
Lupe des Suchknopfes auf dem Sicht-Umschalter (ein Knopf, der auf 12
Seiten ins Leere tippt), bei 768 px wurde der Abmelden-Knopf bis zu
15 px aus dem Bild geschoben, weil die Textgrenze auf 760 stand und
ein Tablet 768 hat. Nachgewiesen durch Messen mit und ohne Glocke,
nicht durch Vermuten.
3. .block__frage war viermal gestaltet und stand auf einer Seite, die
keine dieser Dateien laedt -- derselbe Fehler wie bei der
Teilnehmerwahl. Gefunden von der neuen Klassenpruefung beim ersten
Lauf.
NEUE PRUEFUNGEN
pruef-css-klassen jede gestaltete Klasse muss auf ihrer Seite ankommen
(unterscheidet Struktur-Anker von echtem Verlust)
pruef-dabei-optik die Wahl im Browser, an den echten Pixeln
pruef-abbrechen Umstellung auf einer Kopie, Rechte, Rueckweg
pruef-abbrechen-optik Knopf, Dialog, Bereich, Handy
pruef-glocke Zustaende, An/Abmelden, jede Rolle
pruef-push(-weg) Rechnung gegen die RFC-Vektoren, Zustellung
pruef-struktur prueft jetzt zusaetzlich, ob sich jedes Server-Modul als
ESM laden laesst. node --check auf einer .js-Datei prueft als CommonJS
und meldete "ok", waehrend der Import scheiterte.
Gesamtlauf: 55 von 55 Dateien, 1973 von 1973 Punkten.
Was NICHT geprueft werden konnte und deshalb dasteht: Der Schritt
"Browser holt eine Adresse beim Push-Dienst" braucht eine Verbindung zu
Googles FCM, die ein Pruef-Browser nicht hat. Die Pruefung misst das
zuerst und meldet es als dritten Ausgang, statt gruen zu sein.
Verschluesselung und Zustellung sind getrennt geprueft; diese eine
Strecke beweist sich erst auf dem Server.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -511,3 +511,148 @@
|
||||
.call-raum { align-items: flex-start; }
|
||||
.call-raum button { margin-left: 0; }
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
ABBRECHEN — Knopf, Bereich und Dialog
|
||||
=====================================================================
|
||||
|
||||
Wunsch Filipe, 05.09.2026: *"ich will dass man in jedem status die
|
||||
aufgaben auch abbrechen kann."*
|
||||
|
||||
GESTALTUNGSREGEL HIER: zurückhaltend. Abbrechen ist die seltene
|
||||
Handlung neben "starten" und "erledigt" -- sie darf auf der Karte
|
||||
nicht lauter sein als die beiden, die man täglich braucht. Kein
|
||||
Signalrot, kein Ausrufezeichen: ein gedeckter Ton, der sich vom
|
||||
Weiterschalten unterscheidet, ohne die Karte an sich zu reißen.
|
||||
(Augenschonend ist hier ohnehin Hausregel.) */
|
||||
|
||||
/* Ein warmer, gedämpfter Ton statt Alarmrot. --f ist die Farbvariable,
|
||||
die .schritt in gate.css für Rand, Schrift und Schimmer benutzt. */
|
||||
.schritt--ab { --f: #c98a7d; }
|
||||
.schritt--ab:hover { color: color-mix(in srgb, #c98a7d 40%, #ffffff); }
|
||||
|
||||
/* ---------- Der Bereich unter dem Brett ---------------------------------- */
|
||||
|
||||
.abgebrochen {
|
||||
margin: 22px 0 0;
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 255, 255, .022);
|
||||
}
|
||||
|
||||
.abgebrochen__kopf {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
padding: 13px 17px;
|
||||
cursor: pointer;
|
||||
font-size: .82rem; font-weight: 700;
|
||||
letter-spacing: .06em; text-transform: uppercase;
|
||||
color: var(--text-still);
|
||||
/* Das eigene Dreieck von <summary> weg -- es wird unten selbst
|
||||
gezeichnet, damit es links steht und sich mitdreht. */
|
||||
list-style: none;
|
||||
}
|
||||
.abgebrochen__kopf::-webkit-details-marker { display: none; }
|
||||
.abgebrochen__kopf:hover { color: var(--text-leise); }
|
||||
.abgebrochen__kopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; border-radius: 14px; }
|
||||
|
||||
/* Das Dreieck. Dreht sich beim Aufklappen -- die Bewegung sagt, dass
|
||||
der Inhalt darunter erscheint und nicht woanders. */
|
||||
.abgebrochen__kopf::before {
|
||||
content: ""; flex: none;
|
||||
width: 0; height: 0;
|
||||
border-left: 5px solid currentColor;
|
||||
border-top: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
transition: transform .18s ease;
|
||||
}
|
||||
.abgebrochen[open] .abgebrochen__kopf::before { transform: rotate(90deg); }
|
||||
|
||||
.abgebrochen__name { flex: 1; }
|
||||
.abgebrochen__zahl {
|
||||
padding: 2px 9px; border-radius: 999px;
|
||||
font-size: .78rem; font-weight: 700; letter-spacing: 0;
|
||||
color: var(--text-leise);
|
||||
background: rgba(255, 255, 255, .06);
|
||||
border: 1px solid var(--rand);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.abgebrochen__unter {
|
||||
margin: 0; padding: 0 17px 4px;
|
||||
font-size: .8rem; color: var(--text-still); max-width: 72ch;
|
||||
}
|
||||
|
||||
.abgebrochen__liste {
|
||||
display: grid; gap: 10px;
|
||||
/* Mehrspaltig, sobald Platz ist: Abgebrochenes liest man am Stück,
|
||||
nicht einzeln -- eine lange Spalte zwänge zum Scrollen durch etwas,
|
||||
das man ohnehin nur überfliegt. */
|
||||
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
||||
padding: 10px 17px 17px;
|
||||
}
|
||||
|
||||
.abbruch-karte {
|
||||
padding: 13px 15px;
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, .028);
|
||||
}
|
||||
.abbruch-karte__kopf {
|
||||
display: flex; align-items: baseline; gap: 9px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
/* Durchgestrichen sagt "gilt nicht mehr" schneller als jedes Wort --
|
||||
und bleibt lesbar, anders als bloßes Ausgrauen. */
|
||||
.abbruch-karte__titel {
|
||||
margin: 0; flex: 1;
|
||||
font-size: .92rem; font-weight: 600;
|
||||
color: var(--text-leise);
|
||||
text-decoration: line-through;
|
||||
text-decoration-color: color-mix(in srgb, var(--text-still) 70%, transparent);
|
||||
}
|
||||
/* Wo es stand, als es abgebrochen wurde. */
|
||||
.abbruch-karte__vorher {
|
||||
flex: none;
|
||||
padding: 2px 8px; border-radius: 999px;
|
||||
font-size: .68rem; font-weight: 700;
|
||||
letter-spacing: .04em; text-transform: uppercase;
|
||||
color: var(--text-still);
|
||||
background: rgba(255, 255, 255, .05);
|
||||
border: 1px solid var(--rand);
|
||||
}
|
||||
.abbruch-karte__grund {
|
||||
margin: 0 0 7px;
|
||||
font-size: .84rem; color: var(--text-leise);
|
||||
/* Der Grund ist der eigentliche Inhalt dieser Karte -- er steht in
|
||||
normaler Textfarbe, während der Titel durchgestrichen zurücktritt. */
|
||||
}
|
||||
.abbruch-karte__wer {
|
||||
margin: 0 0 9px;
|
||||
font-size: .74rem; color: var(--text-still);
|
||||
}
|
||||
.abbruch-karte .schritt { font-size: .8rem; padding: 7px 13px; }
|
||||
|
||||
/* ---------- Der Dialog --------------------------------------------------- */
|
||||
|
||||
.dialog__unter {
|
||||
margin: -4px 0 14px;
|
||||
font-size: .85rem; color: var(--text-still);
|
||||
max-width: 60ch; line-height: 1.5;
|
||||
}
|
||||
|
||||
#abbruch-grund {
|
||||
width: 100%;
|
||||
resize: vertical;
|
||||
min-height: 72px;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.abgebrochen__kopf::before { transition: none; }
|
||||
}
|
||||
|
||||
/* Ohne Farbverläufe trägt die Kante allein. Der Durchstrich bleibt --
|
||||
er ist hier das eigentliche Merkmal und keine Deko. */
|
||||
@media (forced-colors: active) {
|
||||
.abgebrochen, .abbruch-karte { border: 1px solid CanvasText; }
|
||||
.abgebrochen__zahl, .abbruch-karte__vorher { border: 1px solid CanvasText; }
|
||||
}
|
||||
|
||||
@@ -672,3 +672,133 @@
|
||||
bleibt das Unterscheidungsmerkmal einer pausierten Serie. */
|
||||
.k-serie[data-aktiv="nein"] { opacity: 1; border-style: dashed; }
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
WER IST NOCH DABEI — die Teilnehmerwahl
|
||||
=====================================================================
|
||||
|
||||
Vorgeschichte (05.09.2026, Filipe mit Bildschirmfoto): *"das soll
|
||||
viel besser aussehen bitte und dass soll für jeden verfügbar sein."*
|
||||
|
||||
Auf dem Bild klebten die Namen aneinander -- "DogfatherDogFather",
|
||||
"CigdemManager", "BananaStiftScout". Zwei Fehler auf einmal:
|
||||
|
||||
1. DAS CSS WAR GAR NICHT DA. Die Wahl benutzte `.wahl__knopf` aus
|
||||
dateien.css -- und kalender.html bindet dateien.css nicht ein.
|
||||
Ohne `display:inline-flex` und `gap` stehen zwei <span> eben
|
||||
direkt nebeneinander. Vierzig grüne Prüfungen zur Teilnehmerwahl
|
||||
hatten das nicht gemerkt: Keine davon hat je gemessen, ob es auch
|
||||
AUSSIEHT wie gedacht. Deshalb gibt es jetzt eigene Klassen im
|
||||
eigenen Stylesheet -- eine Seite, die ihr CSS selbst mitbringt,
|
||||
kann es nicht verlieren.
|
||||
|
||||
2. DIE ROLLE STAND AN JEDEM NAMEN. Auch mit Abstand bliebe es eine
|
||||
lange graue Wurst, in der man niemanden findet. Jetzt tragen die
|
||||
GRUPPEN die Rolle ("Manager", "Scouts"), die Namen darunter nur
|
||||
noch den Namen. Das Wort steht einmal statt neunmal, und man
|
||||
sucht nicht mehr, sondern springt zur richtigen Gruppe.
|
||||
|
||||
AUGENSCHONEND (Projektregel): gedeckte Rollentöne, kein Neon, keine
|
||||
harten Weißflächen. Ausgewählt wird über Rand, Häkchen UND Schrift
|
||||
erkennbar -- nicht über Farbe allein, sonst ist es für
|
||||
Farbfehlsichtige nicht zu unterscheiden. */
|
||||
|
||||
.k-dabei { margin-top: 6px; }
|
||||
|
||||
.k-dabei__gruppe + .k-dabei__gruppe { margin-top: 12px; }
|
||||
|
||||
.k-dabei__titel {
|
||||
margin: 0 0 6px;
|
||||
font-size: .68rem; font-weight: 700;
|
||||
letter-spacing: .08em; text-transform: uppercase;
|
||||
color: var(--text-still);
|
||||
display: flex; align-items: center; gap: 7px;
|
||||
}
|
||||
/* Der Punkt trägt die Rollenfarbe -- ein ruhiger Anker fürs Auge,
|
||||
ohne die ganze Überschrift einzufärben. */
|
||||
.k-dabei__punkt {
|
||||
width: 7px; height: 7px; border-radius: 50%;
|
||||
background: var(--r, var(--text-still)); flex: none;
|
||||
}
|
||||
|
||||
.k-dabei__liste { display: flex; flex-wrap: wrap; gap: 7px; }
|
||||
|
||||
.k-dabei__knopf {
|
||||
--r: rgba(255, 255, 255, .5);
|
||||
display: inline-flex; align-items: center; gap: 9px;
|
||||
/* 40px Mindesthöhe: am Handy mit dem Daumen sicher zu treffen. */
|
||||
min-height: 40px;
|
||||
padding: 5px 14px 5px 6px;
|
||||
cursor: pointer; font: inherit;
|
||||
color: var(--text-leise);
|
||||
background: rgba(255, 255, 255, .035);
|
||||
border: 1px solid var(--rand); border-radius: 999px;
|
||||
transition: color .16s ease, border-color .16s ease, background .16s ease;
|
||||
}
|
||||
.k-dabei__knopf:hover {
|
||||
color: var(--text);
|
||||
border-color: rgba(255, 255, 255, .24);
|
||||
background: rgba(255, 255, 255, .06);
|
||||
}
|
||||
.k-dabei__knopf:focus-visible {
|
||||
outline: 2px solid var(--r); outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Die Initiale. Ersetzt ein Bild, das es hier nicht gibt, und macht
|
||||
aus einer Textzeile ein Gesicht, das man wiedererkennt. */
|
||||
.k-dabei__zeichen {
|
||||
flex: none;
|
||||
width: 28px; height: 28px; border-radius: 50%;
|
||||
display: grid; place-items: center;
|
||||
font-size: .76rem; font-weight: 700; line-height: 1;
|
||||
color: var(--r);
|
||||
background: color-mix(in srgb, var(--r) 14%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--r) 34%, transparent);
|
||||
}
|
||||
.k-dabei__name { font-size: .86rem; font-weight: 550; }
|
||||
|
||||
/* Das Häkchen steht NEBEN der Farbe, nicht statt ihr. Wer Farben
|
||||
schlecht unterscheidet, sieht trotzdem sofort, wer dabei ist. */
|
||||
.k-dabei__haken {
|
||||
flex: none; width: 14px; height: 14px;
|
||||
opacity: 0; transform: scale(.7);
|
||||
transition: opacity .16s ease, transform .16s ease;
|
||||
}
|
||||
.k-dabei__haken path { stroke: var(--r); stroke-width: 2.4; fill: none;
|
||||
stroke-linecap: round; stroke-linejoin: round; }
|
||||
|
||||
.k-dabei__knopf[data-an="ja"] {
|
||||
color: var(--text); font-weight: 600;
|
||||
border-color: color-mix(in srgb, var(--r) 55%, transparent);
|
||||
background: color-mix(in srgb, var(--r) 13%, transparent);
|
||||
}
|
||||
.k-dabei__knopf[data-an="ja"] .k-dabei__zeichen {
|
||||
color: #12151b;
|
||||
background: var(--r);
|
||||
border-color: var(--r);
|
||||
}
|
||||
.k-dabei__knopf[data-an="ja"] .k-dabei__haken { opacity: 1; transform: none; }
|
||||
|
||||
/* Rollentöne. Dieselben wie in personen.css -- eine Farbe pro Rolle im
|
||||
ganzen Workspace, sonst muss man sie auf jeder Seite neu lernen. */
|
||||
.k-dabei__gruppe[data-rolle="admin"],
|
||||
.k-dabei__knopf[data-rolle="admin"] { --r: #e8c07d; }
|
||||
.k-dabei__gruppe[data-rolle="manager"],
|
||||
.k-dabei__knopf[data-rolle="manager"] { --r: #8a76ff; }
|
||||
.k-dabei__gruppe[data-rolle="scout"],
|
||||
.k-dabei__knopf[data-rolle="scout"] { --r: #5fc99a; }
|
||||
.k-dabei__gruppe[data-rolle="creator"],
|
||||
.k-dabei__knopf[data-rolle="creator"] { --r: #3fbdf5; }
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.k-dabei__knopf, .k-dabei__haken { transition: none; }
|
||||
}
|
||||
|
||||
/* Ohne Farbverläufe trägt die Kante allein -- und das Häkchen, das
|
||||
hier zum eigentlichen Merkmal wird. */
|
||||
@media (forced-colors: active) {
|
||||
.k-dabei__knopf { border: 1px solid CanvasText; }
|
||||
.k-dabei__knopf[data-an="ja"] { border-width: 2px; }
|
||||
.k-dabei__zeichen { border: 1px solid CanvasText; }
|
||||
.k-dabei__haken path { stroke: CanvasText; }
|
||||
}
|
||||
|
||||
@@ -2785,6 +2785,7 @@ body.start #protokoll {
|
||||
flex: 0 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sicht__schild {
|
||||
flex: none;
|
||||
/* 0,75 rem = 12 px. Nicht kleiner: Unter 11,5 px meldet die
|
||||
@@ -2879,6 +2880,47 @@ body[data-fremde-sicht="ja"]::after {
|
||||
.sicht { padding: 3px 4px; }
|
||||
.wer__name { display: none; }
|
||||
}
|
||||
|
||||
/* SEHR SCHMAL: die Kopfleiste darf umbrechen (05.09.2026).
|
||||
|
||||
Die Rechnung darueber ging genau auf, solange rechts vier Dinge
|
||||
standen. Mit der Glocke sind es fuenf, und bei 320 px (iPhone SE)
|
||||
passte es nicht mehr: Die Lupe des Suchknopfes lag danach mitten auf
|
||||
dem Sicht-Umschalter -- ein Knopf, der auf zwoelf Seiten ins Leere
|
||||
tippt. Gemeldet von pruef-handy, bevor es jemand gesehen hat.
|
||||
|
||||
WARUM UMBRECHEN und nicht weiter schrumpfen: Jedes Stueck hier hat
|
||||
seine Mindestgroesse aus einem guten Grund -- 104 px, damit der
|
||||
Umschalter mit dem Daumen zu treffen ist, und die Glocke ist bereits
|
||||
auf das blosse Zeichen zusammengefallen. Wer hier weiter kuerzt,
|
||||
tauscht ein sichtbares Problem gegen ein unsichtbares: Knoepfe, die
|
||||
zwar nebeneinander liegen, aber zu klein zum Treffen sind.
|
||||
|
||||
Eine zweite Zeile auf einem 320-Pixel-Schirm kostet 44 Pixel Hoehe.
|
||||
Das ist der guenstigste Preis, der hier zu haben ist -- und er faellt
|
||||
nur auf Geraeten an, die wirklich so schmal sind. */
|
||||
@media (max-width: 380px) {
|
||||
.kopfleiste { flex-wrap: wrap; row-gap: 8px; }
|
||||
/* Die Marke nimmt die erste Zeile ganz ein, die Bedienelemente
|
||||
ruecken geschlossen in die zweite. Ohne das brechen sie mitten
|
||||
zwischen Suche und Glocke um. */
|
||||
.kopfleiste > .marke { flex: 1 0 100%; }
|
||||
.kopfleiste__rechts {
|
||||
width: 100%; justify-content: flex-end;
|
||||
/* AUCH DIE ZWEITE ZEILE DARF UMBRECHEN. Ohne das reichten die
|
||||
294 Pixel weiterhin nicht: Umschalter (104) + Suche (47) +
|
||||
Glocke (37) + Plakette + Abmelden sind zusammen mehr. Die
|
||||
Elemente wurden dann zwar nicht mehr ueberdeckt, aber der
|
||||
Umschalter ragte aus seinem eigenen Kasten heraus -- ein
|
||||
stilles Ueberlaufen, das keine Pruefung meldet und trotzdem
|
||||
falsch aussieht. */
|
||||
flex-wrap: wrap; row-gap: 6px;
|
||||
}
|
||||
/* Und der Umschalter behaelt seine Breite, statt gequetscht zu
|
||||
werden: Sein Inhalt kann ohnehin nicht unter 104 px, also waere
|
||||
jedes Schrumpfen nur ein Ueberlauf mit anderem Namen. */
|
||||
.sicht { flex: 0 0 auto; }
|
||||
}
|
||||
@media (forced-colors: active) {
|
||||
body[data-fremde-sicht="ja"]::after { border-color: Highlight; }
|
||||
}
|
||||
@@ -3012,3 +3054,100 @@ body[data-fremde-sicht="ja"]::after {
|
||||
@media (forced-colors: active) {
|
||||
.kachel::after { display: none; }
|
||||
}
|
||||
|
||||
/* ---------- Der Benachrichtigungs-Knopf ------------------------------
|
||||
Wunsch Filipe (05.09.2026): ein Knopf wie "Benachrichtigungen aus",
|
||||
auf jeder Seite erreichbar.
|
||||
|
||||
Gebaut wie `.abmelden` daneben, damit die Kopfleiste eine Sprache
|
||||
spricht -- und mit denselben Umbruchregeln: Auf schmalen Schirmen
|
||||
bleibt nur die Glocke stehen, der Text weicht. Genau daran ist die
|
||||
Kopfleiste am 31.08.2026 schon einmal gescheitert (214 px aus dem
|
||||
Bild); deshalb hier von vornherein `min-width: 0` und ein Text, der
|
||||
verschwinden darf. */
|
||||
.glocke {
|
||||
display: inline-flex; align-items: center; gap: 7px;
|
||||
min-width: 0; flex: none;
|
||||
padding: 7px 13px;
|
||||
background: rgba(255, 255, 255, .04);
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: 999px;
|
||||
color: var(--text-leise);
|
||||
font: inherit; font-size: .82rem;
|
||||
cursor: pointer;
|
||||
transition: border-color var(--tempo), background var(--tempo), color var(--tempo);
|
||||
}
|
||||
.glocke:hover:not(:disabled) { background: rgba(255, 255, 255, .07); border-color: var(--rand-hell); }
|
||||
.glocke:disabled { opacity: .55; cursor: not-allowed; }
|
||||
|
||||
.glocke__zeichen { width: 17px; height: 17px; flex: none; }
|
||||
.glocke__zeichen path {
|
||||
fill: none; stroke: currentColor; stroke-width: 1.7;
|
||||
stroke-linecap: round; stroke-linejoin: round;
|
||||
}
|
||||
.glocke__strich { opacity: 0; }
|
||||
|
||||
/* AN: die Glocke bekommt Farbe, der Strich bleibt weg. */
|
||||
.glocke[data-lage="an"] {
|
||||
color: var(--akzent);
|
||||
border-color: color-mix(in srgb, var(--akzent) 42%, transparent);
|
||||
background: color-mix(in srgb, var(--akzent) 10%, transparent);
|
||||
}
|
||||
|
||||
/* AUS: durchgestrichene Glocke -- man sieht auf einen Blick, dass
|
||||
nichts kommt, ohne den Text zu lesen. */
|
||||
.glocke[data-lage="aus"] .glocke__strich { opacity: .85; }
|
||||
|
||||
/* Die drei Faelle, in denen der Knopf nichts schalten kann, sind
|
||||
gedaempft und tragen ebenfalls den Strich: Sie sind naeher an "aus"
|
||||
als an "an", und genau so soll es aussehen. */
|
||||
.glocke[data-lage="iphone"], .glocke[data-lage="verboten"],
|
||||
.glocke[data-lage="geht-nicht"] {
|
||||
color: var(--text-still);
|
||||
}
|
||||
.glocke[data-lage="iphone"] .glocke__strich,
|
||||
.glocke[data-lage="verboten"] .glocke__strich,
|
||||
.glocke[data-lage="geht-nicht"] .glocke__strich { opacity: .7; }
|
||||
|
||||
/* Schmale Schirme: nur die Glocke. Der Text steht weiterhin im
|
||||
aria-label, Vorleseprogramme verlieren also nichts.
|
||||
|
||||
900 PIXEL, NICHT 760 (korrigiert 05.09.2026). Die erste Fassung
|
||||
nahm 760 -- und ein Tablet hochkant hat 768. Dort stand der Text
|
||||
also noch, die Glocke war rund 200 statt 37 Pixel breit, und der
|
||||
Abmelden-Knopf wurde um bis zu 15 Pixel aus dem Bild geschoben. Auf
|
||||
vier Seiten, gemeldet von pruef-breiten.
|
||||
|
||||
Die Grenze liegt jetzt auf derselben Stufe wie die uebrigen Regeln
|
||||
fuer die enge Kopfleiste (der Sicht-Umschalter wird ab 900 px
|
||||
ebenfalls schmaler). Eine eigene Schwelle daneben waere genau die
|
||||
Art Zahl, die beim naechsten Mal wieder knapp danebenliegt. */
|
||||
@media (max-width: 900px) {
|
||||
.glocke { padding: 7px 9px; }
|
||||
.glocke__text { display: none; }
|
||||
}
|
||||
|
||||
/* ERKLÄRSATZ UNTER EINER ÜBERSCHRIFT — der Grundwert.
|
||||
|
||||
Gefunden am 05.09.2026 von pruef-css-klassen.mjs, beim allerersten
|
||||
Lauf. `.block__frage` war viermal fast gleich definiert -- in
|
||||
automation.css, calls.css, report.css und wissen.css -- und wurde
|
||||
auf content.html benutzt, das keine dieser vier Dateien lädt. Der
|
||||
Absatz stand dort seit jeher unformatiert.
|
||||
|
||||
Genau dasselbe Muster wie bei der Teilnehmerwahl am selben Tag:
|
||||
Das CSS existiert, es sieht im Editor richtig aus, und auf der Seite
|
||||
kommt nichts an. Solange es nur in Seiten-Stylesheets steht, findet
|
||||
es niemand.
|
||||
|
||||
Hier steht deshalb der Grundwert, den jede Seite bekommt. Die vier
|
||||
Seiten-Stylesheets werden NACH start.css geladen und behalten damit
|
||||
ihre Feinheiten (12, 13 oder 14 Pixel Abstand) -- sie bleiben
|
||||
unverändert. Neu ist nur, dass eine Seite ohne eigene Fassung nicht
|
||||
mehr leer ausgeht. */
|
||||
.block__frage {
|
||||
margin: 0 0 13px;
|
||||
font-size: .85rem;
|
||||
color: var(--text-still);
|
||||
max-width: 76ch;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user