feat: enhance BrandShowcase component with improved layout and visual elements
Some checks are pending
CI/CD / test-and-build (push) Waiting to run
CI/CD / deploy (push) Blocked by required conditions

This commit is contained in:
Najjar\NajjarV02 2026-05-20 17:58:58 +04:00
parent d7c343ac7d
commit bfe589be27

View File

@ -1,96 +1,426 @@
'use client';
import Image from 'next/image';
import Link from 'next/link';
import { ArrowRight } from 'lucide-react';
import { BRANDS, ROBOTS, type RobotBrand } from '@/data/robots';
type BrandVisual = {
description: string;
chips: string[];
primary: { src: string; alt: string };
secondary?: { src: string; alt: string };
};
const BRAND_VISUALS: Record<RobotBrand, BrandVisual> = {
unitree: {
description:
'Quadruped and humanoid robotics platforms — available exclusively in the UAE through YS Lootah Robotics.',
chips: ['Quadruped', 'Humanoid', 'Inspection', 'Research'],
primary: { src: '/images/robots/unitree-g1.png', alt: 'Unitree G1 humanoid robot' },
secondary: { src: '/images/robots/unitree-go2.png', alt: 'Unitree Go2 quadruped robot' },
},
pudu: {
description:
'Service, delivery, cleaning, and hospitality robotics — available exclusively in the UAE through YS Lootah Robotics.',
chips: ['Service', 'Delivery', 'Cleaning', 'Hospitality'],
primary: { src: '/images/robots/pudu-bellabot.svg', alt: 'Pudu BellaBot delivery robot' },
secondary: { src: '/images/robots/pudu-kettybot.svg', alt: 'Pudu KettyBot service robot' },
},
};
export function BrandShowcase() {
const brandIds = Object.keys(BRANDS) as RobotBrand[];
return (
<div
style={{
display: 'grid',
gap: '1.25rem',
gridTemplateColumns: 'repeat(auto-fit, minmax(min(260px, 100%), 1fr))',
gap: 'clamp(1rem, 2vw, 1.5rem)',
gridTemplateColumns: 'repeat(auto-fit, minmax(min(360px, 100%), 1fr))',
}}
>
{brandIds.map((id) => {
const brand = BRANDS[id];
const count = ROBOTS.filter((r) => r.brand === id).length;
return (
<Link
key={id}
href={`/brands/#${id}`}
className="card"
style={{
padding: '1.75rem',
textDecoration: 'none',
color: '#FBFBFD',
display: 'flex',
flexDirection: 'column',
gap: '1rem',
minHeight: 220,
position: 'relative',
}}
>
<div
style={{
position: 'absolute',
inset: 0,
background: `radial-gradient(circle at 80% 0%, ${brand.accent}22, transparent 60%)`,
pointerEvents: 'none',
}}
/>
<div style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<div
style={{
fontSize: '1.45rem',
fontWeight: 700,
letterSpacing: '0.04em',
color: '#ffffff',
}}
>
{brand.name.split(' ')[0]}
<span style={{ color: brand.accent, marginLeft: 6 }}>
{brand.name.split(' ').slice(1).join(' ')}
</span>
</div>
<span
style={{
fontSize: '0.7rem',
letterSpacing: '0.2em',
textTransform: 'uppercase',
color: brand.accent,
}}
>
{count} model{count === 1 ? '' : 's'}
</span>
</div>
<p style={{ position: 'relative', margin: 0, color: '#8891C7', lineHeight: 1.6, fontSize: '0.95rem' }}>
{brand.tagline}
</p>
<div
style={{
position: 'relative',
marginTop: 'auto',
display: 'inline-flex',
alignItems: 'center',
gap: '0.5rem',
color: brand.accent,
fontSize: '0.8rem',
letterSpacing: '0.18em',
textTransform: 'uppercase',
fontWeight: 600,
}}
>
Explore {brand.name.split(' ')[0]}
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" 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>
</div>
</Link>
);
const visual = BRAND_VISUALS[id];
return <BrandCard key={id} id={id} brand={brand} count={count} visual={visual} />;
})}
</div>
);
}
function BrandCard({
id,
brand,
count,
visual,
}: {
id: RobotBrand;
brand: { name: string; tagline: string; description: string; url: string; accent: string };
count: number;
visual: BrandVisual;
}) {
const brandWord = brand.name.split(' ')[0];
const brandRest = brand.name.split(' ').slice(1).join(' ');
const accent = brand.accent;
return (
<Link
href={`/brands/#${id}`}
className="brand-card"
style={{
position: 'relative',
display: 'grid',
gridTemplateColumns: 'minmax(0, 1.05fr) minmax(0, 1fr)',
gap: 'clamp(0.75rem, 2vw, 1.25rem)',
padding: 'clamp(1.25rem, 2.5vw, 1.75rem)',
minHeight: 280,
borderRadius: 22,
background:
`radial-gradient(ellipse 60% 80% at 100% 0%, ${accent}1F, transparent 60%), linear-gradient(135deg, rgba(28,27,33,0.86), rgba(8,8,10,0.96))`,
border: `1px solid ${accent}33`,
color: '#FBFBFD',
textDecoration: 'none',
overflow: 'hidden',
boxShadow: '0 18px 50px rgba(0,0,0,0.6), inset 0 1px 0 rgba(222,224,240,0.06)',
transition: 'transform 0.35s cubic-bezier(0.16,1,0.3,1), border-color 0.35s ease, box-shadow 0.35s ease',
}}
>
{/* metallic edge */}
<div
aria-hidden
style={{
position: 'absolute',
inset: 0,
borderRadius: 22,
padding: 1,
background: `linear-gradient(135deg, ${accent}55, transparent 50%, ${accent}22)`,
WebkitMask: 'linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)',
WebkitMaskComposite: 'xor',
maskComposite: 'exclude',
pointerEvents: 'none',
}}
/>
{/* subtle grid */}
<div
aria-hidden
style={{
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)',
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%)',
pointerEvents: 'none',
}}
/>
{/* hover glow */}
<span
className="brand-card-glow"
aria-hidden
style={{
position: 'absolute',
inset: '-15%',
background: `radial-gradient(circle at 70% 20%, ${accent}33, transparent 60%)`,
opacity: 0,
transition: 'opacity 0.5s ease',
pointerEvents: 'none',
}}
/>
{/* LEFT — copy */}
<div
style={{
position: 'relative',
display: 'flex',
flexDirection: 'column',
gap: '0.875rem',
minWidth: 0,
padding: '0.25rem 0',
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '0.5rem', flexWrap: 'wrap' }}>
<span
style={{
fontSize: '0.62rem',
letterSpacing: '0.26em',
textTransform: 'uppercase',
color: '#8891C7',
fontWeight: 700,
}}
>
Available exclusively in UAE
</span>
<span
style={{
fontSize: '0.62rem',
letterSpacing: '0.2em',
textTransform: 'uppercase',
color: accent,
fontWeight: 700,
padding: '0.2rem 0.5rem',
borderRadius: 999,
border: `1px solid ${accent}55`,
background: 'rgba(14,13,18,0.6)',
}}
>
{count} {count === 1 ? 'model' : 'models'}
</span>
</div>
<h3
style={{
margin: 0,
fontSize: 'clamp(1.4rem, 2.6vw, 1.85rem)',
fontWeight: 700,
letterSpacing: '-0.01em',
lineHeight: 1.1,
color: '#FBFBFD',
}}
>
{brandWord}
{brandRest && (
<span
style={{
marginLeft: 8,
background: `linear-gradient(110deg, #FBFBFD, ${accent})`,
WebkitBackgroundClip: 'text',
backgroundClip: 'text',
WebkitTextFillColor: 'transparent',
color: 'transparent',
}}
>
{brandRest}
</span>
)}
</h3>
<p
style={{
margin: 0,
color: '#BFC3E2',
fontSize: '0.92rem',
lineHeight: 1.55,
}}
>
{visual.description}
</p>
<ul
style={{
listStyle: 'none',
padding: 0,
margin: 0,
display: 'flex',
flexWrap: 'wrap',
gap: '0.4rem',
}}
>
{visual.chips.map((chip) => (
<li
key={chip}
style={{
padding: '0.3rem 0.6rem',
borderRadius: 999,
fontSize: '0.68rem',
letterSpacing: '0.16em',
textTransform: 'uppercase',
color: '#DEE0F0',
background: `${accent}14`,
border: `1px solid ${accent}44`,
fontWeight: 600,
}}
>
{chip}
</li>
))}
</ul>
<span
style={{
marginTop: 'auto',
display: 'inline-flex',
alignItems: 'center',
gap: '0.5rem',
color: accent,
fontSize: '0.78rem',
fontWeight: 700,
letterSpacing: '0.16em',
textTransform: 'uppercase',
paddingTop: '0.5rem',
}}
>
Explore {brandWord} {brandRest && brandRest.replace(/^(.)/, (m) => m.toLowerCase())}
<ArrowRight size={14} />
</span>
</div>
{/* RIGHT — product visual */}
<div
style={{
position: 'relative',
minHeight: 200,
borderRadius: 16,
overflow: 'hidden',
background:
`radial-gradient(ellipse 70% 50% at 50% 60%, ${accent}22 0%, transparent 65%), linear-gradient(180deg, rgba(28,27,33,0.6), rgba(10,10,12,0.95))`,
border: '1px solid rgba(222,224,240,0.08)',
}}
>
{/* inner grid */}
<div
aria-hidden
style={{
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)',
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%)',
pointerEvents: 'none',
}}
/>
{/* spotlight */}
<div
aria-hidden
style={{
position: 'absolute',
top: '4%',
left: '50%',
transform: 'translateX(-50%)',
width: '70%',
height: '70%',
background: `radial-gradient(ellipse 60% 70% at 50% 30%, ${accent}3A 0%, transparent 65%)`,
filter: 'blur(10px)',
pointerEvents: 'none',
}}
/>
{/* secondary product (back-left, smaller) */}
{visual.secondary && (
<div
style={{
position: 'absolute',
left: '4%',
bottom: '14%',
width: '50%',
height: '74%',
opacity: 0.75,
filter: 'drop-shadow(0 12px 18px rgba(0,0,0,0.65))',
transform: 'scale(0.88)',
transformOrigin: 'bottom left',
}}
>
<Image
src={visual.secondary.src}
alt={visual.secondary.alt}
fill
sizes="240px"
style={{ objectFit: 'contain', objectPosition: 'center bottom' }}
/>
</div>
)}
{/* primary product (front-right, large) */}
<div
className="brand-card-primary"
style={{
position: 'absolute',
right: '2%',
bottom: '12%',
width: '70%',
height: '92%',
filter:
'drop-shadow(0 18px 28px rgba(0,0,0,0.78)) drop-shadow(0 0 22px rgba(58,85,196,0.45))',
transition: 'transform 0.5s cubic-bezier(0.16,1,0.3,1)',
}}
>
<Image
src={visual.primary.src}
alt={visual.primary.alt}
fill
sizes="320px"
style={{ objectFit: 'contain', objectPosition: 'center bottom' }}
/>
</div>
{/* floor reflection (faded) */}
<div
aria-hidden
style={{
position: 'absolute',
right: '2%',
bottom: '2%',
width: '70%',
height: '22%',
opacity: 0.32,
transform: 'scaleY(-1)',
transformOrigin: 'center top',
maskImage: 'linear-gradient(to bottom, rgba(0,0,0,0.7), transparent 75%)',
WebkitMaskImage: 'linear-gradient(to bottom, rgba(0,0,0,0.7), transparent 75%)',
pointerEvents: 'none',
filter: 'blur(1.2px)',
}}
>
<Image
src={visual.primary.src}
alt=""
fill
sizes="320px"
style={{ objectFit: 'contain', objectPosition: 'center top' }}
/>
</div>
{/* floor line */}
<div
aria-hidden
style={{
position: 'absolute',
left: '5%',
right: '5%',
bottom: '24%',
height: 1,
background: 'linear-gradient(90deg, transparent, rgba(222,224,240,0.55), transparent)',
pointerEvents: 'none',
}}
/>
{/* UAE badge */}
<span
style={{
position: 'absolute',
top: '0.625rem',
right: '0.625rem',
padding: '0.25rem 0.55rem',
borderRadius: 999,
border: `1px solid ${accent}55`,
background: 'rgba(14,13,18,0.75)',
color: accent,
fontSize: '0.58rem',
fontWeight: 800,
letterSpacing: '0.24em',
textTransform: 'uppercase',
backdropFilter: 'blur(8px)',
}}
>
UAE Exclusive
</span>
</div>
<style jsx>{`
.brand-card:hover {
transform: translateY(-6px);
border-color: ${accent}88;
box-shadow: 0 26px 70px rgba(0, 0, 0, 0.75), 0 0 40px ${accent}33;
}
.brand-card:hover .brand-card-glow {
opacity: 1;
}
.brand-card:hover .brand-card-primary {
transform: translateY(-4px) scale(1.02);
}
@media (max-width: 540px) {
.brand-card {
grid-template-columns: 1fr !important;
}
}
`}</style>
</Link>
);
}