Der Playwright-Editortest war durch den Editorumbau kaputt: er steuerte die abgeschafften Auswahllisten. Umgeschrieben auf die freien Bedienelemente - Einheitenfelder, Vererbung über drei Geräte, einzelnes Zurücksetzen, Palettenfarbe, Abstand je Seite, Hover-Regel, freie Rasterspalten und die weiter vorhandenen Bewegungseffekte. Dabei kamen drei Fehler heraus, die ohne Browserlauf unsichtbar sind: 1. Die frei gestalteten Werte wirkten in der Editorvorschau gar nicht. Ein srcdoc-Iframe erbt die Richtlinie des einbettenden Dokuments, und die Verwaltung verbietet Inline-Styles - das erzeugte style-Element wurde stillschweigend verworfen. Ausgeliefert wurde es korrekt, nur die Vorschau log. Jetzt als inertes template plus adoptedStyleSheets. 2. Die Einrückung der Unterseiten in der Seitenliste hat nie funktioniert; sie lief über ein style-Attribut, das dieselbe Richtlinie verwirft. Jetzt über Klassen. 3. Das Theme setzte alle Links auf die Akzentfarbe und überschrieb die kontextabhängigen Farben: 3,08:1 auf dunklem Grund. Die Regel gilt jetzt nur für Links in Textblöcken, die voreingestellte Linkfarbe liegt auf allen hellen Tönen über 4,5:1. Geprüft: 155 PHP-Tests / 579 Assertions unter PHP 8.2.12 und 8.4.22, 15 JavaScript-Modelltests, vollständiger Editortest mit axe (null Verstöße) und Lighthouse 13.4.1 mit je drei Läufen mobil und Desktop, alle fünf Kategorien 100. Offen: npm run test:browser schlägt wegen eines Inhalts fehl - /grundlagen trägt einen im Editor gesetzten Textblock mit 2,75:1. Nicht verändert, weil es eine Nutzerentscheidung ist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
61 lines
4.1 KiB
Twig
61 lines
4.1 KiB
Twig
<!doctype html>
|
||
<html lang="{{ page.locale }}">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>{{ page.document.title }}</title>
|
||
<meta name="description" content="{{ page.document.description }}">
|
||
<link rel="canonical" href="{{ canonical }}">
|
||
{% if page.robots|default('index') != 'index' %}<meta name="robots" content="noindex, follow">{% endif %}
|
||
<meta property="og:title" content="{{ page.document.title }}">
|
||
<meta property="og:description" content="{{ page.document.description }}">
|
||
<meta property="og:type" content="{{ page.type|default('page') == 'post' ? 'article' : 'website' }}">
|
||
<meta property="og:url" content="{{ canonical }}">
|
||
{% if socialImage|default(null) %}<meta property="og:image" content="{{ socialImage }}"><meta name="twitter:card" content="summary_large_image">{% endif %}
|
||
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||
<link rel="stylesheet" href="/assets/site.css">
|
||
{% if googleFonts|default(null) %}<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="stylesheet" href="{{ googleFonts }}">{% endif %}
|
||
<link rel="alternate" type="application/rss+xml" title="Beiträge" href="/feed.xml">
|
||
{% if page.document.schemaVersion >= 2 %}<link rel="stylesheet" href="/assets/design.css">{% endif %}
|
||
{% if page.document.schemaVersion >= 3 %}<link rel="stylesheet" href="/assets/enhancements.css">{% endif %}
|
||
{% if needsTabs|default(false) %}<script src="/assets/tabs.js" defer></script>{% endif %}
|
||
{# A data block, not a script: CSP script-src does not apply to application/ld+json. #}
|
||
{% for block in structuredData|default([]) %}<script type="application/ld+json">{{ block|json_encode(constant('JSON_UNESCAPED_SLASHES') b-or constant('JSON_UNESCAPED_UNICODE'))|raw }}</script>
|
||
{% endfor %}
|
||
{% if pageStyles|default('') %}
|
||
{# In the editor the preview inherits the administration's policy, which forbids inline
|
||
styles. The stylesheet therefore travels as inert template text and the editor applies
|
||
it as a constructed stylesheet – same result, no policy violation and a clean console. #}
|
||
{% if editing|default(false) %}<template id="kant-styles">{{ pageStyles|raw }}</template>
|
||
{% else %}<style>{{ pageStyles|raw }}</style>{% endif %}
|
||
{% endif %}
|
||
</head>
|
||
<body class="kant">
|
||
<a class="skip-link" href="#main">Zum Inhalt springen</a>
|
||
<header class="site-header shell">
|
||
<a class="brand" href="/" aria-label="Kant CMS – Startseite"><span class="brand-icon" aria-hidden="true">k.</span> kant<span class="brand-light">cms</span></a>
|
||
{% if navigation.header|default([]) is not empty %}
|
||
<nav aria-label="Hauptnavigation">{% include 'nav.html.twig' with {links: navigation.header} only %}</nav>
|
||
{% endif %}
|
||
</header>
|
||
<main id="main" tabindex="-1">
|
||
{% if postMeta is defined and postMeta is not null %}
|
||
<p class="post-header shell">
|
||
{% if page.published_at %}<time datetime="{{ page.published_at|date('Y-m-d') }}">{{ page.published_at|date('d.m.Y') }}</time>{% endif %}
|
||
{% if page.author %}<span>von {{ page.author }}</span>{% endif %}
|
||
{% for term in postMeta.category %}<a href="{{ term.href }}">{{ term.name }}</a>{% endfor %}
|
||
{% for term in postMeta.tag %}<a class="post-tag" href="{{ term.href }}">#{{ term.name }}</a>{% endfor %}
|
||
</p>
|
||
{% endif %}
|
||
{% for block in page.document.blocks %}{% include 'blocks/block.html.twig' with {block: block, editing: editing|default(false), postLists: postLists|default({}), forms: forms|default({}), breadcrumbs: breadcrumbs|default([])} only %}{% endfor %}
|
||
</main>
|
||
<footer class="site-footer shell">
|
||
<a class="brand" href="/">kant<span class="brand-light">cms</span></a>
|
||
{% if navigation.footer|default([]) is not empty %}
|
||
<nav aria-label="Fußzeile">{% include 'nav.html.twig' with {links: navigation.footer} only %}</nav>
|
||
{% endif %}
|
||
<span>Lokaler Entwicklungsprototyp · 2026</span>
|
||
</footer>
|
||
</body>
|
||
</html>
|