Extra technical detail: randomness comes from Web Crypto (crypto.getRandomValues). I avoided server-side generation so the draw can work offline-ish and doesn’t require sending participant lists to a backend.
If anyone wants it, I can add a short “how randomness works” page + a reproducibility note.