theming: append the :root override, don't prepend -- cascade order matters
commit 46fd58b7d44a19fdecb7e51db1014d99da995085 · parent 8921cae64f
· browse this tree
Ximianth, 2026-07-30 11:10:44 UTC
Caught live in a browser after deploy: the prepended theme block lost to the embedded stylesheet's own :root --accent, because at equal specificity the LATER declaration wins. The stylesheet test asserted presence and position but position was asserted the wrong way around; it now requires the override at the end, and was watched failing against the prepend order.
diff --git a/serve.go b/serve.go index b464ed0..01bd142 100644 --- a/serve.go +++ b/serve.go @@ -107,10 +107,11 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // keeping it distinct from any configured mount name. if r.URL.Path == "/-/style.css" { w.Header().Set("Content-Type", "text/css; charset=utf-8") - // The theme's :root block precedes the embedded stylesheet, - // so its --accent wins over the stylesheet's default by cascade order. - w.Write(s.theme.CSS) + // The theme's :root block follows the embedded stylesheet: + // at equal specificity the later declaration wins, + // so appending is what lets the theme's --accent override the stylesheet's default. w.Write(styleCSS) + w.Write(s.theme.CSS) return } diff --git a/theme.go b/theme.go index abb3c74..ccf8209 100644 --- a/theme.go +++ b/theme.go @@ -15,7 +15,7 @@ import ( // theme is one host's visual identity, computed once at startup. type theme struct { Name string // the seed itself, shown in the nav next to the site name - CSS []byte // ":root" accent override, prepended to the stylesheet by the /-/style.css handler + CSS []byte // ":root" accent override, appended after the stylesheet by the /-/style.css handler } func newTheme(seed string) theme { diff --git a/theme_test.go b/theme_test.go index 571ee0e..5a9fc7a 100644 --- a/theme_test.go +++ b/theme_test.go @@ -57,8 +57,10 @@ func TestHostLabel(t *testing.T) { } } -// TestStylesheetCarriesThemeAccent checks that /-/style.css leads with the -// computed :root override and still contains the embedded stylesheet after it. +// TestStylesheetCarriesThemeAccent checks that /-/style.css ends with the +// computed :root override, after the embedded stylesheet: +// at equal specificity the later declaration wins, +// so appending (not prepending) is what makes the theme accent take effect. func TestStylesheetCarriesThemeAccent(t *testing.T) { rec := get(t, newTestServer(t), "/-/style.css") if rec.Code != http.StatusOK { @@ -67,11 +69,11 @@ func TestStylesheetCarriesThemeAccent(t *testing.T) { body := rec.Body.String() // "testhost" is the seed newTestServer uses; it hashes to hue 351, lightness 35%. want := ":root { --accent: hsl(351 70% 35%); }\n" - if !strings.HasPrefix(body, want) { - t.Errorf("stylesheet does not start with theme override %q; head: %q", want, body[:min(len(body), 120)]) + if !strings.HasSuffix(body, want) { + t.Errorf("stylesheet does not end with theme override %q; tail: %q", want, body[max(0, len(body)-120):]) } if !strings.Contains(body, "--paper") { - t.Errorf("embedded stylesheet missing after theme override") + t.Errorf("embedded stylesheet missing before theme override") } }