vitrine

display: export ThemeHue for embedders composing accent artifacts

commit 1f54fea43dc8fa8086ad1a0b52e7b365697db7b0 · parent c714b15828 · browse this tree
Ximianth, 2026-10-30 14:26:08 UTC

diff --git a/display/theme.go b/display/theme.go
index 03d9521..6e20953 100644
--- a/display/theme.go
+++ b/display/theme.go
@@ -19,7 +19,7 @@ type Theme struct {
 }
 
 func NewTheme(seed string) Theme {
-	hue := themeHue(seed)
+	hue := ThemeHue(seed)
 	return Theme{
 		Name: seed,
 		CSS: []byte(fmt.Sprintf(
@@ -37,10 +37,12 @@ func HostLabel(hostname string) string {
 	return label
 }
 
-// themeHue hashes a theme seed to a hue in [0, 360) via FNV-1a.
+// ThemeHue hashes a theme seed to a hue in [0, 360) via FNV-1a.
 // Deterministic and pinned by tests:
 // changing this function silently repaints every deployed host.
-func themeHue(seed string) int {
+// Exported so embedders composing extra accent-colored artifacts (favicons, badges)
+// can stay on the same wheel without duplicating the hash.
+func ThemeHue(seed string) int {
 	h := fnv.New32a()
 	h.Write([]byte(seed))
 	return int(h.Sum32() % 360)
diff --git a/display/theme_test.go b/display/theme_test.go
index 1ca26f2..ebb5428 100644
--- a/display/theme_test.go
+++ b/display/theme_test.go
@@ -16,8 +16,8 @@ func TestThemeHuePinned(t *testing.T) {
 		"":            61,
 	}
 	for seed, want := range cases {
-		if got := themeHue(seed); got != want {
-			t.Errorf("themeHue(%q) = %d, want %d", seed, got, want)
+		if got := ThemeHue(seed); got != want {
+			t.Errorf("ThemeHue(%q) = %d, want %d", seed, got, want)
 		}
 	}
 }