Goal: Create an "XP Bar" radio group animation.
Visual behavior: A gaming radio group with 3 options (Novice/Adept/Master), each rendered as a card with a label, XP reward text, and a 4px-tall XP progress bar. On selection, the bar fills from 0%→100% width over 600ms with a glowing gradient (CSS xp-fill keyframe). Small spark particles pop at the right edge of the bar (CSS xp-spark: translate+scale+fade). Each option has a distinct color (green/blue/purple). The card background tints to the option's color when selected.
Technique: React useState tracks selected option and a fillKey counter. fillKey increments on each selection to force remount of the fill bar and sparks, restarting their animations. CSS custom properties (--sx, --sy) define spark directions. CSS @keyframes drive bar fill and spark pop. Inline styles drive card tinting. No library dependencies.
Accessibility: Hidden native <input type="radio"> per option, shared name. Keyboard-navigable. Bar fill and spark animations skipped under prefers-reduced-motion.
My stack: {{USER_STACK}}
My styling: {{USER_STYLING}}
My constraints: {{USER_CONSTRAINTS}}
Return a single self-contained component. Do not introduce dependencies beyond what I've listed.
Paste into Claude, ChatGPT, or Cursor. Edit YOUR_STACK /
YOUR_STYLING / YOUR_CONSTRAINTS before sending.