Widen dicebear rings avatar palette to 2x+ distinct greens (emerald/green/teal only) #550

Closed
opened 2026-09-14 23:54:31 +00:00 by crueber · 3 comments
Owner

What's requested

Widen the dicebear "rings" figure palette from the current narrow emerald run to at least twice as many distinct greens, drawing from the emerald / green / teal families only, so seeded avatars are more distinguishable from each other while staying deterministic and theme-legible.

Evidence

internal/identity/avatar.go:89-99 — userAvatarRingColors currently carries 9 entries: Tailwind emerald-300 through emerald-950 (8 greens, all one hue family) plus black. All figures share the emerald hue, so two users' avatars frequently differ only in lightness steps, and at small render sizes many seeds are hard to tell apart. The background is fixed emerald-600 (userAvatarBackgroundColor, line 75), and figures land on that background, so the widening must stay within the green family the brand already owns.

Current list:

6ee7b7  emerald-300
34d399  emerald-400
10b981  emerald-500
059669  emerald-600 (background hue)
047857  emerald-700
065f46  emerald-800
064e3b  emerald-900
022c22  emerald-950
000000  black

Architecture notes

  • The palette rides the dicebear-go v10 "ringColor" core-library option (name+"Color" in the vendored dicebear-go/internal/render/options.go); a user-supplied list overrides the style collection per resolver.go's r.options.color(name). Widening is a change to one slice literal — no wire, store, or option plumbing changes.
  • Constraints that must survive the widening (all documented in the file header and pinned by tests):
    • Greens-family only: emerald / green / teal Tailwind runs. No blue-adjacent hues (cyan is out — it reads as blue at avatar size), no rainbow colors. The existing test TestGenerateGreensOnlyFigures asserts none of the 16 style-default rainbow colors appears in output across seeds; that test keeps pinning the boundary and must stay green unchanged.
    • Deterministic: the seed feeds the PRNG only; same email → identical SVG. Widening the palette changes renders (which is fine — avatars regenerate on demand/logins), but must not introduce any nondeterminism.
    • Theme-legible: the SVG is generated once server-side and served as static bytes, so it cannot theme-switch; every chosen color must read acceptably on both light and dark surfaces, and figures must stay readable against the emerald-600 background (059669). Skip or guard colors too close to the background hue (the current list already notes emerald-600 figures read via ring gaps — keep that note or its equivalent).
    • Keep black as the dark terminus so the lightness ramp still reaches full contrast.
  • "At least 2x" means ≥ 18 distinct figure colors. A concrete shape that satisfies it: emerald 300–950 (8) + green 300–950 (8) + teal 300–950 (8) + black = 25, ordered so the lightness ramp interleaves sensibly. Exact run choice is the implementer's call — the hard criteria are the count, the family restriction, and background/contrast legibility.
  • Comment on userAvatarRingColors should be updated to describe the widened palette and keep the "why greens-only" rationale (indigo-family style defaults clashed with the app-green background, #539).

Acceptance criteria

  • userAvatarRingColors contains at least 18 distinct figure colors, all from Tailwind emerald/green/teal runs, plus black retained
  • TestGenerateGreensOnlyFigures still passes unchanged (no rainbow defaults in output across seeds)
  • Avatars remain deterministic per seed (same email renders byte-identical SVG)
  • Generated figures remain legible against the emerald-600 background on both light and dark surfaces (spot-check a handful of seeds)
  • File header and userAvatarRingColors comment updated to match the new palette
  • Existing avatar tests (TestGenerateSeedAbsent, sanitization gates) untouched and green
## What's requested Widen the dicebear "rings" figure palette from the current narrow emerald run to at least twice as many distinct greens, drawing from the emerald / green / teal families only, so seeded avatars are more distinguishable from each other while staying deterministic and theme-legible. ## Evidence `internal/identity/avatar.go:89-99` — `userAvatarRingColors` currently carries 9 entries: Tailwind emerald-300 through emerald-950 (8 greens, all one hue family) plus black. All figures share the emerald hue, so two users' avatars frequently differ only in lightness steps, and at small render sizes many seeds are hard to tell apart. The background is fixed emerald-600 (`userAvatarBackgroundColor`, line 75), and figures land on that background, so the widening must stay within the green family the brand already owns. Current list: ``` 6ee7b7 emerald-300 34d399 emerald-400 10b981 emerald-500 059669 emerald-600 (background hue) 047857 emerald-700 065f46 emerald-800 064e3b emerald-900 022c22 emerald-950 000000 black ``` ## Architecture notes - The palette rides the dicebear-go v10 `"ringColor"` core-library option (name+"Color" in the vendored `dicebear-go/internal/render/options.go`); a user-supplied list overrides the style collection per resolver.go's `r.options.color(name)`. Widening is a change to one slice literal — no wire, store, or option plumbing changes. - Constraints that must survive the widening (all documented in the file header and pinned by tests): - **Greens-family only**: emerald / green / teal Tailwind runs. No blue-adjacent hues (cyan is out — it reads as blue at avatar size), no rainbow colors. The existing test `TestGenerateGreensOnlyFigures` asserts none of the 16 style-default rainbow colors appears in output across seeds; that test keeps pinning the boundary and must stay green unchanged. - **Deterministic**: the seed feeds the PRNG only; same email → identical SVG. Widening the palette changes renders (which is fine — avatars regenerate on demand/logins), but must not introduce any nondeterminism. - **Theme-legible**: the SVG is generated once server-side and served as static bytes, so it cannot theme-switch; every chosen color must read acceptably on both light and dark surfaces, and figures must stay readable against the emerald-600 background (`059669`). Skip or guard colors too close to the background hue (the current list already notes emerald-600 figures read via ring gaps — keep that note or its equivalent). - Keep black as the dark terminus so the lightness ramp still reaches full contrast. - "At least 2x" means ≥ 18 distinct figure colors. A concrete shape that satisfies it: emerald 300–950 (8) + green 300–950 (8) + teal 300–950 (8) + black = 25, ordered so the lightness ramp interleaves sensibly. Exact run choice is the implementer's call — the hard criteria are the count, the family restriction, and background/contrast legibility. - Comment on `userAvatarRingColors` should be updated to describe the widened palette and keep the "why greens-only" rationale (indigo-family style defaults clashed with the app-green background, #539). ## Acceptance criteria - [ ] `userAvatarRingColors` contains at least 18 distinct figure colors, all from Tailwind emerald/green/teal runs, plus black retained - [ ] `TestGenerateGreensOnlyFigures` still passes unchanged (no rainbow defaults in output across seeds) - [ ] Avatars remain deterministic per seed (same email renders byte-identical SVG) - [ ] Generated figures remain legible against the emerald-600 background on both light and dark surfaces (spot-check a handful of seeds) - [ ] File header and `userAvatarRingColors` comment updated to match the new palette - [ ] Existing avatar tests (`TestGenerateSeedAbsent`, sanitization gates) untouched and green
crueber added this to the v1 milestone 2026-09-14 23:54:39 +00:00
Author
Owner

Fix PR: #553 (branch fix/issue-550). Palette 9 -> 25 (emerald/green/teal 300-950 + black); all 6 acceptance criteria covered in PR description. Ready for review — not merging.

Fix PR: https://git.packden.us/crueber/walhub/pulls/553 (branch fix/issue-550). Palette 9 -> 25 (emerald/green/teal 300-950 + black); all 6 acceptance criteria covered in PR description. Ready for review — not merging.
Author
Owner

Review of PR #553 (fix/issue-550, commit e7d23ed) — verified in a scratch worktree; main worktree untouched. No browser drive (no UI/browser-facing change; renders inspected via test harness instead).

ACCEPTANCE CRITERIA (all 6 pass):

  1. Count: userAvatarRingColors (avatar.go:97-123) holds 25 entries, 25 distinct — 24 greens + black, >= 18 required. PASS.
  2. Real Tailwind shades: every hex checked against the authoritative upstream palette (tailwindlabs/tailwindcss v3.4.18 src/public/colors.js). Emerald run 6ee7b7/34d399/10b981/059669/047857/065f46/064e3b/022c22, green run 86efac/4ade80/22c55e/16a34a/15803d/166534/14532d/052e16, teal run 5eead4/2dd4bf/14b8a6/0d9488/0f766e/115e59/134e4a/042f2e — all 24 exact matches. (Note: local tailwindcss v4 theme.css expresses these in higher-chroma oklch that does not round-trip to v3 hex in sRGB, so v3 colors.js is the correct reference.) PASS.
  3. No blue-adjacent: zero cyan shades (67e8f9 family) present; teal is explicitly in-bounds per the issue. PASS.
  4. Black retained (000000 terminus, avatar.go:122). PASS.
  5. Background unchanged: userAvatarBackgroundColor still 059669 emerald-600 (avatar.go:75). PASS.
  6. Tests: TestGenerateGreensOnlyFigures unchanged (no diff on avatar_test.go) and green; determinism (TestGenerateDeterminism), seed-absent (TestGenerateSeedAbsent), sanitize gates (TestCheckAvatarSVG) all green. PASS.

DIVERSIFICATION SPOT-CHECK (temporary probe test, removed afterward): 6 seeds rendered — figures used spanned all three families (green-800 166534, green-500 22c55e, teal-400 2dd4bf, emerald-400 34d399) vs emerald-only before; background fill present in every SVG; same-seed re-render byte-identical. Tone-on-tone seeds (figure == 059669 bg) still occur and remain distinguishable by ring geometry — the documented accepted outcome. PASS.

HYGIENE: gofmt clean, go vet clean, go build ./... clean, full identity suite -race clean, coverage 95.6% (gate >= 95%). go.mod/go.sum untouched — no new deps (law 1). Docs decision appended in docs/features/01_identity_permissions.md in the same change (law 12); doc hex runs match the code exactly; header + palette comments updated. One nit, not blocking: the pre-existing #539 bullet's continuation lines got re-indented 2sp -> 3sp in the docs diff — renders identically, ignore.

No fixes needed; nothing pushed. MERGE RECOMMENDATION: ready to merge.

Review of PR #553 (fix/issue-550, commit e7d23ed) — verified in a scratch worktree; main worktree untouched. No browser drive (no UI/browser-facing change; renders inspected via test harness instead). ACCEPTANCE CRITERIA (all 6 pass): 1. Count: userAvatarRingColors (avatar.go:97-123) holds 25 entries, 25 distinct — 24 greens + black, >= 18 required. PASS. 2. Real Tailwind shades: every hex checked against the authoritative upstream palette (tailwindlabs/tailwindcss v3.4.18 src/public/colors.js). Emerald run 6ee7b7/34d399/10b981/059669/047857/065f46/064e3b/022c22, green run 86efac/4ade80/22c55e/16a34a/15803d/166534/14532d/052e16, teal run 5eead4/2dd4bf/14b8a6/0d9488/0f766e/115e59/134e4a/042f2e — all 24 exact matches. (Note: local tailwindcss v4 theme.css expresses these in higher-chroma oklch that does not round-trip to v3 hex in sRGB, so v3 colors.js is the correct reference.) PASS. 3. No blue-adjacent: zero cyan shades (67e8f9 family) present; teal is explicitly in-bounds per the issue. PASS. 4. Black retained (000000 terminus, avatar.go:122). PASS. 5. Background unchanged: userAvatarBackgroundColor still 059669 emerald-600 (avatar.go:75). PASS. 6. Tests: TestGenerateGreensOnlyFigures unchanged (no diff on avatar_test.go) and green; determinism (TestGenerateDeterminism), seed-absent (TestGenerateSeedAbsent), sanitize gates (TestCheckAvatarSVG) all green. PASS. DIVERSIFICATION SPOT-CHECK (temporary probe test, removed afterward): 6 seeds rendered — figures used spanned all three families (green-800 166534, green-500 22c55e, teal-400 2dd4bf, emerald-400 34d399) vs emerald-only before; background fill present in every SVG; same-seed re-render byte-identical. Tone-on-tone seeds (figure == 059669 bg) still occur and remain distinguishable by ring geometry — the documented accepted outcome. PASS. HYGIENE: gofmt clean, go vet clean, go build ./... clean, full identity suite -race clean, coverage 95.6% (gate >= 95%). go.mod/go.sum untouched — no new deps (law 1). Docs decision appended in docs/features/01_identity_permissions.md in the same change (law 12); doc hex runs match the code exactly; header + palette comments updated. One nit, not blocking: the pre-existing #539 bullet's continuation lines got re-indented 2sp -> 3sp in the docs diff — renders identically, ignore. No fixes needed; nothing pushed. MERGE RECOMMENDATION: ready to merge.
Author
Owner

Fixed by PR #553 (review clean — 25 distinct greens independently verified, rainbow test intact, distinctness spot-checked), merged. Closing.

Fixed by PR #553 (review clean — 25 distinct greens independently verified, rainbow test intact, distinctness spot-checked), merged. Closing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crueber/walhub#550
No description provided.