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
+42
View File
@@ -221,3 +221,45 @@ def test_seiten_laden_nichts_von_fremden_servern(client, kategorie_id):
html = client.get(pfad).text
fremde = re.findall(r'(?:src|href)="(?:https?:)?//[^"]+"', html)
assert not fremde, f"{pfad} lädt von aussen: {fremde}"
# --------------------------------------------------------- Darstellung ---
def test_fusszeile_zeigt_die_version(client, monkeypatch):
"""Die CI reicht Tag und Commit durch; lokal steht der Build-Zeitpunkt."""
from app.version import version_info
version_info.cache_clear()
monkeypatch.setenv("APP_VERSION", "1.2.3")
monkeypatch.setenv("APP_REVISION", "abcdef1234567")
try:
assert "Version 1.2.3" in client.get("/").text
finally:
version_info.cache_clear()
def test_ohne_tag_erscheint_der_commit(client, monkeypatch):
from app.version import version_info
version_info.cache_clear()
monkeypatch.setenv("APP_VERSION", "")
monkeypatch.setenv("APP_REVISION", "abcdef1234567")
try:
assert "Commit abcdef1" in client.get("/").text
finally:
version_info.cache_clear()
def test_farbschema_skript_laeuft_vor_dem_zeichnen(client):
"""Ohne das blitzt beim Laden kurz die helle Fassung auf."""
html = client.get("/").text
theme = html.index('src="/static/theme.js"')
koerper = html.index("<body")
assert theme < koerper, "theme.js muss vor <body> stehen"
# und darf nicht verzögert werden
zeile = html[html.rindex("<script", 0, theme):html.index(">", theme) + 1]
assert "defer" not in zeile and "async" not in zeile
def test_umschalter_ist_vorhanden(client):
assert 'id="schema-knopf"' in client.get("/").text