Fassung 1.4.3: Update ohne Git, Verwaltung auf dem Telefon, eigene Symbole
CMS quality / php (8.2) (push) Canceled after 0s
CMS quality / php (8.4) (push) Canceled after 0s
CMS quality / browser (push) Canceled after 0s
CMS quality / mysql (push) Canceled after 0s

Vier Wuensche und ein Fund beim Nachmessen.

- Farbwaehler im Designbereich. Das Textfeld bleibt massgeblich, damit
  "@akzent" ein Verweis auf die Palette bleibt und nicht beim ersten
  Klick zu einem festen Hexwert erstarrt (ADR 066).
- Die Verwaltung auf dem Telefon: das Menue klappt unter 760 px zu und
  nennt den Bereich, in dem man steht; Ziele 44 px, kein Skript.
- Eigene SVG-Symbole statt Unicode-Zeichen - ein Telefon ersetzt die
  sonst durch Emoji in fremdem Stil. Zwei Eintraege trugen dabei
  denselben Pfad; ein Test findet beides (ADR 067).
- Update aus dem Releasearchiv: der Weg fuer Installationen ohne Git.
  Zwei Schritte, weil ein Prozess, der sich selbst ausgetauscht hat,
  mit dem alten Code weiterarbeitet. var/, .env, hochgeladene
  Schriften und das erzeugte Buendel bleiben unberuehrt; public/ wird
  dazu Datei fuer Datei zusammengefuehrt. Geprueft ohne Netz gegen
  eine Releaseseite im Speicher (ADR 068).

Beim Nachmessen der echten Startseite statt einer Testseite: das
groesste Element ueber der Falz ist dort kein <img>, sondern der
Hintergrund des ersten Abschnitts - und der steht nur im Stylesheet.
Drei Vorabverweise mit denselben Geraetegrenzen wie der Compiler holen
genau die Variante, die die Regel auch nimmt. LCP 1,3 s -> 1,1 s.
Dabei gefunden: dasselbe Bild wurde je Geraeteregel neu abgefragt -
Startseite 19 -> 15 Abfragen (ADR 069).

Geprueft: 428 Tests auf PHP 8.2 und 8.4, Editor-, Browser- und
Linkpruefung, Lighthouse auf drei echten Seiten (alles ausser der
Leistung der Startseite 100).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5 committed 2026-09-13 23:01:32 +02:00
1 parent ea3dd4ddf2
commit d6d476177a
26 files changed
+1740 -26

No files matched your search

+28 -13
View File
@@ -5,31 +5,46 @@
{% block body %}
<header class="shell-nav">
<a class="brand" href="{{ path('admin_pages') }}"><span class="brand-icon" aria-hidden="true">k.</span>kant<span>sites</span></a>
{# Auf dem Telefon ein Klappmenue, am Schreibtisch die gewohnte Spalte. Ein details-Element
kann beides, ohne eine Zeile JavaScript: die Zusammenfassung wird auf grossen Bildschirmen
ausgeblendet und der Inhalt dauerhaft gezeigt. Zwoelf Eintraege in einer Wischleiste zu
verstecken war die schlechtere Loesung - man sieht nie, was man nicht trifft. #}
<details class="shell-menu">
<summary>
<svg class="shell-menu-icon" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" aria-hidden="true" focusable="false"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
<span class="shell-menu-label">{{ {
'pages': 'Seiten', 'partials': 'Bereiche', 'menus': 'Menüs', 'media': 'Mediathek',
'forms': 'Formulare', 'statistics': 'Statistik', 'theme': 'Design',
'settings': 'Einstellungen', 'system': 'System', 'users': 'Benutzer',
'account': 'Mein Konto'
}[nav|default('')]|default('Verwaltung') }}</span>
</summary>
<nav aria-label="Verwaltung">
<p class="nav-label" id="nav-content">INHALT</p>
<ul class="nav-list" aria-labelledby="nav-content">
{% set entries = [
{id: 'pages', route: 'admin_pages', icon: '▤', label: 'Seiten'},
{id: 'partials', route: 'admin_partials', icon: '◫', label: 'Bereiche'},
{id: 'menus', route: 'admin_menus', icon: '☰', label: 'Menüs'},
{id: 'media', route: 'admin_media', icon: '▩', label: 'Mediathek'},
{id: 'forms', route: 'admin_forms', icon: '✉', label: 'Formulare'},
{id: 'statistics', route: 'admin_statistics', icon: '▁', label: 'Statistik'}
{id: 'pages', route: 'admin_pages', icon: 'pages', label: 'Seiten'},
{id: 'partials', route: 'admin_partials', icon: 'partials', label: 'Bereiche'},
{id: 'menus', route: 'admin_menus', icon: 'menus', label: 'Menüs'},
{id: 'media', route: 'admin_media', icon: 'media', label: 'Mediathek'},
{id: 'forms', route: 'admin_forms', icon: 'forms', label: 'Formulare'},
{id: 'statistics', route: 'admin_statistics', icon: 'statistics', label: 'Statistik'}
] %}
{% for entry in entries %}
<li><a class="nav-item" href="{{ path(entry.route) }}"{{ nav|default('') == entry.id ? ' aria-current="page"' : '' }}><span class="nav-icon" aria-hidden="true">{{ entry.icon }}</span>{{ entry.label }}</a></li>
<li><a class="nav-item" href="{{ path(entry.route) }}"{{ nav|default('') == entry.id ? ' aria-current="page"' : '' }}>{% include 'admin/icon.html.twig' with {name: entry.icon} only %}{{ entry.label }}</a></li>
{% endfor %}
</ul>
<p class="nav-label" id="nav-site">WEBSITE</p>
<ul class="nav-list" aria-labelledby="nav-site">
<li><a class="nav-item" href="{{ path('admin_theme') }}"{{ nav|default('') == 'theme' ? ' aria-current="page"' : '' }}><span class="nav-icon" aria-hidden="true">◐</span>Design</a></li>
<li><a class="nav-item" href="{{ path('admin_settings') }}"{{ nav|default('') == 'settings' ? ' aria-current="page"' : '' }}><span class="nav-icon" aria-hidden="true">⚙</span>Einstellungen</a></li>
{% if is_granted('ROLE_ADMIN') %}<li><a class="nav-item" href="{{ path('admin_system') }}"{{ nav|default('') == 'system' ? ' aria-current="page"' : '' }}><span class="nav-icon" aria-hidden="true">⌬</span>System</a></li>{% endif %}
{% if is_granted('ROLE_ADMIN') %}<li><a class="nav-item" href="{{ path('admin_users') }}"{{ nav|default('') == 'users' ? ' aria-current="page"' : '' }}><span class="nav-icon" aria-hidden="true">☺</span>Benutzer</a></li>{% endif %}
<li><a class="nav-item nav-out" href="/">Website ansehen</a></li>
<li><a class="nav-item nav-out" href="/beitraege">Beitragsübersicht</a></li>
<li><a class="nav-item" href="{{ path('admin_theme') }}"{{ nav|default('') == 'theme' ? ' aria-current="page"' : '' }}>{% include 'admin/icon.html.twig' with {name: 'theme'} only %}Design</a></li>
<li><a class="nav-item" href="{{ path('admin_settings') }}"{{ nav|default('') == 'settings' ? ' aria-current="page"' : '' }}>{% include 'admin/icon.html.twig' with {name: 'settings'} only %}Einstellungen</a></li>
{% if is_granted('ROLE_ADMIN') %}<li><a class="nav-item" href="{{ path('admin_system') }}"{{ nav|default('') == 'system' ? ' aria-current="page"' : '' }}>{% include 'admin/icon.html.twig' with {name: 'system'} only %}System</a></li>{% endif %}
{% if is_granted('ROLE_ADMIN') %}<li><a class="nav-item" href="{{ path('admin_users') }}"{{ nav|default('') == 'users' ? ' aria-current="page"' : '' }}>{% include 'admin/icon.html.twig' with {name: 'users'} only %}Benutzer</a></li>{% endif %}
<li><a class="nav-item nav-out" href="/">{% include 'admin/icon.html.twig' with {name: 'external'} only %}Website ansehen</a></li>
<li><a class="nav-item nav-out" href="/beitraege">{% include 'admin/icon.html.twig' with {name: 'external'} only %}Beitragsübersicht</a></li>
</ul>
</nav>
</details>
<div class="shell-foot">
<p class="shell-version">Fassung {{ kant_version() }}</p>
<a class="shell-user" href="{{ path('admin_account') }}"{{ nav|default('') == 'account' ? ' aria-current="page"' : '' }}><span class="shell-avatar" aria-hidden="true">{{ app.user.userIdentifier|first|upper }}</span><strong>{{ app.user.userIdentifier }}</strong></a>