"use client"; /** * RewardCelebration — a full-screen confetti celebration shown when the * devotee earns a streak gift. Centered card with the reward image, its * cosmic name, and symbolic meaning. Dismissing it acknowledges the gift * (via the caller) so it surfaces exactly once. * * Scrolls internally on small screens (max-h + overflow) and reads in both * themes (card/foreground tokens). Esc or backdrop-click closes. */ import { useEffect } from "react"; import { createPortal } from "react-dom"; import Image from "next/image"; import { motion } from "framer-motion"; import { Confetti } from "./confetti"; import type { SadhnaRewardGrant } from "@/lib/sadhna"; import { useMounted } from "@/lib/use-mounted"; export function RewardCelebration({ grant, onClose, }: { grant: SadhnaRewardGrant; onClose: () => void; }) { const mounted = useMounted(); // Esc to close + lock background scroll while open. useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; window.addEventListener("keydown", onKey); const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = prev; }; }, [onClose]); if (!mounted) return null; const r = grant.reward; return createPortal(

A gift for your sādhana

You've earned a reward!

For {grant.milestone} days of unbroken sādhana 🙏

{r.name}

{r.name}

{r.meaning ? (

{r.meaning}

) : null}
, document.body, ); }