Definitive bug fix release
Every reported issue from v1.5.37 is fixed. Root causes found and addressed, not patched over.
Activity feed privacy — FIXED FOR REAL
Root cause: JSON key casing mismatch. The save function sent camelCase keys but the C# model expected PascalCase. Even with "both casings" approach, stale keys in the merged payload caused ambiguity. Fix: both save functions now delete old keys before setting canonical values, and all preference properties have explicit [JsonPropertyName] attributes.
Spoiler mode — NOW WORKS ON ALL ENDPOINTS
Root cause: GetBadge() (single badge endpoint) never applied spoiler logic — only the list endpoint did. Locked badge descriptions now show "???" everywhere.
Badge rarity borders — CLASS NAME FIXED
Root cause: light theme CSS targeted .rarity-common-border but the actual JS class is .ab-r-common-border. All 6 tiers fixed.
Rank progress bar — VISIBLE IN LIGHT MODE
Added an ID to the track element so the light theme can override the inline rgba(255,255,255,0.12) background.
Welcome message — WORKING
New GET /public-config endpoint (no admin auth) serves the welcome message. Banner displays at the top of the achievements page when a message is set.
"CASSETTE" / "VINYL" text — FIXED
Invalid Material Icons names (custom badge icons) rendered as literal text. Added a 350+ icon allowlist — unknown icons fall back to the trophy icon.
Light theme — ALL TEXT VISIBLE
Every secondary text color bumped to rgba(0,0,0,0.6) minimum. Fixed: showcase cards, equipped empty state, profile card link, hero icons, inline-style progress bar tracks.