/** * MapSkeletonPins * ───────────────────────────────────────────────────────────────────────────── * A tasteful "spots are loading" overlay shown ONLY on a genuinely cold, empty * map (no cached spots yet + still fetching). Instead of a blank map that reads * as broken, we scatter a few softly-pulsing ghost pins in the SkateSpots pin * shape, so the moment reads as "finding spots near you…". * * It's purely decorative and non-interactive (`pointer-events-none`), sits above * the tiles but below every real control, and fully respects reduced-motion. * The instant real spots arrive the parent unmounts this — no layout shift. */ import { useTranslation } from '@/contexts/language'; interface Ghost { /** left/top as viewport percentages so it scales on any screen. */ left: number; top: number; /** teardrop scale + animation delay for an organic, staggered feel. */ scale: number; delay: number; } // Hand-placed so they feel scattered-but-balanced (not a rigid grid). const GHOSTS: Ghost[] = [ { left: 22, top: 34, scale: 1.0, delay: 0 }, { left: 48, top: 22, scale: 0.82, delay: 0.35 }, { left: 71, top: 38, scale: 1.1, delay: 0.15 }, { left: 34, top: 58, scale: 0.9, delay: 0.6 }, { left: 62, top: 62, scale: 1.0, delay: 0.45 }, { left: 82, top: 66, scale: 0.78, delay: 0.8 }, ]; export function MapSkeletonPins() { const { t } = useTranslation(); return (