feat: add robotics showcase components and UI enhancements
Some checks are pending
CI/CD / test-and-build (push) Waiting to run
CI/CD / deploy (push) Blocked by required conditions

- 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:
Najjar\NajjarV02 2026-05-20 17:46:36 +04:00
parent 92cf4aba3b
commit 461a00384c
73 changed files with 2041 additions and 582 deletions

104
package-lock.json generated
View File

@ -18,22 +18,27 @@
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@react-three/postprocessing": "^2.16.0",
"@splinetool/react-spline": "^4.1.0",
"@splinetool/runtime": "^1.12.94",
"@stripe/react-stripe-js": "^6.1.0",
"@stripe/stripe-js": "^9.1.0",
"@types/three": "^0.183.1",
"bcryptjs": "^3.0.3",
"clsx": "^2.1.1",
"draco3dgltf": "^1.5.7",
"framer-motion": "^12.38.0",
"gsap": "^3.14.2",
"i18next": "^26.0.3",
"i18next-browser-languagedetector": "^8.2.1",
"jose": "^6.2.2",
"lucide-react": "^1.16.0",
"next": "16.2.2",
"react": "19.0.0",
"react-country-phone-input": "^1.0.2",
"react-dom": "19.0.0",
"react-i18next": "^17.0.2",
"stripe": "^22.0.1",
"tailwind-merge": "^3.6.0",
"three": "^0.170.0",
"tsx": "^4.19.2",
"zustand": "^5.0.12"
@ -2713,6 +2718,37 @@
"text-hex": "1.0.x"
}
},
"node_modules/@splinetool/react-spline": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@splinetool/react-spline/-/react-spline-4.1.0.tgz",
"integrity": "sha512-Y379gm17gw+1nxT/YXTCJnVIWuu7tsUH1tp/YxsYb0pZnc9Gljk7Om4Kpq7WPq0bZ4zidVCxf6xn6jgDcbHifQ==",
"dependencies": {
"blurhash": "2.0.5",
"lodash.debounce": "4.0.8",
"react-merge-refs": "2.1.1",
"thumbhash": "0.1.1"
},
"peerDependencies": {
"@splinetool/runtime": "*",
"next": ">=14.2.0",
"react": "*",
"react-dom": "*"
},
"peerDependenciesMeta": {
"next": {
"optional": true
}
}
},
"node_modules/@splinetool/runtime": {
"version": "1.12.94",
"resolved": "https://registry.npmjs.org/@splinetool/runtime/-/runtime-1.12.94.tgz",
"integrity": "sha512-Y49qppQkzVHhbeePpmdXBOeVOtgAcn8qObBujB8ePYnGYBxSAA2NCHo91pY1Sv1DCMXrowuTSAJexVeXf+t4Pw==",
"dependencies": {
"on-change": "4.0.0",
"semver-compare": "1.0.0"
}
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
@ -3714,6 +3750,12 @@
"require-from-string": "^2.0.2"
}
},
"node_modules/blurhash": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/blurhash/-/blurhash-2.0.5.tgz",
"integrity": "sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==",
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
@ -4022,6 +4064,15 @@
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/color": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz",
@ -6043,6 +6094,15 @@
"url": "https://github.com/sponsors/wellwelwel"
}
},
"node_modules/lucide-react": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.16.0.tgz",
"integrity": "sha512-dYwyPzb4MEKpGUmNYk3WKWPnMrHs3FKM+q94kAnJrcDIqqn1hq2xY8scaS2ovsOCM5D51ey2gaRG3PBb1vgoYQ==",
"license": "ISC",
"peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/lz-string": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
@ -6515,6 +6575,18 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/on-change": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/on-change/-/on-change-4.0.0.tgz",
"integrity": "sha512-PTu7C9Jsz4b+sNMDpH0eZFTr7uxdOtoDWRnhaVNK50bgrrnW5nvbWI0jm5DG9qOoTnIhBzE9xoKVFPD9xgtbdg==",
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sindresorhus/on-change?sponsor=1"
}
},
"node_modules/one-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
@ -6947,6 +7019,16 @@
"license": "MIT",
"peer": true
},
"node_modules/react-merge-refs": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-2.1.1.tgz",
"integrity": "sha512-jLQXJ/URln51zskhgppGJ2ub7b2WFKGq3cl3NYKtlHoTG+dN2q7EzWrn3hN3EgPsTMvpR9tpq5ijdp7YwFZkag==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
}
},
"node_modules/react-use-measure": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
@ -7170,6 +7252,12 @@
"node": ">=10"
}
},
"node_modules/semver-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
"license": "MIT"
},
"node_modules/seq-queue": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
@ -7713,6 +7801,16 @@
"node": ">=6"
}
},
"node_modules/tailwind-merge": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz",
"integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/dcastil"
}
},
"node_modules/tailwindcss": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",
@ -7779,6 +7877,12 @@
"integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==",
"license": "MIT"
},
"node_modules/thumbhash": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/thumbhash/-/thumbhash-0.1.1.tgz",
"integrity": "sha512-kH5pKeIIBPQXAOni2AiY/Cu/NKdkFREdpH+TLdM0g6WA7RriCv0kPLgP731ady67MhTAqrVG/4mnEeibVuCJcg==",
"license": "MIT"
},
"node_modules/tinybench": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",

View File

@ -21,22 +21,27 @@
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@react-three/postprocessing": "^2.16.0",
"@splinetool/react-spline": "^4.1.0",
"@splinetool/runtime": "^1.12.94",
"@stripe/react-stripe-js": "^6.1.0",
"@stripe/stripe-js": "^9.1.0",
"@types/three": "^0.183.1",
"bcryptjs": "^3.0.3",
"clsx": "^2.1.1",
"draco3dgltf": "^1.5.7",
"framer-motion": "^12.38.0",
"gsap": "^3.14.2",
"i18next": "^26.0.3",
"i18next-browser-languagedetector": "^8.2.1",
"jose": "^6.2.2",
"lucide-react": "^1.16.0",
"next": "16.2.2",
"react": "19.0.0",
"react-country-phone-input": "^1.0.2",
"react-dom": "19.0.0",
"react-i18next": "^17.0.2",
"stripe": "^22.0.1",
"tailwind-merge": "^3.6.0",
"three": "^0.170.0",
"tsx": "^4.19.2",
"zustand": "^5.0.12"

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

View File

@ -1,20 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" role="img" aria-label="Pudu BellaBot delivery robot silhouette">
<defs>
<radialGradient id="bg" cx="50%" cy="45%" r="60%">
<stop offset="0%" stop-color="#c4a265" stop-opacity="0.35"/>
<stop offset="60%" stop-color="#0a0907" stop-opacity="0"/>
<stop offset="0%" stop-color="#3a55c4" stop-opacity="0.35"/>
<stop offset="60%" stop-color="#0a0a0c" stop-opacity="0"/>
</radialGradient>
<linearGradient id="body" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#f5f1e8"/>
<stop offset="100%" stop-color="#94908a"/>
<stop offset="0%" stop-color="#FBFBFD"/>
<stop offset="100%" stop-color="#8891C7"/>
</linearGradient>
<linearGradient id="screen" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#1f1a10"/>
<stop offset="100%" stop-color="#0a0907"/>
<stop offset="0%" stop-color="#1c1b21"/>
<stop offset="100%" stop-color="#0a0a0c"/>
</linearGradient>
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#e0c896"/>
<stop offset="100%" stop-color="#8b6f47"/>
<stop offset="0%" stop-color="#DEE0F0"/>
<stop offset="100%" stop-color="#273F94"/>
</linearGradient>
</defs>
<rect width="600" height="600" fill="url(#bg)"/>
@ -22,18 +22,18 @@
<ellipse cx="0" cy="0" rx="160" ry="14" fill="#000" opacity="0.55"/>
</g>
<g transform="translate(300 100)">
<rect x="-120" y="0" width="240" height="120" rx="36" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<rect x="-120" y="0" width="240" height="120" rx="36" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<rect x="-100" y="20" width="200" height="80" rx="22" fill="url(#screen)"/>
<circle cx="-44" cy="60" r="14" fill="url(#accent)"/>
<circle cx="44" cy="60" r="14" fill="url(#accent)"/>
<path d="M -30 88 Q 0 78 30 88" stroke="url(#accent)" stroke-width="4" fill="none" stroke-linecap="round"/>
<rect x="-140" y="140" width="280" height="14" rx="6" fill="#5a4a30"/>
<rect x="-128" y="170" width="256" height="50" rx="12" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<rect x="-128" y="240" width="256" height="50" rx="12" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<rect x="-128" y="310" width="256" height="50" rx="12" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<rect x="-100" y="370" width="200" height="14" rx="6" fill="#3a2f1c"/>
<circle cx="-72" cy="384" r="20" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<circle cx="72" cy="384" r="20" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<rect x="-140" y="140" width="280" height="14" rx="6" fill="#5a5e7a"/>
<rect x="-128" y="170" width="256" height="50" rx="12" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<rect x="-128" y="240" width="256" height="50" rx="12" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<rect x="-128" y="310" width="256" height="50" rx="12" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<rect x="-100" y="370" width="200" height="14" rx="6" fill="#3a3d52"/>
<circle cx="-72" cy="384" r="20" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
<circle cx="72" cy="384" r="20" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
</g>
<text x="50%" y="96%" text-anchor="middle" fill="#94908a" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU BELLABOT</text>
<text x="50%" y="96%" text-anchor="middle" fill="#8891C7" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU BELLABOT</text>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,31 +1,31 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" role="img" aria-label="Pudu CC1 cleaning robot silhouette">
<defs>
<radialGradient id="bg" cx="50%" cy="55%" r="60%">
<stop offset="0%" stop-color="#c4a265" stop-opacity="0.32"/>
<stop offset="60%" stop-color="#0a0907" stop-opacity="0"/>
<stop offset="0%" stop-color="#3a55c4" stop-opacity="0.32"/>
<stop offset="60%" stop-color="#0a0a0c" stop-opacity="0"/>
</radialGradient>
<linearGradient id="body" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#f5f1e8"/>
<stop offset="100%" stop-color="#94908a"/>
<stop offset="0%" stop-color="#FBFBFD"/>
<stop offset="100%" stop-color="#8891C7"/>
</linearGradient>
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#e0c896"/>
<stop offset="100%" stop-color="#8b6f47"/>
<stop offset="0%" stop-color="#DEE0F0"/>
<stop offset="100%" stop-color="#273F94"/>
</linearGradient>
</defs>
<rect width="600" height="600" fill="url(#bg)"/>
<g transform="translate(300 360)">
<ellipse cx="0" cy="120" rx="200" ry="20" fill="#000" opacity="0.55"/>
<rect x="-180" y="-180" width="360" height="240" rx="40" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<rect x="-160" y="-160" width="160" height="100" rx="18" fill="#0a0907"/>
<rect x="-180" y="-180" width="360" height="240" rx="40" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<rect x="-160" y="-160" width="160" height="100" rx="18" fill="#0a0a0c"/>
<rect x="-150" y="-150" width="140" height="14" rx="6" fill="url(#accent)" opacity="0.9"/>
<rect x="-150" y="-130" width="100" height="10" rx="4" fill="#5a4a30"/>
<rect x="-150" y="-110" width="120" height="10" rx="4" fill="#5a4a30"/>
<circle cx="120" cy="-110" r="34" fill="#1f1a10" stroke="#5a4a30" stroke-width="2"/>
<rect x="-150" y="-130" width="100" height="10" rx="4" fill="#5a5e7a"/>
<rect x="-150" y="-110" width="120" height="10" rx="4" fill="#5a5e7a"/>
<circle cx="120" cy="-110" r="34" fill="#1c1b21" stroke="#5a5e7a" stroke-width="2"/>
<circle cx="120" cy="-110" r="14" fill="url(#accent)"/>
<rect x="-170" y="80" width="340" height="30" rx="8" fill="#0a0907"/>
<circle cx="-130" cy="110" r="22" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<circle cx="130" cy="110" r="22" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<rect x="-170" y="80" width="340" height="30" rx="8" fill="#0a0a0c"/>
<circle cx="-130" cy="110" r="22" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
<circle cx="130" cy="110" r="22" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
</g>
<text x="50%" y="96%" text-anchor="middle" fill="#94908a" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU CC1 CLEANING ROBOT</text>
<text x="50%" y="96%" text-anchor="middle" fill="#8891C7" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU CC1 CLEANING ROBOT</text>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,35 +1,35 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" role="img" aria-label="Pudu KettyBot service robot silhouette">
<defs>
<radialGradient id="bg" cx="50%" cy="45%" r="60%">
<stop offset="0%" stop-color="#c4a265" stop-opacity="0.32"/>
<stop offset="60%" stop-color="#0a0907" stop-opacity="0"/>
<stop offset="0%" stop-color="#3a55c4" stop-opacity="0.32"/>
<stop offset="60%" stop-color="#0a0a0c" stop-opacity="0"/>
</radialGradient>
<linearGradient id="body" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#f5f1e8"/>
<stop offset="100%" stop-color="#94908a"/>
<stop offset="0%" stop-color="#FBFBFD"/>
<stop offset="100%" stop-color="#8891C7"/>
</linearGradient>
<linearGradient id="screen" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0a0907"/>
<stop offset="100%" stop-color="#3a2f1c"/>
<stop offset="0%" stop-color="#0a0a0c"/>
<stop offset="100%" stop-color="#3a3d52"/>
</linearGradient>
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#e0c896"/>
<stop offset="100%" stop-color="#c4a265"/>
<stop offset="0%" stop-color="#DEE0F0"/>
<stop offset="100%" stop-color="#3a55c4"/>
</linearGradient>
</defs>
<rect width="600" height="600" fill="url(#bg)"/>
<g transform="translate(300 110)">
<rect x="-110" y="0" width="220" height="280" rx="28" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<rect x="-110" y="0" width="220" height="280" rx="28" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<rect x="-92" y="22" width="184" height="240" rx="18" fill="url(#screen)"/>
<g transform="translate(0 110)">
<circle cx="-30" cy="0" r="12" fill="url(#accent)"/>
<circle cx="30" cy="0" r="12" fill="url(#accent)"/>
<path d="M -22 30 Q 0 18 22 30" stroke="url(#accent)" stroke-width="3" fill="none" stroke-linecap="round"/>
</g>
<rect x="-130" y="300" width="260" height="14" rx="6" fill="#5a4a30"/>
<path d="M -120 320 L 120 320 L 100 460 L -100 460 Z" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<circle cx="-70" cy="460" r="22" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<circle cx="70" cy="460" r="22" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<rect x="-130" y="300" width="260" height="14" rx="6" fill="#5a5e7a"/>
<path d="M -120 320 L 120 320 L 100 460 L -100 460 Z" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<circle cx="-70" cy="460" r="22" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
<circle cx="70" cy="460" r="22" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
</g>
<text x="50%" y="96%" text-anchor="middle" fill="#94908a" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU KETTYBOT</text>
<text x="50%" y="96%" text-anchor="middle" fill="#8891C7" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU KETTYBOT</text>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,29 +1,29 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" role="img" aria-label="Pudu D-Series industrial delivery robot silhouette">
<defs>
<radialGradient id="bg" cx="50%" cy="55%" r="60%">
<stop offset="0%" stop-color="#c4a265" stop-opacity="0.32"/>
<stop offset="60%" stop-color="#0a0907" stop-opacity="0"/>
<stop offset="0%" stop-color="#3a55c4" stop-opacity="0.32"/>
<stop offset="60%" stop-color="#0a0a0c" stop-opacity="0"/>
</radialGradient>
<linearGradient id="body" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#f5f1e8"/>
<stop offset="100%" stop-color="#6b6862"/>
<stop offset="0%" stop-color="#FBFBFD"/>
<stop offset="100%" stop-color="#6a73a5"/>
</linearGradient>
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#e0c896"/>
<stop offset="100%" stop-color="#c4a265"/>
<stop offset="0%" stop-color="#DEE0F0"/>
<stop offset="100%" stop-color="#3a55c4"/>
</linearGradient>
</defs>
<rect width="600" height="600" fill="url(#bg)"/>
<g transform="translate(300 380)">
<ellipse cx="0" cy="120" rx="200" ry="18" fill="#000" opacity="0.55"/>
<rect x="-180" y="-220" width="360" height="320" rx="36" fill="url(#body)" stroke="#3a2f1c" stroke-width="2"/>
<rect x="-160" y="-200" width="320" height="40" rx="10" fill="#0a0907"/>
<rect x="-160" y="-140" width="320" height="80" rx="12" fill="#1f1a10"/>
<rect x="-160" y="-40" width="320" height="80" rx="12" fill="#1f1a10"/>
<rect x="-180" y="-220" width="360" height="320" rx="36" fill="url(#body)" stroke="#3a3d52" stroke-width="2"/>
<rect x="-160" y="-200" width="320" height="40" rx="10" fill="#0a0a0c"/>
<rect x="-160" y="-140" width="320" height="80" rx="12" fill="#1c1b21"/>
<rect x="-160" y="-40" width="320" height="80" rx="12" fill="#1c1b21"/>
<rect x="-160" y="60" width="320" height="30" rx="10" fill="url(#accent)" opacity="0.85"/>
<rect x="-180" y="100" width="360" height="20" rx="8" fill="#0a0907"/>
<circle cx="-130" cy="120" r="26" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<circle cx="130" cy="120" r="26" fill="#0a0907" stroke="#5a4a30" stroke-width="2"/>
<rect x="-180" y="100" width="360" height="20" rx="8" fill="#0a0a0c"/>
<circle cx="-130" cy="120" r="26" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
<circle cx="130" cy="120" r="26" fill="#0a0a0c" stroke="#5a5e7a" stroke-width="2"/>
</g>
<text x="50%" y="96%" text-anchor="middle" fill="#94908a" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU D-SERIES</text>
<text x="50%" y="96%" text-anchor="middle" fill="#8891C7" font-family="Inter, sans-serif" font-size="20" letter-spacing="6">PUDU D-SERIES</text>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -5,11 +5,14 @@ import { MotionSection } from '@/components/ui/MotionSection';
import { DemoCTA } from '@/components/robotics/DemoCTA';
import { WhyUs } from '@/components/robotics/WhyUs';
import { FloatingTechPanel } from '@/components/robotics/FloatingTechPanel';
import { CompanyStory } from '@/components/robotics/CompanyStory';
import { FounderSection } from '@/components/robotics/FounderSection';
import { ServicesGrid } from '@/components/robotics/ServicesGrid';
export const metadata: Metadata = {
title: 'About YS Lootah Robotics — Exclusive UAE Access to Unitree & Pudu',
description:
'YS Lootah Robotics holds exclusive UAE sales rights for selected Unitree and Pudu Robotics solutions — with a Dubai-based team managing sales, demo, configuration, and deployment.',
'YS Lootah Robotics is part of the Yousuf Saeed Lootah Investment Group — a trusted UAE robotics partner delivering AI, automation, and intelligent robotics across Dubai and the UAE.',
};
export default function AboutPage() {
@ -20,26 +23,43 @@ export default function AboutPage() {
<main style={{ paddingTop: 'clamp(6rem, 10vw, 8rem)', paddingBottom: 'clamp(4rem, 8vw, 6rem)' }}>
<div className="container-wide" style={{ display: 'flex', flexDirection: 'column', gap: 'clamp(3rem, 6vw, 5rem)' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem', maxWidth: 820 }}>
<span className="eyebrow">About · Exclusive UAE Access</span>
<span className="eyebrow">About · YS Lootah Robotics</span>
<h1 style={{ margin: 0, fontSize: 'clamp(2rem, 5vw, 3.4rem)', fontWeight: 300, lineHeight: 1.05, letterSpacing: '-0.03em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>The UAE&apos;s dedicated destination for Unitree and Pudu Robotics.</span>
<span className="text-gradient" style={{ fontWeight: 500 }}>In Tech We Innovate. In Trust We Lead.</span>
</h1>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
YS Lootah Robotics is the robotics arm of the YS Lootah group a UAE-based technology partner that holds exclusive sales rights in the UAE for selected Unitree and Pudu Robotics solutions. Our Dubai team manages sales, live demos, configuration, deployment, and ongoing service across the UAE.
</p>
<p style={{ margin: 0, color: '#94908a', fontSize: '0.92rem', lineHeight: 1.7 }}>
Brand names and product trademarks are property of their respective owners. Available exclusively in the UAE through YS Lootah Robotics.
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
YS Lootah Robotics is part of the Yousuf Saeed Lootah Investment Group a trusted UAE technology and robotics partner helping businesses innovate, automate, and deploy intelligent robotic solutions. The UAE&apos;s dedicated destination for selected Unitree and Pudu Robotics solutions.
</p>
</div>
<MotionSection>
<CompanyStory />
</MotionSection>
<MotionSection>
<FloatingTechPanel />
</MotionSection>
<MotionSection>
<FounderSection />
</MotionSection>
<MotionSection>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<h2 style={{ margin: 0, fontSize: 'clamp(1.5rem, 3vw, 2.2rem)', fontWeight: 400, letterSpacing: '-0.02em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>Why work with us</span>
<span className="text-gradient" style={{ fontWeight: 500 }}>Our solutions</span>
</h2>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7, maxWidth: 760 }}>
Eleven robotics services covering autonomous deployment, integration, motion programming, cloud, analytics, and live diagnostics.
</p>
<ServicesGrid />
</div>
</MotionSection>
<MotionSection>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<h2 style={{ margin: 0, fontSize: 'clamp(1.5rem, 3vw, 2.2rem)', fontWeight: 400, letterSpacing: '-0.02em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>Why businesses choose us</span>
</h2>
<WhyUs />
</div>

View File

@ -52,10 +52,10 @@ export default function AdminLoginPage() {
}}>
🔐
</div>
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0907', margin: 0, marginBottom: '0.25rem' }}>
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0a0c', margin: 0, marginBottom: '0.25rem' }}>
Admin Login
</h1>
<p style={{ fontSize: '0.8rem', color: '#94908a', margin: 0 }}>
<p style={{ fontSize: '0.8rem', color: '#8891C7', margin: 0 }}>
Lootah Robotics G1 Configurator
</p>
</div>
@ -112,8 +112,8 @@ export default function AdminLoginPage() {
padding: '0.7rem',
borderRadius: '0.5rem',
border: '1px solid rgba(59, 130, 246, 0.3)',
background: loading ? 'rgba(196, 162, 101, 0.1)' : 'rgba(59, 130, 246, 0.08)',
color: loading ? '#94908a' : '#2563eb',
background: loading ? 'rgba(39, 63, 148, 0.1)' : 'rgba(59, 130, 246, 0.08)',
color: loading ? '#8891C7' : '#2563eb',
fontSize: '0.875rem',
fontWeight: 600,
cursor: loading ? 'not-allowed' : 'pointer',
@ -164,7 +164,7 @@ const inputStyle: React.CSSProperties = {
borderRadius: '0.5rem',
border: '1px solid rgba(0, 0, 0, 0.1)',
background: '#ffffff',
color: '#0a0907',
color: '#0a0a0c',
fontSize: '0.875rem',
outline: 'none',
transition: 'border-color 0.2s ease',

View File

@ -488,7 +488,7 @@ export default function AdminPage() {
new Date(ts * 1000).toLocaleDateString('en-AE', { day: 'numeric', month: 'short', year: 'numeric' });
if (!isPricingHydrated) {
return <div style={pageStyle}><p style={{ color: '#6b6862' }}>Loading</p></div>;
return <div style={pageStyle}><p style={{ color: '#6a73a5' }}>Loading</p></div>;
}
return (
@ -497,10 +497,10 @@ export default function AdminPage() {
{/* HEADER */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '1.5rem' }}>
<div>
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0907', margin: 0, marginBottom: '0.2rem' }}>
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0a0c', margin: 0, marginBottom: '0.2rem' }}>
Admin Dashboard
</h1>
<p style={{ fontSize: '0.75rem', color: '#94908a', margin: 0 }}>Lootah Robotics G1 Configurator</p>
<p style={{ fontSize: '0.75rem', color: '#8891C7', margin: 0 }}>Lootah Robotics G1 Configurator</p>
</div>
<div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
<button onClick={() => setShowPwModal(true)} style={ghostBtnStyle}>Change Password</button>
@ -527,7 +527,7 @@ export default function AdminPage() {
borderRadius: '0.375rem',
border: 'none',
background: activeTab === t ? 'rgba(59,130,246,0.08)' : 'transparent',
color: activeTab === t ? '#2563eb' : '#6b6862',
color: activeTab === t ? '#2563eb' : '#6a73a5',
fontSize: '0.8rem',
fontWeight: activeTab === t ? 600 : 400,
cursor: 'pointer',
@ -558,9 +558,9 @@ export default function AdminPage() {
aria-label={`Label for ${item.label}`}
/>
</div>
<div style={{ fontSize: '0.7rem', color: '#94908a', fontFamily: 'monospace', paddingLeft: '0.25rem' }}>{item.id}</div>
<div style={{ fontSize: '0.7rem', color: '#8891C7', fontFamily: 'monospace', paddingLeft: '0.25rem' }}>{item.id}</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.375rem' }}>
<span style={{ fontSize: '0.7rem', color: '#94908a' }}>AED</span>
<span style={{ fontSize: '0.7rem', color: '#8891C7' }}>AED</span>
<input
type="text"
value={formatPrice(editedPrices[item.id] ?? item.price)}
@ -584,7 +584,7 @@ export default function AdminPage() {
) : null}
<label
title="Upload / replace .glb"
style={{ display: 'inline-flex', alignItems: 'center', gap: '0.25rem', cursor: rowGlbUploading[item.id] ? 'wait' : 'pointer', fontSize: '0.7rem', color: rowGlbUploading[item.id] ? '#2563eb' : '#94908a', background: rowGlbUploading[item.id] ? 'rgba(59,130,246,0.06)' : 'transparent', border: `1px dashed ${rowGlbUploading[item.id] ? 'rgba(59,130,246,0.3)' : 'rgba(0,0,0,0.12)'}`, borderRadius: '0.375rem', padding: '0.2rem 0.45rem', whiteSpace: 'nowrap' }}
style={{ display: 'inline-flex', alignItems: 'center', gap: '0.25rem', cursor: rowGlbUploading[item.id] ? 'wait' : 'pointer', fontSize: '0.7rem', color: rowGlbUploading[item.id] ? '#2563eb' : '#8891C7', background: rowGlbUploading[item.id] ? 'rgba(59,130,246,0.06)' : 'transparent', border: `1px dashed ${rowGlbUploading[item.id] ? 'rgba(59,130,246,0.3)' : 'rgba(0,0,0,0.12)'}`, borderRadius: '0.375rem', padding: '0.2rem 0.45rem', whiteSpace: 'nowrap' }}
>
<input type="file" accept=".glb" style={{ display: 'none' }} onChange={(e) => {
const f = e.target.files?.[0] ?? null;
@ -642,7 +642,7 @@ export default function AdminPage() {
background: addItemGlb ? 'rgba(59,130,246,0.04)' : '#fff',
cursor: 'pointer',
fontSize: '0.8rem',
color: addItemGlb ? '#2563eb' : '#94908a',
color: addItemGlb ? '#2563eb' : '#8891C7',
transition: 'all 0.2s',
}}>
<input
@ -658,7 +658,7 @@ export default function AdminPage() {
{addItemGlb && (
<button
onClick={(e) => { e.preventDefault(); setAddItemGlb(null); }}
style={{ marginLeft: 'auto', background: 'none', border: 'none', cursor: 'pointer', color: '#94908a', fontSize: '0.75rem', padding: '0 2px' }}
style={{ marginLeft: 'auto', background: 'none', border: 'none', cursor: 'pointer', color: '#8891C7', fontSize: '0.75rem', padding: '0 2px' }}
></button>
)}
</label>
@ -686,7 +686,7 @@ export default function AdminPage() {
{activeTab === 'personas' && (
<div>
{!isPersonaHydrated ? (
<p style={{ color: '#6b6862', fontSize: '0.85rem' }}>Loading personas</p>
<p style={{ color: '#6a73a5', fontSize: '0.85rem' }}>Loading personas</p>
) : (
<TableCard>
<TableHeader cols="1fr 80px 80px 56px" labels={['Persona', 'Torso', 'Legs', '']} />
@ -694,15 +694,15 @@ export default function AdminPage() {
<div key={p.id} style={{ display: 'grid', gridTemplateColumns: '1fr 80px 80px 56px', padding: '0.875rem 1.25rem', alignItems: 'center', borderBottom: i < personas.length - 1 ? '1px solid rgba(0,0,0,0.04)' : 'none' }}>
<div>
<div style={{ fontSize: '0.85rem', color: '#374151', fontWeight: 500 }}>{p.label}</div>
<div style={{ fontSize: '0.7rem', color: '#94908a' }}>{p.description}</div>
<div style={{ fontSize: '0.7rem', color: '#8891C7' }}>{p.description}</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.375rem' }}>
<div style={{ width: 20, height: 20, borderRadius: 4, backgroundColor: p.colors.torso, border: '1px solid rgba(0,0,0,0.1)', flexShrink: 0 }} />
<span style={{ fontSize: '0.7rem', color: '#94908a', fontFamily: 'monospace' }}>{p.colors.torso}</span>
<span style={{ fontSize: '0.7rem', color: '#8891C7', fontFamily: 'monospace' }}>{p.colors.torso}</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.375rem' }}>
<div style={{ width: 20, height: 20, borderRadius: 4, backgroundColor: p.colors.legs, border: '1px solid rgba(0,0,0,0.1)', flexShrink: 0 }} />
<span style={{ fontSize: '0.7rem', color: '#94908a', fontFamily: 'monospace' }}>{p.colors.legs}</span>
<span style={{ fontSize: '0.7rem', color: '#8891C7', fontFamily: 'monospace' }}>{p.colors.legs}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'center' }}>
{p.id !== 'none' && (
@ -762,7 +762,7 @@ export default function AdminPage() {
</div>
{ordersError && <p style={errorTextStyle}>{ordersError}</p>}
{!ordersLoading && orders.length === 0 && !ordersError && (
<p style={{ color: '#94908a', fontSize: '0.85rem', textAlign: 'center', padding: '2rem' }}>No orders found.</p>
<p style={{ color: '#8891C7', fontSize: '0.85rem', textAlign: 'center', padding: '2rem' }}>No orders found.</p>
)}
{orders.length > 0 && (
<TableCard>
@ -791,7 +791,7 @@ export default function AdminPage() {
</div>
{contactsError && <p style={errorTextStyle}>{contactsError}</p>}
{!contactsLoading && contacts.length === 0 && !contactsError && (
<p style={{ color: '#94908a', fontSize: '0.85rem', textAlign: 'center', padding: '2rem' }}>No contact inquiries yet.</p>
<p style={{ color: '#8891C7', fontSize: '0.85rem', textAlign: 'center', padding: '2rem' }}>No contact inquiries yet.</p>
)}
{contacts.length > 0 && (
<TableCard>
@ -799,10 +799,10 @@ export default function AdminPage() {
{contacts.map((c, i) => (
<div key={c.id} style={{ display: 'grid', gridTemplateColumns: '1.5fr 1fr 1fr 2.5fr 1fr', padding: '1rem 1.25rem', alignItems: 'flex-start', borderBottom: i < contacts.length - 1 ? '1px solid rgba(0,0,0,0.04)' : 'none', gap: '1rem' }}>
<div style={{ fontSize: '0.85rem', fontWeight: 500, color: '#1e293b' }}>{c.name}</div>
<div style={{ fontSize: '0.8rem', color: '#6b6862' }}><a href={`mailto:${c.email}`} style={{ color: '#3b82f6', textDecoration: 'none' }}>{c.email}</a></div>
<div style={{ fontSize: '0.8rem', color: '#6b6862' }}>{c.phone ? <a href={`tel:${c.phone}`} style={{ color: '#6b6862', textDecoration: 'none' }}>{c.phone}</a> : '-'}</div>
<div style={{ fontSize: '0.8rem', color: '#6a73a5' }}><a href={`mailto:${c.email}`} style={{ color: '#3b82f6', textDecoration: 'none' }}>{c.email}</a></div>
<div style={{ fontSize: '0.8rem', color: '#6a73a5' }}>{c.phone ? <a href={`tel:${c.phone}`} style={{ color: '#6a73a5', textDecoration: 'none' }}>{c.phone}</a> : '-'}</div>
<div style={{ fontSize: '0.8rem', color: '#475569', whiteSpace: 'pre-wrap', lineHeight: 1.5 }}>{c.message}</div>
<div style={{ fontSize: '0.75rem', color: '#94908a' }}>{new Date(c.createdAt).toLocaleDateString('en-AE')}</div>
<div style={{ fontSize: '0.75rem', color: '#8891C7' }}>{new Date(c.createdAt).toLocaleDateString('en-AE')}</div>
</div>
))}
</TableCard>
@ -813,15 +813,15 @@ export default function AdminPage() {
{/* SETTINGS TAB */}
{activeTab === 'settings' && (
<div>
<h2 style={{ fontSize: '1rem', fontWeight: 700, color: '#0a0907', margin: '0 0 1rem' }}>App Settings</h2>
<h2 style={{ fontSize: '1rem', fontWeight: 700, color: '#0a0a0c', margin: '0 0 1rem' }}>App Settings</h2>
{settingError && <p style={{ color: '#dc2626', fontSize: '0.8rem', marginBottom: '0.75rem' }}>{settingError}</p>}
{settingsLoading ? (
<p style={{ color: '#6b6862', fontSize: '0.875rem' }}>Loading</p>
<p style={{ color: '#6a73a5', fontSize: '0.875rem' }}>Loading</p>
) : (
<TableCard>
<TableHeader cols="1fr 1.5fr 110px 50px" labels={['Key', 'Value', '', '']} />
{settings.length === 0 && (
<p style={{ padding: '1rem', color: '#94908a', fontSize: '0.8rem' }}>No settings yet.</p>
<p style={{ padding: '1rem', color: '#8891C7', fontSize: '0.8rem' }}>No settings yet.</p>
)}
{settings.map((s, i) => (
<SettingRow
@ -837,8 +837,8 @@ export default function AdminPage() {
)}
{/* Add new setting */}
<div style={{ marginTop: '1.25rem', padding: '1rem', background: '#f5f1e8', borderRadius: '0.75rem', border: '1px solid rgba(0,0,0,0.06)' }}>
<h3 style={{ fontSize: '0.875rem', fontWeight: 600, color: '#0a0907', margin: '0 0 0.75rem' }}>Add Setting</h3>
<div style={{ marginTop: '1.25rem', padding: '1rem', background: '#FBFBFD', borderRadius: '0.75rem', border: '1px solid rgba(0,0,0,0.06)' }}>
<h3 style={{ fontSize: '0.875rem', fontWeight: 600, color: '#0a0a0c', margin: '0 0 0.75rem' }}>Add Setting</h3>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1.5fr auto', gap: '0.5rem', alignItems: 'flex-end' }}>
<div>
<label style={labelStyle}>Key</label>
@ -869,7 +869,7 @@ export default function AdminPage() {
{showPwModal && (
<div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.3)', backdropFilter: 'blur(4px)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 50 }}>
<div style={{ background: '#fff', borderRadius: '1rem', padding: '1.5rem', width: '100%', maxWidth: '380px', boxShadow: '0 20px 60px rgba(0,0,0,0.15)' }}>
<h2 style={{ fontSize: '1rem', fontWeight: 700, color: '#0a0907', margin: '0 0 1.25rem' }}>Change Password</h2>
<h2 style={{ fontSize: '1rem', fontWeight: 700, color: '#0a0a0c', margin: '0 0 1.25rem' }}>Change Password</h2>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
{(['current', 'next', 'confirm'] as const).map((field) => (
<div key={field}>
@ -918,7 +918,7 @@ function SettingRow({
useEffect(() => { setEditVal(setting.value); }, [setting.value]);
return (
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1.5fr 110px 50px', gap: '0.75rem', padding: '0.625rem 1rem', alignItems: 'center', background: index % 2 === 0 ? '#fff' : '#f5f1e8', borderTop: index > 0 ? '1px solid rgba(0,0,0,0.04)' : 'none' }}>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1.5fr 110px 50px', gap: '0.75rem', padding: '0.625rem 1rem', alignItems: 'center', background: index % 2 === 0 ? '#fff' : '#FBFBFD', borderTop: index > 0 ? '1px solid rgba(0,0,0,0.04)' : 'none' }}>
<span style={{ fontSize: '0.8rem', fontFamily: 'monospace', color: '#334155' }}>{setting.key}</span>
<input
value={editVal}
@ -979,7 +979,7 @@ function OrderRow({
const fieldStyle: React.CSSProperties = {
fontSize: '0.63rem',
fontWeight: 600,
color: '#94908a',
color: '#8891C7',
textTransform: 'uppercase',
letterSpacing: '0.04em',
};
@ -996,8 +996,8 @@ function OrderRow({
<div style={{ display: 'grid', gridTemplateColumns: '1fr 130px 90px 100px 28px', padding: '0.75rem 1.25rem', alignItems: 'center' }}>
<div>
<div style={{ fontSize: '0.85rem', color: '#374151', fontWeight: 500 }}>{name}</div>
{email && <div style={{ fontSize: '0.7rem', color: '#94908a' }}>{email}</div>}
<div style={{ fontSize: '0.65rem', color: '#cbc4b3', fontFamily: 'monospace', marginTop: '0.1rem' }}>{order.id}</div>
{email && <div style={{ fontSize: '0.7rem', color: '#8891C7' }}>{email}</div>}
<div style={{ fontSize: '0.65rem', color: '#DEE0F0', fontFamily: 'monospace', marginTop: '0.1rem' }}>{order.id}</div>
</div>
<div style={{ fontSize: '0.85rem', color: '#374151', fontWeight: 500 }}>{formatAmount(order.amount, order.currency)}</div>
<div>
@ -1008,17 +1008,17 @@ function OrderRow({
fontSize: '0.65rem',
fontWeight: 600,
textTransform: 'uppercase',
background: order.status === 'succeeded' ? 'rgba(34,197,94,0.1)' : order.status === 'canceled' ? 'rgba(239,68,68,0.08)' : 'rgba(196, 162, 101,0.15)',
color: order.status === 'succeeded' ? '#16a34a' : order.status === 'canceled' ? '#dc2626' : '#6b6862',
background: order.status === 'succeeded' ? 'rgba(34,197,94,0.1)' : order.status === 'canceled' ? 'rgba(239,68,68,0.08)' : 'rgba(39, 63, 148,0.15)',
color: order.status === 'succeeded' ? '#16a34a' : order.status === 'canceled' ? '#dc2626' : '#6a73a5',
}}>
{order.status}
</span>
</div>
<div style={{ fontSize: '0.75rem', color: '#94908a' }}>{formatDate(order.created)}</div>
<div style={{ fontSize: '0.75rem', color: '#8891C7' }}>{formatDate(order.created)}</div>
<button
onClick={handleExpand}
title={expanded ? 'Collapse' : 'Show details'}
style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#94908a', fontSize: '0.7rem', padding: '2px 4px', borderRadius: 4 }}
style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#8891C7', fontSize: '0.7rem', padding: '2px 4px', borderRadius: 4 }}
>
{expanded ? '▲' : '▼'}
</button>
@ -1073,16 +1073,16 @@ function OrderRow({
</div>
))}
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: '0.4rem', marginTop: '0.1rem', borderTop: '1px solid rgba(0,0,0,0.07)' }}>
<span style={{ fontSize: '0.82rem', fontWeight: 700, color: '#0a0907' }}>Total</span>
<span style={{ fontSize: '0.88rem', fontWeight: 700, color: '#0a0907', fontFamily: 'monospace' }}>
<span style={{ fontSize: '0.82rem', fontWeight: 700, color: '#0a0a0c' }}>Total</span>
<span style={{ fontSize: '0.88rem', fontWeight: 700, color: '#0a0a0c', fontFamily: 'monospace' }}>
{formatAmount(order.amount, order.currency)}
</span>
</div>
</div>
) : (
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ fontSize: '0.78rem', color: '#6b6862' }}>Total (legacy order)</span>
<span style={{ fontSize: '0.88rem', fontWeight: 700, color: '#0a0907', fontFamily: 'monospace' }}>
<span style={{ fontSize: '0.78rem', color: '#6a73a5' }}>Total (legacy order)</span>
<span style={{ fontSize: '0.88rem', fontWeight: 700, color: '#0a0a0c', fontFamily: 'monospace' }}>
{formatAmount(order.amount, order.currency)}
</span>
</div>
@ -1090,16 +1090,16 @@ function OrderRow({
</SectionBox>
{/* Payment ID */}
<div style={{ fontSize: '0.65rem', color: '#cbc4b3', fontFamily: 'monospace' }}>
<div style={{ fontSize: '0.65rem', color: '#DEE0F0', fontFamily: 'monospace' }}>
Payment ID: {order.id}
</div>
</div>
{/* Right: snapshot */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.375rem' }}>
<div style={{ fontSize: '0.63rem', fontWeight: 600, color: '#94908a', textTransform: 'uppercase', letterSpacing: '0.04em' }}>Robot Snapshot</div>
<div style={{ fontSize: '0.63rem', fontWeight: 600, color: '#8891C7', textTransform: 'uppercase', letterSpacing: '0.04em' }}>Robot Snapshot</div>
{snapshot === 'loading' && (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', minHeight: 120, fontSize: '0.75rem', color: '#94908a' }}>Loading</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', minHeight: 120, fontSize: '0.75rem', color: '#8891C7' }}>Loading</div>
)}
{snapshot && snapshot !== 'loading' && snapshot !== 'none' && (
/* eslint-disable-next-line @next/next/no-img-element */
@ -1110,7 +1110,7 @@ function OrderRow({
/>
)}
{snapshot === 'none' && (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', minHeight: 80, fontSize: '0.72rem', color: '#cbc4b3' }}>No snapshot</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', minHeight: 80, fontSize: '0.72rem', color: '#DEE0F0' }}>No snapshot</div>
)}
</div>
</div>
@ -1122,7 +1122,7 @@ function OrderRow({
function SectionBox({ title, children }: { title: string; children: React.ReactNode }) {
return (
<div style={{ background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', padding: '0.75rem 1rem' }}>
<div style={{ fontSize: '0.6rem', fontWeight: 700, color: '#94908a', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: '0.5rem' }}>{title}</div>
<div style={{ fontSize: '0.6rem', fontWeight: 700, color: '#8891C7', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: '0.5rem' }}>{title}</div>
{children}
</div>
);
@ -1138,7 +1138,7 @@ function InfoField({ label, value }: { label: string; value?: string | null }) {
if (!value) return null;
return (
<div>
<div style={{ fontSize: '0.63rem', fontWeight: 600, color: '#94908a', textTransform: 'uppercase', letterSpacing: '0.04em' }}>{label}</div>
<div style={{ fontSize: '0.63rem', fontWeight: 600, color: '#8891C7', textTransform: 'uppercase', letterSpacing: '0.04em' }}>{label}</div>
<div style={{ fontSize: '0.8rem', color: '#374151', marginTop: '0.1rem', wordBreak: 'break-word' }}>{value}</div>
</div>
);
@ -1147,8 +1147,8 @@ function InfoField({ label, value }: { label: string; value?: string | null }) {
function StatCard({ label, value }: { label: string; value: string }) {
return (
<div style={{ background: 'rgba(255,255,255,0.95)', border: '1px solid rgba(0,0,0,0.06)', borderRadius: '0.75rem', padding: '1rem 1.25rem' }}>
<div style={{ fontSize: '0.7rem', fontWeight: 600, color: '#94908a', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: '0.25rem' }}>{label}</div>
<div style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0907' }}>{value}</div>
<div style={{ fontSize: '0.7rem', fontWeight: 600, color: '#8891C7', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: '0.25rem' }}>{label}</div>
<div style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0a0c' }}>{value}</div>
</div>
);
}
@ -1165,7 +1165,7 @@ function TableHeader({ cols, labels }: { cols: string; labels: string[] }) {
return (
<div style={{ display: 'grid', gridTemplateColumns: cols, padding: '0.6rem 1.25rem', borderBottom: '1px solid rgba(0,0,0,0.04)', background: 'rgba(248,248,246,0.5)' }}>
{labels.map((l) => (
<span key={l} style={{ fontSize: '0.65rem', fontWeight: 600, color: '#6b6862', textTransform: 'uppercase', letterSpacing: '0.05em' }}>{l}</span>
<span key={l} style={{ fontSize: '0.65rem', fontWeight: 600, color: '#6a73a5', textTransform: 'uppercase', letterSpacing: '0.05em' }}>{l}</span>
))}
</div>
);
@ -1204,7 +1204,7 @@ const formInputStyle: React.CSSProperties = {
borderRadius: '0.375rem',
border: '1px solid rgba(0,0,0,0.1)',
background: '#ffffff',
color: '#0a0907',
color: '#0a0a0c',
fontSize: '0.8rem',
outline: 'none',
boxSizing: 'border-box',
@ -1216,7 +1216,7 @@ const tableInputStyle: React.CSSProperties = {
borderRadius: '0.375rem',
border: '1px solid rgba(0,0,0,0.1)',
background: '#ffffff',
color: '#0a0907',
color: '#0a0a0c',
fontSize: '0.8rem',
fontFamily: 'monospace',
textAlign: 'right' as const,

View File

@ -21,7 +21,7 @@ export default function BookDemoPage() {
<h1 style={{ margin: 0, fontSize: 'clamp(2rem, 5vw, 3.2rem)', fontWeight: 300, lineHeight: 1.05, letterSpacing: '-0.03em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>See the future in person.</span>
</h1>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
Book a live robot demo at our Dubai showroom or schedule an on-site demo at your venue. Our team will tailor the demo to your use case before you arrive.
</p>
@ -32,8 +32,8 @@ export default function BookDemoPage() {
'Walk through configuration and deployment options',
'Get UAE-specific pricing and availability',
].map((b) => (
<li key={b} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.625rem', color: '#cbc4b3', lineHeight: 1.55 }}>
<span style={{ width: 8, height: 8, marginTop: 8, borderRadius: 999, background: '#e0c896', flex: 'none' }} />
<li key={b} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.625rem', color: '#DEE0F0', lineHeight: 1.55 }}>
<span style={{ width: 8, height: 8, marginTop: 8, borderRadius: 999, background: '#DEE0F0', flex: 'none' }} />
{b}
</li>
))}

View File

@ -28,10 +28,10 @@ export default function BrandsPage() {
Selected Unitree and Pudu solutions exclusively in the UAE.
</span>
</h1>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
YS Lootah Robotics holds exclusive UAE sales rights for selected Unitree and Pudu Robotics solutions with on-the-ground sales, demo, and deployment support across Dubai and the UAE.
</p>
<p style={{ margin: 0, color: '#6b6862', fontSize: '0.82rem', lineHeight: 1.6 }}>
<p style={{ margin: 0, color: '#6a73a5', fontSize: '0.82rem', lineHeight: 1.6 }}>
Brand names and product trademarks are property of their respective owners. Available exclusively in the UAE through YS Lootah Robotics.
</p>
</div>
@ -57,7 +57,7 @@ export default function BrandsPage() {
{robots.length} model{robots.length === 1 ? '' : 's'}
</span>
</div>
<p style={{ margin: 0, color: '#cbc4b3', lineHeight: 1.7, maxWidth: 800, marginBottom: '1.5rem' }}>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7, maxWidth: 800, marginBottom: '1.5rem' }}>
{brand.description}
</p>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.625rem', marginBottom: '2rem' }}>

View File

@ -17,8 +17,8 @@ export default function ConfigurePage() {
paddingLeft: 'clamp(1rem, 4vw, 2rem)',
paddingRight: 'clamp(1rem, 4vw, 2rem)',
background:
'radial-gradient(ellipse 60% 80% at 50% 0%, rgba(196, 162, 101,0.12), transparent 60%), linear-gradient(180deg, #050505 0%, #030303 100%)',
borderBottom: '1px solid rgba(196, 162, 101,0.12)',
'radial-gradient(ellipse 60% 80% at 50% 0%, rgba(39, 63, 148,0.12), transparent 60%), linear-gradient(180deg, #050505 0%, #030303 100%)',
borderBottom: '1px solid rgba(39, 63, 148,0.12)',
}}
>
<div style={{ maxWidth: 1320, margin: '0 auto', display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
@ -34,7 +34,7 @@ export default function ConfigurePage() {
>
<span className="text-gradient" style={{ fontWeight: 500 }}>Configure your robot.</span>
</h1>
<p style={{ margin: 0, color: '#94908a', fontSize: 'clamp(0.85rem, 1.6vw, 0.95rem)', lineHeight: 1.6, maxWidth: 720 }}>
<p style={{ margin: 0, color: '#8891C7', fontSize: 'clamp(0.85rem, 1.6vw, 0.95rem)', lineHeight: 1.6, maxWidth: 720 }}>
Choose persona, attire, colors, and accessories visualize your Unitree G1 humanoid before you request a quotation from YS Lootah Robotics.
</p>
</div>

View File

@ -21,14 +21,14 @@ export default function ContactPage() {
<h1 style={{ margin: 0, fontSize: 'clamp(2rem, 5vw, 3.2rem)', fontWeight: 300, lineHeight: 1.05, letterSpacing: '-0.03em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>Talk to our Dubai robotics team.</span>
</h1>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
Tell us about your venue, timeline, and use case. We will recommend a robot, share availability, and book a live demo at our Dubai showroom.
</p>
<div className="card" style={{ padding: 'clamp(1.5rem, 4vw, 2rem)', display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<ContactRow label="Phone" value="+971 55 948 2728" href="tel:+971559482728" />
<ContactRow label="Office" value="+971 4 349 9319" href="tel:+97143499319" />
<ContactRow label="Email" value="info@yslootahtech.com" href="mailto:info@yslootahtech.com" />
<ContactRow label="Email" value="info@yslootahrobotics.com" href="mailto:info@yslootahrobotics.com" />
<ContactRow label="WhatsApp" value="+971 55 948 2728" href="https://wa.me/971559482728" external />
<ContactRow label="Address" value="Office 408, City Bay Business Center, Dubai, UAE" href="https://maps.google.com/?q=Office+408+City+Bay+Business+Center+Dubai" external />
</div>
@ -60,13 +60,13 @@ function ContactRow({ label, value, href, external = false }: { label: string; v
alignItems: 'center',
gap: '1rem',
padding: '0.75rem 0',
borderBottom: '1px solid rgba(196, 162, 101,0.1)',
borderBottom: '1px solid rgba(39, 63, 148,0.1)',
textDecoration: 'none',
color: '#f5f1e8',
color: '#FBFBFD',
}}
>
<span style={{ fontSize: '0.7rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#94908a' }}>{label}</span>
<span style={{ fontSize: '0.95rem', color: '#f5f1e8', textAlign: 'right' }}>{value}</span>
<span style={{ fontSize: '0.7rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8891C7' }}>{label}</span>
<span style={{ fontSize: '0.95rem', color: '#FBFBFD', textAlign: 'right' }}>{value}</span>
</a>
);
}

View File

@ -1,44 +1,48 @@
@import "tailwindcss";
@theme {
/* === Luxury robotics — Black + Gold === */
--color-bg: #050505;
--color-bg-2: #0a0a0c;
--color-bg-3: #111114;
--color-bg-4: #18181c;
--color-surface: rgba(20, 18, 14, 0.7);
--color-primary: #050505;
--color-secondary: #0a0a0c;
/* === Luxury robotics — Graphite + Royal Blue + Silver === */
--color-bg: #0a0a0c;
--color-bg-2: #16151a;
--color-bg-3: #1c1b21;
--color-bg-4: #221f20;
--color-surface: rgba(34, 31, 32, 0.7);
--color-primary: #0a0a0c;
--color-secondary: #16151a;
/* Gold spectrum (matches YS Lootah brand) */
--color-gold: #c4a265;
--color-gold-light: #e0c896;
--color-gold-rich: #d4af6a;
--color-gold-bronze: #8b6f47;
--color-gold-deep: #6b5436;
/* Logo palette */
--color-blue: #273F94;
--color-blue-deep: #1a2e6e;
--color-blue-bright: #3a55c4;
--color-silver: #DEE0F0;
--color-silver-soft: #BFC3E2;
--color-steel: #8891C7;
--color-graphite: #221F20;
--color-white: #FBFBFD;
/* Accent aliases */
--color-accent: #c4a265;
--color-accent-2: #d4af6a;
--color-accent-3: #8b6f47;
--color-accent-hover: #d4af6a;
/* Accent aliases (kept for legacy class names) */
--color-gold: #DEE0F0;
--color-accent: #273F94;
--color-accent-2: #BFC3E2;
--color-accent-3: #8891C7;
--color-accent-hover: #3a55c4;
/* Text */
--color-text-primary: #f5f1e8;
--color-text-secondary: #cbc4b3;
--color-text-muted: #94908a;
--color-text-dim: #6b6862;
--color-text-primary: #FBFBFD;
--color-text-secondary: #DEE0F0;
--color-text-muted: #8891C7;
--color-text-dim: #6a73a5;
/* Borders */
--color-border: rgba(196, 162, 101, 0.18);
--color-border-strong: rgba(196, 162, 101, 0.36);
--color-border-light: rgba(196, 162, 101, 0.08);
--color-border-neutral: rgba(245, 241, 232, 0.08);
--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-neutral: rgba(255, 255, 255, 0.08);
/* Glass */
--color-glass-bg: rgba(20, 18, 14, 0.55);
--color-glass-border: rgba(196, 162, 101, 0.22);
--color-glass-highlight: rgba(245, 241, 232, 0.05);
--color-glass-bg: rgba(28, 27, 33, 0.6);
--color-glass-border: rgba(191, 195, 226, 0.22);
--color-glass-highlight: rgba(222, 224, 240, 0.06);
/* Spacing */
--spacing-xs: 0.25rem;
@ -56,9 +60,9 @@
--radius-2xl: 1.5rem;
/* Shadows */
--shadow-glow: 0 0 30px rgba(196, 162, 101, 0.22);
--shadow-glow-lg: 0 0 60px rgba(196, 162, 101, 0.28);
--shadow-card: 0 14px 50px rgba(0, 0, 0, 0.55);
--shadow-glow: 0 0 30px rgba(39, 63, 148, 0.32);
--shadow-glow-lg: 0 0 60px rgba(39, 63, 148, 0.4);
--shadow-card: 0 14px 50px rgba(0, 0, 0, 0.6);
/* Transitions */
--transition-fast: 150ms ease;
@ -81,10 +85,10 @@ body {
body {
background:
radial-gradient(1200px 700px at 80% -10%, rgba(196, 162, 101, 0.10), transparent 60%),
radial-gradient(900px 500px at -10% 30%, rgba(196, 162, 101, 0.06), transparent 60%),
radial-gradient(800px 500px at 50% 110%, rgba(139, 111, 71, 0.10), transparent 60%),
linear-gradient(180deg, #030303 0%, #050505 50%, #030303 100%);
radial-gradient(1200px 700px at 80% -10%, rgba(39, 63, 148, 0.18), transparent 60%),
radial-gradient(900px 500px at -10% 30%, rgba(58, 85, 196, 0.10), transparent 60%),
radial-gradient(800px 500px at 50% 110%, rgba(136, 145, 199, 0.10), transparent 60%),
linear-gradient(180deg, #050507 0%, #0a0a0c 50%, #050507 100%);
background-attachment: fixed;
}
@ -93,12 +97,12 @@ html {
}
:focus-visible {
outline: 2px solid var(--color-gold);
outline: 2px solid var(--color-blue);
outline-offset: 2px;
}
::selection {
background-color: rgba(196, 162, 101, 0.4);
background-color: rgba(39, 63, 148, 0.55);
color: #ffffff;
}
@ -123,9 +127,9 @@ html {
background: linear-gradient(135deg, var(--color-glass-highlight) 0%, transparent 60%);
}
/* === Typography gradients === */
/* === Typography gradients (metallic silver-blue) === */
.text-gradient {
background: linear-gradient(135deg, #ffffff 0%, #f5e9c8 40%, #d4af6a 100%);
background: linear-gradient(135deg, #FBFBFD 0%, #DEE0F0 45%, #8891C7 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
@ -133,18 +137,17 @@ html {
}
.text-gradient-accent {
background: linear-gradient(135deg, #e0c896 0%, #c4a265 50%, #8b6f47 100%);
background: linear-gradient(135deg, #FBFBFD 0%, #DEE0F0 35%, #BFC3E2 65%, #273F94 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.text-gold {
color: var(--color-gold);
}
.text-blue { color: var(--color-blue); }
.text-silver { color: var(--color-silver); }
/* Metallic gold border */
/* Metallic silver-blue border */
.metallic-border {
position: relative;
}
@ -154,7 +157,7 @@ html {
inset: 0;
border-radius: inherit;
padding: 1px;
background: linear-gradient(135deg, rgba(224, 200, 150, 0.6), rgba(196, 162, 101, 0.25) 45%, rgba(139, 111, 71, 0.0) 100%);
background: linear-gradient(135deg, rgba(222, 224, 240, 0.55), rgba(136, 145, 199, 0.3) 45%, rgba(39, 63, 148, 0.0) 100%);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
@ -166,10 +169,10 @@ html {
position: absolute;
inset: 0;
background:
radial-gradient(ellipse 70% 60% at 60% 40%, rgba(196, 162, 101, 0.20) 0%, transparent 60%),
radial-gradient(ellipse 60% 50% at 20% 70%, rgba(139, 111, 71, 0.18) 0%, transparent 55%),
radial-gradient(ellipse 80% 70% at 80% 100%, rgba(224, 200, 150, 0.14) 0%, transparent 60%),
linear-gradient(180deg, #050505 0%, #070605 50%, #030303 100%);
radial-gradient(ellipse 70% 60% at 60% 40%, rgba(39, 63, 148, 0.32) 0%, transparent 60%),
radial-gradient(ellipse 60% 50% at 20% 70%, rgba(58, 85, 196, 0.22) 0%, transparent 55%),
radial-gradient(ellipse 80% 70% at 80% 100%, rgba(136, 145, 199, 0.18) 0%, transparent 60%),
linear-gradient(180deg, #07080c 0%, #0a0a10 50%, #050507 100%);
animation: heroShift 16s ease-in-out infinite alternate;
}
@ -183,8 +186,8 @@ html {
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(196, 162, 101, 0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(196, 162, 101, 0.04) 1px, transparent 1px);
linear-gradient(rgba(191, 195, 226, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(191, 195, 226, 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%);
@ -199,12 +202,29 @@ html {
}
.shimmer {
background: linear-gradient(110deg, transparent 35%, rgba(224, 200, 150, 0.12) 50%, transparent 65%);
background: linear-gradient(110deg, transparent 35%, rgba(222, 224, 240, 0.14) 50%, transparent 65%);
background-size: 200% 100%;
animation: shimmer 3.5s linear infinite;
}
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
/* Cinematic light sweep across hero */
.light-sweep {
position: absolute;
inset: 0;
pointer-events: none;
background: linear-gradient(110deg, transparent 30%, rgba(191, 195, 226, 0.07) 50%, transparent 70%);
background-size: 250% 100%;
animation: lightSweep 9s ease-in-out infinite;
mix-blend-mode: screen;
}
@keyframes lightSweep {
0% { background-position: 200% 0; opacity: 0; }
25% { opacity: 1; }
75% { opacity: 1; }
100% { background-position: -200% 0; opacity: 0; }
}
.float-y { animation: floatY 6s ease-in-out infinite; }
@keyframes floatY {
0%, 100% { transform: translateY(0); }
@ -214,8 +234,8 @@ html {
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulseGlow {
0%, 100% { box-shadow: 0 0 0 0 rgba(196, 162, 101, 0.55), 0 0 40px rgba(196, 162, 101, 0.25); }
50% { box-shadow: 0 0 0 12px rgba(196, 162, 101, 0), 0 0 60px rgba(196, 162, 101, 0.45); }
0%, 100% { box-shadow: 0 0 0 0 rgba(39, 63, 148, 0.55), 0 0 40px rgba(39, 63, 148, 0.32); }
50% { box-shadow: 0 0 0 12px rgba(39, 63, 148, 0), 0 0 60px rgba(39, 63, 148, 0.55); }
}
/* Scroll indicator */
@ -232,7 +252,7 @@ html {
left: 0;
width: 1px;
height: 100%;
background: linear-gradient(180deg, var(--color-gold), transparent);
background: linear-gradient(180deg, var(--color-blue), transparent);
animation: scrollPulse 2s ease-in-out infinite;
}
@keyframes scrollPulse {
@ -243,8 +263,8 @@ html {
/* === Scrollbar === */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--color-bg-2); }
::-webkit-scrollbar-thumb { background: rgba(196, 162, 101, 0.25); border-radius: var(--radius-sm); }
::-webkit-scrollbar-thumb:hover { background: rgba(196, 162, 101, 0.55); }
::-webkit-scrollbar-thumb { background: rgba(136, 145, 199, 0.28); border-radius: var(--radius-sm); }
::-webkit-scrollbar-thumb:hover { background: rgba(39, 63, 148, 0.7); }
/* === Buttons === */
.btn {
@ -266,33 +286,33 @@ html {
.btn:hover { transform: translateY(-1px); }
.btn-primary {
background: linear-gradient(135deg, #e0c896 0%, #c4a265 55%, #8b6f47 100%);
color: #0b0905;
box-shadow: 0 8px 28px rgba(196, 162, 101, 0.35), inset 0 1px 0 rgba(255, 244, 220, 0.4);
background: linear-gradient(135deg, #3a55c4 0%, #273F94 55%, #1a2e6e 100%);
color: #FBFBFD;
box-shadow: 0 8px 28px rgba(39, 63, 148, 0.45), inset 0 1px 0 rgba(222, 224, 240, 0.25);
}
.btn-primary:hover {
box-shadow: 0 12px 38px rgba(224, 200, 150, 0.55), inset 0 1px 0 rgba(255, 244, 220, 0.5);
box-shadow: 0 12px 38px rgba(58, 85, 196, 0.6), inset 0 1px 0 rgba(222, 224, 240, 0.35);
}
.btn-ghost {
background: rgba(245, 241, 232, 0.04);
color: #f5f1e8;
border-color: rgba(196, 162, 101, 0.28);
background: rgba(222, 224, 240, 0.04);
color: #FBFBFD;
border-color: rgba(191, 195, 226, 0.28);
backdrop-filter: blur(12px);
}
.btn-ghost:hover {
background: rgba(196, 162, 101, 0.10);
border-color: rgba(196, 162, 101, 0.55);
color: #e0c896;
background: rgba(39, 63, 148, 0.16);
border-color: rgba(136, 145, 199, 0.6);
color: #DEE0F0;
}
.btn-outline {
background: transparent;
color: #e0c896;
border-color: rgba(196, 162, 101, 0.55);
color: #DEE0F0;
border-color: rgba(136, 145, 199, 0.55);
}
.btn-outline:hover {
background: rgba(196, 162, 101, 0.10);
background: rgba(39, 63, 148, 0.14);
}
/* === Layout helpers === */
@ -312,13 +332,13 @@ html {
content: '';
width: 28px;
height: 1px;
background: linear-gradient(90deg, transparent, var(--color-gold));
background: linear-gradient(90deg, transparent, var(--color-silver));
}
/* === Cards === */
.card {
position: relative;
background: rgba(10, 9, 7, 0.72);
background: rgba(22, 21, 26, 0.72);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid var(--color-border);
@ -328,8 +348,8 @@ html {
}
.card:hover {
transform: translateY(-6px);
border-color: rgba(196, 162, 101, 0.55);
box-shadow: 0 20px 60px rgba(0,0,0,0.7), 0 0 40px rgba(196, 162, 101, 0.15);
border-color: rgba(136, 145, 199, 0.55);
box-shadow: 0 20px 60px rgba(0,0,0,0.7), 0 0 40px rgba(39, 63, 148, 0.22);
}
/* === Configurator (preserve previous theme rules) === */
@ -461,6 +481,7 @@ html {
scroll-behavior: auto !important;
}
.hero-gradient { animation: none !important; }
.light-sweep { animation: none !important; opacity: 0 !important; }
}
html, body { overflow-x: hidden; max-width: 100vw; }

View File

@ -25,7 +25,7 @@ export default function IndustriesPage() {
Robotics solutions for UAE businesses.
</span>
</h1>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
We deploy humanoid, quadruped, and service robots across industries that are reshaping how the UAE operates every venue is matched to the right robot.
</p>
</div>

View File

@ -45,7 +45,7 @@ export const metadata: Metadata = {
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
themeColor: '#050505',
themeColor: '#0a0a0c',
};
export default function RootLayout({

View File

@ -12,6 +12,10 @@ import { ExclusiveAccessSection } from '@/components/robotics/ExclusiveAccessSec
import { MarqueeStrip } from '@/components/robotics/MarqueeStrip';
import { BentoGrid } from '@/components/robotics/BentoGrid';
import { HowItWorks } from '@/components/robotics/HowItWorks';
import { CompanyStory } from '@/components/robotics/CompanyStory';
import { ServicesGrid } from '@/components/robotics/ServicesGrid';
import { FounderSection } from '@/components/robotics/FounderSection';
import { BuSunaidahSection } from '@/components/robotics/BuSunaidahSection';
import { MotionSection } from '@/components/ui/MotionSection';
import { FEATURED_ROBOTS } from '@/data/robots';
@ -51,6 +55,12 @@ export default function HomePage() {
</div>
</MotionSection>
<MotionSection style={{ padding: 'clamp(3rem, 6vw, 5rem) 0' }} id="about">
<div className="container-wide">
<CompanyStory />
</div>
</MotionSection>
<MotionSection style={{ padding: 'clamp(3rem, 6vw, 5rem) 0' }} id="brands">
<div className="container-wide" style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
<SectionHeading
@ -111,6 +121,29 @@ export default function HomePage() {
</div>
</MotionSection>
<MotionSection style={{ padding: 'clamp(3rem, 6vw, 5rem) 0' }} id="services">
<div className="container-wide" style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
<SectionHeading
eyebrow="Our solutions"
title="Intelligent robotics across the full lifecycle."
description="From autonomous robotics and intelligent automation to motion programming, SDKs, and remote diagnostics — a complete robotics partner for UAE businesses."
/>
<ServicesGrid />
</div>
</MotionSection>
<MotionSection style={{ padding: 'clamp(3rem, 6vw, 5rem) 0' }} id="leadership">
<div className="container-wide">
<FounderSection />
</div>
</MotionSection>
<MotionSection style={{ padding: 'clamp(3rem, 6vw, 5rem) 0' }} id="bu-sunaidah">
<div className="container-wide">
<BuSunaidahSection />
</div>
</MotionSection>
<MotionSection style={{ padding: 'clamp(3rem, 6vw, 5rem) 0' }} id="how-it-works">
<div className="container-wide" style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
<SectionHeading
@ -158,7 +191,7 @@ function SectionHeading({ eyebrow, title, description }: { eyebrow: string; titl
<span className="text-gradient" style={{ fontWeight: 500 }}>{title}</span>
</h2>
{description && (
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
{description}
</p>
)}

View File

@ -9,38 +9,38 @@ export default function PrivacyPolicyPage() {
<div style={{ background: '#050508', minHeight: '100vh', color: '#ffffff', fontFamily: 'Inter, sans-serif' }}>
<main style={{ maxWidth: '800px', margin: '0 auto', padding: '12rem 1.5rem 6rem', lineHeight: 1.8 }}>
<h1 style={{ fontSize: '3rem', fontWeight: 200, marginBottom: '1rem', letterSpacing: '-0.03em' }}>Privacy <span style={{ color: 'var(--color-gold)', fontWeight: 500 }}>Policy</span></h1>
<p style={{ color: '#94908a', fontSize: '1rem', marginBottom: '4rem' }}>Effective Date: {new Date().toLocaleDateString('en-AE')}</p>
<p style={{ color: '#8891C7', fontSize: '1rem', marginBottom: '4rem' }}>Effective Date: {new Date().toLocaleDateString('en-AE')}</p>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>1. Information We Collect</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
At YS Lootah Robotics, we collect information you provide directly to us when you request information, use the G1 Customizer, or contact us. This includes your name, email address, phone number, and any other information you choose to provide in your message.
</p>
</section>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>2. How We Use Your Information</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
We use the information we collect to respond to your inquiries, deliver our robotics enterprise solutions, maintain our dashboard, and communicate with you about your custom humanoid configurations.
</p>
</section>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>3. Data Security</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
We implement robust security measures designed to protect your personal information. Your contact data is stored securely in our private databases strictly for administrative and operational purposes.
</p>
</section>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>4. Contact Us</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
If you have questions or concerns about this Privacy Policy, please reach out to us at:
<br/><br/>
<strong>YS Lootah Robotics</strong><br/>
Office 408, City Bay Business Center<br/>
Dubai, United Arab Emirates<br/>
Email: info@yslootahtech.com
Email: info@yslootahrobotics.com
</p>
</section>
</main>

View File

@ -71,7 +71,7 @@ function CatalogInner() {
</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: '0.5rem' }}>
<span style={{ color: '#94908a', fontSize: '0.85rem' }}>
<span style={{ color: '#8891C7', fontSize: '0.85rem' }}>
{filtered.length} robot{filtered.length === 1 ? '' : 's'} found
</span>
{(filter.brand !== 'all' || filter.category !== 'all') && (
@ -81,7 +81,7 @@ function CatalogInner() {
style={{
background: 'transparent',
border: 'none',
color: '#e0c896',
color: '#DEE0F0',
fontSize: '0.78rem',
letterSpacing: '0.14em',
textTransform: 'uppercase',
@ -95,9 +95,9 @@ function CatalogInner() {
</div>
{filtered.length === 0 ? (
<div className="card" style={{ padding: '2rem', textAlign: 'center', color: '#cbc4b3' }}>
<div className="card" style={{ padding: '2rem', textAlign: 'center', color: '#DEE0F0' }}>
No robots match these filters yet. Try a different brand or category, or{' '}
<a href="/contact/" style={{ color: '#e0c896', textDecoration: 'none' }}>contact us</a> for tailored options.
<a href="/contact/" style={{ color: '#DEE0F0', textDecoration: 'none' }}>contact us</a> for tailored options.
</div>
) : (
<div
@ -118,7 +118,7 @@ function CatalogInner() {
export function CatalogClient() {
return (
<Suspense fallback={<div className="card" style={{ padding: '2rem', color: '#cbc4b3' }}>Loading catalog</div>}>
<Suspense fallback={<div className="card" style={{ padding: '2rem', color: '#DEE0F0' }}>Loading catalog</div>}>
<CatalogInner />
</Suspense>
);

View File

@ -43,12 +43,12 @@ export default async function RobotDetailPage({ params }: { params: Promise<Para
<main style={{ paddingTop: 'clamp(6rem, 10vw, 8rem)', paddingBottom: 'clamp(4rem, 8vw, 6rem)' }}>
<div className="container-wide" style={{ display: 'flex', flexDirection: 'column', gap: 'clamp(3rem, 6vw, 5rem)' }}>
<nav style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', fontSize: '0.78rem', letterSpacing: '0.14em', textTransform: 'uppercase', color: '#94908a' }}>
<Link href="/" style={{ color: '#94908a', textDecoration: 'none' }}>Home</Link>
<nav style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', fontSize: '0.78rem', letterSpacing: '0.14em', textTransform: 'uppercase', color: '#8891C7' }}>
<Link href="/" style={{ color: '#8891C7', textDecoration: 'none' }}>Home</Link>
<span>/</span>
<Link href="/robots/" style={{ color: '#94908a', textDecoration: 'none' }}>Robots</Link>
<Link href="/robots/" style={{ color: '#8891C7', textDecoration: 'none' }}>Robots</Link>
<span>/</span>
<span style={{ color: '#cbc4b3' }}>{robot.name}</span>
<span style={{ color: '#DEE0F0' }}>{robot.name}</span>
</nav>
<section
@ -73,8 +73,8 @@ export default async function RobotDetailPage({ params }: { params: Promise<Para
padding: '0.3rem 0.55rem',
borderRadius: 999,
background: 'rgba(5, 5, 5,0.6)',
border: '1px solid rgba(196, 162, 101,0.2)',
color: '#94908a',
border: '1px solid rgba(39, 63, 148,0.2)',
color: '#8891C7',
fontSize: '0.62rem',
letterSpacing: '0.2em',
textTransform: 'uppercase',
@ -94,8 +94,8 @@ export default async function RobotDetailPage({ params }: { params: Promise<Para
{robot.name}
</span>
</h1>
<p style={{ margin: 0, color: '#e0c896', fontSize: '1.05rem', lineHeight: 1.5 }}>{robot.tagline}</p>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: '1rem', lineHeight: 1.7 }}>{robot.longDescription}</p>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: '1.05rem', lineHeight: 1.5 }}>{robot.tagline}</p>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: '1rem', lineHeight: 1.7 }}>{robot.longDescription}</p>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.625rem' }}>
<a className="btn btn-primary" href="#inquire">Request quotation</a>
@ -123,14 +123,14 @@ export default async function RobotDetailPage({ params }: { params: Promise<Para
<Block title="Key features">
<ul style={{ margin: 0, paddingLeft: '1.1rem', display: 'flex', flexDirection: 'column', gap: '0.6rem' }}>
{robot.features.map((f) => (
<li key={f} style={{ color: '#cbc4b3', lineHeight: 1.6 }}>{f}</li>
<li key={f} style={{ color: '#DEE0F0', lineHeight: 1.6 }}>{f}</li>
))}
</ul>
</Block>
<Block title="Use cases">
<ul style={{ margin: 0, paddingLeft: '1.1rem', display: 'flex', flexDirection: 'column', gap: '0.6rem' }}>
{robot.useCases.map((u) => (
<li key={u} style={{ color: '#cbc4b3', lineHeight: 1.6 }}>{u}</li>
<li key={u} style={{ color: '#DEE0F0', lineHeight: 1.6 }}>{u}</li>
))}
</ul>
</Block>
@ -156,7 +156,7 @@ export default async function RobotDetailPage({ params }: { params: Promise<Para
Request a quotation for {robot.name}.
</span>
</h2>
<p style={{ margin: 0, color: '#cbc4b3', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7 }}>
Tell us about your venue, timeline, and use case. We will respond with availability, configuration options, and pricing for the UAE.
</p>
</div>
@ -166,12 +166,12 @@ export default async function RobotDetailPage({ params }: { params: Promise<Para
<div className="card" style={{ padding: 'clamp(1.5rem, 4vw, 2.25rem)', display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<span className="eyebrow">Talk to an advisor</span>
<h3 style={{ margin: 0, fontSize: '1.25rem', fontWeight: 600 }}>Prefer a quick conversation?</h3>
<p style={{ margin: 0, color: '#cbc4b3', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7 }}>
Call our Dubai team or message us on WhatsApp we will share availability and demo slots for {robot.name}.
</p>
<a className="btn btn-ghost" href="tel:+971559482728">Call +971 55 948 2728</a>
<a className="btn btn-outline" href="https://wa.me/971559482728" target="_blank" rel="noopener noreferrer">WhatsApp us</a>
<a className="btn btn-ghost" href="mailto:info@yslootahtech.com">Email info@yslootahtech.com</a>
<a className="btn btn-ghost" href="mailto:info@yslootahrobotics.com">Email info@yslootahrobotics.com</a>
</div>
</div>
</MotionSection>

View File

@ -23,7 +23,7 @@ export default function RobotsPage() {
Robots ready to deploy across the UAE.
</span>
</h1>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
Browse {ROBOTS.length}+ models across our portfolio. Filter by brand or category, then request a price or book a live demo at our Dubai showroom.
</p>
</div>

View File

@ -9,32 +9,32 @@ export default function TermsOfServicePage() {
<div style={{ background: '#050508', minHeight: '100vh', color: '#ffffff', fontFamily: 'Inter, sans-serif' }}>
<main style={{ maxWidth: '800px', margin: '0 auto', padding: '12rem 1.5rem 6rem', lineHeight: 1.8 }}>
<h1 style={{ fontSize: '3rem', fontWeight: 200, marginBottom: '1rem', letterSpacing: '-0.03em' }}>Terms of <span style={{ color: 'var(--color-gold)', fontWeight: 500 }}>Service</span></h1>
<p style={{ color: '#94908a', fontSize: '1rem', marginBottom: '4rem' }}>Effective Date: {new Date().toLocaleDateString('en-AE')}</p>
<p style={{ color: '#8891C7', fontSize: '1rem', marginBottom: '4rem' }}>Effective Date: {new Date().toLocaleDateString('en-AE')}</p>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>1. Acceptance of Terms</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
By accessing and utilizing the YS Lootah Robotics web platform and the G1 Configurator, you accept and agree to be bound by the terms and provisions of this agreement.
</p>
</section>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>2. Use of the Site & Configurator</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
The 3D G1 Configurator is provided for informational and demonstrative purposes to showcase the capabilities of YS Lootah technologies. You agree to use this site strictly for lawful purposes resulting in enterprise robotics inquiries and configurations.
</p>
</section>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>3. Intellectual Property Rights</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
All original content on this website, including but not limited to text, graphics, 3D models (GLB files), logos, and software, is the exclusive property of YS Lootah Robotics and is protected by United Arab Emirates and international copyright laws.
</p>
</section>
<section style={{ marginBottom: '3rem' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 500, color: '#e8e0cf', marginBottom: '1rem' }}>4. Disclaimer of Warranties</h2>
<p style={{ color: '#cbc4b3', marginBottom: '1rem' }}>
<p style={{ color: '#DEE0F0', marginBottom: '1rem' }}>
The materials on our platform are provided "as is". We make no warranties, expressed or implied, and hereby disclaim to the fullest extent permitted by law all warranties regarding the immediate enterprise availability of the rendered concepts displayed in the Configurator.
</p>
</section>

View File

@ -103,7 +103,7 @@ export function CheckoutOverlay() {
borderRadius: '0.375rem',
border: '1px solid rgba(0, 0, 0, 0.08)',
background: 'transparent',
color: '#94908a',
color: '#8891C7',
cursor: 'pointer',
fontSize: '0.75rem',
transition: 'all 0.2s ease',
@ -111,7 +111,7 @@ export function CheckoutOverlay() {
>
Back
</button>
<h2 style={{ fontSize: '0.9rem', fontWeight: 600, color: '#0a0907', margin: 0 }}>
<h2 style={{ fontSize: '0.9rem', fontWeight: 600, color: '#0a0a0c', margin: 0 }}>
Checkout
</h2>
<button
@ -122,7 +122,7 @@ export function CheckoutOverlay() {
borderRadius: '50%',
border: '1px solid rgba(0, 0, 0, 0.08)',
background: 'transparent',
color: '#94908a',
color: '#8891C7',
cursor: 'pointer',
fontSize: '0.9rem',
display: 'flex',
@ -155,7 +155,7 @@ export function CheckoutOverlay() {
}} />
<span style={{
fontSize: '0.65rem',
color: isActive ? '#2563eb' : isComplete ? '#3b82f6' : '#6b6862',
color: isActive ? '#2563eb' : isComplete ? '#3b82f6' : '#6a73a5',
fontWeight: isActive ? 600 : 400,
textAlign: 'center',
}}>
@ -216,7 +216,7 @@ export function CheckoutOverlay() {
</button>
</div>
) : (
<span style={{ color: '#94908a' }}>Initializing secure payment...</span>
<span style={{ color: '#8891C7' }}>Initializing secure payment...</span>
)}
</div>
) : null}

View File

@ -141,14 +141,14 @@ export function ConfigPanel() {
<div style={{
fontSize: '0.8rem',
fontWeight: isActive ? 600 : 400,
color: isActive ? '#374151' : '#94908a',
color: isActive ? '#374151' : '#8891C7',
marginBottom: '2px',
}}>
{persona.label}
</div>
<div style={{
fontSize: '0.65rem',
color: '#6b6862',
color: '#6a73a5',
lineHeight: 1.3,
}}>
{persona.description}
@ -221,14 +221,14 @@ export function ConfigPanel() {
<div style={{
fontSize: '0.8rem',
fontWeight: isActive ? 600 : 500,
color: isActive ? '#374151' : '#6b6862',
color: isActive ? '#374151' : '#6a73a5',
marginBottom: '2px',
}}>
{opt.label}
</div>
<div style={{
fontSize: '0.65rem',
color: '#94908a',
color: '#8891C7',
lineHeight: 1.3,
}}>
{opt.description}
@ -282,7 +282,7 @@ function ColorInput({ label, value, onChange }: { label: string; value: string;
/>
<div style={{ flex: 1 }}>
<div style={{ fontSize: '0.8rem', color: '#374151', marginBottom: '2px' }}>{label}</div>
<div style={{ fontSize: '0.7rem', color: '#6b6862', fontFamily: 'monospace' }}>{value}</div>
<div style={{ fontSize: '0.7rem', color: '#6a73a5', fontFamily: 'monospace' }}>{value}</div>
</div>
</div>
);
@ -291,7 +291,7 @@ function ColorInput({ label, value, onChange }: { label: string; value: string;
const sectionTitleStyle: React.CSSProperties = {
fontSize: '0.75rem',
fontWeight: 500,
color: '#94908a',
color: '#8891C7',
textTransform: 'uppercase',
letterSpacing: '0.05em',
margin: 0,

View File

@ -94,7 +94,7 @@ export function ConfiguratorSection() {
style={{
fontSize: '1rem',
fontWeight: 600,
color: '#0a0907',
color: '#0a0a0c',
margin: 0,
}}
>
@ -156,7 +156,7 @@ export function ConfiguratorSection() {
animation: 'spin 1s linear infinite',
}}
/>
<p style={{ marginTop: '1rem', fontSize: '0.875rem', color: '#94908a' }}>
<p style={{ marginTop: '1rem', fontSize: '0.875rem', color: '#8891C7' }}>
{t('loading.configuration')}
</p>
</div>

View File

@ -1,12 +1,13 @@
'use client';
import Link from 'next/link';
import Image from 'next/image';
import { BRANDS } from '@/data/robots';
const CONTACT = {
phonePrimary: '+971 55 948 2728',
phoneSecondary: '+971 4 349 9319',
email: 'info@yslootahtech.com',
email: 'info@yslootahrobotics.com',
address: 'Office 408, City Bay Business Center, Dubai, UAE',
whatsapp: 'https://wa.me/971559482728',
maps: 'https://maps.google.com/?q=Office+408+City+Bay+Business+Center+Dubai',
@ -22,10 +23,10 @@ export function FooterAndContact() {
position: 'relative',
zIndex: 10,
marginTop: 'clamp(4rem, 8vw, 6rem)',
borderTop: '1px solid rgba(196, 162, 101,0.12)',
borderTop: '1px solid rgba(39, 63, 148,0.12)',
background:
'radial-gradient(ellipse 80% 60% at 50% 0%, rgba(196, 162, 101,0.05), transparent 60%), linear-gradient(180deg, #030303, #02040a)',
color: '#cbc4b3',
'radial-gradient(ellipse 80% 60% at 50% 0%, rgba(39, 63, 148,0.05), transparent 60%), linear-gradient(180deg, #030303, #02040a)',
color: '#DEE0F0',
}}
>
<div className="container-wide" style={{ paddingTop: 'clamp(3rem, 6vw, 5rem)', paddingBottom: '2rem' }}>
@ -38,37 +39,41 @@ export function FooterAndContact() {
}}
>
<div style={{ minWidth: 0 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.625rem', marginBottom: '1.25rem' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.7rem', marginBottom: '1.25rem' }}>
<span
aria-hidden
style={{
width: 36,
height: 36,
borderRadius: 10,
background: 'linear-gradient(135deg, #e0c896, #c4a265 50%, #8b6f47)',
boxShadow: '0 0 20px rgba(196, 162, 101,0.4)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
width: 46,
height: 46,
borderRadius: '50%',
overflow: 'hidden',
flex: 'none',
boxShadow: '0 0 18px rgba(39, 63, 148, 0.35)',
border: '1px solid rgba(39, 63, 148,0.4)',
}}
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#04111a" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
<rect x="4" y="6" width="16" height="12" rx="3" />
<path d="M9 12h6M12 2v4" />
</svg>
<Image
src="/images/brands/ys-lootah-robotics-logo.png"
alt="YS Lootah Robotics logo"
fill
sizes="46px"
style={{ objectFit: 'cover' }}
/>
</span>
<span style={{ display: 'flex', flexDirection: 'column', lineHeight: 1 }}>
<span style={{ fontSize: '1rem', fontWeight: 700, letterSpacing: '0.16em', color: '#ffffff', textTransform: 'uppercase' }}>
YS Lootah
</span>
<span style={{ fontSize: '0.7rem', fontWeight: 500, letterSpacing: '0.32em', color: '#e0c896', textTransform: 'uppercase', marginTop: 4 }}>
<span style={{ fontSize: '0.7rem', fontWeight: 500, letterSpacing: '0.32em', color: '#DEE0F0', textTransform: 'uppercase', marginTop: 4 }}>
Robotics
</span>
</span>
</div>
<p style={{ margin: 0, color: '#94908a', lineHeight: 1.7, fontSize: '0.95rem' }}>
Premium humanoid, quadruped, and service robotics available through YS Lootah Robotics for businesses and innovators across Dubai and the UAE.
<p style={{ margin: '0 0 0.75rem', color: '#DEE0F0', fontSize: '0.78rem', letterSpacing: '0.22em', textTransform: 'uppercase', fontWeight: 600 }}>
In Tech We Innovate · In Trust We Lead
</p>
<p style={{ margin: 0, color: '#8891C7', lineHeight: 1.7, fontSize: '0.95rem' }}>
Innovating today for a smarter tomorrow. YS Lootah Robotics the UAE&apos;s dedicated destination for selected Unitree and Pudu Robotics solutions.
</p>
<div style={{ display: 'flex', gap: '0.625rem', marginTop: '1.5rem' }}>
@ -110,7 +115,7 @@ export function FooterAndContact() {
/>
<div style={{ minWidth: 0 }}>
<h4 style={{ margin: '0 0 1.25rem', fontSize: '0.72rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#94908a', fontWeight: 700 }}>
<h4 style={{ margin: '0 0 1.25rem', fontSize: '0.72rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8891C7', fontWeight: 700 }}>
Contact
</h4>
<ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
@ -124,12 +129,12 @@ export function FooterAndContact() {
<a href={`mailto:${CONTACT.email}`} style={footerLink}>{CONTACT.email}</a>
</li>
<li>
<a href={CONTACT.maps} target="_blank" rel="noopener noreferrer" style={{ ...footerLink, color: '#94908a' }}>
<a href={CONTACT.maps} target="_blank" rel="noopener noreferrer" style={{ ...footerLink, color: '#8891C7' }}>
{CONTACT.address}
</a>
</li>
<li>
<a href={CONTACT.whatsapp} target="_blank" rel="noopener noreferrer" style={{ ...footerLink, color: '#e0c896' }}>
<a href={CONTACT.whatsapp} target="_blank" rel="noopener noreferrer" style={{ ...footerLink, color: '#DEE0F0' }}>
WhatsApp us
</a>
</li>
@ -137,19 +142,19 @@ export function FooterAndContact() {
</div>
</div>
<div style={{ borderTop: '1px solid rgba(196, 162, 101,0.1)', paddingTop: '1.75rem', display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', alignItems: 'center', gap: '1rem' }}>
<p style={{ margin: 0, fontSize: '0.82rem', color: '#6b6862' }}>
<div style={{ borderTop: '1px solid rgba(39, 63, 148,0.1)', paddingTop: '1.75rem', display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', alignItems: 'center', gap: '1rem' }}>
<p style={{ margin: 0, fontSize: '0.82rem', color: '#6a73a5' }}>
© {new Date().getFullYear()} YS Lootah Robotics. All rights reserved.
</p>
<p style={{ margin: 0, fontSize: '0.78rem', color: '#6b6862' }}>
<p style={{ margin: 0, fontSize: '0.78rem', color: '#6a73a5' }}>
Website designed &amp; developed by{' '}
<a href="https://yslootahtech.com" target="_blank" rel="noopener noreferrer" style={{ color: '#94908a', textDecoration: 'none' }}>
<a href="https://yslootahtech.com" target="_blank" rel="noopener noreferrer" style={{ color: '#8891C7', textDecoration: 'none' }}>
YS Lootah Tech
</a>
</p>
<div style={{ display: 'flex', gap: '1.5rem' }}>
<Link href="/privacy-policy/" style={{ fontSize: '0.82rem', color: '#6b6862', textDecoration: 'none' }}>Privacy</Link>
<Link href="/terms-of-service/" style={{ fontSize: '0.82rem', color: '#6b6862', textDecoration: 'none' }}>Terms</Link>
<Link href="/privacy-policy/" style={{ fontSize: '0.82rem', color: '#6a73a5', textDecoration: 'none' }}>Privacy</Link>
<Link href="/terms-of-service/" style={{ fontSize: '0.82rem', color: '#6a73a5', textDecoration: 'none' }}>Terms</Link>
</div>
</div>
</div>
@ -159,7 +164,7 @@ export function FooterAndContact() {
const footerLink: React.CSSProperties = {
fontSize: '0.9rem',
color: '#cbc4b3',
color: '#DEE0F0',
textDecoration: 'none',
transition: 'color 0.2s',
};
@ -167,7 +172,7 @@ const footerLink: React.CSSProperties = {
function ColumnLinks({ title, items }: { title: string; items: { label: string; href: string }[] }) {
return (
<div style={{ minWidth: 0 }}>
<h4 style={{ margin: '0 0 1.25rem', fontSize: '0.72rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#94908a', fontWeight: 700 }}>
<h4 style={{ margin: '0 0 1.25rem', fontSize: '0.72rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8891C7', fontWeight: 700 }}>
{title}
</h4>
<ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
@ -196,8 +201,8 @@ function SocialLink({ href, label, path }: { href: string; label: string; path:
alignItems: 'center',
justifyContent: 'center',
background: 'rgba(15, 12, 8,0.6)',
border: '1px solid rgba(196, 162, 101,0.18)',
color: '#94908a',
border: '1px solid rgba(39, 63, 148,0.18)',
color: '#8891C7',
transition: 'all 0.25s ease',
}}
>

View File

@ -116,7 +116,7 @@ export function InteractiveHotspot({
whiteSpace: 'nowrap',
fontFamily: 'system-ui, -apple-system, sans-serif',
fontSize: '12px',
color: '#0a0907',
color: '#0a0a0c',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',
animation: 'fadeIn 0.15s ease-out',
}}
@ -125,7 +125,7 @@ export function InteractiveHotspot({
<div
style={{
fontSize: '10px',
color: '#94908a',
color: '#8891C7',
display: 'flex',
alignItems: 'center',
gap: 4,

View File

@ -23,7 +23,7 @@ export function LanguageSwitcher() {
backgroundColor: 'rgba(0, 0, 0, 0.04)',
border: '1px solid rgba(0, 0, 0, 0.08)',
borderRadius: '0.5rem',
color: '#0a0907',
color: '#0a0a0c',
cursor: 'pointer',
fontSize: '0.875rem',
fontWeight: 500,

View File

@ -2,6 +2,7 @@
import React, { useEffect, useState } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { usePathname } from 'next/navigation';
const NAV_LINKS = [
@ -50,7 +51,7 @@ export function Navbar() {
background: scrolled ? 'rgba(5, 5, 5, 0.78)' : 'linear-gradient(180deg, rgba(5, 5, 5,0.6), rgba(5, 5, 5,0))',
backdropFilter: scrolled ? 'blur(18px)' : 'blur(8px)',
WebkitBackdropFilter: scrolled ? 'blur(18px)' : 'blur(8px)',
borderBottom: scrolled ? '1px solid rgba(196, 162, 101,0.14)' : '1px solid transparent',
borderBottom: scrolled ? '1px solid rgba(39, 63, 148,0.14)' : '1px solid transparent',
transition: 'all 0.35s cubic-bezier(0.16,1,0.3,1)',
}}
>
@ -66,31 +67,33 @@ export function Navbar() {
transition: 'padding 0.3s ease',
}}
>
<Link href="/" style={{ textDecoration: 'none', display: 'flex', alignItems: 'center', gap: '0.5rem', minWidth: 0 }} onClick={() => setMobileOpen(false)}>
<Link href="/" style={{ textDecoration: 'none', display: 'flex', alignItems: 'center', gap: '0.65rem', minWidth: 0 }} onClick={() => setMobileOpen(false)} aria-label="YS Lootah Robotics — Home">
<span
aria-hidden
style={{
width: 30,
height: 30,
borderRadius: 8,
background: 'linear-gradient(135deg, #e0c896, #c4a265 50%, #8b6f47)',
boxShadow: '0 0 18px rgba(196, 162, 101,0.4)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
width: 40,
height: 40,
borderRadius: '50%',
overflow: 'hidden',
flex: 'none',
boxShadow: '0 0 18px rgba(39, 63, 148, 0.35)',
border: '1px solid rgba(39, 63, 148,0.4)',
}}
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#04111a" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
<rect x="4" y="6" width="16" height="12" rx="3" />
<path d="M9 12h6M12 2v4" />
</svg>
<Image
src="/images/brands/ys-lootah-robotics-logo.png"
alt="YS Lootah Robotics logo"
fill
sizes="40px"
style={{ objectFit: 'cover' }}
priority
/>
</span>
<span style={{ display: 'flex', flexDirection: 'column', lineHeight: 1 }}>
<span style={{ fontSize: '0.95rem', fontWeight: 700, letterSpacing: '0.16em', color: '#ffffff', textTransform: 'uppercase' }}>
YS Lootah
</span>
<span style={{ fontSize: '0.7rem', fontWeight: 500, letterSpacing: '0.32em', color: '#e0c896', textTransform: 'uppercase', marginTop: 3 }}>
<span style={{ fontSize: '0.7rem', fontWeight: 500, letterSpacing: '0.32em', color: '#DEE0F0', textTransform: 'uppercase', marginTop: 3 }}>
Robotics
</span>
</span>
@ -103,7 +106,7 @@ export function Navbar() {
href={l.href}
style={{
position: 'relative',
color: isActive(l.href) ? '#e0c896' : '#cbc4b3',
color: isActive(l.href) ? '#DEE0F0' : '#DEE0F0',
fontSize: '0.78rem',
fontWeight: 600,
textDecoration: 'none',
@ -111,7 +114,7 @@ export function Navbar() {
textTransform: 'uppercase',
transition: 'color 0.2s',
paddingBottom: 4,
borderBottom: isActive(l.href) ? '1px solid #e0c896' : '1px solid transparent',
borderBottom: isActive(l.href) ? '1px solid #DEE0F0' : '1px solid transparent',
}}
>
{l.label}
@ -137,9 +140,9 @@ export function Navbar() {
width: 42,
height: 42,
borderRadius: 12,
border: '1px solid rgba(196, 162, 101,0.2)',
border: '1px solid rgba(39, 63, 148,0.2)',
background: 'rgba(15, 12, 8,0.6)',
color: '#f5f1e8',
color: '#FBFBFD',
cursor: 'pointer',
display: 'none',
alignItems: 'center',
@ -185,11 +188,11 @@ export function Navbar() {
style={{
fontSize: '1.5rem',
fontWeight: 500,
color: isActive(l.href) ? '#e0c896' : '#f5f1e8',
color: isActive(l.href) ? '#DEE0F0' : '#FBFBFD',
textDecoration: 'none',
letterSpacing: '-0.01em',
padding: '0.75rem 0',
borderBottom: '1px solid rgba(196, 162, 101,0.12)',
borderBottom: '1px solid rgba(39, 63, 148,0.12)',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',

View File

@ -94,7 +94,7 @@ function PayloadLoader({ modelPath }: { modelPath: string }) {
if (child instanceof THREE.Mesh) {
if (child.material) {
child.material = new THREE.MeshStandardMaterial({
color: '#6b6862',
color: '#6a73a5',
metalness: 0.6,
roughness: 0.4,
});

View File

@ -70,7 +70,7 @@ export function PricingEngine() {
<h3 style={{
fontSize: '0.75rem',
fontWeight: 500,
color: '#94908a',
color: '#8891C7',
textTransform: 'uppercase',
letterSpacing: '0.05em',
margin: 0,
@ -101,7 +101,7 @@ export function PricingEngine() {
}}
>
<span style={{ fontSize: '0.8rem', fontWeight: 600, color: '#374151' }}>Total</span>
<span style={{ fontSize: '0.9rem', fontWeight: 700, color: '#0a0907', fontFamily: 'monospace' }}>
<span style={{ fontSize: '0.9rem', fontWeight: 700, color: '#0a0a0c', fontFamily: 'monospace' }}>
AED {formatAED(total)}
</span>
</div>
@ -136,7 +136,7 @@ function PriceLine({ label, price }: { label: string; price: number }) {
justifyContent: 'space-between',
alignItems: 'center',
}}>
<span style={{ fontSize: '0.75rem', color: '#94908a' }}>{label}</span>
<span style={{ fontSize: '0.75rem', color: '#8891C7' }}>{label}</span>
<span style={{ fontSize: '0.75rem', color: '#374151', fontFamily: 'monospace' }}>
AED {formatAED(price)}
</span>

View File

@ -29,7 +29,7 @@ function Loader() {
borderRadius: '50%',
animation: 'spin 1s linear infinite',
}} />
<p style={{ fontSize: '0.875rem', color: '#6b6862', fontFamily: 'system-ui, sans-serif' }}>
<p style={{ fontSize: '0.875rem', color: '#6a73a5', fontFamily: 'system-ui, sans-serif' }}>
{progress.toFixed(0)}% loaded
</p>
</div>
@ -53,7 +53,7 @@ function SceneContent({ onCapture }: { onCapture: (gl: WebGLRenderer, scene: Sce
<ambientLight intensity={0.8} />
<directionalLight position={[5, 5, 5]} intensity={1.8} color="#ffffff" castShadow shadow-mapSize={[1024, 1024]} />
<directionalLight position={[-4, 3, 2]} intensity={0.8} color="#e8f0ff" />
<directionalLight position={[0, 3, -5]} intensity={0.8} color="#94908a" />
<directionalLight position={[0, 3, -5]} intensity={0.8} color="#8891C7" />
<spotLight position={[0, 8, 0]} intensity={1.0} angle={0.6} penumbra={0.5} color="#ffffff" />
<directionalLight position={[0, 2, 5]} intensity={0.7} color="#ffffff" />
<RobotModel />
@ -148,7 +148,7 @@ export function RobotCanvas() {
<button
onClick={handleSnapshot}
disabled={isCapturing}
style={{ ...btnBase, left: '1rem', backgroundColor: 'rgba(255,255,255,0.8)', border: '1px solid #e8e0cf', color: '#0a0907' }}
style={{ ...btnBase, left: '1rem', backgroundColor: 'rgba(255,255,255,0.8)', border: '1px solid #e8e0cf', color: '#0a0a0c' }}
aria-label="Capture 3D scene snapshot"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
@ -164,7 +164,7 @@ export function RobotCanvas() {
left: '8.5rem',
backgroundColor: shareStatus === 'copied' ? 'rgba(34,197,94,0.1)' : 'rgba(255,255,255,0.8)',
border: `1px solid ${shareStatus === 'copied' ? '#86efac' : '#e8e0cf'}`,
color: shareStatus === 'copied' ? '#16a34a' : '#0a0907',
color: shareStatus === 'copied' ? '#16a34a' : '#0a0a0c',
}}
aria-label="Share configuration link"
>

View File

@ -172,24 +172,24 @@ export function ScrollOverlays() {
{/* 1. Brand Intro */}
<OverlaySection progress={scrollYProgress} {...SECTION_CONFIGS[0]} className="overlay-brand">
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '1rem', marginBottom: '1rem' }}>
<div style={{ width: '30px', height: '1px', background: 'linear-gradient(90deg, transparent, #c4a265)' }} />
<span style={{ fontSize: '0.75rem', fontWeight: 600, color: '#c4a265', letterSpacing: '0.4em', textTransform: 'uppercase' }}>
<div style={{ width: '30px', height: '1px', background: 'linear-gradient(90deg, transparent, #273F94)' }} />
<span style={{ fontSize: '0.75rem', fontWeight: 600, color: '#273F94', letterSpacing: '0.4em', textTransform: 'uppercase' }}>
YS Lootah Robotics
</span>
<div style={{ width: '30px', height: '1px', background: 'linear-gradient(90deg, #c4a265, transparent)' }} />
<div style={{ width: '30px', height: '1px', background: 'linear-gradient(90deg, #273F94, transparent)' }} />
</div>
<p style={{ fontSize: '0.9rem', color: '#6b6862', fontWeight: 400, letterSpacing: '0.15em', margin: 0 }}>
<p style={{ fontSize: '0.9rem', color: '#6a73a5', fontWeight: 400, letterSpacing: '0.15em', margin: 0 }}>
Pioneering Humanoid Robotics in the UAE
</p>
</OverlaySection>
{/* 2. Hero */}
<OverlaySection progress={scrollYProgress} {...SECTION_CONFIGS[1]}>
<motion.h1 className="overlay-hero-heading" style={{ fontWeight: 200, color: '#0a0907', lineHeight: 1.0, letterSpacing: '-0.04em', margin: 0 }}>
<motion.h1 className="overlay-hero-heading" style={{ fontWeight: 200, color: '#0a0a0c', lineHeight: 1.0, letterSpacing: '-0.04em', margin: 0 }}>
The Future
</motion.h1>
<motion.h1 className="overlay-hero-heading" style={{ fontWeight: 200, color: '#0a0907', lineHeight: 1.0, letterSpacing: '-0.04em', margin: '0.1em 0 0' }}>
of <span style={{ color: '#c4a265', fontWeight: 400 }}>Robotics</span>
<motion.h1 className="overlay-hero-heading" style={{ fontWeight: 200, color: '#0a0a0c', lineHeight: 1.0, letterSpacing: '-0.04em', margin: '0.1em 0 0' }}>
of <span style={{ color: '#273F94', fontWeight: 400 }}>Robotics</span>
</motion.h1>
<p style={{ fontSize: '1rem', color: '#475569', lineHeight: 1.7, margin: '1.5rem 0 0', fontWeight: 300 }}>
Meet the G1 Humanoid Robot. Fully customizable, enterprise-ready, designed for the world of tomorrow.
@ -199,11 +199,11 @@ export function ScrollOverlays() {
{/* 3. Head Reveal */}
<OverlaySection progress={scrollYProgress} {...SECTION_CONFIGS[2]}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end' }}>
<div style={{ width: '50px', height: '2px', background: '#c4a265', marginBottom: '1.5rem' }} />
<div style={{ fontSize: '0.65rem', fontWeight: 600, color: '#c4a265', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
<div style={{ width: '50px', height: '2px', background: '#273F94', marginBottom: '1.5rem' }} />
<div style={{ fontSize: '0.65rem', fontWeight: 600, color: '#273F94', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
Intelligent by Design
</div>
<h2 className="overlay-heading" style={{ fontWeight: 300, color: '#0a0907', lineHeight: 1.1, margin: '0 0 1rem', letterSpacing: '-0.03em' }}>
<h2 className="overlay-heading" style={{ fontWeight: 300, color: '#0a0a0c', lineHeight: 1.1, margin: '0 0 1rem', letterSpacing: '-0.03em' }}>
Vision That<br />Understands
</h2>
<p style={{ fontSize: '0.95rem', color: '#475569', lineHeight: 1.6, margin: 0, fontWeight: 300 }}>
@ -211,12 +211,12 @@ export function ScrollOverlays() {
</p>
<div style={{ display: 'flex', gap: '2.5rem', marginTop: '2rem' }}>
<div style={{ textAlign: 'center' }}>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0907', fontFamily: 'monospace' }}>360°</div>
<div style={{ fontSize: '0.65rem', color: '#6b6862', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Field of View</div>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0a0c', fontFamily: 'monospace' }}>360°</div>
<div style={{ fontSize: '0.65rem', color: '#6a73a5', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Field of View</div>
</div>
<div style={{ textAlign: 'center' }}>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0907', fontFamily: 'monospace' }}>{'<'}50ms</div>
<div style={{ fontSize: '0.65rem', color: '#6b6862', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Response Time</div>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0a0c', fontFamily: 'monospace' }}>{'<'}50ms</div>
<div style={{ fontSize: '0.65rem', color: '#6a73a5', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Response Time</div>
</div>
</div>
</div>
@ -224,11 +224,11 @@ export function ScrollOverlays() {
{/* 4. Customization */}
<OverlaySection progress={scrollYProgress} {...SECTION_CONFIGS[3]}>
<div style={{ width: '50px', height: '2px', background: '#c4a265', marginBottom: '1.5rem' }} />
<div style={{ fontSize: '0.65rem', fontWeight: 600, color: '#c4a265', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
<div style={{ width: '50px', height: '2px', background: '#273F94', marginBottom: '1.5rem' }} />
<div style={{ fontSize: '0.65rem', fontWeight: 600, color: '#273F94', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
Your Identity
</div>
<h2 className="overlay-heading" style={{ fontWeight: 300, color: '#0a0907', lineHeight: 1.1, margin: '0 0 1rem', letterSpacing: '-0.03em' }}>
<h2 className="overlay-heading" style={{ fontWeight: 300, color: '#0a0a0c', lineHeight: 1.1, margin: '0 0 1rem', letterSpacing: '-0.03em' }}>
Dress for Any<br />Mission
</h2>
<p style={{ fontSize: '0.95rem', color: '#475569', lineHeight: 1.6, margin: 0, fontWeight: 300 }}>
@ -252,9 +252,9 @@ export function ScrollOverlays() {
padding: '0.6rem 1.25rem',
borderRadius: '2rem',
background: 'rgba(255, 255, 255, 0.5)',
border: '1px solid rgba(196, 162, 101, 0.3)',
border: '1px solid rgba(39, 63, 148, 0.3)',
fontSize: '0.75rem',
color: '#0a0907',
color: '#0a0a0c',
letterSpacing: '0.1em',
fontWeight: 600,
cursor: 'pointer',
@ -268,11 +268,11 @@ export function ScrollOverlays() {
e.currentTarget.style.background = 'var(--color-gold)';
e.currentTarget.style.color = '#ffffff';
e.currentTarget.style.transform = 'translateY(-2px)';
e.currentTarget.style.boxShadow = '0 6px 16px rgba(196, 162, 101, 0.3)';
e.currentTarget.style.boxShadow = '0 6px 16px rgba(39, 63, 148, 0.3)';
}}
onMouseOut={(e) => {
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.5)';
e.currentTarget.style.color = '#0a0907';
e.currentTarget.style.color = '#0a0a0c';
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,0,0,0.05)';
}}
@ -286,11 +286,11 @@ export function ScrollOverlays() {
{/* 5. Mobility */}
<OverlaySection progress={scrollYProgress} {...SECTION_CONFIGS[4]}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end' }}>
<div style={{ width: '50px', height: '2px', background: '#c4a265', marginBottom: '1.5rem' }} />
<div style={{ fontSize: '0.65rem', fontWeight: 600, color: '#c4a265', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
<div style={{ width: '50px', height: '2px', background: '#273F94', marginBottom: '1.5rem' }} />
<div style={{ fontSize: '0.65rem', fontWeight: 600, color: '#273F94', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
Advanced Mobility
</div>
<h2 className="overlay-heading" style={{ fontWeight: 300, color: '#0a0907', lineHeight: 1.1, margin: '0 0 1rem', letterSpacing: '-0.03em' }}>
<h2 className="overlay-heading" style={{ fontWeight: 300, color: '#0a0a0c', lineHeight: 1.1, margin: '0 0 1rem', letterSpacing: '-0.03em' }}>
23 Degrees of<br />Freedom
</h2>
<p style={{ fontSize: '0.95rem', color: '#475569', lineHeight: 1.6, margin: 0, fontWeight: 300 }}>
@ -298,12 +298,12 @@ export function ScrollOverlays() {
</p>
<div style={{ display: 'flex', gap: '2.5rem', marginTop: '2rem' }}>
<div style={{ textAlign: 'center' }}>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0907', fontFamily: 'monospace' }}>2m/s</div>
<div style={{ fontSize: '0.65rem', color: '#6b6862', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Max Speed</div>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0a0c', fontFamily: 'monospace' }}>2m/s</div>
<div style={{ fontSize: '0.65rem', color: '#6a73a5', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Max Speed</div>
</div>
<div style={{ textAlign: 'center' }}>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0907', fontFamily: 'monospace' }}>127kg</div>
<div style={{ fontSize: '0.65rem', color: '#6b6862', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Payload</div>
<div className="overlay-stat" style={{ fontWeight: 300, color: '#0a0a0c', fontFamily: 'monospace' }}>127kg</div>
<div style={{ fontSize: '0.65rem', color: '#6a73a5', letterSpacing: '0.15em', textTransform: 'uppercase', marginTop: '0.5rem' }}>Payload</div>
</div>
</div>
</div>
@ -325,7 +325,7 @@ export function ScrollOverlays() {
opacity: useTransform(scrollYProgress, [0, 0.05], [1, 0]),
}}
>
<span style={{ fontSize: '0.65rem', fontWeight: 500, color: '#6b6862', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
<span style={{ fontSize: '0.65rem', fontWeight: 500, color: '#6a73a5', letterSpacing: '0.3em', textTransform: 'uppercase', marginBottom: '1rem' }}>
Scroll to Explore
</span>
<div className="scroll-indicator" />

View File

@ -163,13 +163,13 @@ function LightOrbs() {
{/* Orbiting gold point light (no visible mesh) */}
<group ref={goldOrbRef}>
<pointLight ref={goldPointRef} color="#c4a265" intensity={1.8} distance={4.5} decay={2} />
<pointLight ref={goldPointRef} color="#273F94" intensity={1.8} distance={4.5} decay={2} />
</group>
{/* Halo ring above head - visible during close-up */}
<mesh ref={haloRef} position={[0, 1.6, 0]} rotation={[Math.PI / 2, 0, 0]}>
<torusGeometry args={[0.25, 0.008, 16, 64]} />
<meshBasicMaterial color="#c4a265" transparent opacity={0} />
<meshBasicMaterial color="#273F94" transparent opacity={0} />
</mesh>
</>
);
@ -220,7 +220,7 @@ function ScrollLighting() {
return (
<>
<directionalLight ref={rimLightRef} position={[0, 3, -5]} intensity={3.0} color="#4a7aff" />
<spotLight ref={goldSpotRef} position={[0.5, 2.5, 2]} intensity={0} color="#c4a265" angle={0.5} penumbra={0.8} />
<spotLight ref={goldSpotRef} position={[0.5, 2.5, 2]} intensity={0} color="#273F94" angle={0.5} penumbra={0.8} />
<directionalLight ref={leftSideRef} position={[-5, 3, 2]} intensity={0.8} color="#e8f0ff" />
<directionalLight ref={rightSideRef} position={[5, 2, 3]} intensity={0.8} color="#e0e8ff" />
<directionalLight ref={fillRef} position={[0, 2, 5]} intensity={0.8} color="#ffffff" />
@ -236,12 +236,12 @@ function Loader() {
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '0.75rem' }}>
<div style={{
width: '48px', height: '48px',
border: '3px solid rgba(196, 162, 101, 0.15)',
borderTopColor: '#c4a265',
border: '3px solid rgba(39, 63, 148, 0.15)',
borderTopColor: '#273F94',
borderRadius: '50%',
animation: 'spin 1s linear infinite',
}} />
<p style={{ fontSize: '0.8rem', color: '#6b6862', fontFamily: 'Inter, system-ui, sans-serif' }}>
<p style={{ fontSize: '0.8rem', color: '#6a73a5', fontFamily: 'Inter, system-ui, sans-serif' }}>
{progress.toFixed(0)}%
</p>
</div>

View File

@ -47,7 +47,7 @@ function SnapshotButtonInner({ gl, scene, camera, filename = 'g1-robot', onSnaps
backgroundColor: 'rgba(59, 130, 246, 0.1)',
border: '1px solid rgba(59, 130, 246, 0.3)',
borderRadius: '0.5rem',
color: '#f5f1e8',
color: '#FBFBFD',
cursor: isCapturing ? 'wait' : 'pointer',
fontSize: '0.875rem',
fontWeight: 500,

View File

@ -39,10 +39,10 @@ export function ConfirmationStep() {
</div>
<div>
<h3 style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0907', margin: 0, marginBottom: '0.5rem' }}>
<h3 style={{ fontSize: '1.25rem', fontWeight: 700, color: '#0a0a0c', margin: 0, marginBottom: '0.5rem' }}>
Order Confirmed!
</h3>
<p style={{ fontSize: '0.8rem', color: '#94908a', margin: 0 }}>
<p style={{ fontSize: '0.8rem', color: '#8891C7', margin: 0 }}>
Thank you for your order. Your G1 Robot is being prepared.
</p>
</div>
@ -54,7 +54,7 @@ export function ConfirmationStep() {
background: 'rgba(59, 130, 246, 0.04)',
border: '1px solid rgba(59, 130, 246, 0.2)',
}}>
<div style={{ fontSize: '0.65rem', color: '#6b6862', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: '0.25rem' }}>
<div style={{ fontSize: '0.65rem', color: '#6a73a5', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: '0.25rem' }}>
Order ID
</div>
<div style={{ fontSize: '1.1rem', fontWeight: 700, color: '#2563eb', fontFamily: 'monospace', letterSpacing: '0.05em' }}>
@ -72,16 +72,16 @@ export function ConfirmationStep() {
textAlign: 'left',
}}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
<span style={{ fontSize: '0.75rem', color: '#94908a' }}>Configuration</span>
<span style={{ fontSize: '0.75rem', color: '#8891C7' }}>Configuration</span>
<span style={{ fontSize: '0.75rem', color: '#374151' }}>{personaSummary}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
<span style={{ fontSize: '0.75rem', color: '#94908a' }}>Ship to</span>
<span style={{ fontSize: '0.75rem', color: '#8891C7' }}>Ship to</span>
<span style={{ fontSize: '0.75rem', color: '#374151' }}>{shipping.name}, {shipping.city}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', paddingTop: '0.5rem', borderTop: '1px solid rgba(0, 0, 0, 0.06)' }}>
<span style={{ fontSize: '0.85rem', fontWeight: 600, color: '#374151' }}>Total Paid</span>
<span style={{ fontSize: '0.85rem', fontWeight: 700, color: '#0a0907', fontFamily: 'monospace' }}>AED {formatAED(orderTotal)}</span>
<span style={{ fontSize: '0.85rem', fontWeight: 700, color: '#0a0a0c', fontFamily: 'monospace' }}>AED {formatAED(orderTotal)}</span>
</div>
</div>

View File

@ -32,7 +32,7 @@ export function PaymentStep() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<h3 style={{ fontSize: '1rem', fontWeight: 600, color: '#0a0907', margin: 0 }}>
<h3 style={{ fontSize: '1rem', fontWeight: 600, color: '#0a0a0c', margin: 0 }}>
Payment Details
</h3>

View File

@ -97,7 +97,7 @@ export function ReviewStep() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
<h3 style={{ fontSize: '1rem', fontWeight: 600, color: '#0a0907', margin: 0 }}>
<h3 style={{ fontSize: '1rem', fontWeight: 600, color: '#0a0a0c', margin: 0 }}>
Review Your Order
</h3>
@ -124,8 +124,8 @@ export function ReviewStep() {
<div style={{ fontWeight: 500 }}>{shipping.name}</div>
<div>{shipping.address}</div>
<div>{shipping.city}, {shipping.country} {shipping.postalCode}</div>
<div style={{ color: '#94908a', marginTop: '0.25rem' }}>{shipping.email}</div>
<div style={{ color: '#94908a' }}>{shipping.phone}</div>
<div style={{ color: '#8891C7', marginTop: '0.25rem' }}>{shipping.email}</div>
<div style={{ color: '#8891C7' }}>{shipping.phone}</div>
</div>
</SummarySection>
@ -137,7 +137,7 @@ export function ReviewStep() {
alignItems: 'center',
}}>
<span style={{ fontSize: '0.85rem', fontWeight: 600, color: '#374151' }}>Total</span>
<span style={{ fontSize: '1.1rem', fontWeight: 700, color: '#0a0907', fontFamily: 'monospace' }}>
<span style={{ fontSize: '1.1rem', fontWeight: 700, color: '#0a0a0c', fontFamily: 'monospace' }}>
AED {formatAED(orderTotal)}
</span>
</div>
@ -195,7 +195,7 @@ function SummarySection({ title, children }: { title: string; children: React.Re
<div style={{
fontSize: '0.65rem',
fontWeight: 600,
color: '#6b6862',
color: '#6a73a5',
textTransform: 'uppercase',
letterSpacing: '0.05em',
marginBottom: '0.5rem',
@ -215,7 +215,7 @@ function SummaryRow({ label, value }: { label: string; value: React.ReactNode })
alignItems: 'center',
padding: '0.25rem 0',
}}>
<span style={{ fontSize: '0.8rem', color: '#94908a' }}>{label}</span>
<span style={{ fontSize: '0.8rem', color: '#8891C7' }}>{label}</span>
<span style={{ fontSize: '0.8rem', color: '#374151' }}>{value}</span>
</div>
);

View File

@ -9,7 +9,7 @@ const inputStyle: React.CSSProperties = {
borderRadius: '0.375rem',
border: '1px solid rgba(0, 0, 0, 0.08)',
background: 'rgba(255, 255, 255, 0.8)',
color: '#0a0907',
color: '#0a0a0c',
fontSize: '0.8rem',
outline: 'none',
transition: 'border-color 0.2s ease',
@ -18,7 +18,7 @@ const inputStyle: React.CSSProperties = {
const labelStyle: React.CSSProperties = {
fontSize: '0.7rem',
fontWeight: 500,
color: '#94908a',
color: '#8891C7',
marginBottom: '0.3rem',
display: 'block',
};
@ -80,7 +80,7 @@ export function ShippingStep() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<h3 style={{ fontSize: '1rem', fontWeight: 600, color: '#0a0907', margin: 0 }}>
<h3 style={{ fontSize: '1rem', fontWeight: 600, color: '#0a0a0c', margin: 0 }}>
Shipping Information
</h3>

View File

@ -21,7 +21,7 @@ export function BentoGrid() {
gridAutoRows: 'minmax(180px, auto)',
}}
>
<Tile col="span 7" row="span 2" accent="#e0c896">
<Tile col="span 7" row="span 2" accent="#DEE0F0">
<div style={{ position: 'absolute', inset: 0 }}>
<Image
src={FEATURED_ROBOTS[0].image}
@ -36,7 +36,7 @@ export function BentoGrid() {
<h3 style={{ margin: 0, fontSize: 'clamp(1.4rem, 2.6vw, 2rem)', fontWeight: 500, letterSpacing: '-0.02em', lineHeight: 1.1 }}>
<span className="text-gradient">Unitree G1 humanoid live in our Dubai showroom.</span>
</h3>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: '0.92rem', lineHeight: 1.6 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: '0.92rem', lineHeight: 1.6 }}>
Configure persona, attire, and accessories. Then book a live demo.
</p>
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', marginTop: '0.5rem' }}>
@ -46,41 +46,41 @@ export function BentoGrid() {
</div>
</Tile>
<Tile col="span 5" row="span 1" accent="#c4a265" icon={SOC_PATHS.bolt}>
<Tile col="span 5" row="span 1" accent="#273F94" icon={SOC_PATHS.bolt}>
<span className="eyebrow">Sales & demos</span>
<h3 style={{ margin: 0, fontSize: 'clamp(1.2rem, 2vw, 1.5rem)', fontWeight: 500, letterSpacing: '-0.02em', lineHeight: 1.15 }}>
<span className="text-gradient">Fast quotes for UAE businesses.</span>
</h3>
<p style={{ margin: 0, color: '#94908a', fontSize: '0.88rem', lineHeight: 1.55 }}>
<p style={{ margin: 0, color: '#8891C7', fontSize: '0.88rem', lineHeight: 1.55 }}>
Tell us your use case we respond within one business day with availability and pricing.
</p>
</Tile>
<Tile col="span 5" row="span 1" accent="#8b6f47" icon={SOC_PATHS.shield}>
<Tile col="span 5" row="span 1" accent="#8891C7" icon={SOC_PATHS.shield}>
<span className="eyebrow">End-to-end</span>
<h3 style={{ margin: 0, fontSize: 'clamp(1.2rem, 2vw, 1.5rem)', fontWeight: 500, letterSpacing: '-0.02em', lineHeight: 1.15 }}>
<span className="text-gradient">Procurement, deployment, support.</span>
</h3>
<p style={{ margin: 0, color: '#94908a', fontSize: '0.88rem', lineHeight: 1.55 }}>
<p style={{ margin: 0, color: '#8891C7', fontSize: '0.88rem', lineHeight: 1.55 }}>
Local team handles import, setup, training, and ongoing service across the UAE.
</p>
</Tile>
<Tile col="span 4" row="span 1" accent="#e0c896" icon={SOC_PATHS.brain}>
<Tile col="span 4" row="span 1" accent="#DEE0F0" icon={SOC_PATHS.brain}>
<span className="eyebrow">Exclusive UAE access</span>
<h3 style={{ margin: 0, fontSize: 'clamp(1.05rem, 1.8vw, 1.3rem)', fontWeight: 500, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
<span className="text-gradient">Unitree · Pudu one Dubai team.</span>
</h3>
</Tile>
<Tile col="span 4" row="span 1" accent="#c4a265" icon={SOC_PATHS.globe}>
<Tile col="span 4" row="span 1" accent="#273F94" icon={SOC_PATHS.globe}>
<span className="eyebrow">10+ industries</span>
<h3 style={{ margin: 0, fontSize: 'clamp(1.05rem, 1.8vw, 1.3rem)', fontWeight: 500, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
<span className="text-gradient">Hospitality, security, healthcare, retail.</span>
</h3>
</Tile>
<Tile col="span 4" row="span 1" accent="#8b6f47">
<Tile col="span 4" row="span 1" accent="#8891C7">
<span className="eyebrow">Configurator</span>
<h3 style={{ margin: 0, fontSize: 'clamp(1.05rem, 1.8vw, 1.3rem)', fontWeight: 500, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
<span className="text-gradient">3D persona builder for the G1.</span>
@ -92,7 +92,7 @@ export function BentoGrid() {
display: 'inline-flex',
alignItems: 'center',
gap: '0.4rem',
color: '#8b6f47',
color: '#8891C7',
fontSize: '0.78rem',
letterSpacing: '0.18em',
textTransform: 'uppercase',

View File

@ -24,7 +24,7 @@ export function BrandShowcase() {
style={{
padding: '1.75rem',
textDecoration: 'none',
color: '#f5f1e8',
color: '#FBFBFD',
display: 'flex',
flexDirection: 'column',
gap: '1rem',
@ -65,7 +65,7 @@ export function BrandShowcase() {
{count} model{count === 1 ? '' : 's'}
</span>
</div>
<p style={{ position: 'relative', margin: 0, color: '#94908a', lineHeight: 1.6, fontSize: '0.95rem' }}>
<p style={{ position: 'relative', margin: 0, color: '#8891C7', lineHeight: 1.6, fontSize: '0.95rem' }}>
{brand.tagline}
</p>
<div

View File

@ -0,0 +1,169 @@
'use client';
import Image from 'next/image';
export function BuSunaidahSection() {
return (
<div
style={{
position: 'relative',
borderRadius: '2rem',
padding: 'clamp(2rem, 5vw, 3.5rem)',
overflow: 'hidden',
background:
'radial-gradient(ellipse 60% 80% at 0% 100%, rgba(39, 63, 148,0.18), transparent 65%), radial-gradient(ellipse 70% 60% at 100% 0%, rgba(222, 224, 240,0.12), transparent 60%), linear-gradient(135deg, rgba(28, 27, 33,0.95), rgba(5,5,5,0.98))',
border: '1px solid rgba(39, 63, 148,0.32)',
boxShadow: '0 30px 100px rgba(0,0,0,0.7), inset 0 1px 0 rgba(222, 224, 240,0.05)',
}}
>
<div
aria-hidden
style={{
position: 'absolute',
inset: 0,
background:
'linear-gradient(rgba(39, 63, 148,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(39, 63, 148,0.05) 1px, transparent 1px)',
backgroundSize: '48px 48px',
maskImage: 'radial-gradient(ellipse 60% 80% at 50% 50%, #000 30%, transparent 80%)',
WebkitMaskImage: 'radial-gradient(ellipse 60% 80% at 50% 50%, #000 30%, transparent 80%)',
pointerEvents: 'none',
}}
/>
<div style={{ position: 'relative', display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(280px, 100%), 1fr))', gap: 'clamp(2rem, 5vw, 3.5rem)', alignItems: 'center' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
<span className="eyebrow" style={{ color: '#DEE0F0' }}>
Brand · Culture · Storytelling
</span>
<h2 style={{ margin: 0, fontSize: 'clamp(1.8rem, 4.4vw, 2.8rem)', lineHeight: 1.1, fontWeight: 300, letterSpacing: '-0.03em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>
Meet Bu Sunaidah.
</span>
</h2>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7, fontSize: '1rem' }}>
An Emirati culture-inspired robotics character Bu Sunaidah is YS Lootah Robotics&apos; community and storytelling ambassador. Designed to celebrate UAE heritage at media events, exhibitions, and innovation programs, Bu Sunaidah shows what intelligent automation looks like when it speaks the language of the region.
</p>
<ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '0.6rem' }}>
{[
'Emirati-inspired robotics persona',
'Media presence and event activations across the UAE',
'Community engagement and innovation storytelling',
'A modern face for advanced robotics in our region',
].map((b) => (
<li key={b} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.625rem', color: '#FBFBFD', fontSize: '0.95rem', lineHeight: 1.55 }}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#DEE0F0" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" style={{ flex: 'none', marginTop: 4 }} aria-hidden="true">
<path d="M20 6 9 17l-5-5" />
</svg>
{b}
</li>
))}
</ul>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.625rem', marginTop: '0.5rem' }}>
<a
className="btn btn-ghost"
href="https://www.instagram.com/bu.sunaidah"
target="_blank"
rel="noopener noreferrer"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" />
</svg>
Follow @bu.sunaidah
</a>
<a className="btn btn-outline" href="/contact/">
Book Bu Sunaidah for events
</a>
</div>
</div>
<div
style={{
position: 'relative',
aspectRatio: '1 / 1',
maxWidth: 460,
margin: '0 auto',
width: '100%',
}}
>
<div
aria-hidden
style={{
position: 'absolute',
inset: '-2rem',
background:
'radial-gradient(ellipse 60% 60% at 50% 60%, rgba(222, 224, 240,0.32), transparent 65%)',
filter: 'blur(28px)',
pointerEvents: 'none',
}}
/>
<div
style={{
position: 'relative',
width: '100%',
height: '100%',
borderRadius: '1.75rem',
overflow: 'hidden',
border: '1px solid rgba(39, 63, 148,0.35)',
background:
'radial-gradient(ellipse 70% 60% at 50% 55%, rgba(222, 224, 240,0.18), transparent 60%), linear-gradient(180deg, rgba(28, 27, 33,0.85), rgba(5,5,5,0.95))',
boxShadow: '0 30px 100px rgba(0,0,0,0.7)',
}}
>
<Image
src="/images/robots/unitree-g1.png"
alt="Bu Sunaidah — Emirati-inspired robotics character based on a Unitree G1 humanoid"
fill
sizes="(max-width: 768px) 90vw, 460px"
style={{ objectFit: 'contain', padding: 'clamp(1.5rem, 4vw, 3rem)' }}
/>
<div
style={{
position: 'absolute',
bottom: '1rem',
left: '1rem',
right: '1rem',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: '0.75rem',
}}
>
<span
style={{
padding: '0.4rem 0.75rem',
borderRadius: 999,
background: 'rgba(14, 13, 18,0.7)',
border: '1px solid rgba(39, 63, 148,0.35)',
color: '#DEE0F0',
fontSize: '0.66rem',
letterSpacing: '0.22em',
textTransform: 'uppercase',
fontWeight: 600,
backdropFilter: 'blur(8px)',
}}
>
Emirati-inspired persona
</span>
<span
style={{
padding: '0.35rem 0.65rem',
borderRadius: 999,
background: 'rgba(222, 224, 240,0.18)',
border: '1px solid rgba(222, 224, 240,0.4)',
color: '#FBFBFD',
fontSize: '0.7rem',
letterSpacing: '0.16em',
textTransform: 'uppercase',
fontWeight: 700,
}}
>
Bu Sunaidah
</span>
</div>
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,61 @@
'use client';
const PILLARS = [
{ title: 'Artificial intelligence', body: 'AI applications tailored for UAE government and private sector clients.' },
{ title: 'Robotics', body: 'Humanoid, quadruped, service, and delivery robotics deployed across Dubai and the UAE.' },
{ title: 'Digital transformation', body: 'Automation systems and smart projects that modernize operations end to end.' },
{ title: 'Training & enablement', body: 'Coding and robotics training programs that prepare the next generation of talent.' },
];
export function CompanyStory() {
return (
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(min(280px, 100%), 1fr))',
gap: 'clamp(2rem, 5vw, 3rem)',
alignItems: 'flex-start',
}}
>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<span className="eyebrow">About YS Lootah Robotics</span>
<h2 style={{ margin: 0, fontSize: 'clamp(1.8rem, 4.4vw, 2.8rem)', fontWeight: 300, lineHeight: 1.1, letterSpacing: '-0.03em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>
A trusted UAE technology and robotics partner.
</span>
</h2>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7, fontSize: '1rem' }}>
YS Lootah Robotics is part of the <strong style={{ color: '#DEE0F0' }}>Yousuf Saeed Lootah Investment Group</strong>. We help organizations innovate, automate, and deploy intelligent robotic solutions across artificial intelligence, robotics, digital transformation, automation systems, and smart projects for government and private sector clients alike.
</p>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7, fontSize: '1rem' }}>
Beyond hardware, we also run coding and robotics training programs that prepare the UAE&apos;s next generation of talent for an automated future.
</p>
<p style={{ margin: 0, color: '#8891C7', fontSize: '0.82rem', letterSpacing: '0.18em', textTransform: 'uppercase', fontWeight: 600 }}>
In Tech We Innovate · In Trust We Lead
</p>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(180px, 100%), 1fr))', gap: '1rem' }}>
{PILLARS.map((p, i) => (
<div
key={p.title}
className="card"
style={{
padding: '1.5rem',
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
minHeight: 160,
}}
>
<span style={{ fontSize: '0.7rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8891C7', fontWeight: 700 }}>
0{i + 1}
</span>
<h3 style={{ margin: 0, fontSize: '1.05rem', fontWeight: 600, color: '#FBFBFD' }}>{p.title}</h3>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.55, fontSize: '0.88rem' }}>{p.body}</p>
</div>
))}
</div>
</div>
);
}

View File

@ -26,8 +26,8 @@ export function ConfigureCTA({
padding: 'clamp(1.75rem, 4vw, 2.75rem)',
borderRadius: '1.5rem',
background:
'radial-gradient(ellipse 80% 80% at 100% 0%, rgba(196, 162, 101,0.16), transparent 60%), linear-gradient(135deg, rgba(15, 12, 8,0.85), rgba(5, 5, 5,0.95))',
border: '1px solid rgba(196, 162, 101,0.28)',
'radial-gradient(ellipse 80% 80% at 100% 0%, rgba(39, 63, 148,0.16), transparent 60%), linear-gradient(135deg, rgba(15, 12, 8,0.85), rgba(5, 5, 5,0.95))',
border: '1px solid rgba(39, 63, 148,0.28)',
overflow: 'hidden',
boxShadow: '0 20px 80px rgba(0, 0, 0,0.55)',
}}
@ -38,7 +38,7 @@ export function ConfigureCTA({
position: 'absolute',
inset: 0,
background:
'linear-gradient(rgba(196, 162, 101,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(196, 162, 101,0.05) 1px, transparent 1px)',
'linear-gradient(rgba(39, 63, 148,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(39, 63, 148,0.05) 1px, transparent 1px)',
backgroundSize: '40px 40px',
maskImage: 'radial-gradient(ellipse 60% 80% at 80% 30%, #000 30%, transparent 80%)',
WebkitMaskImage: 'radial-gradient(ellipse 60% 80% at 80% 30%, #000 30%, transparent 80%)',
@ -50,7 +50,7 @@ export function ConfigureCTA({
<h3 style={{ margin: 0, fontSize: 'clamp(1.4rem, 3vw, 2rem)', lineHeight: 1.15, fontWeight: 400, letterSpacing: '-0.02em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>{title}</span>
</h3>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: '0.95rem', lineHeight: 1.65 }}>{description}</p>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: '0.95rem', lineHeight: 1.65 }}>{description}</p>
</div>
<div style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '0.75rem', flexWrap: 'wrap' }}>
<Link href={href} className="btn btn-primary">

View File

@ -27,8 +27,8 @@ export function DemoCTA({
padding: 'clamp(2rem, 5vw, 4rem)',
overflow: 'hidden',
background:
'radial-gradient(ellipse 60% 80% at 20% 20%, rgba(196, 162, 101,0.18), transparent 60%), radial-gradient(ellipse 70% 80% at 80% 100%, rgba(139, 111, 71,0.18), transparent 60%), linear-gradient(135deg, rgba(15, 12, 8,0.9), rgba(5, 5, 5,0.95))',
border: '1px solid rgba(196, 162, 101,0.18)',
'radial-gradient(ellipse 60% 80% at 20% 20%, rgba(39, 63, 148,0.18), transparent 60%), radial-gradient(ellipse 70% 80% at 80% 100%, rgba(136, 145, 199,0.18), transparent 60%), linear-gradient(135deg, rgba(15, 12, 8,0.9), rgba(5, 5, 5,0.95))',
border: '1px solid rgba(39, 63, 148,0.18)',
boxShadow: '0 30px 100px rgba(0, 0, 0,0.6), inset 0 1px 0 rgba(255,255,255,0.04)',
}}
>
@ -37,7 +37,7 @@ export function DemoCTA({
position: 'absolute',
inset: 0,
background:
'linear-gradient(rgba(196, 162, 101,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(196, 162, 101,0.05) 1px, transparent 1px)',
'linear-gradient(rgba(39, 63, 148,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(39, 63, 148,0.05) 1px, transparent 1px)',
backgroundSize: '48px 48px',
maskImage: 'radial-gradient(ellipse 60% 80% at 50% 30%, #000 30%, transparent 80%)',
WebkitMaskImage: 'radial-gradient(ellipse 60% 80% at 50% 30%, #000 30%, transparent 80%)',
@ -58,7 +58,7 @@ export function DemoCTA({
>
<span className="text-gradient" style={{ fontWeight: 500 }}>{title}</span>
</h2>
<p style={{ margin: 0, color: '#cbc4b3', maxWidth: 620, lineHeight: 1.7, fontSize: 'clamp(0.95rem, 2vw, 1.05rem)' }}>
<p style={{ margin: 0, color: '#DEE0F0', maxWidth: 620, lineHeight: 1.7, fontSize: 'clamp(0.95rem, 2vw, 1.05rem)' }}>
{description}
</p>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.75rem', justifyContent: 'center', marginTop: '0.5rem' }}>

View File

@ -12,9 +12,9 @@ export function ExclusiveAccessSection() {
padding: 'clamp(2rem, 5vw, 4rem)',
overflow: 'hidden',
background:
'radial-gradient(ellipse 60% 80% at 0% 0%, rgba(224,200,150,0.18), transparent 60%), radial-gradient(ellipse 70% 80% at 100% 100%, rgba(139,111,71,0.22), transparent 60%), linear-gradient(135deg, rgba(20,17,11,0.92), rgba(5,5,5,0.97))',
border: '1px solid rgba(196,162,101,0.32)',
boxShadow: '0 30px 100px rgba(0,0,0,0.7), inset 0 1px 0 rgba(255,240,200,0.06)',
'radial-gradient(ellipse 60% 80% at 0% 0%, rgba(222, 224, 240,0.18), transparent 60%), radial-gradient(ellipse 70% 80% at 100% 100%, rgba(136, 145, 199,0.22), transparent 60%), linear-gradient(135deg, rgba(28, 27, 33,0.92), rgba(5,5,5,0.97))',
border: '1px solid rgba(39, 63, 148,0.32)',
boxShadow: '0 30px 100px rgba(0,0,0,0.7), inset 0 1px 0 rgba(222, 224, 240,0.06)',
}}
>
<div
@ -23,7 +23,7 @@ export function ExclusiveAccessSection() {
position: 'absolute',
inset: 0,
background:
'linear-gradient(rgba(196,162,101,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(196,162,101,0.05) 1px, transparent 1px)',
'linear-gradient(rgba(39, 63, 148,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(39, 63, 148,0.05) 1px, transparent 1px)',
backgroundSize: '48px 48px',
maskImage: 'radial-gradient(ellipse 60% 80% at 50% 30%, #000 30%, transparent 80%)',
WebkitMaskImage: 'radial-gradient(ellipse 60% 80% at 50% 30%, #000 30%, transparent 80%)',
@ -41,16 +41,16 @@ export function ExclusiveAccessSection() {
gap: '0.6rem',
padding: '0.5rem 0.9rem',
borderRadius: 999,
border: '1px solid rgba(196,162,101,0.4)',
background: 'rgba(196,162,101,0.08)',
color: '#e0c896',
border: '1px solid rgba(39, 63, 148,0.4)',
background: 'rgba(39, 63, 148,0.08)',
color: '#DEE0F0',
fontSize: '0.7rem',
letterSpacing: '0.24em',
textTransform: 'uppercase',
fontWeight: 700,
}}
>
<span aria-hidden style={{ width: 6, height: 6, borderRadius: 999, background: '#e0c896', boxShadow: '0 0 10px rgba(224,200,150,0.8)' }} />
<span aria-hidden style={{ width: 6, height: 6, borderRadius: 999, background: '#DEE0F0', boxShadow: '0 0 10px rgba(222, 224, 240,0.8)' }} />
Exclusive UAE Access
</span>
@ -60,7 +60,7 @@ export function ExclusiveAccessSection() {
</span>
</h2>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
YS Lootah Robotics holds exclusive sales rights in the UAE for selected Unitree and Pudu Robotics solutions. We deliver advanced robots to businesses, venues, and innovators across Dubai and the UAE from inquiry to live deployment.
</p>
@ -71,8 +71,8 @@ export function ExclusiveAccessSection() {
'Curated portfolio across humanoid, quadruped, service, and delivery robots.',
'End-to-end procurement, training, and ongoing support.',
].map((b) => (
<li key={b} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.65rem', color: '#f5f1e8', fontSize: '0.95rem', lineHeight: 1.55 }}>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#e0c896" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" style={{ flex: 'none', marginTop: 3 }} aria-hidden="true">
<li key={b} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.65rem', color: '#FBFBFD', fontSize: '0.95rem', lineHeight: 1.55 }}>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#DEE0F0" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" style={{ flex: 'none', marginTop: 3 }} aria-hidden="true">
<path d="M20 6 9 17l-5-5" />
</svg>
{b}
@ -87,8 +87,8 @@ export function ExclusiveAccessSection() {
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '1rem' }}>
<BrandTile name="Unitree" sub="Quadruped · Humanoid" href="/brands/#unitree" accent="#e0c896" />
<BrandTile name="Pudu Robotics" sub="Service · Delivery · Cleaning" href="/brands/#pudu" accent="#8b6f47" />
<BrandTile name="Unitree" sub="Quadruped · Humanoid" href="/brands/#unitree" accent="#DEE0F0" />
<BrandTile name="Pudu Robotics" sub="Service · Delivery · Cleaning" href="/brands/#pudu" accent="#8891C7" />
<Stat value="UAE" label="Exclusive sales territory" />
<Stat value="Dubai" label="Showroom & demo" />
</div>
@ -108,9 +108,9 @@ function BrandTile({ name, sub, href, accent }: { name: string; sub: string; hre
gap: '0.6rem',
padding: '1.25rem',
borderRadius: 16,
background: `linear-gradient(135deg, rgba(20,17,11,0.85), rgba(5,5,5,0.95))`,
background: `linear-gradient(135deg, rgba(28, 27, 33,0.85), rgba(5,5,5,0.95))`,
border: `1px solid ${accent}44`,
color: '#f5f1e8',
color: '#FBFBFD',
textDecoration: 'none',
position: 'relative',
overflow: 'hidden',
@ -131,7 +131,7 @@ function BrandTile({ name, sub, href, accent }: { name: string; sub: string; hre
}}
/>
<span style={{ fontSize: '1.05rem', fontWeight: 600, letterSpacing: '-0.01em' }}>{name}</span>
<span style={{ fontSize: '0.72rem', color: '#94908a', letterSpacing: '0.18em', textTransform: 'uppercase' }}>{sub}</span>
<span style={{ fontSize: '0.72rem', color: '#8891C7', letterSpacing: '0.18em', textTransform: 'uppercase' }}>{sub}</span>
<span style={{ fontSize: '0.68rem', color: accent, letterSpacing: '0.22em', textTransform: 'uppercase', fontWeight: 700, marginTop: 'auto' }}>
Available in UAE
</span>
@ -145,8 +145,8 @@ function Stat({ value, label }: { value: string; label: string }) {
style={{
padding: '1.25rem',
borderRadius: 16,
background: 'linear-gradient(135deg, rgba(20,17,11,0.7), rgba(5,5,5,0.92))',
border: '1px solid rgba(196,162,101,0.22)',
background: 'linear-gradient(135deg, rgba(28, 27, 33,0.7), rgba(5,5,5,0.92))',
border: '1px solid rgba(39, 63, 148,0.22)',
display: 'flex',
flexDirection: 'column',
gap: '0.4rem',
@ -157,7 +157,7 @@ function Stat({ value, label }: { value: string; label: string }) {
<span className="text-gradient-accent" style={{ fontSize: 'clamp(1.5rem, 2.6vw, 1.9rem)', fontWeight: 700, letterSpacing: '-0.02em' }}>
{value}
</span>
<span style={{ fontSize: '0.7rem', color: '#94908a', letterSpacing: '0.22em', textTransform: 'uppercase' }}>{label}</span>
<span style={{ fontSize: '0.7rem', color: '#8891C7', letterSpacing: '0.22em', textTransform: 'uppercase' }}>{label}</span>
</div>
);
}

View File

@ -40,15 +40,15 @@ export function FloatingTechPanel() {
width: 60,
height: 60,
borderRadius: '50%',
background: `radial-gradient(circle, ${['#e0c896', '#c4a265', '#8b6f47', '#e0c896'][i % 4]}33, transparent 70%)`,
background: `radial-gradient(circle, ${['#DEE0F0', '#273F94', '#8891C7', '#DEE0F0'][i % 4]}33, transparent 70%)`,
pointerEvents: 'none',
}}
/>
<span style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#94908a' }}>{s.label}</span>
<span style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8891C7' }}>{s.label}</span>
<span className="text-gradient-accent" style={{ fontSize: 'clamp(1.7rem, 3vw, 2.2rem)', fontWeight: 700, letterSpacing: '-0.02em' }}>
{s.value}
</span>
{s.sub && <span style={{ color: '#cbc4b3', fontSize: '0.82rem', lineHeight: 1.5 }}>{s.sub}</span>}
{s.sub && <span style={{ color: '#DEE0F0', fontSize: '0.82rem', lineHeight: 1.5 }}>{s.sub}</span>}
</div>
))}
</div>

View File

@ -0,0 +1,88 @@
'use client';
export function FounderSection() {
return (
<div
style={{
position: 'relative',
borderRadius: '2rem',
padding: 'clamp(2rem, 5vw, 3.5rem)',
overflow: 'hidden',
background:
'radial-gradient(ellipse 50% 70% at 100% 0%, rgba(222, 224, 240,0.15), transparent 60%), linear-gradient(135deg, rgba(28, 27, 33,0.95), rgba(5,5,5,0.98))',
border: '1px solid rgba(39, 63, 148,0.28)',
boxShadow: '0 30px 100px rgba(0,0,0,0.7)',
}}
>
<div
aria-hidden
style={{
position: 'absolute',
inset: 0,
background:
'linear-gradient(rgba(39, 63, 148,0.04) 1px, transparent 1px), linear-gradient(90deg, rgba(39, 63, 148,0.04) 1px, transparent 1px)',
backgroundSize: '48px 48px',
maskImage: 'radial-gradient(ellipse 70% 80% at 50% 30%, #000 30%, transparent 80%)',
WebkitMaskImage: 'radial-gradient(ellipse 70% 80% at 50% 30%, #000 30%, transparent 80%)',
pointerEvents: 'none',
}}
/>
<div style={{ position: 'relative', display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(280px, 100%), 1fr))', gap: 'clamp(2rem, 4vw, 3rem)', alignItems: 'center' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<span className="eyebrow">Leadership · YS Lootah Group</span>
<h2 style={{ margin: 0, fontSize: 'clamp(1.6rem, 3.8vw, 2.4rem)', fontWeight: 400, letterSpacing: '-0.02em', lineHeight: 1.1 }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>
Mr. Yousif Bin Saeed Al Lootah
</span>
</h2>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: '0.85rem', letterSpacing: '0.12em', textTransform: 'uppercase', fontWeight: 600 }}>
Founder · Yousuf Saeed Lootah Investment Group
</p>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.7, fontSize: '1rem' }}>
Under the leadership of Mr. Yousif Bin Saeed Al Lootah, the group has championed innovation, trust, and long-term value creation across the UAE from technology and robotics to investment and enterprise. YS Lootah Robotics carries that vision into the future of intelligent automation.
</p>
<p style={{ margin: 0, color: '#8891C7', lineHeight: 1.7, fontSize: '0.92rem' }}>
<em>Innovating today for a smarter tomorrow.</em>
</p>
</div>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
gap: '1rem',
}}
>
<Pillar value="Group" label="Yousuf Saeed Lootah Investment Group" />
<Pillar value="AI" label="Artificial intelligence & automation" />
<Pillar value="UAE" label="Trusted technology partner" />
<Pillar value="Future" label="Smart, autonomous, intelligent" />
</div>
</div>
</div>
);
}
function Pillar({ value, label }: { value: string; label: string }) {
return (
<div
style={{
padding: '1.25rem',
borderRadius: 14,
background: 'linear-gradient(135deg, rgba(28, 27, 33,0.7), rgba(5,5,5,0.92))',
border: '1px solid rgba(39, 63, 148,0.22)',
display: 'flex',
flexDirection: 'column',
gap: '0.4rem',
minHeight: 110,
justifyContent: 'center',
}}
>
<span className="text-gradient-accent" style={{ fontSize: 'clamp(1.2rem, 2.2vw, 1.5rem)', fontWeight: 700, letterSpacing: '-0.01em' }}>
{value}
</span>
<span style={{ fontSize: '0.72rem', color: '#8891C7', letterSpacing: '0.14em', textTransform: 'uppercase', lineHeight: 1.45 }}>{label}</span>
</div>
);
}

View File

@ -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',
}}

View File

@ -5,19 +5,19 @@ const STEPS = [
n: '01',
title: 'Discover',
body: 'Tell us about your venue and use case. We recommend a brand and model — humanoid, quadruped, service, delivery, cleaning, or commercial.',
accent: '#e0c896',
accent: '#DEE0F0',
},
{
n: '02',
title: 'Demo & configure',
body: 'Book a live demo at our Dubai showroom or your venue. Configure your robots persona, attire, and accessories in our 3D configurator.',
accent: '#c4a265',
accent: '#273F94',
},
{
n: '03',
title: 'Deploy & support',
body: 'We handle procurement, setup, training, and ongoing service across the UAE — so your team can run, not maintain.',
accent: '#8b6f47',
accent: '#8891C7',
},
];
@ -78,7 +78,7 @@ export function HowItWorks() {
Step {i + 1}
</div>
<h3 style={{ margin: 0, fontSize: '1.35rem', fontWeight: 600, letterSpacing: '-0.01em' }}>{s.title}</h3>
<p style={{ margin: 0, color: '#cbc4b3', lineHeight: 1.65, fontSize: '0.95rem' }}>{s.body}</p>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.65, fontSize: '0.95rem' }}>{s.body}</p>
</div>
))}
</div>

View File

@ -54,11 +54,11 @@ export function IndustryUseCases({ limit }: { limit?: number }) {
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
<div>
<div style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#6b6862', marginBottom: 4 }}>Problem</div>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: '0.92rem', lineHeight: 1.55 }}>{i.problem}</p>
<div style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#6a73a5', marginBottom: 4 }}>Problem</div>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: '0.92rem', lineHeight: 1.55 }}>{i.problem}</p>
</div>
<div>
<div style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#6b6862', marginBottom: 4 }}>Solution</div>
<div style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#6a73a5', marginBottom: 4 }}>Solution</div>
<p style={{ margin: 0, color: '#e8e0cf', fontSize: '0.92rem', lineHeight: 1.55 }}>{i.solution}</p>
</div>
<div>

View File

@ -63,9 +63,9 @@ export function InquiryForm({ defaultRobot = '', defaultCategory = '', intent =
width: '100%',
padding: '0.875rem 1rem',
borderRadius: '0.75rem',
border: '1px solid rgba(196, 162, 101,0.18)',
border: '1px solid rgba(39, 63, 148,0.18)',
background: 'rgba(15, 12, 8,0.55)',
color: '#f5f1e8',
color: '#FBFBFD',
fontSize: '0.95rem',
outline: 'none',
boxSizing: 'border-box',
@ -77,7 +77,7 @@ export function InquiryForm({ defaultRobot = '', defaultCategory = '', intent =
fontSize: '0.72rem',
letterSpacing: '0.18em',
textTransform: 'uppercase',
color: '#94908a',
color: '#8891C7',
fontWeight: 600,
};
@ -90,7 +90,7 @@ export function InquiryForm({ defaultRobot = '', defaultCategory = '', intent =
)}
{status === 'error' && (
<div style={{ padding: '0.875rem 1rem', borderRadius: 12, background: 'rgba(239,68,68,0.1)', border: '1px solid rgba(239,68,68,0.3)', color: '#fca5a5' }}>
Something went wrong. Please try again, or email info@yslootahtech.com.
Something went wrong. Please try again, or email info@yslootahrobotics.com.
</div>
)}

View File

@ -9,12 +9,12 @@ type Item = {
};
const DEFAULT_ITEMS: Item[] = [
{ label: 'Exclusive UAE Access', sub: 'YS Lootah Robotics', accent: '#e0c896' },
{ label: 'Unitree', sub: 'Quadruped · Humanoid', accent: '#c4a265' },
{ label: 'Pudu Robotics', sub: 'Service · Delivery · Cleaning', accent: '#8b6f47' },
{ label: 'Dubai · UAE', sub: 'Sales · Demo · Configure', accent: '#e0c896' },
{ label: 'Showroom', sub: 'City Bay Business Center', accent: '#c4a265' },
{ label: '10+ Industries', sub: 'Hospitality · Security · Healthcare', accent: '#8b6f47' },
{ label: 'Exclusive UAE Access', sub: 'YS Lootah Robotics', accent: '#DEE0F0' },
{ label: 'Unitree', sub: 'Quadruped · Humanoid', accent: '#273F94' },
{ label: 'Pudu Robotics', sub: 'Service · Delivery · Cleaning', accent: '#8891C7' },
{ label: 'Dubai · UAE', sub: 'Sales · Demo · Configure', accent: '#DEE0F0' },
{ label: 'Showroom', sub: 'City Bay Business Center', accent: '#273F94' },
{ label: '10+ Industries', sub: 'Hospitality · Security · Healthcare', accent: '#8891C7' },
];
export function MarqueeStrip({ items = DEFAULT_ITEMS, speed = 38 }: { items?: Item[]; speed?: number }) {
@ -28,8 +28,8 @@ export function MarqueeStrip({ items = DEFAULT_ITEMS, speed = 38 }: { items?: It
maskImage: 'linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent)',
WebkitMaskImage: 'linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent)',
padding: '1.25rem 0',
borderTop: '1px solid rgba(196, 162, 101,0.12)',
borderBottom: '1px solid rgba(196, 162, 101,0.12)',
borderTop: '1px solid rgba(39, 63, 148,0.12)',
borderBottom: '1px solid rgba(39, 63, 148,0.12)',
background:
'linear-gradient(180deg, rgba(15, 12, 8,0.4), rgba(5, 5, 5,0.6))',
}}
@ -59,8 +59,8 @@ export function MarqueeStrip({ items = DEFAULT_ITEMS, speed = 38 }: { items?: It
width: 8,
height: 8,
borderRadius: 999,
background: it.accent ?? '#e0c896',
boxShadow: `0 0 12px ${it.accent ?? '#e0c896'}88`,
background: it.accent ?? '#DEE0F0',
boxShadow: `0 0 12px ${it.accent ?? '#DEE0F0'}88`,
}}
/>
<span
@ -79,7 +79,7 @@ export function MarqueeStrip({ items = DEFAULT_ITEMS, speed = 38 }: { items?: It
fontSize: '0.7rem',
letterSpacing: '0.22em',
textTransform: 'uppercase',
color: '#6b6862',
color: '#6a73a5',
}}
>
{it.sub}

View File

@ -15,7 +15,7 @@ export function ProductFilterTabs({ tabs, activeId, onChange, title }: Props) {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', minWidth: 0 }}>
{title && (
<span style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#94908a', fontWeight: 700 }}>
<span style={{ fontSize: '0.68rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8891C7', fontWeight: 700 }}>
{title}
</span>
)}
@ -39,9 +39,9 @@ export function ProductFilterTabs({ tabs, activeId, onChange, title }: Props) {
border: '1px solid',
cursor: 'pointer',
transition: 'all 0.2s',
background: active ? (t.accent ? `${t.accent}1F` : 'rgba(196, 162, 101,0.18)') : 'rgba(15, 12, 8,0.55)',
borderColor: active ? (t.accent ?? '#e0c896') : 'rgba(196, 162, 101,0.2)',
color: active ? (t.accent ?? '#e0c896') : '#cbc4b3',
background: active ? (t.accent ? `${t.accent}1F` : 'rgba(39, 63, 148,0.18)') : 'rgba(15, 12, 8,0.55)',
borderColor: active ? (t.accent ?? '#DEE0F0') : 'rgba(39, 63, 148,0.2)',
color: active ? (t.accent ?? '#DEE0F0') : '#DEE0F0',
}}
>
{t.label}

View File

@ -22,7 +22,7 @@ export function ProductGallery({ images, accent }: Props) {
overflow: 'hidden',
background:
`radial-gradient(ellipse 70% 60% at 50% 50%, ${accent}33, transparent 60%), linear-gradient(180deg, rgba(15, 12, 8,0.7), rgba(5, 5, 5,0.95))`,
border: '1px solid rgba(196, 162, 101,0.18)',
border: '1px solid rgba(39, 63, 148,0.18)',
boxShadow: '0 30px 100px rgba(0, 0, 0,0.6)',
}}
>
@ -32,7 +32,7 @@ export function ProductGallery({ images, accent }: Props) {
position: 'absolute',
inset: 0,
background:
'linear-gradient(rgba(196, 162, 101,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(196, 162, 101,0.05) 1px, transparent 1px)',
'linear-gradient(rgba(39, 63, 148,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(39, 63, 148,0.05) 1px, transparent 1px)',
backgroundSize: '40px 40px',
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%)',
@ -64,7 +64,7 @@ export function ProductGallery({ images, accent }: Props) {
overflow: 'hidden',
cursor: 'pointer',
background: 'rgba(15, 12, 8,0.6)',
border: `1px solid ${idx === active ? accent : 'rgba(196, 162, 101,0.2)'}`,
border: `1px solid ${idx === active ? accent : 'rgba(39, 63, 148,0.2)'}`,
padding: 4,
transition: 'all 0.2s',
}}

View File

@ -4,24 +4,24 @@ import type { RobotSpec } from '@/data/robots';
export function ProductSpecTable({ specs }: { specs: RobotSpec[] }) {
return (
<table style={{ width: '100%', borderCollapse: 'collapse', color: '#cbc4b3' }}>
<table style={{ width: '100%', borderCollapse: 'collapse', color: '#DEE0F0' }}>
<tbody>
{specs.map((s) => (
<tr key={s.label} style={{ borderBottom: '1px solid rgba(196, 162, 101,0.1)' }}>
<tr key={s.label} style={{ borderBottom: '1px solid rgba(39, 63, 148,0.1)' }}>
<td
style={{
padding: '0.65rem 0',
fontSize: '0.74rem',
letterSpacing: '0.14em',
textTransform: 'uppercase',
color: '#94908a',
color: '#8891C7',
width: '46%',
verticalAlign: 'top',
}}
>
{s.label}
</td>
<td style={{ padding: '0.65rem 0', color: '#f5f1e8', fontSize: '0.92rem' }}>{s.value}</td>
<td style={{ padding: '0.65rem 0', color: '#FBFBFD', fontSize: '0.92rem' }}>{s.value}</td>
</tr>
))}
</tbody>

View File

@ -7,49 +7,49 @@ const CATEGORY_META: { id: RobotCategory; description: string; accent: string; i
{
id: 'humanoid',
description: 'Bipedal robots for events, education, hospitality, and research.',
accent: '#e0c896',
accent: '#DEE0F0',
iconPath: 'M12 2a4 4 0 0 1 4 4v2h-8V6a4 4 0 0 1 4-4Zm-6 8h12v4l-2 2v6h-3v-5h-2v5H8v-6l-2-2v-4Z',
},
{
id: 'quadruped',
description: 'Four-legged robots for inspection, security, and field operations.',
accent: '#c4a265',
accent: '#273F94',
iconPath: 'M3 11l3-3h4l2-2 2 2h4l3 3v3l-2 1v3h-3v-3h-3l-1 2-1-2H8v3H5v-3l-2-1v-3Z',
},
{
id: 'service',
description: 'Customer-facing robots that greet, guide, and assist.',
accent: '#8b6f47',
accent: '#8891C7',
iconPath: 'M12 2a5 5 0 0 1 5 5v3a5 5 0 0 1-10 0V7a5 5 0 0 1 5-5Zm-7 17a7 7 0 0 1 14 0v3H5v-3Z',
},
{
id: 'delivery',
description: 'Autonomous delivery for restaurants, hotels, and back-of-house.',
accent: '#e0c896',
accent: '#DEE0F0',
iconPath: 'M3 6h11v9H3V6Zm14 3h3l2 3v3h-2a2 2 0 1 1-4 0h-1V9h2ZM6 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4Zm12 0a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z',
},
{
id: 'hospitality',
description: 'Premium hospitality robotics for hotels, resorts, and venues.',
accent: '#8b6f47',
accent: '#8891C7',
iconPath: 'M4 7h16v3H4V7Zm0 5h16v8h-3v-3H7v3H4v-8Z',
},
{
id: 'cleaning',
description: 'Commercial cleaning robots for malls, airports, and offices.',
accent: '#c4a265',
accent: '#273F94',
iconPath: 'M5 4h6v8H5V4Zm0 10h6v2H5v-2Zm-2 4h10v3H3v-3Zm12-14h3l3 9v9h-3v-7h-3V4Z',
},
{
id: 'commercial',
description: 'Commercial automation for warehouses, sites, and facilities.',
accent: '#e0c896',
accent: '#DEE0F0',
iconPath: 'M3 21V8l9-5 9 5v13h-6v-6h-6v6H3Z',
},
{
id: 'inspection',
description: 'Inspection robots for energy, utilities, and industrial sites.',
accent: '#c4a265',
accent: '#273F94',
iconPath: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 4a6 6 0 1 1 0 12 6 6 0 0 1 0-12Zm0 3a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z',
},
];
@ -73,7 +73,7 @@ export function RobotCategoryGrid() {
style={{
padding: '1.5rem',
textDecoration: 'none',
color: '#f5f1e8',
color: '#FBFBFD',
display: 'flex',
flexDirection: 'column',
gap: '0.875rem',
@ -102,7 +102,7 @@ export function RobotCategoryGrid() {
{count} models
</span>
</div>
<p style={{ margin: 0, fontSize: '0.88rem', color: '#94908a', lineHeight: 1.55 }}>
<p style={{ margin: 0, fontSize: '0.88rem', color: '#8891C7', lineHeight: 1.55 }}>
{cat.description}
</p>
</Link>

View File

@ -19,7 +19,7 @@ export function RobotProductCard({ robot, priority = false }: Props) {
display: 'flex',
flexDirection: 'column',
height: '100%',
color: '#f5f1e8',
color: '#FBFBFD',
}}
>
<Link
@ -41,7 +41,7 @@ export function RobotProductCard({ robot, priority = false }: Props) {
position: 'absolute',
inset: 0,
backgroundImage:
'linear-gradient(rgba(196, 162, 101,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(196, 162, 101,0.05) 1px, transparent 1px)',
'linear-gradient(rgba(39, 63, 148,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(39, 63, 148,0.05) 1px, transparent 1px)',
backgroundSize: '32px 32px',
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%)',
@ -90,11 +90,11 @@ export function RobotProductCard({ robot, priority = false }: Props) {
padding: '0.35rem 0.7rem',
borderRadius: '999px',
background: 'rgba(255,255,255,0.05)',
border: '1px solid rgba(196, 162, 101,0.2)',
border: '1px solid rgba(39, 63, 148,0.2)',
fontSize: '0.66rem',
letterSpacing: '0.18em',
textTransform: 'uppercase',
color: '#cbc4b3',
color: '#DEE0F0',
backdropFilter: 'blur(8px)',
}}
>
@ -104,11 +104,11 @@ export function RobotProductCard({ robot, priority = false }: Props) {
<div style={{ padding: '1.5rem', display: 'flex', flexDirection: 'column', gap: '0.75rem', flex: 1 }}>
<h3 style={{ margin: 0, fontSize: '1.2rem', fontWeight: 600, letterSpacing: '-0.01em' }}>
<Link href={detailHref} style={{ color: '#f5f1e8', textDecoration: 'none' }}>
<Link href={detailHref} style={{ color: '#FBFBFD', textDecoration: 'none' }}>
{robot.name}
</Link>
</h3>
<p style={{ margin: 0, color: '#94908a', fontSize: '0.88rem', lineHeight: 1.55, flex: 1 }}>
<p style={{ margin: 0, color: '#8891C7', fontSize: '0.88rem', lineHeight: 1.55, flex: 1 }}>
{robot.shortDescription}
</p>
@ -118,10 +118,10 @@ export function RobotProductCard({ robot, priority = false }: Props) {
key={u}
style={{
fontSize: '0.7rem',
color: '#94908a',
color: '#8891C7',
padding: '0.2rem 0.5rem',
borderRadius: 999,
border: '1px solid rgba(196, 162, 101,0.18)',
border: '1px solid rgba(39, 63, 148,0.18)',
background: 'rgba(15, 12, 8,0.5)',
letterSpacing: '0.04em',
}}
@ -135,7 +135,7 @@ export function RobotProductCard({ robot, priority = false }: Props) {
style={{
marginTop: 'auto',
paddingTop: '0.75rem',
borderTop: '1px solid rgba(196, 162, 101,0.1)',
borderTop: '1px solid rgba(39, 63, 148,0.1)',
display: 'flex',
flexWrap: 'wrap',
gap: '0.4rem',
@ -176,8 +176,8 @@ export function RobotProductCard({ robot, priority = false }: Props) {
padding: '0.55rem 0.75rem',
borderRadius: 10,
background: 'transparent',
border: '1px solid rgba(196, 162, 101,0.2)',
color: '#cbc4b3',
border: '1px solid rgba(39, 63, 148,0.2)',
color: '#DEE0F0',
fontSize: '0.72rem',
fontWeight: 600,
letterSpacing: '0.1em',
@ -198,8 +198,8 @@ export function RobotProductCard({ robot, priority = false }: Props) {
padding: '0.55rem 0.75rem',
borderRadius: 10,
background: 'transparent',
border: '1px solid rgba(196, 162, 101,0.2)',
color: '#cbc4b3',
border: '1px solid rgba(39, 63, 148,0.2)',
color: '#DEE0F0',
fontSize: '0.72rem',
fontWeight: 600,
letterSpacing: '0.1em',

View File

@ -0,0 +1,101 @@
'use client';
type Service = { title: string; body: string; icon: string };
const SERVICES: Service[] = [
{
title: 'Autonomous Robotics & Intelligent Automation',
body: 'End-to-end deployment of autonomous robotic systems for industrial, commercial, and public sector operations.',
icon: 'M12 2a8 8 0 0 1 8 8v3l2 4-2 1v3a3 3 0 0 1-3 3h-2v-3h-2v3H9v-3H7v3H5a3 3 0 0 1-3-3v-3l-2-1 2-4v-3a8 8 0 0 1 8-8Z',
},
{
title: 'Autonomous Site Inspection & Patrolling',
body: 'Quadruped patrol robots for facility, infrastructure, and security inspection across UAE sites.',
icon: 'M3 11l3-3h4l2-2 2 2h4l3 3v3l-2 1v3h-3v-3h-3l-1 2-1-2H8v3H5v-3l-2-1v-3Z',
},
{
title: 'Smart Service & Delivery Robots',
body: 'Hospitality, retail, and back-of-house delivery robots configured for UAE venues.',
icon: 'M3 6h11v9H3V6Zm14 3h3l2 3v3h-2a2 2 0 1 1-4 0h-1V9h2ZM6 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z',
},
{
title: 'Collaborative & Flexible Robotics Integration',
body: 'Integration of robotic systems into existing workflows — collaborative, flexible, business-friendly.',
icon: 'M12 2v6m0 8v6M4.93 4.93l4.24 4.24m5.66 5.66 4.24 4.24M2 12h6m8 0h6M4.93 19.07l4.24-4.24m5.66-5.66 4.24-4.24',
},
{
title: 'Custom Robot Motion Programming',
body: 'Tailored motion sequences and choreography for events, demos, and brand activations.',
icon: 'M3 12h4l3-7 4 14 3-7h4',
},
{
title: 'Cloud-Based Robot Program Repository',
body: 'Centralized program repository for storing, versioning, and deploying robot behaviors.',
icon: 'M7 18a4 4 0 0 1-1.4-7.8 5 5 0 0 1 9.6-1.6A4.5 4.5 0 0 1 21 13.5 4.5 4.5 0 0 1 16.5 18H7Z',
},
{
title: 'Algorithm Customization & Optimization',
body: 'Tuning of perception, planning, and control algorithms for venue-specific performance.',
icon: 'M4 6h16M4 12h10m-6 6h12',
},
{
title: 'Remote System Monitoring & Diagnostics',
body: 'Live monitoring, alerts, and remote diagnostics keep your robot fleet running.',
icon: 'M2 12h4l3-9 4 18 3-9h6',
},
{
title: 'Hardware-Software Co-Design Consultation',
body: 'Co-design across hardware, sensors, software, and integration for custom robotics programs.',
icon: 'M4 4h7v7H4Zm9 0h7v7h-7Zm-9 9h7v7H4Zm9 0h7v7h-7Z',
},
{
title: 'Robotics Software Development Kit',
body: 'SDK access for partners and developers building on top of our deployed robots.',
icon: 'M8 3 3 8l5 5m8-10 5 5-5 5M14 3l-4 18',
},
{
title: 'Data Analytics Dashboard',
body: 'Centralized dashboards turning robot telemetry into actionable business insight.',
icon: 'M3 21V8h4v13H3Zm7 0V3h4v18h-4Zm7 0v-9h4v9h-4Z',
},
];
const ACCENTS = ['#DEE0F0', '#273F94', '#8891C7'];
export function ServicesGrid() {
return (
<div
style={{
display: 'grid',
gap: '1rem',
gridTemplateColumns: 'repeat(auto-fit, minmax(min(260px, 100%), 1fr))',
}}
>
{SERVICES.map((s, i) => {
const accent = ACCENTS[i % ACCENTS.length];
return (
<div key={s.title} className="card" style={{ padding: '1.5rem', display: 'flex', flexDirection: 'column', gap: '0.875rem', minHeight: 200 }}>
<div
style={{
width: 44,
height: 44,
borderRadius: 12,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: `${accent}1A`,
border: `1px solid ${accent}55`,
}}
>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke={accent} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d={s.icon} />
</svg>
</div>
<h3 style={{ margin: 0, fontSize: '1rem', fontWeight: 600, lineHeight: 1.3 }}>{s.title}</h3>
<p style={{ margin: 0, color: '#DEE0F0', lineHeight: 1.6, fontSize: '0.88rem' }}>{s.body}</p>
</div>
);
})}
</div>
);
}

View File

@ -4,25 +4,25 @@ const REASONS = [
{
title: 'Exclusive UAE portfolio',
body: 'Selected Unitree and Pudu Robotics solutions — available exclusively in the UAE through YS Lootah Robotics for hospitality, security, education, and industry.',
accent: '#e0c896',
accent: '#DEE0F0',
icon: 'M3 3h7v7H3V3Zm0 11h7v7H3v-7Zm11-11h7v7h-7V3Zm0 11h7v7h-7v-7Z',
},
{
title: 'Dubai sales and support',
body: 'A local Dubai team manages your inquiry, demo, deployment, and on-the-ground support — not just a website with a contact form.',
accent: '#c4a265',
accent: '#273F94',
icon: 'M12 2 2 7v6c0 5 4 9 10 11 6-2 10-6 10-11V7l-10-5Z',
},
{
title: 'Custom configuration',
body: 'Configure persona, attire, and accessories for humanoid robots — visualize your deployment before you order with our 3D configurator.',
accent: '#8b6f47',
accent: '#8891C7',
icon: 'M12 4a4 4 0 0 1 4 4v1h5v6h-5v1a4 4 0 0 1-8 0v-1H3V9h5V8a4 4 0 0 1 4-4Z',
},
{
title: 'End-to-end deployment',
body: 'From procurement and configuration to delivery, installation, training, and ongoing support — we handle the full lifecycle.',
accent: '#e0c896',
accent: '#DEE0F0',
icon: 'M3 12h4l3-7 4 14 3-7h4',
},
];
@ -55,7 +55,7 @@ export function WhyUs() {
</svg>
</div>
<h3 style={{ margin: 0, fontSize: '1.1rem', fontWeight: 600 }}>{r.title}</h3>
<p style={{ margin: 0, color: '#cbc4b3', fontSize: '0.92rem', lineHeight: 1.6 }}>{r.body}</p>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: '0.92rem', lineHeight: 1.6 }}>{r.body}</p>
</div>
))}
</div>

View File

@ -0,0 +1,184 @@
'use client';
import Image from 'next/image';
import Link from 'next/link';
import { ArrowRight, BadgeCheck, Cpu, MapPin, Sparkles, Bot, Truck } from 'lucide-react';
import { ContainerScroll } from '@/components/ui/container-scroll-animation';
const SHOWROOM_ROBOTS = [
{
name: 'Unitree G1',
slug: 'unitree-g1',
image: '/images/robots/unitree-g1.png',
category: 'Humanoid',
accent: '#DEE0F0',
},
{
name: 'Unitree Go2',
slug: 'unitree-go2',
image: '/images/robots/unitree-go2.png',
category: 'Quadruped',
accent: '#BFC3E2',
},
{
name: 'Pudu BellaBot',
slug: 'pudu-bellabot',
image: '/images/robots/pudu-bellabot.svg',
category: 'Delivery',
accent: '#8891C7',
},
];
const TABS = [
{ label: 'All', icon: Sparkles, active: true },
{ label: 'Unitree', icon: Bot },
{ label: 'Pudu', icon: Truck },
{ label: 'Humanoid', icon: BadgeCheck },
{ label: 'Quadruped', icon: Cpu },
];
export function RoboticsScrollShowcase() {
return (
<section
style={{
position: 'relative',
overflow: 'hidden',
background:
'radial-gradient(ellipse 60% 50% at 50% 0%, rgba(39,63,148,0.18), transparent 60%)',
}}
>
<ContainerScroll
titleComponent={
<div className="flex flex-col items-center gap-4">
<span
className="inline-flex items-center gap-2 rounded-full border border-[#DEE0F0]/30 bg-[#273F94]/15 px-4 py-1.5 text-[10px] font-semibold uppercase tracking-[0.32em] text-[#DEE0F0]"
>
<span className="h-1.5 w-1.5 rounded-full bg-[#DEE0F0]" />
Exclusive UAE Robotics Showroom
</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">
Exclusive UAE access.
</span>
<span className="mt-3 block text-base font-normal text-[#BFC3E2] sm:text-lg md:text-xl">
Built for Dubai&apos;s next generation of automation.
</span>
</h2>
<p className="max-w-2xl text-sm leading-relaxed text-[#DEE0F0]/75 sm:text-base">
Explore selected Unitree and Pudu Robotics solutions through an immersive showroom experience built for UAE businesses, venues, and innovators.
</p>
</div>
}
>
<ConsoleInterior />
</ContainerScroll>
</section>
);
}
function ConsoleInterior() {
return (
<div className="relative h-full w-full">
{/* left sidebar — category rail */}
<aside className="hidden h-full w-44 flex-col gap-1.5 border-r border-[#DEE0F0]/10 bg-[#0a0a0c]/60 p-3 md:flex md:absolute md:inset-y-0 md:left-0">
<div className="px-2 py-2 text-[9px] font-semibold uppercase tracking-[0.28em] text-[#8891C7]">
Categories
</div>
{TABS.map((t) => (
<button
key={t.label}
type="button"
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]'
}`}
>
<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">
<span className="block text-[#DEE0F0]">YS Lootah Robotics</span>
In Tech We Innovate
</div>
</aside>
{/* main display */}
<div className="absolute inset-0 md:left-44">
{/* top breadcrumb */}
<div className="flex items-center justify-between border-b border-[#DEE0F0]/10 px-4 py-2 text-[10px] uppercase tracking-[0.22em] text-[#8891C7] md:px-6">
<span>Robots · Exclusive UAE Portfolio</span>
<span className="hidden sm:inline">11 Models · 2 Brands · Dubai</span>
</div>
{/* product grid */}
<div className="grid grid-cols-3 gap-3 p-4 md:p-6">
{SHOWROOM_ROBOTS.map((r) => (
<article
key={r.slug}
className="relative flex flex-col gap-2 overflow-hidden rounded-xl border border-[#DEE0F0]/15 bg-[#0a0a0c]/70 p-3 backdrop-blur-xl md:p-4"
>
<div
className="relative aspect-[4/5] overflow-hidden rounded-lg"
style={{
background: `radial-gradient(ellipse 70% 50% at 50% 60%, ${r.accent}22 0%, transparent 65%), linear-gradient(180deg, rgba(28,27,33,0.7), rgba(10,10,12,0.95))`,
}}
>
<Image
src={r.image}
alt={`${r.name} robot`}
fill
sizes="(max-width: 768px) 33vw, 240px"
className="object-contain p-2 md:p-4"
/>
<span
className="absolute left-1.5 top-1.5 rounded-full border px-1.5 py-0.5 text-[8px] font-bold uppercase tracking-[0.2em] backdrop-blur md:left-2 md:top-2 md:px-2 md:py-0.5 md:text-[9px]"
style={{ borderColor: `${r.accent}66`, color: r.accent, background: 'rgba(10,10,12,0.7)' }}
>
{r.category}
</span>
</div>
<div>
<div className="text-[10px] font-semibold uppercase tracking-[0.22em] text-[#8891C7]">
Available in UAE
</div>
<div className="text-xs font-semibold text-white md:text-sm">{r.name}</div>
</div>
</article>
))}
</div>
{/* CTA strip */}
<div className="absolute bottom-0 left-0 right-0 flex flex-wrap items-center justify-between gap-2 border-t border-[#DEE0F0]/10 bg-[#0a0a0c]/85 px-4 py-3 backdrop-blur-xl md:px-6">
<div className="flex flex-wrap items-center gap-2">
<Link
href="/book-demo/"
className="inline-flex items-center gap-1.5 rounded-full bg-gradient-to-br from-[#3a55c4] via-[#273F94] to-[#1a2e6e] px-3.5 py-2 text-[10px] font-bold uppercase tracking-[0.16em] text-white shadow-[0_8px_24px_rgba(39,63,148,0.45)] md:text-[11px]"
>
Book demo
<ArrowRight className="h-3 w-3" />
</Link>
<Link
href="/configure/"
className="inline-flex items-center gap-1.5 rounded-full border border-[#DEE0F0]/30 bg-white/5 px-3.5 py-2 text-[10px] font-bold uppercase tracking-[0.16em] text-[#DEE0F0] backdrop-blur md:text-[11px]"
>
Configure solution
<ArrowRight className="h-3 w-3" />
</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]"
>
Request UAE quotation
</Link>
</div>
<div className="hidden items-center gap-2 text-[10px] uppercase tracking-[0.22em] text-[#8891C7] md:flex">
<MapPin className="h-3 w-3" /> Dubai · UAE
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,117 @@
'use client';
import { SplineScene } from '@/components/ui/spline-scene';
import { Card } from '@/components/ui/card';
import { Spotlight } from '@/components/ui/spotlight';
import { ArrowRight, BadgeCheck, Cpu, MapPin } from 'lucide-react';
import Link from 'next/link';
const SPLINE_SCENE = 'https://prod.spline.design/kZDDjO5HuC9GJUM2/scene.splinecode';
export function RoboticsSplineShowcase() {
return (
<section className="relative overflow-hidden bg-[#221F20] px-4 py-20 text-white sm:px-6 lg:px-8">
<div
aria-hidden
className="absolute inset-0 bg-[radial-gradient(circle_at_70%_30%,rgba(39,63,148,0.42),transparent_42%),radial-gradient(circle_at_20%_80%,rgba(222,224,240,0.10),transparent_36%)]"
/>
<div
aria-hidden
className="absolute inset-0 bg-[linear-gradient(to_right,rgba(255,255,255,0.045)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,0.035)_1px,transparent_1px)] bg-[size:64px_64px] opacity-30"
/>
<div className="relative mx-auto max-w-7xl">
<Card className="relative min-h-[680px] overflow-hidden border-[#DEE0F0]/15 bg-[#221F20]/70">
<Spotlight size={460} />
<div className="grid min-h-[680px] grid-cols-1 lg:grid-cols-2">
{/* Left: copy + CTA */}
<div className="relative z-10 flex flex-col justify-center p-6 sm:p-10 lg:p-14">
<div className="mb-6 inline-flex w-fit items-center gap-2 rounded-full border border-[#DEE0F0]/25 bg-[#273F94]/20 px-4 py-2 text-[10px] font-bold uppercase tracking-[0.3em] text-[#DEE0F0]">
<span className="h-1.5 w-1.5 rounded-full bg-[#DEE0F0]" />
Exclusive UAE Access
</div>
<h2 className="max-w-2xl text-4xl font-semibold leading-[1.02] tracking-[-0.04em] text-white sm:text-5xl lg:text-6xl xl:text-7xl">
Advanced robotics.
<span className="block bg-gradient-to-r from-white via-[#DEE0F0] to-[#8891C7] bg-clip-text text-transparent">
Built for UAE innovation.
</span>
</h2>
<p className="mt-6 max-w-xl text-base leading-7 text-[#DEE0F0]/78 sm:text-lg sm:leading-8">
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>
<div className="mt-8 flex flex-col gap-3 sm:flex-row">
<Link
href="/robots/"
className="group inline-flex items-center justify-center rounded-full bg-gradient-to-br from-[#3a55c4] via-[#273F94] to-[#1a2e6e] px-6 py-3 text-xs font-bold uppercase tracking-[0.16em] text-white shadow-[0_18px_45px_rgba(39,63,148,0.45)] transition hover:brightness-110"
>
Explore robots
<ArrowRight className="ml-2 h-4 w-4 transition group-hover:translate-x-1" />
</Link>
<Link
href="/configure/"
className="group inline-flex items-center justify-center rounded-full border border-[#DEE0F0]/25 bg-white/[0.04] px-6 py-3 text-xs font-bold uppercase tracking-[0.16em] text-[#DEE0F0] backdrop-blur-xl transition hover:bg-white/[0.08]"
>
Configure your solution
<ArrowRight className="ml-2 h-4 w-4 transition group-hover:translate-x-1" />
</Link>
</div>
<div className="mt-10 grid max-w-xl grid-cols-1 gap-3 sm:grid-cols-3">
{[
{ icon: BadgeCheck, label: 'Exclusive UAE', value: 'Access' },
{ icon: Cpu, label: 'Unitree + Pudu', value: 'Robotics' },
{ icon: MapPin, label: 'Dubai', value: 'Showroom & Demo' },
].map((item) => (
<div
key={item.label}
className="rounded-2xl border border-[#DEE0F0]/12 bg-white/[0.045] p-4 backdrop-blur-xl"
>
<item.icon className="mb-3 h-5 w-5 text-[#DEE0F0]" />
<div className="text-sm font-semibold text-white">{item.label}</div>
<div className="mt-1 text-xs uppercase tracking-[0.18em] text-[#BFC3E2]/70">
{item.value}
</div>
</div>
))}
</div>
<p className="mt-8 text-[11px] font-semibold uppercase tracking-[0.32em] text-[#BFC3E2]">
In Tech We Innovate · In Trust We Lead
</p>
</div>
{/* Right: Spline 3D scene */}
<div className="relative min-h-[520px] overflow-hidden lg:min-h-full">
<div
aria-hidden
className="absolute inset-6 rounded-[2rem] border border-[#DEE0F0]/15 bg-[#273F94]/10 shadow-[inset_0_0_80px_rgba(222,224,240,0.05)] backdrop-blur-xl"
/>
<div className="absolute left-8 top-8 z-10 rounded-full border border-[#DEE0F0]/20 bg-[#221F20]/70 px-4 py-2 text-[10px] font-bold uppercase tracking-[0.24em] text-[#DEE0F0] backdrop-blur">
Interactive Robot Scene
</div>
<div className="absolute bottom-8 right-8 z-10 rounded-2xl border border-[#DEE0F0]/15 bg-[#221F20]/75 px-5 py-4 backdrop-blur-xl">
<div className="text-[10px] uppercase tracking-[0.22em] text-[#BFC3E2]/70">
YS Lootah Robotics
</div>
<div className="mt-1 text-sm font-semibold text-white">In Tech We Innovate</div>
</div>
<SplineScene scene={SPLINE_SCENE} className="relative z-[2] h-full w-full" />
{/* Replacement note (visible only in dev) */}
<span className="sr-only">
Interactive 3D scene placeholder Spline reference robot for development. Replace
with approved YS Lootah Robotics custom Spline scene when available.
</span>
</div>
</div>
</Card>
</div>
</section>
);
}

View File

@ -8,7 +8,7 @@ type Props = {
className?: string;
};
export function CursorSpotlight({ color = 'rgba(196, 162, 101, 0.18)', size = 520, className = '' }: Props) {
export function CursorSpotlight({ color = 'rgba(39, 63, 148, 0.18)', size = 520, className = '' }: Props) {
const ref = useRef<HTMLDivElement | null>(null);
const [pos, setPos] = useState<{ x: number; y: number } | null>(null);
const [enabled, setEnabled] = useState(false);

View File

@ -16,7 +16,7 @@ export function GlassPanel({ className = '', children, glow = false, style }: Pr
style={{
borderRadius: '1.25rem',
padding: '1.5rem',
boxShadow: glow ? '0 12px 60px rgba(0, 0, 0,0.5), 0 0 60px rgba(196, 162, 101,0.18)' : undefined,
boxShadow: glow ? '0 12px 60px rgba(0, 0, 0,0.5), 0 0 60px rgba(39, 63, 148,0.18)' : undefined,
...style,
}}
>

View File

@ -0,0 +1,63 @@
import * as React from 'react';
import { cn } from '@/lib/utils';
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
'rounded-3xl border border-[#DEE0F0]/15 bg-[#221F20]/80 text-white shadow-[0_24px_120px_rgba(39,63,148,0.22)] backdrop-blur-2xl',
className
)}
{...props}
/>
));
Card.displayName = 'Card';
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />
));
CardHeader.displayName = 'CardHeader';
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn('text-2xl font-semibold leading-none tracking-tight', className)}
{...props}
/>
));
CardTitle.displayName = 'CardTitle';
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p ref={ref} className={cn('text-sm text-[#DEE0F0]/70', className)} {...props} />
));
CardDescription.displayName = 'CardDescription';
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn('p-6 pt-0', className)} {...props} />
));
CardContent.displayName = 'CardContent';
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn('flex items-center p-6 pt-0', className)} {...props} />
));
CardFooter.displayName = 'CardFooter';
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };

View File

@ -0,0 +1,158 @@
'use client';
import React, { useRef } from 'react';
import { useScroll, useTransform, motion, type MotionValue } from 'framer-motion';
import { cn } from '@/lib/utils';
type Props = {
titleComponent: React.ReactNode;
children: React.ReactNode;
className?: string;
};
export function ContainerScroll({ titleComponent, children, className }: Props) {
const containerRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ['start end', 'end start'],
});
const [isMobile, setIsMobile] = React.useState(false);
React.useEffect(() => {
const check = () => setIsMobile(window.innerWidth <= 768);
check();
window.addEventListener('resize', check);
return () => window.removeEventListener('resize', check);
}, []);
const scaleDimensions = (): [number, number] => (isMobile ? [0.86, 0.96] : [1.04, 1]);
const rotate = useTransform(scrollYProgress, [0, 0.55], [22, 0]);
const scale = useTransform(scrollYProgress, [0, 0.55], scaleDimensions());
const translate = useTransform(scrollYProgress, [0, 0.55], [0, -90]);
const titleOpacity = useTransform(scrollYProgress, [0, 0.3], [0.6, 1]);
const titleY = useTransform(scrollYProgress, [0, 0.4], [40, 0]);
return (
<div
ref={containerRef}
className={cn(
'relative flex h-[60rem] items-center justify-center p-4 md:h-[80rem] md:p-12',
className
)}
>
<div
className="relative w-full"
style={{ perspective: '1100px' }}
>
<Header titleComponent={titleComponent} opacity={titleOpacity} y={titleY} />
<DisplayFrame rotate={rotate} translate={translate} scale={scale}>
{children}
</DisplayFrame>
</div>
</div>
);
}
function Header({
titleComponent,
opacity,
y,
}: {
titleComponent: React.ReactNode;
opacity: MotionValue<number>;
y: MotionValue<number>;
}) {
return (
<motion.div
style={{ opacity, y }}
className="mx-auto max-w-5xl pb-8 text-center md:pb-12"
>
{titleComponent}
</motion.div>
);
}
function DisplayFrame({
rotate,
scale,
translate,
children,
}: {
rotate: MotionValue<number>;
scale: MotionValue<number>;
translate: MotionValue<number>;
children: React.ReactNode;
}) {
return (
<motion.div
style={{
rotateX: rotate,
scale,
y: translate,
boxShadow:
'0 0 0 1px rgba(222,224,240,0.08), 0 40px 120px rgba(0,0,0,0.65), 0 0 80px rgba(39,63,148,0.28), inset 0 1px 0 rgba(222,224,240,0.08)',
}}
className={cn(
'relative mx-auto w-full max-w-6xl rounded-[30px] border border-[#DEE0F0]/15 p-2 md:p-4',
'bg-[linear-gradient(180deg,rgba(28,27,33,0.92)_0%,rgba(20,18,22,0.96)_55%,rgba(8,8,10,0.98)_100%)]',
'backdrop-blur-2xl'
)}
>
{/* outer frame chrome */}
<div className="pointer-events-none absolute -inset-px rounded-[30px] bg-[linear-gradient(135deg,rgba(222,224,240,0.18),rgba(136,145,199,0.08)_40%,transparent_70%)] opacity-60" />
{/* corner taps */}
<CornerTaps />
{/* inner content stage */}
<div className="relative h-[27rem] w-full overflow-hidden rounded-[22px] border border-[#DEE0F0]/12 bg-[#0a0a0c] md:h-[38rem] md:rounded-[24px]">
{/* grid floor + blue glow */}
<div
aria-hidden
className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_70%_60%_at_50%_30%,rgba(58,85,196,0.32),transparent_60%),radial-gradient(ellipse_50%_40%_at_50%_100%,rgba(222,224,240,0.18),transparent_70%)]"
/>
<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%)]"
/>
{/* 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">
<div className="flex items-center gap-1.5">
<span className="h-2 w-2 rounded-full bg-[#8891C7]/60" />
<span className="h-2 w-2 rounded-full bg-[#8891C7]/40" />
<span className="h-2 w-2 rounded-full bg-[#3a55c4]" />
</div>
<span className="text-[10px] font-semibold uppercase tracking-[0.28em] text-[#DEE0F0]/80">
YS Lootah Robotics · Showroom Console
</span>
<span className="text-[10px] font-semibold uppercase tracking-[0.28em] text-[#8891C7]">
Live · UAE
</span>
</div>
<div className="relative h-full pt-10">{children}</div>
</div>
</motion.div>
);
}
function CornerTaps() {
return (
<>
{[
'top-2 left-2',
'top-2 right-2',
'bottom-2 left-2',
'bottom-2 right-2',
].map((pos) => (
<span
key={pos}
aria-hidden
className={cn(
'pointer-events-none absolute h-3 w-3 rounded-[3px] border border-[#DEE0F0]/35 bg-[#0a0a0c]/60',
pos
)}
/>
))}
</>
);
}

View File

@ -0,0 +1,29 @@
'use client';
import { Suspense, lazy } from 'react';
import { cn } from '@/lib/utils';
const Spline = lazy(() => import('@splinetool/react-spline'));
interface SplineSceneProps {
scene: string;
className?: string;
}
export function SplineScene({ scene, className }: SplineSceneProps) {
return (
<Suspense
fallback={
<div className="flex h-full w-full items-center justify-center bg-[#221F20]">
<div className="relative h-12 w-12">
<div className="absolute inset-0 rounded-full border border-[#DEE0F0]/20" />
<div className="absolute inset-0 animate-spin rounded-full border-t-2 border-[#DEE0F0]" />
<div className="absolute inset-2 rounded-full bg-[#273F94]/30 blur-md" />
</div>
</div>
}
>
<Spline scene={scene} className={cn('h-full w-full', className)} />
</Suspense>
);
}

View File

@ -0,0 +1,83 @@
'use client';
import React, { useRef, useState, useCallback, useEffect } from 'react';
import { motion, useSpring, useTransform, type SpringOptions } from 'framer-motion';
import { cn } from '@/lib/utils';
type SpotlightProps = {
className?: string;
size?: number;
springOptions?: SpringOptions;
};
export function Spotlight({
className,
size = 280,
springOptions = { bounce: 0, stiffness: 120, damping: 18 },
}: SpotlightProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [isHovered, setIsHovered] = useState(false);
const [parentElement, setParentElement] = useState<HTMLElement | null>(null);
const mouseX = useSpring(0, springOptions);
const mouseY = useSpring(0, springOptions);
const spotlightLeft = useTransform(mouseX, (x) => `${x - size / 2}px`);
const spotlightTop = useTransform(mouseY, (y) => `${y - size / 2}px`);
useEffect(() => {
if (containerRef.current) {
const parent = containerRef.current.parentElement;
if (parent) {
parent.style.position = 'relative';
parent.style.overflow = 'hidden';
setParentElement(parent);
}
}
}, []);
const handleMouseMove = useCallback(
(event: MouseEvent) => {
if (!parentElement) return;
const { left, top } = parentElement.getBoundingClientRect();
mouseX.set(event.clientX - left);
mouseY.set(event.clientY - top);
},
[mouseX, mouseY, parentElement]
);
useEffect(() => {
if (!parentElement) return;
const handleEnter = () => setIsHovered(true);
const handleLeave = () => setIsHovered(false);
parentElement.addEventListener('mousemove', handleMouseMove);
parentElement.addEventListener('mouseenter', handleEnter);
parentElement.addEventListener('mouseleave', handleLeave);
return () => {
parentElement.removeEventListener('mousemove', handleMouseMove);
parentElement.removeEventListener('mouseenter', handleEnter);
parentElement.removeEventListener('mouseleave', handleLeave);
};
}, [parentElement, handleMouseMove]);
return (
<motion.div
ref={containerRef}
className={cn(
'pointer-events-none absolute rounded-full bg-[radial-gradient(circle_at_center,var(--tw-gradient-stops),transparent_75%)] blur-2xl transition-opacity duration-300',
'from-[#DEE0F0]/45 via-[#273F94]/35 to-transparent',
isHovered ? 'opacity-100' : 'opacity-0',
className
)}
style={{
width: size,
height: size,
left: spotlightLeft,
top: spotlightTop,
}}
/>
);
}

View File

@ -21,7 +21,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Service and delivery robots that greet, deliver, and assist around the clock.',
benefit: 'Consistent guest experience, lower turnover impact, premium brand positioning.',
matchCategories: ['hospitality', 'service', 'delivery'],
accent: '#e0c896',
accent: '#DEE0F0',
icon: 'hotel',
},
{
@ -32,7 +32,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Delivery robots like BellaBot and KettyBot move food fast and reliably.',
benefit: 'Faster table turns, happier staff, instagrammable brand moment.',
matchCategories: ['delivery', 'service', 'hospitality'],
accent: '#8b6f47',
accent: '#8891C7',
icon: 'utensils',
},
{
@ -43,7 +43,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Multi-floor delivery robots and humanoid concierge experiences.',
benefit: 'Faster service, lower overhead, signature guest moments.',
matchCategories: ['delivery', 'hospitality', 'service'],
accent: '#c4a265',
accent: '#273F94',
icon: 'hotel',
},
{
@ -54,7 +54,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Cleaning robots, service robots, and humanoid activations for retail floors.',
benefit: 'Cleaner venues, memorable customer experiences, modern positioning.',
matchCategories: ['cleaning', 'service', 'humanoid'],
accent: '#e0c896',
accent: '#DEE0F0',
icon: 'shopping-bag',
},
{
@ -65,7 +65,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Autonomous delivery robots for medications, meals, and supplies.',
benefit: 'More clinician time at the bedside, lower contamination risk, predictable logistics.',
matchCategories: ['delivery', 'service'],
accent: '#c4a265',
accent: '#273F94',
icon: 'heart-pulse',
},
{
@ -76,7 +76,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Unitree humanoids and quadrupeds for STEM labs and innovation programs.',
benefit: 'Future-ready students, signature programs, and stronger STEM outcomes.',
matchCategories: ['humanoid', 'service'],
accent: '#8b6f47',
accent: '#8891C7',
icon: 'graduation-cap',
},
{
@ -87,7 +87,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Quadruped robots like Unitree Go2 and B2 patrol autonomously.',
benefit: 'Continuous coverage, audit trails, and consistent perimeter monitoring.',
matchCategories: ['quadruped', 'commercial'],
accent: '#e0c896',
accent: '#DEE0F0',
icon: 'shield',
},
{
@ -98,7 +98,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Quadruped inspection robots and autonomous delivery platforms.',
benefit: 'Higher throughput, fewer errors, and accurate facility monitoring.',
matchCategories: ['quadruped', 'delivery', 'commercial'],
accent: '#c4a265',
accent: '#273F94',
icon: 'warehouse',
},
{
@ -109,7 +109,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'Humanoid and quadruped robot showcases configured for your brand.',
benefit: 'Press coverage, viral content, and unmistakable premium positioning.',
matchCategories: ['humanoid', 'quadruped'],
accent: '#8b6f47',
accent: '#8891C7',
icon: 'sparkles',
},
{
@ -120,7 +120,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'A multi-robot fleet across cleaning, delivery, and patrol functions.',
benefit: 'Single operational system, predictable costs, future-ready facility.',
matchCategories: ['cleaning', 'commercial', 'delivery'],
accent: '#e0c896',
accent: '#DEE0F0',
icon: 'building',
},
{
@ -131,7 +131,7 @@ export const INDUSTRIES: Industry[] = [
solution: 'A curated multi-brand robotics portfolio with full local support.',
benefit: 'Visible innovation leadership and a UAE-supported deployment model.',
matchCategories: ['humanoid', 'quadruped', 'service'],
accent: '#c4a265',
accent: '#273F94',
icon: 'landmark',
},
];

View File

@ -36,9 +36,9 @@ export interface Robot {
}
/* Gold spectrum for accents (no cyan/blue/violet) */
const GOLD_CHAMPAGNE = '#e0c896';
const GOLD_BRAND = '#c4a265';
const GOLD_BRONZE = '#8b6f47';
const GOLD_CHAMPAGNE = '#DEE0F0';
const GOLD_BRAND = '#273F94';
const GOLD_BRONZE = '#8891C7';
export const BRANDS: Record<RobotBrand, { name: string; tagline: string; description: string; url: string; accent: string }> = {
unitree: {

6
src/lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

View File

@ -35,7 +35,7 @@ export const DEFAULT_PERSONAS: PersonaOption[] = [
id: 'emarati-kandura',
label: 'Emarati Kandura',
description: 'Traditional white robe attire',
colors: { torso: '#f5f1e8', legs: '#f5f1e8' },
colors: { torso: '#FBFBFD', legs: '#FBFBFD' },
},
{
id: 'industrial-vest',