updated mobile view

This commit is contained in:
R-Bharathraj
2026-07-15 13:16:11 +05:30
parent 89b0089457
commit 85e0f6eb63
25 changed files with 572 additions and 219 deletions

View File

@@ -29,22 +29,22 @@ const nextConfig: NextConfig = {
},
{
source: '/loyaly_php/use_cases.php',
destination: '/use_cases',
destination: '/for_business',
permanent: true,
},
{
source: '/use_cases.php',
destination: '/use_cases',
destination: '/for_business',
permanent: true,
},
{
source: '/loyaly_php/solutions_page.php',
destination: '/solutions_page',
destination: '/meet_the_agents',
permanent: true,
},
{
source: '/solutions_page.php',
destination: '/solutions_page',
destination: '/meet_the_agents',
permanent: true,
},
{

View File

@@ -1,6 +1,6 @@
'use client';
import React, { useState } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { useReveal } from '@/hooks/useReveal';
@@ -28,7 +28,7 @@ export default function AboutUsPage() {
minHeight: '100vh', background: 'radial-gradient(ellipse 120% 90% at 22% 0%, #3a2b5e 0%, #251c40 38%, #1a1530 100%)',
display: 'flex', alignItems: 'center',
padding: '120px 8% 80px',
margin: '20px', borderRadius: '32px',
margin: 'var(--hero-top) var(--sec-gutter) var(--sec-gap) var(--sec-gutter)', borderRadius: '32px',
position: 'relative', overflow: 'hidden',
}}>
{/* Background photo */}
@@ -57,7 +57,7 @@ export default function AboutUsPage() {
</section>
{/* ── OUR STORY ── */}
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<div className="au-story-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8vw', alignItems: 'start' }}>
<Reveal>
<SectionEyebrow variant="line" style={{ marginBottom: 24 }}>Our Story</SectionEyebrow>
@@ -77,7 +77,7 @@ export default function AboutUsPage() {
</section>
{/* ── MISSION & VISION ── */}
<section style={{ position: 'relative', overflow: 'hidden', padding: 'clamp(60px, 9vh, 104px) 8%', background: '#07070d', margin: '0 20px 20px', borderRadius: 28 }}>
<section style={{ position: 'relative', overflow: 'hidden', padding: 'clamp(60px, 9vh, 104px) 8%', background: '#07070d', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 28 }}>
{/* Ambient top glow */}
<div aria-hidden style={{ position: 'absolute', top: '-24%', left: '50%', transform: 'translateX(-50%)', width: 680, height: 420, background: 'radial-gradient(ellipse, rgba(244,190,40,0.12) 0%, transparent 70%)', pointerEvents: 'none' }} />
@@ -209,7 +209,7 @@ export default function AboutUsPage() {
</section>
{/* ── MARKET OPPORTUNITY ── */}
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<div className="au-market-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8vw', alignItems: 'start' }}>
<Reveal>
<SectionEyebrow variant="pill" style={{ marginBottom: 24 }}>Market Opportunity</SectionEyebrow>
@@ -243,7 +243,7 @@ export default function AboutUsPage() {
{/* ── CLOSE: POINT TO THE CREW ── */}
<section style={{
padding: '160px 8%', background: '#f4be28',
margin: '0 20px 20px', borderRadius: 24,
margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24,
display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center',
position: 'relative', overflow: 'hidden',
}}>
@@ -253,7 +253,7 @@ export default function AboutUsPage() {
"We're not just building a product. We're redefining retail."
</p>
<div style={{ display: 'flex', gap: 14, flexWrap: 'wrap', justifyContent: 'center', position: 'relative', zIndex: 2 }}>
<Link href="/solutions_page" style={{
<Link href="/meet_the_agents" style={{
display: 'inline-flex', alignItems: 'center', gap: 10,
padding: '18px 44px', background: '#111', color: '#f4be28',
fontSize: 16, fontWeight: 800, borderRadius: 100, textDecoration: 'none',
@@ -370,11 +370,37 @@ function TeamCarousel() {
const [touchEnd, setTouchEnd] = useState<number | null>(null);
const { ref, visible } = useReveal();
const count = TEAM_MEMBERS.length;
// Dimensions matching premium layout
const CARD_W = 320;
const CARD_GAP = 24;
const STEP = CARD_W + CARD_GAP;
// The card width (and gap) is responsive via CSS media queries, so the slide
// distance can't be a hard-coded constant. We measure the real pixel offset
// between the first two cards and recompute it on resize — this keeps the
// active card perfectly centered at every breakpoint.
const trackRef = useRef<HTMLDivElement>(null);
const [step, setStep] = useState(CARD_W + CARD_GAP);
useEffect(() => {
const measure = () => {
const track = trackRef.current;
if (!track) return;
const cards = track.querySelectorAll<HTMLElement>('.team-card');
if (cards.length >= 2) {
const delta = cards[1].offsetLeft - cards[0].offsetLeft;
if (delta > 0) setStep(delta);
}
};
measure();
// Re-measure once layout has settled (fonts, media queries, reveal) so the
// slide distance always matches the real rendered card width.
const raf = requestAnimationFrame(() => requestAnimationFrame(measure));
window.addEventListener('resize', measure);
return () => {
cancelAnimationFrame(raf);
window.removeEventListener('resize', measure);
};
}, [visible]);
const go = (dir: number) => setActive(a => Math.min(count - 1, Math.max(0, a + dir)));
@@ -405,10 +431,10 @@ function TeamCarousel() {
const indexStr = String(active + 1).padStart(2, '0');
return (
<section ref={ref as React.RefObject<HTMLElement>} style={{
<section ref={ref as React.RefObject<HTMLElement>} className="team-section" style={{
padding: '110px 0 120px',
background: '#07070d',
margin: '0 20px 20px',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: 24,
overflow: 'hidden',
position: 'relative'
@@ -602,8 +628,10 @@ function TeamCarousel() {
{/* Right Column: Carousel Stage */}
<div className="team-stage" style={{ flex: 1, minWidth: 0, position: 'relative' }}>
{/* Main viewport */}
<div style={{ position: 'relative', height: 510, padding: '20px 10px', margin: '-20px -10px', overflow: 'hidden' }}>
<div className="team-viewport" style={{ position: 'relative', height: 510, padding: '20px 10px', margin: '-20px -10px', overflow: 'hidden' }}>
<div
ref={trackRef}
className="team-track"
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
@@ -612,7 +640,7 @@ function TeamCarousel() {
gap: CARD_GAP,
alignItems: 'center',
height: '100%',
transform: `translateX(${-active * STEP}px)`,
transform: `translateX(${-active * step}px)`,
transition: 'transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1)',
}}
>
@@ -647,7 +675,7 @@ function TeamCarousel() {
}}
>
{/* Top Left Number Tag */}
<div style={{
<div className="team-num-tag" style={{
position: 'absolute',
top: 20,
left: 20,
@@ -850,7 +878,7 @@ function TeamCarousel() {
)}
{/* Bottom controls: arrows and page counter */}
<div style={{ display: 'flex', alignItems: 'center', gap: 16, marginTop: 40, ...enter(4) }}>
<div className="team-controls" style={{ display: 'flex', alignItems: 'center', gap: 16, marginTop: 40, ...enter(4) }}>
{/* Prev button */}
<button
onClick={() => go(-1)}
@@ -972,6 +1000,28 @@ function TeamCarousel() {
to { transform: translateX(120%); }
}
/* ── Premium active-card finish: a layered depth shadow, a faint gold
rim, and a soft light spilling from the top edge. ── */
.team-card.is-active {
box-shadow:
0 34px 70px -20px rgba(0,0,0,0.9),
0 0 0 1px rgba(244,190,40,0.35),
0 0 46px -6px rgba(244,190,40,0.28) !important;
}
.team-card.is-active::after {
content: '';
position: absolute;
inset: 0;
z-index: 3;
pointer-events: none;
border-radius: 18px;
background: radial-gradient(130% 55% at 50% -8%, rgba(244,190,40,0.16) 0%, transparent 55%);
}
/* Gold accent line under the active thumbnail number tag reads richer */
.team-card.is-active .team-num-tag {
box-shadow: 0 6px 16px -4px rgba(244,190,40,0.5);
}
@media (max-width: 1024px) {
.team-wrap {
padding: 0 40px !important;
@@ -982,12 +1032,21 @@ function TeamCarousel() {
}
}
/* ────────────────────────────────────────────────────────────
MOBILE / TABLET — heading stacks above a centered card
carousel. The slide distance is measured in JS, so overriding
the card width here (with !important, to beat the inline style)
automatically keeps the active card centered.
──────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
.team-section {
padding: 84px 0 92px !important;
}
.team-wrap {
flex-direction: column !important;
gap: 48px !important;
gap: 44px !important;
align-items: stretch !important;
padding: 0 32px !important;
padding: 0 28px !important;
}
.team-head {
width: 100% !important;
@@ -996,10 +1055,10 @@ function TeamCarousel() {
}
.team-purpose-badge {
align-self: center !important;
max-width: 320px;
max-width: 340px;
}
.team-top-dots {
display: none !important; /* Hide top-right dots on mobile, they overflow */
display: none !important; /* moved to the bottom counter row on mobile */
}
.team-stage {
width: 100% !important;
@@ -1007,16 +1066,52 @@ function TeamCarousel() {
flex-direction: column;
align-items: center;
}
/* Centre the card row in the stage with a symmetric peek of the
neighbouring card on both sides. */
.team-viewport {
height: 452px !important;
width: 100% !important;
padding: 20px calc((100% - min(300px, 80vw)) / 2) !important;
margin: -20px 0 !important;
}
.team-track {
gap: 18px !important;
}
.team-card {
width: min(300px, 80vw) !important;
height: 412px !important;
}
.team-card.is-active {
height: 452px !important;
}
.team-next-overlay {
right: 0px !important;
display: none !important; /* redundant with the bottom Next control */
}
/* Bottom controls: centre them under the carousel */
.team-controls {
justify-content: center !important;
margin-top: 28px !important;
}
}
@media (max-width: 480px) {
.team-wrap {
padding: 0 20px !important;
.team-section {
padding: 64px 0 72px !important;
}
.team-next-overlay {
display: none !important; /* Hide overlay button on very small screens */
.team-wrap {
padding: 0 16px !important;
gap: 36px !important;
}
.team-viewport {
height: 424px !important;
padding: 20px calc((100% - min(272px, 82vw)) / 2) !important;
}
.team-card {
width: min(272px, 82vw) !important;
height: 388px !important;
}
.team-card.is-active {
height: 424px !important;
}
}
@media (prefers-reduced-motion: reduce) {

View File

@@ -101,7 +101,7 @@ export default function BlogMainPage() {
{/* ── HERO ── */}
<section style={{
padding: '120px 8% 90px', background: 'radial-gradient(ellipse 120% 90% at 50% 0%, #2c2350 0%, #211c3e 38%, #181429 100%)',
margin: '20px', borderRadius: '32px',
margin: 'var(--hero-top) var(--sec-gutter) var(--sec-gap) var(--sec-gutter)', borderRadius: '32px',
position: 'relative', overflow: 'hidden',
}}>
{/* Background photo */}
@@ -296,7 +296,7 @@ export default function BlogMainPage() {
</section>
{/* ── NEWSLETTER CTA ── */}
<section style={{ padding: 0, background: '#07070d', margin: '0 20px 20px', borderRadius: 28, overflow: 'hidden', position: 'relative' }}>
<section style={{ padding: 0, background: '#07070d', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 28, overflow: 'hidden', position: 'relative' }}>
<div style={{ position: 'absolute', top: '20%', left: '10%', width: 420, height: 420, borderRadius: '50%', background: 'radial-gradient(circle,rgba(244,190,40,0.1) 0%,transparent 70%)', pointerEvents: 'none' }} />
<div style={{ position: 'absolute', bottom: '-10%', right: '5%', width: 380, height: 380, borderRadius: '50%', background: 'radial-gradient(circle,rgba(167,139,250,0.08) 0%,transparent 70%)', pointerEvents: 'none' }} />
<div style={{ position: 'absolute', inset: 0, backgroundImage: 'linear-gradient(rgba(244,190,40,0.025) 1px,transparent 1px),linear-gradient(90deg,rgba(244,190,40,0.025) 1px,transparent 1px)', backgroundSize: '56px 56px', pointerEvents: 'none' }} />

View File

@@ -43,7 +43,7 @@ export default function BlogSinglePage() {
{/* Hero */}
<section style={{
padding: '140px 8% 100px', background: 'radial-gradient(ellipse 120% 90% at 50% 0%, #2c2350 0%, #211c3e 38%, #181429 100%)',
margin: '20px', borderRadius: '32px',
margin: 'var(--hero-top) var(--sec-gutter) var(--sec-gap) var(--sec-gutter)', borderRadius: '32px',
position: 'relative', overflow: 'hidden',
}}>
{/* Background photo */}
@@ -78,7 +78,7 @@ export default function BlogSinglePage() {
</section>
{/* Article body */}
<section style={{ padding: '80px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section style={{ padding: '80px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<div style={{ maxWidth: 740, margin: '0 auto' }}>
{ARTICLE.sections.map((s, i) => (
<div key={i} style={{ marginBottom: 56 }}>
@@ -109,7 +109,7 @@ export default function BlogSinglePage() {
</section>
{/* CTA */}
<section style={{ padding: '80px 8%', background: '#07070d', margin: '0 20px 20px', borderRadius: 24, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 32 }}>
<section style={{ padding: '80px 8%', background: '#07070d', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 32 }}>
<div>
<h2 style={{ fontSize: 'clamp(28px, 3.5vw, 52px)', fontWeight: 800, letterSpacing: '-0.04em', color: '#fff', margin: '0 0 12px', fontFamily: 'Sora, sans-serif' }}>
Ready to see your store&apos;s data?
@@ -122,7 +122,7 @@ export default function BlogSinglePage() {
</section>
{/* Related articles */}
<section style={{ padding: '80px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section style={{ padding: '80px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: '#f4be28', fontFamily: 'Sora, sans-serif', marginBottom: 32 }}>More from Market Insights</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(240px,1fr))', gap: 16 }}>
{ARTICLE.relatedArticles.map((a) => (

View File

@@ -15,7 +15,7 @@ export default function ContactsPage() {
{/* ── HERO ── */}
<section style={{
padding: '120px 8% 100px', background: 'radial-gradient(ellipse 120% 90% at 78% 0%, #2e2350 0%, #221b3e 38%, #191529 100%)',
margin: '20px', borderRadius: '32px',
margin: 'var(--hero-top) var(--sec-gutter) var(--sec-gap) var(--sec-gutter)', borderRadius: '32px',
position: 'relative', overflow: 'hidden',
display: 'flex', alignItems: 'center',
}}>

View File

@@ -51,7 +51,7 @@ export default function FAQPage() {
{/* Hero */}
<section style={{
padding: '140px 8% 100px', background: 'radial-gradient(ellipse 120% 90% at 50% 0%, #2c2350 0%, #211c3e 38%, #181429 100%)',
margin: '20px', borderRadius: '32px',
margin: 'var(--hero-top) var(--sec-gutter) var(--sec-gap) var(--sec-gutter)', borderRadius: '32px',
position: 'relative', overflow: 'hidden',
display: 'flex', alignItems: 'center',
}}>
@@ -81,7 +81,7 @@ export default function FAQPage() {
{/* FAQ sections */}
{FAQS.map((section) => (
<section key={section.category} style={{ padding: '80px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section key={section.category} style={{ padding: '80px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
{/* Category header */}
<div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 40 }}>
<div style={{ width: 10, height: 10, borderRadius: '50%', background: section.color, boxShadow: `0 0 14px ${section.color}` }} />
@@ -133,7 +133,7 @@ export default function FAQPage() {
))}
{/* CTA */}
<section style={{ padding: '80px 8%', background: '#f4be28', margin: '0 20px 20px', borderRadius: 24, textAlign: 'center' }}>
<section style={{ padding: '80px 8%', background: '#f4be28', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24, textAlign: 'center' }}>
<h2 style={{ fontSize: 'clamp(28px, 4vw, 56px)', fontWeight: 800, letterSpacing: '-0.04em', color: '#111', margin: '0 0 16px', fontFamily: 'Sora, sans-serif' }}>Still have questions?</h2>
<p style={{ fontSize: 16, color: 'rgba(0,0,0,0.55)', fontFamily: 'Sora, sans-serif', margin: '0 0 36px' }}>Our team is happy to help get in touch and we&apos;ll respond within one business day.</p>
<Link href="/contacts" style={{ display: 'inline-flex', alignItems: 'center', gap: 10, padding: '16px 40px', background: '#111', color: '#f4be28', fontSize: 15, fontWeight: 800, borderRadius: 100, textDecoration: 'none', fontFamily: 'Sora, sans-serif' }}>

View File

@@ -134,7 +134,7 @@ export default function ForBusinessPage() {
minHeight: '100vh', background: 'radial-gradient(ellipse 120% 90% at 30% 0%, #2c2350 0%, #211c3e 38%, #181429 100%)',
display: 'flex', alignItems: 'center',
padding: '120px 8% 100px', position: 'relative', overflow: 'hidden',
margin: '20px', borderRadius: '32px',
margin: 'var(--hero-top) var(--sec-gutter) var(--sec-gap) var(--sec-gutter)', borderRadius: '32px',
}}>
{/* Background photo */}
<Image src="/assets/images/stock/use-cases.jpg" alt="" fill priority style={{ objectFit: 'cover', opacity: 0.9 }} />
@@ -199,7 +199,7 @@ export default function ForBusinessPage() {
</section>
{/* ── CHALLENGE ── */}
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<RevealBlock>
<div style={{ maxWidth: 200, height: 2, background: '#f4be28', marginBottom: 48 }} />
</RevealBlock>
@@ -288,9 +288,9 @@ export default function ForBusinessPage() {
<ProductsScrollSection />
{/* ── CAPABILITIES ── */}
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section className="uc-cap-section" style={{ padding: '140px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<RevealBlock>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 80, flexWrap: 'wrap', gap: 24 }}>
<div className="uc-cap-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 80, flexWrap: 'wrap', gap: 24 }}>
<div>
<SectionEyebrow variant="number" index="01" style={{ marginBottom: 16 }}>The AI Agents</SectionEyebrow>
<h2 style={{ fontSize: 'clamp(36px, 5vw, 72px)', fontWeight: 800, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#0a0a0f', margin: 0, fontFamily: 'Sora, sans-serif' }}>
@@ -338,7 +338,7 @@ export default function ForBusinessPage() {
<p style={{ fontSize: 14.5, lineHeight: 1.7, color: 'rgba(255,255,255,0.72)', margin: '0 0 26px', fontFamily: 'Sora, sans-serif' }}>{cap.desc}</p>
{/* Metric chips with icon badges */}
<div style={{ display: 'flex', flexWrap: 'nowrap', gap: 12 }}>
<div className="uc-cap-metrics" style={{ display: 'flex', flexWrap: 'nowrap', gap: 12 }}>
{cap.metrics.map((m, j) => (
<div key={j} style={{ flex: '1 1 0', minWidth: 0, display: 'flex', alignItems: 'center', gap: 11, padding: '12px 14px', borderRadius: 14, background: 'rgba(0,0,0,0.22)', border: `1px solid ${cap.accent}26` }}>
<span style={{ flexShrink: 0, width: 34, height: 34, borderRadius: '50%', background: `${cap.accent}30`, display: 'flex', alignItems: 'center', justifyContent: 'center', color: cap.accent }}>
@@ -359,7 +359,7 @@ export default function ForBusinessPage() {
</section>
{/* ── HOW IT WORKS ── */}
<section style={{ padding: '140px 8%', background: '#07070d', margin: '0 20px 20px', borderRadius: 24, overflow: 'hidden', position: 'relative' }}>
<section style={{ padding: '140px 8%', background: '#07070d', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24, overflow: 'hidden', position: 'relative' }}>
<div style={{ position: 'absolute', inset: 0, backgroundImage: 'linear-gradient(rgba(244,190,40,0.025) 1px,transparent 1px),linear-gradient(90deg,rgba(244,190,40,0.025) 1px,transparent 1px)', backgroundSize: '64px 64px', pointerEvents: 'none' }} />
<RevealBlock>
<SectionEyebrow variant="dot" style={{ marginBottom: 20, position: 'relative' }}>How It Works</SectionEyebrow>
@@ -409,7 +409,7 @@ export default function ForBusinessPage() {
</section>
{/* ── PROXIMITY MARKETING ── */}
<section style={{ padding: '120px 8%', background: '#ffffff', margin: '0 20px 20px', borderRadius: 24, overflow: 'hidden', position: 'relative' }}>
<section style={{ padding: '120px 8%', background: '#ffffff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24, overflow: 'hidden', position: 'relative' }}>
<div style={{ position: 'absolute', inset: 0, backgroundImage: 'linear-gradient(rgba(23,21,18,0.035) 1px,transparent 1px),linear-gradient(90deg,rgba(23,21,18,0.035) 1px,transparent 1px)', backgroundSize: '56px 56px', pointerEvents: 'none' }} />
<RevealBlock>
<div className="uc-proximity-grid" style={{ display: 'grid', gridTemplateColumns: '0.9fr 1.1fr', gap: '5vw', alignItems: 'center', position: 'relative' }}>
@@ -542,7 +542,7 @@ export default function ForBusinessPage() {
</section>
{/* ── OUTCOMES ── */}
<section ref={statsRef} style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section ref={statsRef} style={{ padding: '140px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<RevealBlock>
<SectionEyebrow variant="line" style={{ marginBottom: 20 }}>Outcomes</SectionEyebrow>
<h2 style={{ fontSize: 'clamp(36px, 5vw, 68px)', fontWeight: 800, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#0a0a0f', margin: '0 0 80px', fontFamily: 'Sora, sans-serif' }}>
@@ -566,7 +566,7 @@ export default function ForBusinessPage() {
</section>
{/* ── WHO IT'S FOR ── */}
<section style={{ padding: '140px 8%', background: '#1a1a24', margin: '0 20px 20px', borderRadius: 24, position: 'relative', overflow: 'hidden' }}>
<section style={{ padding: '140px 8%', background: '#1a1a24', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24, position: 'relative', overflow: 'hidden' }}>
{/* Background photo */}
<Image src="/assets/images/stock/physical retail.png" alt="" fill style={{ objectFit: 'cover', opacity: 0.72, filter: 'blur(7px)', transform: 'scale(1.06)' }} />
{/* Minimal black vignette — keeps the center bright, softly shades only the edges */}
@@ -608,7 +608,7 @@ export default function ForBusinessPage() {
</section>
{/* ── FINAL CTA ── */}
<section style={{ padding: '160px 8%', background: '#f4be28', margin: '0 20px 20px', borderRadius: 24, textAlign: 'center', position: 'relative', overflow: 'hidden' }}>
<section style={{ padding: '160px 8%', background: '#f4be28', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24, textAlign: 'center', position: 'relative', overflow: 'hidden' }}>
<div style={{ position: 'absolute', top: '-20%', left: '50%', transform: 'translateX(-50%)', width: '120%', height: '140%', background: 'radial-gradient(ellipse,rgba(255,255,255,0.15) 0%,transparent 60%)', pointerEvents: 'none' }} />
<RevealBlock>
<h2 style={{ fontSize: 'clamp(44px, 7vw, 100px)', fontWeight: 800, letterSpacing: '-0.05em', lineHeight: 0.92, color: '#111', margin: '0 0 24px', fontFamily: 'Sora, sans-serif', position: 'relative', zIndex: 2 }}>
@@ -653,9 +653,10 @@ export default function ForBusinessPage() {
.uc-outcomes-grid { grid-template-columns: repeat(2,1fr) !important; }
.uc-outcomes-grid > div > div { border-radius: 16px !important; }
.uc-who-grid { grid-template-columns: repeat(2,1fr) !important; }
/* AI Agents — single column; keep the artwork on the right for tablets */
.uc-cap-grid { grid-template-columns: 1fr !important; }
.uc-cap-content { width: 62% !important; }
.uc-cap-art { width: 40% !important; }
.uc-cap-content { width: 60% !important; }
.uc-cap-art { width: 42% !important; }
.uc-pillar-grid { grid-template-columns: 1fr !important; }
.uc-proximity-grid { grid-template-columns: 1fr !important; gap: 40px !important; }
.uc-prox-stats { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
@@ -663,11 +664,24 @@ export default function ForBusinessPage() {
.uc-timeline-row > div:first-child { width: 44px !important; height: 44px !important; }
.uc-timeline-line { left: 21px !important; }
}
/* AI Agents phone redesign: drop the artwork, let copy use the full
width, and give each card a compact, self-sizing height */
@media (max-width: 640px) {
.uc-cap-section { padding: 96px 6% !important; }
.uc-cap-header { margin-bottom: 44px !important; }
.uc-cap-grid { gap: 16px !important; }
.uc-cap-card { min-height: 0 !important; padding: 28px 24px !important; }
.uc-cap-content { width: 100% !important; }
.uc-cap-art { display: none !important; }
}
@media (max-width: 360px) {
/* Very narrow: stack the two metric chips instead of squeezing them */
.uc-cap-metrics { flex-direction: column !important; }
.uc-cap-metrics > div { width: 100% !important; }
}
@media (max-width: 520px) {
.uc-outcomes-grid { grid-template-columns: 1fr !important; }
.uc-who-grid { grid-template-columns: 1fr !important; }
.uc-cap-content { width: 100% !important; }
.uc-cap-art { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
.uc-radar-ring { animation: none !important; opacity: 0.4 !important; }

View File

@@ -8,6 +8,25 @@
--loyaly-carbon: #171512;
--loyaly-warm-text: #4f463a;
--loyaly-copper: #bc7122;
/* Section gutters. --sec-gutter = left/right side margin (+ width calc);
--sec-gap = vertical gap between stacked sections; --hdr-gutter = header side padding.
On phones the side gutter goes to 0 (full-bleed sections) while the vertical
gap is preserved. Laptop/desktop/tablet keep the original values. */
--sec-gutter: 20px;
--sec-gap: 20px;
--hero-top: 20px;
--hdr-gutter: 48px;
}
/* Phones only — sections span the full width (no left/right margin),
and hero sections sit flush to the top (top margin 0). */
@media (max-width: 600px) {
:root {
--sec-gutter: 0px;
--sec-gap: 12px;
--hero-top: 0px;
--hdr-gutter: 20px;
}
}
/* Legacy styles are loaded dynamically in layout.tsx. This file is kept minimal. */

View File

@@ -98,7 +98,7 @@ export default function MeetTheCrewPage() {
minHeight: '100vh', background: 'radial-gradient(ellipse 120% 90% at 22% 0%, #3a2b5e 0%, #251c40 38%, #1a1530 100%)',
display: 'flex', alignItems: 'center',
padding: '120px 8% 80px',
margin: '20px', borderRadius: '32px',
margin: 'var(--hero-top) var(--sec-gutter) var(--sec-gap) var(--sec-gutter)', borderRadius: '32px',
position: 'relative', overflow: 'hidden',
}}>
{/* Background photo */}
@@ -127,7 +127,7 @@ export default function MeetTheCrewPage() {
</section>
{/* ── VALUES ── */}
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24 }}>
<Reveal>
<SectionEyebrow variant="bar" style={{ marginBottom: 20 }}>How We Work</SectionEyebrow>
<h2 style={{ fontSize: 'clamp(36px, 5vw, 72px)', fontWeight: 800, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#0a0a0f', margin: '0 0 80px', fontFamily: 'Sora, sans-serif' }}>
@@ -185,7 +185,7 @@ export default function MeetTheCrewPage() {
</section>
{/* ── OUR PRODUCTS ── */}
<section style={{ padding: '140px 5%', background: '#07070d', margin: '0 20px 20px', borderRadius: 24, overflow: 'hidden', position: 'relative' }}>
<section style={{ padding: '140px 5%', background: '#07070d', margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24, overflow: 'hidden', position: 'relative' }}>
{/* Background photo confined to the hero band at the top so it isn't
stretched/zoomed across the tall product-stack section below */}
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 760, pointerEvents: 'none' }}>
@@ -210,20 +210,37 @@ export default function MeetTheCrewPage() {
<ScrollStack useWindowScroll disabled={isMobile} stackPosition="14%" scaleEndPosition="8%" itemDistance={160} itemScale={0} itemStackDistance={40} baseScale={1} hideBehind>
{PRODUCTS.map((p, i) => (
<ScrollStackItem key={i}>
<div style={{
position: 'relative', overflow: 'hidden',
background: `radial-gradient(130% 80% at 100% 0%, ${p.color}22 0%, transparent 46%), linear-gradient(155deg, #16161f 0%, #0a0a10 100%)`,
border: `1px solid ${p.color}4d`,
boxShadow: `inset 0 1px 0 rgba(255,255,255,0.06)`,
borderRadius: 28, padding: 'clamp(26px, 3vw, 48px)',
minHeight: 'clamp(320px, 42vh, 440px)', height: '100%', boxSizing: 'border-box',
}}>
<div
className="mtc-product-card"
style={{
position: 'relative', overflow: 'hidden',
background: `radial-gradient(130% 80% at 100% 0%, ${p.color}1a 0%, transparent 46%), linear-gradient(155deg, #16161f 0%, #0a0a10 100%)`,
border: `1px solid ${p.color}1c`,
boxShadow: `inset 0 1px 0 rgba(255,255,255,0.06)`,
borderRadius: 28, padding: 'clamp(26px, 3vw, 48px)',
minHeight: 'clamp(320px, 42vh, 440px)', height: '100%', boxSizing: 'border-box',
['--card-color' as string]: p.color,
}}
>
{/* Background photo */}
<Image src={p.image} alt="" fill sizes="(max-width: 900px) 100vw, 1100px" style={{ objectFit: 'cover', opacity: 0.55 }} />
{/* Left-anchored scrim — copy sits on near-solid dark, photo breathes to the right */}
<div aria-hidden style={{ position: 'absolute', inset: 0, background: `linear-gradient(100deg, rgba(8,8,12,0.94) 0%, rgba(8,8,12,0.82) 34%, rgba(8,8,12,0.5) 66%, rgba(8,8,12,0.32) 100%)`, pointerEvents: 'none' }} />
{/* Ambient pulsing glow */}
<div className="mtc-card-glow" style={{
position: 'absolute',
top: 0, right: 0,
width: '60%', height: '60%',
background: `radial-gradient(circle, ${p.color}24 0%, transparent 70%)`,
pointerEvents: 'none',
zIndex: 1,
}} />
{/* Accent tint from the top-right + bottom vignette for depth */}
<div aria-hidden style={{ position: 'absolute', inset: 0, background: `radial-gradient(120% 90% at 100% 0%, ${p.color}2e 0%, transparent 42%), linear-gradient(180deg, transparent 55%, rgba(6,6,10,0.7) 100%)`, pointerEvents: 'none' }} />
<div aria-hidden style={{ position: 'absolute', inset: 0, background: `radial-gradient(120% 90% at 100% 0%, ${p.color}2e 0%, transparent 42%), linear-gradient(180deg, transparent 55%, rgba(6,6,10,0.7) 100%)`, pointerEvents: 'none', zIndex: 1 }} />
{/* Border beam */}
<div className="mtc-border-beam-container" aria-hidden="true">
<div className="mtc-border-beam" style={{ ['--card-color' as string]: p.color } as React.CSSProperties} />
</div>
<div className="mtc-product-grid" style={{ position: 'relative', display: 'grid', gridTemplateColumns: '1.3fr 1fr', gap: 'clamp(32px, 4.5vw, 68px)', alignItems: 'center', height: '100%' }}>
@@ -289,7 +306,7 @@ export default function MeetTheCrewPage() {
{/* ── CULTURE CLOSE ── */}
<section style={{
padding: '160px 8%', background: '#f4be28',
margin: '0 20px 20px', borderRadius: 24,
margin: '0 var(--sec-gutter) var(--sec-gap)', borderRadius: 24,
display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center',
position: 'relative', overflow: 'hidden',
}}>
@@ -315,8 +332,85 @@ export default function MeetTheCrewPage() {
.mtc-vc-shine { background: linear-gradient(115deg, transparent 32%, rgba(255,255,255,0.22) 48%, transparent 64%); transform: translateX(-130%); transition: transform 0.9s cubic-bezier(0.22,1,0.36,1); }
.mtc-value-card:hover { transform: translateY(-8px) scale(1.02); box-shadow: 0 34px 60px -22px var(--vc-glow); }
.mtc-value-card:hover .mtc-vc-shine { transform: translateX(130%); }
/* Premium Card Hover & Animation Styles */
.mtc-product-card {
transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.mtc-product-card:hover {
transform: translateY(-4px) scale(1.005);
box-shadow: 0 45px 95px -30px rgba(0, 0, 0, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
.mtc-product-card:active {
transform: scale(0.995);
}
.mtc-card-glow {
opacity: 0.65;
mix-blend-mode: plus-lighter;
transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.8s ease;
animation: mtcCardGlow 14s ease-in-out infinite alternate;
}
.mtc-product-card:hover .mtc-card-glow {
opacity: 1 !important;
transform: scale(1.2) translate(-5%, 5%);
}
@keyframes mtcCardGlow {
0% {
transform: translate(6%, -6%) scale(1);
}
50% {
transform: translate(-4%, 4%) scale(1.15);
}
100% {
transform: translate(4%, -2%) scale(0.95);
}
}
/* Premium Card Border Beam */
.mtc-border-beam-container {
position: absolute;
inset: 0;
border-radius: 28px;
padding: 1.5px;
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
overflow: hidden;
z-index: 10;
}
.mtc-border-beam {
position: absolute;
top: 50%;
left: 50%;
width: 250%;
height: 250%;
background: conic-gradient(from 0deg, transparent 35%, var(--card-color) 50%, transparent 65%);
transform: translate(-50%, -50%) rotate(0deg);
animation: mtcBorderRotate 9s linear infinite;
transform-origin: center;
opacity: 0.75;
transition: opacity 0.5s ease;
}
.mtc-product-card:hover .mtc-border-beam {
animation-duration: 5s;
opacity: 1;
}
@keyframes mtcBorderRotate {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.mtc-value-card, .mtc-vc-glow { animation: none !important; }
.mtc-value-card, .mtc-vc-glow, .mtc-card-glow, .mtc-border-beam { animation: none !important; }
.mtc-border-beam { transform: translate(-50%, -50%) rotate(0deg) !important; }
}
@media (max-width: 860px) {
.mtc-value-grid { grid-template-columns: 1fr !important; }

View File

@@ -9,16 +9,16 @@ const NAV = [
title: 'Product',
links: [
{ label: 'For People', href: '/for_people' },
{ label: 'For Business', href: '/use_cases' },
{ label: 'Meet the Agents', href: '/solutions_page' },
{ label: 'For Business', href: '/for_business' },
{ label: 'Meet the Agents', href: '/meet_the_agents' },
],
},
{
title: 'Platform',
links: [
{ label: 'Behavision AI', href: '/use_cases' },
{ label: 'SpendSense AI', href: '/use_cases' },
{ label: 'Dyscount AI', href: '/use_cases' },
{ label: 'Behavision AI', href: '/for_business' },
{ label: 'SpendSense AI', href: '/for_business' },
{ label: 'Dyscount AI', href: '/for_business' },
],
},
{
@@ -66,7 +66,7 @@ export default function Footer() {
color: '#ffffff',
position: 'relative',
overflow: 'hidden',
margin: '0 20px 20px',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: '0 0 24px 24px',
}}>

View File

@@ -16,7 +16,7 @@ const DETAILS = [
},
{
label: 'Email us',
value: <a href="mailto:loyalydigital@gmail.com" style={{ color: '#fff', textDecoration: 'none', fontWeight: 600 }}>loyalydigital@gmail.com</a>,
value: <a href="mailto:loyalydigital@gmail.com" className="git-email-link">loyalydigital@gmail.com</a>,
icon: (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<rect x="2" y="4" width="20" height="16" rx="2" /><path d="m22 7-10 5L2 7" />
@@ -72,7 +72,7 @@ export default function GetInTouch() {
aria-label="Contact us"
style={{
position: 'relative',
margin: '0 20px 0',
margin: '0 var(--sec-gutter) 0',
borderRadius: '24px 24px 0 0',
overflow: 'hidden',
background: '#07070d',
@@ -84,7 +84,7 @@ export default function GetInTouch() {
maxWidth: 1200, margin: '0 auto',
padding: 'clamp(56px, 8vh, 100px) clamp(28px, 5vw, 72px)',
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))',
gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 320px), 1fr))',
gap: 'clamp(40px, 5vw, 80px)',
alignItems: 'start',
}}>
@@ -117,20 +117,13 @@ export default function GetInTouch() {
{/* Detail cards */}
<div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginBottom: 36 }}>
{DETAILS.map((d) => (
<div key={d.label} style={{
display: 'flex', gap: 16, alignItems: 'flex-start',
padding: '18px 20px', borderRadius: 16,
background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.07)',
}}>
<div style={{
width: 40, height: 40, borderRadius: 11, flexShrink: 0,
display: 'flex', alignItems: 'center', justifyContent: 'center',
background: 'rgba(244,190,40,0.1)', border: '1px solid rgba(244,190,40,0.22)',
color: '#f4be28',
}}>{d.icon}</div>
<div key={d.label} className="git-detail">
<div className="git-detail-icon">
{d.icon}
</div>
<div>
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.4)', fontFamily: 'Sora, sans-serif', marginBottom: 6 }}>{d.label}</div>
<div style={{ fontSize: 15, lineHeight: 1.6, color: 'rgba(255,255,255,0.7)', fontFamily: 'Sora, sans-serif' }}>{d.value}</div>
<div className="git-detail-label">{d.label}</div>
<div className="git-detail-value">{d.value}</div>
</div>
</div>
))}
@@ -147,16 +140,7 @@ export default function GetInTouch() {
</div>
</div>
{/* ── Right — form ── */}
<div style={{
background: 'rgba(255,255,255,0.03)',
border: '1px solid rgba(255,255,255,0.08)',
borderRadius: 24,
padding: 'clamp(28px, 3vw, 44px)',
backdropFilter: 'blur(20px)',
WebkitBackdropFilter: 'blur(20px)',
boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.05)',
}}>
<div className="git-form-card">
{formState === 'success' ? (
<div role="status" aria-live="polite" style={{ textAlign: 'center', padding: '40px 0' }}>
<div style={{
@@ -235,6 +219,95 @@ export default function GetInTouch() {
@keyframes gitspin { to { transform: rotate(360deg); } }
.git-input::placeholder { color: rgba(255,255,255,0.3); }
.git-input:focus { border-color: rgba(244,190,40,0.6) !important; box-shadow: 0 0 0 3px rgba(244,190,40,0.12) !important; }
.git-detail {
display: flex;
gap: 20px;
align-items: flex-start;
padding: 10px 0;
transition: transform 0.2s ease;
}
.git-detail-icon {
width: 42px;
height: 42px;
border-radius: 50%;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255,255,255,0.02);
border: 1px solid rgba(255,255,255,0.06);
color: rgba(255,255,255,0.5);
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.git-detail:hover .git-detail-icon {
background: rgba(244,190,40,0.1);
border-color: rgba(244,190,40,0.3);
color: #f4be28;
transform: scale(1.05);
box-shadow: 0 0 15px rgba(244,190,40,0.1);
}
.git-detail-label {
font-size: 11px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: rgba(255,255,255,0.4);
font-family: 'Sora', sans-serif;
margin-bottom: 6px;
transition: color 0.3s ease;
}
.git-detail:hover .git-detail-label {
color: #f4be28;
}
.git-detail-value {
font-size: 15px;
line-height: 1.6;
color: rgba(255,255,255,0.75);
font-family: 'Sora', sans-serif;
transition: color 0.3s ease;
}
.git-detail:hover .git-detail-value {
color: rgba(255,255,255,0.95);
}
.git-email-link {
color: #fff;
text-decoration: none;
font-weight: 600;
position: relative;
transition: color 0.3s ease;
}
.git-email-link::after {
content: '';
position: absolute;
width: 100%;
transform: scaleX(0);
height: 1px;
bottom: -2px;
left: 0;
background-color: #f4be28;
transform-origin: bottom right;
transition: transform 0.25s ease-out;
}
.git-email-link:hover {
color: #f4be28;
}
.git-email-link:hover::after {
transform: scaleX(1);
transform-origin: bottom left;
}
.git-form-card {
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 24px;
padding: clamp(28px, 3vw, 44px);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
}
.git-social {
width: 38px; height: 38px; border-radius: 10px;
display: flex; align-items: center; justify-content: center;
@@ -242,6 +315,17 @@ export default function GetInTouch() {
color: rgba(255,255,255,0.5); transition: all 0.2s ease;
}
.git-social:hover { background: rgba(244,190,40,0.12); border-color: rgba(244,190,40,0.3); color: #f4be28; }
@media (max-width: 768px) {
.git-form-card {
border: none;
background: transparent;
padding: 20px 0;
box-shadow: none;
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
}
@media (max-width: 420px) {
.git-grid { grid-template-columns: 1fr !important; }
}

View File

@@ -8,8 +8,8 @@ import Image from 'next/image';
const NAV_LINKS = [
{ label: 'Home', href: '/' },
{ label: 'For People', href: '/for_people' },
{ label: 'For Business', href: '/use_cases' },
{ label: 'Meet the Agents', href: '/solutions_page' },
{ label: 'For Business', href: '/for_business' },
{ label: 'Meet the Agents', href: '/meet_the_agents' },
{ label: 'About us', href: '/about_us' },
{ label: 'Blogs', href: '/blog_main' },
];
@@ -232,7 +232,7 @@ export default function Header() {
className={transparentHeader ? 'header-transparent' : ''}
style={{
position: 'fixed',
top: isMobileViewport ? '14px' : 0,
top: isMobileViewport ? '20px' : 0,
left: '20px',
right: '20px',
width: 'auto',
@@ -247,18 +247,18 @@ export default function Header() {
transition: 'transform 0.35s cubic-bezier(0.4,0,0.2,1), background 0.3s ease, box-shadow 0.3s ease',
}}
>
<div style={{
<div className="header-inner" style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '0 48px',
padding: '0 var(--hdr-gutter)',
height: transparentHeader ? '150px' : '92px',
width: '100%',
boxSizing: 'border-box',
transition: 'height 0.3s ease',
}}>
{/* Logo */}
<div style={{ flexShrink: 0, flex: 1, minWidth: 120 }}>
<div style={{ flexShrink: 0, flex: 1, minWidth: 120, display: 'flex', alignItems: 'center' }}>
<Link href="/" aria-label="Loyaly.AI home" style={{ display: 'inline-flex', alignItems: 'center', textDecoration: 'none' }}>
<Image
src={transparentHeader ? '/assets/images/logo-dark.png' : '/assets/images/loyalyai.png'}
@@ -360,6 +360,8 @@ export default function Header() {
@media (max-width: 1023px) {
.desktop-nav { display: none !important; }
.menu-trigger { display: flex !important; }
.header-inner { height: 68px !important; }
.header-logo-img { height: 32px !important; }
}
@media (min-width: 1024px) and (max-width: 1280px) {
.header-nav-pill { padding: 5px 6px !important; }

View File

@@ -9,7 +9,7 @@ export default function MapSection() {
return (
<section style={{
margin: '0 20px 20px',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: 24,
overflow: 'hidden',
background: '#fff',

View File

@@ -100,11 +100,14 @@ export default function EarnRewardsSection() {
}} />
{/* Safe area — reserves the notch strip above the app's top bar */}
<div style={{ height: 32, flexShrink: 0, background: '#ffffff' }} />
{/* The embed is a Flutter web app built for a real phone's logical
width (390px). Rendering it at 390 and scaling to fit keeps the
UI proportioned as designed instead of cramped at ~280px. The
iframe is overscanned ~16px past the right clip so Flutter's
desktop-style list scrollbar falls outside the visible screen. */}
{/* 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. */}
<div className="erm-phone-viewport" style={{ position: 'relative', flex: 1, minHeight: 0, overflow: 'hidden' }}>
<iframe
src="https://anbarasu22004.github.io/lytsup_view/"
@@ -118,6 +121,8 @@ export default function EarnRewardsSection() {
transformOrigin: 'top left',
}}
/>
{/* Masks Flutter's canvas-painted scrollbar at the far right edge */}
<div className="erm-scrollbar-mask" aria-hidden />
</div>
</div>
<style>{`
@@ -126,10 +131,15 @@ export default function EarnRewardsSection() {
/* --pm-scale = screen width (frame - 2*10px padding) ÷ 390px design width */
.erm-phone-shell { --pm-scale: calc(280 / 390); }
.erm-phone-iframe {
width: calc(100% / var(--pm-scale) + 16px);
width: calc(100% / var(--pm-scale));
height: calc(100% / var(--pm-scale));
transform: scale(var(--pm-scale));
}
.erm-scrollbar-mask {
position: absolute; top: 0; right: 0; z-index: 2;
width: 7px; height: 100%; pointer-events: none;
background: linear-gradient(to right, rgba(255,255,255,0), #ffffff 75%);
}
@media (prefers-reduced-motion: reduce) { .erm-phone-shell { animation: none !important; } }
@media (max-width: 900px) {
.erm-phone-shell { width: 280px !important; --pm-scale: calc(260 / 390); }

View File

@@ -10,22 +10,7 @@ if (typeof window !== 'undefined') gsap.registerPlugin(ScrollTrigger);
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
function useMagnetic() {
const ref = useRef<HTMLAnchorElement | null>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const onMove = (e: MouseEvent) => {
const r = el.getBoundingClientRect();
el.style.transform = `translate(${((e.clientX - r.left) / r.width - 0.5) * 16}px,${((e.clientY - r.top) / r.height - 0.5) * 16}px) scale(1.04)`;
};
const onLeave = () => { el.style.transform = ''; };
el.addEventListener('mousemove', onMove);
el.addEventListener('mouseleave', onLeave);
return () => { el.removeEventListener('mousemove', onMove); el.removeEventListener('mouseleave', onLeave); };
}, []);
return ref;
}
const PROOF = [
{ val: '50K+', label: 'Active users', color: '#f4be28', icon: '👥', iconBg: '#fffbeb' },
@@ -36,8 +21,6 @@ const PROOF = [
export default function FinalCTASection() {
const sectionRef = useRef<HTMLDivElement>(null);
const mag1 = useMagnetic();
const mag2 = useMagnetic();
const coinLayerRef = useRef<HTMLDivElement>(null);
const badgeMag1 = useMagneticShared<HTMLDivElement>(10);
const badgeMag2 = useMagneticShared<HTMLDivElement>(10);
@@ -106,10 +89,6 @@ export default function FinalCTASection() {
'-=0.35'
)
.call(burstCoins)
.fromTo('.fcta-btns',
{ opacity: 0, y: 20 },
{ opacity: 1, y: 0, duration: 0.55, ease: 'power3.out' }, '-=0.45'
)
.fromTo('.fcta-stat',
{ opacity: 0, y: 28, scale: 0.88 },
{ opacity: 1, y: 0, scale: 1, duration: 0.55, stagger: 0.1, ease: 'back.out(1.8)' }, '-=0.25'
@@ -147,8 +126,8 @@ export default function FinalCTASection() {
ref={sectionRef}
style={{
position: 'relative',
width: 'calc(100% - 40px)',
margin: '0 20px 20px',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: 32,
overflow: 'hidden',
background: '#ffffff',
@@ -176,7 +155,7 @@ export default function FinalCTASection() {
fontSize: 'clamp(52px,8vw,116px)',
fontWeight: 900, color: '#171512',
}}>
Your lyts
Your Lyts
</span>
<span className="fcta-line-2" style={{
display: 'block',
@@ -263,41 +242,7 @@ export default function FinalCTASection() {
</div>
</div>
{/* CTAs */}
<div className="fcta-btns" style={{ display: 'flex', gap: 14, justifyContent: 'center', flexWrap: 'wrap', marginBottom: 64 }}>
<Link
href="/contacts"
ref={mag1}
style={{
display: 'inline-flex', alignItems: 'center', gap: 9,
padding: '16px 34px', borderRadius: 100,
background: 'linear-gradient(135deg,#f4be28,#ff9500)',
color: '#1a1200', fontWeight: 800, fontSize: '0.97rem',
fontFamily: 'Sora, sans-serif', textDecoration: 'none',
boxShadow: '0 8px 32px rgba(244,190,40,0.35)',
transition: 'box-shadow 0.3s ease, transform 0.3s ease',
}}
>
<svg width="17" height="17" viewBox="0 0 24 24" fill="currentColor"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.8-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/></svg>
Download for iOS
</Link>
<Link
href="/contacts"
ref={mag2}
style={{
display: 'inline-flex', alignItems: 'center', gap: 9,
padding: '16px 34px', borderRadius: 100,
background: 'transparent',
color: '#171512', fontWeight: 700, fontSize: '0.97rem',
fontFamily: 'Sora, sans-serif', textDecoration: 'none',
border: '1.5px solid rgba(23,21,18,0.2)',
transition: 'border-color 0.3s ease, background 0.3s ease',
}}
>
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7"><rect x="2" y="8" width="20" height="10" rx="2"/><path d="M7.83 3l1.3 2.35M16.17 3l-1.3 2.35"/></svg>
Get on Android
</Link>
</div>
{/* Proof stats — individual sticker cards, matching the dark-border card system used across the page */}
<div className="fcta-proof-row" style={{ display: 'flex', justifyContent: 'center', gap: 18, flexWrap: 'wrap', width: '80%', maxWidth: 720, margin: '0 auto' }}>
@@ -389,18 +334,10 @@ export default function FinalCTASection() {
.fcta-sweep { display: none; }
}
@media (max-width: 1023px) {
.fcta-store-badges {
display: none !important;
}
.fcta-sub {
margin-bottom: 40px !important;
}
}
@media (min-width: 1024px) {
.fcta-btns {
display: none !important;
}
}
@media (max-width: 560px) {
.fcta-proof-row {
width: 100% !important;

View File

@@ -357,6 +357,10 @@ export default function VerticalScrollWrapper({ children, sections = [] }: Props
}
@media (max-width: 600px) {
.fp-shell { padding: 0 22px; }
/* Full-bleed panels on phones (no left/right margin), keep bottom gap */
.fp-panel { width: 100%; margin: 0 0 12px; }
/* Hero flush to the top on phones */
.fp-root { padding-top: 0; }
}
@media (prefers-reduced-motion: reduce) {

View File

@@ -178,6 +178,16 @@ export default function HeroCarousel({ onReady }: HeroCarouselProps) {
}
}
/* Phones — full-bleed hero, flush to top (top margin 0), keep bottom gap */
@media (max-width: 600px) {
.hero-carousel {
width: 100%;
height: calc(100vh - 12px);
height: calc(100svh - 12px);
margin: 0 0 12px;
}
}
.hero-carousel-slides {
position: absolute;
inset: 0;

View File

@@ -156,8 +156,8 @@ export default function LytsUpSection({ isLoaded = true }: LytsUpSectionProps) {
id="lytsup"
className="relative overflow-hidden"
style={{
width: 'calc(100% - 40px)',
margin: '0 20px 20px',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: 32,
padding: 'clamp(64px, 8vw, 110px) clamp(20px, 4vw, 64px) clamp(64px, 8vw, 96px)',
zIndex: 2,

View File

@@ -110,8 +110,8 @@ export default function ProblemSection({ isLoaded = true }: ProblemSectionProps)
className="relative overflow-hidden problem-section"
style={{
background: '#ffffff',
width: 'calc(100% - 40px)',
margin: '0 20px 20px',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: '32px',
padding: 'clamp(72px, 9vw, 130px) clamp(20px, 4vw, 64px) clamp(64px, 7vw, 96px)',
zIndex: 1,
@@ -526,8 +526,14 @@ export default function ProblemSection({ isLoaded = true }: ProblemSectionProps)
}
@media (max-width: 900px) {
#problem .problem-header-grid { grid-template-columns: 1fr; }
#problem .problem-header-right { border-left: none; padding-left: 0; border-top: 2px solid rgba(23,21,18,0.1); padding-top: 20px; margin-top: 20px; }
#problem .problem-header-grid { grid-template-columns: 1fr !important; }
#problem .problem-header-right {
border-left: none !important;
padding-left: 0 !important;
border-top: 2px solid rgba(23,21,18,0.1) !important;
padding-top: 20px !important;
margin-top: 20px !important;
}
#problem .problem-stats-row { grid-template-columns: 1fr !important; }
#problem .dark-bento-grid { grid-template-columns: 1fr !important; }
#problem .dark-bento-card-4 { grid-column: span 1; }

View File

@@ -389,7 +389,7 @@ function ProductCard({ product, index }: { product: Product; index: number }) {
</div>
<Link
href="/solutions_page"
href="/meet_the_agents"
style={{
display: 'inline-flex', alignItems: 'center', gap: '8px', width: 'max-content',
padding: '11px 22px', borderRadius: '99px', fontSize: '0.85rem', fontWeight: 800,
@@ -694,7 +694,15 @@ export default function ProductsSection({ isLoaded = false }: ProductsSectionPro
flex-direction: column; align-items: flex-start; gap: 16px;
padding: clamp(40px, 8vw, 64px) 24px 24px;
}
.products-heading-hint { text-align: left !important; }
.products-heading-hint {
text-align: left !important;
border-right: none !important;
padding-right: 0 !important;
border-top: 2px solid rgba(244,190,40,0.3) !important;
padding-top: 16px !important;
margin-top: 8px !important;
max-width: 100% !important;
}
.products-track {
position: relative; height: auto;
padding-top: 8px; padding-bottom: 8px;

View File

@@ -135,8 +135,8 @@ export default function ShiftSection({ isLoaded = true }: ShiftSectionProps) {
className="relative overflow-hidden shift-section"
style={{
background: 'linear-gradient(155deg, #fffdf6 0%, #fbf5e4 48%, #f6ecd2 100%)',
width: 'calc(100% - 40px)',
margin: '0 20px 20px',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: '32px',
padding: 'clamp(72px, 9vw, 130px) clamp(20px, 4vw, 64px) clamp(56px, 7vw, 90px)',
zIndex: 1,
@@ -490,8 +490,14 @@ export default function ShiftSection({ isLoaded = true }: ShiftSectionProps) {
}
@media (max-width: 900px) {
#shift .shift-header-grid { grid-template-columns: 1fr; }
#shift .shift-header-right { border-left: none; padding-left: 0; border-top: 2px solid rgba(244,190,40,0.3); padding-top: 20px; margin-top: 20px; }
#shift .shift-header-grid { grid-template-columns: 1fr !important; }
#shift .shift-header-right {
border-left: none !important;
padding-left: 0 !important;
border-top: 2px solid rgba(244,190,40,0.3) !important;
padding-top: 20px !important;
margin-top: 20px !important;
}
}
`}</style>
</section>

View File

@@ -32,7 +32,7 @@ interface Step {
const STEPS: Step[] = [
{ step: '01', id: 'earn', title: 'Earn Online', desc: 'Daily login, 5,000-step walking challenges, and interactive games like Maze and Spin Wheel earn LYTs and unlock surprise coupons.' },
{ step: '02', id: 'engage', title: 'Unlock Deals', desc: 'Merchants create game based discount campaigns: customers play once to reveal their exclusive reward on a specific product.' },
{ step: '02', id: 'engage', title: 'Unlock Deals', desc: 'Merchants create LYTs-earning campaigns: customers play once to reveal their exclusive reward on a specific product.' },
{ step: '03', id: 'spend', title: 'Discover & Visit', desc: 'Browse participating stores nearby, view active game campaigns and LYTs-earning offers, then walk in and shop in person.' },
{ step: '04', id: 'repeat', title: 'Redeem & Repeat', desc: 'Use LYTs and coupons at checkout to save money, then come back tomorrow to earn more and keep the loop going.' },
];
@@ -270,8 +270,8 @@ export default function TheLoop() {
id="the-loop"
style={{
position: 'relative',
width: 'calc(100% - 40px)',
margin: '0 20px 0',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) 0',
borderRadius: '32px 32px 0 0',
overflow: 'hidden',
zIndex: 2,
@@ -316,7 +316,7 @@ export default function TheLoop() {
color: 'rgba(255,255,255,0.38)', lineHeight: 1.75,
fontFamily: 'Sora, sans-serif',
}}>
Earn LYTs online, unlock game based deals, discover nearby stores, and redeem offline.
Earn LYTs online, unlock LYTs-based deals, discover nearby stores, and redeem offline.
</p>
</div>
@@ -536,8 +536,8 @@ export default function TheLoop() {
id="the-loop-mobile"
style={{
position: 'relative',
width: 'calc(100% - 40px)',
margin: '0 20px 0',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) 0',
borderRadius: '32px 32px 0 0',
overflow: 'hidden',
zIndex: 2,
@@ -581,7 +581,7 @@ export default function TheLoop() {
color: 'rgba(255,255,255,0.4)', lineHeight: 1.5,
fontFamily: 'Sora, sans-serif',
}}>
Earn LYTs online, unlock game based deals, discover nearby stores, and redeem offline.
Earn LYTs online, unlock LYTs-based deals, discover nearby stores, and redeem offline.
</p>
</div>
@@ -729,8 +729,8 @@ export default function TheLoop() {
{/* Impact metrics — outside section to avoid overflow:hidden clipping */}
<div style={{
position: 'relative', zIndex: 2,
width: 'calc(100% - 40px)',
margin: '0 20px 20px',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: '0 0 32px 32px',
background: '#0c0a07',
padding: 'clamp(32px,4vh,52px) clamp(28px,5vw,80px) clamp(28px,4vh,48px)',

View File

@@ -221,8 +221,8 @@ export default function WhatWeDo({ isLoaded = false }: WhatWeDoProps) {
id="what-we-do"
className="relative bg-[#0D0D0D] !pt-32 sm:!pt-40 md:!pt-44 pb-24 md:pb-32 px-6 md:px-12 xl:px-16 overflow-hidden select-none"
style={{
width: 'calc(100% - 40px)',
margin: '0 20px 20px',
width: 'calc(100% - (var(--sec-gutter) * 2))',
margin: '0 var(--sec-gutter) var(--sec-gap)',
borderRadius: 32,
zIndex: 2,
}}

View File

@@ -24,7 +24,7 @@ export const HERO_SLIDES: HeroSlideData[] = [
ctaLabel: 'Book a Demo',
ctaHref: '/contacts',
secondaryLabel: 'See How It Works',
secondaryHref: '/solutions_page',
secondaryHref: '/meet_the_agents',
image: '/assets/home_hero/home_hero_01.png',
imageAlt: 'Shoppers walking through a modern premium shopping mall',
},
@@ -50,9 +50,9 @@ export const HERO_SLIDES: HeroSlideData[] = [
description:
'Behavision, SpendSense, Dyscount, Identiq, Flowmind, and the Loyaly App — a connected AI suite that knows your customers inside out.',
ctaLabel: 'Explore Platform',
ctaHref: '/solutions_page',
ctaHref: '/meet_the_agents',
secondaryLabel: 'Meet the Tools',
secondaryHref: '/solutions_page',
secondaryHref: '/meet_the_agents',
image: '/assets/home_hero/home_hero_03.png',
imageAlt: 'Aerial view of a large, crowded luxury shopping mall atrium',
},

View File

@@ -115,17 +115,17 @@ export default function ProductsScrollSection() {
return (
<section
ref={sectionRef}
className="products-scroll-section"
style={{
position: 'relative',
height: `${(TOTAL - 1) * STEP_VH + 100}vh`,
background: '#07070d',
margin: '0 20px 20px',
borderRadius: 24,
overflow: 'hidden',
}}
>
<div
ref={pinRef}
className="uc-pp-pin"
style={{
height: '100vh',
display: 'flex',
@@ -144,7 +144,7 @@ export default function ProductsScrollSection() {
}} />
{/* Header */}
<div style={{ position: 'relative', zIndex: 2, marginBottom: 'clamp(56px,8vh,96px)' }}>
<div className="uc-pp-header" style={{ position: 'relative', zIndex: 2, marginBottom: 'clamp(56px,8vh,96px)' }}>
<SectionEyebrow variant="pill" style={{ marginBottom: 16 }}>Our Products</SectionEyebrow>
<h2 style={{ fontSize: 'clamp(32px, 4.5vw, 64px)', fontWeight: 800, letterSpacing: '-0.05em', lineHeight: 0.92, color: '#fff', margin: 0, fontFamily: 'Sora, sans-serif', maxWidth: 640 }}>
Offline Shopping. Online Intelligence.
@@ -152,7 +152,7 @@ export default function ProductsScrollSection() {
</div>
{/* Horizontal progress track with 3 points */}
<div style={{ position: 'relative', zIndex: 2, margin: '0 0 clamp(72px,10vh,120px)', padding: '0 16px' }}>
<div className="uc-pp-track" style={{ position: 'relative', zIndex: 2, margin: '0 0 clamp(72px,10vh,120px)', padding: '0 16px' }}>
<div style={{ position: 'relative', height: 2, background: 'rgba(255,255,255,0.08)', borderRadius: 2 }}>
{/* Growing fill line */}
<div
@@ -215,6 +215,7 @@ export default function ProductsScrollSection() {
<div
key={p.name}
ref={el => { visualRefs.current[i] = el; }}
data-pp-panel
style={{
position: 'absolute', inset: 0,
opacity: i === 0 ? 1 : 0,
@@ -234,7 +235,7 @@ export default function ProductsScrollSection() {
<div style={{ position: 'absolute', bottom: '-25%', left: '-15%', width: '55%', aspectRatio: '1', borderRadius: '50%', background: 'rgba(0,0,0,0.08)', pointerEvents: 'none' }} />
{/* Ghost number */}
<span style={{
<span data-pp-ghost style={{
position: 'absolute', bottom: -30, right: 14, lineHeight: 1,
fontSize: 'clamp(130px,13vw,200px)', fontWeight: 900,
fontFamily: 'Sora, sans-serif', letterSpacing: '-0.06em',
@@ -257,7 +258,7 @@ export default function ProductsScrollSection() {
{/* Hero metric */}
<div style={{ position: 'relative' }}>
<div style={{
<div data-pp-metric style={{
fontSize: 'clamp(72px,8.5vw,130px)', fontWeight: 900, lineHeight: 0.9,
color: '#111', fontFamily: 'Sora, sans-serif', letterSpacing: '-0.05em',
}}>{p.metric}</div>
@@ -273,7 +274,7 @@ export default function ProductsScrollSection() {
</div>
{/* Right — editorial text (stacked, cross-fading) */}
<div style={{ position: 'relative', minHeight: 'clamp(300px, 38vh, 420px)' }}>
<div className="uc-pp-text" style={{ position: 'relative', minHeight: 'clamp(300px, 38vh, 420px)' }}>
{PRODUCTS.map((p, i) => (
<div
key={p.name}
@@ -287,22 +288,22 @@ export default function ProductsScrollSection() {
display: 'flex', flexDirection: 'column', justifyContent: 'center',
}}
>
<div style={{
<div data-pp-tag style={{
display: 'inline-block', width: 'fit-content', fontSize: 11, fontWeight: 700, letterSpacing: '0.14em',
textTransform: 'uppercase', color: p.color, fontFamily: 'Sora, sans-serif',
marginBottom: 20, background: `${p.color}15`, padding: '6px 14px', borderRadius: 100,
border: `1px solid ${p.color}30`,
}}>{p.tag}</div>
<h3 style={{ fontSize: 'clamp(34px, 4vw, 60px)', fontWeight: 800, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#fff', margin: '0 0 22px', fontFamily: 'Sora, sans-serif' }}>{p.name}</h3>
<h3 data-pp-title style={{ fontSize: 'clamp(34px, 4vw, 60px)', fontWeight: 800, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#fff', margin: '0 0 22px', fontFamily: 'Sora, sans-serif' }}>{p.name}</h3>
<p style={{
<p data-pp-desc style={{
fontSize: 'clamp(15px,1.25vw,19px)', lineHeight: 1.7, color: 'rgba(255,255,255,0.45)',
fontFamily: 'Sora, sans-serif', margin: '0 0 36px', maxWidth: 460,
paddingLeft: 20, borderLeft: `2px solid ${p.color}55`,
}}>{p.desc}</p>
<Link href="/contacts" style={{
<Link href="/contacts" data-pp-cta style={{
display: 'inline-flex', alignItems: 'center', gap: 8, width: 'fit-content',
padding: '15px 32px', background: p.color, color: '#111',
fontSize: 14, fontWeight: 800, borderRadius: 100, textDecoration: 'none',
@@ -315,12 +316,75 @@ export default function ProductsScrollSection() {
</div>
<style>{`
.products-scroll-section {
margin: 0 20px 20px;
width: calc(100% - 40px);
border-radius: 24px;
}
@media (max-width: 768px) {
.products-scroll-section {
margin: 0 var(--sec-gutter) 20px !important;
width: calc(100% - (var(--sec-gutter) * 2)) !important;
}
}
/* ── Tablet / large phone: stack the two columns. The section is a fixed
100vh pin, so the stacked blocks are kept compact enough to fit the
viewport height across this whole range (incl. shorter tablets). ── */
@media (max-width: 860px) {
.uc-pp-grid { grid-template-columns: 1fr !important; gap: 24px !important; }
.uc-pp-visual { min-height: 260px !important; }
.uc-pp-pin { padding: 0 4% !important; }
.uc-pp-grid { grid-template-columns: 1fr !important; gap: 20px !important; }
.uc-pp-visual { min-height: 200px !important; }
/* Text panels are absolutely-positioned crossfaders, so the column
needs an explicit height to reserve space for them. */
.uc-pp-text { min-height: 260px !important; }
.uc-pp-label { display: none; }
.uc-pp-header { margin-bottom: 30px !important; }
.uc-pp-track { margin-bottom: 40px !important; }
}
/* ── Phone: compress further so the pinned frame never clips the header
or CTA, even on short viewports. ── */
@media (max-width: 600px) {
.uc-pp-pin { padding: 0 24px !important; }
.uc-pp-header { margin-bottom: 26px !important; }
.uc-pp-header h2 { font-size: clamp(26px, 7.5vw, 34px) !important; }
.uc-pp-track { margin-bottom: 34px !important; padding: 0 14px !important; }
.uc-pp-grid { gap: 18px !important; }
.uc-pp-visual { min-height: 190px !important; }
.uc-pp-text { min-height: 270px !important; }
/* Shrink the oversized hero metric + ghost number to fit the panel */
.uc-pp-visual [data-pp-metric] { font-size: clamp(52px, 15vw, 72px) !important; }
.uc-pp-visual [data-pp-ghost] { font-size: clamp(96px, 30vw, 130px) !important; bottom: -20px !important; }
.uc-pp-visual [data-pp-panel] { padding: 20px 22px !important; }
/* Tighten the editorial text stack */
.uc-pp-text [data-pp-title] { font-size: clamp(28px, 8vw, 38px) !important; margin-bottom: 14px !important; }
.uc-pp-text [data-pp-desc] { font-size: 14px !important; margin-bottom: 22px !important; line-height: 1.6 !important; }
.uc-pp-text [data-pp-tag] { margin-bottom: 14px !important; }
.uc-pp-text [data-pp-cta] { padding: 13px 26px !important; }
}
/* ── Short viewports (small phones like iPhone SE ~568px, landscape,
short windows). The pinned frame equals the viewport height, so on
these we compress aggressively so nothing spills out of view.
Scoped to the stacked range so desktop short windows are untouched. ── */
@media (max-width: 860px) and (max-height: 700px) {
.uc-pp-header { margin-bottom: 16px !important; }
.uc-pp-header h2 { font-size: clamp(20px, 6vw, 27px) !important; line-height: 1 !important; }
.uc-pp-track { margin-bottom: 22px !important; }
.uc-pp-grid { gap: 14px !important; }
.uc-pp-visual { min-height: 156px !important; }
.uc-pp-text { min-height: 230px !important; }
.uc-pp-visual [data-pp-metric] { font-size: 46px !important; }
.uc-pp-visual [data-pp-ghost] { font-size: 92px !important; bottom: -16px !important; }
.uc-pp-visual [data-pp-panel] { padding: 16px 18px !important; }
.uc-pp-text [data-pp-tag] { margin-bottom: 10px !important; }
.uc-pp-text [data-pp-title] { font-size: 25px !important; margin-bottom: 8px !important; }
.uc-pp-text [data-pp-desc] { font-size: 12.5px !important; margin-bottom: 14px !important; line-height: 1.5 !important; }
.uc-pp-text [data-pp-cta] { padding: 10px 20px !important; font-size: 12.5px !important; }
}
`}</style>
</section>
);
}
}