diff --git a/news/templates/_nav.html b/news/templates/_nav.html index 6f0304e..037a0ee 100644 --- a/news/templates/_nav.html +++ b/news/templates/_nav.html @@ -4,4 +4,29 @@ Digest Tune Config + + diff --git a/news/templates/_theme.html b/news/templates/_theme.html new file mode 100644 index 0000000..14ecd19 --- /dev/null +++ b/news/templates/_theme.html @@ -0,0 +1,44 @@ +{#- Shared palette, theme toggle and nav styling. + + Three states, not two: system (follow the OS), light, dark. The dark rules + are guarded with :not([data-theme="light"]) so an explicit light choice wins + over a dark OS setting -- without that guard the toggle only works one way. +-#} + + diff --git a/news/templates/config.html b/news/templates/config.html index 700babe..1e62cf4 100644 --- a/news/templates/config.html +++ b/news/templates/config.html @@ -2,15 +2,8 @@ Config +{% include "_theme.html" %}
diff --git a/news/templates/digest.html b/news/templates/digest.html index 2b9f29f..b0910b1 100644 --- a/news/templates/digest.html +++ b/news/templates/digest.html @@ -2,12 +2,8 @@ Briefing — {{ day }} +{% include "_theme.html" %}
diff --git a/news/templates/triage.html b/news/templates/triage.html index 9c427f3..4c23cf4 100644 --- a/news/templates/triage.html +++ b/news/templates/triage.html @@ -2,15 +2,8 @@ Triage +{% include "_theme.html" %} diff --git a/news/templates/tune.html b/news/templates/tune.html index 171d4d7..7cc6920 100644 --- a/news/templates/tune.html +++ b/news/templates/tune.html @@ -2,13 +2,8 @@ Tune +{% include "_theme.html" %}
diff --git a/tests/test_delivery.py b/tests/test_delivery.py index d4e4148..8228fb7 100644 --- a/tests/test_delivery.py +++ b/tests/test_delivery.py @@ -243,3 +243,27 @@ def test_every_page_carries_the_nav(client, path, active): for target in ("/tune", "/config", "/digest"): assert f'href="{target}"' in html, f"{path} is missing a link to {target}" assert f'class="here">{active}<' in html, f"{path} does not mark itself active" + + +@pytest.mark.parametrize("path", ["/", "/tune", "/config", "/digest"]) +def test_every_page_has_a_working_theme_toggle(client, path): + """Three states (system/light/dark), no flash, and the guard that makes the + light choice win over a dark OS setting.""" + c, _ = client + html = c.get(path).text + assert 'id="theme"' in html, "theme button missing" + assert '[data-theme="dark"]' in html, "explicit dark rules missing" + assert ':root:not([data-theme="light"])' in html, ( + "without this guard, choosing light does nothing under a dark OS theme") + # The theme must be applied before first paint, so its script has to appear + # ahead of any rendered content. + assert html.index("localStorage.getItem('theme')") < html.index("