forked from emre/www_projectmycelium_com
- Added new WebP images for different pages (agent, cloud, compute, gpu, network, storage) - Updated benefits section images with optimized WebP versions - Enhanced text styling: - Increased paragraph font size to text-xl on large screens - Adjusted H5 line height for better readability - Updated card paragraph text size to text-base - Refined visual design elements: - Changed cube stroke color to gray-600 for subtler appearance - Adjusted glow effects and gradients to
113 lines
4.8 KiB
TypeScript
113 lines
4.8 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { motion } from "framer-motion";
|
||
import { CubeLight } from "@/components/ui/CubeLight";
|
||
|
||
const stackData = [
|
||
{
|
||
id: "agent",
|
||
title: "Agent Layer",
|
||
descriptionTitle:
|
||
"Your sovereign agent with private memory and permissioned data access—always under your control.",
|
||
description:
|
||
"Choose from a wide library of open-source LLMs, paired with built-in semantic search and retrieval.\nIt coordinates across people, apps, and other agents to plan, create, and execute.\nIt operates inside a compliant legal & financial sandbox, ready for real-world transactions and operations.\nMore than just an assistant—an intelligent partner that learns and does your way.",
|
||
position: "top",
|
||
},
|
||
{
|
||
id: "network",
|
||
title: "Network Layer",
|
||
descriptionTitle:
|
||
"A global, end-to-end encrypted overlay that simply doesn’t break.",
|
||
description:
|
||
"Shortest-path routing moves your traffic the fastest way, every time.\nInstant discovery with integrated DNS, semantic search, and indexing.\nA distributed CDN and edge delivery keep content available and tamper-resistant worldwide.\nBuilt-in tool services and secure coding sandboxes—seamless on phones, desktops, and edge.",
|
||
position: "middle",
|
||
},
|
||
{
|
||
id: "cloud",
|
||
title: "Cloud Layer",
|
||
descriptionTitle:
|
||
"An autonomous, stateless OS that enforces pre-deterministic deployments you define.",
|
||
description:
|
||
"Workloads are cryptographically bound to your private key—location and access are yours.\nNo cloud vendor or middleman in the path: end-to-end ownership and isolation by default.\nGeo-aware placement delivers locality, compliance, and ultra-low latency where it matters.\nEncrypted, erasure-coded storage, decentralized compute and GPU on demand—including LLMs.",
|
||
position: "bottom",
|
||
},
|
||
];
|
||
|
||
export function StackedCubesLight() {
|
||
const [active, setActive] = useState<string | null>("network");
|
||
const [selectedForMobile, setSelectedForMobile] = useState<string | null>("network");
|
||
|
||
const handleCubeClick = (id: string) => {
|
||
setSelectedForMobile((prev) => (prev === id ? null : id));
|
||
};
|
||
|
||
const selectedMobileLayer = stackData.find(
|
||
(layer) => layer.id === selectedForMobile
|
||
);
|
||
|
||
return (
|
||
<div className="flex flex-col items-center relative">
|
||
{/* ✨ Ambient cyan-white gradient background */}
|
||
<div className="absolute inset-0 bg-gradient-to-b from-white via-cyan-50/30 to-white blur-3xl opacity-70 pointer-events-none" />
|
||
<div
|
||
className="relative w-full flex items-center justify-center lg:justify-center min-h-[450px] lg:min-h-[400px]"
|
||
onMouseLeave={() => setActive("network")}
|
||
>
|
||
<motion.div
|
||
className="relative lg:pl-0 pl-6 h-[300px] lg:h-[400px] w-64 sm:w-80 lg:w-96"
|
||
animate={{ y: ["-8px", "8px"] }}
|
||
transition={{
|
||
duration: 4,
|
||
repeat: Infinity,
|
||
repeatType: "reverse",
|
||
ease: "easeInOut",
|
||
}}
|
||
>
|
||
{stackData.map((layer, index) => (
|
||
<div
|
||
key={layer.id}
|
||
className="absolute transition-all duration-500"
|
||
style={{
|
||
top: `calc(${index * 30}% - ${index * 10}px)`,
|
||
zIndex: active === layer.id ? 20 : 10 - index,
|
||
}}
|
||
>
|
||
{/* 🌫 subtle glow behind each cube */}
|
||
<div
|
||
className={`absolute inset-0 blur-2xl rounded-3xl transition-all duration-500 ${
|
||
active === layer.id
|
||
? "bg-cyan-300/20 opacity-20"
|
||
: "bg-cyan-200/20 opacity-20"
|
||
}`}
|
||
/>
|
||
<CubeLight
|
||
title={layer.title}
|
||
descriptionTitle={layer.descriptionTitle}
|
||
description={layer.description}
|
||
isActive={active === layer.id}
|
||
index={index}
|
||
onHover={() => setActive(layer.id)}
|
||
onLeave={() => {}}
|
||
onClick={() => handleCubeClick(layer.id)}
|
||
/>
|
||
</div>
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
|
||
{/* Mobile layer description */}
|
||
{selectedMobileLayer && (
|
||
<div className="lg:hidden w-full max-w-md p-6 -mt-8 bg-white/50 backdrop-blur-xl border border-cyan-100/40 rounded-xl shadow-[0_0_25px_rgba(0,255,255,0.15)]">
|
||
<h4 className="text-black text-lg font-semibold mb-2 text-center drop-shadow-[0_0_6px_rgba(255,255,255,0.6)]">
|
||
{selectedMobileLayer.descriptionTitle}
|
||
</h4>
|
||
<p className="text-cyan-900/80 text-sm leading-relaxed text-center drop-shadow-[0_0_4px_rgba(255,255,255,0.4)]">
|
||
{selectedMobileLayer.description}
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|