From Reactions to Buttons: Re-architecting Giveaway Entries

Reaction-based giveaways were brittle and unaccountable. Switching to persistent button views with an entries collection gave us atomic state, deterministic rerolls, and a way out of Discord's reaction cache.

Atomic JSON Without the Tears

A small wrapper around os.replace plus an asyncio.Lock and a .bak recovery path got us crash-safe persistence without needing a database.

No-JS Safety for Reveal Animations

If your reveal classes start at opacity:0 and JS never runs, your content is invisible. Scoping the hidden state under html[data-reveal-ready] fixes the failure mode without giving up the animation.