Programmheft: visuelle Neugestaltung der gesamten Plattform - #319
Merged
Merged
Conversation
Archivo mit Breitenachse als Variable für die öffentliche Website (das Dashboard bleibt bei Inter). Neue Farb-Tokens (Tinte, Papier, Messing-Tinte, Haarlinie, Nachtdruck), schmale Schnitte, Satzbreite, Füllzeile, Fokus- und Markierungsfarben sowie reduzierte Bewegung.
Gleiche Links, Texte und Logik; neue Darstellung ohne Rundungen und Schatten, 44px-Bedienflächen, Menüs mit Tintenrahmen, Tastaturfokus für die Aufklappmenüs. Banner mit lesbarem Kontrast (Tinte auf Orange).
Titelblatt mit Bildstrecke (anhaltbar, ohne Autoplay bei reduzierter Bewegung), „Kommende Termine“ als Programmliste mit offenen Anmeldungen vorn (oranges Datumsfeld, Frist, Anmelden), Aktuelles als Druckspalten mit Logo ohne Titelbild, Register „Beliebte Seiten & Partner“ und Schlussseite auf Papier. Inhalte und Texte bleiben unverändert.
PRODUCT.md hält Zielgruppen, Ziele, Markenvorgaben und belegte Inhalte fest; DESIGN.md beschreibt das Programmheft-Designsystem der öffentlichen Website (Tokens, Typografie, Regeln, Komponenten) als Grundlage für den Rollout auf die übrigen Seiten.
„Lust auf Posaunenchor?“ steht als bewusster Blickfang auf voller oranger Fläche mit der Schaltfläche „Mehr erfahren“. DESIGN.md beschreibt den Schlussaufruf als eigene Komponente und passt Do/Don't daran an.
…itive Die Startseite setzt sich jetzt aus wiederverwendbaren Programmheft- Bausteinen zusammen: Köpfe (Heading, SectionHead, ArrowLink), Abschnitt (PageSection), Wegzeilen und Registerzeilen (WayList, WayRow), Programm- zeilen mit Datumsslot und offener Anmeldung (ProgrammeList, ProgrammeRow, DateSlot), Bezirksmarke, Beitragsspalten (NewsColumns), Schaltflächen (ButtonLink) und Schlussaufruf (ClosingCall). Die Startseite rendert unverändert: alle Blöcke stehen pixelgenau an derselben Position. Neu im CSS sind die blaue Zeilenfüllung für Förderverein-Zeilen und der Fließtext-Link `.link-ink`.
PublicPage setzt Innenseiten jetzt im Programmheft: ein Seitenkopf auf Papier (PageHead) mit Brotkrumen, genau einem <h1>, Satzstrich und Leitsatz; die klebende zweite Titelleiste (PageHeader) entfällt. Die Seite steht vollständig in Archivo, auch Abschnitte, die noch nicht übertragen sind. - `color` entfällt: Bezirksfarben färben keine Köpfe mehr, der Förderverein setzt `tone="foerderverein"` (blauer Satzstrich). - Öffentliche Varianten statt ui/card, ui/badge, ui/alert, die dem Dashboard bleiben: Panel, Tag, Note. - PersonRow/PersonList ersetzen PeopleCard (Förderverein, Posaunenrat). - Wegzeilen ersetzen ParticipationCard auf Über uns, Spiele, Materialien. - Kopfzeilen der Kurs-, Termin-, Anmelde- und Ensembleseiten mit Etiketten und Bezirksmarke statt weißer Pillen; der negative Abstand unter dem alten Kopf entfällt. - Der Ladezustand von /termine nutzt denselben Seitenkopf.
Alle Texte bleiben, nur die Darstellung wechselt: Einstiegsmöglichkeiten als Registerzeilen, Förderverein mit blauem Satzstrich, Fakten in Haarlinienspalten und blau füllenden Wegzeilen, „Warum Posaunenchor?“ als Merkpunkte, Mitgliedsbeiträge im Tabellensatz, Downloads als Wegzeilen, Ehrungen und Versicherungsfrist als Hinweise, der Schadensfall als Kasten mit Unterlagenliste. „Noch Fragen?“ schließt die Seite als oranger Schlussaufruf; der Newsletter steht deshalb davor. Neue Bausteine: PointList (Merkpunkte) und ValueTable (Beträge). ParticipationCard und SectionHeader werden nicht mehr gebraucht.
- Beta-Etikett ohne Sperrung und Versalien (Tag); Banner-Varianten Warnung und Wartung als Tintenfläche, das ungenutzte „success“ entfällt. - themeColor im Dunkelmodus auf den Nachtgrund #141517. - Ungenutzte animate-homepage-*-Animationen entfernt. - hero-carousel.tsx und upcoming-courses-carousel.tsx gelöscht.
Kurs-, Termin- und Anmeldeseite zeigten die Datenbankwerte (LEHRGANG, KONZERT) statt der Bezeichnungen, die auch das Programm der Startseite nutzt.
…tmachen - Förderverein-Abschnitt als volle Druckfläche in Fördervereinsblau (PageSection surface="foerderverein", `.print-field`: Tinte auch im Nachtdruck, Zeilen füllen sich papierweiß). - Fotofeld neben „Warum Posaunenchor?“ mit Bildnachweis; bis eigene Fotos gepflegt sind, aus der Bildstrecke der Startseite. - Ein Strichsystem: der Seitenkopf schließt vollbreit wie die Abschnitte (Nacht: Nachtlinie). - Längere Vorspanne stehen unter dem Titel statt in der schmalen Spalte. - Kasten im Nachtdruck gleich gebaut; Ehrungen ohne zweiten Kasten. - Etiketten sind nie umrandet: Art, Dauer, Ort und Bezirk im kompakten Kopf als Meta-Text, der Outline-Ton von Tag entfällt. - Mitmachen: 5/7-Raster, Tabelle und Hinweis über die volle Spalte, bewusster Umbruch „Einstiegs-“.
Auf Wunsch des Eigentümers alternieren die Köpfe ab 64rem wie linke und rechte Heftseiten (neuer Baustein `Split`, 4/12 Kopf neben 8/12 Inhalt, Kopf im DOM immer zuerst). Das Raster kehrt damit zu 4/8 zurück; das Fotofeld neben „Warum Posaunenchor?“ entfällt.
DESIGN.md beschreibt jetzt, was diese Sitzung gebaut hat: Seitenkopf der Innenseiten (normal und kompakt), Abschnitt mit Split und blauer Druckfläche, Merkpunkte, Beträge, Personenzeile, Etikett, Hinweis, Kasten, wiederverwendbarer Schlussaufruf, Banner-Varianten, Schaltflächen auf Papier und Textlinks im Fließtext. Neu sind die One Field Rule (höchstens eine blaue Förderverein-Fläche neben Titelblatt und Schlussaufruf) sowie Do's und Don'ts zu Köpfen, Etiketten und Kästen. Der veraltete Hinweis auf die alten Bausteine ist ersetzt.
Die Einstiegsseite richtet sich an Neue: Jungbläserarbeit rückt nach vorn, „Warum Posaunenchor?“ steht vor dem Förderverein, Anrede durchgehend „du“, aktuelle Förderverein-Angaben. Mitgliedschaft, Beiträge, Ehrungen und Instrumentenversicherung stehen wörtlich unverändert auf /mitmachen/mitgliedschaft (Anrede „Sie“), verlinkt aus Abschnitt, Menü und Fußzeile und aufgenommen in Sitemap und Suche.
Geschwister-Ermäßigung sind 20 % der Lehrgangskosten ab dem zweiten Kind, die Geschenk-CD gibt es für alle Neumitglieder. Die abgelaufenen Sonderaktionen 2025 samt Verlosung entfallen.
Beitragsliste und ähnliche Beiträge als Druckspalten mit Haarlinien statt Karten, Filterleiste flach, Beiträge ohne Titelbild zeigen das Logo auf Tinte. Beitragsseite mit ruhigem Kopf, Meta-Zeile und Bildfeld im Text; Lightbox ohne Rundungen und Weichzeichner. Suche erstmals mit Seitenrahmen und nach Art gruppierten Trefferzeilen. Newsletter-Seiten als Innenseiten mit flachen Eingabefeldern. Texte, Filter, RSS und Double-Opt-in unverändert.
…rogrammheft Downloads stehen als Wegzeilen mit Dateimeta, Auszug und Etiketten im Tabellensatz statt in Karten. Die Blechblatt-Ausgaben laufen zweispaltig als Haarlinienliste, die Bläserhefte als Druckspalten mit Cover. Die Cover liegen alle im Querformat 3:2 vor. Bisher streckte die Flex-Zeile die Bildspalte auf Texthoehe, wodurch object-cover nur einen senkrechten Streifen aus der Bildmitte zeigte. Das Feld uebernimmt jetzt das echte Verhaeltnis und steht mit self-start oben.
…Programmheft Sechs Seiten verlieren Karten, Schatten und Icon-Kreise und laufen im Haarlinien- und Tabellensatz. Bezirksfarben stehen nur noch als kleine Marker vor dem Namen, nicht mehr als Farbfläche hinter Karten und Etiketten; die farbigen Kopfstreifen im Posaunenrat entfallen. Die Kernzahlen stehen als Werttabelle, die Zeitleiste tabellarisch mit Jahreszahl in Ziffernbreite. Auf der Strukturseite bleibt das blaue Fördervereinsfeld die einzige volle Druckfläche vor dem Schlussaufruf. Neu ist person-contact-row als Variante von PersonRow für Einträge mit Telefon und Kurzbiografie. Lange Komposita in den schmalen Kopfspalten werden per weichem Trennstrich getrennt, der Ensemblename aus der Datenbank per automatischer Silbentrennung.
Kontakt, Impressum, Datenschutz, Lizenzen, Prävention, Feedback, Offline- und Wartungsseite laufen im Haarliniensatz mit Abschnittsköpfen in der Kopfspalte. Der Wortlaut der Rechtstexte bleibt unverändert. Neu ist programmheft/field mit Beschriftung, Hinweis, Fehlermeldung und einem eckigen Kontrollkästchen. Das Kontaktformular nutzt jetzt ein natives Auswahlfeld statt der gerundeten Dashboard-Komponente, weil cn() in diesem Projekt Klassen nur aneinanderhängt und deren eingebackene Rundung deshalb nicht zuverlässig überschrieben werden konnte.
Die drei geteilten Oberflächen waren die letzten Flächen der alten Welt: gerundete Tafeln mit Schlagschatten, Grau-Palette und bunte Typ-Pillen. Sie sind jetzt eckige Tafeln mit Tintenrand und Haarlinienzeilen. Im Suchfenster entfallen die farbigen Icon-Kacheln je Ergebnisart; die Art steht als Wort in der Metazeile, davor ein blankes Zeichen in Tinte. Der Zähler an der Glocke stand als Papierschrift auf Orange und erreichte damit nur 1,99:1. Er steht jetzt in Tinte auf Orange. Der QR-Code wird in Tinte statt in Graublau gezeichnet, seine Logofläche ist nicht mehr gerundet.
…ndnotiz Der Abonnieren-Knopf war deaktiviert, solange die Einwilligung fehlte, und stand damit von der ersten Sekunde an grau da, ohne zu sagen was fehlt. Er ist jetzt immer bedienbar; das required am Kästchen lässt den Browser genau dorthin springen. Deaktiviert wird nur noch während des Absendens. Der Hinweis zur Abmeldung steht neben dem Formular statt darunter, damit die rechte Seitenhälfte nicht leer bleibt.
Die Terminliste läuft als Programmzeilen mit Datumsfeld, Monatsköpfen und Haarlinien statt als Kartenraster; bei offener Anmeldung steht das Datum im orangen Feld mit Status und Anmelde-Schaltfläche. Kurs- und Termindetails nutzen Werttabellen, Wegzeilen und je eine Tafel für den Anmeldeblock. Der Anzahlungsbereich stand in verschachtelten Bernstein-Kästen und liegt jetzt als eine Tafel mit einer durchgehenden Werttabelle vor: Status, Beträge, IBAN, BIC und Verwendungszweck in einer Spalte. Drei Stellen formatierten Geld mit toFixed(2) statt über formatEuro und zeigten damit Punkt statt Komma; sie sind korrigiert. Die Überweisungsdaten brachen auf schmalen Geräten aus der Zeile, weil Werttabellen ihre Werte nicht umbrechen — dort brechen sie jetzt um. Die Bezirksfarben auf den Kalendermarken bleiben erhalten: Der Kalender ist eine Datenansicht, in der die Farbe unterscheidet und nicht schmückt.
Aus Icon-Kreis-Karten werden Punktlisten und Wegzeilen, aus farbigen Aufruf-Balken der Schlussaufruf am Seitenende. Der Erfahrungsbericht auf der Ehrenamtsseite steht als typografisches Zitat mit Tintenstrich statt in einer Karte. Der Hinweis „Wichtig" auf der Bildungsseite bekommt einen Tintenrahmen statt einer orangen Füllung: Die Seite trägt bereits das blaue Fördervereinsfeld und den orangen Schlussaufruf, und eine dritte Farbfläche direkt unter dem Titel war lauter als die Überschrift. Damit liegt die Seite beim selben Maß wie /mitmachen und /ueber-uns/struktur.
titleAs erlaubte nur p, h3 und h4. Die Bildungsseite setzt den Hinweis „Wichtig" als eigenen Abschnitt und übergab h2, was die Typprüfung zurückwies. Der Fehler ist mit de227c7 hereingekommen, weil meine Typprüfungen den Pfad ausgeblendet hatten, solange dort ein Agent arbeitete.
Die Chorsuche läuft als Registerzeilen mit eckigen Filterfeldern, eckiger
Blätterung und einer Umschaltung zwischen Liste und Karte; die Karte steht
im einzigen Kasten der Seite. Das Bezirksverzeichnis wird zur durchlaufenden
Liste, die Bezirksfarbe steht nur noch als Marker vor dem Namen statt als
Kopffläche einer Karte.
Auf der Bezirksseite stand der Schlussaufruf in Papierschrift auf Orange und
erreichte damit nur 1,99:1; er nutzt jetzt den Schlussaufruf-Baustein mit
Tinte. Der Hinweis „Posaunenchor in der Nähe suchen" bekommt einen
Tintenrahmen statt einer orangen Füllung, weil der Schlussaufruf am
Seitenende dieselbe Bitte stellt und der einzige Blickfang bleiben soll.
Die Bezirksfarbe wurde als bg-district-${n} gesetzt. Tailwind kann aus einem
Laufzeit-Template keine Klasse erzeugen, die Einfärbung war also vermutlich
schon vorher wirkungslos; sie läuft jetzt über getDistrictColor.
Beitragsspalten: Die Innenabstände hingen am laufenden Index, wodurch die mittleren Spalten schmaler waren. Bei festem Seitenverhältnis wurden ihre Bildfelder niedriger und die Überschriften standen versetzt. Jetzt hat jede Spalte denselben Abstand, das Raster wird um diesen Betrag nach links gezogen. Gemessen: Bildhöhen gleich, Überschriften innerhalb von 1 px. Bläserhefte: Das Bildfeld war als Flex-Kind mit w-full und shrink-0 mehrdeutig. WebKit gab ihm die ganze Zeilenbreite und quetschte den Text auf ein Wort pro Zeile — in Safari war die Seite dadurch unbrauchbar. Jetzt eine feste Rasterspalte, in echtem WebKit nachgeprüft. Die Einträge laufen über die volle Satzbreite, weil sie mit Cover und Text schon zwei Spalten mitbringen und daneben eine dritte, leere Spalte stand. Auswahlfelder: Tailwinds appearance-none schreibt kein -webkit-Präfix, deshalb stand in Safari zusätzlich das native Dreieck neben unserem eigenen. Etiketten: Die Zeilenfüllung färbte auch ihre Schrift in Tinte — auf einem tintefarbenen Etikett war sie unlesbar. Sie sind jetzt ausgenommen. Klebende Filterleisten: Ihr Abstand war mit 112/144 px fest verdrahtet, der Höhe der alten Kopfzeile samt Kontextleiste. Die Navigation ist heute 64 bzw. 80 px hoch, darüber blieb eine Lücke. Gemessen wird jetzt die Navigation selbst. Weniger Linien: Kalender und Blechblatt setzten ihre inneren Trenner in 2 px, wodurch sich beim Öffnen fünf schwere Linien stapelten; sie sind jetzt Haarlinien. Auf der Bildungsseite teilen sich Hinweis und erster Abschnitt ein Band statt drei Linien hintereinander zu erzeugen. Abstand unter dem Seitenkopf: flush="top" nahm Spiele, Newsletter und den Über-uns-Unterseiten die Luft zum ersten Abschnitt.
Die Seite war beim Ausrollen übersehen worden und trug als letzte öffentliche Seite noch Rundungen, Schatten und Icon-Kacheln. Sie läuft jetzt im Haarliniensatz mit dem blauen Fördervereinsfeld als einziger Farbfläche vor dem Schlussaufruf; die Bankverbindung steht im einen erlaubten Kasten der Seite. Wortlaut und Zahlen unverändert.
Die Umstellung hatte die Fotos auf kleine runde Avatare verkleinert. Sie stehen jetzt wieder als großzügige Porträts im festen Seitenverhältnis 3:4, rechteckig und ohne Schatten, mit Name, Amt und Kontakt im Haarliniensatz darunter. Fehlt ein Foto, steht dort das Logo auf Tintenfeld wie bei Meldungen ohne Titelbild, damit die Reihe gleich aufgebaut bleibt.
Beide Blöcke standen untereinander; nebeneinander waren sie praktischer. Sie stehen jetzt in zwei Spalten mit Haarlinie dazwischen und stapeln sich unterhalb von 640px wieder. Wortlaut unverändert. Hinweis: Der Dev-Server liefert für diese Route ein veraltetes Kompilat und zeigt die Änderung erst nach einem Neustart — Datei, Lint und Typprüfung sind sauber, live gesehen habe ich sie nicht.
Beim Scrollen verlor man die Seite aus dem Blick: Die alte Kopfzeile zeigte sie an, die neue nicht mehr. Die Leiste trägt jetzt links den Seitentitel wie ein Kolumnentitel im Heft, daneben Ansicht, Trefferzahl und Aktionen. Sie füllt damit genau den Platz, der vorher als Lücke unter der Navigation stand. Beide Leisten sprechen jetzt dieselbe Sprache: Haarlinie statt 2px-Strich unten, gleicher Aufbau von Titel, Zahl und Aktionen. Vorher war die eine schwer abgesetzt, die andere fein.
Die Seite trug als einzige noch einen eigenen Rahmen mit fuenfteiligem, handgeschriebenem Brotkrumenpfad — rund fuenfzig Zeilen JSX, die DashboardPage als Datenfeld entgegennimmt. Der abgebrochene Agent hatte die Migration begonnen und den Import bereits gesetzt, kam aber nicht mehr zum Umbau; ich hatte danach nur umgefaerbt, wodurch der Import verwaist blieb und ESLint zu Recht anschlug. Der blaue Hinweiskasten weicht einer Haarlinie: Er erklaert eine Ausnahme (Nachtragen nach Anmeldeschluss), er warnt nicht — eine eigene Signalfarbe braucht er dafuer nicht. Damit ist die letzte Seite erledigt, die der Abbruch durch die Sitzungsgrenze unfertig hinterlassen hatte.
Select trug role="combobox" — dort zaehlt sichtbarer Text nicht als Name. aria-label wurde vom Typ zwar akzeptiert, aber nie durchgereicht: Der Compiler sagte ja, zur Laufzeit fiel es auf den Boden. Deshalb konnten die Aufrufstellen den Fehler gar nicht selbst beheben. Jetzt durchgereicht, mit dem Platzhalter als Rueckfall — er benennt den Zweck und wechselt im Gegensatz zum Auswahltext nicht mit der Auswahl. Wer ein id mitgibt, behaelt seine <label for>-Kopplung; ein aria-label wuerde deren sichtbaren Text ueberschreiben. Vier Kategorie-Auswahlen und drei Datums-, Zeit- und Dateifelder an ihre bereits sichtbaren Label gekoppelt. Zwei Sprunglinks: einer ueberspringt die Navigation, einer die Seitenleiste. Der Weg zum Dashboard-Inhalt kostete 29 Tabulatorschritte, jetzt zwei. Verschoben statt sr-only, weil sr-only und not-sr-only sich um dieselbe position-Eigenschaft streiten. Seitenleisten-Links waren 36 und 32 Pixel hoch — ausgerechnet in der Datei, die der Kontrakt als Vorlage nennt. Jetzt 44. Spiel-Schrittanzeiger war weiss auf Orange (1,99:1), jetzt Tinte auf Orange (8,46:1). axe ueber acht Dashboard-Seiten in Chromium und WebKit: 0 Verstoesse, vorher 33 button-name und 16 label.
"Posaunenenchoere" auf /ueber-uns. /mitmachen/bildung nannte 25 Euro pro weiterem Kind, /mitmachen und /foerderverein nennen 20 Prozent — und die Berechnung in lib/sibling-discount.ts rechnet mit 0.2. Drei Quellen gegen eine; der Festbetrag war veraltet.
Gemessen: Weiss traegt auf keiner der dreizehn Bezirksfarben (1,81:1 bis 4,47:1). Tinte reicht bei Kleintext auf neun von dreizehn, schlechtester Wert 3,78:1. Es gibt also keine Schriftfarbe, die auf allen dreizehn funktioniert — deshalb steht die Farbe jetzt als Quadrat neben der Schrift, wie BezirkLabel und die Termin- und Kursliste es laengst machen. Ausnahme mit Ansage: Die Bezirkskachel auf der Detailseite behaelt ihre Flaeche. 24px fett ist WCAG-Grosstext mit Schwelle 3:1, dort traegt Tinte auf allen dreizehn. Auswahlchor-Platzhalter trug ein weisses Zeichen auf Druckorange (1,99:1), jetzt Tinte. Geschwisterrabatt-Pille war pastellgruen bzw. pastellgelb mit voller Rundung; jetzt Tag. Berechtigt wird gefuellt, nicht berechtigt umrandet — gefuellt heisst: Das musst du sehen.
article-content.css gestaltet den gespeicherten Beitrags-HTML an drei Stellen zugleich: oeffentliche Beitragsansicht, Dashboard-Vorschau und Editorflaeche. Sie war vollstaendig im alten Design und dem Audit entgangen, weil der gerenderte Dashboard-Seiten geprueft hat, nicht Artikelkoerper. Gemessen vorher: Links standen auf #faa619 — Druckorange als Schriftfarbe auf Papier, 1,99:1. In allen drei veroeffentlichten Beitraegen mit Links. Jetzt primary-ink: 5,26:1 hell, 9,16:1 dunkel. 10 von 10 Links bestehen, in Chromium und WebKit. Links sind zusaetzlich dauerhaft unterstrichen. Vorher waren sie im Fliesstext allein an der Farbe zu erkennen — das reicht fuer farbfehlsichtige Leser nicht (WCAG 1.4.1). code stand auf Magenta #d946ef (3,46:1), jetzt Tinte auf getoentem Grund. Rundungen und Schlagschatten an Bildern, Code und Tabellen entfernt: von je 0 gemessen, vorher auf jedem Bild. Tabellenkoepfe tragen jetzt eine Linie statt einer Flaeche, Trennlinien sind Haarlinien. Die Graustufen des Fliesstexts waren uebrigens KEIN Kontrastfehler (7,56:1) — das war eine Stilfrage. Nur Links und code sind wirklich durchgefallen. Das !important bleibt mit Absicht: Im gespeicherten HTML stehen noch Tailwind-Klassen aus der TipTap-Konfiguration. Weil dieses Stylesheet sie uebersteuert, wirkt die Korrektur auch auf Altbeitraege — sonst muesste jeder einzeln neu gespeichert werden.
Die Funktion verspricht dem Namen nach, die Schriftfarbe auf einer Bezirksfarbe zu waehlen, kann das Kontrastproblem aber nicht loesen. Sie rechnet mit wahrnehmungsbasierter Helligkeit statt WCAG-Relativluminanz, und selbst richtig gerechnet decken Schwarz und Weiss zusammen die dreizehn Farben nicht ab. Nachgemessen: Weiss faellt auf allen dreizehn durch, Tinte bei Kleintext auf vier, diese Funktion ebenfalls auf vier (Bezirk 1, 3, 5, 9). Sie ist derzeit harmlos, weil ihr einziger Aufrufer post-card.tsx selbst von niemandem importiert wird. Der Kommentar steht da, damit der Naechste nicht danach greift — der Name laedt dazu ein. getDistrictColorLight hat gar keinen Aufrufer.
…eschlossen Zwei Regeln, ueber den Dashboard-Baum durchgezogen. Rohe Gruen-, Bernstein- und Gelbtoene: 106 Fundstellen auf 3. Zustaende tragen jetzt Tag mit vorhandenem Ton, Erfolgs- und Hinweiskaesten wurden zu Tinte auf Papier an einer Haarlinie, bunte Kennzahlen zu neutraler Schrift. Rot bleibt ueberall Rot — Fehler, Absagen und Loeschungen behalten ihre Signalfarbe. Die drei verbleibenden stehen mit Absicht: zwei kategoriale Punkte einer Mitgliedschaftslegende, in der Blau, Lila und Markenfarbe danebenliegen — nur den gruenen zu aendern haette die Kategorie unlesbar gemacht, ohne dass irgendetwas einheitlicher wird. Dazu ein Bernstein-Knopf fuer "Absagen", der einen eigenen Kommentar traegt: folgenreich, aber keine Loeschung. text-dark ohne dark:-Gegenstueck: 38 auf 15, und die 15 liegen ausschliesslich in den Spielen und den Instagram-Vorlagen, die beide bewusst ausgenommen sind. --color-dark ist #58595b und hat keine Dunkelmodus-Ueberschreibung; auf Nachtgrund waren das 2,58:1. Jetzt night-muted mit 7,68:1. Sieben Stellen auf der Anmeldungs-Detailseite hatte ich selbst gesperrt, weil ich dort kurz zuvor gearbeitet hatte — hier nachgezogen. Die Rabattzeile wird dabei bewusst KEIN Akzent: Sie steht zwischen Zwischensumme und Gesamtbetrag, und der Gesamtbetrag traegt den Akzent bereits. Zwei gleich gewichtete Zeilen haetten die Endsumme entwertet. Geprueft: prettier, eslint und tsc je Exit 0 ueber alle geaenderten Dateien; axe ueber acht Dashboard-Seiten in Chromium und WebKit 0 Verstoesse; Anmeldungs-Detailseite rendert hell und dunkel ohne Konsolen- fehler und ohne horizontalen Ueberlauf.
In der geteilten Huelle brach der Kopf ab sm nicht um. Der Titel trug min-w-0 und durfte auf null schrumpfen, die Knopfgruppe trug shrink-0 und schrumpfte nie — weshalb ihr eigenes flex-wrap nie ausloeste und sie stur bei voller Breite blieb. Das Defizit musste also allein der Titel tragen. Reproduziert ohne Datenaenderung, vierter Knopf nur im DOM eingeblendet: bei 1024px fiel "Rechnungen" von 190x35px auf 0x350px — null Breite, zehn Zeilen hoch, buchstabenweise untereinander. Bei 1100px 59x105px. Ab 1280px unauffaellig. Das deckt sich mit dem Befund aus der Inhaltspruefung, der allerdings die Rechnungsseite als Ursache vermutete; sie liegt in der Huelle und betraf jede Dashboard-Seite mit vielen Aktionen. Nachher an derselben Stelle: 190x35px, Knopfgruppe in zwei Zeilen, kein Ueberlauf. Regression geprueft ueber 13 Dashboard-Seiten bei 390, 768, 1024 und 1440px in Chromium und WebKit: 104 Messungen, 0 gequetschte Titel, 0 horizontale Ueberlaeufe. axe ueber acht Seiten weiterhin 0 Verstoesse.
Zwei Fehler, beide im Kurs-Router. Die Veroeffentlichungswahl beim Anlegen war Dekoration. Das Eingabeschema von courses.create kannte kein status-Feld, der Client schickte keins, jeder Kurs landete auf dem Prisma-Vorgabewert PENDING — auch wenn die Oberflaeche ausdruecklich "Der Kurs wird sofort auf der Webseite angezeigt" versprach. Termine fuehrten das Feld laengst; hier nachgezogen, inklusive der Pruefung, dass nur mit courses.approve auf APPROVED gesetzt werden darf. Ohne sie koennte sich jeder Autor seine eigenen Kurse freigeben, sobald das Feld ueberhaupt ankommt. Invoice.course stand auf onDelete: Cascade. Ein geloeschter Kurs riss seine Rechnungen mit, samt fortlaufender Nummer, archiviertem PDF und Veroeffentlichungsdatum. Das widersprach dem Schema an anderer Stelle: Invoice.registration steht auf SetNull, ausdruecklich weil "die Rechnung aufbewahrungspflichtig" ist. Jetzt weisen delete und bulkDelete das Loeschen ab, solange Rechnungen mit vergebener Nummer existieren; Entwuerfe haben keine Nummer und stehen nicht im Weg. bulkDelete braucht dieselbe Sperre, sonst waere sie ueber die Mehrfachauswahl zu umgehen. Der Loeschdialog nennt die Regel jetzt vorher, nicht erst als Fehlermeldung danach. Geprueft gegen die echten Prozeduren ueber HTTP, mit Wegwerf-Daten und synthetischer Rechnungsnummer ausserhalb des Zaehlers: DRAFT, PENDING und APPROVED kommen alle drei an; Kurs ohne Rechnung loescht; nummerierte Rechnung sperrt mit PRECONDITION_FAILED und der Kurs steht danach noch; reiner Entwurf sperrt nicht; bulkDelete sperrt ebenso. Kein Rueckstand, die vier echten Rechnungen unveraendert.
USE_PROFILES stand neben ALLOWED_TAGS. DOMPurify *erweitert* damit die Profilliste, statt sie zu ersetzen — die beiden Listen darunter waren praktisch wirkungslos. Nachgemessen kamen `<p style="position:fixed; width:100vw;height:100vh">` und `<form><input type="password">` unveraendert durch. Zusammen ist das ein bildschirmfuellendes Passwortfeld auf eigener Domain, verfasst im Beitragseditor — genau die Ueberlagerung, vor der der Kommentar an ALLOWED_ATTR warnte. Die Absicht stand also da, nur griff sie nicht. Skripte waren nie betroffen: script, onerror, javascript:, iframe und svg wurden auch vorher entfernt. Es braucht ein Redaktionskonto, anonym ist nichts moeglich. figure und figcaption jetzt ausdruecklich erlaubt: posts.ts haengt Bildnachweise serverseitig an, *bevor* gefiltert wird — ohne sie haette das Zuschnueren genau diese Nachweise wieder ausgeraeumt. data-copyright und data-creator werden benannt durchgelassen; der Leuchtkasten der Beitragsansicht liest sie aus, sie wurden aber entfernt. Dazu ADD_URI_SAFE_ATTR, sonst haette die Erlaubnis nur halb gewirkt: DOMPurify verwirft Attributwerte mit Doppelpunkt als moegliche URIs. Gemessen flog `data-creator="Foto: A. B."` raus, `"Foto A B"` blieb — und „Foto: Name" ist genau das Format, das posts.ts erzeugt. Die pauschale data-Erlaubnis bleibt aus. Geprueft: 13 Faelle, keine Fehlschlaege. style, form/input, script, onerror, javascript: in href und src, iframe und fremde data-Attribute fallen; class, width/height, figure/figcaption und die zwei benannten Attribute bleiben; das echte posts.ts-Markup geht unveraendert durch. Bestandsdaten sind unbelastet: von acht Beitraegen enthaelt keiner style, form, input, iframe oder data-Attribute, Termine und Kurse ebenso wenig. Alle acht Nutzer von sanitizeHtml geprueft, auch der Mailpfad — der filtert Markdown-erzeugtes HTML, das kein style enthaelt.
Grundlage fuer den Magazinsatz. Das Lesemass ist von der Huelle in post-detail-view auf den Artikelkoerper selbst gewandert — solange es aussen hing, konnte kein Bild breiter werden als der Text. Vier Breiten (schmal 45%, halb 60%, breit, randlos) und drei Ausrichtungen (links, rechts, mittig) als Klassen. Klassen deshalb, weil der Filter Inline-CSS verwirft; class, width und height ueberleben, style nicht. Ein festes Vokabular passt ohnehin besser zum Heft als freies Skalieren. Bewusst kein Raster mit benannten Spalten: TipTap fuegt Bilder als Blockknoten direkt unter der Wurzel ein, sie waeren damit Rasterelemente — und auf Rasterelementen wird float ignoriert, der Textumfluss also unmoeglich. Im Blockfluss traegt beides. `randlos` meint den Satzspiegel, nicht 100vw: Ein 100vw breites Element in einem zentrierten Container erzeugt bei sichtbarer Scrollleiste waagerechten Ueberlauf. Ausbruch nur mit `--seite`. Die Ausbruchsbreiten rechnen mit 100vw, und das Fenster ist in der Editorflaeche genauso breit wie auf der Seite; ohne Sperre wurde ein randlos-Bild im 596px schmalen Editor 1360px breit (gemessen). Editor und Dashboard-Vorschau bleiben jetzt beim Lesemass. Der Anriss trug sein Mass zuerst selbst und stand 27px zu weit links: `ch` bemisst sich an der eigenen Schriftgroesse, und der Anriss laeuft in text-xl — 65ch sind dort 649px statt 596px. Das Mass steht jetzt in einem Rahmen in Grundschriftgroesse darum. Gemessen in Chromium und WebKit bei 1440, 1024, 768 und 390px: schmal 45%, halb 60%, breit 156%, randlos 228% des Masses; randlos bei 1024px korrekt auf 944px begrenzt; Floats greifen bei halb+links/rechts, breit und randlos schalten sie ab; :has() hebt die Breite auf eine <figure> mit Bildnachweis; unterhalb 48rem faellt alles auf volle Breite; Autorenzeile, Anriss, Artikelkoerper und Zurueck-Link fluchten auf 596px; kein waagerechter Ueberlauf in keiner Kombination.
…chten Eigene TipTap-Bildnotiz: Breite und Ausrichtung als Attribute, die als Klassen ins Markup gehen. Am Bildrand sitzen Ziehgriffe, die beim Ziehen auf die naechste Stufe einrasten (schmal, halb, Satzbreite, breit, randlos) und die aktuelle Stufe anzeigen. Freies Skalieren waere nicht speicherbar: Der HTML-Filter verwirft style-Attribute, nur class, width und height ueberleben. Unterwegs kam heraus, dass der erste Ansatz die Speicherung gar nicht erreicht haette. Der Editor speichert Markdown — getHTML, dann turndown, dann onChange. Gemessen: Nach dem Ziehen auf „halb" stand in der Datenbank nur ``, die Einstellung war weg, weil Markdown keine Bildbreiten kennt. Deshalb jetzt eine Turndown-Regel, die Bilder MIT Klasse als rohes <img> schreibt; Bilder ohne Klasse bleiben Markdown, damit sich am Bestand nichts aendert. Dieselbe Loesung nutzt die Datei laengst fuer Unterstreichung, Durchstreichung und Tabellen. mergeAttributes kommt aus @tiptap/react, nicht aus @tiptap/core: Der Kern ist keine direkte Abhaengigkeit und unter pnpm nicht aufloesbar; @tiptap/react reicht ihn vollstaendig durch. Gemessen im laufenden Editor: Einfuegen, Knotenansicht mit zwei Ziehgriffen und Stufenanzeige, Ziehen um 200px rastet auf „breit" ein und bleibt nach dem Loslassen erhalten. Im Editor bleibt die Bildbreite dabei beim Lesemass — richtig so, der Ausbruch haengt an --seite und gilt nur der oeffentlichen Seite. Rundlauf ueber einen Wegwerf-Beitrag: gespeichert wird `<img src="…" alt="…" class="bild-halb">`, ohne die Umrandungsklassen der Bearbeitungsansicht, und die Klasse uebersteht marked und den Filter. Kein Rueckstand in der Datenbank.
Vorlage ist das Blechblatt selbst (Ausgabe 2025/01, Seiten 2-9): Kein Artikel dort beginnt mit einem Bild ueber die volle Breite. Ueberschrift, sofort Text, das Aufmacherbild etwa halbseitig daneben, Bildnachweis als kleine Zeile darunter. Breite Bilder kommen vor, aber am Fuss der Seite, nicht davor. Gemessen vorher auf der Beitragsseite: Der Titelblock war 885px hoch, der erste Absatz begann bei y=1383 — bei 1440x900 mussten 483px gescrollt werden, bevor ein einziges Wort zu sehen war, bei 1440x1080 noch 303px. Nachher steht der Text bei y=497 bzw. y=536, also sofort sichtbar. Das Bild sitzt jetzt als umflossene Abbildung in der Textspalte: 60% der Spalte, rechts, mit dem Nachweis als figcaption. Ein Float umfliesst nur Text im selben Blockfluss, deshalb tragen Bild und Artikelkoerper eine gemeinsame Huelle, und der Koerper gibt sein Lesemass dort ab (--in-spalte). Editorflaeche und Dashboard-Vorschau haben keine solche Huelle und behalten ihres unveraendert. Die Huelle braucht ein eigenes clear, weil der Float ein Geschwister ist — das clear am Artikelende greift dafuer nicht. Auf dem Handy steht das Bild ueber dem Text statt daneben; dort kostete 3:2 zu viel Hoehe und schob den ersten Absatz bei einem Beitrag 20px unter die Kante — derselbe Fehler, nur klein. Unterhalb sm jetzt 2:1, damit bleibt das Bild und der Text sichtbar. MediaCredit trug noch text-gray-500/dark:text-gray-400; da es hier zur Bildunterschrift wird, jetzt Programmheft-Farben. Der Kontrast steigt in beiden Modi (7,01:1 statt 4,83:1 hell, 7,68:1 statt 7,20:1 dunkel). Die Variante fuer Auflagen auf Fotos bleibt unangetastet. Gemessen in Chromium und WebKit bei 390x844, 1440x900 und 1440x1080: erster Text ueberall ohne Scrollen sichtbar, Umfluss greift, Zurueck-Link bleibt unter dem Bild, Ausbruchsbreiten unveraendert (928 / 1360), kein waagerechter Ueberlauf, keine Seitenfehler.
Zwei Reste aus dem alten Design, die verschiedener Art sind. Die Huelle um EditorContent trug text-gray-900 / dark:text-gray-100. Das ist die Schreibflaeche selbst, also Oberflaeche und nicht Artikelinhalt — jetzt Tinte. Gemessen: rgb(28,29,31) hell, rgb(236,235,232) dunkel. Die TipTap-Attribute fuer Tabellenzellen und Kopfzellen schrieben border-gray-300 / dark:border-gray-600 und bg-gray-100 / dark:bg-gray-800 in jeden neuen Beitrag. Sichtbar wirkungslos, weil article-content.css sie ueberstimmt — aber sie landen im gespeicherten HTML und bleiben dort als tote Klassen liegen, jetzt erst recht, seit der Filter class durchlaesst. Da das Stylesheet Tabellen ohnehin vollstaendig bestimmt, entfaellt die Konfiguration ganz. Nachgemessen an einer Tabelle ohne jede Klasse in der Schreibflaeche: Linien 1px rule bzw. night-rule, Kopfzeile 2px Tinte bzw. Nachtschrift darunter, keine Fuellung, 12px Polster — in hell und dunkel. Das Entfernen kostet also nichts.
Letzte zwei Stellen derselben Art wie die Tabellenzellen zuvor. Link.configure schrieb `text-primary underline` in jeden gespeicherten Beitrag. Sichtbar wirkungslos, weil article-content.css Links vollstaendig bestimmt — aber es war ausgerechnet Orange als Schriftfarbe, also 1,99:1, das dort dauerhaft abgelegt wurde. Table.configure schrieb `border-collapse w-full my-4`, was das Stylesheet ebenfalls schon setzt. `openOnClick` und `resizable` bleiben: Das ist Verhalten, keine Gestaltung. Belegt statt angenommen: Ein Link ohne Klasse im Artikelkoerper rendert primary-ink auf Papier (5,26:1) und Druckorange im Nachtdruck (9,16:1), unterstrichen, Gewicht 500 — also genau das Vorgesehene. Und ein bestehender Beitrag im Editor geoeffnet zeigt drei Links mit class=null, die trotzdem korrekt eingefaerbt und unterstrichen sind. Damit traegt die Erweiterungs-Konfiguration kein HTMLAttributes mehr; Gestaltung steht ausschliesslich in article-content.css, fuer Schreibflaeche und veroeffentlichten Beitrag gleichermassen.
Die Ausrichtung war vollstaendig vorhanden — als Attribut in der Knotennotiz, als CSS mit Textumfluss, und die Turndown-Regel bewahrte sie beim Speichern. Nur gab es keine Bedienung dafuer: Die Ziehgriffe aendern allein die Groesse. Der Umfluss war damit eine Faehigkeit, die niemand ausloesen konnte, und "in der Position verschieben" blieb eine halbe Funktion. Jetzt sitzen in der Auswahl-Ueberlagerung neben der Stufenanzeige drei Knoepfe: Links, Mittig, Rechts. Sie tragen aria-pressed, damit der Zustand nicht allein an der Farbe haengt, und 44px Hoehe wie im Dashboard-Kontrakt gefordert — in einer neu gebauten Komponente will ich nicht unterschreiten, was ich anderswo eingefordert habe. Das preventDefault auf mousedown ist notwendig, nicht dekorativ: Ohne es nimmt der Klick dem Editor den Fokus, ProseMirror hebt die Knotenauswahl auf, und die Leiste verschwindet, bevor onClick greift. Gemessen im laufenden Editor: Nach der Anwahl stehen die drei Knoepfe mit "Mittig" auf aria-pressed=true; Ziehen setzt bild-halb und laesst die Ausrichtung unberuehrt; ein Klick auf "Rechts" ergibt class="bild-halb bild-rechts", data-ausrichtung=rechts und korrekt umspringende aria-pressed-Werte, wobei die Knotenauswahl erhalten bleibt. Rundlauf ueber einen Wegwerf-Beitrag: gespeichert wird `<img … class="bild-halb bild-rechts">` — beide Klassen gemeinsam, ohne die Umrandungsklassen der Bearbeitungsansicht, und sie ueberstehen marked und den Filter. Bisher war nur die Groesse belegt. Kein Rueckstand.
…ernt Sechs Bausteine trugen noch alte Tokens und schlugen damit auf laengst umgestellte Seiten durch: - loading-spinner: Grauschrift und oranger Ring -> Tinte. Haengt an vier oeffentlichen Seiten (Materialien, Blechblatt, Bezirke, Chor finden). - image-with-fallback: bg-gray-800/dark:bg-gray-100 -> Tinte bzw. night-raised, wie der bereits umgestellte CoverFallback. Das Feld kehrte sich vorher um und brauchte deshalb zwei Logos; auf durchgehend dunklem Grund genuegt das helle. - password-strength-meter: leere Spur und Hinweistext waren Grau. Die Skala rot/bernstein/limette/gruen bleibt — sie IST die Aussage der Anzeige. - rich-text-editor-lazy: Ladezustand mit rounded-lg und Graustufen. - dashboard-overflow-menu: text-gray-400 an den Zeichen. - ensemble-map: alte Dunkel-Token, Graustufen und rounded-lg auf einer oeffentlichen Seite. Dazu die Aufklappliste im Kursformular, die nicht nur zwei Dunkel-Token trug, sondern rounded-lg, bg-white, shadow-lg, border-gray-200, text-gray-800 und hover:bg-gray-100 — also komplett altes Design. Geloescht, weil nachweislich ohne jeden Aufrufer (namensbasiert geprueft, nicht ueber Pfade): ui/alert.tsx samt Sammelexport, posts/post-card.tsx, general/user-menu.tsx. Mit post-card faellt der letzte Aufrufer von getDistrictTextColor weg; die Funktion und das nie benutzte getDistrictColorLight sind damit ebenfalls raus. Die Begruendung bleibt als Kommentar stehen, damit niemand so etwas neu baut: Weder Schwarz noch Weiss deckt die dreizehn Bezirksfarben ab. Gemessen: Ensemblekarte auf drei Seiten mit Rundung 0px, Rahmen und Leiste auf rule bzw. rule/25, Link auf dark; Passwortmesser mit leerer Spur auf rule statt Grau; axe auf /register und /materialien je 0 Verstoesse in Chromium und WebKit, keine Seitenfehler. tsc ueber den ganzen Baum sauber — der Beleg, dass die drei geloeschten Dateien wirklich niemand brauchte.
Abschnittskoepfe (Vorstand, Posaunenrat, Materialien) klebten 21px unter dem Kolumnentitel, ihre erste Zeile war verdeckt. Ensemble-Randspalte und Bezirks-Infospalte nutzten ein festes top-24 und rutschten zusaetzlich unter die Navigation. Gemeinsame Klasse sticky-below-nav rechnet Navigation, Banner und die Hoehe des Kolumnentitels ein, die PublicPage als Variable setzt. Der Kolumnentitel hat dafuer eine feste Hoehe.
Der erste Abschnitt hatte als einzige Inhaltsseite kein oberes Polster: 85px zwischen Titel und erster Ueberschrift statt 181px wie auf /mitmachen, /materialien und /kontakt.
Bei rechtsstehendem Kopf endete der Text linksbuendig mitten in der Spalte, 242px vor dem Bild. Text, Termine und Hinweis stehen jetzt in einem gemeinsamen Block von 65 Zeichen, der bei rechtsstehendem Kopf an das Bild heranrueckt.
In Safari standen alle Auswahlchoere links: col-span-4 setzt als grid-column-Kurzform auch den Start zurueck, ob col-start-9 danach noch greift, hing an der Reihenfolge im Stylesheet. Kopf und Inhalt im Split sowie die Randspalte des Newsletters setzen Start und Spanne jetzt in einer Klasse.
Termin- und Kursansicht trugen als letzte Stellen noch `lg:top-24`. Die feste Zahl ergibt 96px, die Navigation endet aber bei 120px: Auf /termine/event/... lief die Randspalte gemessen 24px unter dem Streifen hindurch, in Chromium wie WebKit und auf allen Breiten ab 1024px. `sticky-below-nav` rechnet Banner- und Navigationshoehe zur Laufzeit aus, wie schon auf der Ensemble- und der Bezirksseite. Nachgemessen liegt die Spalte jetzt bei 189px mit 69px Luft. Die Kursansicht klebt mit den heutigen Daten nie, weil ihre Randspalte so hoch ist wie die Spalte daneben. Die Zahl war dort aber dieselbe Falle, sobald ein Kurs laengeren Text bekommt.
Holt den Anmeldungs-Stack (#314, #316, #317) in die Neugestaltung. Konflikte in sechs Dateien, jeweils mit der Programmheft-Fassung als Grundlage: - Anmeldeformular: Sperre bei ungeklaerter Platzwahl uebernommen, Knopf bleibt in Tinte. - Schritt 3: pauschaler Wartelisten-Hinweis entfaellt, wie im Stack; den genauen Hinweis gibt jetzt seat-shortage-notice. - Meine Anmeldungen und Anmeldungsdetail: Etiketten "Aufgeteilt" und "Nachruecken moeglich", Nachrueck-Angebot und Hinweis auf den anderen Teil einer aufgeteilten Anmeldung neu im Programmheft gesetzt. - Dashboard-Teilnehmende: Verweise auf weitere Teile und das Nachrueck-Angebot als Etiketten.
Die mit dem Stack gekommenen Bausteine standen noch im alten Stil: Hinweis bei zu wenig Plaetzen, Wahl zwischen ganzer Warteliste und Aufteilen samt Teilnehmerauswahl, und das Nachrueck-Angebot auf der Anmeldungsseite. Jetzt mit Note, Tag, Haarlinien und Tintenrahmen fuer die gewaehlte Karte; Texte und Verhalten unveraendert. Die Radio-Knoepfe sind selbst gezeichnet: WebKit zeigte den nativen Knopf im Nachtdruck als volle weisse Scheibe, die wie gewaehlt aussah. Der Link auf den weiteren Teil einer Anmeldung im Dashboard behaelt die Etikettenhoehe, trifft aber auf 44px.
Merged
nichtLehdev
added a commit
that referenced
this pull request
Sep 18, 2026
Programmheft: visuelle Neugestaltung der gesamten Plattform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ersetzt die karten- und schattenlastige Gestaltung durch die Programmheft-Welt: weißes Papier, orange Druckfelder, Tinte, Haarlinien, Archivo in schmaler und halbschmaler Achse. Keine Rundungen, keine Schlagschatten, keine verschachtelten Rahmen.
Inhalt, Texte, Informationsarchitektur und Funktion bleiben — es ändert sich die Darstellung. Ausnahmen, die darüber hinausgehen, sind unten einzeln aufgeführt.
Umfang
76 Commits, 318 Dateien, +27.982/−28.794 Zeilen.
Neu entstanden ist eine Bausteinschicht unter
_components/programmheft/(Seitenkopf, Abschnitte, Etiketten, Personenzeilen, Wegelisten, Bezirksmarke). Entfallen sind die alten Karten-, Karussell- und Kopfzeilen-Bausteine.Über die Gestaltung hinaus
Diese Änderungen betreffen Verhalten, nicht nur Aussehen, und sollten beim Prüfen besondere Aufmerksamkeit bekommen:
USE_PROFILESstand nebenALLOWED_TAGSim HTML-Filter und machte beide Listen wirkungslos.<p style="position:fixed;width:100vw;height:100vh">und<form><input type="password">kamen unverändert durch — zusammen ein bildschirmfüllendes Passwortfeld auf eigener Domain, verfasst im Beitragseditor. Skripte waren nie betroffen, und es braucht ein Redaktionskonto. (83e2c71)PENDING, obwohl die Oberfläche „wird sofort angezeigt" versprach. Und ein gelöschter Kurs riss seine ausgestellten Rechnungen per Kaskade mit, entgegen der Zusage „bleibt im Archiv erhalten". (3d1d8a6)f3d7f99,19ec1dd,9829989,deffe0d)7ad3d8a,aca562f)Geprüft
jest: 54 Suiten, 634 Tests grünnext build: erfolgreichtsc --noEmit,eslint,prettier: sauberaxe-coreüber acht Dashboard- und sieben öffentliche Seiten, Chromium und WebKit, hell und dunkel: 0 Verstöße, inklusivecolor-contrastBewusst nicht enthalten
/spielebleiben im alten Design — eigener Durchgang, folgt separat.Offen, zur Entscheidung
dashboard/media/page.tsxsagt „Ausstehend"/„Freigegeben", die Dialoge daneben „Zur Prüfung"/„Veröffentlicht"@example.de, Testkurstest-2026öffentlich,motto = "unchanged"auf zwei KursenDESIGN.mdbeschreibt den Stand vom 15.09. und kennt das Dashboard noch nicht