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
71 lines
3.1 KiB
HTML
71 lines
3.1 KiB
HTML
<!doctype html>
|
|
<html lang="de-CH">
|
|
<head>
|
|
<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 die IP jedes Besuchers weiter. #}
|
|
<script src="/static/htmx.min.js" defer></script>
|
|
</head>
|
|
<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 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 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>
|
|
{% if entwurf_anzahl %}
|
|
<a href="/entwuerfe" class="knopf-still">
|
|
Entwürfe
|
|
<span class="bg-marke-700 text-white rounded-full px-2 text-xs">
|
|
{{ entwurf_anzahl }}</span>
|
|
</a>
|
|
{% endif %}
|
|
<form method="post" action="/abmelden" class="inline">
|
|
<input type="hidden" name="csrf" value="{{ csrf }}">
|
|
<button class="knopf-still">Abmelden</button>
|
|
</form>
|
|
{% 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>
|
|
|
|
<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 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 dark:text-slate-500 py-6">
|
|
Kinderkleider-Börse ·
|
|
<span title="{{ version.titel }}">{{ version.label }}</span>
|
|
</footer>
|
|
</body>
|
|
</html>
|