convert-next.js
This commit is contained in:
418
src/app/about_us/page.tsx
Normal file
418
src/app/about_us/page.tsx
Normal file
@@ -0,0 +1,418 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useReveal } from '@/hooks/useReveal';
|
||||
import GSAPAnimator from '@/components/GSAPAnimator';
|
||||
|
||||
function Reveal({ children, delay = 0 }: { children: React.ReactNode; delay?: number }) {
|
||||
const { ref, visible } = useReveal();
|
||||
return (
|
||||
<div ref={ref} style={{
|
||||
opacity: visible ? 1 : 0,
|
||||
transform: visible ? 'translateY(0)' : 'translateY(48px)',
|
||||
transition: `opacity 0.9s cubic-bezier(0.22,1,0.36,1) ${delay}s, transform 0.9s cubic-bezier(0.22,1,0.36,1) ${delay}s`,
|
||||
}}>{children}</div>
|
||||
);
|
||||
}
|
||||
|
||||
const VALUES = [
|
||||
{ n: '01', title: 'Intelligence first', desc: 'Every product decision starts with data, not instinct.' },
|
||||
{ n: '02', title: 'Merchant obsessed', desc: 'We build for the store owner who works 14-hour days.' },
|
||||
{ n: '03', title: 'Radical transparency', desc: 'No black boxes. Our AI explains every recommendation.' },
|
||||
{ n: '04', title: 'Build to last', desc: 'We optimise for long-term impact, not vanity metrics.' },
|
||||
];
|
||||
|
||||
const TEAM: { name: string; role: string; initials: string; color: string }[] = [];
|
||||
|
||||
export default function AboutUsPage() {
|
||||
return (
|
||||
<main style={{ background: '#ffffff', minHeight: '100vh', overflowX: 'hidden' }}>
|
||||
<GSAPAnimator />
|
||||
|
||||
{/* ── HERO ── */}
|
||||
<section style={{
|
||||
minHeight: '100vh', background: '#07070d',
|
||||
display: 'flex', alignItems: 'center',
|
||||
padding: '120px 8% 80px',
|
||||
margin: '0 20px 20px', borderRadius: '0 0 24px 24px',
|
||||
position: 'relative', overflow: 'hidden',
|
||||
}}>
|
||||
{/* Big ghost text */}
|
||||
<div style={{
|
||||
position: 'absolute', top: '50%', left: '50%',
|
||||
transform: 'translate(-50%,-50%)',
|
||||
fontSize: 'clamp(120px, 22vw, 320px)', fontWeight: 900,
|
||||
fontFamily: 'Sora, sans-serif', color: 'transparent',
|
||||
WebkitTextStroke: '1px rgba(244,190,40,0.06)',
|
||||
letterSpacing: '-0.06em', lineHeight: 1,
|
||||
whiteSpace: 'nowrap', userSelect: 'none',
|
||||
pointerEvents: 'none', zIndex: 0,
|
||||
}}>LOYALY</div>
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 2, width: '100%', display: 'grid', gridTemplateColumns: '1fr auto', alignItems: 'center', gap: '6vw' }}>
|
||||
<div style={{ maxWidth: 680 }}>
|
||||
<div data-gsap="badge" style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: '#f4be28', fontFamily: 'Manrope, sans-serif', marginBottom: 28, display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<span data-gsap="line" style={{ width: 32, height: 1, background: '#f4be28', display: 'block' }} />Meet the Crew
|
||||
</div>
|
||||
<h1 data-gsap="heading" style={{
|
||||
fontSize: 'clamp(52px, 9vw, 140px)', fontWeight: 900,
|
||||
letterSpacing: '-0.06em', lineHeight: 0.88,
|
||||
color: '#ffffff', margin: '0 0 36px', fontFamily: 'Sora, sans-serif',
|
||||
}}>
|
||||
The People<br />
|
||||
<span style={{ color: '#f4be28' }}>Behind</span> Loyaly.
|
||||
</h1>
|
||||
<p data-gsap="text" style={{ fontSize: 'clamp(16px, 1.5vw, 20px)', lineHeight: 1.75, color: 'rgba(255,255,255,0.4)', fontFamily: 'Manrope, sans-serif', maxWidth: 560, margin: 0 }}>
|
||||
We're not just building a product. We're redefining retail — one store at a time.
|
||||
</p>
|
||||
</div>
|
||||
{/* Company DNA widget */}
|
||||
<div className="pw-widget-col" style={{ flexShrink: 0, width: 320 }}>
|
||||
<div style={{
|
||||
borderRadius: 24, padding: '28px 24px',
|
||||
background: 'linear-gradient(145deg,#0e0e13 0%,#16161d 100%)',
|
||||
border: '1px solid rgba(244,190,40,0.15)',
|
||||
boxShadow: '0 40px 100px rgba(0,0,0,0.6)',
|
||||
}}>
|
||||
{/* Brand header */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 24 }}>
|
||||
<div style={{ width: 42, height: 42, borderRadius: 13, background: 'rgba(244,190,40,0.12)', border: '1px solid rgba(244,190,40,0.28)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 18, color: '#f4be28' }}>✦</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 15, fontWeight: 800, color: '#fff', fontFamily: 'Sora, sans-serif' }}>Loyaly.ai</div>
|
||||
<div style={{ fontSize: 10, color: '#f4be28', fontFamily: 'Manrope, sans-serif', letterSpacing: '0.12em', textTransform: 'uppercase' }}>AI Retail Platform</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Stats */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10, marginBottom: 20 }}>
|
||||
{[['2024', 'Founded'], ['12+', 'Cities'], ['20+', 'Team']].map(([v, l]) => (
|
||||
<div key={l} style={{ background: 'rgba(255,255,255,0.04)', borderRadius: 14, padding: '14px 8px', textAlign: 'center', border: '1px solid rgba(255,255,255,0.07)' }}>
|
||||
<div style={{ fontSize: 20, fontWeight: 900, color: '#f4be28', fontFamily: 'Sora, sans-serif', letterSpacing: '-0.02em' }}>{v}</div>
|
||||
<div style={{ fontSize: 10, color: 'rgba(255,255,255,0.38)', fontFamily: 'Manrope, sans-serif', marginTop: 4 }}>{l}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Values */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 18 }}>
|
||||
{['Intelligence first', 'Merchant obsessed', 'Build to last'].map((v, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 14px', borderRadius: 12, background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.06)' }}>
|
||||
<span style={{ width: 6, height: 6, borderRadius: '50%', background: '#f4be28', flexShrink: 0 }} />
|
||||
<span style={{ fontSize: 13, color: 'rgba(255,255,255,0.68)', fontFamily: 'Manrope, sans-serif', fontWeight: 600 }}>{v}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Mission */}
|
||||
<div style={{ padding: '14px 16px', borderRadius: 14, background: 'rgba(244,190,40,0.06)', border: '1px solid rgba(244,190,40,0.2)' }}>
|
||||
<div style={{ fontSize: 10, fontWeight: 700, color: '#f4be28', fontFamily: 'Manrope, sans-serif', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 6 }}>Mission</div>
|
||||
<div style={{ fontSize: 12, color: 'rgba(255,255,255,0.5)', fontFamily: 'Manrope, sans-serif', lineHeight: 1.65 }}>Transform physical retail with AI-driven intelligence and meaningful customer engagement.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── OUR STORY ── */}
|
||||
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8vw', alignItems: 'start' }}>
|
||||
<Reveal>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: '#f4be28', fontFamily: 'Manrope, sans-serif', marginBottom: 24 }}>Our Story</div>
|
||||
<h2 style={{ fontSize: 'clamp(36px, 4.5vw, 68px)', fontWeight: 900, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#0a0a0f', margin: '0 0 32px', fontFamily: 'Sora, sans-serif' }}>
|
||||
We started with<br />a simple idea.
|
||||
</h2>
|
||||
</Reveal>
|
||||
<Reveal delay={0.15}>
|
||||
<p style={{ fontSize: 'clamp(17px, 1.6vw, 22px)', lineHeight: 1.8, color: 'rgba(0,0,0,0.55)', fontFamily: 'Manrope, sans-serif', margin: '0 0 32px' }}>
|
||||
Offline retail deserves the same intelligence as online. A store owner in Coimbatore shouldn't be flying blind while an e-commerce algorithm knows exactly what every user wants.
|
||||
</p>
|
||||
<p style={{ fontSize: 'clamp(17px, 1.6vw, 22px)', lineHeight: 1.8, color: 'rgba(0,0,0,0.55)', fontFamily: 'Manrope, sans-serif', margin: 0 }}>
|
||||
Today, we're building a connected ecosystem where businesses grow smarter and customers shop better — together.
|
||||
</p>
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── MISSION & VISION ── */}
|
||||
<section style={{ padding: '0 8% 20px', background: '#ffffff' }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20, alignItems: 'stretch' }}>
|
||||
{[
|
||||
{
|
||||
label: 'Mission', bg: '#07070d', textColor: '#fff', accent: '#f4be28',
|
||||
body: 'To transform physical retail with AI-driven intelligence and meaningful customer engagement.',
|
||||
},
|
||||
{
|
||||
label: 'Vision', bg: '#f4be28', textColor: '#111', accent: '#c9960f',
|
||||
body: 'To become the leading retail intelligence platform across global markets.',
|
||||
},
|
||||
].map((mv, i) => (
|
||||
<Reveal key={i} delay={i * 0.15}>
|
||||
<div style={{
|
||||
padding: '72px 56px', borderRadius: 24, background: mv.bg,
|
||||
height: '100%', minHeight: 360,
|
||||
display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
|
||||
margin: '0 20px 20px', boxSizing: 'border-box',
|
||||
}}>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: mv.accent, fontFamily: 'Manrope, sans-serif' }}>{mv.label}</div>
|
||||
<p style={{ fontSize: 'clamp(22px, 2.5vw, 36px)', fontWeight: 800, lineHeight: 1.25, color: mv.textColor, fontFamily: 'Sora, sans-serif', margin: 0, letterSpacing: '-0.02em' }}>
|
||||
{mv.body}
|
||||
</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── VALUES ── */}
|
||||
<section style={{ padding: '140px 8%', background: '#fff', margin: '0 20px 20px', borderRadius: 24 }}>
|
||||
<Reveal>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: '#f4be28', fontFamily: 'Manrope, sans-serif', marginBottom: 20 }}>How We Work</div>
|
||||
<h2 style={{ fontSize: 'clamp(36px, 5vw, 72px)', fontWeight: 900, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#0a0a0f', margin: '0 0 80px', fontFamily: 'Sora, sans-serif' }}>
|
||||
What we believe.
|
||||
</h2>
|
||||
</Reveal>
|
||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
{VALUES.map((v, i) => (
|
||||
<Reveal key={i} delay={i * 0.08}>
|
||||
<div style={{
|
||||
display: 'grid', gridTemplateColumns: '80px 1fr 1fr',
|
||||
gap: '4vw', alignItems: 'center',
|
||||
padding: '40px 0', borderBottom: '1px solid rgba(0,0,0,0.07)',
|
||||
}}>
|
||||
<span style={{ fontSize: 13, fontWeight: 700, color: '#f4be28', fontFamily: 'Sora, sans-serif', letterSpacing: '0.06em' }}>{v.n}</span>
|
||||
<h3 style={{ fontSize: 'clamp(20px, 2.5vw, 36px)', fontWeight: 800, color: '#0a0a0f', fontFamily: 'Sora, sans-serif', margin: 0, letterSpacing: '-0.03em' }}>{v.title}</h3>
|
||||
<p style={{ fontSize: 16, color: 'rgba(0,0,0,0.45)', fontFamily: 'Manrope, sans-serif', margin: 0, lineHeight: 1.65 }}>{v.desc}</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── TEAM ── */}
|
||||
<TeamCarousel />
|
||||
|
||||
{/* ── CULTURE CLOSE ── */}
|
||||
<section style={{
|
||||
padding: '160px 8%', background: '#f4be28',
|
||||
margin: '0 20px 20px', borderRadius: 24,
|
||||
display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center',
|
||||
position: 'relative', overflow: 'hidden',
|
||||
}}>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse at 50% 0%,rgba(255,255,255,0.2) 0%,transparent 60%)', pointerEvents: 'none' }} />
|
||||
<Reveal>
|
||||
<p style={{ fontSize: 'clamp(32px, 6vw, 90px)', fontWeight: 900, letterSpacing: '-0.05em', lineHeight: 0.95, color: '#111', margin: '0 0 48px', fontFamily: 'Sora, sans-serif', position: 'relative', zIndex: 2 }}>
|
||||
"We're not just building a product. We're redefining retail."
|
||||
</p>
|
||||
<Link href="/contacts" style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 10,
|
||||
padding: '18px 44px', background: '#111', color: '#f4be28',
|
||||
fontSize: 16, fontWeight: 800, borderRadius: 100, textDecoration: 'none',
|
||||
fontFamily: 'Manrope, sans-serif', position: 'relative', zIndex: 2,
|
||||
}}>Join Us →</Link>
|
||||
</Reveal>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Team Carousel ─────────────────────────────────────────────────────── */
|
||||
|
||||
const TEAM_MEMBERS = [
|
||||
{ name: 'Coming Soon', role: 'Co-Founder & CEO', gradient: 'linear-gradient(160deg,#1a0a3a 0%,#4a2080 100%)', initials: '?' },
|
||||
{ name: 'Coming Soon', role: 'Head of Product', gradient: 'linear-gradient(160deg,#0a1a3a 0%,#1a5080 100%)', initials: '?' },
|
||||
{ name: 'Coming Soon', role: 'Lead Engineer', gradient: 'linear-gradient(160deg,#1a1200 0%,#f4be28 100%)', initials: '✦' },
|
||||
{ name: 'Coming Soon', role: 'Head of Design', gradient: 'linear-gradient(160deg,#0a2a1a 0%,#1a8050 100%)', initials: '?' },
|
||||
{ name: 'Coming Soon', role: 'Growth & Marketing', gradient: 'linear-gradient(160deg,#2a0a1a 0%,#80203a 100%)', initials: '?' },
|
||||
];
|
||||
|
||||
function TeamCarousel() {
|
||||
const [active, setActive] = useState(2);
|
||||
|
||||
const CARD_W = 320;
|
||||
const CARD_GAP = 24;
|
||||
const STEP = CARD_W + CARD_GAP;
|
||||
|
||||
return (
|
||||
<section style={{ padding: '100px 0 120px', background: '#07070d', margin: '0 20px 20px', borderRadius: 24, overflow: 'hidden', position: 'relative' }}>
|
||||
{/* Grid bg */}
|
||||
<div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', 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: '60px 60px' }} />
|
||||
|
||||
{/* Header */}
|
||||
<div style={{ textAlign: 'center', marginBottom: 72, position: 'relative', zIndex: 2, padding: '0 8%' }}>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: '#f4be28', fontFamily: 'Manrope, sans-serif', marginBottom: 16 }}>The Team</div>
|
||||
<h2 style={{ fontSize: 'clamp(36px, 5vw, 72px)', fontWeight: 900, letterSpacing: '-0.04em', lineHeight: 0.95, color: '#fff', margin: '0 0 16px', fontFamily: 'Sora, sans-serif' }}>
|
||||
Builders. Thinkers.<br />Retail obsessives.
|
||||
</h2>
|
||||
<p style={{ fontSize: 15, color: 'rgba(255,255,255,0.35)', fontFamily: 'Manrope, sans-serif', margin: 0 }}>
|
||||
Profiles coming soon — we're still busy building the future of retail.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Carousel viewport */}
|
||||
<div style={{ position: 'relative', zIndex: 2, height: 'clamp(380px,48vw,560px)', overflow: 'hidden' }}>
|
||||
{/* Sliding track — translate so active card is always centered */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
gap: CARD_GAP,
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
left: '50%',
|
||||
transform: `translateX(calc(-50% - ${(active - 2) * STEP}px))`,
|
||||
transition: 'transform 0.6s cubic-bezier(0.22,1,0.36,1)',
|
||||
paddingLeft: STEP * 2,
|
||||
paddingRight: STEP * 2,
|
||||
}}>
|
||||
{TEAM_MEMBERS.map((member, i) => {
|
||||
const dist = Math.abs(i - active);
|
||||
const isActive = i === active;
|
||||
const scale = isActive ? 1 : dist === 1 ? 0.82 : 0.68;
|
||||
const blur = isActive ? 0 : dist === 1 ? 2 : 4;
|
||||
const opacity = isActive ? 1 : dist === 1 ? 0.72 : 0.42;
|
||||
const cardH = isActive ? '100%' : dist === 1 ? '82%' : '68%';
|
||||
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
onClick={() => setActive(i)}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
width: CARD_W,
|
||||
height: cardH,
|
||||
borderRadius: 32,
|
||||
background: member.gradient,
|
||||
cursor: isActive ? 'default' : 'pointer',
|
||||
filter: `blur(${blur}px)`,
|
||||
transform: `scale(${scale})`,
|
||||
opacity,
|
||||
transition: 'all 0.6s cubic-bezier(0.22,1,0.36,1)',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
boxShadow: isActive ? '0 40px 100px rgba(0,0,0,0.75)' : '0 10px 40px rgba(0,0,0,0.35)',
|
||||
border: isActive ? '1.5px solid rgba(244,190,40,0.4)' : '1px solid rgba(255,255,255,0.07)',
|
||||
alignSelf: 'center',
|
||||
}}
|
||||
>
|
||||
{/* Dark gradient overlay */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg,transparent 45%,rgba(0,0,0,0.8) 100%)', zIndex: 2 }} />
|
||||
|
||||
{/* Watermark */}
|
||||
<div style={{
|
||||
position: 'absolute', top: '40%', left: '50%',
|
||||
transform: 'translate(-50%,-50%)',
|
||||
fontSize: 96, fontWeight: 900,
|
||||
color: 'rgba(255,255,255,0.06)', fontFamily: 'Sora, sans-serif',
|
||||
userSelect: 'none', pointerEvents: 'none', lineHeight: 1,
|
||||
}}>{member.initials}</div>
|
||||
|
||||
{/* Avatar */}
|
||||
<div style={{
|
||||
position: 'absolute', top: '35%', left: '50%',
|
||||
transform: 'translate(-50%,-50%)',
|
||||
width: isActive ? 76 : 52, height: isActive ? 76 : 52,
|
||||
borderRadius: '50%',
|
||||
background: 'rgba(255,255,255,0.07)',
|
||||
border: `2px solid rgba(244,190,40,${isActive ? 0.4 : 0.2})`,
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
transition: 'all 0.6s ease', zIndex: 3,
|
||||
}}>
|
||||
<div style={{ width: 26, height: 26, borderRadius: '50%', background: 'rgba(244,190,40,0.15)', border: '1px solid rgba(244,190,40,0.3)' }} />
|
||||
</div>
|
||||
|
||||
{/* Name & role */}
|
||||
<div style={{
|
||||
position: 'absolute', bottom: 0, left: 0, right: 0,
|
||||
padding: '20px 22px 26px', zIndex: 4,
|
||||
opacity: isActive ? 1 : 0,
|
||||
transition: 'opacity 0.4s ease',
|
||||
}}>
|
||||
<div style={{ fontSize: 17, fontWeight: 800, color: '#fff', fontFamily: 'Sora, sans-serif', letterSpacing: '-0.02em', marginBottom: 4 }}>{member.name}</div>
|
||||
<div style={{ fontSize: 12, color: 'rgba(255,255,255,0.5)', fontFamily: 'Manrope, sans-serif' }}>{member.role}</div>
|
||||
</div>
|
||||
|
||||
{/* Gold dot */}
|
||||
{isActive && (
|
||||
<div style={{ position: 'absolute', top: 18, right: 18, zIndex: 4, width: 10, height: 10, borderRadius: '50%', background: '#f4be28', boxShadow: '0 0 14px rgba(244,190,40,0.9)' }} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Edge fade masks */}
|
||||
<div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', background: 'linear-gradient(90deg,#07070d 0%,transparent 18%,transparent 82%,#07070d 100%)', zIndex: 10 }} />
|
||||
</div>
|
||||
|
||||
{/* Navigation dots + arrow buttons */}
|
||||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 24, marginTop: 44, position: 'relative', zIndex: 2 }}>
|
||||
|
||||
{/* Left arrow */}
|
||||
<button
|
||||
onClick={() => setActive(a => Math.max(0, a - 1))}
|
||||
disabled={active === 0}
|
||||
className="carousel-arrow"
|
||||
style={{
|
||||
width: 48, height: 48, borderRadius: '50%', border: '1.5px solid rgba(244,190,40,0.35)',
|
||||
background: active === 0 ? 'rgba(255,255,255,0.04)' : 'rgba(244,190,40,0.1)',
|
||||
color: active === 0 ? 'rgba(255,255,255,0.2)' : '#f4be28',
|
||||
cursor: active === 0 ? 'default' : 'pointer',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
transition: 'all 0.3s ease',
|
||||
animation: active > 0 ? 'arrowPulse 2s ease-in-out infinite' : 'none',
|
||||
}}
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M19 12H5M12 5l-7 7 7 7"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Dots */}
|
||||
<div style={{ display: 'flex', gap: 8 }}>
|
||||
{TEAM_MEMBERS.map((_, i) => (
|
||||
<button
|
||||
key={i}
|
||||
onClick={() => setActive(i)}
|
||||
style={{
|
||||
width: i === active ? 28 : 8, height: 8,
|
||||
borderRadius: 4, border: 'none', cursor: 'pointer', padding: 0,
|
||||
background: i === active ? '#f4be28' : 'rgba(255,255,255,0.2)',
|
||||
transition: 'all 0.35s ease',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Right arrow */}
|
||||
<button
|
||||
onClick={() => setActive(a => Math.min(TEAM_MEMBERS.length - 1, a + 1))}
|
||||
disabled={active === TEAM_MEMBERS.length - 1}
|
||||
className="carousel-arrow"
|
||||
style={{
|
||||
width: 48, height: 48, borderRadius: '50%', border: '1.5px solid rgba(244,190,40,0.35)',
|
||||
background: active === TEAM_MEMBERS.length - 1 ? 'rgba(255,255,255,0.04)' : 'rgba(244,190,40,0.1)',
|
||||
color: active === TEAM_MEMBERS.length - 1 ? 'rgba(255,255,255,0.2)' : '#f4be28',
|
||||
cursor: active === TEAM_MEMBERS.length - 1 ? 'default' : 'pointer',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
transition: 'all 0.3s ease',
|
||||
animation: active < TEAM_MEMBERS.length - 1 ? 'arrowPulse 2s ease-in-out 0.3s infinite' : 'none',
|
||||
}}
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<style>{`
|
||||
@keyframes arrowPulse {
|
||||
0%,100% { box-shadow: 0 0 0 0 rgba(244,190,40,0); transform: scale(1); }
|
||||
50% { box-shadow: 0 0 0 8px rgba(244,190,40,0.15); transform: scale(1.08); }
|
||||
}
|
||||
.carousel-arrow:hover:not(:disabled) {
|
||||
background: rgba(244,190,40,0.22) !important;
|
||||
border-color: rgba(244,190,40,0.7) !important;
|
||||
transform: scale(1.12) !important;
|
||||
box-shadow: 0 0 20px rgba(244,190,40,0.3) !important;
|
||||
}
|
||||
`}</style>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user