'use client'; import React, { useEffect, useLayoutEffect, useRef } from 'react'; import Link from 'next/link'; import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; if (typeof window !== 'undefined') { gsap.registerPlugin(ScrollTrigger); } const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; interface Product { id: number; href: string; title: string; subtitle: string; description: string; accent: string; accentRgb: string; tags: string[]; } const PRODUCTS: Product[] = [ { id: 1, href: '/solutions/behavision', title: 'Behavision', subtitle: 'AI Powered Footfall Analytics', description: 'AI powered footfall analytics and behavioral intelligence. Understand how customers move, dwell, and engage, turning raw foot traffic into rich, actionable insights.', accent: '#f4be28', accentRgb: '244, 190, 40', tags: ['Footfall Tracking', 'Behavior Analysis'], }, { id: 2, href: '/solutions/spendsense', title: 'SpendSense', subtitle: 'Customer Spending Intelligence', description: 'Deep insights into customer spending patterns. Identify high-value segments, predict buying behaviour, and unlock incremental revenue hiding in plain sight.', accent: '#10B981', accentRgb: '16, 185, 129', tags: ['Spending Trends', 'Revenue Analytics', 'Customer Value'], }, { id: 3, href: '/solutions/dyscount', title: 'Dyscount', subtitle: 'Smart Discount Engine', description: 'Smart discount engine that maximises conversions without killing margins. Deliver the right offer to the right customer at exactly the right moment.', accent: '#EF4444', accentRgb: '239, 68, 68', tags: ['Smart Discounts', 'Offer Automation', 'Margin Protection'], }, { id: 4, href: '/solutions/loyaly-app', title: 'Identiq', subtitle: 'Consumer Loyalty Platform', description: 'Earn LYTs through daily logins and games, then redeem Lyts at real offline stores.', accent: '#f4be28', accentRgb: '244, 190, 40', tags: ['Daily Lyts', 'Game Based Offers', 'Offline Redemption'], }, ]; function ProductIcon({ id, accent }: { id: number; accent: string }) { if (id === 1) { return ( ); } if (id === 2) { return ( ); } if (id === 3) { return ( ); } return ( ); } /* Real product-preview visual per product — a believable mini-UI, not generic decoration */ function ProductVisual({ product }: { product: Product }) { const { id, accent, accentRgb } = product; // 1 — Behavision: footfall heatmap + live counter if (id === 1) { const cells = Array.from({ length: 48 }); return (
Live footfall 2,847
{cells.map((_, i) => { const intensity = Math.abs(Math.sin(i * 1.7) * Math.cos(i * 0.6)); const alpha = (0.08 + intensity * 0.7).toFixed(3); return (
); })}
{[['Peak', '6–8 PM'], ['Dwell', '14 min'], ['Zones', '12']].map(([k, v]) => (
{k}
{v}
))}
); } // 2 — SpendSense: spend trend chart if (id === 2) { const pts = [22, 30, 26, 42, 38, 54, 48, 66, 72]; const max = 80; const w = 280, h = 120; const path = pts.map((p, i) => `${(i / (pts.length - 1)) * w},${h - (p / max) * h}`).join(' '); return (
Avg basket value
₹1,240 +18%
{pts.map((p, i) => ( i === pts.length - 1 ? ( ) : null ))}
); } // 3 — Dyscount: smart offer + conversion uplift if (id === 3) { return (
{/* Live campaign badge, floating on the card edge */}
Live campaign
{/* Coupon-style offer card with perforated divider */}
Smart Offer
15% OFF
Targeted · high-intent shoppers
{/* Perforated tear-off edge */}
DYSCOUNT
Conversion uplift +41%
{/* Mini stat grid */}
{[['Margin protected', '100%'], ['Waste', '0'], ['Redemptions', '1.2k']].map(([k, v]) => (
{k}
{v}
))}
); } // 4 — Loyaly App: rewards card const REDEMPTIONS: [string, string, string][] = [ ['Starbucks', '+120', '#1e6b52'], ['Nike Store', '+85', '#374151'], ]; return (
{/* Streak badge, floating on the card edge */}
🔥 6-day streak
{/* Member header */}
L
LytsUp
Member since 2024
✦ GOLD
{/* LYTs balance card with progress to next tier */}
Lyts Balance
284
116 LYTs to Platinum
{/* Recent redemptions */}
Recently redeemed {REDEMPTIONS.map(([s, p, dot], i) => (
{s}
{p}
))}
); } /* ── Gallery card (horizontal panel) ──────────────────────────────── */ function ProductCard({ product, index }: { product: Product; index: number }) { return (
{/* ── Left content ── */}
0{product.id} {product.subtitle}

{product.title}

{product.description}

{product.tags.map((tag) => ( {tag} ))}
{ (e.currentTarget as HTMLAnchorElement).style.transform = 'scale(1.04)'; }} onMouseLeave={(e) => { (e.currentTarget as HTMLAnchorElement).style.transform = 'scale(1)'; }} > Explore {product.title}
{/* ── Right visual panel ── */}
); } interface ProductsSectionProps { isLoaded?: boolean; } export default function ProductsSection({ isLoaded = false }: ProductsSectionProps) { const sectionRef = useRef(null); const trackRef = useRef(null); const progressRef = useRef(null); const counterRef = useRef(null); useIsomorphicLayoutEffect(() => { if (!isLoaded) return; if (typeof window === 'undefined') return; const section = sectionRef.current; const track = trackRef.current; if (!section || !track) return; const mm = gsap.matchMedia(); // Desktop / tablet: pinned horizontal scroll mm.add('(min-width: 901px)', () => { const cards = gsap.utils.toArray('.products-card', track); const distance = () => Math.max(0, track.scrollWidth - section.clientWidth); const steps = Math.max(1, PRODUCTS.length - 1); // Depth cue: the card nearest the viewport centre sits at full scale/ // opacity, neighbours ease back slightly — makes the ride feel guided // rather than a flat strip sliding past, and the eased response // absorbs small scrub jitter instead of showing it as a raw jump. const updateDepth = () => { const centerX = section.clientWidth / 2; cards.forEach((card) => { const trackX = Number(gsap.getProperty(track, 'x', 'px')); const cardCenter = card.offsetLeft + card.offsetWidth / 2 + trackX; const dist = Math.abs(cardCenter - centerX); const norm = gsap.utils.clamp(0, 1, dist / (section.clientWidth * 0.62)); gsap.set(card, { scale: 1 - norm * 0.07, opacity: 1 - norm * 0.32 }); }); }; const tween = gsap.to(track, { x: () => -distance(), ease: 'none', scrollTrigger: { trigger: section, start: 'top top', end: () => `+=${distance()}`, pin: true, pinSpacing: true, anticipatePin: 1, scrub: 0.4, invalidateOnRefresh: true, refreshPriority: 5, snap: { snapTo: (value) => Math.round(value * steps) / steps, duration: { min: 0.2, max: 0.5 }, ease: 'power2.inOut', }, onUpdate: (self) => { if (progressRef.current) progressRef.current.style.transform = `scaleX(${self.progress})`; if (counterRef.current) { const idx = Math.min(PRODUCTS.length, Math.max(1, Math.round(self.progress * steps) + 1)); counterRef.current.textContent = `0${idx}`; } updateDepth(); }, }, }); updateDepth(); ScrollTrigger.refresh(); return () => { tween.scrollTrigger?.kill(); tween.kill(); gsap.set(track, { clearProps: 'transform' }); gsap.set(cards, { clearProps: 'scale,opacity' }); }; }); return () => mm.revert(); }, [isLoaded]); return (
{/* ambient glow */}
{/* Heading (fixed within the pinned viewport) */}
Platform

Four agents.{' '} One AI.

Powering every stage of the retail journey with intelligent AI solutions.

Unified into one platform 04
{/* Horizontal track */}
{PRODUCTS.map((product, index) => ( ))}
{/* Progress bar + counter */}
01
0{PRODUCTS.length}
); }