'use client'; import React, { useEffect, useLayoutEffect, useRef } from 'react'; import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; import FpIcon, { type FpIconName } from './FpIcons'; if (typeof window !== 'undefined') gsap.registerPlugin(ScrollTrigger); const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; /* Logical viewport the embedded LytsUp web app is designed against — see EarnRewardsSection for the full rationale. */ const DESIGN_HEIGHT = 844; const NOTCH_STRIP = 32; export default function SpendAnywhereSection() { const panelRef = useRef(null); const phoneRef = useRef(null); // Phone mockup rises in from the bottom as the section scrolls into view useIsomorphicLayoutEffect(() => { if (typeof window === 'undefined') return; const section = panelRef.current; const phone = phoneRef.current; if (!section || !phone) return; const ctx = gsap.context(() => { gsap.fromTo(phone, { y: 160, opacity: 0 }, { y: 0, opacity: 1, ease: 'power2.out', scrollTrigger: { trigger: section, start: 'top 92%', end: 'top 25%', scrub: 1.2 }, } ); }, section); return () => ctx.revert(); }, []); return (
{/* Left — headline + copy */}
Spend03

Your Lyts. Your Choice.

Walk into a participating brand or store. Choose what you love. Tell the cashier you're paying with Lyts. Enjoy instant savings, no waiting, no cashback, no complicated redemption.

{([ { label: 'No waiting', icon: 'bolt' }, { label: 'No cashback', icon: 'ban' }, { label: 'No complicated redemption', icon: 'check' }, ] as { label: string; icon: FpIconName }[]).map((tag) => (
{tag.label}
))}

One Wallet. Thousands of Lyts.

{/* Right — live LytsUp Spend preview embedded in a real phone frame */}
{/* Screen — height is derived, not a fixed aspect ratio: see EarnRewardsSection. A hard 9/19.5 left the iframe ~47 logical px short once the notch strip was subtracted, clipping the app's bottom nav; this lands it on exactly 390x844 at every breakpoint. */}
{/* Dynamic island */}
{/* Safe area — reserves the notch strip above the app's top bar */}
{/* The embed is a responsive Flutter web app. We render it at a comfortable logical width (390px) and scale it down to fill the screen exactly, so the UI stays proportioned as designed instead of cramped at ~260px. The iframe width is exactly the design width (no horizontal overscan) so the app lays out edge-to-edge and stays centered — nothing on the right (e.g. the Profile tab) gets clipped. Flutter's thin right-edge list scrollbar is hidden by a slim mask strip rather than by cutting into the layout. */}