Reachy_Mini / src /pages /Home.jsx
apirrone
update
02c9e04
import { useState, useEffect } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import {
Box,
Container,
Typography,
Button,
Grid,
Stack,
Link,
} from '@mui/material';
import { useSpring, animated } from '@react-spring/web';
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import Layout from '../components/Layout';
import Section from '../components/Section';
// Floating Sticker Component with scroll parallax
function FloatingSticker({ src, size, top, left, right, bottom, rotation = 0, floatRange = 15, floatSpeed = 6000, scrollFactor = 0.05 }) {
const [floatOffset, setFloatOffset] = useState(0);
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
let startTime = Date.now();
let animationFrame;
const animate = () => {
const elapsed = Date.now() - startTime;
const offset = Math.sin((elapsed / floatSpeed) * Math.PI * 2) * floatRange;
setFloatOffset(offset);
animationFrame = requestAnimationFrame(animate);
};
animationFrame = requestAnimationFrame(animate);
return () => cancelAnimationFrame(animationFrame);
}, [floatSpeed, floatRange]);
useEffect(() => {
const handleScroll = () => setScrollY(window.scrollY);
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const springProps = useSpring({
transform: `translateY(${floatOffset + scrollY * scrollFactor}px) rotate(${rotation}deg)`,
config: { mass: 3, tension: 80, friction: 40 },
});
return (
<animated.img
src={src}
alt=""
style={{
position: 'absolute',
top, left, right, bottom,
width: size,
height: 'auto',
pointerEvents: 'none',
zIndex: 2,
...springProps,
}}
/>
);
}
// Hero Section
function Hero() {
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => setScrollY(window.scrollY);
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const videoParallax = useSpring({
transform: `translate(-45%, calc(-50% + ${scrollY * 0.15}px))`,
config: { mass: 1, tension: 280, friction: 60 },
});
return (
<Box
sx={{
position: 'relative',
minHeight: { xs: '85vh', md: '80vh' },
display: 'flex',
alignItems: 'center',
backgroundColor: '#000',
overflow: 'hidden',
// Curved bottom edge
'&::after': {
content: '""',
position: 'absolute',
bottom: -1,
left: 0,
right: 0,
height: { xs: 60, md: 90 },
background: 'inherit',
backgroundColor: 'background.default',
borderRadius: '100% 100% 0 0 / 100% 100% 0 0',
transform: 'translateY(50%)',
},
}}
>
<animated.video
autoPlay
muted
loop
playsInline
style={{
position: 'absolute',
top: '50%',
left: '50%',
minWidth: '100%',
minHeight: '100%',
width: 'auto',
height: 'auto',
opacity: 0.9,
...videoParallax,
}}
>
<source src="/assets/Reachy-mini-wake-up-companion.mp4" type="video/mp4" />
</animated.video>
{/* Overlay gradients + vignette */}
<Box
sx={{
position: 'absolute',
inset: 0,
background: `
linear-gradient(to right, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.15) 100%),
linear-gradient(to top, rgba(0,0,0,0.6) 0%, transparent 40%),
radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,0.4) 100%)
`,
}}
/>
<Container maxWidth="lg" sx={{ position: 'relative', zIndex: 10 }}>
<Box sx={{ maxWidth: 640 }}>
<Stack direction="row" spacing={1} alignItems="center" sx={{ mb: 2 }}>
<Typography
sx={{
color: 'rgba(255,255,255,0.6)',
fontSize: 13,
fontWeight: 500,
}}
>
Open Source Robot
</Typography>
<Box sx={{ width: 4, height: 4, borderRadius: '50%', bgcolor: 'rgba(255,255,255,0.3)' }} />
<Typography
sx={{
color: 'rgba(255,255,255,0.6)',
fontSize: 13,
fontWeight: 500,
display: 'flex',
alignItems: 'center',
gap: 0.5,
}}
>
Powered by <Box component="img" src="/assets/hf-logo.svg" alt="Hugging Face" sx={{ height: 14 }} />
</Typography>
</Stack>
<Box sx={{ position: 'relative', display: 'inline-block', mb: 2 }}>
<Typography
variant="h1"
component="h1"
sx={{
color: 'white',
background: 'linear-gradient(135deg, #ffffff 0%, rgba(255,255,255,0.85) 100%)',
backgroundClip: 'text',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
}}
>
Reachy Mini
</Typography>
</Box>
<Typography
variant="h5"
component="p"
sx={{
color: 'rgba(255,255,255,0.75)',
fontWeight: 400,
mb: 4,
lineHeight: 1.6,
maxWidth: 520,
}}
>
An expressive companion robot designed for{' '}
<Box component="span" sx={{ color: 'white', fontWeight: 500 }}>
human interaction
</Box>
,{' '}
<Box component="span" sx={{ color: 'white', fontWeight: 500 }}>
creative coding
</Box>
, and{' '}
<Box component="span" sx={{ color: 'white', fontWeight: 500 }}>
AI experimentation
</Box>
.
</Typography>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
<Button
component={RouterLink}
to="/buy"
variant="contained"
size="large"
sx={{
px: 4,
py: 1.75,
fontSize: 16,
fontWeight: 600,
background: 'linear-gradient(135deg, #FF9500 0%, #ff7b00 100%)',
boxShadow: '0 4px 24px rgba(255, 149, 0, 0.35)',
'&:hover': {
boxShadow: '0 8px 32px rgba(255, 149, 0, 0.5)',
transform: 'translateY(-2px)',
},
}}
>
Buy Reachy Mini
</Button>
<Button
variant="outlined"
size="large"
component={RouterLink}
to="/getting-started"
sx={{
px: 4,
py: 1.75,
fontSize: 16,
fontWeight: 600,
color: 'rgba(255,255,255,0.9)',
borderColor: 'rgba(255,255,255,0.3)',
'&:hover': {
color: 'white',
borderColor: 'rgba(255,255,255,0.6)',
backgroundColor: 'rgba(255,255,255,0.05)'
},
}}
>
Get Started
</Button>
</Stack>
</Box>
</Container>
</Box>
);
}
// Stats/Bento Section - Sober backgrounds, illustrations for color
function StatsSection() {
return (
<Section id="stats" sx={{ py: { xs: 8, md: 12 }, position: 'relative', overflow: 'visible' }}>
<Grid container spacing={2}>
{/* Big stat - Open Source */}
<Grid size={{ xs: 12, md: 8 }}>
<Box
component={RouterLink}
to="/getting-started"
sx={{
height: { xs: 280, md: 320 },
borderRadius: 4,
background: '#0f0f1a',
border: '1px solid rgba(255,255,255,0.08)',
p: { xs: 4, md: 6 },
position: 'relative',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
// Clip only bottom and sides, allow top overflow
clipPath: 'inset(-100px 0 0 0 round 16px)',
textDecoration: 'none',
color: 'inherit',
cursor: 'pointer',
transition: 'border-color 0.3s ease, transform 0.3s ease',
'&:hover': {
borderColor: 'rgba(255,255,255,0.2)',
transform: 'translateY(-2px)',
},
}}
>
{/* Hacker illustration - overflows top */}
<Box
component="img"
src="/assets/reachies/plumber.png"
alt=""
sx={{
position: 'absolute',
top: -50,
right: 20,
height: 350,
opacity: 1,
pointerEvents: 'none',
display: { xs: 'none', sm: 'block' },
}}
/>
<Box sx={{ position: 'relative', zIndex: 1 }}>
<Typography
sx={{
fontSize: { xs: 50, md: 60 },
fontWeight: 800,
lineHeight: 1,
color: 'white',
}}
>
Build your own <br />
robot
</Typography>
<Typography
variant="h4"
sx={{ color: 'white', fontWeight: 600, mt: 1 }}
>
Get Started
</Typography>
</Box>
<Typography sx={{ color: 'rgba(255,255,255,0.5)', fontSize: 15, position: 'relative', zIndex: 1, maxWidth: 400 }}>
Follow our guides to assemble your Reachy Mini β†’
</Typography>
</Box>
</Grid>
{/* 30+ Apps with Hand Tracking GIF */}
<Grid size={{ xs: 12, sm: 6, md: 4 }}>
<Box
component={RouterLink}
to="/apps"
sx={{
height: { xs: 280, md: 320 },
borderRadius: 4,
background: '#0f0f1a',
border: '1px solid rgba(255,255,255,0.08)',
overflow: 'hidden',
position: 'relative',
textDecoration: 'none',
display: 'block',
transition: 'all 0.3s ease',
'&:hover': { borderColor: 'rgba(255,255,255,0.2)' },
}}
>
{/* GIF Background */}
<Box
component="img"
src="/assets/reachy-mini-hand-tracking.gif"
alt="Real-time interaction"
sx={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
objectFit: 'cover',
}}
/>
{/* Overlay gradient */}
<Box
sx={{
position: 'absolute',
inset: 0,
background: 'linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0.1) 100%)',
}}
/>
{/* Content */}
<Box
sx={{
position: 'relative',
zIndex: 1,
height: '100%',
p: { xs: 4, md: 5 },
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
}}
>
<Typography
sx={{
fontSize: { xs: 56, md: 72 },
fontWeight: 800,
lineHeight: 1,
color: 'white',
}}
>
Apps
</Typography>
<Box sx={{ mt: 1 }}>
<Typography sx={{ color: 'rgba(255,255,255,0.6)', fontSize: 14, mt: 0.5 }}>
Explore ready-to-use app β†’
</Typography>
</Box>
</Box>
</Box>
</Grid>
{/* Community */}
<Grid size={{ xs: 12, sm: 6, md: 4 }}>
<Box
component="a"
href="https://discord.gg/2bAhWfXme9"
target="_blank"
rel="noopener noreferrer"
sx={{
height: { xs: 200, md: 200 },
borderRadius: 4,
background: '#0f0f1a',
border: '1px solid rgba(255,255,255,0.08)',
p: { xs: 4, md: 5 },
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
textDecoration: 'none',
transition: 'all 0.3s ease',
'&:hover': { borderColor: 'rgba(255,255,255,0.2)' },
}}
>
<Box
component="img"
src="/assets/discord-logo.svg"
alt="Discord"
sx={{ width: 36, height: 36, opacity: 0.8 }}
/>
<Box>
<Typography variant="h5" sx={{ color: 'white', fontWeight: 600 }}>
Join our Discord Community
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.5)', fontSize: 14, mt: 0.5 }}>
We are already 4500+ Makers β†’
</Typography>
</Box>
</Box>
</Grid>
{/* Python SDK */}
<Grid size={{ xs: 12, md: 8 }}>
<Box
component="a"
href="https://github.com/pollen-robotics/reachy_mini"
target="_blank"
rel="noopener noreferrer"
sx={{
height: { xs: 200, md: 200 },
borderRadius: 4,
background: '#0d1117',
border: '1px solid rgba(255,255,255,0.08)',
p: { xs: 4, md: 5 },
display: 'flex',
alignItems: 'center',
gap: 4,
textDecoration: 'none',
transition: 'all 0.3s ease',
overflow: 'hidden',
'&:hover': { borderColor: 'rgba(255,255,255,0.2)' },
}}
>
<Box
sx={{
fontFamily: '"JetBrains Mono", monospace',
fontSize: { xs: 12, md: 14 },
color: '#e6edf3',
flex: 1,
whiteSpace: 'pre',
overflow: 'hidden',
}}
>
<Box component="span" sx={{ color: '#ff7b72' }}>from</Box>{' '}
<Box component="span" sx={{ color: '#79c0ff' }}>reachy_mini</Box>{' '}
<Box component="span" sx={{ color: '#ff7b72' }}>import</Box>{' '}
<Box component="span" sx={{ color: '#ffa657' }}>ReachyMini</Box>
{'\n\n'}
<Box component="span" sx={{ color: '#ff7b72' }}>with</Box>{' '}
<Box component="span" sx={{ color: '#ffa657' }}>ReachyMini</Box>
<Box component="span" sx={{ color: '#8b949e' }}>()</Box>{' '}
<Box component="span" sx={{ color: '#ff7b72' }}>as</Box>{' '}
<Box component="span" sx={{ color: '#79c0ff' }}>mini</Box>:
{'\n'}
{' '}mini.<Box component="span" sx={{ color: '#d2a8ff' }}>goto_target</Box>(head=pose)
</Box>
<Box sx={{ textAlign: 'right' }}>
<Typography variant="h5" sx={{ color: 'white', fontWeight: 600 }}>
Discover the Python SDK
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.5)', fontSize: 14, mt: 0.5 }}>
Full control in 3 lines β†’
</Typography>
</Box>
</Box>
</Grid>
</Grid>
</Section>
);
}
// Products Section - Minimal comparison
function ProductsSection() {
return (
<Section background="alt" sx={{ py: { xs: 8, md: 12 }, position: 'relative', overflow: 'visible' }}>
{/* Stickers */}
<Box sx={{ display: { xs: 'none', lg: 'block' } }}>
<FloatingSticker
src="/assets/reachies/captain.png"
size={240}
top={80}
left={60}
rotation={-8}
floatRange={12}
floatSpeed={5500}
scrollFactor={0.03}
/>
</Box>
<Box sx={{ textAlign: 'center', mb: 8 }}>
<Typography variant="h2" sx={{ mb: 2 }}>
Two ways to Reachy
</Typography>
<Typography variant="body1" color="text.secondary" sx={{ maxWidth: 500, mx: 'auto' }}>
Choose wireless for standalone use, or Lite for a budget-friendly tethered experience.
</Typography>
</Box>
<Grid container spacing={4} justifyContent="center">
{/* Wireless */}
<Grid size={{ xs: 12, md: 5 }}>
<Box
sx={{
p: 5,
borderRadius: 4,
border: '2px solid',
borderColor: 'primary.main',
background: 'linear-gradient(135deg, rgba(255,149,0,0.03) 0%, transparent 100%)',
textAlign: 'center',
position: 'relative',
}}
>
<Box
sx={{
position: 'absolute',
top: -12,
left: '50%',
transform: 'translateX(-50%)',
px: 2,
py: 0.5,
borderRadius: 50,
background: 'linear-gradient(135deg, #FF9500 0%, #ff7b00 100%)',
}}
>
<Typography sx={{ color: 'white', fontSize: 12, fontWeight: 700, textTransform: 'uppercase' }}>
Most Popular
</Typography>
</Box>
<Typography variant="h3" sx={{ mt: 2, mb: 1 }}>
Reachy Mini
</Typography>
<Typography color="text.secondary" sx={{ mb: 3 }}>
Wireless β€’ On-board compute
</Typography>
<Typography
sx={{
fontSize: 56,
fontWeight: 800,
mb: 3,
background: 'linear-gradient(135deg, #FF9500 0%, #ff7b00 100%)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
}}
>
$449
</Typography>
<Stack spacing={1} sx={{ mb: 4, textAlign: 'left', maxWidth: 280, mx: 'auto' }}>
{['Raspberry Pi 4 on-board', 'Wi-Fi + USB', 'Camera, 4 mics, speaker', 'Accelerometer'].map((item) => (
<Typography key={item} sx={{ fontSize: 14, color: 'text.secondary' }}>
βœ“ {item}
</Typography>
))}
</Stack>
<Button
variant="contained"
size="large"
fullWidth
href="https://buy.stripe.com/9B65kFfFlaKFbY34W873G03"
target="_blank"
sx={{ py: 1.5 }}
>
Order Now
</Button>
</Box>
</Grid>
{/* Lite */}
<Grid size={{ xs: 12, md: 5 }}>
<Box
sx={{
p: 5,
borderRadius: 4,
border: '1px solid',
borderColor: 'divider',
textAlign: 'center',
}}
>
<Typography variant="h3" sx={{ mt: 2, mb: 1 }}>
Reachy Mini Lite
</Typography>
<Typography color="text.secondary" sx={{ mb: 3 }}>
USB β€’ External compute
</Typography>
<Typography
sx={{
fontSize: 56,
fontWeight: 800,
mb: 3,
color: 'text.primary',
}}
>
$299
</Typography>
<Stack spacing={1} sx={{ mb: 4, textAlign: 'left', maxWidth: 280, mx: 'auto' }}>
{['Your Mac/PC as brain', 'USB only', 'Camera, 4 mics, speaker', 'Same motion capabilities'].map((item) => (
<Typography key={item} sx={{ fontSize: 14, color: 'text.secondary' }}>
βœ“ {item}
</Typography>
))}
</Stack>
<Button
variant="outlined"
size="large"
fullWidth
href="https://buy.stripe.com/6oUfZj78P1a5e6b0FS73G02"
target="_blank"
sx={{ py: 1.5 }}
>
Order Now
</Button>
</Box>
</Grid>
</Grid>
<Typography variant="body2" color="text.secondary" sx={{ textAlign: 'center', mt: 5 }}>
Both ship as DIY kits. Assembly takes ~2 hours.{' '}
<Link component={RouterLink} to="/getting-started">Watch the guide β†’</Link>
</Typography>
</Section>
);
}
// Apps Showcase - Sober design with illustrations
function AppsShowcase() {
return (
<Box
sx={{
py: { xs: 8, md: 12 },
background: '#0a0a12',
position: 'relative',
overflow: 'visible',
}}
>
{/* Sticker */}
<Box sx={{ display: { xs: 'none', lg: 'block' } }}>
<FloatingSticker
src="/assets/reachies/jazzman.png"
size={240}
top={40}
right={80}
rotation={10}
floatRange={10}
floatSpeed={5800}
scrollFactor={0.04}
/>
</Box>
<Container maxWidth="lg">
{/* Header */}
<Box sx={{ textAlign: 'center', mb: 8 }}>
<Typography
variant="overline"
sx={{ color: 'rgba(255,255,255,0.5)', mb: 2, display: 'block', letterSpacing: '0.15em' }}
>
App Ecosystem
</Typography>
<Typography
variant="h2"
sx={{ color: 'white', mb: 3 }}
>
30+ apps, one click install
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.5)', maxWidth: 500, mx: 'auto', lineHeight: 1.7 }}>
From AI conversations to hand tracking - explore what the community has built
or create your own and share it with the world.
</Typography>
</Box>
{/* Featured App - AI Companion (large) */}
<Box
sx={{
mb: 4,
borderRadius: 4,
overflow: 'hidden',
background: '#0f0f1a',
border: '1px solid rgba(255,255,255,0.08)',
display: 'flex',
flexDirection: { xs: 'column', md: 'row' },
}}
>
{/* Illustration */}
<Box
sx={{
flex: { xs: 'none', md: 1 },
height: { xs: 250, md: 'auto' },
minHeight: { md: 320 },
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden',
}}
>
<Box
component="img"
src="/assets/reachy-conversation-app.jpg"
alt="AI Companion"
sx={{
width: '100%',
height: '100%',
objectFit: 'cover',
}}
/>
</Box>
{/* Content */}
<Box
sx={{
flex: { xs: 'none', md: 1 },
p: { xs: 4, md: 6 },
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}}
>
<Box
sx={{
display: 'inline-flex',
alignItems: 'center',
gap: 1,
px: 2,
py: 0.5,
mb: 2,
borderRadius: 50,
background: 'rgba(255,255,255,0.08)',
border: '1px solid rgba(255,255,255,0.1)',
width: 'fit-content',
}}
>
<Box sx={{ width: 6, height: 6, borderRadius: '50%', bgcolor: 'rgba(255,255,255,0.5)' }} />
<Typography sx={{ color: 'rgba(255,255,255,0.7)', fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em' }}>
Featured
</Typography>
</Box>
<Typography variant="h3" sx={{ color: 'white', mb: 2 }}>
AI Companion
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.6)', mb: 4, lineHeight: 1.8, maxWidth: 400 }}>
Have a conversation with Reachy! Powered by LLMs, it understands what you say
and responds with expressive movements and speech.
</Typography>
<Button
component={RouterLink}
to="/apps"
variant="contained"
endIcon={<ArrowForwardIcon />}
>
Try it now
</Button>
</Box>
</Box>
{/* Other apps grid */}
<Grid container spacing={3}>
{/* Hand Tracking */}
<Grid size={{ xs: 12, md: 6 }}>
<Box
sx={{
borderRadius: 4,
overflow: 'hidden',
background: '#0f0f1a',
border: '1px solid rgba(255,255,255,0.08)',
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
height: { xs: 'auto', md: 200 },
transition: 'border-color 0.3s',
'&:hover': { borderColor: 'rgba(255,255,255,0.2)' },
}}
>
<Box
sx={{
width: { xs: '100%', sm: 200 },
height: { xs: 150, sm: 'auto' },
flexShrink: 0,
overflow: 'hidden',
}}
>
<Box
component="img"
src="/assets/reachy-hand-tracking-app.jpg"
alt="Hand Tracking"
sx={{
width: '100%',
height: '100%',
objectFit: 'cover',
}}
/>
</Box>
<Box sx={{ p: 3, display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
<Typography variant="h5" sx={{ color: 'white', mb: 1 }}>
Hand Tracking
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.5)', fontSize: 14, lineHeight: 1.6 }}>
Reachy follows your hand movements in real-time using OpenCV.
</Typography>
</Box>
</Box>
</Grid>
{/* More apps CTA */}
<Grid size={{ xs: 12, md: 6 }}>
<Box
component={RouterLink}
to="/apps"
sx={{
borderRadius: 4,
height: { xs: 150, md: 200 },
background: '#0f0f1a',
border: '1px solid rgba(255,255,255,0.08)',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
textDecoration: 'none',
transition: 'all 0.3s',
'&:hover': { borderColor: 'rgba(255,255,255,0.2)' },
}}
>
<Typography
sx={{
fontSize: 48,
fontWeight: 800,
color: 'white',
mb: 1,
}}
>
+28
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.7)', fontWeight: 600 }}>
more apps to explore
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.4)', fontSize: 13, mt: 0.5 }}>
Browse all β†’
</Typography>
</Box>
</Grid>
</Grid>
{/* Build your own CTA */}
<Box sx={{ textAlign: 'center', mt: 6 }}>
<Typography sx={{ color: 'rgba(255,255,255,0.4)', fontSize: 14 }}>
Got an idea?{' '}
<Link
href="https://github.com/pollen-robotics/reachy_mini"
target="_blank"
rel="noopener noreferrer"
sx={{ color: 'primary.main', textDecoration: 'none', '&:hover': { textDecoration: 'underline' } }}
>
Build your own app β†’
</Link>
</Typography>
</Box>
</Container>
</Box>
);
}
// Community Section
function CommunitySection() {
return (
<Section sx={{ py: { xs: 8, md: 12 }, position: 'relative', overflow: 'visible' }}>
<Box sx={{ display: { xs: 'none', md: 'block' } }}>
<FloatingSticker src="/assets/reachies/cowboy.png" size={280} top={-20} left={100} rotation={-10} floatRange={12} floatSpeed={5500} scrollFactor={0.04} />
<FloatingSticker src="/assets/reachies/astronaut.png" size={300} bottom={-40} right={120} rotation={8} floatRange={15} floatSpeed={6500} scrollFactor={0.05} />
</Box>
<Box
sx={{
background: '#0f0f1a',
border: '1px solid rgba(255,255,255,0.08)',
borderRadius: 4,
p: { xs: 5, md: 8 },
textAlign: 'center',
color: 'white',
position: 'relative',
}}
>
<Box sx={{ position: 'relative', zIndex: 1 }}>
<Typography variant="h2" sx={{ mb: 2 }}>
Join 4500+ makers
</Typography>
<Typography sx={{ color: 'rgba(255,255,255,0.6)', maxWidth: 500, mx: 'auto', mb: 4, lineHeight: 1.8 }}>
Connect with other Reachy Mini owners on Discord. Share your projects,
get help, and stay updated on the latest developments.
</Typography>
<Button
variant="contained"
size="large"
href="https://discord.gg/2bAhWfXme9"
target="_blank"
endIcon={<OpenInNewIcon />}
>
Join Discord
</Button>
</Box>
</Box>
</Section>
);
}
// Final CTA
function FinalCTA() {
return (
<Section background="alt" sx={{ py: { xs: 8, md: 12 } }}>
<Box sx={{ textAlign: 'center', maxWidth: 600, mx: 'auto' }}>
<Typography variant="h2" sx={{ mb: 3 }}>
Ready to meet Reachy?
</Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 5, lineHeight: 1.8 }}>
Get your own expressive companion robot and join the community of makers
building the future of human-robot interaction.
</Typography>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} justifyContent="center">
<Button
variant="contained"
size="large"
component={RouterLink}
to="/buy"
sx={{ px: 5, py: 1.75, fontSize: 16 }}
>
Buy Reachy Mini
</Button>
</Stack>
{/* <Stack direction={{ xs: 'column', sm: 'row' }} spacing={{ xs: 1, sm: 4 }} justifyContent="center" sx={{ mt: 5, color: 'text.secondary' }}>
<Typography variant="body2">βœ“ Free worldwide shipping</Typography>
<Typography variant="body2">βœ“ 30-day returns</Typography>
<Typography variant="body2">βœ“ 1-year warranty</Typography>
</Stack> */}
</Box>
</Section>
);
}
// Main Home Page
export default function Home() {
return (
<Layout transparentHeader>
<Hero />
<StatsSection />
<ProductsSection />
<AppsShowcase />
<CommunitySection />
<FinalCTA />
</Layout>
);
}