fix(web): ship avatar-picker CSS inline so a stale styles.css can't break it (BUNYIP-408) #400
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/BUNYIP-408-avatar-picker-inline-css"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The bug (bug.jpg)
On the deployed Settings page the avatar control was a disaster: a page-filling green circle with the initial floating in the middle, the raw "Choose File / No file chosen" native input showing, both the no-JS "Upload" and the enhanced "Change photo" buttons visible, and a "selected file is empty" error.
Root cause
The component's structural CSS lived in the Tailwind-built
assets/styles.css- a separately-built, browser-cached file. The running app served fresh SSR HTML + inline JS but a stale cached stylesheet with none of the.avatar-picker*rules. With those rules missing, theabsolute inset-0fallback initial escaped its (now unsized, unpositioned) container and filled the card, the input clip never applied, and the enhancement-hiding never applied. (Confirming how easy this class is to hit: the three utilities the markup leaned on -sr-only,select-none, and a novelto-teal-600- are not even in the built stylesheet, because Tailwind purges unused classes.)Fix
Move every structural
.avatar-picker*/.avatar-slot__imgrule out ofinput.css/styles.cssand into an inline<style>in the SSR document head (avatar_picker::AVATAR_PICKER_CSS), exactly like the app's existing inline theme/toast scripts. Inline CSS ships with the always-fresh HTML, is never separately cached, and needs no Tailwind rebuild - the stale-stylesheet failure mode is gone.input.cssandassets/styles.cssare reverted to their pre-picker state, so this branch no longer touches the built stylesheet at all.Hardening so a missing stylesheet can never be catastrophic again: the letter fallback sizes with
h-full w-fullinside an inline-CSS-sized circle instead ofabsolute inset-0, and the markup drops the purgedsr-only/select-noneutilities (accessible name viaaria-label, non-select via inline CSS).Verification
just check-containergreen: fmt + clippy-D warnings+ all test binaries (116 web tests).🤖 Generated with Claude Code