import React, { useEffect } from "react"; import { createPortal } from "react-dom"; import confetti from "canvas-confetti"; import { stylesTokens } from "../styles/theme"; export default function WinnerCelebration({ open, winnerName, onClose }) { useEffect(() => { if (!open) return; // Scroll lock const prevOverflow = document.body.style.overflow; document.body.style.overflow = "hidden"; const reduceMotion = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (!reduceMotion) { const end = Date.now() + 4500; // WICHTIG: über dem Overlay rendern const TOP_Z = 2147483647; // hellere Farben damit’s auch auf dark overlay knallt const bright = ["#ffffff", "#ffd166", "#06d6a0", "#4cc9f0", "#f72585"]; // 2 große Bursts confetti({ particleCount: 170, spread: 95, startVelocity: 42, origin: { x: 0.12, y: 0.62 }, zIndex: TOP_Z, colors: bright, }); confetti({ particleCount: 170, spread: 95, startVelocity: 42, origin: { x: 0.88, y: 0.62 }, zIndex: TOP_Z, colors: bright, }); // “Rain” über die Zeit (function frame() { confetti({ particleCount: 8, spread: 75, startVelocity: 34, origin: { x: Math.random(), y: Math.random() * 0.18 }, scalar: 1.05, zIndex: TOP_Z, colors: bright, }); if (Date.now() < end) requestAnimationFrame(frame); })(); } const t = setTimeout(() => onClose?.(), 5500); return () => { clearTimeout(t); document.body.style.overflow = prevOverflow; }; }, [open, onClose]); useEffect(() => { if (!open) return; const onKey = (e) => e.key === "Escape" && onClose?.(); window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [open, onClose]); if (!open) return null; const node = (