diff --git a/app/components/WishlistButton.tsx b/app/components/WishlistButton.tsx index 0675609..bfd41e9 100644 --- a/app/components/WishlistButton.tsx +++ b/app/components/WishlistButton.tsx @@ -26,10 +26,16 @@ export function WishlistButton({ * filled heart stays as a permanent status indicator) — right for a * multi-card grid (ProductGrid.tsx), where a heart on every single card * reads as visual noise. Relies on the parent card already carrying - * `group`/`focus-within` (see ProductGrid.tsx). Always visible on - * coarse-pointer (touch) devices regardless of hover/focus state — + * `group`/`focus-within` (see ProductGrid.tsx). + * + * On coarse-pointer (touch) devices, hover-reveal can't work at all — * touch has no persistent `:hover`, so a tap on the card never reliably - * reveals a `group-hover`-gated element the way a mouse hover does. */ + * reveals a `group-hover`-gated element the way a mouse hover does. + * Rather than falling back to "always visible at full size" (which + * recreates the exact "a heart on every card" visual noise this mode + * exists to avoid), touch devices get a smaller, backgroundless variant + * instead — present and tappable everywhere, but visually quiet enough + * not to read as a wall of hearts. */ revealOnHover?: boolean; }) { const { isWishlisted, toggle } = useWishlist(); @@ -62,11 +68,17 @@ export function WishlistButton({ disabled={pending} className={`flex h-9 w-9 items-center justify-center rounded-full bg-bg-base/90 backdrop-blur-sm transition-all active:scale-90 disabled:opacity-60 ${ revealOnHover && !wishlisted - ? "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 pointer-coarse:opacity-100" + ? "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 pointer-coarse:opacity-100 pointer-coarse:h-7 pointer-coarse:w-7 pointer-coarse:bg-transparent pointer-coarse:backdrop-blur-none" : "" } ${className}`} > - +