Jede Verwaltungsseite trug bisher ihre eigene Kopfzeile und ihre eigene, unvollständige Liste von Links auf die anderen Seiten - die Seitenübersicht verlinkte sieben Bereiche, das Menü fünf, die Fassungen drei. Wo man war, stand nirgends. Jetzt gibt es einen Rahmen für alle: eine feste Seitenleiste mit der Navigation, der aktive Eintrag über aria-current markiert, und eine Kopfzeile mit Titel, einem Satz Erklärung und Platz für die Hauptaktion. Jede Seite füllt nur noch heading, lead, actions und content. Auf schmalen Fenstern wird die Seitenleiste zu einer scrollbaren Leiste, ohne JavaScript. Die Seitenübersicht zeigt je Seite eine Zeile mit dem Alltäglichen und einem Aufklappfeld "Einstellungen", das darunter an seinem Platz öffnet - vorher waren es sechs Aufklappfelder, deren Inhalt als absolut positionierter Kasten über den Rand der Karte hinausragte. Tabellen scrollen seitlich, statt die Karte aus dem Fenster zu schieben. Das Stylesheet ist geteilt: die Editorregeln stehen in editor.css, das nur Editor und Mediathek laden; admin.css ist neu geschrieben und lesbar. Der Editor behält seinen Aufbau und übernimmt die neue Gestaltung - Systemschrift, gleiche Radien, gleiche Schaltflächen, und ein paar Panelgrößen, die zum Lesen zu klein waren. Beim Zerlegen des Stylesheets schnitt mein Skript am Ende jedes @media-Blocks alle schließenden Klammern ab statt nur einer. editor.css war damit ab dem ersten Medienblock ungültig: der Browser behielt 29 von 202 Regeln. Gefunden hat das der Browsertest, an einer Vorschaubreite von 1236 statt 1240 Pixeln - vier Pixel als einziges Anzeichen dafür, dass dreiviertel des Stylesheets fehlte. 201 PHP-Tests / 716 Assertions unter PHP 8.2.12 und 8.4.22, Playwright- Editortest mit axe ohne Verstöße auf Anmeldung, Seitenübersicht und Editor, öffentliche Browserprüfung grün. Zwei Testselektoren zeigten auf umbenannte Klassen und prüfen dieselbe Sache nun über den neuen Namen. Nicht geprüft: kein Screenreader, und die Bildschirme Menüs, Formulare, Bereiche, Design, Einstellungen und Fassungen sind nur von Hand bedient, nicht automatisiert geprüft. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
47 KiB
Projektstatus
Stand: 12.09.2026. Arbeitstitel Kant CMS. Die Verwaltung hat einen gemeinsamen Rahmen mit einer Navigation, die zeigt, wo man ist. Eigenes CSS je Element für alle, eigenes Skript nur für Administratoren und nur als eigene Datei. Formatierter Text mit Werkzeugleiste und HTML-Ansicht, serverseitig gegen eine Positivliste gefiltert. Kopf- und Fußbereich sind frei gestaltbare Blockdokumente, dazu verknüpfte wiederverwendbare Sektionen (Arbeitspaket G, Teil 1). Frei wählbare Startseite; /sitemap.xml und Geschwister waren lokal nie erreichbar und sind es jetzt. Seiten verschieben mit automatischen Weiterleitungen, Papierkorb, Fassungsverlauf und geplante Veröffentlichung (Arbeitspaket F). Browsertests wiederhergestellt und erweitert; dabei drei echte Fehler gefunden und behoben, darunter die in der Vorschau wirkungslose Gestaltung. Direktbearbeitung in der Vorschau, Kontrastwarnung, Gestaltungsvorlagen und Bildauswahl für Hintergrundbilder. Der Editor gestaltet frei statt über feste Auswahllisten: eigene Farbpalette, Schriften, und jede Eigenschaft je Block, je Gerät und für den Hover-Zustand frei einstellbar (Dokumentschema v10). SEO-Grundlage mit Sitemap, robots.txt, Weiterleitungen und strukturierten Daten (Arbeitspaket E). Formulare mit serverseitiger Validierung, Einwilligung, E-Mail-Versand und Spamschutz (Arbeitspaket D). Tabs als fortschreitende Verbesserung mit JavaScript (Dokumentschema v7). Zehn neue Blöcke für die Abschnitte der Pilotstartseite (Arbeitspaket C). Beiträge mit Datum, Autor, Auszug, Beitragsbild, Kategorien, Schlagwörtern, Archiven, einbettbarer Beitragsliste und RSS (Arbeitspaket B). Menüs mit Seiten-, Anker- und externen Zielen ersetzen die fest verdrahtete Navigation (Arbeitspaket A). Seiten und Beiträge lassen sich im Browser anlegen und löschen, mit Adresshierarchie bis vier Ebenen. Die vollständige Phase-1-Abnahme bleibt wegen des fehlenden UX-Builder-Referenzabgleichs offen.
Erster Commit angelegt (82b0782); das Projekt hat damit einen Rückfallpunkt. Noch kein Remote und kein Push.
Erledigt
AGENTS.mdundENTWICKLUNGSPLAN.mdunverändert aus Downloads im Projektstamm abgelegt; SHA-256 jeweils mit dem Original identisch.- Leeres lokales Git-Projekt auf
maininitialisiert; Quellen und Lockfiles für den ersten Commit vorgemerkt. Noch kein Commit und kein Remote/Push. - Nutzerentscheidung „herkömmliches PHP-Webhosting“ übernommen. Symfony 7.4 / Twig / Doctrine gewählt; kein Python-/Django-Anwendungscode.
- Start-/Build-/Prüfkommandos und Hostingvoraussetzungen in README, begründete Architektur und Datenmodell in ARCHITECTURE, Plananalyse/offene Anforderungen in REQUIREMENTS.
- Erstes Datenbankschema, versionierte Blockdokumente, unveränderliche Revisionen über den Repository-Vertrag, getrennte Entwürfe/Veröffentlichungen und optimistische Schreibkonflikterkennung.
- Drei gespeicherte öffentliche HTML-Demoseiten, lokale CSS-Ausgabe ohne JavaScript, Metadaten/Canonical, 404, Sprunglink und sichtbarer Fokus.
/homeleitet auf/um. - Idempotentes Demo-Seeding und lokaler CLI-Import validierter Entwürfe. Keine ungeschützte HTTP-Schreibschnittstelle.
- Symfony-Security-Anmeldung, CSRF, Login-Throttling, geschützte Sessions und Rollen Editor/Publisher/Admin. Neue Migration ergänzt ausschließlich die Benutzertabelle. Passwort-Rehash hält Sessionbenutzer und Datenbank synchron; Rollenänderungen invalidieren bestehende Sitzungen.
- Seitenübersicht und visueller Editor: Elementbibliothek, Strukturbaum, gemeinsame serverseitige Live-Vorschau, Eigenschaften, Drag-and-drop und Schaltflächen zum Verschieben/Verschachteln, Duplizieren/Löschen, lokales Undo/Redo.
- Inhalt-/Designbereiche mit typabhängigen Abständen, Ausrichtung, Schriftgröße/-stärke, Zeilenhöhe, Spaltenaufteilung/-abstand und Ecken. Gerätewerte Desktop → Tablet → Mobil samt Vererbung, Einzel-/Gerätereset und Undo. Echte Vorschau-Layoutbreiten 1240/768/390 px mit visueller Skalierung.
- Drei bearbeitbare Abschnittsvorlagen (Intro, zwei Leistungen, Kontaktaufruf), einklappbarer Werkzeugkasten, Struktursuche mit Vorfahren, einklappbare Teilbäume, Pfadnavigation und dauerhaft erreichbare Blockaktionen.
- Dokumentformat v2, erhaltender idempotenter v1-Konverter, gemeinsame Tokenliste für Validator/Editor/CSS und dokumentierter Migrations-/Rückweg. Bestehende v1-Seiten werden beim Öffnen nicht geändert; keine neue DB-Migration erforderlich.
- Dokumentformat v3 für Galerie, Bildbeschriftungen/-varianten und Effekte, mit erhaltendem Upgrade ohne Downgrade und Undo. v1/v2 bleiben unterstützt. Schatten, Hover-Anheben/Bildzoom und Einblenden beim Laden ohne öffentliches JavaScript; Bewegungsreduktion wird berücksichtigt.
- Medienverwaltung im Editor und unter
/admin/media: JPEG/PNG/WebP-Upload, echte Bildvalidierung, Größen-/Pixel-/Speichergrenzen, WebP-Varianten bis 480/960/1600 px, Suche, Titel/Alt-Text, Archivieren/Wiederherstellen und Schreibkonflikterkennung. Bildauswahl für einzelne Bilder und Galerien, kontextbezogene Alt-Texte/dekorative Verwendung und Beschriftungen. - Neue Medientabelle durch Migration
20260912000300lokal angewendet. Vorher konsistentes SQLite-Backup untervar/backups/before-media-20260912-051258.db. Bestehende Seiten/Benutzer nicht geändert. Lokal läuft PHP 8.4 mit 8M Upload-, 10M POST- und 256M Speicherlimit; originale Uploads werden nicht gespeichert. - Speichern/Laden von Entwürfen, separates Veröffentlichen mit Bestätigung, sichtbare Speicher-/Fehler-/Konfliktzustände, JSON-Sicherung und bewusster Server-Neuladedialog. Keine Tests schreiben in den echten Seitenbestand.
- Auf ausdrücklichen Nutzerwunsch lokalen Administrator
umutmit zufälligem Passwort angelegt und im In-App-Browser erfolgreich angemeldet. Das Passwort steht in keiner Projektdatei; nur der Hash in der lokalen Datenbank. Keine Browser-Passwortspeicherung ausgelöst. - Seitenerstellung und -löschung im Browser:
POST /admin/pages(abROLE_EDITOR) legt Seite oder Beitrag mit gültigem Startdokument als privaten Entwurf an;POST /admin/pages/{id}/delete(nurROLE_ADMIN) entfernt eine Seite mit allen Revisionen. Beide mit CSRF-Token, Fehlermeldungen als Flash und ohne JavaScript bedienbar. - Adresshierarchie: neue Spalten
path,parent_id,type,created_atüber Migration20260912000400; websiteweit eindeutiger Pfad statt eindeutigem Slug, Tiefe bis vier Ebenen, Beiträge ohne Unterseiten, reservierte Adressen und Adressableitung aus dem Titel. Öffentliche Route bedient verschachtelte Pfade wie/leistungen/webdesign; ein Lookahead hält/admin,/mediaund/assetsaus dem Auffangmuster. - Verwaltung neu gestaltet (ADR 029): ein Rahmen für alle Bildschirme mit fester Seitenleiste, aktivem Eintrag über
aria-current, Titel, einem Satz Erklärung und Platz für die Hauptaktion. Vorher trug jede Seite ihre eigene Kopfzeile und eine eigene, unvollständige Linkliste. Je Seite eine Zeile mit dem Alltäglichen und einem Aufklappfeld „Einstellungen“, das an seinem Platz öffnet, statt sechs Kästen, die über den Rand hinausragten. Tabellen scrollen seitlich, statt die Karte aus dem Fenster zu schieben. Die Editorregeln stehen jetzt ineditor.css, das nur Editor und Mediathek laden. - Verwaltung neu gestaltet (ADR 029): ein Rahmen für alle Bildschirme mit fester Seitenleiste, aktivem Eintrag über
aria-current, Titel, einem Satz Erklärung und Platz für die Hauptaktion. Vorher trug jede Seite ihre eigene Kopfzeile und eine eigene, unvollständige Linkliste. Je Seite eine Zeile mit dem Alltäglichen und einem Aufklappfeld „Einstellungen“, das an seinem Platz öffnet, statt sechs Kästen, die über den Rand hinausragten. Tabellen scrollen seitlich. Der Editor behält seinen Aufbau und übernimmt die neue Gestaltung; seine Regeln stehen jetzt ineditor.css, das nur Editor und Mediathek laden. - Eigenes CSS je Element (Dokumentschema v13) im neuen Reiter „Erweitert“: Eigenschaften für das Element und verschachtelte Regeln mit
&. Der Selektor wird vom Server gesetzt, die Ausgabe neu serialisiert – eine überzählige}kann den Block nicht verlassen. Abgewiesen: @-Regeln, Backslash-Escapes,expression(), fremde Selektoren und jede Adresse außer einem einzelnen/oderhttps://. Für jeden mit Editorrolle. - Eigenes Skript je Element nur für Administratoren. Durchgesetzt beim Schreiben durch Vergleich mit dem gespeicherten Stand – ein Editor kann eine Seite mit Skript weiter bearbeiten, das Skript aber nicht anfassen, auch nicht über eine eigene Anfrage. Ausgeliefert als
/assets/seite/{id}.jsnur für veröffentlichte Seiten, jedes Skript in einer eigenen Closure mitelementundtry/catch. Nur eine Seite mit eigenem Skript sendetscript-src 'self', jede andere behältscript-src 'none'; inline ist nirgends erlaubt. In der Editorvorschau wird nichts ausgeführt. - Formatierter Text in Textblöcken (Dokumentschema v12): fett, kursiv, unterstrichen, durchgestrichen, Code, hervorgehoben, hoch-/tiefgestellt, Absätze, Listen und Links. Im Editor eine Werkzeugleiste plus HTML-Ansicht; eingefügter Inhalt kommt als reiner Text an. Gefiltert wird auf dem Server beim Speichern, nicht im Editor und nicht beim Rendern – was in der Datenbank liegt, ist schon sicher. Nicht erlaubte Elemente werden ausgepackt, der Text bleibt;
script,style,iframeund Verwandte werden samt Inhalt entfernt. Attribute fallen weg außerhrefnach Adressprüfung. Ältere Dokumente behalten Klartextsemantik und werden weiter maskiert. - Kopf- und Fußbereich sind Blockdokumente unter
/admin/partials, im selben Editor gestaltbar wie eine Seite. Im Template steht keine Marke und keine Navigation mehr; ein neuer Blockmenuzeigt einen Menüplatz. Geteilte Bereiche haben keinen Entwurf und keine Veröffentlichung – gespeichert heißt live – und dürfen keine Hauptüberschrift enthalten, weil jede Seite ihre eigene bringt. - Wiederverwendbare Sektionen werden verknüpft, nicht kopiert (Block
partialref, Dokumentschema v11): die Seite speichert nur die Adresse, eine Änderung erreicht jede Seite, die sie einbindet. Zyklen werden abgewiesen, Verschachtelung auf drei Ebenen begrenzt, eine entfernte Sektion hinterlässt keine Lücke und der Verweis bleibt gespeichert. Die Abschnittsvorlagen kopieren weiterhin – beide Wege stehen bewusst nebeneinander. - Frei wählbare Startseite unter Einstellungen. Es gibt jetzt eine Quelle dafür –
SiteSettings::homePath()undpublicPath(); das Literalhomekommt im Anwendungscode nicht mehr vor. Die gewählte Seite muss veröffentlicht und nicht im Papierkorb sein, ihre eigene Adresse leitet dauerhaft auf/, und solange sie die Wurzel ist, lässt sie sich nicht umbenennen oder löschen. /sitemap.xml,/robots.txt,/llms.txtund/feed.xmlwaren lokal nie erreichbar, obwohl jeder Kernel-Test sie bestand: der eingebaute PHP-Server antwortet für fehlende Pfade mit Dateiendung selbst mit 404.bin/dev-router.phpbildet die Rewrite-Regel des Hostings nach; Start- und CI-Befehl nutzen es, und der Browsertest ruft die vier Adressen jetzt über HTTP auf.- Barrierefreiheitsbefunde werden nach Ursache getrennt: ein Kontrastfehler aus Theme oder Stylesheet bricht den Lauf ab, einer aus einer im Editor gesetzten Blockfarbe wird bei jedem Lauf mit Seite, Farbe und Verhältnis ausgegeben und in
reports/browser.jsongeschrieben. Stillschweigend durchgelassen wird nichts. - Seiten umbenennen und verschieben zieht den ganzen Teilbaum mit und hinterlässt für jede alte Adresse eine dauerhafte Weiterleitung. Kollisionen, Tiefengrenze und das Verschieben unter eigene Unterseiten werden vorher abgewiesen; alles in einer Transaktion.
- Papierkorb statt sofortigem Löschen für die Editorrolle: alle Fassungen bleiben, öffentlich 404, verschwunden aus Navigation, Archiven, Feed, Sitemap,
llms.txtund Editorliste. Unterseiten gehen mit; beim Wiederherstellen muss das Elternteil zuerst zurück. Endgültiges Löschen bleibt der Administratorrolle. - Fassungsverlauf je Seite unter
/admin/pages/{id}/revisionsmit Wiederherstellen. Das überschreibt nichts: die alte Fassung wird als neuer Entwurf gespeichert. revision.seqbehebt einen echten Fehler: die Reihenfolge des Verlaufs war nicht eindeutig, weilcreated_atnur Sekunden kennt und mehrere Speichervorgänge in dieselbe Sekunde fallen. Jede Fassung hat jetzt einen je Seite aufsteigenden Zähler.- Geplante Veröffentlichung über
publish_atund den Cron-Befehlcms:publish-due. Ohne Cron bleibt die Seite ein Entwurf. Zeiten in UTC; Seiten im Papierkorb werden nie durch den Zeitplan veröffentlicht. - Die erzeugten Stile wirkten in der Editorvorschau nicht. Ein
srcdoc-Iframe erbt die Richtlinie der Verwaltung, die Inline-Styles verbietet; das Stylesheet wurde stillschweigend verworfen. Die Vorschau liefert es jetzt als inertes<template>, der Editor wendet es überadoptedStyleSheetsan. Ausgeliefert wurde es die ganze Zeit korrekt – nur die Vorschau log. - Die Einrückung der Unterseiten in der Seitenliste hat nie funktioniert: sie lief über ein
style-Attribut, das dieselbe Richtlinie verwirft. Jetzt über Klassen. - Das Theme überschrieb alle Linkfarben und erzeugte damit 3,08:1 auf dunklem Grund. Die Regel gilt jetzt nur für Links in Textblöcken; die voreingestellte Linkfarbe
#a4510fliegt auf allen hellen Tönen über 4,5:1. - Bewegungseffekte (Schatten, Hover, Einblendung) bleiben als eigener Panelabschnitt für jeden Block: sie sind Keyframes und lassen sich mit freien Deklarationen nicht ausdrücken. Die alten Tokenwerte erscheinen nur noch, wo eine Seite sie trägt.
- Direktbearbeitung in der Vorschau: Doppelklick auf Überschrift, Text, Zitat, Aufruf-Band, Symbolkarte, Akkordeon-Eintrag, Tab-Titel oder Kennzahl bearbeitet den Text an Ort und Stelle; Escape beendet, Eingaben werden zu einem Undo-Schritt zusammengefasst. Die Vorschau führt dabei weiterhin kein eigenes JavaScript aus – der Editor greift in ihr Dokument. Eine Schaltfläche im Panel startet dasselbe ohne Maus.
- Kontrastwarnung im Designpanel: Verhältnis zwischen wirksamer Text- und Hintergrundfarbe nach WCAG 2.1 mit drei Stufen. Eine Warnung, kein Verbot.
- Gestaltungsvorlagen im Theme: eine Gestaltung unter einem Namen speichern und auf jedem Block jeder Seite anwenden, dazu Kopieren und Einfügen zwischen Blöcken innerhalb der Sitzung. Vorlagen werden mit demselben Compiler geprüft wie Blockstile.
- Hintergrundbilder werden über die Mediathek gewählt statt über eine eingetippte ID.
- Freie Gestaltung (Dokumentschema v10).
StyleSchemaerklärt jede Eigenschaft einmal mit Typ, CSS-Entsprechung und Grenzen; Validator, CSS-Erzeugung und Editorpanel lesen dieselbe Definition. Rund fünfzig Eigenschaften in sieben Gruppen: Typografie (Schriftart, Größe, Stärke, Lage, Zeilenhöhe, Buchstaben- und Wortabstand, Ausrichtung, Schreibweise, Textlinie, Farbe), Hintergrund (Farbe, Verlauf, Bild mit Größe/Ausschnitt/Wiederholung/Parallax, Überlagerung), Abstände je Seite, Größen, Rahmen je Seite und Ecken je Ecke, Layout (Flex, Raster, Verteilung, Abstand, Reihenfolge) und Wirkung (Deckkraft, freier Schatten, Verschieben, Skalieren, Drehen, Übergangsdauer). Werte je Gerät mit Vererbung Desktop → Tablet → Mobil und einzeln zurücksetzbar; farbige, numerische und Bewegungswerte zusätzlich für den Hover-Zustand. - Theme unter
/admin/theme: frei definierbare Farbpalette (bis 40 eigene Farben, im Editor als@schlüssel), Schriften aus Systemschrift oder Google Fonts mit Auswahl der Schnitte, und die Grundtypografie aus Schrift, Grundgröße, Zeilenhöhe, Überschriftenskala, Inhaltsbreite sowie Text-, Hintergrund- und Linkfarbe. Eine Palettenfarbe zu ändern wirkt überall, wo sie verwendet wird. - Der Server erzeugt pro Seite ein blockgenaues Stylesheet mit Media Queries und
:hover,:focus-within. Es steht inline und ist über seinen eigenen SHA-256-Hash erlaubt, nicht überunsafe-inline. Google Fonts auf ausdrückliche Nutzerentscheidung – das bedeutet eine Anfrage an Google je Seitenaufruf; die Richtlinie öffnet die Hosts nur, wenn tatsächlich eine Google-Schrift eingestellt ist. - SEO: Indexierungssteuerung und Vorschaubild je Seite, Unternehmensdaten unter
/admin/settings,sitemap.xml,robots.txt, Weiterleitungen mit 301 und 410, optionalellms.txt, Brotkrumen-Block (Dokumentschema v9) sowie strukturierte Daten fürOrganization/LocalBusiness,ArticleundBreadcrumbList. Alles Maschinenlesbare wird aus dem veröffentlichten Bestand abgeleitet: eine nicht indexierbare Seite verschwindet gleichzeitig aus der Sitemap und bekommt einnoindex-Meta. Ohne gepflegte Unternehmensdaten wird kein leerer Organization-Block ausgegeben.llms.txtist standardmäßig aus. - Dokumentschema v8: Formulare. Verwaltung unter
/admin/formsmit Feldtypen Text, E-Mail, Telefon, Mehrzeiliges, Auswahl und Einwilligung, Empfänger, Betreff, Antwortadresse und Erfolgsmeldung. Der Formularblock im Seiteninhalt enthält nur die Adresse – Felder und Empfänger liegen in der Datenbank, damit gespeicherter Inhalt nicht ändern kann, wohin eine Anfrage geht. Serverseitige Validierung mit einer Meldung je Feld überaria-describedby/aria-invalid, Eingaben bleiben bei Ablehnung erhalten (HTTP 422), gültige Absendung per HTTP 303 zurück auf die Seite. Spamschutz ohne Dienst Dritter: Honeypot, signierter Zeitstempel und fünf Absendungen je Absender und Stunde. Die Absenderadresse wird nie gespeichert, nur ein Hash; der Zeitpunkt der Einwilligung getrennt. Gespeichert wird vor dem Versand, damit ein kaputter Mailversand keine Anfrage verliert; nicht versendete Einsendungen sind in der Verwaltung gekennzeichnet. Voreingestellter Transportsendmail, perMAILER_DSNauf SMTP umstellbar. Kein CSRF-Token auf dem öffentlichen Weg, weil dafür eine Sitzung und damit ein Cookie auf jeder öffentlichen Seite nötig wäre; Begründung in ADR 017. - Dokumentschema v7: Tabs. Der Server liefert Ankerliste und alle Panels mit Überschriften, also vollständigen Inhalt ohne JavaScript;
public/assets/tabs.jsmacht daraus ein echtes Tab-Widget mittablist/tab/tabpanelund Pfeiltastenbedienung. Die strenge Richtlinie bleibt Voreinstellung: öffentliche Seiten senden weiterhinscript-src 'none', nur eine Seite mit Tab-Block sendetscript-src 'self'. Inline-Skript ist nie erlaubt. In der Editorvorschau erscheinen Tabs untereinander, weil die Vorschau kein JavaScript ausführt; ein Hinweis im Eigenschaftenpanel sagt das. - Dokumentschema v6 mit zehn Blöcken für die Pilotseite: Symbolkarte, Kennzahl, Kundenstimme mit Bewertung, Logoleiste, Aufruf-Band, Kontaktdaten, Trennlinie, Abstand, Akkordeon und Akkordeon-Eintrag. Symbole als Inline-SVG aus einer festen Liste, kein Symbolschriftsatz und keine externe Anfrage. Kontaktdaten werden zu
tel:- undmailto:-Verweisen. Akkordeon überdetails/summary, also ohne öffentliches JavaScript. Tabs sind bewusst nicht umgesetzt – ohne JavaScript gibt es dafür keine zugängliche Lösung; Begründung in ADR 015. - Beiträge: Datum, Autor, Auszug und Beitragsbild als Seitenspalten, gepflegt über ein Formular in der Seitenübersicht. Kategorien und Schlagwörter als Begriffe mit eigenen Archiven unter
/kategorie/{slug}und/schlagwort/{slug}, Gesamtübersicht unter/beitraegemit Paginierung über?seite=N, RSS unter/feed.xml. Der Blockpostlist(Dokumentschema v5) speichert nur Anzahl und Filter; die Beiträge stellt der Controller beim Ausliefern zusammen, damit ein gespeichertes Dokument keinen unveröffentlichten Beitrag zeigen kann. - Menüverwaltung unter
/admin/menusfür die Plätze Hauptnavigation und Fußzeile. Ein Eintrag verweist auf eine Seite, auf ein Sprungziel innerhalb einer Seite oder auf eine Adresse (HTTPS, lokaler Pfad,mailto:,tel:). Zwei Ebenen, bis 60 Einträge, optimistische Konflikterkennung. Bedienung über eine nummerierte Zeilenliste, vollständig ohne JavaScript; Untermenüs in der Ausgabe überdetails/summary. Seitenverweise speichern die Seiten-ID, nicht den Pfad – ein Eintrag folgt einer umbenannten Seite und überlebt eine gelöschte. - Dokumentformat v4: Blocktypen mit Namensraum (
acme.slider) gelten als Bausteine einer Erweiterung und werden erhalten statt abgewiesen. Öffentlich rendert der Kern aus ihnen nichts außer einem HTML-Kommentar, in der Editorvorschau einen Platzhalter. Im Editor bleiben sie auswählbar, verschiebbar, duplizierbar und löschbar, aber nicht bearbeitbar. v1 bis v3 bleiben unverändert unterstützt. - Login-Throttling nutzt in der Testumgebung einen Array-Cache. Zuvor überdauerten die Zähler den Testlauf und sperrten die Anmeldung nach wenigen Wiederholungen aus, was als Testfehler erschien.
- Lokale PHP-/Browser-/Lighthouse-Prüfungen und minimale GitHub-Actions-Konfiguration einschließlich vorbereitetem MySQL-Smokejob.
Geprüft
- 201 PHP-Tests / 716 Assertions unter PHP 8.2.12 und 8.4.22 erfolgreich; zusätzlich 15 JavaScript-Modelltests, der vollständige Playwright-Editortest und die öffentliche Browserprüfung. Abgedeckt sind Migration/Erhaltung, Versionen, ungültige Geräte-/Typ-/Design-/Effektwerte, Vererbung/Reset/Undo, Vorlage-/Galerie-IDs, Uploadvalidierung und Neuencodierung, Metadatenkonflikte, Archivierung sowie sichere Bildquellen.
- Neu geprüft (15 Tests): privater Entwurf nach dem Anlegen, verschachtelte Pfade mit gleichem Slug unter verschiedenen Eltern, abgewiesene Adressen (Großbuchstaben, Schrägstrich, leer, reserviert, unbekannter Typ, fehlendes Elternteil) ohne Schreibzugriff, doppelte Adresse, Tiefengrenze, Beiträge ohne Unterseiten, Löschen mit allen Revisionen samt Schutz für Elternseiten und veraltete Versionen, sowie dass die CMS-Routen nicht vom öffentlichen Auffangmuster verschluckt werden. Über HTTP zusätzlich: anonyme Schreibversuche, CSRF für Anlegen und Löschen, Adressableitung aus dem Titel, kein Löschangebot und HTTP 403 für die Editorrolle, erfolgreiches Löschen als Administrator.
- Verwaltung geprüft: axe ohne Verstöße auf Anmeldung, Seitenübersicht und Editor (Desktop und Mobil), 201 PHP-Tests grün. Nicht geprüft: kein Screenreader, und die Bildschirme Menüs, Formulare, Bereiche, Design, Einstellungen und Fassungen sind nur von Hand angesehen, nicht automatisiert auf Barrierefreiheit geprüft – die Browserprüfung deckt sie nicht ab.
- Verwaltung geprüft: axe ohne Verstöße auf Anmeldung, Seitenübersicht und Editor (Desktop und Mobil), alle PHP-Tests grün. Nicht geprüft: kein Screenreader, und die Bildschirme Menüs, Formulare, Bereiche, Design, Einstellungen und Fassungen habe ich nur im Browser angesehen – die automatische Barrierefreiheitsprüfung deckt sie nicht ab.
- Eigener Code geprüft: fünf CSS-Formen werden korrekt auf das Element bezogen, darunter
& .block-textmit erhaltenem Nachfahren-Leerzeichen. Zehn abgewiesene CSS-Eingaben erreichen kein Dokument: Ausbruch mit}, fremder Selektor,@import,@media,javascript:-Adresse, protokollrelative Adresse, Backslash-Escape,expression(), Eigenschaft ohne Wert und unsinniger Eigenschaftsname. Eigenes CSS erscheint im Seiten-Stylesheet, eigenes Skript nur als Datei mitscript-src 'self'ausschließlich auf dieser Seite; eine Seite ohne eigenes Skript behältscript-src 'none'und liefert keine Datei. Ein Skript aus einem unveröffentlichten Entwurf wird nicht ausgeliefert. Der Rollenvergleich weist Ändern, Entfernen und Hinzufügen eines Skripts ab und lässt unveränderte Skripte durch. - Formatierter Text geprüft: dreizehn Fälle durch den Filter, darunter erlaubte Auszeichnung und Listen, ein
scriptsamt Inhalt entfernt und der Text danach erhalten, Ereignisattribut entfernt,class/styleentfernt und das Element ausgepackt,javascript:-Link zu Text geworden, Bild mitonerrorentfernt,iframeentfernt, unausgeglichene Auszeichnung geschlossen, lokaler Link erhalten, externer Link mitrel="noopener", Klartext maskiert und Umbruch zu<br>. Dazu: gefiltert wird beim Speichern (die Datenbank enthält schon die sichere Fassung), ein nach dem Filtern leerer Textblock wird abgewiesen ohne zu schreiben, ab v12 erscheint Auszeichnung als Auszeichnung in einemdiv, vor v12 maskiert in einemp, und in einem geteilten Bereich gilt derselbe Filter. - Bereiche geprüft: die eingesetzten Kopf- und Fußbereiche erscheinen als gewöhnliche Blöcke, der Navigationsblock zeigt das Menü, und eine Änderung am Kopfbereich erreicht beide Seiten gleichzeitig. Ein leerer Bereich rendert nichts statt einer kaputten Hülle. Verknüpfte Sektion geprüft: auf zwei Seiten sichtbar, die Seitendokumente enthalten nur die Adresse, eine Änderung wirkt an beiden Stellen,
usedBynennt beide Seiten, und nach dem Entfernen bleiben die Seiten heil und der Verweis erhalten. Abgewiesen werden: Hauptüberschrift in einem geteilten Bereich, Sektion mit Selbstbezug, zweiter Kopfbereich und das Löschen von Kopf- oder Fußbereich. - Startseite geprüft: eine andere veröffentlichte Seite wird zur Wurzel, antwortet unter
/, ihre eigene Adresse leitet mit 301 dorthin, die bisherige Wurzel wird eine gewöhnliche Seite und ist wieder verschiebbar. Sitemap, strukturierte Daten und Menüauflösung folgen derselben Entscheidung. Solange eine Seite die Wurzel ist, werden Umbenennen und Papierkorb abgewiesen. Drei ungültige Wurzelangaben (nicht vorhanden, leer, Großbuchstaben) ändern nichts. - Öffentliche Browserprüfung wieder grün, inklusive der vier maschinenlesbaren Adressen über HTTP mit richtigem Inhaltstyp. Sechs Seiten-/Breitenkombinationen ohne Code-Verstoß; die redaktionelle Feststellung zu
/grundlagenwird ausgegeben. - Lighthouse 13.4.1: je drei Läufe mobil und Desktop, alle fünf Kategorien 100 mit Startseite, Theme, gehashtem Stylesheet und Routerskript.
- Seitenverwaltung geprüft: Verschieben ändert drei Adressen über zwei Ebenen, jede neue antwortet mit 200 und jede alte mit 301 auf das richtige Ziel, Slugs und Elternbeziehungen der Unterseiten bleiben erhalten. Vier Fälle werden abgewiesen, ohne etwas zu bewegen oder eine Weiterleitung zu erfinden: in die eigene Unterseite, in sich selbst, auf eine vergebene Adresse und mit einem unbrauchbaren Slug; dazu die Startseite. Papierkorb geprüft: Teilbaum geht mit, öffentlich 404, verschwunden aus Navigation, Sitemap, Archiv, Feed und Editorliste, Kind kann nicht vor dem Elternteil zurück, Wiederherstellen stellt nur die gewählte Seite zurück. Fassungen geprüft: Reihenfolge neueste zuerst, Wiederherstellen fügt eine Fassung hinzu statt zu überschreiben, eine fremde Fassung wird abgewiesen. Zeitplan geprüft: ein künftiger Zeitpunkt veröffentlicht nichts, ein vergangener genau einmal, danach ist der Zeitpunkt verbraucht, und eine Seite im Papierkorb wird nie veröffentlicht.
- Der vollständige Browser-End-to-End-Test läuft wieder und deckt jetzt das neue System ab.
npm run test:editorwar durch den Umbau kaputt (er steuerte die abgeschafften Auswahllisten) und wurde auf die freien Bedienelemente umgeschrieben: Einheitenfelder, Vererbung über drei Geräte, einzelnes Zurücksetzen, Palettenfarbe, Abstand je Seite, Hover-Regel über den Template-Weg, freie Rasterspalten und die weiterhin vorhandenen Bewegungseffekte. axe meldet null Verstöße auf Login, Seitenliste, Editor in Desktop- und Mobilbreite, Medienauswahl und der bearbeiteten veröffentlichten Seite. - Lighthouse 13.4.1 auf der Startseite mit dem neuen Theme-System: je drei Läufe mobil und Desktop, alle fünf Kategorien 100. Das ist die erste Messung seit dem Umbau des Editors.
- Im laufenden Editor durchgespielt: Doppelklick setzt das Element auf
contenteditable="plaintext-only", eine Eingabe landet im Modell (Speicherstatus wechselt auf „Ungespeicherte Änderungen“, der Strukturbaum zeigt den neuen Text), und das Verlassen beendet die Bearbeitung sauber. Die Kontrastwarnung meldete bei#ccccccauf#ffffffkorrekt „Kontrast 1.6:1 – zu wenig“. Die Schaltflächen zum Kopieren und Einfügen erscheinen mit richtigem Aktivierungszustand. Die Teständerungen wurden verworfen und nicht gespeichert. - Gestaltungsvorlagen über HTTP geprüft: anonymer Zugriff führt zur Anmeldung, CSRF-Token ist Pflicht, ein Stil mit eingeschleuster Deklaration und ein leerer Name werden mit HTTP 422 abgewiesen ohne zu schreiben, Speichern und Entfernen funktionieren, und das Designpanel erhält Vokabular, Palette und Vorlagen aus einer Quelle.
- Freie Gestaltung geprüft: ein v10-Dokument mit Farben, Abständen je Seite, Ecken je Ecke, Schatten, Hover und eigenem Mobilwert wird unverändert gespeichert und zu blockgenauem CSS samt Media Query und Hover-Regel. Vierzehn abgewiesene Eingaben schreiben nichts: unbekannte Eigenschaft, unbekanntes Gerät, Farbe als Wort, Farbe als Funktion, Länge ohne Einheit, Länge als
calc(), ein eingeschleustes;position:fixed, Auswahlwert außerhalb der Liste, Zahl außerhalb des Bereichs, Seitenwert als Einzelwert, unbekannte Seite, Hover auf einer Eigenschaft ohne Hover, Schriftschlüssel mit Anführungszeichen und Hintergrundbild als Pfad. Zusätzlich geprüft, dass freie Stile Schema v10 verlangen. - Sicherheitsrichtlinie geprüft: das erzeugte Stylesheet wird über seinen eigenen SHA-256-Hash erlaubt,
unsafe-inlinekommt nicht vor und Skripte bleiben aus. Ohne Google-Schrift wird kein fremder Host erlaubt und keiner kontaktiert; mit Google-Schrift erscheinenfonts.googleapis.cominstyle-srcundfonts.gstatic.cominfont-src. - Theme geprüft: Palettenfarben werden zu CSS-Variablen und normalisiert, die Schriftvariable enthält Familie und Ersatz, Grundgröße, Zeilenhöhe und Inhaltsbreite wirken auf jeder Seite. Acht ungültige Themes schreiben nichts: Farbe als Wort, doppelter Schlüssel, Schriftname als Stapel, Google-Schrift ohne Namen, Grundfarbe ohne Paletteneintrag, Grundgröße ohne Einheit, Zeilenhöhe außerhalb des Bereichs und leere Palette.
- Im Editormodell geprüft: Vererbung vom größeren Gerät, einzelnes Zurücksetzen, das Entfernen leerer Reste, Kopieren der Gestaltung ohne geteilte Objekte und ein vollständiges Undo auf den Ausgangszustand.
- SEO geprüft: die Sitemap ist wohlgeformtes XML und enthält weder eine
noindex-Seite noch einen Entwurf, dafür Beitragsübersicht und Begriffsarchiv;robots.txtverweist auf sie und sperrt/admin; eine nicht indexierbare Seite trägt zusätzlich einnoindex-Meta. Weiterleitungen antworten vor dem 404 mit 301 beziehungsweise 410, eine vorhandene Seite gewinnt gegen eine gleichnamige Weiterleitung, und Selbstbezug, Kette, Großbuchstaben sowie ein anderer Statuscode werden abgewiesen. Strukturierte Daten entstehen nur aus gepflegten Werten: ohne Angaben kein Block, danachLocalBusinessmit Anschrift und entdoppelten Profilen,Articlemit Autor aus den Beitragsdaten undBreadcrumbListaus der Hierarchie.llms.txtantwortet ausgeschaltet mit 404 und listet eingeschaltet weder einenoindex-Seite noch einen Entwurf. Fünf ungültige Unternehmensangaben schreiben nichts, und inrobots.txtüberleben weder Markup noch eine zweite Sitemap-Zeile. - Formulare geprüft: Ausgabe ohne Skript, Honeypot außerhalb der Tabreihenfolge, gültige Absendung wird gespeichert und per HTTP 303 zurückgeleitet, Einwilligungszeitpunkt festgehalten, keine Absenderadresse in der Zeile sondern ein 64-stelliger Hash, Erfolgsmeldung auf der Zielseite. Fehlerhafte Absendung: HTTP 422, nichts gespeichert, vier Meldungen an den richtigen Feldern mit
aria-describedbyundaria-invalid, genau eine Zusammenfassung mitrole=alert, alle Eingaben erhalten. Vier Spamfälle (gefüllter Honeypot, zu schnell, gefälschte Signatur, zu alter Zeitstempel) werden still verworfen und wie ein Erfolg beantwortet. Das Limit stoppt die sechste Absendung innerhalb einer Stunde. Die Formularverwaltung verlangt Anmeldung, Editorrolle und CSRF-Token und weist eine ungültige Empfängeradresse mit Meldung ab. - Tabs geprüft: beide Panels samt Inhalt und Überschrift stehen ohne JavaScript im HTML und sind serverseitig nicht versteckt, die Ankerliste verweist auf die Panels, das Skript wird als externe Datei geladen und nie inline. Die Richtlinie sendet
script-src 'self'ausschließlich auf der Seite mit Tab-Block; eine Seite ohne Tabs und die 404-Seite behaltenscript-src 'none'und laden kein Skript. Ein Tab außerhalb einer Tabgruppe, eine Tabgruppe mit Textkind und Tabs in Schema v6 werden abgewiesen. Im Modell: eine neue Tabgruppe bringt zwei Tabs mit eigenen IDs mit, nimmt nur Tabs auf, und ein Tab lässt sich weder in eine Sektion noch in ein Akkordeon einfügen. - Neue Blöcke geprüft: eine Seite aus allen zehn Abschnittsarten wird unverändert gespeichert, veröffentlicht und ausgegeben; Kontaktdaten werden zu
tel:- undmailto:-Verweisen mit bereinigter Nummer, das Akkordeon ist ein echtesdetails-Element, Symbole sind Inline-SVG, die Bewertung ist für Screenreader ausgeschrieben, und die Ausgabe enthält keinscript. Vierzehn abgewiesene Eingaben schreiben nichts: unbekanntes Symbol, fehlender Titel,javascript:-Ziel, Bewertung außerhalb 0–5 und als Zeichenkette, leerer Kontaktblock, ungültige Telefonnummer und E-Mail-Adresse, unbekannte Abstandsgröße, unerlaubtes Linkschema, Text in Logoleiste und Akkordeon, Akkordeon-Eintrag ohne Akkordeon sowie Kinder an einer Trennlinie. Zusätzlich geprüft, dass die neuen Blöcke in Schema v5 weiterhin abgewiesen werden. - Beiträge geprüft: Sortierung nach Datum mit Paginierung und Begrenzung zu großer Seitenzahlen, Seiten und unveröffentlichte Beiträge bleiben aus dem Archiv, Kategorie- und Schlagwortarchive einschließlich getrennter Namensräume, erneutes Speichern ersetzt die Zuordnung statt sie zu ergänzen, ein leer gewordenes Archiv antwortet weiter mit HTTP 200 und leerer Liste, Löschen löst die Zuordnungen und lässt die Begriffe bestehen, Veröffentlichen stempelt ein fehlendes Datum und lässt ein gepflegtes unangetastet, Seiten werden nie gestempelt. Sechs abgewiesene Metadateneingaben schreiben nichts und erhöhen die Version nicht. Die Beitragsliste zeigt nur Beiträge des gefilterten Begriffs, und das gespeicherte Dokument enthält weiterhin ausschließlich Anzahl und Filter. Der Feed ist wohlgeformtes XML mit absoluten Adressen und enthält keinen unveröffentlichten Beitrag.
- Menüs geprüft: Seiten-, Anker- und externe Ziele einschließlich
tel:in der Ausgabe,aria-currentnur auf der tatsächlich aktuellen Seite und nicht auf Ankereinträgen, gelöschte und unveröffentlichte Seiten fallen aus der Navigation ohne die übrigen Einträge zu verlieren, Kinder eines übersprungenen Eintrags rücken nach, gespeicherte Einträge bleiben erhalten und erscheinen nach dem Veröffentlichen wieder. Zehn abgewiesene Eingaben (leere und überlange Beschriftung, unbekannte Zielart, fehlende Seite, ungültige Sprungziele,javascript:,http:, protokollrelative Adresse, dritte Ebene) schreiben nichts. Über HTTP zusätzlich: anonymer Schreibversuch, CSRF, veraltete Version, Aufbau des Baums aus flachen Formularzeilen mit Position und Ebene, normalisiertes Sprungziel und die Bestätigung, dass die Navigation nicht mehr aus dem Template stammt. - Plugin-Erhalt geprüft: ein v4-Dokument mit
acme.slidersamt verschachteltem Text wird Byte für Byte gespeichert, veröffentlicht und wieder geladen; weder Props noch Kindinhalte noch einejavascript:-URL erscheinen in der öffentlichen Ausgabe, die übrige Seite rendert normal. Fehlerhafte Namensräume und Plugin-Blöcke in v1 bis v3 werden weiterhin abgewiesen, ohne zu schreiben. Im JavaScript-Modell zusätzlich: Verschieben, Duplizieren mit neuen IDs, unverändertes Undo, kein Einfügen in den Baustein und keine Erzeugung über die Elementbibliothek. - Testumgebung:
tests/bootstrap.phpverwirftvar/cache/testeinmal pro Lauf. Ohne Debug prüft Symfony weder den kompilierten Container noch die Vorlagen auf Aktualität; das hat zweimal ein falsches Ergebnis erzeugt (eine Vorlagenänderung wurde übergangen, später schlug ein geänderter Konstruktor aus einem veralteten Container fehl). Zusätzlich lädt Twig in der Testumgebung automatisch neu. - Migration
20260912000600zuerst gegen eine Kopie der lokalen Datenbank ausgeführt und das Ergebnis kontrolliert: acht Anweisungen, vorhandene Seiten und Dokumente unverändert, neue Tabellentermundpage_term, Sortierindex angelegt. Danach nach Backup untervar/backups/before-posts-*.dblokal angewendet. - Migration
20260912000500zuerst gegen eine Kopie der lokalen Datenbank ausgeführt, dann nach Backup untervar/backups/before-menus-*.dblokal angewendet. Seeding legt fehlende Menüs an und lässt vorhandene unverändert; zweimal hintereinander ausgeführt. - Migration
20260912000400zuerst gegen eine Kopie der lokalen Datenbank geprüft und die erzeugten Anweisungen kontrolliert: vier reineALTER TABLE … ADD COLUMN, kein Tabellenneuaufbau. Danach nach konsistentem Backup untervar/backups/before-hierarchy-20260912-102402.dblokal angewendet; Backfill, Indexumstellung und unveränderte Dokumente überprüft. Wiederholtes Seeding und Produktionsbuild erfolgreich. - Composer-/Format-/Twig-/YAML-/Containerprüfungen, Migration, wiederholtes Seeding und Produktionsbuild erfolgreich.
- Frische Quellkopie ohne bestehende DB/Secrets/Dev-Abhängigkeiten erfolgreich eingerichtet; gespeicherte Seite als HTTP 200 gerendert.
- Browserprüfung aller drei öffentlichen Seiten mobil und Desktop; keine axe-Verstöße, keine Überläufe, funktionierende Sprunglink-/Navigationsabläufe auch ohne JavaScript.
- Editor-End-to-End in isolierter Installation: Anmeldung, Auswahl im Iframe, Texteingabe, Undo/Redo, Einfügen/Duplizieren/Verschieben/Drag-and-drop/Löschen, identisches Neuladen, private Entwürfe, Veröffentlichung, Dialog-Fokus/Escape, simulierter Netzwerkfehler mit Wiederholung, 409-Konflikt mit JSON-Export und Server-Neuladen. Einschränkungen der axe-Frameprüfung sind in QUALITY dokumentiert.
- Ausbau im Browser geprüft: Struktursuche und Auswahl per Tastatur, Einklappen, Abstände, Schriftwerte und Vererbung in echten Gerätebreiten, Rücksetzen/Undo, responsive Zweispaltenvorlage und identische Styles nach Speichern/Publizieren auf allen drei Geräten.
- Editoroberfläche, Login und Seitenübersicht ohne axe-Verstöße; identisch gerenderter bearbeiteter öffentlicher Inhalt separat geprüft. Desktop- und Mobil-Screenshots visuell durchgesehen.
- Lighthouse-Startseite: jeweils drei echte mobile und Desktop-Läufe, Median in allen fünf Kategorien 100. Nur lokaler Prototyp; keine Kundenwebsite-Abnahme. Umfang und Grenzen siehe QUALITY.
- Gestaltete v2-Testseite mit Design-CSS und responsiver Abschnittsvorlage: zusätzliche sechs Lighthouse-Läufe, alle fünf Kategorien jeweils 100; LCP-Median mobil 901 ms/Desktop 240 ms, CLS/TBT 0. Echte Seitenbestände und geöffnete Browserentwürfe unangetastet. Bericht:
docs/quality/editor-design-lighthouse.json. - v3-Galerieseite mit echten optimierten Testbildern und Effekten: sechs Lighthouse-Läufe, alle fünf Kategorien jeweils 100; LCP-Median mobil 937 ms/Desktop 279 ms, CLS/TBT 0. Upload, Metadaten, Mehrfachauswahl per Tastatur, Bildbeschriftung, Sortier-Undo, Archivieren/Wiederherstellen, Bewegungsreduktion und öffentliche Bilder im isolierten Browserablauf bestanden. Keine axe-Verstöße in Desktop-/Mobil-Mediathek; Screenshots geprüft. Berichte:
docs/quality/editor-media-browser.jsonundeditor-media-lighthouse.json. - Keine bekannten Dependency-Advisories im ausgeführten Composer-Audit/npm-Installationsaudit.
Bekannte Einschränkungen
- Gestaltung über geprüfte Tokens, keine beliebigen Pixelwerte, eigenen Schriften oder freien Farben. Noch keine Inline-Textbearbeitung, Formulare, dynamischen Menüs, Plugin-/Themeverwaltung oder WordPress-Import. Abschnittsvorlagen sind lokale Blockrezepte, keine globale Templateverwaltung.
- Mediathek derzeit für statische Bilder: keine Videos/PDFs/SVGs, Lightbox/Slideshow, freie Bildzuschnitte, Ordner, Paginierung oder physische Löschung. Bild-URLs sind öffentlich; Archivieren schützt keine vertraulichen Dateien. Originale werden durch optimierte Varianten ersetzt. Einblendungen starten beim Laden, nicht beim Scrollen.
- Sektionen bieten die vorhandenen Farb-/Breitentokens geräteübergreifend. Benutzerverwaltung und Passwortänderung sind noch nicht als Browseroberfläche verfügbar.
- Offene redaktionelle Feststellung:
/grundlagenträgt einen im Editor gesetzten Textblock in#d08080auf hellem Grund – 2,75:1, unter der AA-Schwelle. Die Farbe wurde nicht verändert, weil sie eine Nutzerentscheidung ist; die Prüfung nennt sie bei jedem Lauf, und die Kontrastwarnung im Editor meldet sie ebenfalls. - Aus Umuts erweitertem Auftrag noch offen (Paket G2 im Ausbauplan): die Neugestaltung der Verwaltung.
- Eigenes CSS kennt keine Gerätevarianten – dafür sind die Vorschaugrößen im Designbereich da. Eigenes Skript hat keine Fassungsverwaltung außer der Seitenhistorie und keine Prüfung auf Syntaxfehler; ein fehlerhaftes Skript schreibt in die Browserkonsole und lässt die Seite sonst unangetastet.
- Formatierter Text gilt nur für Textblöcke. Überschrift, Button, Zitat und die Titel von Karten, Tabs und Akkordeon bleiben Klartext; Auszeichnung in einer Überschrift bringt mehr Ärger als Nutzen. Die Werkzeugleiste ist nicht mit einem Screenreader geprüft.
- Offen: der Papierkorb wird nicht automatisch geleert, es gibt keine Aufbewahrungsfrist, und Weiterleitungen aus einem Verschiebevorgang lassen sich nur einzeln in den Einstellungen entfernen.
- Weiterhin keine Erprobung mit einem Screenreader. Bei der Direktbearbeitung wiegt das: dass der Fokus sinnvoll wandert und der Zustandswechsel angekündigt wird, ist durch axe nicht abgedeckt.
- Gestaltungsvorlagen lassen sich in der Oberfläche nur anlegen und anwenden, nicht umbenennen; das Entfernen geht bisher nur über die Schnittstelle. Es gibt keine Vorschau einer Vorlage.
- SEO-Titel und -Beschreibung sind weiterhin die Dokumentfelder; getrennte SEO-Titel gibt es nicht. Das Vorschaubild wird über seine Mediathek-ID eingetragen und noch nicht als
og:imageaufgelöst. Weiterleitungen werden nur bei genauer Übereinstimmung des Pfades gefunden, ohne Muster und ohne Berücksichtigung von Abfrageparametern; Seiten umbenennen erzeugt noch keine automatische Weiterleitung (Paket F). - Dateiuploads in Formularen fehlen – Anhänge brauchen einen nicht öffentlichen Ablageort mit Zugriffsschutz und eine eigene Typprüfung; Begründung in ADR 017. Ebenfalls offen: Formulare lassen sich nicht löschen oder umbenennen, Einsendungen nicht exportieren oder löschen, und es gibt keine Aufbewahrungsfrist. Der tatsächliche E-Mail-Versand ist nie ausgeführt worden: die Tests nutzen einen Transport, der nichts sendet.
- Das Tab-Skript ist nicht im Browser geprüft: Pfeiltastenbedienung,
aria-selected, das Verstecken der Panels und die Auswahl über ein Sprungziel sind nur im Code umgesetzt, nicht ausgeführt. Geprüft ist bisher ausschließlich die serverseitig erzeugte Auszeichnung und die Sicherheitsrichtlinie. - Die neuen Blöcke lassen sich nicht in einer Vorlage bündeln: die drei Abschnittsvorlagen sind unverändert. Die Logoleiste hat keine Graustufen- oder Größenoption, die Kundenstimme kein Bild, die Symbolkarte keine eigene Farbe.
- Beiträge haben noch keine Vorschau des Beitragsbilds in der Verwaltung: das Bild wird über seine Mediathek-ID eingetragen. Es gibt keine Begriffsverwaltung (Umbenennen, Zusammenführen, Löschen ungenutzter Begriffe), keine Beitragssuche und keine Archivbeschreibungen. Die Paginierung der Übersicht ist auf zehn Beiträge je Seite festgelegt.
- Menüs kennen nur die beiden festen Plätze Hauptnavigation und Fußzeile; weitere Plätze, eigene Menüs pro Seite und automatisch aus der Hierarchie erzeugte Einträge gibt es nicht. Die Einträge werden über Position und Ebene sortiert, nicht per Drag-and-drop.
- Seiten lassen sich anlegen und löschen, aber noch nicht umbenennen oder verschieben: eine Adressänderung müsste die Pfade aller Unterseiten mitziehen und Weiterleitungen anlegen. Beiträge werden gespeichert und ausgegeben, haben aber noch keine Übersichtsseite, keine Sortierung nach Datum und keine strukturierten Daten. Die Hauptnavigation ist weiterhin fest im Template; verschachtelte Seiten erscheinen dort nicht automatisch.
- Für diesen Schritt wurden bewusst keine Browser-, Lighthouse- oder axe-Läufe ausgeführt (Nutzerentscheidung). Oberfläche und Ausgabe der neuen Formulare sind nur über die Funktionstests geprüft, nicht visuell.
- SQLite tatsächlich getestet. MySQL-/MariaDB-Kompatibilität und CI erst vorbereitet, nicht nachgewiesen; Anbieter-/Tarifdetails und Livebetrieb offen.
- Der Erhaltungsvertrag für Plugin-Blöcke steht, ein Pluginsystem nicht: Registrierung, Hooks, Abhängigkeiten und Ressourcenladen folgen in Phase 4. Kinder eines Plugin-Blocks werden gespeichert, aber nicht gerendert. Kern-Designtokens gelten für sie nicht.
- Kein Inhaltscache, nur Symfony-Programmcache. Seiten senden
no-store; Veröffentlichung ist dadurch ohne Cacheinvalidierungsverzögerung sichtbar. - Noch keine repräsentativen Kundeninhalte/Bilder/Blog-/Formularseite, keine Felddaten und keine vollständige manuelle Barrierefreiheitsprüfung.
- Die vor der Hostingantwort erzeugte
.venvbleibt ungenutzt und von Git ausgeschlossen. Die automatische Freigabeprüfung blockierte ihren Löschversuch mit „blocked by policy“; keine Umgehung versucht. Auchvar/fresh-check, DB, Secrets und Berichte sind lokal ignoriert.
Nächster konkreter Schritt
Den Editor mit einem Screenreader prüfen und die übrigen Verwaltungsbildschirme in die automatische Barrierefreiheitsprüfung aufnehmen. Danach der Rest von Arbeitspaket G (Inline-Ausbau, globale Bereiche für Header und Footer, wiederverwendbare Sektionen). Danach Arbeitspaket F aus docs/AUSBAUPLAN.md: Seiten umbenennen und verschieben mit Aktualisierung aller Kindpfade und automatischer Weiterleitung, frei wählbare Startseite, geplantes Veröffentlichen, Revisionsliste mit Wiederherstellung und ein Papierkorb statt sofortigem Löschen.
kant-it.de ist seit 12.09.2026 als Pilotwebsite bestimmt. Der öffentliche Bestand wurde erhoben (WordPress 7.1, Flatsome 3.20.9 mit eigenem Child-Theme, WPForms Lite, Complianz, Google-Rezensionen, eigenes Plugin kant-nova-chat) und die noch offene Arbeit daraus in docs/AUSBAUPLAN.md in elf Arbeitspakete aufgeschlüsselt. Erhoben wurde ausschließlich die öffentlich ausgelieferte Startseite; ohne Backendzugang sind Beitragsbestand, Formularkonfiguration, Benutzer und Flatsome-Shortcodes nicht inventarisierbar. Keine externe Veröffentlichung erfolgt.
Lokale Vorschau
Öffentlich: http://127.0.0.1:8080/. Verwaltung: http://127.0.0.1:8080/admin. PHP 8.4.22 im Symfony-Produktionsmodus; der Browser wurde als umut angemeldet. Der Prozess ist sitzungsabhängig; zum erneuten Start README verwenden.