import { AnimatePresence, motion, useReducedMotion } from 'framer-motion' import { useState } from 'react' import { useBannerStack } from './BannerStackProvider' const PEEK_OFFSET = 8 const MAX_PEEKS = 2 const SPRING = { type: 'spring', stiffness: 300, damping: 30 } as const export const BannerStack = () => { const { banners } = useBannerStack() const [isHovered, setIsHovered] = useState(false) const reduceMotion = useReducedMotion() const activeBanners = banners.filter((b) => !b.isDismissed) if (activeBanners.length === 0) return null const [frontBanner, ...extraBanners] = activeBanners const peekCount = Math.min(extraBanners.length, MAX_PEEKS) // Deepest sliver first so the closer ones paint on top of it. const peeks = Array.from({ length: peekCount }, (_, i) => peekCount - i) const transition = reduceMotion ? { duration: 0 } : SPRING return ( setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} animate={{ y: isHovered ? -8 : 0 }} transition={transition} >
{!isHovered && peeks.map((depth) => ( ))} {frontBanner.content}
{isHovered && extraBanners.map((banner, index) => ( {banner.content} ))}
) }