diff --git a/public/images/accessories/unitree-dex5-1.gif b/public/images/accessories/unitree-dex5-1.gif deleted file mode 100644 index ea007d4..0000000 Binary files a/public/images/accessories/unitree-dex5-1.gif and /dev/null differ diff --git a/public/images/accessories/unitree-dex5-1.png b/public/images/accessories/unitree-dex5-1.png new file mode 100644 index 0000000..63f9368 Binary files /dev/null and b/public/images/accessories/unitree-dex5-1.png differ diff --git a/src/app/accessories/[slug]/page.tsx b/src/app/accessories/[slug]/page.tsx new file mode 100644 index 0000000..a218749 --- /dev/null +++ b/src/app/accessories/[slug]/page.tsx @@ -0,0 +1,525 @@ +import type { Metadata } from 'next'; +import Image from 'next/image'; +import Link from 'next/link'; +import { notFound } from 'next/navigation'; +import ChevronRight from 'lucide-react/dist/esm/icons/chevron-right'; +import Check from 'lucide-react/dist/esm/icons/check'; +import ArrowRight from 'lucide-react/dist/esm/icons/arrow-right'; +import { Navbar } from '@/components/Navbar'; +import { FooterAndContact } from '@/components/FooterAndContact'; +import { MotionSection } from '@/components/ui/MotionSection'; +import { CTAButton } from '@/components/ui/CTAButton'; +import { ACCESSORIES, GROUP_LABELS, getAccessoryBySlug, type Accessory } from '@/data/accessories'; + +type Params = { slug: string }; + +export function generateStaticParams() { + return ACCESSORIES.map((a) => ({ slug: a.slug })); +} + +export async function generateMetadata({ params }: { params: Promise }): Promise { + const { slug } = await params; + const a = getAccessoryBySlug(slug); + if (!a) return { title: 'Accessory not found · YS Lootah Robotics' }; + return { + title: `${a.brandLabel} ${a.name} · Available in UAE | YS Lootah Robotics`, + description: `${a.tagline} ${a.description} Available through YS Lootah Robotics in Dubai.`, + alternates: { canonical: `/accessories/${a.slug}/` }, + openGraph: { + title: `${a.brandLabel} ${a.name}`, + description: a.tagline, + url: `/accessories/${a.slug}/`, + type: 'website', + }, + }; +} + +export default async function AccessoryDetailPage({ params }: { params: Promise }) { + const { slug } = await params; + const accessory = getAccessoryBySlug(slug); + if (!accessory) notFound(); + + const accent = accessory.accent; + const related = ACCESSORIES + .filter((a) => a.id !== accessory.id && (a.group === accessory.group || a.brand === accessory.brand)) + .slice(0, 3); + + return ( + <> + + +
+
+ {/* BREADCRUMBS */} + + + {/* HERO */} + +
+
+
+ +
+
+ {`${accessory.name} + + +
+ +
+ + + {accessory.brandLabel} · {GROUP_LABELS[accessory.group]} + +

+ {accessory.name} +

+

{accessory.tagline}

+

{accessory.description}

+ +
+ + Request UAE Quotation + + + Book a Live Demo + +
+
+
+
+
+ + {/* FEATURES + COMPATIBILITY */} + +
+
+
+ Key features +

What makes it different.

+
+
    + {accessory.features.map((f) => ( +
  • + + {f} +
  • + ))} +
+
+ +
+
+ Compatibility +

Where it deploys.

+
+ {accessory.compatibility && accessory.compatibility.length > 0 ? ( +
    + {accessory.compatibility.map((c) => ( +
  • + · + {c} +
  • + ))} +
+ ) : ( +

Compatible across the YS Lootah Robotics catalog. Talk to our Dubai team for fit-check.

+ )} + +
+
+ Brand + {accessory.brandLabel} +
+
+ Category + {GROUP_LABELS[accessory.group]} +
+
+ Availability + UAE · Dubai +
+
+ Demo + Showroom or on-site +
+
+
+
+
+ + {/* INQUIRY */} + +
+
+
+
+ Inquiry +

Bring the {accessory.name} to your operation.

+

+ Tell us how you plan to use it, what robot platform you’re pairing it with, and your timeline. Our Dubai team will respond with UAE pricing, availability, and demo slots. +

+
+
+ + Request UAE Quotation + + + Book a Live Demo + + + WhatsApp Us + +
+
+
+
+ + {/* RELATED */} + {related.length > 0 && ( + +
+
+ Related accessories +

You might also need…

+
+
+ {related.map((r) => ( + + ))} +
+
+
+ )} +
+
+ + + + + + ); +} + +function RelatedCard({ accessory }: { accessory: Accessory }) { + const accent = accessory.accent; + return ( + +
+ {`${accessory.name} + +
+
+ + {accessory.brandLabel} + +

{accessory.name}

+

{accessory.tagline}

+ + View accessory + +
+ + ); +} diff --git a/src/app/accessories/page.tsx b/src/app/accessories/page.tsx new file mode 100644 index 0000000..9ddb320 --- /dev/null +++ b/src/app/accessories/page.tsx @@ -0,0 +1,57 @@ +import type { Metadata } from 'next'; +import Link from 'next/link'; +import ChevronRight from 'lucide-react/dist/esm/icons/chevron-right'; +import { Navbar } from '@/components/Navbar'; +import { FooterAndContact } from '@/components/FooterAndContact'; +import { AccessoriesShowcase } from '@/components/robotics/AccessoriesShowcase'; +import { ACCESSORIES } from '@/data/accessories'; + +export const metadata: Metadata = { + title: 'Robotics Accessories · Dexterous Hands, Arms, Sensors, IoT | YS Lootah Robotics', + description: + 'Browse Unitree dexterous hands, robotic arms, perception sensors, and Pudu dispatch, docking, modular attachments, and building IoT modules — available in the UAE through YS Lootah Robotics.', + alternates: { canonical: '/accessories/' }, +}; + +export default function AccessoriesIndexPage() { + return ( + <> + + +
+
+ + +
+ Add-ons · Accessories +

+ + {ACCESSORIES.length} accessories — dexterous hands, arms, sensors, IoT modules. + +

+

+ Robot platforms get their full capability from accessories. Browse Unitree dexterous hands and arms, perception sensors, and Pudu dispatch, docking, modular attachments, and building IoT modules — all available in the UAE through YS Lootah Robotics. +

+
+ + +
+
+ + + + ); +} diff --git a/src/app/bu-sunaidah/page.tsx b/src/app/bu-sunaidah/page.tsx index 252f882..762dd77 100644 --- a/src/app/bu-sunaidah/page.tsx +++ b/src/app/bu-sunaidah/page.tsx @@ -432,6 +432,170 @@ export default function BuSunaidahPage() { } .bs-pillar p { margin: 0; color: #C9CCDE; font-size: 0.88rem; line-height: 1.55; } + /* REEL */ + .bs-reel { + position: relative; + aspect-ratio: 16 / 9; + width: 100%; + border-radius: 22px; + overflow: hidden; + isolation: isolate; + border: 1px solid rgba(74, 102, 216, 0.28); + background: + radial-gradient(ellipse 70% 100% at 0% 0%, rgba(58, 85, 196, 0.22), transparent 55%), + radial-gradient(ellipse 60% 80% at 100% 100%, rgba(136, 145, 199, 0.16), transparent 60%), + linear-gradient(180deg, #0a0a0e 0%, #050508 100%); + box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.05); + } + .bs-reel-glow { + position: absolute; + inset: -20% -10% auto auto; + width: 60%; height: 80%; + background: radial-gradient(ellipse 60% 60% at 50% 50%, rgba(58, 85, 196, 0.5), transparent 70%); + filter: blur(40px); + pointer-events: none; + z-index: 0; + } + .bs-corner { + position: absolute; + width: 14px; height: 14px; + z-index: 3; + pointer-events: none; + } + .bs-corner-tl { top: 8px; left: 8px; border-top: 1px solid rgba(222, 224, 240, 0.32); border-left: 1px solid rgba(222, 224, 240, 0.32); } + .bs-corner-tr { top: 8px; right: 8px; border-top: 1px solid rgba(222, 224, 240, 0.32); border-right: 1px solid rgba(222, 224, 240, 0.32); } + .bs-corner-bl { bottom: 8px; left: 8px; border-bottom: 1px solid rgba(222, 224, 240, 0.32); border-left: 1px solid rgba(222, 224, 240, 0.32); } + .bs-corner-br { bottom: 8px; right: 8px; border-bottom: 1px solid rgba(222, 224, 240, 0.32); border-right: 1px solid rgba(222, 224, 240, 0.32); } + .bs-reel-media { + position: absolute; + inset: 0; + width: 100%; height: 100%; + border: 0; + background: #050508; + z-index: 1; + } + .bs-reel-placeholder { position: absolute; inset: 0; z-index: 1; } + .bs-reel-overlay { + position: absolute; + inset: 0; + background: linear-gradient(180deg, rgba(8, 8, 12, 0.0) 35%, rgba(8, 8, 12, 0.85) 100%); + pointer-events: none; + z-index: 2; + } + .bs-reel-cta { + position: absolute; + left: clamp(1rem, 2.5vw, 1.5rem); + bottom: clamp(1rem, 2.5vw, 1.5rem); + right: clamp(1rem, 2.5vw, 1.5rem); + z-index: 3; + display: flex; + align-items: center; + gap: 0.9rem; + } + .bs-reel-play { + display: inline-flex; align-items: center; justify-content: center; + width: 48px; height: 48px; + border-radius: 999px; + background: + radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.32), transparent 60%), + linear-gradient(135deg, #5a76e8, #273F94); + color: #FFFFFF; + border: 1px solid rgba(255, 255, 255, 0.22); + box-shadow: 0 18px 32px rgba(58, 85, 196, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.3); + flex: none; + } + .bs-reel-eyebrow { + display: block; + font-size: 0.62rem; + letter-spacing: 0.28em; + text-transform: uppercase; + font-weight: 800; + color: #DEE0F0; + margin-bottom: 0.2rem; + } + .bs-reel-caption { + display: block; + color: #FFFFFF; + font-size: clamp(0.95rem, 1.6vw, 1.05rem); + font-weight: 500; + letter-spacing: -0.005em; + line-height: 1.4; + } + + /* PRESS & MEDIA */ + .bs-press-wall { + list-style: none; margin: 0; padding: 0; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0.75rem; + } + @media (min-width: 640px) { .bs-press-wall { grid-template-columns: repeat(3, minmax(0, 1fr)); } } + @media (min-width: 1000px) { .bs-press-wall { grid-template-columns: repeat(5, minmax(0, 1fr)); } } + .bs-press-cell { + display: flex; align-items: center; justify-content: center; + min-height: 76px; + padding: 0.9rem 1rem; + border-radius: 14px; + border: 1px solid rgba(222, 224, 240, 0.10); + background: linear-gradient(135deg, rgba(20, 19, 26, 0.78), rgba(10, 10, 14, 0.94)); + transition: border-color 0.3s, transform 0.3s; + } + .bs-press-cell:hover { border-color: rgba(74, 102, 216, 0.35); transform: translateY(-2px); } + .bs-press-cell a { + display: inline-flex; align-items: center; justify-content: center; + text-decoration: none; + color: inherit; + } + .bs-press-cell img { + filter: grayscale(1) brightness(1.2); + opacity: 0.78; + transition: filter 0.3s, opacity 0.3s; + } + .bs-press-cell:hover img { filter: grayscale(0) brightness(1); opacity: 1; } + .bs-press-fallback { + font-size: 0.78rem; + letter-spacing: 0.16em; + text-transform: uppercase; + font-weight: 700; + color: #C9CCDE; + } + + .bs-press-quotes { + display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; + margin-top: 1rem; + } + @media (min-width: 720px) { .bs-press-quotes { grid-template-columns: repeat(2, minmax(0, 1fr)); } } + @media (min-width: 1100px) { .bs-press-quotes { grid-template-columns: repeat(3, minmax(0, 1fr)); } } + .bs-press-quote { + margin: 0; + display: flex; flex-direction: column; gap: 0.65rem; + padding: 1.15rem 1.2rem 1.15rem; + border-radius: 18px; + border: 1px solid rgba(222, 224, 240, 0.10); + background: + radial-gradient(ellipse 75% 50% at 100% 0%, color-mix(in srgb, var(--acc) 14%, transparent), transparent 60%), + linear-gradient(180deg, rgba(22, 21, 30, 0.9), rgba(10, 10, 14, 0.96)); + } + .bs-press-quote-mark { + display: inline-flex; align-items: center; justify-content: center; + width: 30px; height: 30px; + border-radius: 999px; + color: color-mix(in srgb, var(--acc) 82%, white); + background: color-mix(in srgb, var(--acc) 14%, rgba(14, 13, 18, 0.6)); + border: 1px solid color-mix(in srgb, var(--acc) 32%, transparent); + } + .bs-press-quote p { margin: 0; color: #ECEEF6; font-size: 0.97rem; line-height: 1.65; } + .bs-press-quote footer { + color: #8891C7; + font-size: 0.7rem; + letter-spacing: 0.18em; + text-transform: uppercase; + font-weight: 700; + } + .bs-press-quote footer a { color: #8891C7; text-decoration: none; } + .bs-press-quote footer a:hover { color: #FFFFFF; } + .bs-press-date { color: #5a627e; } + /* INSTAGRAM LINK */ .bs-ig-link { display: inline-flex; align-items: center; gap: 0.5rem; diff --git a/src/app/robots/page.tsx b/src/app/robots/page.tsx index 3945bcb..c6aadba 100644 --- a/src/app/robots/page.tsx +++ b/src/app/robots/page.tsx @@ -1,68 +1,306 @@ import type { Metadata } from 'next'; +import Link from 'next/link'; +import ChevronRight from 'lucide-react/dist/esm/icons/chevron-right'; import { Navbar } from '@/components/Navbar'; import { FooterAndContact } from '@/components/FooterAndContact'; import { CatalogClient } from './CatalogClient'; import { AccessoriesShowcase } from '@/components/robotics/AccessoriesShowcase'; -import { RoboticsSplineShowcase } from '@/components/sections/robotics-spline-showcase'; +import { CTAButton } from '@/components/ui/CTAButton'; import { ROBOTS } from '@/data/robots'; import { ACCESSORIES } from '@/data/accessories'; export const metadata: Metadata = { - title: 'Robots Catalog YS Lootah Robotics Dubai', + title: 'Robots Catalog · Unitree & Pudu in UAE | YS Lootah Robotics', description: 'Explore selected humanoid, quadruped, industrial, service, delivery, hospitality, and cleaning robots — plus dexterous hands, arms, sensors, and accessories — from Unitree and Pudu available in the UAE through YS Lootah Robotics.', + alternates: { canonical: '/robots/' }, }; +const unitreeCount = ROBOTS.filter((r) => r.brand === 'unitree').length; +const puduCount = ROBOTS.filter((r) => r.brand === 'pudu').length; + +const HERO_STATS: { value: string; label: string }[] = [ + { value: String(ROBOTS.length), label: 'Robot models' }, + { value: String(ACCESSORIES.length), label: 'Accessories' }, + { value: String(unitreeCount), label: 'Unitree' }, + { value: String(puduCount), label: 'Pudu' }, +]; + export default function RobotsPage() { return ( <> -
-
- -
-
-
- Catalog · Filter & Browse -

- - {ROBOTS.length} robots across the UAE portfolio. - -

-

- Filter by brand or category, then request a UAE quotation or book a live demo at our Dubai showroom. -

-
+
+
+ {/* BREADCRUMBS */} + - + {/* HERO */} +
+
+
+
-
-
+
+
+ + + Catalog · UAE Portfolio · Dubai + +

+ + {ROBOTS.length} robots + {ACCESSORIES.length} accessories. + +

+

+ Selected Unitree and Pudu Robotics platforms — humanoid, quadruped, industrial, delivery, service, and cleaning — plus dexterous hands, arms, sensors, and building IoT modules. Available in the UAE through YS Lootah Robotics. +

+ +
+ + Browse the Catalog + + + Book a Live Demo + +
+ + +
+ + +
+
+ + {/* CATALOG */} +
+
+ Filter & Browse +

+ {ROBOTS.length} robots across the UAE portfolio. +

+

Filter by brand or category, then request a UAE quotation or book a live demo at our Dubai showroom.

+
+ +
+ + {/* ACCESSORIES */} +
+
Add-ons · Accessories -

- +

+ {ACCESSORIES.length} accessories — dexterous hands, arms, sensors, IoT modules.

-

- Robot platforms get their full capability from accessories. Browse Unitree dexterous hands and arms, perception sensors, and Pudu dispatch, docking, modular attachments, and building IoT modules. -

-

+

Robot platforms get their full capability from accessories. Each one has its own detail page with features, compatibility, and inquiry form.

+
+ + + ); } diff --git a/src/components/robotics/AccessoriesShowcase.tsx b/src/components/robotics/AccessoriesShowcase.tsx index 46b541a..4d3517f 100644 --- a/src/components/robotics/AccessoriesShowcase.tsx +++ b/src/components/robotics/AccessoriesShowcase.tsx @@ -2,6 +2,7 @@ import { useMemo, useState } from 'react'; import Image from 'next/image'; +import Link from 'next/link'; import { ACCESSORIES, GROUP_LABELS, type AccessoryGroup, type Accessory } from '@/data/accessories'; type Filter = AccessoryGroup | 'all'; @@ -83,10 +84,9 @@ function FilterChip({ function AccessoryCard({ accessory }: { accessory: Accessory }) { const accent = accessory.accent; return ( -
- + ); } diff --git a/src/components/robotics/BuSunaidahSection.tsx b/src/components/robotics/BuSunaidahSection.tsx index 65bbddf..4e5a8fc 100644 --- a/src/components/robotics/BuSunaidahSection.tsx +++ b/src/components/robotics/BuSunaidahSection.tsx @@ -1,6 +1,9 @@ 'use client'; import Image from 'next/image'; +import Link from 'next/link'; +import { BU_SUNAIDAH_URL, BU_SUNAIDAH_PORTRAIT } from '@/data/bu-sunaidah'; +import { InstagramGlyph } from '@/components/icons/InstagramGlyph'; export function BuSunaidahSection() { return ( @@ -97,9 +100,12 @@ export function BuSunaidahSection() { pointerEvents: 'none', }} /> - +
diff --git a/src/data/accessories.ts b/src/data/accessories.ts index 42956a0..d27ac43 100644 --- a/src/data/accessories.ts +++ b/src/data/accessories.ts @@ -81,7 +81,7 @@ export const ACCESSORIES: Accessory[] = [ '±22° four-finger lateral swing', 'Backdrivable, low-damping reducers', ], - image: '/images/accessories/unitree-dex5-1.gif', + image: '/images/accessories/unitree-dex5-1.png', accent: GOLD_BRAND, officialUrl: 'https://www.unitree.com/Dex5-1', compatibility: ['Unitree G1', 'Unitree H1', 'Unitree H2', 'Research arms'], diff --git a/src/data/bu-sunaidah.ts b/src/data/bu-sunaidah.ts index d95f920..aa7ba52 100644 --- a/src/data/bu-sunaidah.ts +++ b/src/data/bu-sunaidah.ts @@ -16,6 +16,19 @@ export type InstagramPost = { export const BU_SUNAIDAH_HANDLE = 'bu.sunaidah'; export const BU_SUNAIDAH_URL = `https://www.instagram.com/${BU_SUNAIDAH_HANDLE}`; +/** + * Portrait shown in the home-page Bu Sunaidah section and detail page hero. + * + * Set to a local path (e.g. '/bu-sunaidah/portrait.jpg') once the official + * Bu Sunaidah photo has been saved into /public/bu-sunaidah/. + * + * Leave as null to render the "View on Instagram" placeholder card. + * + * IMPORTANT: do NOT hotlink Instagram CDN images in production — save the + * approved photo locally inside the repo first. + */ +export const BU_SUNAIDAH_PORTRAIT: { src: string; alt: string } | null = null; + // TODO: populate with curated post shortcodes from @bu.sunaidah. // Each entry renders as a 16:20 Instagram embed iframe. export const BU_SUNAIDAH_POSTS: InstagramPost[] = [];