Umut hat den Namen festgelegt: aus dem Arbeitstitel "Kant CMS" wird KantSites. Geändert in allen Seitentiteln der Verwaltung, im Wortmarken-Schriftzug von Anmeldung und Seitenleiste, in den Fußzeilen, in den Demoinhalten für eine frische Installation, in package.json, .claude/launch.json und der Dokumentation. Die Bezeichnung der Website in der Datenbank heißt jetzt ebenfalls KantSites. Nicht angefasst: die bereits gespeicherten Demoinhalte der lokalen Installation. Titel wie "Die Grundlage · Kant CMS" und der Text im Kopfbereich sind Inhalt, nicht Systemname - die gehören in den Editor, nicht in ein Skript, das Revisionen umschreibt. 219 PHP-Tests / 881 Assertions grün, Playwright-Editortest grün. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
110 lines
7.5 KiB
Twig
110 lines
7.5 KiB
Twig
{% extends 'admin/shell.html.twig' %}
|
||
{% set nav = 'theme' %}
|
||
{% block title %}Design{% endblock %}
|
||
{% block heading %}Farben, Schriften, Grundtypografie{% endblock %}
|
||
{% block lead %}Das ist die Grundlage für die ganze Website. Jeder Block erbt von hier und kann jeden Wert einzeln überschreiben – je Gerät und beim Überfahren.{% endblock %}
|
||
{% block content %}
|
||
<form action="{{ path('admin_theme_save') }}" method="post" class="card card-body theme-form">
|
||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('theme') }}">
|
||
|
||
<div class="section-head"><h2>Farbpalette <span class="count">{{ theme.colors|length }}</span></h2><span class="muted">Beliebig viele eigene Farben</span></div>
|
||
<table class="table theme-table">
|
||
<caption class="visually-hidden">Farben der Website. Einen Schlüssel zu leeren entfernt die Farbe.</caption>
|
||
<thead><tr><th scope="col">Schlüssel</th><th scope="col">Name</th><th scope="col">Farbe</th><th scope="col">Wert</th></tr></thead>
|
||
<tbody>
|
||
{% for row in theme.colors|merge([{key: '', name: '', value: '#000000'}, {key: '', name: '', value: '#000000'}, {key: '', name: '', value: '#000000'}]) %}
|
||
{% set n = loop.index0 %}
|
||
<tr{% if row.key == '' %} class="table-new"{% endif %}>
|
||
<td><input name="colors[{{ n }}][key]" maxlength="32" value="{{ row.key }}" pattern="[a-z][a-z0-9-]*" aria-label="Schlüssel von Farbe {{ n + 1 }}" placeholder="akzent"></td>
|
||
<td><input name="colors[{{ n }}][name]" maxlength="60" value="{{ row.name }}" aria-label="Name von Farbe {{ n + 1 }}" placeholder="Akzent"></td>
|
||
<td><input type="color" name="colors[{{ n }}][value]" value="{{ row.value }}" aria-label="Farbwähler für Farbe {{ n + 1 }}" class="theme-swatch"></td>
|
||
<td><code>{{ row.value }}</code></td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
<p class="field-help">Der Schlüssel wird im Editor als <code>@schlüssel</code> verwendet und bleibt bei Farbänderungen gleich – eine Farbe ändern wirkt überall, wo sie benutzt wird.</p>
|
||
|
||
<div class="section-head"><h2>Schriften <span class="count">{{ theme.fonts|length }}</span></h2><span class="muted">Systemschrift oder Google Fonts</span></div>
|
||
<table class="table theme-table">
|
||
<caption class="visually-hidden">Schriften der Website. Einen Schlüssel zu leeren entfernt die Schrift.</caption>
|
||
<thead><tr><th scope="col">Schlüssel</th><th scope="col">Name</th><th scope="col">Quelle</th><th scope="col">Schriftname</th><th scope="col">Ersatz</th><th scope="col">Schnitte</th></tr></thead>
|
||
<tbody>
|
||
{% for row in theme.fonts|merge([{key: '', name: '', family: '', source: 'google', fallback: 'sans-serif', weights: [400, 700]}]) %}
|
||
{% set n = loop.index0 %}
|
||
<tr{% if row.key == '' %} class="table-new"{% endif %}>
|
||
<td><input name="fonts[{{ n }}][key]" maxlength="40" value="{{ row.key }}" pattern="[a-z][a-z0-9-]*" aria-label="Schlüssel von Schrift {{ n + 1 }}" placeholder="heading"></td>
|
||
<td><input name="fonts[{{ n }}][name]" maxlength="60" value="{{ row.name }}" aria-label="Name von Schrift {{ n + 1 }}" placeholder="Überschriften"></td>
|
||
<td>
|
||
<select name="fonts[{{ n }}][source]" aria-label="Quelle von Schrift {{ n + 1 }}">
|
||
<option value="system"{{ row.source == 'system' ? ' selected' : '' }}>Systemschrift</option>
|
||
<option value="google"{{ row.source == 'google' ? ' selected' : '' }}>Google Fonts</option>
|
||
</select>
|
||
</td>
|
||
<td><input name="fonts[{{ n }}][family]" maxlength="48" value="{{ row.family }}" aria-label="Schriftname von Schrift {{ n + 1 }}" placeholder="Inter"></td>
|
||
<td>
|
||
<select name="fonts[{{ n }}][fallback]" aria-label="Ersatzschrift von Schrift {{ n + 1 }}">
|
||
{% for value, label in fallbacks %}<option value="{{ value }}"{{ row.fallback == value ? ' selected' : '' }}>{{ label }}</option>{% endfor %}
|
||
</select>
|
||
</td>
|
||
<td class="weights-cell">
|
||
{% for weight in weights %}
|
||
<label><input type="checkbox" name="fonts[{{ n }}][weights][]" value="{{ weight }}"{{ weight in row.weights ? ' checked' : '' }}> {{ weight }}</label>
|
||
{% endfor %}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
<p class="field-help">Bei Google Fonts den Namen genau wie dort schreiben, zum Beispiel <code>Inter</code> oder <code>Playfair Display</code>. Je Schnitt wird eine Datei geladen – nur ankreuzen, was wirklich gebraucht wird. <strong>Google Fonts bedeutet eine Anfrage an Google bei jedem Seitenaufruf.</strong></p>
|
||
|
||
<div class="section-head"><h2>Grundtypografie</h2><span class="muted">Gilt überall, solange ein Block nichts anderes sagt</span></div>
|
||
<div class="fields">
|
||
<div>
|
||
<label for="base-font">Schrift für Fließtext</label>
|
||
<select id="base-font" name="base[fontFamily]">
|
||
{% for font in theme.fonts %}<option value="{{ font.key }}"{{ theme.base.fontFamily == font.key ? ' selected' : '' }}>{{ font.name }}</option>{% endfor %}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="base-heading-font">Schrift für Überschriften</label>
|
||
<select id="base-heading-font" name="base[headingFontFamily]">
|
||
{% for font in theme.fonts %}<option value="{{ font.key }}"{{ theme.base.headingFontFamily == font.key ? ' selected' : '' }}>{{ font.name }}</option>{% endfor %}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="base-size">Grundgröße</label>
|
||
<input id="base-size" name="base[fontSize]" value="{{ theme.base.fontSize }}" placeholder="18px">
|
||
</div>
|
||
<div>
|
||
<label for="base-line">Zeilenhöhe</label>
|
||
<input id="base-line" name="base[lineHeight]" type="number" step="0.05" min="0.8" max="3" value="{{ theme.base.lineHeight }}">
|
||
</div>
|
||
<div>
|
||
<label for="base-scale">Überschriftenskala</label>
|
||
<input id="base-scale" name="base[headingScale]" type="number" step="0.01" min="1" max="2" value="{{ theme.base.headingScale }}">
|
||
<p class="field-help">1,25 ergibt eine ruhige Staffelung, 1,5 eine sehr kontrastreiche.</p>
|
||
</div>
|
||
<div>
|
||
<label for="base-container">Inhaltsbreite</label>
|
||
<input id="base-container" name="base[containerWidth]" value="{{ theme.base.containerWidth }}" placeholder="1240px">
|
||
</div>
|
||
<div>
|
||
<label for="base-color">Textfarbe</label>
|
||
<input id="base-color" name="base[color]" value="{{ theme.base.color }}" placeholder="@ink">
|
||
</div>
|
||
<div>
|
||
<label for="base-bg">Hintergrundfarbe</label>
|
||
<input id="base-bg" name="base[backgroundColor]" value="{{ theme.base.backgroundColor }}" placeholder="@paper">
|
||
</div>
|
||
<div>
|
||
<label for="base-link">Linkfarbe</label>
|
||
<input id="base-link" name="base[linkColor]" value="{{ theme.base.linkColor }}" placeholder="@accent">
|
||
</div>
|
||
</div>
|
||
<p class="field-help">Farben entweder als <code>@schlüssel</code> aus der Palette oder als Wert wie <code>#1a2b3c</code>.</p>
|
||
<button class="primary" type="submit">Design speichern</button>
|
||
</form>
|
||
<p class="footnote">KantSites · Arbeitsstand</p>
|
||
{% endblock %}
|