refactor: replace RobotCategoryGrid with CategoryShowcaseScroll and update styles across components
- Updated HomePage to use CategoryShowcaseScroll instead of RobotCategoryGrid for better category display. - Modified BrandShowcase component to adjust background gradients and text colors for improved aesthetics. - Changed CompanyStory component to enhance visual consistency with updated accent colors. - Refined ExclusiveAccessSection to align with new design standards, including gradient adjustments. - Enhanced Hero3DRobotics with new gradient backgrounds and updated text colors for better readability. - Updated RoboticsScrollShowcase to reflect new color scheme and improved text visibility. - Adjusted RoboticsSplineShowcase to maintain design consistency with updated colors and gradients. - Improved MotionSection to enhance scroll behavior and visibility transitions. - Updated container-scroll-animation styles for better visual effects. - Introduced new CategoryShowcaseScroll component for a more dynamic category display experience.
This commit is contained in:
parent
729ab71c2c
commit
8457493f49
@ -15,7 +15,7 @@
|
||||
--color-blue-deep: #1a2e6e;
|
||||
--color-blue-bright: #3a55c4;
|
||||
--color-silver: #DEE0F0;
|
||||
--color-silver-soft: #BFC3E2;
|
||||
--color-silver-soft: #D7DBEA;
|
||||
--color-steel: #8891C7;
|
||||
--color-graphite: #221F20;
|
||||
--color-white: #FBFBFD;
|
||||
@ -23,7 +23,7 @@
|
||||
/* Accent aliases (kept for legacy class names) */
|
||||
--color-gold: #DEE0F0;
|
||||
--color-accent: #273F94;
|
||||
--color-accent-2: #BFC3E2;
|
||||
--color-accent-2: #D7DBEA;
|
||||
--color-accent-3: #8891C7;
|
||||
--color-accent-hover: #3a55c4;
|
||||
|
||||
@ -34,14 +34,14 @@
|
||||
--color-text-dim: #6a73a5;
|
||||
|
||||
/* Borders */
|
||||
--color-border: rgba(191, 195, 226, 0.18);
|
||||
--color-border-strong: rgba(191, 195, 226, 0.36);
|
||||
--color-border-light: rgba(191, 195, 226, 0.08);
|
||||
--color-border: rgba(199, 207, 230, 0.18);
|
||||
--color-border-strong: rgba(199, 207, 230, 0.36);
|
||||
--color-border-light: rgba(199, 207, 230, 0.08);
|
||||
--color-border-neutral: rgba(255, 255, 255, 0.08);
|
||||
|
||||
/* Glass */
|
||||
--color-glass-bg: rgba(28, 27, 33, 0.6);
|
||||
--color-glass-border: rgba(191, 195, 226, 0.22);
|
||||
--color-glass-border: rgba(199, 207, 230, 0.22);
|
||||
--color-glass-highlight: rgba(222, 224, 240, 0.06);
|
||||
|
||||
/* Spacing */
|
||||
@ -129,7 +129,7 @@ html {
|
||||
|
||||
/* === Typography gradients (metallic silver-blue) === */
|
||||
.text-gradient {
|
||||
background: linear-gradient(135deg, #FBFBFD 0%, #DEE0F0 45%, #8891C7 100%);
|
||||
background: linear-gradient(135deg, #FFFFFF 0%, #DEE0F0 50%, #8891C7 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
@ -137,7 +137,7 @@ html {
|
||||
}
|
||||
|
||||
.text-gradient-accent {
|
||||
background: linear-gradient(135deg, #FBFBFD 0%, #DEE0F0 35%, #BFC3E2 65%, #273F94 100%);
|
||||
background: linear-gradient(135deg, #FFFFFF 0%, #DEE0F0 50%, #8891C7 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
@ -186,8 +186,8 @@ html {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image:
|
||||
linear-gradient(rgba(191, 195, 226, 0.05) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(191, 195, 226, 0.05) 1px, transparent 1px);
|
||||
linear-gradient(rgba(199, 207, 230, 0.05) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(199, 207, 230, 0.05) 1px, transparent 1px);
|
||||
background-size: 48px 48px;
|
||||
mask-image: radial-gradient(ellipse 60% 50% at 50% 40%, #000 30%, transparent 80%);
|
||||
-webkit-mask-image: radial-gradient(ellipse 60% 50% at 50% 40%, #000 30%, transparent 80%);
|
||||
@ -213,7 +213,7 @@ html {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
background: linear-gradient(110deg, transparent 30%, rgba(191, 195, 226, 0.07) 50%, transparent 70%);
|
||||
background: linear-gradient(110deg, transparent 30%, rgba(199, 207, 230, 0.07) 50%, transparent 70%);
|
||||
background-size: 250% 100%;
|
||||
animation: lightSweep 9s ease-in-out infinite;
|
||||
mix-blend-mode: screen;
|
||||
@ -297,7 +297,7 @@ html {
|
||||
.btn-ghost {
|
||||
background: rgba(222, 224, 240, 0.04);
|
||||
color: #FBFBFD;
|
||||
border-color: rgba(191, 195, 226, 0.28);
|
||||
border-color: rgba(199, 207, 230, 0.28);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
.btn-ghost:hover {
|
||||
|
||||
@ -3,7 +3,7 @@ import { Navbar } from '@/components/Navbar';
|
||||
import { FooterAndContact } from '@/components/FooterAndContact';
|
||||
import { Hero3DRobotics } from '@/components/robotics/Hero3DRobotics';
|
||||
import { BrandShowcase } from '@/components/robotics/BrandShowcase';
|
||||
import { RobotCategoryGrid } from '@/components/robotics/RobotCategoryGrid';
|
||||
import { CategoryShowcaseScroll } from '@/components/robotics/CategoryShowcaseScroll';
|
||||
import { RobotProductCard } from '@/components/robotics/RobotProductCard';
|
||||
import { IndustryUseCases } from '@/components/robotics/IndustryUseCases';
|
||||
import { DemoCTA } from '@/components/robotics/DemoCTA';
|
||||
@ -88,9 +88,9 @@ export default function HomePage() {
|
||||
<SectionHeading
|
||||
eyebrow="Robot categories"
|
||||
title="From quadruped patrol to humanoid concierge."
|
||||
description="Find the right robot for your business humanoid for events and education, quadruped for inspection and security, service and delivery for hospitality."
|
||||
description="Find the right robot for your business — humanoid platforms for events and education, quadrupeds for inspection and security, and service robots for hospitality, delivery, and cleaning."
|
||||
/>
|
||||
<RobotCategoryGrid />
|
||||
<CategoryShowcaseScroll />
|
||||
</div>
|
||||
</MotionSection>
|
||||
|
||||
|
||||
@ -107,7 +107,7 @@ function BrandCard({
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
backgroundImage:
|
||||
'linear-gradient(rgba(191,195,226,0.04) 1px, transparent 1px), linear-gradient(90deg, rgba(191,195,226,0.04) 1px, transparent 1px)',
|
||||
'linear-gradient(rgba(199, 207, 230,0.04) 1px, transparent 1px), linear-gradient(90deg, rgba(199, 207, 230,0.04) 1px, transparent 1px)',
|
||||
backgroundSize: '32px 32px',
|
||||
maskImage: 'radial-gradient(ellipse 60% 80% at 50% 40%, #000 30%, transparent 80%)',
|
||||
WebkitMaskImage: 'radial-gradient(ellipse 60% 80% at 50% 40%, #000 30%, transparent 80%)',
|
||||
@ -198,7 +198,7 @@ function BrandCard({
|
||||
<p
|
||||
style={{
|
||||
margin: 0,
|
||||
color: '#BFC3E2',
|
||||
color: '#D7DBEA',
|
||||
fontSize: '0.92rem',
|
||||
lineHeight: 1.55,
|
||||
}}
|
||||
@ -274,7 +274,7 @@ function BrandCard({
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
backgroundImage:
|
||||
'linear-gradient(rgba(191,195,226,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(191,195,226,0.06) 1px, transparent 1px)',
|
||||
'linear-gradient(rgba(199, 207, 230,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(199, 207, 230,0.06) 1px, transparent 1px)',
|
||||
backgroundSize: '24px 24px',
|
||||
maskImage: 'radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 80%)',
|
||||
WebkitMaskImage: 'radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 80%)',
|
||||
|
||||
670
src/components/robotics/CategoryShowcaseScroll.tsx
Normal file
670
src/components/robotics/CategoryShowcaseScroll.tsx
Normal file
@ -0,0 +1,670 @@
|
||||
'use client';
|
||||
|
||||
import { useRef, useEffect, useState } from 'react';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { motion, useScroll, useTransform } from 'framer-motion';
|
||||
import { ArrowRight, Bot, Footprints, Coffee, Truck, Sparkles, Hotel, Search, Factory } from 'lucide-react';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
|
||||
type Category = {
|
||||
id: string;
|
||||
name: string;
|
||||
brand: 'Unitree' | 'Pudu Robotics' | 'Unitree + Pudu';
|
||||
brandAccent: string;
|
||||
models: string;
|
||||
description: string;
|
||||
useCases: string[];
|
||||
image: string;
|
||||
imageAlt: string;
|
||||
href: string;
|
||||
Icon: LucideIcon;
|
||||
};
|
||||
|
||||
const CATEGORIES: Category[] = [
|
||||
{
|
||||
id: 'humanoid',
|
||||
name: 'Humanoid Robots',
|
||||
brand: 'Unitree',
|
||||
brandAccent: '#DEE0F0',
|
||||
models: 'G1 · H2 · R1',
|
||||
description:
|
||||
'Bipedal humanoid platforms for events, education, research, and customer-facing experiences across the UAE.',
|
||||
useCases: ['Events & activations', 'Education & STEM', 'Research labs', 'Concierge & reception'],
|
||||
image: '/images/robots/unitree-g1.png',
|
||||
imageAlt: 'Unitree G1 humanoid robot',
|
||||
href: '/robots/?category=humanoid',
|
||||
Icon: Bot,
|
||||
},
|
||||
{
|
||||
id: 'quadruped',
|
||||
name: 'Quadruped Robots',
|
||||
brand: 'Unitree',
|
||||
brandAccent: '#DEE0F0',
|
||||
models: 'Go2 · B2 · A2',
|
||||
description:
|
||||
'Agile four-legged robots built for inspection, security patrol, and field mobility in any terrain.',
|
||||
useCases: ['Facility inspection', 'Security patrol', 'Terrain mobility', 'Robotics research'],
|
||||
image: '/images/robots/unitree-go2.png',
|
||||
imageAlt: 'Unitree Go2 quadruped robot',
|
||||
href: '/robots/?category=quadruped',
|
||||
Icon: Footprints,
|
||||
},
|
||||
{
|
||||
id: 'service',
|
||||
name: 'Service Robots',
|
||||
brand: 'Pudu Robotics',
|
||||
brandAccent: '#8891C7',
|
||||
models: 'KettyBot · BellaBot',
|
||||
description:
|
||||
'Greeting, guiding, and customer-interaction robots designed for restaurants, hotels, and retail venues.',
|
||||
useCases: ['Restaurant greeting', 'Customer guidance', 'Retail activation', 'Hospitality service'],
|
||||
image: '/images/robots/pudu-kettybot.svg',
|
||||
imageAlt: 'Pudu KettyBot service robot',
|
||||
href: '/robots/?category=service',
|
||||
Icon: Coffee,
|
||||
},
|
||||
{
|
||||
id: 'delivery',
|
||||
name: 'Delivery Robots',
|
||||
brand: 'Pudu Robotics',
|
||||
brandAccent: '#8891C7',
|
||||
models: 'BellaBot · D-Series',
|
||||
description:
|
||||
'Multi-tray autonomous delivery robots for hotels, restaurants, hospitals, and back-of-house operations.',
|
||||
useCases: ['Hotel room service', 'Restaurant delivery', 'Hospital logistics', 'Back-of-house transport'],
|
||||
image: '/images/robots/pudu-bellabot.svg',
|
||||
imageAlt: 'Pudu BellaBot delivery robot',
|
||||
href: '/robots/?category=delivery',
|
||||
Icon: Truck,
|
||||
},
|
||||
{
|
||||
id: 'cleaning',
|
||||
name: 'Cleaning Robots',
|
||||
brand: 'Pudu Robotics',
|
||||
brandAccent: '#8891C7',
|
||||
models: 'CC1 · Commercial Cleaning',
|
||||
description:
|
||||
'Autonomous commercial cleaning platforms that sweep, scrub, mop, and vacuum across large venues.',
|
||||
useCases: ['Shopping malls', 'Airports & transit', 'Hotels & resorts', 'Corporate offices'],
|
||||
image: '/images/robots/pudu-cc1.svg',
|
||||
imageAlt: 'Pudu CC1 cleaning robot',
|
||||
href: '/robots/?category=cleaning',
|
||||
Icon: Sparkles,
|
||||
},
|
||||
{
|
||||
id: 'hospitality',
|
||||
name: 'Hospitality Robots',
|
||||
brand: 'Pudu Robotics',
|
||||
brandAccent: '#8891C7',
|
||||
models: 'BellaBot · KettyBot',
|
||||
description:
|
||||
'Premium guest-facing robots for hotels, resorts, and events — designed to enhance every guest moment.',
|
||||
useCases: ['Hotel concierge', 'Resort service', 'Event activations', 'Guest experience'],
|
||||
image: '/images/robots/pudu-bellabot.svg',
|
||||
imageAlt: 'Pudu BellaBot hospitality robot',
|
||||
href: '/robots/?category=hospitality',
|
||||
Icon: Hotel,
|
||||
},
|
||||
{
|
||||
id: 'inspection',
|
||||
name: 'Inspection Robots',
|
||||
brand: 'Unitree',
|
||||
brandAccent: '#DEE0F0',
|
||||
models: 'Go2 · B2 · AS2',
|
||||
description:
|
||||
'Quadruped inspection platforms for energy, utilities, and industrial sites — equipped with rich sensor payloads.',
|
||||
useCases: ['Energy & utilities', 'Industrial sites', 'Infrastructure', 'Security patrols'],
|
||||
image: '/images/robots/unitree-b2.png',
|
||||
imageAlt: 'Unitree B2 industrial quadruped robot',
|
||||
href: '/robots/?category=inspection',
|
||||
Icon: Search,
|
||||
},
|
||||
{
|
||||
id: 'commercial',
|
||||
name: 'Commercial Automation',
|
||||
brand: 'Unitree + Pudu',
|
||||
brandAccent: '#3a55c4',
|
||||
models: 'Multi-brand portfolio',
|
||||
description:
|
||||
'Mixed robotics fleets for warehouses, smart buildings, and enterprise operations across the UAE.',
|
||||
useCases: ['Warehouses', 'Smart buildings', 'Enterprise venues', 'Mixed-fleet deployments'],
|
||||
image: '/images/robots/unitree-as2.png',
|
||||
imageAlt: 'Unitree AS2 autonomous system for commercial automation',
|
||||
href: '/robots/?category=commercial',
|
||||
Icon: Factory,
|
||||
},
|
||||
];
|
||||
|
||||
export function CategoryShowcaseScroll() {
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const check = () => setIsMobile(window.innerWidth < 900);
|
||||
check();
|
||||
window.addEventListener('resize', check);
|
||||
return () => window.removeEventListener('resize', check);
|
||||
}, []);
|
||||
|
||||
if (isMobile) return <CategoryStack />;
|
||||
return <CategorySticky />;
|
||||
}
|
||||
|
||||
function CategorySticky() {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const { scrollYProgress } = useScroll({
|
||||
target: containerRef,
|
||||
offset: ['start start', 'end end'],
|
||||
});
|
||||
const [activeIdx, setActiveIdx] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
return scrollYProgress.on('change', (v) => {
|
||||
const idx = Math.min(
|
||||
CATEGORIES.length - 1,
|
||||
Math.max(0, Math.floor(v * CATEGORIES.length))
|
||||
);
|
||||
setActiveIdx(idx);
|
||||
});
|
||||
}, [scrollYProgress]);
|
||||
|
||||
/* progress bar height */
|
||||
const progressHeight = useTransform(scrollYProgress, [0, 1], ['0%', '100%']);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
style={{
|
||||
position: 'relative',
|
||||
/* 65vh per category — total ~520vh feels responsive, not endless */
|
||||
height: `${CATEGORIES.length * 65}vh`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'sticky',
|
||||
top: '5.5rem',
|
||||
/* fill the viewport — no empty area below the panel during sticky */
|
||||
height: 'calc(100svh - 6.5rem)',
|
||||
maxHeight: '780px',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'minmax(0, 0.95fr) minmax(0, 1.05fr)',
|
||||
gap: 'clamp(1.5rem, 3vw, 2.5rem)',
|
||||
alignItems: 'stretch',
|
||||
}}
|
||||
>
|
||||
{/* LEFT — sticky text column with progress + active category */}
|
||||
<div style={{ position: 'relative', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: '0.25rem 0', minWidth: 0 }}>
|
||||
{/* progress rail */}
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: 2,
|
||||
background: 'rgba(136,145,199,0.15)',
|
||||
borderRadius: 1,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
aria-hidden
|
||||
>
|
||||
<motion.div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: progressHeight,
|
||||
background: 'linear-gradient(180deg, #DEE0F0, #3a55c4)',
|
||||
boxShadow: '0 0 12px rgba(58,85,196,0.6)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* category list */}
|
||||
<div style={{ paddingLeft: '1.25rem', display: 'flex', flexDirection: 'column', gap: '0.4rem', maxHeight: '32vh', overflow: 'hidden' }}>
|
||||
<span className="eyebrow" style={{ marginBottom: '0.5rem' }}>Robot categories · 8</span>
|
||||
{CATEGORIES.map((c, i) => (
|
||||
<button
|
||||
key={c.id}
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const el = containerRef.current;
|
||||
if (!el) return;
|
||||
const rect = el.getBoundingClientRect();
|
||||
const targetY = window.scrollY + rect.top + (rect.height * (i + 0.5)) / CATEGORIES.length;
|
||||
window.scrollTo({ top: targetY - window.innerHeight / 2, behavior: 'smooth' });
|
||||
}}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.55rem',
|
||||
padding: '0.4rem 0',
|
||||
background: 'transparent',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
textAlign: 'left',
|
||||
color: i === activeIdx ? '#FBFBFD' : '#6a73a5',
|
||||
fontSize: i === activeIdx ? '1rem' : '0.85rem',
|
||||
fontWeight: i === activeIdx ? 600 : 500,
|
||||
letterSpacing: '-0.005em',
|
||||
transition: 'color 0.3s, font-size 0.3s',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
aria-hidden
|
||||
style={{
|
||||
width: i === activeIdx ? 18 : 8,
|
||||
height: 1,
|
||||
background: i === activeIdx ? '#DEE0F0' : '#3a3d52',
|
||||
transition: 'width 0.3s, background 0.3s',
|
||||
}}
|
||||
/>
|
||||
<span style={{ fontSize: '0.65rem', letterSpacing: '0.18em', color: '#6a73a5' }}>
|
||||
{String(i + 1).padStart(2, '0')}
|
||||
</span>
|
||||
{c.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* active category copy */}
|
||||
<div style={{ paddingLeft: '1.25rem', marginTop: '1rem', display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
<motion.h2
|
||||
key={`title-${activeIdx}`}
|
||||
initial={{ opacity: 0, y: 14 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.45, ease: [0.16, 1, 0.3, 1] }}
|
||||
style={{
|
||||
margin: 0,
|
||||
fontSize: 'clamp(1.6rem, 3.4vw, 2.4rem)',
|
||||
fontWeight: 300,
|
||||
lineHeight: 1.1,
|
||||
letterSpacing: '-0.03em',
|
||||
}}
|
||||
>
|
||||
<span className="text-gradient" style={{ fontWeight: 500 }}>
|
||||
{CATEGORIES[activeIdx].name}
|
||||
</span>
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
key={`desc-${activeIdx}`}
|
||||
initial={{ opacity: 0, y: 14 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.45, delay: 0.05, ease: [0.16, 1, 0.3, 1] }}
|
||||
style={{
|
||||
margin: 0,
|
||||
color: '#DEE0F0',
|
||||
fontSize: 'clamp(0.92rem, 1.7vw, 1rem)',
|
||||
lineHeight: 1.65,
|
||||
maxWidth: 500,
|
||||
}}
|
||||
>
|
||||
{CATEGORIES[activeIdx].description}
|
||||
</motion.p>
|
||||
|
||||
<motion.div
|
||||
key={`cta-${activeIdx}`}
|
||||
initial={{ opacity: 0, y: 14 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.45, delay: 0.12, ease: [0.16, 1, 0.3, 1] }}
|
||||
style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}
|
||||
>
|
||||
<Link
|
||||
href={CATEGORIES[activeIdx].href}
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.4rem',
|
||||
padding: '0.7rem 1.2rem',
|
||||
borderRadius: 999,
|
||||
background: 'linear-gradient(135deg, #3a55c4 0%, #273F94 55%, #1a2e6e 100%)',
|
||||
color: '#FBFBFD',
|
||||
fontSize: '0.72rem',
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.16em',
|
||||
textTransform: 'uppercase',
|
||||
textDecoration: 'none',
|
||||
boxShadow: '0 12px 32px rgba(39,63,148,0.45)',
|
||||
}}
|
||||
>
|
||||
Explore robots
|
||||
<ArrowRight size={13} />
|
||||
</Link>
|
||||
<Link
|
||||
href="/book-demo/"
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.4rem',
|
||||
padding: '0.7rem 1.2rem',
|
||||
borderRadius: 999,
|
||||
border: '1px solid rgba(222,224,240,0.28)',
|
||||
background: 'rgba(255,255,255,0.04)',
|
||||
color: '#DEE0F0',
|
||||
fontSize: '0.72rem',
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.16em',
|
||||
textTransform: 'uppercase',
|
||||
textDecoration: 'none',
|
||||
}}
|
||||
>
|
||||
Book demo
|
||||
<ArrowRight size={13} />
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* RIGHT — visual stage */}
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
borderRadius: 24,
|
||||
overflow: 'hidden',
|
||||
background:
|
||||
`radial-gradient(ellipse 70% 50% at 50% 60%, rgba(58,85,196,0.28) 0%, transparent 65%), linear-gradient(180deg, rgba(28,27,33,0.85), rgba(8,8,10,0.97))`,
|
||||
border: '1px solid rgba(222,224,240,0.14)',
|
||||
boxShadow: '0 30px 90px rgba(0,0,0,0.7), inset 0 1px 0 rgba(222,224,240,0.06)',
|
||||
}}
|
||||
>
|
||||
{/* metallic edge */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
borderRadius: 24,
|
||||
padding: 1,
|
||||
background:
|
||||
'linear-gradient(135deg, rgba(222,224,240,0.32), transparent 45%, rgba(58,85,196,0.22))',
|
||||
WebkitMask: 'linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)',
|
||||
WebkitMaskComposite: 'xor',
|
||||
maskComposite: 'exclude',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
{/* grid */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
backgroundImage:
|
||||
'linear-gradient(rgba(199, 207, 230,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(199, 207, 230,0.06) 1px, transparent 1px)',
|
||||
backgroundSize: '36px 36px',
|
||||
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%)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
{/* spotlight */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '5%',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: '70%',
|
||||
height: '70%',
|
||||
background:
|
||||
'radial-gradient(ellipse 60% 70% at 50% 35%, rgba(58,85,196,0.45) 0%, transparent 65%)',
|
||||
filter: 'blur(14px)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* top floating brand chip */}
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '1.25rem',
|
||||
left: '1.25rem',
|
||||
zIndex: 5,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.5rem',
|
||||
padding: '0.4rem 0.85rem',
|
||||
borderRadius: 999,
|
||||
background: 'rgba(14,13,18,0.7)',
|
||||
border: `1px solid ${CATEGORIES[activeIdx].brandAccent}55`,
|
||||
color: CATEGORIES[activeIdx].brandAccent,
|
||||
fontSize: '0.65rem',
|
||||
fontWeight: 800,
|
||||
letterSpacing: '0.24em',
|
||||
textTransform: 'uppercase',
|
||||
backdropFilter: 'blur(8px)',
|
||||
transition: 'border-color 0.4s, color 0.4s',
|
||||
}}
|
||||
>
|
||||
<span style={{ width: 6, height: 6, borderRadius: 999, background: CATEGORIES[activeIdx].brandAccent }} />
|
||||
{CATEGORIES[activeIdx].brand}
|
||||
</div>
|
||||
|
||||
{/* top-right index */}
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '1.25rem',
|
||||
right: '1.25rem',
|
||||
zIndex: 5,
|
||||
fontSize: 'clamp(2rem, 4vw, 3rem)',
|
||||
fontWeight: 800,
|
||||
color: 'transparent',
|
||||
WebkitTextStroke: '1px rgba(222,224,240,0.32)',
|
||||
letterSpacing: '-0.04em',
|
||||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
{String(activeIdx + 1).padStart(2, '0')}
|
||||
<span style={{ color: '#6a73a5', WebkitTextStroke: 0, fontSize: '0.7rem', letterSpacing: '0.2em', marginLeft: 4 }}>
|
||||
/ {String(CATEGORIES.length).padStart(2, '0')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* product stage — cross-fade per category */}
|
||||
<div style={{ position: 'absolute', inset: 0 }}>
|
||||
{CATEGORIES.map((c, i) => (
|
||||
<motion.div
|
||||
key={c.id}
|
||||
aria-hidden={i !== activeIdx}
|
||||
initial={false}
|
||||
animate={{
|
||||
opacity: i === activeIdx ? 1 : 0,
|
||||
scale: i === activeIdx ? 1 : 0.94,
|
||||
filter: i === activeIdx ? 'blur(0px)' : 'blur(6px)',
|
||||
}}
|
||||
transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1] }}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'center',
|
||||
padding: 'clamp(1.5rem, 4vw, 3rem)',
|
||||
paddingBottom: '32%',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
filter:
|
||||
'drop-shadow(0 32px 50px rgba(0,0,0,0.78)) drop-shadow(0 0 32px rgba(58,85,196,0.45))',
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={c.image}
|
||||
alt={c.imageAlt}
|
||||
fill
|
||||
sizes="(max-width: 768px) 90vw, 620px"
|
||||
style={{ objectFit: 'contain', objectPosition: 'center bottom' }}
|
||||
priority={i === 0}
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* floor line */}
|
||||
<div
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '6%',
|
||||
right: '6%',
|
||||
bottom: '32%',
|
||||
height: 1,
|
||||
background: 'linear-gradient(90deg, transparent, rgba(222,224,240,0.55), transparent)',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* floor reflection */}
|
||||
{CATEGORIES.map((c, i) => (
|
||||
<motion.div
|
||||
key={`r-${c.id}`}
|
||||
aria-hidden
|
||||
initial={false}
|
||||
animate={{ opacity: i === activeIdx ? 0.3 : 0 }}
|
||||
transition={{ duration: 0.7 }}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 'clamp(1.5rem, 4vw, 3rem)',
|
||||
right: 'clamp(1.5rem, 4vw, 3rem)',
|
||||
bottom: '6%',
|
||||
height: '22%',
|
||||
transform: 'scaleY(-1)',
|
||||
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%)',
|
||||
pointerEvents: 'none',
|
||||
filter: 'blur(1.4px)',
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={c.image}
|
||||
alt=""
|
||||
fill
|
||||
sizes="(max-width: 768px) 90vw, 620px"
|
||||
style={{ objectFit: 'contain', objectPosition: 'center top' }}
|
||||
/>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{/* bottom info bar: models + use cases */}
|
||||
<motion.div
|
||||
key={`info-${activeIdx}`}
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: 0.08, ease: [0.16, 1, 0.3, 1] }}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: '1rem',
|
||||
left: '1rem',
|
||||
right: '1rem',
|
||||
zIndex: 5,
|
||||
padding: '0.875rem 1.1rem',
|
||||
borderRadius: 16,
|
||||
background: 'rgba(14,13,18,0.78)',
|
||||
border: '1px solid rgba(222,224,240,0.16)',
|
||||
backdropFilter: 'blur(14px)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '0.55rem',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-between', gap: '0.5rem' }}>
|
||||
<span style={{ fontSize: '0.62rem', color: '#8891C7', letterSpacing: '0.24em', textTransform: 'uppercase', fontWeight: 700 }}>
|
||||
Featured models
|
||||
</span>
|
||||
<span style={{ fontSize: '0.85rem', color: '#FBFBFD', fontWeight: 600 }}>
|
||||
{CATEGORIES[activeIdx].models}
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.35rem' }}>
|
||||
{CATEGORIES[activeIdx].useCases.map((u) => (
|
||||
<span
|
||||
key={u}
|
||||
style={{
|
||||
fontSize: '0.66rem',
|
||||
padding: '0.22rem 0.55rem',
|
||||
borderRadius: 999,
|
||||
background: 'rgba(255,255,255,0.04)',
|
||||
border: '1px solid rgba(222,224,240,0.18)',
|
||||
color: '#D7DBEA',
|
||||
letterSpacing: '0.04em',
|
||||
}}
|
||||
>
|
||||
{u}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function CategoryStack() {
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
{CATEGORIES.map((c, i) => (
|
||||
<Link
|
||||
key={c.id}
|
||||
href={c.href}
|
||||
style={{
|
||||
position: 'relative',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'minmax(0, 1fr) 130px',
|
||||
gap: '0.75rem',
|
||||
padding: '1rem',
|
||||
borderRadius: 18,
|
||||
background:
|
||||
`radial-gradient(ellipse 70% 80% at 100% 0%, ${c.brandAccent}1F, transparent 60%), linear-gradient(135deg, rgba(28,27,33,0.85), rgba(8,8,10,0.96))`,
|
||||
border: `1px solid ${c.brandAccent}33`,
|
||||
color: '#FBFBFD',
|
||||
textDecoration: 'none',
|
||||
overflow: 'hidden',
|
||||
minHeight: 150,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', minWidth: 0 }}>
|
||||
<span style={{ fontSize: '0.6rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8891C7', fontWeight: 700 }}>
|
||||
{String(i + 1).padStart(2, '0')} · {c.brand}
|
||||
</span>
|
||||
<h3 style={{ margin: 0, fontSize: '1.05rem', fontWeight: 700, letterSpacing: '-0.01em' }}>
|
||||
{c.name}
|
||||
</h3>
|
||||
<p style={{ margin: 0, color: '#D7DBEA', fontSize: '0.82rem', lineHeight: 1.5 }}>
|
||||
{c.description}
|
||||
</p>
|
||||
<span style={{ marginTop: 'auto', display: 'inline-flex', alignItems: 'center', gap: '0.35rem', color: c.brandAccent, fontSize: '0.68rem', letterSpacing: '0.18em', textTransform: 'uppercase', fontWeight: 700 }}>
|
||||
Explore
|
||||
<ArrowRight size={12} />
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
borderRadius: 12,
|
||||
overflow: 'hidden',
|
||||
background:
|
||||
`radial-gradient(ellipse 70% 50% at 50% 60%, ${c.brandAccent}22 0%, transparent 65%), linear-gradient(180deg, rgba(28,27,33,0.7), rgba(10,10,12,0.95))`,
|
||||
border: '1px solid rgba(222,224,240,0.08)',
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={c.image}
|
||||
alt={c.imageAlt}
|
||||
fill
|
||||
sizes="130px"
|
||||
style={{ objectFit: 'contain', padding: '0.5rem' }}
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -31,7 +31,7 @@ const PILLARS: Pillar[] = [
|
||||
title: 'Digital Transformation',
|
||||
body: 'Automation systems and smart projects that modernize operations.',
|
||||
Icon: Workflow,
|
||||
accent: '#BFC3E2',
|
||||
accent: '#D7DBEA',
|
||||
},
|
||||
{
|
||||
num: '04',
|
||||
@ -63,7 +63,7 @@ export function CompanyStory() {
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
backgroundImage:
|
||||
'linear-gradient(rgba(191,195,226,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(191,195,226,0.06) 1px, transparent 1px)',
|
||||
'linear-gradient(rgba(199, 207, 230,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(199, 207, 230,0.06) 1px, transparent 1px)',
|
||||
backgroundSize: '36px 36px',
|
||||
maskImage: 'radial-gradient(ellipse 70% 80% at 50% 40%, #000 25%, transparent 80%)',
|
||||
WebkitMaskImage: 'radial-gradient(ellipse 70% 80% at 50% 40%, #000 25%, transparent 80%)',
|
||||
@ -348,7 +348,7 @@ function CapabilityTile({ pillar, offset }: { pillar: Pillar; offset: 'up' | 'do
|
||||
margin: 0,
|
||||
fontSize: '0.88rem',
|
||||
lineHeight: 1.55,
|
||||
color: '#BFC3E2',
|
||||
color: '#D7DBEA',
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
|
||||
@ -189,7 +189,7 @@ function BrandShowcaseTile({
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
backgroundImage:
|
||||
'linear-gradient(rgba(191,195,226,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(191,195,226,0.06) 1px, transparent 1px)',
|
||||
'linear-gradient(rgba(199, 207, 230,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(199, 207, 230,0.06) 1px, transparent 1px)',
|
||||
backgroundSize: '24px 24px',
|
||||
maskImage: 'radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 80%)',
|
||||
WebkitMaskImage: 'radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 80%)',
|
||||
@ -334,7 +334,7 @@ function TerritoryTile() {
|
||||
<circle cx="155" cy="55" r="32" fill="none" stroke="#DEE0F0" strokeOpacity="0.45" strokeDasharray="2 4" />
|
||||
<circle cx="155" cy="55" r="22" fill="none" stroke="#DEE0F0" strokeOpacity="0.65" />
|
||||
<circle cx="155" cy="55" r="3.5" fill="#DEE0F0" />
|
||||
<text x="160" y="44" fontFamily="Inter, sans-serif" fontSize="8" letterSpacing="3" fill="#BFC3E2" textAnchor="start">DXB</text>
|
||||
<text x="160" y="44" fontFamily="Inter, sans-serif" fontSize="8" letterSpacing="3" fill="#D7DBEA" textAnchor="start">DXB</text>
|
||||
</svg>
|
||||
<div style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<span style={{ fontSize: '0.62rem', color: '#8891C7', letterSpacing: '0.22em', textTransform: 'uppercase', fontWeight: 700 }}>
|
||||
|
||||
@ -141,7 +141,7 @@ export function Hero3DRobotics() {
|
||||
display: 'block',
|
||||
fontWeight: 600,
|
||||
background:
|
||||
'linear-gradient(110deg, #FBFBFD 0%, #DEE0F0 28%, #BFC3E2 55%, #3a55c4 100%)',
|
||||
'linear-gradient(110deg, #FFFFFF 0%, #DEE0F0 50%, #8891C7 100%)',
|
||||
WebkitBackgroundClip: 'text',
|
||||
backgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent',
|
||||
@ -157,7 +157,7 @@ export function Hero3DRobotics() {
|
||||
<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 }}>
|
||||
<p style={{ margin: 0, color: '#D7DBEA', fontSize: '0.78rem', letterSpacing: '0.32em', textTransform: 'uppercase', fontWeight: 600 }}>
|
||||
In Tech We Innovate · In Trust We Lead
|
||||
</p>
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ const SHOWROOM_ROBOTS = [
|
||||
slug: 'unitree-go2',
|
||||
image: '/images/robots/unitree-go2.png',
|
||||
category: 'Quadruped',
|
||||
accent: '#BFC3E2',
|
||||
accent: '#D7DBEA',
|
||||
},
|
||||
{
|
||||
name: 'Pudu BellaBot',
|
||||
@ -58,10 +58,10 @@ export function RoboticsScrollShowcase() {
|
||||
</span>
|
||||
<h2 className="text-4xl font-light leading-[1.05] tracking-[-0.035em] text-white sm:text-5xl md:text-6xl lg:text-7xl">
|
||||
Advanced robotics.
|
||||
<span className="block bg-gradient-to-r from-white via-[#DEE0F0] to-[#3a55c4] bg-clip-text font-semibold text-transparent">
|
||||
<span className="block bg-gradient-to-r from-white via-[#DEE0F0] to-[#8891C7] bg-clip-text font-semibold text-transparent">
|
||||
Exclusive UAE access.
|
||||
</span>
|
||||
<span className="mt-3 block text-base font-normal text-[#BFC3E2] sm:text-lg md:text-xl">
|
||||
<span className="mt-3 block text-base font-normal text-[#D7DBEA] sm:text-lg md:text-xl">
|
||||
Built for Dubai's next generation of automation.
|
||||
</span>
|
||||
</h2>
|
||||
@ -92,14 +92,14 @@ function ConsoleInterior() {
|
||||
className={`flex items-center gap-2.5 rounded-lg border px-3 py-2 text-left text-xs font-semibold uppercase tracking-[0.12em] transition ${
|
||||
t.active
|
||||
? 'border-[#DEE0F0]/40 bg-[#273F94]/30 text-[#DEE0F0]'
|
||||
: 'border-transparent text-[#BFC3E2]/80 hover:bg-white/[0.04]'
|
||||
: 'border-transparent text-[#D7DBEA]/80 hover:bg-white/[0.04]'
|
||||
}`}
|
||||
>
|
||||
<t.icon className="h-3.5 w-3.5" />
|
||||
{t.label}
|
||||
</button>
|
||||
))}
|
||||
<div className="mt-auto rounded-xl border border-[#DEE0F0]/10 bg-[#221F20]/60 p-3 text-[10px] uppercase tracking-[0.18em] text-[#BFC3E2]/70">
|
||||
<div className="mt-auto rounded-xl border border-[#DEE0F0]/10 bg-[#221F20]/60 p-3 text-[10px] uppercase tracking-[0.18em] text-[#D7DBEA]/70">
|
||||
<span className="block text-[#DEE0F0]">YS Lootah Robotics</span>
|
||||
In Tech We Innovate
|
||||
</div>
|
||||
@ -169,7 +169,7 @@ function ConsoleInterior() {
|
||||
</Link>
|
||||
<Link
|
||||
href="/contact/"
|
||||
className="inline-flex items-center gap-1.5 rounded-full border border-[#DEE0F0]/30 px-3.5 py-2 text-[10px] font-bold uppercase tracking-[0.16em] text-[#BFC3E2] md:text-[11px]"
|
||||
className="inline-flex items-center gap-1.5 rounded-full border border-[#DEE0F0]/30 px-3.5 py-2 text-[10px] font-bold uppercase tracking-[0.16em] text-[#D7DBEA] md:text-[11px]"
|
||||
>
|
||||
Request UAE quotation
|
||||
</Link>
|
||||
|
||||
@ -99,7 +99,7 @@ export function RoboticsSplineShowcase() {
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
background:
|
||||
'linear-gradient(110deg, #FBFBFD 0%, #DEE0F0 35%, #BFC3E2 60%, #3a55c4 100%)',
|
||||
'linear-gradient(110deg, #FFFFFF 0%, #DEE0F0 50%, #8891C7 100%)',
|
||||
WebkitBackgroundClip: 'text',
|
||||
backgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent',
|
||||
@ -190,7 +190,7 @@ export function RoboticsSplineShowcase() {
|
||||
borderRadius: 999,
|
||||
border: '1px solid rgba(136,145,199,0.5)',
|
||||
background: 'transparent',
|
||||
color: '#BFC3E2',
|
||||
color: '#D7DBEA',
|
||||
fontSize: '0.78rem',
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.14em',
|
||||
@ -231,7 +231,7 @@ export function RoboticsSplineShowcase() {
|
||||
>
|
||||
<item.Icon size={18} style={{ color: '#DEE0F0', marginBottom: '0.5rem' }} />
|
||||
<div style={{ fontSize: '0.85rem', fontWeight: 600, color: '#FBFBFD' }}>{item.label}</div>
|
||||
<div style={{ marginTop: 4, fontSize: '0.66rem', letterSpacing: '0.2em', textTransform: 'uppercase', color: 'rgba(191,195,226,0.72)' }}>
|
||||
<div style={{ marginTop: 4, fontSize: '0.66rem', letterSpacing: '0.2em', textTransform: 'uppercase', color: 'rgba(199, 207, 230,0.72)' }}>
|
||||
{item.value}
|
||||
</div>
|
||||
</div>
|
||||
@ -246,7 +246,7 @@ export function RoboticsSplineShowcase() {
|
||||
fontWeight: 600,
|
||||
letterSpacing: '0.32em',
|
||||
textTransform: 'uppercase',
|
||||
color: '#BFC3E2',
|
||||
color: '#D7DBEA',
|
||||
}}
|
||||
>
|
||||
In Tech We Innovate · In Trust We Lead
|
||||
@ -308,7 +308,7 @@ export function RoboticsSplineShowcase() {
|
||||
backdropFilter: 'blur(12px)',
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: '0.62rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: 'rgba(191,195,226,0.7)' }}>
|
||||
<div style={{ fontSize: '0.62rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: 'rgba(199, 207, 230,0.7)' }}>
|
||||
YS Lootah Robotics
|
||||
</div>
|
||||
<div style={{ marginTop: 4, fontSize: '0.88rem', fontWeight: 600, color: '#FBFBFD' }}>
|
||||
|
||||
@ -32,7 +32,7 @@ export function MotionSection({ children, className = '', id, delay = 0, style }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ threshold: 0.12 }
|
||||
{ threshold: 0, rootMargin: '0px 0px -10% 0px' }
|
||||
);
|
||||
obs.observe(el);
|
||||
return () => obs.disconnect();
|
||||
@ -45,7 +45,9 @@ export function MotionSection({ children, className = '', id, delay = 0, style }
|
||||
className={className}
|
||||
style={{
|
||||
opacity: visible ? 1 : 0,
|
||||
transform: visible ? 'translateY(0)' : 'translateY(28px)',
|
||||
// when hidden, lift via translate. When visible, drop transform entirely so
|
||||
// child position:sticky behaves correctly (transformed ancestor would break sticky).
|
||||
...(visible ? {} : { transform: 'translateY(28px)' }),
|
||||
transition: `opacity 0.9s cubic-bezier(0.16,1,0.3,1) ${delay}s, transform 0.9s cubic-bezier(0.16,1,0.3,1) ${delay}s`,
|
||||
scrollMarginTop: '6rem',
|
||||
...style,
|
||||
|
||||
@ -113,7 +113,7 @@ function DisplayFrame({
|
||||
/>
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none absolute inset-0 bg-[linear-gradient(rgba(191,195,226,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(191,195,226,0.06)_1px,transparent_1px)] bg-[size:42px_42px] [mask-image:radial-gradient(ellipse_70%_70%_at_50%_50%,#000_30%,transparent_82%)]"
|
||||
className="pointer-events-none absolute inset-0 bg-[linear-gradient(rgba(199, 207, 230,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(199, 207, 230,0.06)_1px,transparent_1px)] bg-[size:42px_42px] [mask-image:radial-gradient(ellipse_70%_70%_at_50%_50%,#000_30%,transparent_82%)]"
|
||||
/>
|
||||
{/* status bar */}
|
||||
<div className="absolute left-0 right-0 top-0 z-20 flex items-center justify-between border-b border-[#DEE0F0]/10 bg-[#0a0a0c]/80 px-4 py-2.5 backdrop-blur-xl">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user