forked from ourworld_web/www_engage_os
add all
This commit is contained in:
parent
0eee1629c6
commit
045486365d
@ -10,10 +10,13 @@ import Benefits from '@/components/Benefits'
|
||||
import Cta from '@/components/Cta'
|
||||
import { GlobeDemo } from '@/components/GlobeDemo'
|
||||
import { SpotlightPreview } from '@/components/Spotlight'
|
||||
import { StackSectionPreview } from '@/components/StackSection'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<SpotlightPreview />
|
||||
<StackSectionPreview />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ export function Header() {
|
||||
return (
|
||||
<header>
|
||||
<nav>
|
||||
<Container className="relative z-50 flex justify-between py-8">
|
||||
<Container className="relative z-50 flex justify-between py-4">
|
||||
<div className="relative z-10 flex items-center gap-16">
|
||||
<Link href="/" aria-label="Home">
|
||||
<Logo className="h-10 w-auto" />
|
||||
|
@ -1,10 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Spotlight } from "@/components/ui/spotlight";
|
||||
import { Logomark } from "@/components/Logo";
|
||||
import { Button } from "@/components/Button";
|
||||
|
||||
export function SpotlightPreview() {
|
||||
return (
|
||||
<div className="relative flex h-[40rem] w-full overflow-hidden rounded-md bg-black/[0.96] antialiased md:items-center md:justify-center">
|
||||
<div className="relative flex h-[40rem] w-full overflow-hidden rounded-md bg-transparent antialiased md:items-center md:justify-center">
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-0 [background-size:40px_40px] select-none",
|
||||
@ -17,15 +21,33 @@ export function SpotlightPreview() {
|
||||
fill="white"
|
||||
/>
|
||||
<div className="relative z-10 mx-auto w-full max-w-7xl p-4 pt-20 md:pt-0">
|
||||
<h1 className="bg-opacity-50 bg-gradient-to-b from-neutral-50 to-neutral-400 bg-clip-text text-center text-4xl font-bold text-transparent md:text-7xl">
|
||||
Spotlight <br /> is the new trend.
|
||||
<div className="flex justify-center mb-6">
|
||||
<div className="mb-4 relative rounded-full px-3 py-1 text-sm/6 text-gray-600 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
|
||||
Announcing The New TF Marketplace.{' '}
|
||||
<a href="#" className="font-semibold text-white hover:text-gray-200">
|
||||
<span aria-hidden="true" className="absolute inset-0" />
|
||||
Read more <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="bg-opacity-50 bg-gradient-to-b from-neutral-50 to-neutral-400 bg-clip-text tracking-tighter text-center text-4xl font-semibold text-transparent lg:text-6xl">
|
||||
Built by Everyone <br /> for Everyone.
|
||||
</h1>
|
||||
<p className="mx-auto mt-4 max-w-lg text-center text-base font-normal text-neutral-300">
|
||||
Spotlight effect is a great way to draw attention to a specific part
|
||||
of the page. Here, we are drawing the attention towards the text
|
||||
section of the page. I don't know why but I'm running out of
|
||||
copy.
|
||||
<p className="mx-auto mt-8 max-w-lg text-center text-base lg:text-xl font-light text-neutral-300">
|
||||
ThreeFold is a fully operational, decentralized internet infrastructure – deployed locally, scalable globally, and owned and powered by the people.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-col sm:flex-row justify-center gap-4">
|
||||
<Button href="/login" variant="outline" color="gray">
|
||||
Start Building
|
||||
</Button>
|
||||
<Button href="#" variant="outline" color="gray">
|
||||
Start Hosting
|
||||
</Button>
|
||||
<Button href="#" variant="solid" color="white">
|
||||
How it Works →
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
29
src/components/StackSection.tsx
Normal file
29
src/components/StackSection.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
"use client";
|
||||
|
||||
import { StackedCubes } from "@/components/ui/StackedCubes";
|
||||
|
||||
export function StackSectionPreview() {
|
||||
|
||||
return (
|
||||
<section className="w-full bg-transparent px-4 py-8 sm:px-6 sm:pb-12 lg:px-8">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 lg:gap-16 items-center lg:items-start">
|
||||
{/* Left Column - Text (1/3 width) */}
|
||||
<div className="text-center lg:text-left lg:col-span-1 order-1 lg:order-1">
|
||||
<h2 className="text-xl sm:text-2xl font-semibold tracking-tight leading-tight text-white lg:text-3xl">
|
||||
A Decentralized Infrastructure Layer
|
||||
</h2>
|
||||
<p className="mt-4 sm:mt-6 text-sm font-light text-pretty text-gray-700 lg:text-base">
|
||||
We have built a foundational platform that runs directly on bare metal, offering a scalable solution focused on the essential building blocks of the Internet and Cloud: compute, data, and network.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Right Column - Stacked Cubes (2/3 width) */}
|
||||
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start order-2 lg:order-2">
|
||||
<StackedCubes />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
147
src/components/ui/Cube.tsx
Normal file
147
src/components/ui/Cube.tsx
Normal file
@ -0,0 +1,147 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
interface CubeProps {
|
||||
title: string;
|
||||
descriptionTitle: string;
|
||||
description: string;
|
||||
isActive: boolean;
|
||||
index: number;
|
||||
onHover: () => void;
|
||||
onLeave: () => void;
|
||||
}
|
||||
|
||||
const CubeSvg: React.FC<React.SVGProps<SVGSVGElement> & { index: number }> = ({ index, ...props }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="507"
|
||||
height="234"
|
||||
fill="none"
|
||||
viewBox="0 0 507 234"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill={`url(#cube-gradient-${index})`}
|
||||
d="M491.651 144.747L287.198 227.339C265.219 236.22 241.783 236.22 219.802 227.339L15.3486 144.747C-5.11621 136.479 -5.11621 97.5191 15.3486 89.2539L219.802 6.65884C241.783 -2.21961 265.219 -2.21961 287.198 6.65884L491.651 89.2539C512.116 97.5191 512.116 136.479 491.651 144.747Z"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id={`cube-gradient-${index}`}
|
||||
x1="185.298"
|
||||
x2="185.298"
|
||||
y1="-27.5515"
|
||||
y2="206.448"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop />
|
||||
<stop offset="1" stopColor="#3F3B3E" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export function Cube({ title, descriptionTitle, description, isActive, index, onHover, onLeave }: CubeProps) {
|
||||
return (
|
||||
<div className="relative flex flex-col items-center">
|
||||
<motion.div
|
||||
className="relative cursor-pointer"
|
||||
onMouseEnter={onHover}
|
||||
onMouseLeave={onLeave}
|
||||
style={{
|
||||
zIndex: 10 - index,
|
||||
}}
|
||||
animate={{
|
||||
scale: isActive ? 1.05 : 1,
|
||||
}}
|
||||
transition={{
|
||||
duration: 0.3,
|
||||
ease: "easeOut",
|
||||
}}
|
||||
>
|
||||
{/* SVG Cube */}
|
||||
<CubeSvg
|
||||
index={index}
|
||||
className="w-48 sm:w-64 lg:w-80 h-auto drop-shadow-lg opacity-50"
|
||||
style={{
|
||||
filter: isActive ? 'brightness(1.2) drop-shadow(0 0 20px rgba(156, 163, 175, 0.5))' : 'brightness(0.9)',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Title overlay */}
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<h3
|
||||
className="text-white text-sm lg:text-base font-medium text-center px-4 drop-shadow-lg"
|
||||
style={{
|
||||
transform: 'rotate(0deg) skewX(0deg)',
|
||||
transformOrigin: 'center'
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{/* Description with arrow line - Desktop */}
|
||||
{isActive && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="hidden lg:block absolute left-full top-1/2 -translate-y-1/2 z-50"
|
||||
>
|
||||
{/* Arrow line */}
|
||||
<svg
|
||||
className="absolute left-0 top-1/2 -translate-y-1/2"
|
||||
width="120"
|
||||
height="2"
|
||||
viewBox="0 0 120 2"
|
||||
fill="none"
|
||||
>
|
||||
<line
|
||||
x1="0"
|
||||
y1="1"
|
||||
x2="120"
|
||||
y2="1"
|
||||
stroke="white"
|
||||
strokeWidth="1"
|
||||
opacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* Description text */}
|
||||
<div className="ml-32 w-80">
|
||||
<h4 className="text-white text-base font-semibold mb-2">
|
||||
{descriptionTitle}
|
||||
</h4>
|
||||
<p className="text-white text-sm leading-relaxed font-light">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* Description for Mobile - Below cube */}
|
||||
{isActive && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: 10 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="lg:hidden absolute top-full left-1/2 -translate-x-1/2 mt-8 z-50"
|
||||
>
|
||||
<div className="w-64 sm:w-80 px-4">
|
||||
<h4 className="text-white text-base font-semibold mb-2 text-center">
|
||||
{descriptionTitle}
|
||||
</h4>
|
||||
<p className="text-white text-sm leading-relaxed font-light text-center">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
61
src/components/ui/StackedCubes.tsx
Normal file
61
src/components/ui/StackedCubes.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Cube } from "@/components/ui/Cube";
|
||||
|
||||
const stackData = [
|
||||
{
|
||||
id: "network",
|
||||
title: "Network",
|
||||
descriptionTitle: "Secure Network",
|
||||
description:
|
||||
"End-to-end encrypted overlay network, always looking for the shortest possible path between participants. Logical Internet address securely linked to a private key. Unlimited scale and performance optimizations.",
|
||||
position: "top",
|
||||
},
|
||||
{
|
||||
id: "data",
|
||||
title: "Data",
|
||||
descriptionTitle: "Unbreakable Data",
|
||||
description:
|
||||
"Private, distributed, and AI-native storage with user sovereignty at its core. End-to-end encryption and redundancy, with no central control. Optimized for performance and sustainability, far surpassing traditional cloud.",
|
||||
position: "middle",
|
||||
},
|
||||
{
|
||||
id: "compute",
|
||||
title: "Compute",
|
||||
descriptionTitle: "Bare Metal OS",
|
||||
description:
|
||||
"Zero OS, an efficient and secure operating system, runs directly on the hardware – enabling an autonomous cloud. Can run any Web2, Web3, or AI workload at the edge of the Internet, with more scalability and reliability.",
|
||||
position: "bottom",
|
||||
},
|
||||
];
|
||||
|
||||
export function StackedCubes() {
|
||||
const [active, setActive] = useState<string | null>("compute");
|
||||
|
||||
return (
|
||||
<div className="relative w-full flex items-center justify-center lg:justify-start min-h-[600px] sm:min-h-[700px] lg:min-h-[600px]">
|
||||
<div className="relative ml-0 sm:ml-4 lg:ml-8 flex flex-col items-center -space-y-4 sm:-space-y-6 lg:-space-y-8">
|
||||
{stackData.map((layer, index) => (
|
||||
<div
|
||||
key={layer.id}
|
||||
className="relative"
|
||||
style={{
|
||||
zIndex: 10 - index,
|
||||
}}
|
||||
>
|
||||
<Cube
|
||||
title={layer.title}
|
||||
descriptionTitle={layer.descriptionTitle}
|
||||
description={layer.description}
|
||||
isActive={active === layer.id}
|
||||
index={index}
|
||||
onHover={() => setActive(layer.id)}
|
||||
onLeave={() => setActive("compute")}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -64,6 +64,9 @@
|
||||
|
||||
--container-2xl: 40rem;
|
||||
|
||||
/* 3D perspective utilities */
|
||||
--perspective-1000: 1000px;
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
Loading…
Reference in New Issue
Block a user