"use client"; import * as React from "react"; const SURFACE = "[data-glow]"; /** * BitGlow: a light that follows the pointer across every `data-glow` surface. * It only publishes the pointer position as `--gx` / `--gy` on those surfaces; * the light itself is drawn in CSS by a `.bit-glow` child (see globals.css). * Purely decorative, and off when reduced motion is requested. */ export const BitGlow: React.FC = () => { React.useEffect(() => { if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; let frame = 0; let latest: PointerEvent | null = null; const publish = () => { frame = 0; if (!latest) return; const { clientX, clientY, target } = latest; let surface = target instanceof Element ? target.closest(SURFACE) : null; // Surfaces nest (a button inside a dark section): each one gets its own position. while (surface) { const rect = surface.getBoundingClientRect(); surface.style.setProperty("--gx", `${clientX - rect.left}px`); surface.style.setProperty("--gy", `${clientY - rect.top}px`); surface = surface.parentElement?.closest(SURFACE) ?? null; } }; const onPointerMove = (event: PointerEvent) => { latest = event; if (frame === 0) frame = window.requestAnimationFrame(publish); }; window.addEventListener("pointermove", onPointerMove, { passive: true }); return () => { window.removeEventListener("pointermove", onPointerMove); if (frame !== 0) window.cancelAnimationFrame(frame); }; }, []); return null; };