diff --git a/src/app/components/stream-header/RefreshMascot.tsx b/src/app/components/stream-header/RefreshMascot.tsx index 3459fcbd..5647881c 100644 --- a/src/app/components/stream-header/RefreshMascot.tsx +++ b/src/app/components/stream-header/RefreshMascot.tsx @@ -27,6 +27,12 @@ type RefreshMascotProps = { // never rises mid-dance. Null while the still poster (reduced-motion / // not-yet-revealed) is shown instead of the video. videoRef?: React.Ref; + // Called when the user taps the mascot — StreamHeader spawns a one-shot + // "echo" pulse ring on top of the ambient radar. A clean tap fires this; + // a drag instead bubbles to the curtain body gesture (it moves past the + // dead-zone → `preventDefault` → the browser suppresses the click), so the + // poke never fights the pull gesture. + onPoke?: () => void; }; // The card revealed below the tabs row by the curtain's `refresh` snap: @@ -49,7 +55,7 @@ type RefreshMascotProps = { // of the app reads this query one-shot too, and this card is native-only // + aria-hidden, so a mid-session OS toggle not re-evaluating here is // acceptable.) -export function RefreshMascot({ caption, revealing, videoRef }: RefreshMascotProps) { +export function RefreshMascot({ caption, revealing, videoRef, onPoke }: RefreshMascotProps) { const native = isNativePlatform(); const reducedMotion = useMemo( @@ -65,7 +71,15 @@ export function RefreshMascot({ caption, revealing, videoRef }: RefreshMascotPro const showVideo = revealing && !reducedMotion; return ( -