Hell/Dunkel-Umschaltung und Versionsangabe in der Fusszeile

Farbschema folgt zunächst der Systemeinstellung, lässt sich per Knopf in
der Kopfzeile umstellen und wird dann gemerkt. Bei gesperrtem Speicher
(privates Fenster) greift wieder die Systemeinstellung.

theme.js steht bewusst OHNE defer und vor dem Inhalt: es setzt die
Farbklasse, bevor gezeichnet wird. Mit defer blitzte beim Laden kurz die
helle Fassung auf. Eine eigene Datei statt eines <script>-Blocks, weil die
CSP nur script-src 'self' erlaubt - inline wäre blockiert.

Fusszeile zeigt Version oder Commit, gleiches Muster wie die Kantone-App:
die CI reicht beides als Build-Argument durch, lokal erscheint der
Build-Zeitpunkt. Der ändert sich bei jedem Neubau und zeigt damit sofort,
ob wirklich der neue Stand läuft.

Beim Ergänzen der Dunkel-Varianten hatte mein Ersetzer die eben
eingefügten dark:-Klassen selbst nochmal getroffen und daraus Paare wie
"dark:text-slate-300 dark:text-slate-600" gemacht - bereinigt.

81 Tests, alle grün. Neu darunter: die Fusszeile zeigt Tag bzw. Commit,
theme.js steht vor <body> und ohne defer, der Umschalter ist da.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GR4bNaj9GtRu57J4Niii8o
This commit is contained in:
2026-08-29 23:35:35 +02:00
co-authored by Claude Opus 5
parent 75b95b38e6
commit adedaa9a0d
17 changed files with 218 additions and 48 deletions
+25 -8
View File
@@ -4,18 +4,26 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<meta name="color-scheme" content="light dark">
<title>{% block titel %}Kinderkleider-Börse{% endblock %}</title>
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/static/style.css">
{# Bewusst OHNE defer und vor dem Inhalt: das Skript setzt die
Farbklasse, bevor gezeichnet wird. Mit defer blitzte beim Laden
kurz die helle Fassung auf. #}
<script src="/static/theme.js"></script>
{# Lokal ausgeliefert, nicht vom CDN: die CSP erlaubt nur script-src
'self', und ein CDN-Aufruf gäbe zudem die IP jedes Besuchers weiter. #}
'self', und ein CDN-Aufruf gäbe die IP jedes Besuchers weiter. #}
<script src="/static/htmx.min.js" defer></script>
</head>
<body class="bg-slate-50 text-slate-900 min-h-screen flex flex-col">
<body class="bg-slate-50 text-slate-900 dark:bg-slate-900 dark:text-slate-100
min-h-screen flex flex-col">
<header class="bg-white border-b border-slate-200 sticky top-0 z-20">
<header class="bg-white dark:bg-slate-800 border-b border-slate-200
dark:border-slate-700 sticky top-0 z-20">
<div class="max-w-5xl mx-auto px-4 h-14 flex items-center gap-3">
<a href="/" class="font-bold text-marke-700 text-lg">Kleider-Börse</a>
<a href="/" class="font-bold text-marke-700 dark:text-marke-100 text-lg">
Kleider-Börse</a>
<nav class="ml-auto flex items-center gap-2 text-sm">
{% if betreiber %}
<a href="/erfassen" class="knopf-still">Erfassen</a>
@@ -33,6 +41,12 @@
{% else %}
<a href="/anmelden" class="knopf-still">Anmelden</a>
{% endif %}
<button id="schema-knopf" type="button" class="knopf-still !px-3"
aria-label="Zwischen hell und dunkel wechseln" title="Hell / dunkel">
<span class="dark:hidden" aria-hidden="true">🌙</span>
<span class="hidden dark:inline" aria-hidden="true">☀️</span>
</button>
</nav>
</div>
</header>
@@ -40,14 +54,17 @@
<main class="flex-1 w-full max-w-5xl mx-auto px-4 py-5">
{% if meldung %}
<p class="mb-4 rounded-xl px-4 py-3 text-sm
{{ 'bg-emerald-100 text-emerald-900' if meldung_art == 'ok'
else 'bg-rose-100 text-rose-900' }}">{{ meldung }}</p>
{{ 'bg-emerald-100 text-emerald-900 dark:bg-emerald-900 dark:text-emerald-100'
if meldung_art == 'ok'
else 'bg-rose-100 text-rose-900 dark:bg-rose-900 dark:text-rose-100' }}">
{{ meldung }}</p>
{% endif %}
{% block inhalt %}{% endblock %}
</main>
<footer class="text-center text-xs text-slate-400 py-6">
Kinderkleider-Börse
<footer class="text-center text-xs text-slate-400 dark:text-slate-500 py-6">
Kinderkleider-Börse ·
<span title="{{ version.titel }}">{{ version.label }}</span>
</footer>
</body>
</html>