feat: add robotics showcase components and UI enhancements
- Introduced FounderSection component to highlight leadership and vision. - Created ServicesGrid component to display various robotics services offered. - Developed RoboticsScrollShowcase for showcasing robots with interactive elements. - Implemented RoboticsSplineShowcase featuring a 3D Spline scene for enhanced user experience. - Added reusable Card component for consistent styling across sections. - Integrated ContainerScroll for animated scrolling effects in the showcase. - Built SplineScene component for lazy loading Spline 3D scenes. - Added Spotlight component for interactive hover effects. - Created utility function for class name merging to streamline styling.
This commit is contained in:
@@ -8,9 +8,9 @@ import { CursorSpotlight } from '@/components/ui/CursorSpotlight';
|
||||
import { FEATURED_ROBOTS } from '@/data/robots';
|
||||
|
||||
const HERO_STATS = [
|
||||
{ value: 'Exclusive', label: 'UAE access' },
|
||||
{ value: '2', label: 'Premier brands' },
|
||||
{ value: 'Dubai', label: 'Showroom & demo' },
|
||||
{ value: 'Exclusive', label: 'UAE Access' },
|
||||
{ value: 'Unitree + Pudu', label: 'Premier brands' },
|
||||
{ value: 'Dubai', label: 'Showroom & Demo' },
|
||||
];
|
||||
|
||||
type LabelPos = {
|
||||
@@ -22,12 +22,27 @@ type LabelPos = {
|
||||
right?: string;
|
||||
};
|
||||
|
||||
const FLOATING_LABELS: LabelPos[] = [
|
||||
{ text: 'Exclusive UAE Access', top: '10%', left: '5%', delay: 0 },
|
||||
{ text: 'Unitree Robotics', top: '22%', right: '4%', delay: 0.3 },
|
||||
{ text: 'Pudu Service Robots', bottom: '28%', left: '4%', delay: 0.6 },
|
||||
{ text: 'Demo & Sales · Dubai', bottom: '12%', right: '6%', delay: 0.9 },
|
||||
];
|
||||
/* Labels keyed to active robot brand/category for accuracy */
|
||||
function getLabelsFor(brand: string, category: string): LabelPos[] {
|
||||
const brandLabel = brand === 'unitree' ? 'Unitree Robotics' : 'Pudu Robotics';
|
||||
const categoryLabel =
|
||||
category === 'humanoid'
|
||||
? 'Humanoid Platform'
|
||||
: category === 'quadruped'
|
||||
? 'Quadruped Patrol'
|
||||
: category === 'delivery'
|
||||
? 'Delivery Automation'
|
||||
: category === 'service'
|
||||
? 'Service Robotics'
|
||||
: category === 'cleaning'
|
||||
? 'Cleaning Automation'
|
||||
: 'Advanced Robotics';
|
||||
return [
|
||||
{ text: brandLabel, top: '11%', right: '4%', delay: 0.15 },
|
||||
{ text: categoryLabel, bottom: '32%', left: '4%', delay: 0.4 },
|
||||
{ text: 'Demo & Sales · Dubai', bottom: '11%', right: '6%', delay: 0.65 },
|
||||
];
|
||||
}
|
||||
|
||||
export function Hero3DRobotics() {
|
||||
const wrapRef = useRef<HTMLDivElement | null>(null);
|
||||
@@ -43,7 +58,7 @@ export function Hero3DRobotics() {
|
||||
const rect = el.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width - 0.5;
|
||||
const y = (e.clientY - rect.top) / rect.height - 0.5;
|
||||
setTilt({ rx: -y * 9, ry: x * 14 });
|
||||
setTilt({ rx: -y * 8, ry: x * 12 });
|
||||
};
|
||||
const onLeave = () => setTilt({ rx: 0, ry: 0 });
|
||||
el.addEventListener('mousemove', onMove);
|
||||
@@ -55,11 +70,12 @@ export function Hero3DRobotics() {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const t = setInterval(() => setActiveIdx((i) => (i + 1) % FEATURED_ROBOTS.length), 5400);
|
||||
const t = setInterval(() => setActiveIdx((i) => (i + 1) % FEATURED_ROBOTS.length), 5600);
|
||||
return () => clearInterval(t);
|
||||
}, []);
|
||||
|
||||
const robot = FEATURED_ROBOTS[activeIdx];
|
||||
const labels = getLabelsFor(robot.brand, robot.category);
|
||||
|
||||
return (
|
||||
<section
|
||||
@@ -75,15 +91,17 @@ export function Hero3DRobotics() {
|
||||
>
|
||||
<div className="hero-gradient" />
|
||||
<div className="grid-overlay" />
|
||||
<CursorSpotlight color="rgba(224, 200, 150, 0.22)" size={620} />
|
||||
<div className="light-sweep" />
|
||||
<CursorSpotlight color="rgba(58, 85, 196, 0.28)" size={640} />
|
||||
|
||||
{/* Royal-blue beams */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
background:
|
||||
'conic-gradient(from 220deg at 60% 50%, transparent 0deg, rgba(196,162,101,0.06) 25deg, transparent 50deg, rgba(224,200,150,0.05) 180deg, transparent 220deg, rgba(196,162,101,0.05) 320deg, transparent 360deg)',
|
||||
'conic-gradient(from 220deg at 60% 50%, transparent 0deg, rgba(39,63,148,0.10) 25deg, transparent 50deg, rgba(222,224,240,0.06) 180deg, transparent 220deg, rgba(58,85,196,0.10) 320deg, transparent 360deg)',
|
||||
mixBlendMode: 'screen',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
@@ -95,16 +113,16 @@ export function Hero3DRobotics() {
|
||||
<span
|
||||
className="eyebrow"
|
||||
style={{
|
||||
color: '#e0c896',
|
||||
border: '1px solid rgba(196,162,101,0.35)',
|
||||
background: 'rgba(196,162,101,0.06)',
|
||||
color: '#DEE0F0',
|
||||
border: '1px solid rgba(136,145,199,0.45)',
|
||||
background: 'rgba(39,63,148,0.10)',
|
||||
padding: '0.5rem 0.9rem',
|
||||
borderRadius: 999,
|
||||
alignSelf: 'flex-start',
|
||||
gap: '0.625rem',
|
||||
}}
|
||||
>
|
||||
<span aria-hidden style={{ width: 6, height: 6, borderRadius: 999, background: '#e0c896', boxShadow: '0 0 12px rgba(224,200,150,0.8)' }} />
|
||||
<span aria-hidden style={{ width: 6, height: 6, borderRadius: 999, background: '#DEE0F0', boxShadow: '0 0 12px rgba(222,224,240,0.9)' }} />
|
||||
Exclusive UAE Access · Dubai
|
||||
</span>
|
||||
|
||||
@@ -117,15 +135,31 @@ export function Hero3DRobotics() {
|
||||
fontWeight: 300,
|
||||
}}
|
||||
>
|
||||
<span style={{ display: 'block', color: '#f5f1e8', fontWeight: 200 }}>Advanced robotics.</span>
|
||||
<span className="text-gradient-accent" style={{ display: 'block', fontWeight: 600 }}>
|
||||
<span style={{ display: 'block', color: '#FBFBFD', fontWeight: 200 }}>Advanced robotics.</span>
|
||||
<span
|
||||
style={{
|
||||
display: 'block',
|
||||
fontWeight: 600,
|
||||
background:
|
||||
'linear-gradient(110deg, #FBFBFD 0%, #DEE0F0 28%, #BFC3E2 55%, #3a55c4 100%)',
|
||||
WebkitBackgroundClip: 'text',
|
||||
backgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent',
|
||||
color: 'transparent',
|
||||
filter:
|
||||
'drop-shadow(0 2px 12px rgba(222,224,240,0.18)) drop-shadow(0 6px 28px rgba(58,85,196,0.32))',
|
||||
}}
|
||||
>
|
||||
Exclusive UAE access.
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(1rem, 2vw, 1.18rem)', lineHeight: 1.7, maxWidth: 600, fontWeight: 300 }}>
|
||||
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(1rem, 2vw, 1.18rem)', lineHeight: 1.7, maxWidth: 600, fontWeight: 300 }}>
|
||||
YS Lootah Robotics is the exclusive UAE sales destination for selected Unitree and Pudu Robotics solutions — helping businesses explore, configure, book demos, and deploy advanced robots across Dubai and the UAE.
|
||||
</p>
|
||||
<p style={{ margin: 0, color: '#BFC3E2', fontSize: '0.78rem', letterSpacing: '0.32em', textTransform: 'uppercase', fontWeight: 600 }}>
|
||||
In Tech We Innovate · In Trust We Lead
|
||||
</p>
|
||||
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.75rem', marginTop: '0.5rem' }}>
|
||||
<PremiumButton href="/robots/">Explore exclusive robots</PremiumButton>
|
||||
@@ -137,18 +171,28 @@ export function Hero3DRobotics() {
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
|
||||
gap: 'clamp(0.5rem, 2vw, 1.25rem)',
|
||||
paddingTop: '1.25rem',
|
||||
marginTop: '0.5rem',
|
||||
borderTop: '1px solid rgba(196,162,101,0.18)',
|
||||
gap: 'clamp(0.75rem, 2.4vw, 1.75rem)',
|
||||
paddingTop: '1.75rem',
|
||||
paddingBottom: '0.5rem',
|
||||
marginTop: '0.75rem',
|
||||
marginBottom: 'clamp(0.5rem, 2vw, 1.5rem)',
|
||||
borderTop: '1px solid rgba(136,145,199,0.22)',
|
||||
}}
|
||||
>
|
||||
{HERO_STATS.map((s) => (
|
||||
<div key={s.label} style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem' }}>
|
||||
<span className="text-gradient-accent" style={{ fontSize: 'clamp(1.3rem, 2.6vw, 1.8rem)', fontWeight: 700, letterSpacing: '-0.02em' }}>
|
||||
<div key={s.label} style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
|
||||
<span
|
||||
className="text-gradient-accent"
|
||||
style={{
|
||||
fontSize: 'clamp(1.1rem, 2.2vw, 1.5rem)',
|
||||
fontWeight: 700,
|
||||
letterSpacing: '-0.01em',
|
||||
lineHeight: 1.1,
|
||||
}}
|
||||
>
|
||||
{s.value}
|
||||
</span>
|
||||
<span style={{ fontSize: '0.7rem', color: '#94908a', letterSpacing: '0.22em', textTransform: 'uppercase' }}>
|
||||
<span style={{ fontSize: '0.66rem', color: '#8891C7', letterSpacing: '0.24em', textTransform: 'uppercase', fontWeight: 600 }}>
|
||||
{s.label}
|
||||
</span>
|
||||
</div>
|
||||
@@ -160,18 +204,36 @@ export function Hero3DRobotics() {
|
||||
ref={wrapRef}
|
||||
style={{
|
||||
position: 'relative',
|
||||
perspective: '1500px',
|
||||
minHeight: 'clamp(420px, 56vw, 620px)',
|
||||
perspective: '1600px',
|
||||
minHeight: 'clamp(440px, 58vw, 660px)',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
{/* Outer blue glow */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: '-3rem',
|
||||
background:
|
||||
`radial-gradient(ellipse 60% 50% at 50% 50%, ${robot.accent}55 0%, transparent 65%)`,
|
||||
filter: 'blur(28px)',
|
||||
`radial-gradient(ellipse 60% 50% at 50% 45%, ${robot.accent}55 0%, transparent 65%)`,
|
||||
filter: 'blur(34px)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Floor halo */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: '-2rem',
|
||||
left: '8%',
|
||||
right: '8%',
|
||||
height: '8%',
|
||||
background:
|
||||
'radial-gradient(ellipse 50% 100% at 50% 100%, rgba(58,85,196,0.5), transparent 75%)',
|
||||
filter: 'blur(18px)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
@@ -182,26 +244,28 @@ export function Hero3DRobotics() {
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
minHeight: 'clamp(420px, 56vw, 620px)',
|
||||
minHeight: 'clamp(440px, 58vw, 660px)',
|
||||
borderRadius: '1.75rem',
|
||||
background:
|
||||
'linear-gradient(180deg, rgba(20,17,11,0.7) 0%, rgba(5,5,5,0.92) 100%)',
|
||||
border: '1px solid rgba(196,162,101,0.28)',
|
||||
backdropFilter: 'blur(18px)',
|
||||
'linear-gradient(180deg, rgba(28,27,33,0.78) 0%, rgba(10,10,12,0.95) 100%)',
|
||||
border: '1px solid rgba(136,145,199,0.32)',
|
||||
backdropFilter: 'blur(20px)',
|
||||
boxShadow:
|
||||
'0 30px 100px rgba(0,0,0,0.75), inset 0 1px 0 rgba(255,240,200,0.08), 0 0 60px rgba(196,162,101,0.15)',
|
||||
'0 30px 100px rgba(0,0,0,0.8), inset 0 1px 0 rgba(222,224,240,0.1), 0 0 70px rgba(39,63,148,0.22)',
|
||||
transform: `rotateX(${tilt.rx}deg) rotateY(${tilt.ry}deg)`,
|
||||
transition: 'transform 0.25s ease-out',
|
||||
transition: 'transform 0.3s cubic-bezier(0.16,1,0.3,1)',
|
||||
overflow: 'hidden',
|
||||
transformStyle: 'preserve-3d',
|
||||
}}
|
||||
>
|
||||
{/* Grid floor */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
background:
|
||||
'linear-gradient(rgba(196,162,101,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(196,162,101,0.06) 1px, transparent 1px)',
|
||||
'linear-gradient(rgba(136,145,199,0.07) 1px, transparent 1px), linear-gradient(90deg, rgba(136,145,199,0.07) 1px, transparent 1px)',
|
||||
backgroundSize: '40px 40px',
|
||||
maskImage: 'radial-gradient(ellipse 70% 70% at 50% 50%, #000 30%, transparent 80%)',
|
||||
WebkitMaskImage: 'radial-gradient(ellipse 70% 70% at 50% 50%, #000 30%, transparent 80%)',
|
||||
@@ -209,22 +273,43 @@ export function Hero3DRobotics() {
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Royal-blue stage spotlight behind robot */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: '-30%',
|
||||
top: '12%',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: '70%',
|
||||
height: '60%',
|
||||
height: '70%',
|
||||
background:
|
||||
'radial-gradient(ellipse 50% 50% at 50% 30%, rgba(224,200,150,0.30) 0%, transparent 70%)',
|
||||
filter: 'blur(20px)',
|
||||
'radial-gradient(ellipse 60% 70% at 50% 35%, rgba(58,85,196,0.45) 0%, rgba(39,63,148,0.25) 35%, transparent 70%)',
|
||||
filter: 'blur(14px)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Light beam from top */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: '60%',
|
||||
height: '60%',
|
||||
background:
|
||||
'linear-gradient(180deg, rgba(222,224,240,0.18) 0%, rgba(58,85,196,0.12) 35%, transparent 75%)',
|
||||
clipPath: 'polygon(35% 0, 65% 0, 90% 100%, 10% 100%)',
|
||||
filter: 'blur(8px)',
|
||||
mixBlendMode: 'screen',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Robot image — main (enlarged ~12%) */}
|
||||
{FEATURED_ROBOTS.map((r, idx) => (
|
||||
<div
|
||||
key={r.id}
|
||||
@@ -232,55 +317,175 @@ export function Hero3DRobotics() {
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'center',
|
||||
padding: 'clamp(1.5rem, 5vw, 3rem)',
|
||||
paddingTop: 'clamp(0.75rem, 2.5vw, 1.5rem)',
|
||||
paddingBottom: '30%',
|
||||
paddingLeft: 'clamp(0.5rem, 2vw, 1rem)',
|
||||
paddingRight: 'clamp(0.5rem, 2vw, 1rem)',
|
||||
opacity: idx === activeIdx ? 1 : 0,
|
||||
transform: idx === activeIdx ? 'translateY(0) scale(1)' : 'translateY(14px) scale(0.97)',
|
||||
transition: 'opacity 0.9s ease, transform 0.9s ease',
|
||||
transform:
|
||||
idx === activeIdx
|
||||
? `translateY(0) translateX(${tilt.ry * 0.45}px) scale(1.12)`
|
||||
: 'translateY(22px) scale(0.97)',
|
||||
transformOrigin: 'center bottom',
|
||||
transition: 'opacity 1s ease, transform 0.9s cubic-bezier(0.16,1,0.3,1)',
|
||||
filter:
|
||||
idx === activeIdx
|
||||
? 'drop-shadow(0 32px 50px rgba(0,0,0,0.85)) drop-shadow(0 18px 28px rgba(0,0,0,0.6)) drop-shadow(0 0 36px rgba(58,85,196,0.55))'
|
||||
: 'none',
|
||||
willChange: 'transform',
|
||||
}}
|
||||
aria-hidden={idx !== activeIdx}
|
||||
>
|
||||
<div style={{ position: 'relative', width: '100%', height: '100%' }}>
|
||||
<Image
|
||||
src={r.image}
|
||||
alt={`${r.brandLabel} ${r.name}`}
|
||||
fill
|
||||
sizes="(max-width: 768px) 90vw, 720px"
|
||||
style={{ objectFit: 'contain', objectPosition: 'center bottom' }}
|
||||
priority={idx === 0}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Stronger drop-shadow ellipse under robot */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '20%',
|
||||
right: '20%',
|
||||
bottom: '24%',
|
||||
height: '5%',
|
||||
background:
|
||||
'radial-gradient(ellipse 60% 100% at 50% 100%, rgba(0,0,0,0.85), transparent 70%)',
|
||||
filter: 'blur(10px)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Floor reflection (mirror image, faded, blue-tinted) */}
|
||||
{FEATURED_ROBOTS.map((r, idx) => (
|
||||
<div
|
||||
key={`reflect-${r.id}`}
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 'clamp(0.5rem, 2vw, 1rem)',
|
||||
right: 'clamp(0.5rem, 2vw, 1rem)',
|
||||
bottom: '4%',
|
||||
height: '24%',
|
||||
opacity: idx === activeIdx ? 0.32 : 0,
|
||||
transform: `scaleY(-1) translateX(${tilt.ry * 0.45}px) scale(1.12)`,
|
||||
transformOrigin: 'center top',
|
||||
maskImage:
|
||||
'linear-gradient(to bottom, rgba(0,0,0,0.8), transparent 78%)',
|
||||
WebkitMaskImage:
|
||||
'linear-gradient(to bottom, rgba(0,0,0,0.8), transparent 78%)',
|
||||
transition: 'opacity 1s ease, transform 0.9s cubic-bezier(0.16,1,0.3,1)',
|
||||
pointerEvents: 'none',
|
||||
filter: 'blur(1.4px) hue-rotate(220deg)',
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={r.image}
|
||||
alt={`${r.brandLabel} ${r.name}`}
|
||||
alt=""
|
||||
fill
|
||||
sizes="(max-width: 768px) 90vw, 620px"
|
||||
style={{ objectFit: 'contain', padding: 'clamp(1rem, 4vw, 2rem)' }}
|
||||
priority={idx === 0}
|
||||
sizes="(max-width: 768px) 90vw, 720px"
|
||||
style={{ objectFit: 'contain', objectPosition: 'center top' }}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Floor line */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '28%',
|
||||
height: 1,
|
||||
background:
|
||||
'linear-gradient(90deg, transparent, rgba(222,224,240,0.6), transparent)',
|
||||
pointerEvents: 'none',
|
||||
filter: 'blur(0.3px)',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Edge glass glare — silver/blue rim light */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
borderRadius: '1.75rem',
|
||||
background:
|
||||
'linear-gradient(135deg, rgba(222,224,240,0.18) 0%, transparent 18%, transparent 80%, rgba(58,85,196,0.22) 100%)',
|
||||
mixBlendMode: 'screen',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: '10%',
|
||||
right: '10%',
|
||||
height: '2px',
|
||||
background:
|
||||
'linear-gradient(90deg, transparent, rgba(222,224,240,0.5), transparent)',
|
||||
pointerEvents: 'none',
|
||||
filter: 'blur(0.4px)',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Floating labels — keyed to active robot + parallax */}
|
||||
<div className="hero-labels" aria-hidden>
|
||||
{FLOATING_LABELS.map((l) => (
|
||||
<span
|
||||
key={l.text}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: l.top,
|
||||
bottom: l.bottom,
|
||||
left: l.left,
|
||||
right: l.right,
|
||||
padding: '0.4rem 0.75rem',
|
||||
borderRadius: 999,
|
||||
background: 'rgba(10,9,7,0.7)',
|
||||
border: '1px solid rgba(196,162,101,0.3)',
|
||||
color: '#e0c896',
|
||||
fontSize: '0.66rem',
|
||||
letterSpacing: '0.22em',
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: 600,
|
||||
backdropFilter: 'blur(8px)',
|
||||
animation: `floatY 6s ease-in-out ${l.delay}s infinite`,
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{l.text}
|
||||
</span>
|
||||
))}
|
||||
{labels.map((l, i) => {
|
||||
/* labels drift opposite to tilt for parallax depth */
|
||||
const depth = (i + 1) * 0.6;
|
||||
const dx = tilt.ry * depth;
|
||||
const dy = tilt.rx * depth;
|
||||
return (
|
||||
<span
|
||||
key={`${activeIdx}-${l.text}`}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: l.top,
|
||||
bottom: l.bottom,
|
||||
left: l.left,
|
||||
right: l.right,
|
||||
padding: '0.45rem 0.8rem',
|
||||
borderRadius: 999,
|
||||
background: 'rgba(14,13,18,0.78)',
|
||||
border: '1px solid rgba(136,145,199,0.45)',
|
||||
color: '#DEE0F0',
|
||||
fontSize: '0.66rem',
|
||||
letterSpacing: '0.22em',
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: 600,
|
||||
backdropFilter: 'blur(10px)',
|
||||
animation: `floatY 6s ease-in-out ${l.delay}s infinite, fadeInUp 0.9s cubic-bezier(0.16,1,0.3,1) ${l.delay}s both`,
|
||||
whiteSpace: 'nowrap',
|
||||
boxShadow:
|
||||
'0 10px 28px rgba(0,0,0,0.55), 0 0 18px rgba(58,85,196,0.18), inset 0 1px 0 rgba(222,224,240,0.08)',
|
||||
transform: `translate3d(${dx}px, ${dy}px, 0)`,
|
||||
transition: 'transform 0.35s cubic-bezier(0.16,1,0.3,1)',
|
||||
willChange: 'transform',
|
||||
}}
|
||||
>
|
||||
{l.text}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Featured card + dot nav */}
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
@@ -292,6 +497,7 @@ export function Hero3DRobotics() {
|
||||
justifyContent: 'space-between',
|
||||
gap: '1rem',
|
||||
flexWrap: 'wrap',
|
||||
zIndex: 5,
|
||||
}}
|
||||
>
|
||||
<Link
|
||||
@@ -300,22 +506,23 @@ export function Hero3DRobotics() {
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.75rem',
|
||||
padding: '0.65rem 1rem',
|
||||
padding: '0.7rem 1.1rem',
|
||||
borderRadius: 14,
|
||||
background: 'rgba(10,9,7,0.7)',
|
||||
border: '1px solid rgba(196,162,101,0.35)',
|
||||
backdropFilter: 'blur(10px)',
|
||||
color: '#f5f1e8',
|
||||
background: 'rgba(14,13,18,0.72)',
|
||||
border: '1px solid rgba(136,145,199,0.45)',
|
||||
backdropFilter: 'blur(12px)',
|
||||
color: '#FBFBFD',
|
||||
textDecoration: 'none',
|
||||
boxShadow: '0 10px 30px rgba(0,0,0,0.5)',
|
||||
}}
|
||||
>
|
||||
<span style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<span style={{ fontSize: '0.62rem', color: '#94908a', letterSpacing: '0.24em', textTransform: 'uppercase' }}>
|
||||
<span style={{ fontSize: '0.62rem', color: '#8891C7', letterSpacing: '0.24em', textTransform: 'uppercase' }}>
|
||||
Featured · {robot.brandLabel}
|
||||
</span>
|
||||
<span style={{ fontSize: '0.95rem', fontWeight: 600 }}>{robot.name}</span>
|
||||
</span>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={robot.accent} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#DEE0F0" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" />
|
||||
</svg>
|
||||
@@ -328,11 +535,13 @@ export function Hero3DRobotics() {
|
||||
onClick={() => setActiveIdx(idx)}
|
||||
aria-label={`Show ${r.name}`}
|
||||
style={{
|
||||
width: idx === activeIdx ? 24 : 8,
|
||||
width: idx === activeIdx ? 26 : 8,
|
||||
height: 8,
|
||||
borderRadius: 999,
|
||||
border: 'none',
|
||||
background: idx === activeIdx ? r.accent : 'rgba(196,162,101,0.3)',
|
||||
background: idx === activeIdx
|
||||
? 'linear-gradient(90deg, #DEE0F0, #3a55c4)'
|
||||
: 'rgba(136,145,199,0.4)',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.4s ease',
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user