28 Commits

Author SHA1 Message Date
f46482e0f4 feat: redesign CallToAction section with bordered card layout
- Replaced animated circle background with bordered container design using gray-700 borders
- Updated background colors to darker theme (#121212 and #090909) for improved contrast
- Changed button styling from white to cyan for primary action
2025-11-07 23:37:44 +01:00
ee6b5458de feat: convert network use cases to horizontal carousel with icons
- Replaced static grid layout with scrollable carousel supporting touch/mouse navigation
- Added hero icons to each use case card for visual hierarchy
- Introduced intro card with navigation controls and updated styling for better mobile experience
2025-11-07 23:34:27 +01:00
100cae988c refactor: adjust network page styling and typography
- Changed heading levels from H3 to H4 in NetworkCapabilities for better hierarchy
- Updated PrimaryFeatures section with darker background and consistent border styling
- Removed text-lg class from paragraph for standard sizing
2025-11-07 23:21:55 +01:00
716915b19e refactor: update background colors in ComputeUseCases component 2025-11-07 23:21:45 +01:00
f04a7eb3cf feat: redesign network page with improved layout and typography
- Replaced hardcoded text elements with reusable typography components (H2, H3, P, Eyebrow, CT, CP)
- Updated NetworkCapabilities section with dark theme, two-column layout, and visual separators
- Added consistent border styling and spacing across Features and Hero sections
2025-11-07 23:13:40 +01:00
de89539de1 feat: redesign storage use cases section with tabbed layout
- Replaced StorageUseCases with StorageUseCasesNew component featuring interactive tabs
- Implemented two-column layout with tab content on left and image on right
- Added three use case categories: distributed storage, data sovereignty, and content distribution
2025-11-07 23:13:27 +01:00
1851c2d6fb refactor: adjust spacing and styling in compute pages
- Reduced vertical spacing between header and content sections for tighter layout
- Changed border radius from rounded-3xl to rounded-md for consistent styling
- Added hover effect with gradient background to architecture cards
2025-11-07 23:13:18 +01:00
451c1f5c56 feat: redesign storage page with interactive components and dark theme
- Added interactive architecture section with tabbed navigation and smooth transitions
- Implemented horizontal scrolling capabilities carousel with image backgrounds
- Updated call-to-action section with bordered container layout and improved button styling
- Replaced core value section with animated self-healing storage features
- Applied consistent dark theme (#111111, #121212) with cyan accents across all storage components
2025-11-07 22:28:03 +01:00
0b6bcfedd0 chore: archive unused images and add storage feature components
- Moved 35 legacy image assets to archive directory for cleanup
- Created StorageCoreValue component showcasing Digital Me blueprint with logo grid
- Added Encrypted animation component visualizing secure storage with data movement
2025-11-07 20:53:56 +01:00
9bccc89309 feat: make mobile menu background transparent on large screens 2025-11-07 20:49:31 +01:00
73abd593e3 fix: update spacing and border radius for consistent styling
- Changed CloudBluePrint container from pb-12 to py-12 for balanced vertical padding
- Reduced ComputeOverview card border radius from rounded-3xl to rounded-md for uniformity
2025-11-07 20:30:49 +01:00
1f267b057d fix: update navigation links to use clean URLs and close mobile menu on click
- Removed hash-based routing (/#/) in favor of clean URL paths across all navigation links
- Added onClick handlers to close mobile menu when navigation items are clicked
2025-11-07 17:49:20 +01:00
2b5f20f1e9 fix: update navigation links to use hash-based routing 2025-11-07 17:46:07 +01:00
aca13e275b style: lighten border colors from gray-200 to gray-100 2025-11-07 17:28:33 +01:00
e8c424539e fix: correct GitHub icon path to use public directory 2025-11-07 17:17:28 +01:00
912ea4436a feat: update deployment button text to "Deploy Now" 2025-11-07 17:15:54 +01:00
53fd05e6b7 fix: correct logomark image path in footer 2025-11-07 17:13:55 +01:00
5a023651b5 fix: switch from BrowserRouter to HashRouter for static hosting compatibility 2025-11-07 17:10:52 +01:00
b9ba2bab06 refactor: remove unused imports and standardize color prop values
- Removed unused Container, SectionHeader, Small, CT, and CP imports from component files
- Changed color prop from "darkSecondary" to "secondary" for consistency with design system
2025-11-07 17:01:17 +01:00
852d9bfc3e feat: convert ComputeOverview section to light mode theme
- Updated background colors from dark (gray-950) to white with subtle accents
- Modified text colors from light/white to dark gray for improved readability
- Added horizontal border lines and adjusted card styling with light shadows and hover effects
2025-11-07 16:58:50 +01:00
cd3ce54a40 feat: update compute code tabs color scheme from indigo to cyan 2025-11-07 16:54:47 +01:00
6f4f451144 feat: redesign compute page sections with interactive code examples
- Replaced static use cases section with tabbed interface showing AI/ML, application hosting, and edge compute capabilities
- Added ComputeCodeTabs component with interactive code examples (train.py, deploy.yaml, edge.ts)
- Updated CallToAction section with new bordered layout and restructured CTA buttons for hosting and deploying
2025-11-07 16:54:04 +01:00
4b6c8d8327 refactor: simplify benefits section layout and styling
- Replaced complex grid layout with centered 4-column design
- Switched from images to Heroicons for consistent iconography
- Removed unused animation components and dependencies (cobe, motion)
2025-11-07 16:25:43 +01:00
a61267944d refactor: redesign compute architecture section with animated mesh topology
- Replaced simple icon-based architecture cards with interactive animated grid layout
- Added three new SVG animations (MeshNetworking, Deterministic, SovereignCompute) to visualize system concepts
- Updated border colors from gray-600 to gray-800 for consistent dark theme across cloud hosting page
2025-11-07 15:58:11 +01:00
46d02fca47 feat: improve carousel scroll behavior to align fourth card with viewport edge 2025-11-07 13:55:44 +01:00
6779218da6 refactor: redesign ComputeDesign component layout
- Converted feature list to stats-style cards with centered content and icon-first layout
- Replaced vertical Container layout with full-width bordered grid design
- Simplified text content to value/name pairs and updated icons
2025-11-07 13:49:18 +01:00
04b94367a9 feat: improve cloud hosting page layout and spacing
- Restructured grid from 2-column to 5-column layout for better content distribution
- Adjusted spacing and margins throughout for improved visual hierarchy
- Updated heading component from h3 to H4 for consistent typography
2025-11-07 13:28:05 +01:00
cdd6e3104b feat: add horizontal scrolling capabilities section for compute page
- Created new ComputeCapabilitiesNew component with card-based slider showcasing containers, VMs, and native Linux workloads
- Implemented smooth horizontal scroll navigation with arrow controls and snap-to-card behavior
- Added intro card with overview text and navigation controls, followed by capability cards with icons and descriptions
2025-11-07 13:19:13 +01:00
98 changed files with 2744 additions and 855 deletions

View File

Before

Width:  |  Height:  |  Size: 497 KiB

After

Width:  |  Height:  |  Size: 497 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

Before

Width:  |  Height:  |  Size: 431 KiB

After

Width:  |  Height:  |  Size: 431 KiB

View File

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 878 KiB

After

Width:  |  Height:  |  Size: 878 KiB

View File

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 223 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 938 KiB

After

Width:  |  Height:  |  Size: 938 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 316 KiB

After

Width:  |  Height:  |  Size: 316 KiB

View File

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 327 KiB

After

Width:  |  Height:  |  Size: 327 KiB

View File

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
public/images/encrypted.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 KiB

4
public/images/github.svg Normal file
View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" aria-label="GitHub" viewBox="0 0 512 512" id="github">
<rect width="512" height="512" fill="#1B1817" rx="15%"></rect>
<path fill="#fff" d="M335 499c14 0 12 17 12 17H165s-2-17 12-17c13 0 16-6 16-12l-1-50c-71 16-86-28-86-28-12-30-28-37-28-37-24-16 1-16 1-16 26 2 40 26 40 26 22 39 59 28 74 22 2-17 9-28 16-35-57-6-116-28-116-126 0-28 10-51 26-69-3-6-11-32 3-67 0 0 21-7 70 26 42-12 86-12 128 0 49-33 70-26 70-26 14 35 6 61 3 67 16 18 26 41 26 69 0 98-60 120-117 126 10 8 18 24 18 48l-1 70c0 6 3 12 16 12z"></path>
</svg>

After

Width:  |  Height:  |  Size: 563 B

BIN
public/images/ipfs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 KiB

BIN
public/images/s3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 KiB

View File

@@ -1,4 +1,4 @@
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { HashRouter, Routes, Route } from 'react-router-dom';
import { Layout } from './components/Layout'; import { Layout } from './components/Layout';
import { lazy, Suspense } from 'react'; import { lazy, Suspense } from 'react';
@@ -13,7 +13,7 @@ const GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
function App() { function App() {
return ( return (
<BrowserRouter> <HashRouter>
<Suspense fallback={<div>Loading...</div>}> <Suspense fallback={<div>Loading...</div>}>
<Routes> <Routes>
<Route path="/" element={<Layout />}> <Route path="/" element={<Layout />}>
@@ -28,7 +28,7 @@ function App() {
</Route> </Route>
</Routes> </Routes>
</Suspense> </Suspense>
</BrowserRouter> </HashRouter>
) )
} }

View File

@@ -8,7 +8,7 @@ export function Footer() {
<div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-8"> <div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-8">
<div> <div>
<div className="flex items-center text-gray-900"> <div className="flex items-center text-gray-900">
<img src="/src/images/logomark.svg" alt="Mycelium Logomark" className="h-15 w-15 flex-none" /> <img src="/images/logomark.svg" alt="Mycelium Logomark" className="h-15 w-15 flex-none" />
<div className="ml-4"> <div className="ml-4">
<p className="text-base font-semibold">Project Mycelium</p> <p className="text-base font-semibold">Project Mycelium</p>
<p className="mt-1 text-sm">Unleash the Power of Decentralization</p> <p className="mt-1 text-sm">Unleash the Power of Decentralization</p>
@@ -31,7 +31,7 @@ export function Footer() {
</div> </div>
<div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-100 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6"> <div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-100 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6">
<div className="relative flex h-16 w-16 flex-none items-center justify-center"> <div className="relative flex h-16 w-16 flex-none items-center justify-center">
<img src="/src/images/github.svg" alt="GitHub" className="h-16 w-16" /> <img src="/images/github.svg" alt="GitHub" className="h-16 w-16" />
</div> </div>
<div className="ml-4 lg:w-72"> <div className="ml-4 lg:w-72">
<p className="text-base font-semibold text-gray-900"> <p className="text-base font-semibold text-gray-900">
@@ -46,7 +46,7 @@ export function Footer() {
</div> </div>
</div> </div>
</div> </div>
<div className="flex flex-col items-center border-t border-gray-200 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6"> <div className="flex flex-col items-center border-t border-gray-100 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6">
<p className="mt-6 text-sm text-gray-500 md:mt-0"> <p className="mt-6 text-sm text-gray-500 md:mt-0">
&copy; Copyright{' '} &copy; Copyright{' '}
<a href="https://www.threefold.io" target="_blank" rel="noopener noreferrer" className="hover:text-cyan-500 transition-colors"> <a href="https://www.threefold.io" target="_blank" rel="noopener noreferrer" className="hover:text-cyan-500 transition-colors">

View File

@@ -30,7 +30,7 @@ export function Header() {
return ( return (
<header className="bg-white"> <header className="bg-white">
<nav className="border-b border-gray-200"> <nav className="border-b border-gray-100">
<Container className="flex bg-transparent justify-between py-4"> <Container className="flex bg-transparent justify-between py-4">
<div className="relative z-10 flex items-center gap-16"> <div className="relative z-10 flex items-center gap-16">
<Link to="/" aria-label="Home"> <Link to="/" aria-label="Home">
@@ -69,7 +69,7 @@ export function Header() {
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
Start Deployment Deploy Now
</Button> </Button>
<Button to="/download" variant="solid" color="cyan"> <Button to="/download" variant="solid" color="cyan">
Get Mycelium Connector Get Mycelium Connector
@@ -90,7 +90,7 @@ export function Header() {
</nav> </nav>
<Dialog as="div" className="lg:hidden" open={mobileMenuOpen} onClose={setMobileMenuOpen}> <Dialog as="div" className="lg:hidden" open={mobileMenuOpen} onClose={setMobileMenuOpen}>
<div className="fixed inset-0 z-10" /> <div className="fixed inset-0 z-10" />
<Dialog.Panel className="fixed inset-y-0 right-0 z-10 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10"> <Dialog.Panel className="fixed inset-y-0 right-0 z-10 w-full overflow-y-auto lg:bg-transparent bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Link to="#" className="-m-1.5 p-1.5"> <Link to="#" className="-m-1.5 p-1.5">
<span className="sr-only">Mycelium</span> <span className="sr-only">Mycelium</span>
@@ -117,6 +117,7 @@ export function Header() {
key={item.name} key={item.name}
to={item.href} to={item.href}
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50" className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50"
onClick={() => setMobileMenuOpen(false)}
> >
{item.name} {item.name}
</Link> </Link>
@@ -124,12 +125,14 @@ export function Header() {
<Link <Link
to="/network" to="/network"
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50" className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50"
onClick={() => setMobileMenuOpen(false)}
> >
Network Network
</Link> </Link>
<Link <Link
to="/agents" to="/agents"
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50" className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50"
onClick={() => setMobileMenuOpen(false)}
> >
Agents Agents
</Link> </Link>
@@ -142,10 +145,11 @@ export function Header() {
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="w-full" className="w-full"
onClick={() => setMobileMenuOpen(false)}
> >
Start Deployment Start Deployment
</Button> </Button>
<Button to="/download" variant="solid" color="cyan" className="mt-4 w-full"> <Button to="/download" variant="solid" color="cyan" className="mt-4 w-full" onClick={() => setMobileMenuOpen(false)}>
Get Mycelium Connector Get Mycelium Connector
</Button> </Button>
</div> </div>

View File

@@ -106,7 +106,7 @@ export const H5 = createTextComponent(
) )
export const Eyebrow = createTextComponent( export const Eyebrow = createTextComponent(
'h2', 'h2',
'text-base/7 font-semibold tracking-[0.18em] uppercase', 'text-base/7 font-semibold uppercase tracking-[0.16em]',
{ color: 'accent' } { color: 'accent' }
) )
export const SectionHeader = createTextComponent( export const SectionHeader = createTextComponent(

View File

@@ -49,7 +49,7 @@ export function AgentComponents() {
<div className="mx-auto mt-16 max-w-6xl overflow-x-auto"> <div className="mx-auto mt-16 max-w-6xl overflow-x-auto">
<table className="w-full table-auto border-collapse text-left text-sm text-gray-700"> <table className="w-full table-auto border-collapse text-left text-sm text-gray-700">
<thead> <thead>
<tr className="bg-cyan-50 border-b border-gray-200"> <tr className="bg-cyan-50 border-b border-gray-100">
<th className="py-3 px-4 font-semibold text-gray-900">Component</th> <th className="py-3 px-4 font-semibold text-gray-900">Component</th>
<th className="py-3 px-4 font-semibold text-gray-900">Purpose</th> <th className="py-3 px-4 font-semibold text-gray-900">Purpose</th>
<th className="py-3 px-4 font-semibold text-gray-900">Backed By</th> <th className="py-3 px-4 font-semibold text-gray-900">Backed By</th>

View File

@@ -8,7 +8,7 @@ export function AgentHeroAlt() {
<div className=""> <div className="">
{/* Boxed container */} {/* Boxed container */}
<div <div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-200 bg-white overflow-hidden bg-contain bg-right bg-no-repeat" className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/agents.webp')", backgroundSize: "contain" }} style={{ backgroundImage: "url('/images/agents.webp')", backgroundSize: "contain" }}
> >
{/* Inner padding */} {/* Inner padding */}
@@ -36,8 +36,8 @@ export function AgentHeroAlt() {
</div> </div>
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div> </div>
) )
} }

View File

@@ -17,7 +17,7 @@ export function CloudBluePrint() {
<section className="w-full max-w-8xl mx-auto bg-transparent"> <section className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Boxed container */} {/* ✅ Boxed container */}
<div className="max-w-7xl bg-white mx-auto pb-12 border border-t-0 border-b-0 border-gray-200"> <div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-100">
<Container> <Container>
<div className="mx-auto max-w-4xl sm:text-center"> <div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-500">Featured Blueprint</Eyebrow> <Eyebrow className="text-cyan-500">Featured Blueprint</Eyebrow>
@@ -54,8 +54,8 @@ export function CloudBluePrint() {
</div> </div>
{/* ✅ Bottom line + bottom spacer */} {/* ✅ Bottom line + bottom spacer */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200 bg-transparent" /> <div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100 bg-transparent" />
</section> </section>
); );
} }

View File

@@ -243,11 +243,11 @@ export function CloudFeaturesLight() {
return ( return (
<div className=""> <div className="">
{/* ✅ Top horizontal line with spacing */} {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-200" /> <div className="w-full border-t border-l border-r border-gray-100" />
{/* ✅ Boxed container (border-x only) */} {/* ✅ Boxed container (border-x only) */}
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-200 bg-white"> <div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white">
<section className="px-6 py-16 lg:py-16"> <section className="px-6 py-16 lg:py-16">
<Container> <Container>
<div className="max-w-4xl mx-auto items-center text-center"> <div className="max-w-4xl mx-auto items-center text-center">
@@ -274,10 +274,10 @@ export function CloudFeaturesLight() {
</div> </div>
{/* ✅ Bottom horizontal line */} {/* ✅ Bottom horizontal line */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
{/* ✅ Bottom spacer matching hero */} {/* ✅ Bottom spacer matching hero */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div> </div>
) )
} }

View File

@@ -6,7 +6,7 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
<div className=""> <div className="">
{/* Boxed container */} {/* Boxed container */}
<div <div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-200 bg-white overflow-hidden bg-contain bg-right bg-no-repeat" className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/cloudhero4.webp')", backgroundSize: "contain" }} style={{ backgroundImage: "url('/images/cloudhero4.webp')", backgroundSize: "contain" }}
> >
{/* Inner padding */} {/* Inner padding */}
@@ -44,8 +44,8 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div> </div>
) )
} }

View File

@@ -7,7 +7,7 @@ import {
} from '@headlessui/react' } from '@headlessui/react'
import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline' import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline'
import { Eyebrow, H3 } from "@/components/Texts" import { Eyebrow, H3, H4 } from "@/components/Texts"
const product = { const product = {
@@ -42,33 +42,35 @@ export function CloudHostingNew() {
return ( return (
<div className="bg-[#121212] text-white"> <div className="bg-[#121212] text-white">
{/* ✅ Top horizontal line with spacing */} {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-600"></div> <div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
<div className="w-full border-t border-l border-r border-gray-600" /> <div className="w-full border-t border-l border-r border-gray-800" />
{/* ✅ MAIN CONTENT */} {/* ✅ MAIN CONTENT */}
<main className="mx-auto max-w-7xl px-6 lg:px-12 py-12 border border-t-0 border-b-0 border-gray-600"> <main className="mx-auto max-w-7xl px-6 lg:px-12 py-12 border border-t-0 border-b-0 border-gray-800">
<div className="mx-auto max-w-2xl lg:max-w-none"> <div className="mx-auto max-w-2xl lg:max-w-none">
{/* ✅ Product Section */} {/* ✅ Product Section */}
<div className="lg:grid lg:grid-cols-2 lg:items-start lg:gap-x-8"> <div className="lg:grid lg:grid-cols-5 lg:items-start lg:gap-x-8">
{/* ✅ Image */} {/* ✅ Image */}
<img alt="Mycelium Cloud" src="/images/cloudhosting.webp" className="aspect-square w-[600px] object-cover" /> <div className="lg:col-span-2 lg:mt-8 mt-2">
<img alt="Mycelium Cloud" src="/images/cloudhosting.webp" className="aspect-square w-full object-cover" />
</div>
{/* ✅ Product info */} {/* ✅ Product info */}
<div className="mt-10 px-4 sm:mt-16 sm:px-0 lg:mt-0"> <div className="mt-8 px-4 sm:px-0 lg:mt-0 lg:col-span-3">
<Eyebrow>{product.subtitle}</Eyebrow> <Eyebrow>{product.subtitle}</Eyebrow>
<h3 className="lg:text-4xl text-3xl text-white">{product.name}</h3> <H4 className=" text-white">{product.name}</H4>
<div className="mt-6 text-gray-300 text-xl" <div className="mt-4 text-gray-300 text-xl"
dangerouslySetInnerHTML={{ __html: product.description }} dangerouslySetInnerHTML={{ __html: product.description }}
/> />
{/* ✅ Details accordion */} {/* ✅ Details accordion */}
<section className="mt-8"> <section className="mt-6">
<div className="divide-y divide-gray-800 border-t border-cyan-500"> <div className="divide-y divide-gray-800 border-t border-cyan-500">
{product.details.map((detail) => ( {product.details.map((detail) => (
<Disclosure key={detail.name} as="div"> <Disclosure key={detail.name} as="div">
@@ -96,8 +98,8 @@ export function CloudHostingNew() {
</main> </main>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-600" /> <div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-600"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</div> </div>
) )
} }

View File

@@ -41,11 +41,11 @@ export function CloudUseCases() {
<section className="w-full max-w-8xl mx-auto bg-transparent"> <section className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Top horizontal line with spacing */} {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-200" /> <div className="w-full border-t border-l border-r border-gray-100" />
{/* ✅ Inner boxed container */} {/* ✅ Inner boxed container */}
<div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-200"> <div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-100">
<Container> <Container>
<div className="mx-auto max-w-4xl sm:text-center"> <div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-500">USE CASES</Eyebrow> <Eyebrow className="text-cyan-500">USE CASES</Eyebrow>
@@ -70,7 +70,7 @@ export function CloudUseCases() {
{useCases.map((useCase) => ( {useCases.map((useCase) => (
<li <li
key={useCase.title} key={useCase.title}
className="rounded-md border border-gray-200 bg-white p-6 transition-all duration-300 className="rounded-md border border-gray-100 bg-white p-6 transition-all duration-300
hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 flex flex-col" hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 flex flex-col"
> >
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@@ -104,8 +104,8 @@ export function CloudUseCases() {
</div> </div>
{/* ✅ Bottom horizontal line + spacing */} {/* ✅ Bottom horizontal line + spacing */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</section> </section>
) )
} }

View File

@@ -1,42 +1,55 @@
import { CircleBackground } from '../../components/CircleBackground' "use client";
import { Container } from '@/components/Container'
import { Button } from '@/components/Button' import { Container } from "@/components/Container";
import { Button } from "@/components/Button";
export function CallToAction() { export function CallToAction() {
return ( return (
<section <section className="relative overflow-hidden bg-gray-900">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-[#090909] mx-auto py-6 border border-t-0 border-b-0 border-gray-700"></div>
<div className="w-full border-t border-l border-r border-gray-700" />
{/* ✅ Main boxed area */}
<div
id="get-started" id="get-started"
className="relative overflow-hidden bg-gray-900 py-20 sm:py-28" className="relative py-18 max-w-7xl mx-auto bg-[#090909] border border-t-0 border-b-0 border-gray-700"
> >
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<CircleBackground color="#06b6d4" className="animate-spin-slower" />
</div>
<Container className="relative"> <Container className="relative">
<div className="mx-auto max-w-2xl text-center"> <div className="mx-auto max-w-3xl text-center">
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl"> <h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
Choose How You Want to Start Choose How You Want to Start
</h2> </h2>
<p className="mt-6 text-lg text-gray-300"> <p className="mt-6 text-lg text-gray-300">
Run workloads using Mycelium Cloud, or host your own compute node. Host your own node to contribute capacity or deploy workloads using the Mycelium Cloud.
Both use the same deterministic execution fabric. You dont need to host before deploying, and you dont need to deploy before hosting.
</p> </p>
<div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4">
<Button to="/download" variant="solid" color="white"> {/* ✅ Two cards, stacked center with spacing */}
Deploy Workloads <div className="mt-10 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/host" variant="solid" color="cyan" className="mt-4">
Host a Node
</Button> </Button>
<Button </div>
to="https://threefold.info/mycelium_network/docs/"
as="a" <div className="flex flex-col items-center text-center max-w-xs">
target="_blank" <Button to="/cloud" variant="outline" color="white" className="mt-4">
variant="outline" Start Deploying
color="white"
>
Host A Node
</Button> </Button>
</div> </div>
</div> </div>
</div>
</Container> </Container>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-700" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-700 bg-transparent" />
</section> </section>
) );
} }

View File

@@ -1,53 +1,125 @@
import { "use client";
LockClosedIcon,
CpuChipIcon,
AdjustmentsHorizontalIcon,
} from '@heroicons/react/24/solid'
import { Container } from '@/components/Container'
import { Eyebrow, H3, CT, CP } from '@/components/Texts'
const architecture = [ import { Eyebrow, H3, P } from "@/components/Texts";
import MeshNetworking from "./animations/Meshnetworking";
import Deterministic from "./animations/Deterministic";
import SovereignCompute from "./animations/SovereignCompute";
const deterministicCards = [
{ {
name: 'Mesh Networking', id: "core",
description: 'Secure connectivity across all nodes.', eyebrow: "ARCHITECTURE",
icon: LockClosedIcon, title: "Deterministic by Design",
description:
"Every workload runs exactly as declared: no drift, no hidden state, no surpriseSecure connectivity across all nodes..",
animation: null,
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
custom: true,
noBorder: true,
}, },
{ {
name: 'Sovereign Compute', id: "crypto",
description: 'Execution only on hardware you control.', title: "Mesh Networking",
icon: CpuChipIcon, description:
"Secure connectivity across all nodes.",
animation: <MeshNetworking className="lg:-mt-12" />, // ✅ NEW
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-tr-4xl max-lg:rounded-t-4xl",
innerRounded: "lg:rounded-tr-[calc(2rem+1px)] max-lg:rounded-t-[calc(2rem+1px)]",
}, },
{ {
name: 'Deterministic Orchestration', id: "stateless",
description: 'Workloads deploy and update predictably.', title: "Deterministic Orchestration",
icon: AdjustmentsHorizontalIcon, description:
"Workloads deploy and update predictably.",
animation: <Deterministic className="lg:-mt-12" />, // ✅ NEW
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-bl-4xl max-lg:rounded-b-4xl",
innerRounded: "lg:rounded-bl-[calc(2rem+1px)] max-lg:rounded-b-[calc(2rem+1px)]",
}, },
] {
id: "healing",
title: "Automatic healing and recovery",
description:
"Self-repairing processes ensure workloads stay available and consistent.",
animation: <SovereignCompute />, // ✅ NEW
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-br-4xl max-lg:rounded-b-4xl",
innerRounded: "lg:rounded-br-[calc(2rem+1px)] max-lg:rounded-b-[calc(2rem+1px)]",
},
];
export function ComputeArchitecture() { export function ComputeArchitecture() {
return ( return (
<section className="bg-white py-24 sm:py-32"> <section className="relative w-full bg-[#171717] overflow-hidden">
<Container> {/* ✅ Top horizontal line */}
<div className="mx-auto max-w-3xl text-center"> <div className="max-w-7xl bg-[#171717] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
<Eyebrow>ARCHITECTURE</Eyebrow> <div className="w-full border-t border-l border-r border-gray-800" />
<H3 className="mt-4 text-gray-900">HOW IT WORKS</H3>
<div className="mx-auto bg-[#111111] max-w-2xl px-6 lg:max-w-7xl lg:px-10 border border-t-0 border-b-0 border-gray-800">
<div className="grid grid-cols-1 gap-6 pt-6 lg:grid-cols-6 lg:grid-rows-2 pb-6">
{deterministicCards.map((card) => (
<div
key={card.id}
className={`relative ${card.colSpan} ${card.rowSpan} transition-transform duration-300 hover:scale-102 group`}
>
{/* ✅ Disable wrapper on first card */}
{!card.noBorder && (
<div
className={`absolute inset-0 rounded-md border border-gray-800 bg-[#111212] ${card.rounded} group-hover:bg-linear-to-br from-gray-900 to-gray-800`}
/>
)}
<div
className={`relative flex lg:h-90 flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] ${card.innerRounded}`}
>
{/* ✅ SVG Animation instead of images */}
{card.animation ? (
<div className="lg:h-64 h-48 w-full overflow-hidden bg-transparent flex items-center">
<div className="w-full h-full">
{card.animation}
</div>
</div>
) : (
<div className="h-48 w-full flex items-center justify-center bg-transparent" />
)}
<div className="px-8 pt-4 pb-6">
{card.custom ? (
<>
{card.eyebrow && <Eyebrow>{card.eyebrow}</Eyebrow>}
<H3 className="mt-2 text-white">{card.title}</H3>
<P className="mt-4 max-w-lg text-gray-200">{card.description}</P>
</>
) : (
<>
<p className="mt-1 text-lg font-medium lg:text-xl tracking-tight text-white">
{card.title}
</p>
<p className="mt-1 max-w-lg text-sm/6 text-gray-200">
{card.description}
</p>
</>
)}
</div>
</div> </div>
<div className="mx-auto mt-16 max-w-5xl"> {!card.noBorder && (
<dl className="grid grid-cols-1 gap-12 text-gray-600 sm:grid-cols-2 lg:grid-cols-3"> <div
{architecture.map((item) => ( className={`pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 ${card.rounded}`}
<div key={item.name} className="relative pl-12">
<item.icon
aria-hidden="true"
className="absolute left-0 top-1 size-6 text-cyan-600"
/> />
<CT className="font-semibold text-gray-900">{item.name}</CT> )}
<CP className="mt-1 text-gray-600">{item.description}</CP>
</div> </div>
))} ))}
</dl>
</div> </div>
</Container> </div>
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl mx-auto py-6 border-x border-gray-800 border-t-0 border-b-0" />
</section> </section>
) );
} }

View File

@@ -0,0 +1,117 @@
"use client";
import { useRef } from "react";
import { Eyebrow, CP, CT, H5 } from "@/components/Texts";
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
const capabilities = [
{
isIntro: true,
eyebrow: "CAPABILITIES",
title: "What You Can Run",
description:
"Mycelium Compute supports multiple workload types on a single execution fabric, from legacy VMs to modern Kubernetes clusters.",
},
{
title: "Containers & K3s",
description:
"Deploy services, web apps, and APIs with full Kubernetes compatibility.",
icon: (
<div className="flex items-center justify-center">
<img src="/images/kubernetes.webp" alt="Kubernetes" className="h-full w-full object-cover mb-2" />
</div>
),
},
{
title: "Virtual Machines",
description:
"Run legacy apps and specialized stacks with secure boot and attestation.",
icon: (
<div className="flex items-center justify-center">
<img src="/images/vm.webp" alt="Virtual Machines" className="h-full w-full object-cover mb-2" />
</div>
),
},
{
title: "Native Linux Workloads",
description:
"Execute agents, batch jobs, and custom tooling statelessly across the grid.",
icon: (
<div className="flex items-center justify-center">
<img src="/images/linux.png" alt="Linux" className="h-full w-full object-cover mb-2" />
</div>
),
},
];
export function ComputeCapabilitiesNew() {
const sliderRef = useRef<HTMLUListElement>(null);
const scrollLeft = () => sliderRef.current?.scrollBy({ left: -400, behavior: "smooth" });
const scrollRight = () => sliderRef.current?.scrollBy({ left: 400, behavior: "smooth" });
return (
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
<div className="w-full border-t border-l border-r border-gray-800" />
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-800 bg-[#111111] overflow-hidden">
{/* Horizontal Slider — shows part of next card */}
<ul
ref={sliderRef}
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
>
{capabilities.map((item, idx) => (
<li
key={idx}
className={`snap-start shrink-0 w-[85%] sm:w-[50%] lg:w-[33%] border border-gray-800 p-10 relative ${item.isIntro ? 'bg-[#1b1b1b]' : 'bg-[#111]/60'}`}
>
{/* First card with arrows */}
{item.isIntro ? (
<div className="flex flex-col justify-between h-full ">
<div>
<Eyebrow className="">{item.eyebrow}</Eyebrow>
<H5 className="text-white mt-4 lg:text-2xl text-xl">{item.title}</H5>
<p className="mt-4 text-gray-400 lg:text-lg text-sm leading-relaxed">{item.description}</p>
</div>
{/* Arrows inside first card */}
<div className="flex items-center gap-x-4 mt-2">
<a
href="#"
className="inline-flex items-center gap-1 text-cyan-400 hover:text-cyan-300 text-sm font-medium mr-auto"
>
Learn more
</a>
<button
onClick={scrollLeft}
className="h-8 w-8 flex items-center justify-center border border-gray-700 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowBackOutline className="text-gray-300" size={16} />
</button>
<button
onClick={scrollRight}
className="h-8 w-8 flex items-center justify-center border border-gray-700 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowForwardOutline className="text-gray-300" size={16} />
</button>
</div>
</div>
) : (
<>
{item.icon}
<CT className="text-lg font-semibold text-white mt-4">{item.title}</CT>
<CP className="mt-2 text-gray-400 leading-snug">{item.description}</CP>
</>
)}
</li>
))}
</ul>
</div>
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
</section>
);
}

View File

@@ -0,0 +1,112 @@
"use client";
import { useState } from "react";
const files = [
{
id: "train",
label: "train.py",
code: `from mycelium import GPUCluster, Dataset
# connect to private GPU cluster
cluster = GPUCluster("secure://my-node")
# load training data
data = Dataset.load("s3://models/private-dataset")
# run a reproducible training job
job = cluster.train(
model="resnet50",
dataset=data,
epochs=40,
deterministic=True
)
job.save("s3://models/checkpoints/resnet-private")`,
},
{
id: "deploy",
label: "deploy.yaml",
code: `apiVersion: mycelium/v1
kind: Service
metadata:
name: vector-api
spec:
image: registry.mycelium/vector:latest
replicas: 3
selfHeal: true
mesh: private
resources:
gpu: 1
cpu: 2
memory: 4Gi`,
},
{
id: "edge",
label: "edge.ts",
code: `import { EdgeClient } from "@mycelium/sdk"
// deploy inference to nearest node
const client = new EdgeClient()
await client.deploy({
model: "resnet-private",
region: "eu-home-nodes",
autoscale: true,
cache: "on-device"
})`,
},
];
export function ComputeCodeTabs() {
const [active, setActive] = useState("train");
const file = files.find((f) => f.id === active)!;
return (
<div className="sm:px-6 lg:px-0">
<div className="relative isolate overflow-hidden bg-cyan-600 px-6 pt-8 sm:mx-auto sm:max-w-2xl sm:rounded-md sm:pt-16 sm:pr-0 sm:pl-16 lg:mx-0 lg:max-w-none">
<div
aria-hidden="true"
className="absolute -inset-y-px -left-3 -z-10 w-full origin-bottom-left skew-x-[-30deg] bg-cyan-500 opacity-20 ring-1 ring-white ring-inset"
/>
<div className="mx-auto max-w-2xl sm:mx-0 sm:max-w-none">
<div className="w-screen overflow-hidden rounded-tl-xl bg-gray-900 ring-1 ring-white/10">
{/* FILE TABS */}
<div className="flex bg-gray-800/40 ring-1 ring-white/5">
<div className="-mb-px flex text-sm font-medium text-gray-400">
{files.map((f) => (
<button
key={f.id}
onClick={() => setActive(f.id)}
className={`px-4 py-2 border-r border-white/10 ${
active === f.id
? "border-b border-b-white/20 bg-white/5 text-white"
: ""
}`}
>
{f.label}
</button>
))}
</div>
</div>
{/* CODE BLOCK */}
<div className="px-6 pt-6 pb-14 font-mono text-xs leading-relaxed text-gray-200 whitespace-pre overflow-x-auto">
{file.code}
</div>
</div>
</div>
<div
aria-hidden="true"
className="pointer-events-none absolute inset-0 ring-1 ring-white/10 ring-inset sm:rounded-3xl"
/>
</div>
</div>
);
}

View File

@@ -1,56 +1,54 @@
import { CP, CT } from '@/components/Texts'
import { import {
ShieldCheckIcon,
ArrowPathIcon, ArrowPathIcon,
RocketLaunchIcon, GlobeAltIcon,
ShieldCheckIcon,
} from '@heroicons/react/24/solid' } from '@heroicons/react/24/solid'
import { Container } from '@/components/Container'
import { Eyebrow, H3, P, CT, CP } from '@/components/Texts'
const features = [ const stats = [
{ {
id: 1,
name: 'Cryptographically verified deployments', name: 'Cryptographically verified deployments',
description: 'Every cluster state is signed and checksummed to guarantee truth.', value: 'Signed & Checksummed',
icon: ShieldCheckIcon, icon: ShieldCheckIcon,
}, },
{ {
id: 2,
name: 'Stateless execution that scales anywhere', name: 'Stateless execution that scales anywhere',
description: 'Run workloads on any node, region, or edge without manual orchestration.', value: 'Global Scaling',
icon: RocketLaunchIcon, icon: GlobeAltIcon,
}, },
{ {
id: 3,
name: 'Automatic healing and recovery', name: 'Automatic healing and recovery',
description: 'Self-repairing processes ensure workloads stay available and consistent.', value: 'Self-Repairing',
icon: ArrowPathIcon, icon: ArrowPathIcon,
}, },
] ]
export function ComputeDesign() { export function ComputeDesign() {
return ( return (
<section className="bg-white py-24 sm:py-32"> <div className="">
<Container>
<div className="mx-auto max-w-3xl sm:text-center">
<Eyebrow>CORE VALUE</Eyebrow>
<H3 className="mt-4 text-gray-900">Deterministic by Design</H3>
<P className="mt-6 text-gray-600">
Every workload runs exactly as declared: no drift, no hidden state, no surprises.
</P>
</div>
<div className="mx-auto mt-16 max-w-5xl"> {/* ✅ Top horizontal line with spacing */}
<dl className="grid grid-cols-1 gap-12 text-gray-600 sm:grid-cols-2 lg:grid-cols-3"> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
{features.map((feature) => ( <div className="w-full border-t border-l border-r border-gray-100" />
<div key={feature.name} className="relative pl-12">
<feature.icon {/* ✅ Top horizontal line with spacing */}
aria-hidden="true" <div className="mx-auto max-w-7xl border-gray-100">
className="absolute left-0 top-1 size-6 text-cyan-600" <dl className="grid grid-cols-1 gap-4 lg:gap-14 overflow-hidden text-center lg:grid-cols-3">
/> {stats.map((stat) => (
<CT className="font-semibold text-gray-900">{feature.name}</CT> <div key={stat.id} className="flex flex-col items-center bg-gray-400/5 py-8 px-12 border border-gray-100 lg:border-t-0 lg:border-b-0">
<CP className="mt-1 text-gray-600">{feature.description}</CP> <stat.icon className="h-8 w-8 fill-cyan-500 mb-4" aria-hidden="true" />
<CT className="">{stat.value}</CT>
<CP className="mt-1">{stat.name}</CP>
</div> </div>
))} ))}
</dl> </dl>
</div> </div>
</Container> {/* ✅ Bottom horizontal line + spacing */}
</section> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div>
) )
} }

View File

@@ -1,68 +1,101 @@
import { Container } from '@/components/Container'
import { Eyebrow, SectionHeader, P, Small } from '@/components/Texts'
const featureGroups = [ import { Eyebrow, H3, P } from '@/components/Texts'
{ import {
title: 'Self-Managing Infrastructure', ArrowTrendingUpIcon,
description: ChatBubbleLeftRightIcon,
'Scaling, healing, and failover happen automatically, no manual intervention.', MagnifyingGlassIcon,
}, ServerStackIcon,
{ } from '@heroicons/react/24/solid'
title: 'Secure, Stateless Execution',
description:
'Workloads remain isolated, reproducible, and portable, no environment drift or configuration decay.',
},
{
title: 'Zero-Image Delivery',
description:
'Deploy workloads using metadata instead of large container images for instant launches.',
},
{
title: 'Global Placement Control',
description:
'Choose where workloads run, on your hardware or across the decentralized grid.',
},
]
export function ComputeFeatures() { export function ComputeFeatures() {
return ( return (
<section className="bg-white py-24 sm:py-32"> <section className="w-full max-w-8xl mx-auto bg-transparent">
<Container>
<div className="mx-auto max-w-3xl text-center"> {/* ✅ Top horizontal line with spacing */}
<Eyebrow className="tracking-[0.28em] uppercase text-cyan-500"> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
Core Features <div className="w-full border-t border-l border-r border-gray-100" />
<div className="mx-auto max-w-7xl px-6 bg-white lg:px-8 grid grid-cols-1 lg:grid-cols-2 gap-20 py-12 border border-t-0 border-b-0 border-gray-100">
{/* ✅ LEFT SIDE — Title + Intro */}
<div className="max-w-xl">
<Eyebrow className="">
Core Components
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900">
Precision infrastructure that verifies itself. <H3 className="mt-6 ">
</SectionHeader> Network Capabilities
<P className="mt-6 text-gray-600"> </H3>
Every layer is designed for determinism, from how workloads are
declared to the way they scale, protect, and govern themselves on <P className="mt-6 text-lg text-gray-600">
the grid. Built for resilience and autonomy, the Mycelium Network dynamically connects nodes
through intelligent routing, proxy discovery, and decentralized delivery.
</P>
<P className="mt-3 text-lg text-gray-600">
Each component from message passing to content distribution works in harmony
to create a fully self-healing, self-optimizing data mesh.
</P> </P>
</div> </div>
<div className="mt-16 grid gap-8 md:grid-cols-2"> {/* ✅ RIGHT SIDE — 4 items stacked with dividers */}
{featureGroups.map((feature) => ( <div className="space-y-8">
<div
key={feature.title} {/* 1 — Routing */}
className="flex h-full flex-col rounded-3xl border border-slate-200 bg-white p-10 shadow-sm transition hover:-translate-y-1 hover:shadow-xl"
>
<div> <div>
<Small className="text-xs uppercase tracking-[0.3em] text-cyan-500"> <h3 className="text-lg font-semibold text-gray-950 flex items-center">
Feature <ArrowTrendingUpIcon className="h-6 w-6 text-cyan-500 mr-3" />
</Small> Automatic routing & pathfinding
<h3 className="mt-4 text-2xl font-semibold text-gray-900">
{feature.title}
</h3> </h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600"> <p className="mt-2 text-gray-600 max-w-2xl">
{feature.description} The Mycelium Network automatically discovers the shortest and fastest
routes between nodes, ensuring optimal data flow and network efficiency.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
{/* 2 — Distributed bus */}
<div>
<h3 className="text-lg font-semibold text-gray-950 flex items-center">
<ChatBubbleLeftRightIcon className="h-6 w-6 text-cyan-500 mr-3" />
Distributed message bus
</h3>
<p className="mt-2 text-gray-600 max-w-2xl">
Nodes exchange information seamlessly through a resilient global
message layer, enabling asynchronous decentralized communication.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
{/* 3 — Proxy detection */}
<div>
<h3 className="text-lg font-semibold text-gray-950 flex items-center">
<MagnifyingGlassIcon className="h-6 w-6 text-cyan-500 mr-3" />
Automatic proxy discovery
</h3>
<p className="mt-2 text-gray-600 max-w-2xl">
The network scans for open SOCKS5 proxies so devices can join and
connect without manual setup or configuration.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
{/* 4 — Delivery / CDN */}
<div>
<h3 className="text-lg font-semibold text-gray-950 flex items-center">
<ServerStackIcon className="h-6 w-6 text-cyan-500 mr-3" />
Decentralized content distribution
</h3>
<p className="mt-2 text-gray-600 max-w-2xl">
Data can be served from distributed 0-DBs, forming a CDN-like delivery
layer that is faster and more resilient than centralized servers.
</p> </p>
</div> </div>
</div> </div>
))}
</div> </div>
</Container> {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</section> </section>
) )
} }

View File

@@ -6,7 +6,7 @@ export function ComputeHero({ onGetStartedClick = () => {} }: { onGetStartedClic
<div className=""> <div className="">
{/* Boxed container */} {/* Boxed container */}
<div <div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-200 bg-white overflow-hidden bg-contain bg-right bg-no-repeat" className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/computehero.webp')", backgroundSize: "contain" }} style={{ backgroundImage: "url('/images/computehero.webp')", backgroundSize: "contain" }}
> >
{/* Inner padding */} {/* Inner padding */}
@@ -44,8 +44,8 @@ export function ComputeHero({ onGetStartedClick = () => {} }: { onGetStartedClic
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div> </div>
) )
} }

View File

@@ -17,51 +17,68 @@ const overviewCards = [
export function ComputeOverview() { export function ComputeOverview() {
return ( return (
<section className="relative overflow-hidden bg-gray-950 py-24 sm:py-32"> <section className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-100" />
{/* ✅ subtle light-mode background accents */}
<div className="pointer-events-none absolute inset-0"> <div className="pointer-events-none absolute inset-0">
<CircleBackground <CircleBackground
color="#06b6d4" color="#06b6d4"
className="absolute -top-40 left-1/2 h-[520px] w-[520px] -translate-x-1/2 opacity-30 blur-3xl sm:opacity-40" className="absolute -top-40 left-1/2 h-[520px] w-[520px] -translate-x-1/2 opacity-20 blur-3xl"
/> />
<CircleBackground <CircleBackground
color="#22d3ee" color="#22d3ee"
className="absolute bottom-[-18rem] left-[15%] h-[420px] w-[420px] opacity-25 blur-3xl sm:opacity-40" className="absolute bottom-[-18rem] left-[15%] h-[420px] w-[420px] opacity-15 blur-3xl"
/> />
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top,_rgba(15,118,110,0.1),_transparent_55%)]" /> <div className="absolute inset-0 bg-[radial-gradient(circle_at_top,_rgba(0,0,0,0.03),_transparent_55%)]" />
</div> </div>
<Container className="relative">
<Container className="relative py-12 bg-white mx-auto s border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow color="accent" className="tracking-[0.35em] uppercase"> <Eyebrow color="accent" className="tracking-[0.35em] uppercase">
Mycelium Compute Mycelium Compute
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" color="light" className="mt-6 font-medium">
<SectionHeader
as="h2"
color="dark"
className="mt-6 font-medium text-gray-900"
>
Deterministic compute fabric for autonomous workloads. Deterministic compute fabric for autonomous workloads.
</SectionHeader> </SectionHeader>
<P color="lightSecondary" className="mt-6">
<P color="secondary" className="mt-4 text-gray-600">
Mycelium Compute delivers predictable, sovereign performancefree Mycelium Compute delivers predictable, sovereign performancefree
from lock-in and drift. Deploy any workload with cryptographic from lock-in and drift. Deploy any workload with cryptographic
precision, knowing the platform verifies, scales, and heals itself precision, knowing the platform verifies, scales, and heals itself
on your behalf. on your behalf.
</P> </P>
<P color="lightSecondary" className="mt-4">
<P color="secondary" className="mt-4 text-gray-600">
Deterministic. Self-managing. Stateless by design. Deterministic. Self-managing. Stateless by design.
</P> </P>
</div> </div>
<div className="mt-16 grid gap-6 lg:grid-cols-2">
{/* ✅ Light Mode Cards */}
<div className="mt-12 grid gap-6 lg:grid-cols-2">
{overviewCards.map((card) => ( {overviewCards.map((card) => (
<div <div
key={card.title} key={card.title}
className="group relative overflow-hidden rounded-3xl border border-white/10 bg-white/[0.03] p-10 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/40 hover:bg-white/[0.06]" className="group relative overflow-hidden rounded-md border border-gray-100 bg-white p-10 shadow-sm transition hover:-translate-y-1 hover:border-cyan-300 hover:shadow-lg"
> >
<div className="absolute inset-0 bg-gradient-to-br from-cyan-500/0 via-white/[0.04] to-cyan-300/10 opacity-0 transition group-hover:opacity-100" /> <div className="absolute inset-0 bg-gradient-to-br from-cyan-50 via-white to-cyan-100 opacity-0 transition group-hover:opacity-70" />
<div className="relative"> <div className="relative">
<p className="text-[0.7rem] font-semibold uppercase tracking-[0.35em] text-cyan-300"> <p className="text-[0.7rem] font-semibold uppercase tracking-[0.35em] text-cyan-600">
{card.label} {card.label}
</p> </p>
<h3 className="mt-4 text-xl font-semibold text-white"> <h3 className="mt-4 text-xl font-semibold text-gray-900">
{card.title} {card.title}
</h3> </h3>
<p className="mt-4 text-sm leading-relaxed text-gray-300"> <p className="mt-4 text-sm leading-relaxed text-gray-600">
{card.copy} {card.copy}
</p> </p>
</div> </div>
@@ -69,6 +86,9 @@ export function ComputeOverview() {
))} ))}
</div> </div>
</Container> </Container>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</section> </section>
) )
} }

View File

@@ -4,9 +4,9 @@ import { ComputeFeatures } from './ComputeFeatures'
import { ComputeArchitecture } from './ComputeArchitecture' import { ComputeArchitecture } from './ComputeArchitecture'
import { ComputeUseCases } from './ComputeUseCases' import { ComputeUseCases } from './ComputeUseCases'
import { CallToAction } from './CallToAction' import { CallToAction } from './CallToAction'
import { ComputeCapabilities } from './ComputeCapabilities'
import { ComputeDesign } from './ComputeDesign' import { ComputeDesign } from './ComputeDesign'
import { ComputeOverview } from './ComputeOverview' import { ComputeOverview } from './ComputeOverview'
import { ComputeCapabilitiesNew } from './ComputeCapabilitiesNew'
export default function ComputePage() { export default function ComputePage() {
@@ -17,7 +17,7 @@ export default function ComputePage() {
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<ComputeCapabilities /> <ComputeCapabilitiesNew />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>

View File

@@ -1,53 +1,137 @@
import { Container } from '@/components/Container' "use client";
import { Eyebrow, SectionHeader } from '@/components/Texts'
const useCases = [ import { useState } from "react";
import { ComputeCodeTabs } from "./ComputeCodeTabs"; // ✅ Make sure path is correct
import { Eyebrow, H3, P } from "@/components/Texts";
const tabs = [
{ {
title: 'AI / ML Training', id: "ai",
description: label: "AI / ML TRAINING",
'Reproducible pipelines, private model execution, scalable GPU orchestration.', content: [
{
item: "Reproducible pipelines",
desc: "Build deterministic, version-locked training pipelines that produce the same result every time.",
}, },
{ {
title: 'Application Hosting',
description: item: "Private model execution",
'Private, reliable, self-healing services without cloud vendor lock-in.', desc: "Train sensitive models on hardware you control, keeping datasets and checkpoints off hyperscalers.",
}, },
{ {
title: 'Distributed & Edge Compute', item: "Scalable GPU orchestration",
description: desc: "Scale training and inference across decentralized GPU nodes with automated orchestration.",
'Run workloads where data lives, in homes, offices, datacenters, or remote regions.',
}, },
] ],
},
{
id: "apps",
label: "APPLICATION HOSTING",
content: [
{
item: "Self-healing services",
desc: "Private, reliable services that repair automatically without cloud vendor lock-in.",
},
{
item: "Zero cloud lock-in",
desc: "Deploy containers, VMs, or full Kubernetes clusters — migrate off AWS/GCP/Azure with no code changes.",
},
{
item: "Encrypted networking",
desc: "All services communicate through Mycelium Mesh — no VPNs, no exposed ports.",
},
],
},
{
id: "edge",
label: "DISTRIBUTED & EDGE COMPUTE",
content: [
{
item: "Distributed workloads",
desc: "Run compute where data lives — homes, factories, hospitals, or remote regions.",
},
{
item: "Offline-first resilience",
desc: "Nodes keep working even with weak internet or outages — ideal for mission-critical edge.",
},
{
item: "Global deployment, local data",
desc: "Keep data in-country or on-prem for compliance, privacy, and regulated industries.",
},
],
},
];
export function ComputeUseCases() { export function ComputeUseCases() {
const [active, setActive] = useState("ai");
const current = tabs.find((t) => t.id === active)!;
return ( return (
<section className="bg-gray-950 py-24 sm:py-32"> <section className="relative w-full bg-[#121212] overflow-hidden">
<Container> {/* ✅ Top horizontal line with spacing */}
<div className="mx-auto max-w-3xl text-center"> <div className="max-w-7xl bg-[#121212] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
<Eyebrow color="accent" className="tracking-[0.32em] uppercase"> <div className="w-full border-t border-l border-r border-gray-800" />
<div className="max-w-7xl mx-auto px-6 lg:px-8 py-12 border border-t-0 border-b-0 border-gray-800 bg-[#111111] overflow-hidden">
{/* ✅ H3 on own row */}
<div className="mb-16">
<Eyebrow color="accent" className="">
Use Cases Use Cases
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" color="light" className="mt-6"> <H3 color="white">
Built for Serious Workloads Built for Serious Workloads
</SectionHeader> </H3>
<P className="max-w-3xl text-gray-400 mt-6">
Mycelium Compute is a decentralized physical infrastructure network
(DePIN) for high-performance workloads. Run reproducible AI/ML
pipelines, host self-healing applications, or deploy to the edge all
on a fabric thats more resilient and private than the cloud.
</P>
</div> </div>
<div className="mx-auto mt-16 max-w-4xl space-y-6"> {/* ✅ Two-column layout */}
{useCases.map((useCase) => ( <div className="flex flex-col lg:flex-row gap-16">
<div
key={useCase.title} {/* ✅ Replace image with CodeTabs */}
className="rounded-3xl border border-white/10 bg-white/5 p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-200/40 hover:bg-white/10" <div className="w-full lg:w-1/2">
<ComputeCodeTabs />
</div>
{/* ✅ Right side tabs & content */}
<div className="w-full lg:w-1/2 text-white">
{/* Tabs Nav */}
<div className="flex gap-6 border-b border-white/10 pb-2">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActive(tab.id)}
className={`text-sm font-medium tracking-wide pb-2 ${
active === tab.id
? "border-b-2 border-cyan-500 text-white"
: "text-gray-400 hover:text-white"
}`}
> >
<h3 className="text-xl font-semibold text-white"> {tab.label}
{useCase.title} </button>
</h3> ))}
<p className="mt-3 text-sm leading-relaxed text-gray-200"> </div>
{useCase.description}
</p> {/* Tab Content */}
<div className="mt-6 space-y-6">
{current.content.map((c, i) => (
<div key={i} className="space-y-1">
<p className="text-base font-medium text-white">{c.item}</p>
<p className="text-sm text-gray-400 leading-relaxed">{c.desc}</p>
</div> </div>
))} ))}
</div> </div>
</Container> </div>
</div>
</div>
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
<div className="w-full border-b border-gray-800" />
</section> </section>
) );
} }

View File

@@ -0,0 +1,189 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
gridStroke?: string;
};
const W = 760;
const H = 420;
export default function Deterministic({
className,
accent = "#00b8db",
gridStroke = "#2b2a2a",
}: Props) {
const prefers = useReducedMotion();
const stages = [
{ x: 180, y: 180, w: 120, h: 80, label: "Build" },
{ x: 330, y: 180, w: 120, h: 80, label: "Package" },
{ x: 480, y: 180, w: 120, h: 80, label: "Deploy" },
];
// Packet path (deterministic flow)
const packetPath = `M ${stages[0].x + 120} ${stages[0].y + 40}
L ${stages[1].x + 0} ${stages[1].y + 40}
L ${stages[1].x + 120} ${stages[1].y + 40}
L ${stages[2].x + 0} ${stages[2].y + 40}`;
// tiny arrow for each transition
const arrows = [
`M ${stages[0].x + 120} ${stages[0].y + 40} L ${stages[1].x + 6} ${stages[1].y + 40}`,
`M ${stages[1].x + 120} ${stages[1].y + 40} L ${stages[2].x + 6} ${stages[2].y + 40}`
];
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="Deterministic orchestration: predictable deployments"
style={{ background: "transparent" }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* BACKGROUND GRID */}
<defs>
<pattern id="grid-orch" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28"
fill="none"
stroke={gridStroke}
strokeWidth="1"
opacity="0.45"
/>
</pattern>
{/* Soft glow for highlight */}
<filter id="orch-glow">
<feGaussianBlur stdDeviation="4" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect width={W} height={H} fill="url(#grid-orch)" />
{/* STAGE BOXES */}
{stages.map((s, i) => (
<motion.rect
key={`stage-${i}`}
x={s.x}
y={s.y}
width={s.w}
height={s.h}
rx={14}
fill="#0d0d0d"
stroke="#1a1a1a"
strokeWidth={2}
initial={{ opacity: 0 }}
animate={{ opacity: 0.9 }}
transition={{ duration: 0.6 + i * 0.1 }}
/>
))}
{/* Stage labels (subtle, not text-heavy) */}
{stages.map((s, i) => (
<motion.text
key={`label-${i}`}
x={s.x + s.w / 2}
y={s.y + s.h / 2 + 6}
fill="#9ca3af"
textAnchor="middle"
fontSize="14"
fontFamily="Inter, sans-serif"
initial={{ opacity: 0 }}
animate={{ opacity: 0.9 }}
transition={{ delay: 0.1 * i, duration: 0.6 }}
>
{s.label}
</motion.text>
))}
{/* CONSISTENT ORCHESTRATION LINES */}
{arrows.map((d, i) => (
<motion.path
key={`arrow-${i}`}
d={d}
stroke="#3a3a3a"
strokeWidth={4}
strokeLinecap="round"
fill="none"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.8 }}
transition={{ delay: 0.15 * i, duration: 0.8, ease: [0.22, 1, 0.36, 1] }}
/>
))}
{/* CYAN ACCENT OVERLAY ON LINES (predictable updates) */}
{arrows.map((d, i) => (
<motion.path
key={`arrow-accent-${i}`}
d={d}
stroke={accent}
strokeWidth={2}
strokeLinecap="round"
strokeDasharray="10"
fill="none"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{
delay: 0.25 * i,
duration: 0.8,
ease: [0.22, 1, 0.36, 1]
}}
/>
))}
{/* MOVING PACKET SHOWING DETERMINISTIC FLOW */}
{!prefers && (
<motion.circle
r={6}
fill={accent}
filter="url(#orch-glow)"
style={{
offsetPath: `path('${packetPath}')`,
}}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0.2, 1, 0.2],
}}
transition={{
duration: 2.3,
repeat: Infinity,
repeatType: "loop",
ease: "linear",
}}
/>
)}
{/* FINAL CONFIRMATION PULSE AT DEPLOY STAGE */}
{!prefers && (
<motion.circle
cx={stages[2].x + stages[2].w / 2}
cy={stages[2].y + stages[2].h / 2}
r={24}
fill={accent}
opacity={0.1}
initial={{ scale: 0.9, opacity: 0 }}
animate={{ scale: [1, 1.15, 1], opacity: [0.05, 0.3, 0.05] }}
transition={{
duration: 1.8,
repeat: Infinity,
repeatType: "mirror",
ease: [0.22, 1, 0.36, 1],
}}
filter="url(#orch-glow)"
/>
)}
</svg>
</div>
);
}

View File

@@ -0,0 +1,151 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
stroke?: string;
};
const W = 760;
const H = 420;
export default function MeshNetworking({
className,
accent = "#00b8db",
stroke = "#4B5563",
}: Props) {
const prefersReduced = useReducedMotion();
// Nodes in a real mesh (hex pattern)
const nodes = [
{ x: 200, y: 120 },
{ x: 380, y: 100 },
{ x: 560, y: 120 },
{ x: 130, y: 240 },
{ x: 320, y: 240 },
{ x: 540, y: 240 },
{ x: 630, y: 240 },
{ x: 260, y: 340 },
{ x: 440, y: 340 },
];
// All connected pairs (mesh links)
const links = [
[0,1],[1,2],
[0,3],[1,4],[2,5],
[3,4],[4,5],[5,6],
[3,7],[4,7],[4,8],[5,8],
[7,8]
];
const drawLine = (i: number, j: number) => {
const a = nodes[i];
const b = nodes[j];
return `M ${a.x} ${a.y} L ${b.x} ${b.y}`;
};
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="Mesh networking topology"
style={{ background: "transparent" }} // ✅ transparent background
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* ✅ Subtle dark grid */}
<defs>
<pattern id="mesh-grid" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" fill="none" stroke="#2b2a2a" strokeWidth="1" />
</pattern>
</defs>
<rect width={W} height={H} fill="url(#mesh-grid)" />
{/* ✅ Gray baseline mesh connections */}
{links.map(([i, j], idx) => (
<motion.path
key={`base-${idx}`}
d={drawLine(i, j)}
stroke={stroke}
strokeWidth={2}
strokeLinecap="round"
fill="none"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1, opacity: 0.4 }}
transition={{
delay: 0.05 * idx,
duration: 0.6,
ease: [0.22, 1, 0.36, 1],
}}
/>
))}
{/* ✅ Cyan signal traveling across mesh diagonally */}
{!prefersReduced &&
links.map(([i, j], idx) => {
const path = drawLine(i, j);
return (
<motion.circle
key={`signal-${idx}`}
r={4}
fill={accent}
style={{ offsetPath: `path('${path}')` }}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0, 1, 0],
}}
transition={{
delay: idx * 0.15,
duration: 1.8,
repeat: Infinity,
repeatType: "loop",
ease: "linear",
}}
/>
);
})}
{/* ✅ Nodes with soft glow */}
{nodes.map((n, idx) => (
<g key={`node-${idx}`}>
<motion.circle
cx={n.x}
cy={n.y}
r={18}
fill="#0d0d0d"
stroke="#111"
strokeWidth={2}
initial={{ opacity: 0 }}
animate={{ opacity: 0.7 }}
transition={{ duration: 0.5 }}
/>
<motion.circle
cx={n.x}
cy={n.y}
r={10}
fill={accent}
initial={{ opacity: 0, scale: 0.8 }}
animate={{
opacity: 1,
scale: prefersReduced ? 1 : [1, 1.08, 1],
}}
transition={{
duration: 1.6,
repeat: prefersReduced ? 0 : Infinity,
repeatType: "mirror",
ease: [0.22, 1, 0.36, 1],
}}
/>
</g>
))}
</svg>
</div>
);
}

View File

@@ -0,0 +1,236 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string; // cyan highlight
gridStroke?: string; // grid color (default #2b2a2a as requested)
};
const W = 760;
const H = 420;
const Server = ({
x,
y,
w = 140,
h = 90,
rows = 3,
}: {
x: number;
y: number;
w?: number;
h?: number;
rows?: number;
}) => {
const rowH = (h - 24) / rows;
return (
<g>
{/* chassis */}
<rect x={x} y={y} width={w} height={h} rx={12} fill="#0d0d0d" stroke="#1a1a1a" strokeWidth={2} />
{/* bays */}
{Array.from({ length: rows }).map((_, i) => (
<g key={i}>
<rect
x={x + 12}
y={y + 12 + i * rowH}
width={w - 24}
height={rowH - 10}
rx={8}
fill="#111111"
stroke="#1f1f1f"
strokeWidth={1}
/>
{/* bay indicators */}
<rect x={x + 20} y={y + 22 + i * rowH} width={10} height={6} rx={2} fill="#16a34a" opacity={0.8} />
<rect x={x + 36} y={y + 22 + i * rowH} width={10} height={6} rx={2} fill="#9ca3af" opacity={0.6} />
<rect x={x + 52} y={y + 22 + i * rowH} width={10} height={6} rx={2} fill="#9ca3af" opacity={0.6} />
</g>
))}
{/* subtle top highlight */}
<rect x={x + 2} y={y + 2} width={w - 4} height={10} rx={5} fill="#0f0f0f" />
</g>
);
};
export default function SovereignCompute({
className,
accent = "#00b8db",
gridStroke = "#2b2a2a",
}: Props) {
const prefers = useReducedMotion();
// Positions
const left = { x: 140, y: 120 };
const mid = { x: 310, y: 150 };
const right= { x: 500, y: 120 };
// Shield position (trust boundary)
const shield = { cx: 600, cy: 250, r: 38 };
// Attestation paths from racks to shield
const pathFromLeft = `M ${left.x + 140} ${left.y + 45} C 330 150, 470 200, ${shield.cx - 50} ${shield.cy}`;
const pathFromMid = `M ${mid.x + 140} ${mid.y + 45} C 420 190, 500 215, ${shield.cx - 50} ${shield.cy}`;
const pathFromRight = `M ${right.x + 140} ${right.y + 45} C 520 180, 560 220, ${shield.cx - 50} ${shield.cy}`;
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="Sovereign compute: execution only on hardware you control"
style={{ background: "transparent" }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* GRID (transparent bg, subtle dark grid) */}
<defs>
<pattern id="grid-secure" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.45" />
</pattern>
{/* soft glow filter for shield */}
<filter id="glow">
<feGaussianBlur stdDeviation="6" result="coloredBlur" />
<feMerge>
<feMergeNode in="coloredBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect width={W} height={H} fill="url(#grid-secure)" />
{/* RACKS (hardware you control) */}
<Server x={left.x} y={left.y} />
<Server x={mid.x} y={mid.y} />
<Server x={right.x} y={right.y} />
{/* BASELINES for attestation links */}
{[pathFromLeft, pathFromMid, pathFromRight].map((d, i) => (
<motion.path
key={`base-${i}`}
d={d}
fill="none"
stroke="#303030"
strokeWidth={3}
strokeLinecap="round"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.6 }}
transition={{ delay: 0.15 * i, duration: 0.8, ease: [0.22, 1, 0.36, 1] }}
/>
))}
{/* MOVING ATTESTATION TOKENS (signatures/hashes) */}
{!prefers && [pathFromLeft, pathFromMid, pathFromRight].map((d, i) => (
<motion.circle
key={`token-${i}`}
r={5}
fill={accent}
style={{ offsetPath: `path('${d}')` }}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{ offsetDistance: ["0%", "100%"], opacity: [0, 1, 0] }}
transition={{
delay: 0.25 * i,
duration: 2.0,
repeat: Infinity,
repeatType: "loop",
ease: "linear",
}}
/>
))}
{/* TRUST BOUNDARY + SHIELD (hardware attestation target) */}
<motion.circle
cx={shield.cx}
cy={shield.cy}
r={shield.r + 18}
fill="none"
stroke="#1f1f1f"
strokeWidth={2}
initial={{ opacity: 0 }}
animate={{ opacity: 0.9 }}
transition={{ duration: 0.6 }}
/>
{/* cyan halo */}
{!prefers && (
<motion.circle
cx={shield.cx}
cy={shield.cy}
r={shield.r + 6}
fill={accent}
opacity={0.12}
initial={{ scale: 0.95, opacity: 0 }}
animate={{ scale: [1, 1.12, 1], opacity: [0.1, 0.35, 0.1] }}
transition={{ duration: 1.8, repeat: Infinity, repeatType: "mirror", ease: [0.22, 1, 0.36, 1] }}
filter="url(#glow)"
/>
)}
{/* Shield outline */}
<motion.path
d={`M ${shield.cx} ${shield.cy - 30}
L ${shield.cx + 28} ${shield.cy - 15}
L ${shield.cx + 22} ${shield.cy + 24}
L ${shield.cx} ${shield.cy + 34}
L ${shield.cx - 22} ${shield.cy + 24}
L ${shield.cx - 28} ${shield.cy - 15}
Z`}
fill="none"
stroke={accent}
strokeWidth={3}
strokeLinecap="round"
strokeLinejoin="round"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{ duration: 0.9, ease: [0.22, 1, 0.36, 1] }}
filter="url(#glow)"
/>
{/* Check mark (verified hardware) */}
<motion.path
d={`M ${shield.cx - 14} ${shield.cy + 6} L ${shield.cx - 2} ${shield.cy + 18} L ${shield.cx + 18} ${shield.cy - 6}`}
fill="none"
stroke={accent}
strokeWidth={4}
strokeLinecap="round"
strokeLinejoin="round"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.9, delay: 0.2, ease: [0.22, 1, 0.36, 1] }}
filter="url(#glow)"
/>
{/* LOCKED EXECUTION BOUNDARY (subtle arc) */}
<motion.path
d={`M ${shield.cx - 70} ${shield.cy + 46} Q ${shield.cx} ${shield.cy + 76} ${shield.cx + 70} ${shield.cy + 46}`}
fill="none"
stroke="#2e2e2e"
strokeWidth={2}
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.6 }}
transition={{ duration: 0.8, delay: 0.3 }}
/>
{/* Cyan confirmation pulses emanating out (execution allowed) */}
{!prefers && [0, 1].map((i) => (
<motion.circle
key={`emit-${i}`}
cx={shield.cx}
cy={shield.cy}
r={shield.r + 12}
fill="none"
stroke={accent}
strokeWidth={2}
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: [0.0, 0.5, 0.0], scale: [1, 1.15, 1.3] }}
transition={{ duration: 1.8, delay: i * 0.3, repeat: Infinity, ease: [0.22, 1, 0.36, 1] }}
/>
))}
</svg>
</div>
);
}

View File

@@ -73,7 +73,7 @@ export function DownloadHero() {
{features.map((feature) => ( {features.map((feature) => (
<div <div
key={feature.name} key={feature.name}
className="flex flex-col rounded-lg border border-gray-200 p-8 shadow-sm transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20" className="flex flex-col rounded-lg border border-gray-100 p-8 shadow-sm transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20"
> >
<dt className="text-base font-semibold leading-7 text-gray-900"> <dt className="text-base font-semibold leading-7 text-gray-900">
<div className="mb-6 flex h-10 w-10 items-center justify-center"> <div className="mb-6 flex h-10 w-10 items-center justify-center">

View File

@@ -8,7 +8,7 @@ export function GpuHero() {
<div className=""> <div className="">
{/* Boxed container */} {/* Boxed container */}
<div <div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-200 bg-white overflow-hidden bg-contain bg-right bg-no-repeat" className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/gpuhero2.png')", backgroundSize: "contain" }} style={{ backgroundImage: "url('/images/gpuhero2.png')", backgroundSize: "contain" }}
> >
{/* Inner padding */} {/* Inner padding */}
@@ -33,8 +33,8 @@ export function GpuHero() {
</div> </div>
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div> </div>
) )
} }

View File

@@ -5,12 +5,12 @@ export function CallToAction() {
return ( return (
<section className='relative overflow-hidden bg-gray-900'> <section className='relative overflow-hidden bg-gray-900'>
{/* ✅ Top horizontal line with spacing */} {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-600"></div> <div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
{/* === Content === */} {/* === Content === */}
<div className="w-full border-t border-l border-r border-gray-600 " /> <div className="w-full border-t border-l border-r border-gray-800 " />
<div <div
id="get-started" id="get-started"
className="py-18 max-w-7xl mx-auto border-t-0 border-b-0 border bg-[#111111] border-gray-600"> className="py-18 max-w-7xl mx-auto border-t-0 border-b-0 border bg-[#111111] border-gray-800">
<Container className="relative"> <Container className="relative">
<div className="mx-auto max-w-2xl text-center "> <div className="mx-auto max-w-2xl text-center ">
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl"> <h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
@@ -41,8 +41,8 @@ export function CallToAction() {
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-600" /> <div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-600"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</section> </section>
) )
} }

View File

@@ -6,7 +6,7 @@ export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => voi
<div className="px-4"> <div className="px-4">
{/* Boxed container */} {/* Boxed container */}
<div <div
className="relative mx-auto max-w-7xl border border-t-0 border-gray-200 bg-white overflow-hidden bg-contain bg-right bg-no-repeat" className="relative mx-auto max-w-7xl border border-t-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/hero11.webp')" }} style={{ backgroundImage: "url('/images/hero11.webp')" }}
> >
{/* Inner padding */} {/* Inner padding */}

View File

@@ -1,305 +1,69 @@
import createGlobe from "cobe"; import { CP } from '@/components/Texts'
import { useEffect, useRef } from "react"; import {
import { motion } from "motion/react"; ShieldCheckIcon,
import { IconBrandYoutubeFilled } from "@tabler/icons-react"; GlobeAltIcon,
import { H2, CP, Eyebrow } from '@/components/Texts' BoltIcon,
BanknotesIcon,
} from '@heroicons/react/24/solid'
const benefits = [
export function HomeBenefits() {
const features = [
{ {
id: 1,
title: "Unbreakable by Design", title: "Unbreakable by Design",
description: desc: "No central cloud to censor or fail. The network heals itself.",
"No central cloud to censor or fail. The network heals itself.", icon: ShieldCheckIcon,
image: "/images/benefits/energy.webp",
}, },
{ {
id: 2,
title: "Sovereign by Default", title: "Sovereign by Default",
description: desc: "Identity, compute, and data belong to you cryptographically.",
"Identity, compute, and data belong to you cryptographically.", icon: GlobeAltIcon,
image: "/images/benefits/sovereign.webp",
}, },
{ {
id: 3,
title: "Hackable & Open", title: "Hackable & Open",
description: desc: "Learn, build, and experiment without permission.",
"Learn, build, and experiment without permission.", icon: BoltIcon,
image: "/images/benefits/autonomous.webp",
}, },
{ {
id: 4,
title: "Cost & Energy Efficient", title: "Cost & Energy Efficient",
description: desc: "Distributed hardware eliminates hyperscale overhead.",
"Distributed hardware eliminates hyperscale overhead.", icon: BanknotesIcon,
image: "/images/benefits/cost.webp",
}, },
]; ];
export function HomeBenefits() {
return ( return (
<div className="relative z-20 bg-blackpy-6 lg:py-24 max-w-7xl mx-auto border border-t-0 border-gray-200"> <div className="">
<div className="px-12">
<Eyebrow className="text-center text-cyan-500"> {/* ✅ Top horizontal line with spacing */}
Benefits <div className="max-w-7xl bg-transparent mx-auto border border-t-0 border-b-0 border-gray-100" />
</Eyebrow> <div className="w-full border-t border-l border-r border-gray-100" />
<H2 className="text-3xl lg:text-5xl lg:leading-tight max-w-5xl mx-auto text-center tracking-tight font-medium text-black dark:text-white">
Why It Matters {/* ✅ Main content */}
</H2> <div className="mx-auto max-w-7xl border-gray-100">
<dl className="grid grid-cols-1 gap-4 lg:gap-6 lg:grid-cols-4 text-center">
{benefits.map((item) => (
<div
key={item.id}
className="flex flex-col items-center bg-white/40 dark:bg-black/40 py-10 px-4 border border-gray-100 lg:border-t-0 lg:border-b-0"
>
<item.icon className="h-10 w-10 text-cyan-500 mb-4" />
<h3 className="text-lg font-semibold text-black dark:text-white">
{item.title}
</h3>
<CP className="mt-2 max-w-xs text-gray-600 dark:text-gray-300">
{item.desc}
</CP>
</div>
))}
</dl>
</div> </div>
<div className="mt-10 grid grid-cols-1 gap-4 lg:grid-cols-7 lg:grid-rows-2 lg:px-12 px-6"> {/* ✅ Bottom line + spacing */}
<div className="flex p-px lg:col-span-4"> <div className="w-full border-b border-gray-100" />
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 max-lg:rounded-t-4xl lg:rounded-tl-4xl"> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
<div className="flex items-center">
<div className="w-1/3 p-2">
<img
alt={features[0].title}
src={features[0].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-2 pr-12">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[0].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[0].description}
</CP>
</div>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-3">
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 lg:rounded-tr-4xl">
<div className="flex items-center">
<div className="w-1/3 p-4">
<img
alt={features[1].title}
src={features[1].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-4">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[1].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[1].description}
</CP>
</div>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-3">
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 lg:rounded-bl-4xl">
<div className="flex items-center">
<div className="w-1/3 p-4">
<img
alt={features[2].title}
src={features[2].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-4">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[2].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[2].description}
</CP>
</div>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-4">
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 max-lg:rounded-b-4xl lg:rounded-br-4xl">
<div className="flex items-center">
<div className="w-1/3 p-2">
<img
alt={features[3].title}
src={features[3].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-2 pr-12">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[3].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[3].description}
</CP>
</div>
</div>
</div>
</div>
</div>
</div> </div>
); );
} }
export const SkeletonOne = () => {
return (
<div className="relative flex py-6 px-2 gap-10 h-full">
<div className="w-full p-5 mx-auto bg-white dark:bg-neutral-900 shadow-2xl group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 ">
{/* TODO */}
<img
src="/linear.webp"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-left-top rounded-sm"
/>
</div>
</div>
<div className="absolute bottom-0 z-40 inset-x-0 h-60 bg-gradient-to-t from-white dark:from-black via-white dark:via-black to-transparent w-full pointer-events-none" />
<div className="absolute top-0 z-40 inset-x-0 h-60 bg-gradient-to-b from-white dark:from-black via-transparent to-transparent w-full pointer-events-none" />
</div>
);
};
export const SkeletonThree = () => {
return (
<a
href="https://www.youtube.com/watch?v=RPa3_AD1_Vs"
target="__blank"
className="relative flex gap-10 h-full group/image"
>
<div className="w-full mx-auto bg-transparent dark:bg-transparent group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 relative">
{/* TODO */}
<IconBrandYoutubeFilled className="h-20 w-20 absolute z-10 inset-0 text-red-500 m-auto " />
<img
src="https://assets.aceternity.com/fireship.jpg"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-center rounded-sm blur-none group-hover/image:blur-md transition-all duration-200"
/>
</div>
</div>
</a>
);
};
export const SkeletonTwo = () => {
const images = [
"https://images.unsplash.com/photo-1517322048670-4fba75cbbb62?q=80&w=3000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1573790387438-4da905039392?q=80&w=3425&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1555400038-63f5ba517a47?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1554931670-4ebfabf6e7a9?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1546484475-7f7bd55792da?q=80&w=2581&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
];
const imageVariants = {
whileHover: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
whileTap: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
};
return (
<div className="relative flex flex-col items-start p-8 gap-10 h-full overflow-hidden">
{/* TODO */}
<div className="flex flex-row -ml-20">
{images.map((image, idx) => (
<motion.div
variants={imageVariants}
key={"images-first" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-black s border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="flex flex-row">
{images.map((image, idx) => (
<motion.div
key={"images-second" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
variants={imageVariants}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="absolute left-0 z-[100] inset-y-0 w-20 bg-gradient-to-r from-white dark:from-black to-transparent h-full pointer-events-none" />
<div className="absolute right-0 z-[100] inset-y-0 w-20 bg-gradient-to-l from-white dark:from-black to-transparent h-full pointer-events-none" />
</div>
);
};
export const SkeletonFour = () => {
return (
<div className="h-60 md:h-60 flex flex-col items-center relative bg-transparent dark:bg-transparent mt-10">
<Globe className="absolute -right-10 md:-right-10 -bottom-80 md:-bottom-72" />
</div>
);
};
export const Globe = ({ className }: { className?: string }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
let phi = 0;
if (!canvasRef.current) return;
const globe = createGlobe(canvasRef.current, {
devicePixelRatio: 2,
width: 600 * 2,
height: 600 * 2,
phi: 0,
theta: 0,
dark: 1,
diffuse: 1.2,
mapSamples: 16000,
mapBrightness: 6,
baseColor: [0.3, 0.3, 0.3],
markerColor: [0.1, 0.8, 1],
glowColor: [1, 1, 1],
markers: [
// longitude latitude
{ location: [37.7595, -122.4367], size: 0.03 },
{ location: [40.7128, -74.006], size: 0.1 },
],
onRender: (state) => {
// Called on every animation frame.
// `state` will be an empty object, return updated params.
state.phi = phi;
phi += 0.01;
},
});
return () => {
globe.destroy();
};
}, []);
return (
<canvas
ref={canvasRef}
style={{ width: 600, height: 600, maxWidth: "100%", aspectRatio: 1 }}
className={className}
/>
);
};

View File

@@ -111,12 +111,12 @@ export function HomeHosting() {
<section className="w-full max-w-8xl mx-auto bg-transparent"> <section className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Top horizontal line with spacing */} {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-200" /> <div className="w-full border-t border-l border-r border-gray-100" />
{/* ✅ Inner content container */} {/* ✅ Inner content container */}
<div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-200"> <div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-100">
<Container> <Container>
<div className="mx-auto max-w-4xl sm:text-center"> <div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-500">IN ACTIVE EVOLUTION</Eyebrow> <Eyebrow className="text-cyan-500">IN ACTIVE EVOLUTION</Eyebrow>
@@ -138,7 +138,7 @@ export function HomeHosting() {
{features.map((feature) => ( {features.map((feature) => (
<li <li
key={feature.name} key={feature.name}
className="rounded-md border border-gray-200 p-6 transition-all duration-300 ease-in-out className="rounded-md border border-gray-100 p-6 transition-all duration-300 ease-in-out
hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 bg-white" hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 bg-white"
> >
<feature.icon className="h-14 w-14" /> <feature.icon className="h-14 w-14" />
@@ -151,8 +151,8 @@ export function HomeHosting() {
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</section> </section>
) )
} }

View File

@@ -7,7 +7,7 @@ import { CallToAction } from './CallToAction'
import { HomeHosting } from './HomeHosting' import { HomeHosting } from './HomeHosting'
import { HomeAurora } from './HomeAurora' import { HomeAurora } from './HomeAurora'
import { HomeTab } from './HomeTab' import { HomeTab } from './HomeTab'
import { HomeBenefits } from './HomeBenefits'
export default function HomePage() { export default function HomePage() {
@@ -37,6 +37,9 @@ export default function HomePage() {
<AnimatedSection> <AnimatedSection>
<HomeTab /> <HomeTab />
</AnimatedSection> </AnimatedSection>
<AnimatedSection>
<HomeBenefits />
</AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CallToAction /> <CallToAction />

View File

@@ -83,12 +83,12 @@ export function HomeTab() {
<section className="w-full max-w-8xl mx-auto bg-transparent"> <section className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Top spacer + full-width line */} {/* ✅ Top spacer + full-width line */}
<div className="max-w-7xl mx-auto py-6 border-x border-gray-200 bg-white border-t-0 border-b-0" /> <div className="max-w-7xl mx-auto py-6 border-x border-gray-100 bg-white border-t-0 border-b-0" />
<div className="w-full border-t border-l border-r border-gray-200" /> <div className="w-full border-t border-l border-r border-gray-100" />
{/* ✅ Section with vertical borders */} {/* ✅ Section with vertical borders */}
<div className="mx-auto bg-white max-w-2xl px-6 lg:max-w-7xl lg:px-10 border border-t-0 border-b-0 border-gray-200"> <div className="mx-auto bg-white max-w-2xl px-6 lg:max-w-7xl lg:px-10 border border-t-0 border-b-0 border-gray-100">
<Eyebrow className="pt-12 ">Deploy faster</Eyebrow> <Eyebrow className="pt-12 ">Deploy faster</Eyebrow>
<H3 className="mt-2">Mycelium Components</H3> <H3 className="mt-2">Mycelium Components</H3>
<P className="mt-6 max-w-lg"> <P className="mt-6 max-w-lg">
@@ -120,8 +120,8 @@ export function HomeTab() {
</div> </div>
{/* ✅ Bottom full-width line + spacer */} {/* ✅ Bottom full-width line + spacer */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl mx-auto py-6 border-x border-gray-200 border-t-0 border-b-0" /> <div className="max-w-7xl mx-auto py-6 border-x border-gray-100 border-t-0 border-b-0" />
</section> </section>
); );
} }

View File

@@ -9,10 +9,10 @@ export function StackSectionDark() {
return ( return (
<section className="relative w-full bg-[#171717] overflow-hidden"> <section className="relative w-full bg-[#171717] overflow-hidden">
{/* ✅ Top horizontal line with spacing */} {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-600"></div> <div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
<div className="w-full border-t border-l border-r border-gray-600" /> <div className="w-full border-t border-l border-r border-gray-800" />
{/* === Background Layer === */} {/* === Background Layer === */}
<div className="absolute inset-0 z-0 bg-transparent border-t-0 border-b-0 border-gray-600"> <div className="absolute inset-0 z-0 bg-transparent border-t-0 border-b-0 border-gray-800">
{/* Central main aura */} {/* Central main aura */}
<motion.div <motion.div
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[1200px] h-[1200px] rounded-full pointer-events-none" className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[1200px] h-[1200px] rounded-full pointer-events-none"
@@ -54,7 +54,7 @@ export function StackSectionDark() {
</div> </div>
{/* === Content === */} {/* === Content === */}
<div className="relative mx-auto max-w-7xl px-6 lg:px-12 border border-t-0 border-b-0 border-gray-600 grid grid-cols-1 lg:grid-cols-3 gap-16 items-center py-24 "> <div className="relative mx-auto max-w-7xl px-6 lg:px-12 border border-t-0 border-b-0 border-gray-800 grid grid-cols-1 lg:grid-cols-3 gap-16 items-center py-24 ">
{/* Left Column - Text */} {/* Left Column - Text */}
<div className="text-center lg:text-left z-10"> <div className="text-center lg:text-left z-10">
<FadeIn> <FadeIn>
@@ -97,8 +97,8 @@ export function StackSectionDark() {
</div> </div>
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-600" /> <div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-600"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</section> </section>
); );
} }

View File

@@ -4,7 +4,7 @@ import { ArrowRightIcon } from "@heroicons/react/24/solid";
export function HomeCTA() { export function HomeCTA() {
return ( return (
<section className="mx-4 lg:mx-auto max-w-5xl border border-t-0 border-gray-200 py-16"> <section className="mx-4 lg:mx-auto max-w-5xl border border-t-0 border-gray-100 py-16">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 items-center px-6"> <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 items-center px-6">
{/* LEFT: Big CTA Button */} {/* LEFT: Big CTA Button */}

View File

@@ -4,7 +4,7 @@ import { Globe } from "@/components/ui/Globe";
export function HomeGlobeNew() { export function HomeGlobeNew() {
return ( return (
<section className="mx-4 pt-12 border-t lg:mx-auto max-w-5xl border border-gray-200"> <section className="mx-4 pt-12 border-t lg:mx-auto max-w-5xl border border-gray-100">
<div className="lg:-mt-12 grid grid-cols-1 lg:grid-cols-2 divide-y lg:divide-y-0 lg:divide-x divide-gray-200"> <div className="lg:-mt-12 grid grid-cols-1 lg:grid-cols-2 divide-y lg:divide-y-0 lg:divide-x divide-gray-200">
{/* Column 1 */} {/* Column 1 */}

View File

@@ -2,7 +2,7 @@ import { Button } from '@/components/Button'
export function HomeHero() { export function HomeHero() {
return ( return (
<section className="mt-12 bg-transparent border border-gray-200 border-b-0 mx-4 lg:mx-auto max-w-5xl shadow-[0_0_40px_-20px_rgba(0,0,0,0.06)]"> <section className="mt-12 bg-transparent border border-gray-100 border-b-0 mx-4 lg:mx-auto max-w-5xl shadow-[0_0_40px_-20px_rgba(0,0,0,0.06)]">
<div className="px-6 py-12 lg:px-8 lg:py-24"> <div className="px-6 py-12 lg:px-8 lg:py-24">
<div className="max-w-2xl mx-auto text-center"> <div className="max-w-2xl mx-auto text-center">
<h1 className="text-3xl font-semibold tracking-tight text-gray-900 lg:text-5xl"> <h1 className="text-3xl font-semibold tracking-tight text-gray-900 lg:text-5xl">

View File

@@ -6,7 +6,7 @@ export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => voi
<div className="px-4"> <div className="px-4">
{/* Boxed container */} {/* Boxed container */}
<div <div
className="relative mx-auto max-w-7xl border border-t-0 border-gray-200 overflow-hidden bg-cover bg-right bg-no-repeat" className="relative mx-auto max-w-7xl border border-t-0 border-gray-100 overflow-hidden bg-cover bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/hero11.webp')" }} style={{ backgroundImage: "url('/images/hero11.webp')" }}
> >
{/* Inner padding */} {/* Inner padding */}

View File

@@ -2,7 +2,7 @@
export function HomeProductsA() { export function HomeProductsA() {
return ( return (
<section className="mx-4 pt-12 border-t-0 lg:mx-auto max-w-5xl border border-gray-200"> <section className="mx-4 pt-12 border-t-0 lg:mx-auto max-w-5xl border border-gray-100">
<div className="lg:-mt-12 grid grid-cols-1 lg:grid-cols-2 divide-y lg:divide-y-0 lg:divide-x divide-gray-200"> <div className="lg:-mt-12 grid grid-cols-1 lg:grid-cols-2 divide-y lg:divide-y-0 lg:divide-x divide-gray-200">
{/* Product 1 */} {/* Product 1 */}
@@ -32,7 +32,7 @@ export function HomeProductsA() {
</div> </div>
{/* Product 3 */} {/* Product 3 */}
<div className="px-6 lg:px-24 py-16 flex border-t border-gray-200 flex-col items-center text-center"> <div className="px-6 lg:px-24 py-16 flex border-t border-gray-100 flex-col items-center text-center">
<h2 className="mt-4 text-xl font-semibold tracking-tight text-gray-900 lg:text-2xl"> <h2 className="mt-4 text-xl font-semibold tracking-tight text-gray-900 lg:text-2xl">
Mycelium Agents Mycelium Agents
</h2> </h2>
@@ -45,7 +45,7 @@ export function HomeProductsA() {
</div> </div>
{/* Product 4 */} {/* Product 4 */}
<div className="px-6 lg:px-24 py-16 flex border-t border-gray-200 flex-col items-center text-center"> <div className="px-6 lg:px-24 py-16 flex border-t border-gray-100 flex-col items-center text-center">
<h2 className="mt-4 text-xl font-semibold tracking-tight text-gray-900 lg:text-2xl"> <h2 className="mt-4 text-xl font-semibold tracking-tight text-gray-900 lg:text-2xl">
Compute / Storage / GPU Compute / Storage / GPU
</h2> </h2>

View File

@@ -31,7 +31,7 @@ export function HomeStack() {
const current = layers.find((l) => l.id === active)!; const current = layers.find((l) => l.id === active)!;
return ( return (
<section className="mx-4 pt-12 border-t-0 lg:mx-auto max-w-5xl border border-gray-200"> <section className="mx-4 pt-12 border-t-0 lg:mx-auto max-w-5xl border border-gray-100">
<div className="lg:-mt-12 grid grid-cols-1 lg:grid-cols-5 divide-y lg:divide-y-0 lg:divide-x divide-gray-200"> <div className="lg:-mt-12 grid grid-cols-1 lg:grid-cols-5 divide-y lg:divide-y-0 lg:divide-x divide-gray-200">
{/* LEFT COLUMN (2 COLS) */} {/* LEFT COLUMN (2 COLS) */}

View File

@@ -1,6 +1,6 @@
export function HomeStat() { export function HomeStat() {
return ( return (
<section className="mx-4 pt-12 border-t-0 lg:mx-auto max-w-5xl border border-gray-200"> <section className="mx-4 pt-12 border-t-0 lg:mx-auto max-w-5xl border border-gray-100">
<div className="lg:-mt-12 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 divide-y sm:divide-y-0 lg:divide-y-0 lg:divide-x divide-gray-200"> <div className="lg:-mt-12 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 divide-y sm:divide-y-0 lg:divide-y-0 lg:divide-x divide-gray-200">
{/* CORES */} {/* CORES */}

View File

@@ -54,11 +54,11 @@ export function HomeApplication() {
const Icon = current.icon; // ✅ dynamic icon const Icon = current.icon; // ✅ dynamic icon
return ( return (
<section className="mx-4 border-t-0 lg:mx-auto max-w-5xl border border-gray-200"> <section className="mx-4 border-t-0 lg:mx-auto max-w-5xl border border-gray-100">
<div className="grid grid-cols-1 lg:grid-cols-4 gap-12 relative"> <div className="grid grid-cols-1 lg:grid-cols-4 gap-12 relative">
{/* ✅ VERTICAL DIVIDER ON DESKTOP */} {/* ✅ VERTICAL DIVIDER ON DESKTOP */}
<div className="hidden lg:block absolute left-3/4 top-0 bottom-0 border-l border-gray-200 pointer-events-none"></div> <div className="hidden lg:block absolute left-3/4 top-0 bottom-0 border-l border-gray-100 pointer-events-none"></div>
{/* LEFT COLUMN */} {/* LEFT COLUMN */}
<div className="lg:col-span-3 space-y-6 lg:pl-6 py-12"> <div className="lg:col-span-3 space-y-6 lg:pl-6 py-12">
@@ -71,7 +71,7 @@ export function HomeApplication() {
</p> </p>
{/* TABS */} {/* TABS */}
<div className="inline-flex flex-wrap gap-2 bg-gray-50 rounded-full p-1 border border-gray-200 w-auto"> <div className="inline-flex flex-wrap gap-2 bg-gray-50 rounded-full p-1 border border-gray-100 w-auto">
{tabs.map((tab) => ( {tabs.map((tab) => (
<button <button
key={tab.id} key={tab.id}

View File

@@ -4,7 +4,7 @@ import { GlobeAltIcon } from "@heroicons/react/24/outline";
export function HomeUniverse() { export function HomeUniverse() {
return ( return (
<section className="mx-4 lg:mx-auto max-w-5xl border border-t-0 border-gray-200 py-4 text-center"> <section className="mx-4 lg:mx-auto max-w-5xl border border-t-0 border-gray-100 py-4 text-center">
<h2 className="text-2xl sm:text-3xl font-semibold text-gray-900 flex flex-wrap items-center justify-center gap-3"> <h2 className="text-2xl sm:text-3xl font-semibold text-gray-900 flex flex-wrap items-center justify-center gap-3">
{/* left text */} {/* left text */}

View File

@@ -16,7 +16,7 @@ export function HomeWhy() {
]; ];
return ( return (
<section className="mx-4 lg:mx-auto max-w-5xl border border-t-0 border-gray-200 py-12 px-6 text-center"> <section className="mx-4 lg:mx-auto max-w-5xl border border-t-0 border-gray-100 py-12 px-6 text-center">
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 place-items-center"> <div className="grid grid-cols-2 lg:grid-cols-4 gap-4 place-items-center">
{items.map(({ label, icon: Icon }) => ( {items.map(({ label, icon: Icon }) => (
<span <span

View File

@@ -1,40 +1,53 @@
import { CircleBackground } from '../../components/CircleBackground' "use client";
import { Container } from '@/components/Container'
import { Button } from '@/components/Button' import { Container } from "@/components/Container";
import { Button } from "@/components/Button";
export function CallToAction() { export function CallToAction() {
return ( return (
<section <section className="relative overflow-hidden bg-[#121212]">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-[#121212] mx-auto py-6 border border-t-0 border-b-0 border-gray-700"></div>
<div className="w-full border-t border-l border-r border-gray-700" />
{/* ✅ Main boxed area */}
<div
id="get-started" id="get-started"
className="relative overflow-hidden bg-gray-900 py-20 sm:py-28" className="relative py-18 max-w-7xl mx-auto bg-[#090909] border border-t-0 border-b-0 border-gray-700"
> >
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<CircleBackground color="#06b6d4" className="animate-spin-slower" />
</div>
<Container className="relative"> <Container className="relative">
<div className="mx-auto max-w-2xl text-center"> <div className="mx-auto max-w-3xl text-center">
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl"> <h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
Choose How You Want to Start Choose How You Want to Start
</h2> </h2>
<p className="mt-6 text-lg text-gray-300"> <p className="mt-6 text-lg text-gray-300">
Use the network to connect workloads or host nodes to deepen mesh resilience and run your environments on your own hardware. Use the network to connect workloads or host nodes to deepen mesh resilience and run your environments on your own hardware.
</p> </p>
<div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4">
<Button to="/download" variant="solid" color="white"> {/* ✅ Two cards, stacked center with spacing */}
<div className="mt-10 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/download" variant="solid" color="cyan" className="mt-4">
Get Mycelium Network Get Mycelium Network
</Button> </Button>
<Button </div>
to="https://threefold.info/mycelium_network/docs/"
as="a" <div className="flex flex-col items-center text-center max-w-xs">
target="_blank" <Button to="https://threefold.info/mycelium_network/docs/" as="a" target="_blank" variant="outline" color="white" className="mt-4">
variant="outline"
color="white"
>
Host a Node Host a Node
</Button> </Button>
</div> </div>
</div> </div>
</div>
</Container> </Container>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-700" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-700 bg-transparent" />
</section> </section>
) );
} }

View File

@@ -3,27 +3,32 @@ import MessageBus from './animations/MessageBus'
import ProxyDetection from './animations/ProxyDetection' import ProxyDetection from './animations/ProxyDetection'
import ProxyForwarding from './animations/ProxyForwarding' import ProxyForwarding from './animations/ProxyForwarding'
import ContentDistribution from './animations/ContentDistribution' import ContentDistribution from './animations/ContentDistribution'
import { H2, P, H3, CT, CP, Eyebrow } from '@/components/Texts'
export function Features() { export function Features() {
return ( return (
<section id="features" className="py-24"> <section className="w-full max-w-8xl mx-auto bg-transparent">
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8">
<h2 className="text-base/7 font-semibold text-cyan-500">Core Components</h2>
<p className="mt-2 max-w-2xl text-3xl lg:text-4xl font-medium tracking-tight text-pretty text-gray-950"> {/* ✅ Top spacer + full-width line */}
Network Capabilities <div className="max-w-7xl mx-auto py-6 border-x border-gray-100 bg-white border-t-0 border-b-0" />
</p> <div className="w-full border-t border-l border-r border-gray-100" />
<p className="mt-4 max-w-4xl text-lg text-gray-600">
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl bg-white py-12 lg:px-10 border border-t-0 border-b-0 border-gray-100">
<Eyebrow>Core Components</Eyebrow>
<H3>Network Capabilities</H3>
<P className="mt-4 max-w-4xl text-lg text-gray-600">
Built for resilience and autonomy, the Mycelium Network dynamically connects nodes through intelligent routing, proxy discovery, and decentralized delivery. Built for resilience and autonomy, the Mycelium Network dynamically connects nodes through intelligent routing, proxy discovery, and decentralized delivery.
</p> </P>
<p className="mt-2 max-w-4xl text-lg text-gray-600"> <P className="mt-4 max-w-4xl text-lg text-gray-600">
Each component from message passing to content distribution works in harmony to create a fully self-healing, self-optimizing data mesh. Each component from message passing to content distribution works in harmony to create a fully self-healing, self-optimizing data mesh.
</p> </P>
<div className="mt-10 grid grid-cols-1 gap-x-4 gap-y-8 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2"> <div className="mt-8 grid grid-cols-1 gap-x-4 gap-y-8 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2">
<div className="group relative lg:col-span-3 transition-all duration-300 ease-in-out hover:scale-105"> <div className="group relative lg:col-span-3 transition-all duration-300 ease-in-out hover:scale-105">
<div className="absolute inset-0 rounded-lg bg-white max-lg:rounded-t-4xl lg:rounded-tl-4xl" /> <div className="absolute inset-0 rounded-lg bg-white max-lg:rounded-t-4xl lg:rounded-tl-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)] lg:rounded-tl-[calc(2rem+1px)]"> <div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)] lg:rounded-tl-[calc(2rem+1px)]">
<Pathfinding /> <Pathfinding />
<div className="p-10 pt-4"> <div className="p-6 pt-4">
<h3 className="text-sm/4 font-semibold text-cyan-500">Routing</h3> <h3 className="text-sm/4 font-semibold text-cyan-500">Routing</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-950"> <p className="mt-2 text-lg font-medium tracking-tight text-gray-950">
Automatic pathfinding Automatic pathfinding
@@ -40,7 +45,7 @@ export function Features() {
<div className="absolute inset-0 rounded-lg bg-white lg:rounded-tr-4xl" /> <div className="absolute inset-0 rounded-lg bg-white lg:rounded-tr-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-tr-[calc(2rem+1px)]"> <div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-tr-[calc(2rem+1px)]">
<MessageBus /> <MessageBus />
<div className="p-10 pt-4"> <div className="p-6 pt-4">
<h3 className="text-sm/4 font-semibold text-cyan-500">Communication</h3> <h3 className="text-sm/4 font-semibold text-cyan-500">Communication</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-950"> <p className="mt-2 text-lg font-medium tracking-tight text-gray-950">
Distributed message bus Distributed message bus
@@ -57,7 +62,7 @@ export function Features() {
<div className="absolute inset-0 rounded-lg bg-white lg:rounded-bl-4xl" /> <div className="absolute inset-0 rounded-lg bg-white lg:rounded-bl-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-bl-[calc(2rem+1px)]"> <div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-bl-[calc(2rem+1px)]">
<ProxyDetection className="h-80" /> <ProxyDetection className="h-80" />
<div className="p-10 pt-4"> <div className="p-6 pt-4">
<h3 className="text-sm/4 font-semibold text-cyan-500">Discovery</h3> <h3 className="text-sm/4 font-semibold text-cyan-500">Discovery</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-950"> <p className="mt-2 text-lg font-medium tracking-tight text-gray-950">
Automatic proxy detection Automatic proxy detection
@@ -74,7 +79,7 @@ export function Features() {
<div className="absolute inset-0 rounded-lg bg-white" /> <div className="absolute inset-0 rounded-lg bg-white" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)]"> <div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)]">
<ProxyForwarding className="h-80" /> <ProxyForwarding className="h-80" />
<div className="p-10 pt-4"> <div className="p-6 pt-4">
<h3 className="text-sm/4 font-semibold text-cyan-500">Connectivity</h3> <h3 className="text-sm/4 font-semibold text-cyan-500">Connectivity</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-950"> <p className="mt-2 text-lg font-medium tracking-tight text-gray-950">
Seamless proxy forwarding Seamless proxy forwarding
@@ -91,7 +96,7 @@ export function Features() {
<div className="absolute inset-0 rounded-lg bg-white max-lg:rounded-b-4xl lg:rounded-br-4xl" /> <div className="absolute inset-0 rounded-lg bg-white max-lg:rounded-b-4xl lg:rounded-br-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-br-[calc(2rem+1px)]"> <div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-br-[calc(2rem+1px)]">
<ContentDistribution className="h-80" /> <ContentDistribution className="h-80" />
<div className="p-10 pt-4"> <div className="p-6 pt-4">
<h3 className="text-sm/4 font-semibold text-cyan-500">Delivery</h3> <h3 className="text-sm/4 font-semibold text-cyan-500">Delivery</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-950"> <p className="mt-2 text-lg font-medium tracking-tight text-gray-950">
Decentralized content distribution Decentralized content distribution
@@ -106,6 +111,9 @@ export function Features() {
</div> </div>
</div> </div>
</div> </div>
{/* ✅ Bottom full-width line + spacer */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl mx-auto py-6 border-x border-gray-100 border-t-0 border-b-0" />
</section> </section>
) )
} }

View File

@@ -2,6 +2,7 @@ import { useId } from 'react'
import { Container } from '@/components/Container' import { Container } from '@/components/Container'
import { Button } from '@/components/Button' import { Button } from '@/components/Button'
import phoneFrame from '../../images/phoneframe.png' import phoneFrame from '../../images/phoneframe.png'
import { H3, Eyebrow, P, CT, CP } from "@/components/Texts";
function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) { function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
let id = useId() let id = useId()
@@ -74,24 +75,24 @@ function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
export function Hero() { export function Hero() {
return ( return (
<div className="overflow-hidden pb-24 lg:py-32 lg:pb-0"> <div className="overflow-hidden pb-24 lg:py-12 mt-10 lg:pb-0 border border-t-0 border-b border-gray-100">
<Container> <Container>
<div className="flex flex-col-reverse gap-y-16 lg:grid lg:grid-cols-12 lg:gap-x-8 lg:gap-y-20"> <div className="flex flex-col-reverse gap-y-16 lg:grid lg:grid-cols-12 lg:gap-x-8 lg:gap-y-20 px-6 lg:px-8">
<div className="relative z-10 mx-auto max-w-2xl lg:col-span-7 lg:max-w-none lg:pt-6 xl:col-span-6"> <div className="relative z-10 mx-auto max-w-2xl lg:col-span-7 lg:max-w-none lg:pt-6 xl:col-span-6">
<h1 className="text-4xl font-medium tracking-tight text-gray-900 lg:text-6xl"> <H3 className="mb-4">
Mycelium Network Mycelium Network
</h1> </H3>
<h2 className="mt-6 text-xl leading-normal tracking-tight text-gray-600 lg:text-2xl"> <CT className="mt-8 font-medium text-gray-600 ">
Encrypted Peer-to-Peer Connectivity Across the Globe Encrypted Peer-to-Peer Connectivity Across the Globe
</h2> </CT>
<p className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal"> <P className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
Mycelium Network provides an unbreakable sovereign IPv6 mesh that connects people, nodes, and applications directly, with no central servers. Mycelium Network provides an unbreakable sovereign IPv6 mesh that connects people, nodes, and applications directly, with no central servers.
</p> </P>
<p className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal"> <P className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
Works Alone. Works Together. Works Alone. Works Together.
Mycelium Network can be used standalone, or together with Mycelium Cloud Mycelium Network can be used standalone, or together with Mycelium Cloud
for full-stack sovereignty. for full-stack sovereignty.
</p> </P>
<div className="mt-8 flex flex-wrap gap-x-6 gap-y-4"> <div className="mt-8 flex flex-wrap gap-x-6 gap-y-4">
<Button to="/download" variant="solid" color="cyan"> <Button to="/download" variant="solid" color="cyan">
Get Mycelium Connector Get Mycelium Connector

View File

@@ -4,62 +4,94 @@ import {
ArrowPathRoundedSquareIcon, ArrowPathRoundedSquareIcon,
NoSymbolIcon, NoSymbolIcon,
} from '@heroicons/react/24/solid' } from '@heroicons/react/24/solid'
import { Container } from '@/components/Container'
import { Eyebrow, H3, P, CT, CP } from '@/components/Texts'
const capabilities = [ import { Eyebrow, H4, P } from '@/components/Texts'
{
name: 'End-to-End Encrypted Mesh',
description: 'Every packet is encrypted and routed peer-to-peer.',
icon: LockClosedIcon,
},
{
name: 'Global IPv6 Address Space',
description: 'Every node, app, and service gets its own private address.',
icon: GlobeAltIcon,
},
{
name: 'Self-Healing Routing',
description: 'Traffic automatically finds the fastest, most resilient path.',
icon: ArrowPathRoundedSquareIcon,
},
{
name: 'No Central Control',
description: 'No servers to trust, no middlemen, no corporate choke-points.',
icon: NoSymbolIcon,
},
]
export function NetworkCapabilities() { export function NetworkCapabilities() {
return ( return (
<section className="bg-white py-24 sm:py-32"> <section className="w-full max-w-8xl mx-auto bg-[#121212]">
<Container>
<div className="mx-auto max-w-3xl text-center"> {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
<div className="w-full border-t border-l border-r border-gray-800" />
{/* ✅ Main content */}
<div className="mx-auto max-w-7xl px-6 bg-[#111111] lg:px-8 grid grid-cols-1 lg:grid-cols-2 gap-20 py-12 border border-t-0 border-b-0 border-gray-800">
{/* ✅ LEFT SIDE — Title + Intro */}
<div className="max-w-xl ">
<Eyebrow>WHAT IT ENABLES</Eyebrow> <Eyebrow>WHAT IT ENABLES</Eyebrow>
<H3 className="mt-4 text-gray-900">
<H4 className="mt-6 text-white">
A Private Networking Layer for Everything You Run A Private Networking Layer for Everything You Run
</H3> </H4>
<P className="mt-6 text-gray-600">
<P className="mt-6 text-gray-200">
Mycelium Network is the backbone for secure, autonomous connectivity Mycelium Network is the backbone for secure, autonomous connectivity
across devices, data centers, clusters, and self-hosted environments, across devices, data centers, clusters, and self-hosted environments anywhere in the world.
anywhere in the world. </P>
<P className="mt-3 text-lg text-gray-200">
Every node gets its own encrypted identity and address space, forming a
zero-trust mesh without any centralized controller.
</P> </P>
</div> </div>
<div className="mx-auto mt-16 max-w-5xl"> {/* ✅ RIGHT SIDE — 4 stacked features */}
<dl className="grid grid-cols-1 gap-12 sm:grid-cols-2 lg:grid-cols-4"> <div className="space-y-8">
{capabilities.map((item) => (
<div key={item.name} className="flex flex-col text-center"> {/* 1 — Encrypted Mesh */}
<div className="mx-auto flex size-12 items-center justify-center rounded-xl bg-cyan-50"> <div>
<item.icon className="size-6 text-cyan-600" aria-hidden="true" /> <h3 className="text-lg font-semibold text-white flex items-center">
<LockClosedIcon className="h-6 w-6 text-cyan-500 mr-3" />
End-to-End Encrypted Mesh
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Every packet is encrypted and routed peer-to-peer no intermediaries, no sniffing, no compromise.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div> </div>
<CT className="mt-6 text-gray-900">{item.name}</CT>
<CP className="mt-2 text-gray-600">{item.description}</CP> {/* 2 — IPv6 Space */}
<div>
<h3 className="text-lg font-semibold text-white flex items-center">
<GlobeAltIcon className="h-6 w-6 text-cyan-500 mr-3" />
Global IPv6 Address Space
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Every node, app, and microservice gets an address solving discovery, routing, and NAT issues forever.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div> </div>
))}
</dl> {/* 3 — Self-Healing Routing */}
<div>
<h3 className="text-lg font-semibold text-white flex items-center">
<ArrowPathRoundedSquareIcon className="h-6 w-6 text-cyan-500 mr-3" />
Self-Healing Routing
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Traffic automatically finds the fastest path, dynamically re-routing around failures or congestion.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div> </div>
</Container>
{/* 4 — No Central Control */}
<div>
<h3 className="text-lg font-semibold text-white flex items-center">
<NoSymbolIcon className="h-6 w-6 text-cyan-500 mr-3" />
No Central Control
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
No servers to trust, no corporate choke points, and no authority that can turn you off.
</p>
</div>
</div>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</section> </section>
) )
} }

View File

@@ -1,64 +1,125 @@
import { Container } from '@/components/Container' "use client";
import { Eyebrow, SectionHeader, P } from '@/components/Texts'
import { useRef } from "react";
import { Eyebrow, SectionHeader, P, CT, CP } from "@/components/Texts";
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
import {
LockClosedIcon,
ArrowPathIcon,
GlobeAltIcon,
} from "@heroicons/react/24/solid";
const networkUseCases = [ const networkUseCases = [
{ {
title: 'Secure Access to Self-Hosted Services', isIntro: true,
eyebrow: "USE CASES",
title: "Private Connectivity for People, Services, and Infrastructures",
description: description:
'Access your services, VMs, and clusters remotely without VPNs, public IPs, or port forwarding.', "Mycelium Network provides a secure, autonomous communication layer that works across homes, clouds, edge workloads, and global deployments.",
ideal:
'Ideal for: homelabs, personal clouds, long-running self-hosted stacks',
}, },
{ {
title: 'Service-to-Service Networking Across Environments', title: "Secure Access to Self-Hosted Services",
description: description:
'Connect applications running across home labs, cloud regions, edge nodes, and data centers all on one address space.', "Access your services, VMs, and clusters remotely without VPNs, public IPs, or port forwarding.",
ideal: ideal: "Ideal for: homelabs, personal clouds, long-running self-hosted stacks",
'Ideal for: dev teams, distributed apps, container + K3s workloads', icon: LockClosedIcon,
}, },
{ {
title: 'Resilient Connectivity Across Regions & Outages', title: "Service-to-Service Networking Across Environments",
description: description:
'Connect systems across countries, datacenters, edge locations, and remote deployments — with routing that automatically heals around ISP failures, censorship, and regional outages.', "Connect applications running across home labs, cloud regions, edge nodes, and data centers all on one address space.",
ideal: ideal: "Ideal for: dev teams, distributed apps, container + K3s workloads",
'Ideal for: research networks, cross-border orgs, distributed compute, off-grid / rural deployments', icon: GlobeAltIcon,
}, },
] {
title: "Resilient Connectivity Across Regions & Outages",
description:
"Connect systems across countries, datacenters, edge locations, and remote deployments — with routing that automatically heals around ISP failures, censorship, and regional outages.",
ideal:
"Ideal for: research networks, cross-border orgs, distributed compute, off-grid / rural deployments",
icon: ArrowPathIcon,
},
];
export function NetworkUsecases() { export function NetworkUsecases() {
const sliderRef = useRef<HTMLUListElement>(null);
const scrollLeft = () =>
sliderRef.current?.scrollBy({ left: -400, behavior: "smooth" });
const scrollRight = () =>
sliderRef.current?.scrollBy({ left: 400, behavior: "smooth" });
return ( return (
<section className="bg-white py-24 sm:py-32"> <section className="bg-white w-full max-w-8xl mx-auto">
<Container> <div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-slate-200" />
<div className="mx-auto max-w-3xl text-center"> <div className="w-full border-t border-l border-r border-slate-200" />
<Eyebrow>USE CASES</Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-slate-200 bg-white overflow-hidden">
Private Connectivity for People, Services, and Infrastructures <ul
ref={sliderRef}
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
>
{networkUseCases.map((item, idx) => (
<li
key={idx}
className={`snap-start shrink-0 w-[85%] sm:w-[50%] lg:w-[33%] border border-slate-200 p-10 relative ${
item.isIntro ? "bg-gray-50/80" : "bg-white"
}`}
>
{item.isIntro ? (
<div className="flex flex-col justify-between h-full">
<div>
<Eyebrow>{item.eyebrow}</Eyebrow>
<SectionHeader
as="h3"
className="mt-4 text-gray-900 text-xl lg:text-2xl"
>
{item.title}
</SectionHeader> </SectionHeader>
<P className="mt-6 text-gray-600"> <P className="mt-4 text-gray-600 text-sm lg:text-base">
Mycelium Network provides a secure, autonomous communication layer {item.description}
that works across homes, clouds, edge workloads, and global deployments.
</P> </P>
</div> </div>
<div className="mx-auto mt-16 max-w-5xl grid gap-8 lg:grid-cols-3"> <div className="flex items-center gap-x-4 mt-2">
{networkUseCases.map((useCase) => ( <button
<div onClick={scrollLeft}
key={useCase.title} className="h-8 w-8 flex items-center justify-center border border-slate-300 rounded-md hover:border-cyan-500 transition-colors"
className="rounded-3xl border border-slate-200 bg-white p-8 shadow-sm transition hover:-translate-y-1 hover:border-cyan-300 hover:shadow-lg"
> >
<h3 className="text-xl font-semibold text-gray-900"> <IoArrowBackOutline className="text-gray-600" size={16} />
{useCase.title} </button>
</h3> <button
<p className="mt-4 text-sm leading-relaxed text-gray-600"> onClick={scrollRight}
{useCase.description} className="h-8 w-8 flex items-center justify-center border border-slate-300 rounded-md hover:border-cyan-500 transition-colors"
</p> >
<p className="mt-4 text-xs font-medium text-cyan-700"> <IoArrowForwardOutline className="text-gray-600" size={16} />
{useCase.ideal} </button>
</p>
</div> </div>
</div>
) : (
<>
{/* ✅ Icon above title */}
<div className="h-10 w-10 flex items-center justify-center rounded-xl bg-gray-100 mb-4">
<item.icon className="h-6 w-6 text-cyan-600" />
</div>
<CT className="text-lg font-semibold text-gray-900">
{item.title}
</CT>
<CP className="mt-2 text-gray-600 leading-snug">
{item.description}
</CP>
<CP className="mt-3 text-xs font-medium text-cyan-700">
{item.ideal}
</CP>
</>
)}
</li>
))} ))}
</ul>
</div> </div>
</Container>
</section> </section>
) );
} }

View File

@@ -407,9 +407,12 @@ export function PrimaryFeatures() {
<section <section
id="howitworks" id="howitworks"
aria-label="Features for investing all your money" aria-label="Features for investing all your money"
className="bg-gray-900 py-20 sm:py-32" className="bg-[#121212]"
> >
<Container> {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-[#121212] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
<div className="w-full border-t border-l border-r border-gray-800" />
<Container className="pt-12 border border-t-0 border-b-0 border-gray-800">
<div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl "> <div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl ">
<Eyebrow color="accent">How It Works</Eyebrow> <Eyebrow color="accent">How It Works</Eyebrow>
<SectionHeader color="white" className="mt-2"> <SectionHeader color="white" className="mt-2">
@@ -425,9 +428,12 @@ export function PrimaryFeatures() {
<div className="mt-16 md:hidden"> <div className="mt-16 md:hidden">
<FeaturesMobile /> <FeaturesMobile />
</div> </div>
<Container className="hidden md:mt-20 md:block"> <Container className="hidden pt-12 pb-12 md:block border border-t-0 border-b-0 border-gray-800">
<FeaturesDesktop /> <FeaturesDesktop />
</Container> </Container>
{/* ✅ bottom border + bottom spacer to match */}
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800 bg-transparent" />
</section> </section>
) )
} }

View File

@@ -187,12 +187,14 @@ function DeviceChartIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
export function SecondaryFeatures() { export function SecondaryFeatures() {
return ( return (
<section <section className="w-full max-w-8xl mx-auto bg-transparent">
id="comingsoon"
aria-label="Features for building a portfolio" {/* ✅ Top horizontal line with spacing */}
className="py-20 sm:py-32" <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
> <div className="w-full border-t border-l border-r border-gray-100" />
<Container>
<Container className="py-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-4xl sm:text-center"> <div className="mx-auto max-w-4xl sm:text-center">
<h2 className="text-base/7 font-semibold text-cyan-500">IN ACTIVE EVOLUTION</h2> <h2 className="text-base/7 font-semibold text-cyan-500">IN ACTIVE EVOLUTION</h2>
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900"> <p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
@@ -204,12 +206,12 @@ export function SecondaryFeatures() {
</div> </div>
<ul <ul
role="list" role="list"
className="mx-auto mt-16 grid max-w-2xl grid-cols-1 gap-6 text-sm sm:mt-20 sm:grid-cols-2 md:gap-y-10 lg:max-w-none lg:grid-cols-3" className="mx-auto mt-12 grid max-w-2xl grid-cols-1 gap-6 text-sm sm:grid-cols-2 md:gap-y-10 lg:max-w-none lg:grid-cols-3"
> >
{features.map((feature) => ( {features.map((feature) => (
<li <li
key={feature.name} key={feature.name}
className="rounded-2xl border border-gray-200 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20" className="rounded-2xl border border-gray-100 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20"
> >
<feature.icon className="h-8 w-8" /> <feature.icon className="h-8 w-8" />
<h3 className="mt-6 font-semibold text-gray-900"> <h3 className="mt-6 font-semibold text-gray-900">
@@ -220,6 +222,9 @@ export function SecondaryFeatures() {
))} ))}
</ul> </ul>
</Container> </Container>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</section> </section>
) )
} }

View File

@@ -1,48 +1,66 @@
import { CircleBackground } from '../../components/CircleBackground' "use client";
import { Container } from '@/components/Container'
import { Button } from '@/components/Button' import { Container } from "@/components/Container";
import { Button } from "@/components/Button";
export function CallToAction() { export function CallToAction() {
return ( return (
<section <section className="relative overflow-hidden bg-gray-900">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-700"></div>
<div className="w-full border-t border-l border-r border-gray-700" />
{/* ✅ Main boxed area */}
<div
id="get-started" id="get-started"
className="relative overflow-hidden bg-gray-900 py-20 sm:py-28" className="relative py-18 max-w-7xl mx-auto bg-[#090909] border border-t-0 border-b-0 border-gray-700"
> >
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<CircleBackground color="#06b6d4" className="animate-spin-slower" />
</div>
<Container className="relative"> <Container className="relative">
<div className="mx-auto max-w-2xl text-center"> <div className="mx-auto max-w-3xl text-center">
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl"> <h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
Choose How You Want to Start Choose How You Want to Start
</h2> </h2>
<p className="mt-6 text-lg text-gray-300"> <p className="mt-6 text-lg text-gray-300">
Store data in your Mycelium Cloud environment Store data in your Mycelium Cloud environment
or host your own node for full sovereignty. or host your own node for full sovereignty.
</p> </p>
<div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4">
{/* ✅ Two cards, stacked center with spacing */}
<div className="mt-8 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="flex flex-col items-center text-center max-w-xs">
<Button <Button
to="https://myceliumcloud.tf" to="https://myceliumcloud.tf"
as="a" as="a"
variant="solid" variant="solid"
color="white" color="cyan"
className="mt-4"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
> >
Use Storage in Cloud Use Storage in Cloud
</Button> </Button>
</div>
<div className="flex flex-col items-center text-center max-w-xs">
<Button <Button
to="#storage-developer-experience" to="#storage-developer-experience"
as="a" as="a"
variant="outline" variant="outline"
color="white" color="white"
className="mt-4"
> >
Host a Node Host a Node
</Button> </Button>
</div> </div>
</div> </div>
</div>
</Container> </Container>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-700" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-700 bg-transparent" />
</section> </section>
) );
} }

View File

@@ -1,54 +1,81 @@
import { Container } from '@/components/Container' "use client";
import { Eyebrow, SectionHeader, P } from '@/components/Texts'
import { useState } from "react";
import { Container } from "@/components/Container";
import { Eyebrow, SectionHeader, P, H3, H4, H5, CT, CP } from "@/components/Texts";
const architecture = [ const architecture = [
{ {
title: 'Encrypted Storage Substrate', title: "Encrypted Storage Substrate",
description: 'Keeps data private and verifiable.', description: "Keeps data private and verifiable.",
}, },
{ {
title: 'Mesh Routing Layer', title: "Mesh Routing Layer",
description: 'Connects clients and workloads securely, anywhere.', description: "Connects clients and workloads securely, anywhere.",
}, },
{ {
title: 'Protocol Gateway Layer', title: "Protocol Gateway Layer",
description: description:
'Serve the same dataset over S3, IPFS, WebDAV, or HTTP.', "Serve the same dataset over S3, IPFS, WebDAV, or HTTP.",
}, },
] ];
export function StorageArchitecture() { export function StorageArchitecture() {
const [active, setActive] = useState(0);
return ( return (
<section className="bg-gray-50 py-24 sm:py-32"> <section className="bg-[#121212] w-full max-w-8xl mx-auto">
<Container> {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
<div className="w-full border-t border-l border-r border-gray-800" />
{/* ✅ Boxed container */}
<Container className="bg-[#111111] w-full max-w-7xl mx-auto py-12 border border-t-0 border-b-0 border-gray-800">
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow>ARCHITECTURE</Eyebrow> <Eyebrow>ARCHITECTURE</Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <H3 className="mt-4 text-white">
HOW IT WORKS How it Works
</SectionHeader> </H3>
<P className="mt-6 text-gray-600"> <P className="mt-6 text-gray-400">
A layered design that encrypts, routes, and exposes storage through A layered design that encrypts, routes, and exposes storage through
multiple protocols without duplicating data or compromising multiple protocols without duplicating data or compromising
sovereignty. sovereignty.
</P> </P>
</div> </div>
<div className="mx-auto mt-16 max-w-4xl space-y-6"> {/* ✅ New 2-column layout */}
{architecture.map((item) => ( <div className="mx-auto mt-8 grid max-w-5xl grid-cols-1 gap-2 lg:grid-cols-3 bg-[#121212] ">
<div {/* LEFT — 1 column (3 rows) */}
<div className="space-y-2">
{architecture.map((item, index) => (
<button
key={item.title} key={item.title}
className="rounded-3xl border border-slate-200 bg-white p-8 shadow-sm transition hover:-translate-y-1 hover:border-cyan-300 hover:shadow-lg" className={`w-full border bg-[#171717] text-left border-white/10 p-4 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 hover:bg-white/8
${active === index
? "border-cyan-400 shadow-md"
: "border-gray-800 hover:border-cyan-200 hover:shadow-sm"}`}
onClick={() => setActive(index)}
> >
<h3 className="text-xl font-semibold text-gray-900"> <CP className="text-white font-semibold">{item.title}</CP>
{item.title} </button>
</h3>
<p className="mt-3 text-sm leading-relaxed text-gray-600">
{item.description}
</p>
</div>
))} ))}
</div> </div>
{/* RIGHT — 2 columns */}
<div className="lg:col-span-2 flex items-center justify-center border border-gray-800 bg-[#171717] p-10 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 hover:bg-white/8" >
<div
key={active} // ✅ force smooth transition
className="transition-opacity duration-300 opacity-100 animate-fade"
>
<H5 className="text-white">{architecture[active].title}</H5>
<P className="mt-2 text-gray-400 max-w-xl">
{architecture[active].description}
</P>
</div>
</div>
</div>
</Container> </Container>
<div className="w-full border-b border-gray-800 bg-[#121212]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
</section> </section>
) );
} }

View File

@@ -0,0 +1,110 @@
"use client";
import { useRef } from "react";
import { Eyebrow, CP, CT, H5 } from "@/components/Texts";
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
const capabilities = [
{
isIntro: true,
eyebrow: "CAPABILITIES",
title: "Flexible, Resilient, and Controllable Storage",
description:
"Mycelium Storage is designed for modern data workloads, providing a range of access methods and control over data placement.",
},
{
title: "S3-Compatible Object Storage",
description: "Works with existing SDKs & tooling.",
imageUrl: "/images/s3.png",
},
{
title: "IPFS & Content-Addressed Access",
description: "Ideal for distributed and decentralized workloads.",
imageUrl: "/images/ipfs.png",
},
{
title: "Filesystem Mounts (WebDAV / POSIX)",
description: "Mount storage directly into workflows and apps.",
imageUrl: "/images/filesystem.png",
},
{
title: "Encrypted Replication & Placement Control",
description: "Choose data's ownership and locations.",
imageUrl: "/images/encrypted.png",
},
];
export function StorageCapabilitiesNew() {
const sliderRef = useRef<HTMLUListElement>(null);
const scrollLeft = () => sliderRef.current?.scrollBy({ left: -400, behavior: "smooth" });
const scrollRight = () => sliderRef.current?.scrollBy({ left: 400, behavior: "smooth" });
return (
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
<div className="w-full border-t border-l border-r border-gray-800" />
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-800 bg-[#111111] overflow-hidden">
{/* Horizontal Slider — shows part of next card */}
<ul
ref={sliderRef}
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
>
{capabilities.map((item, idx) => (
<li
key={idx}
className={`snap-start shrink-0 w-[85%] sm:w-[50%] lg:w-[33%] border border-gray-800 relative ${item.isIntro ? ' p-10' : 'bg-cover bg-center'}`}
style={item.imageUrl ? { backgroundImage: `url(${item.imageUrl})` } : {}}
>
<div className={`relative z-10 flex flex-col h-full ${item.isIntro ? 'justify-between' : 'justify-end'}`}>
{/* First card with arrows */}
{item.isIntro ? (
<div className="flex flex-col justify-between h-full ">
<div>
<Eyebrow className="">{item.eyebrow}</Eyebrow>
<H5 className="text-white mt-4 lg:text-2xl text-xl">{item.title}</H5>
<p className="mt-4 text-gray-400 lg:text-lg text-sm leading-relaxed">{item.description}</p>
</div>
{/* Arrows inside first card */}
<div className="flex items-center gap-x-4 mt-2">
<a
href="#"
className="inline-flex items-center gap-1 text-cyan-400 hover:text-cyan-300 text-sm font-medium mr-auto"
>
Learn more
</a>
<button
onClick={scrollLeft}
className="h-8 w-8 flex items-center justify-center border border-gray-700 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowBackOutline className="text-gray-300" size={16} />
</button>
<button
onClick={scrollRight}
className="h-8 w-8 flex items-center justify-center border border-gray-700 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowForwardOutline className="text-gray-300" size={16} />
</button>
</div>
</div>
) : (
<div className="bg-[#111111] p-6 h-20 flex flex-col justify-center border-t border-b-0 border-gray-800">
<p className="text-base font-semibold text-white">{item.title}</p>
<p className="mt-2 text-gray-400 leading-snug">{item.description}</p>
</div>
)}
</div>
</li>
))}
</ul>
</div>
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
</section>
);
}

View File

@@ -0,0 +1,76 @@
"use client";
import { Container } from "@/components/Container";
import { H3, P, Eyebrow, CT, CP } from "@/components/Texts";
import Encrypted from "./animation/Encrypted";
import SelfHealing from "./animation/SelfHealing";
import Residency from "./animation/Residency";
export function StorageCoreValue() {
const values = [
{ id: "Encrypted",
title: "Encrypted and verifiable at rest and in motion",
href: "#",
animation: Encrypted,
},
{ id: "SelfHealing",
title: "Self-healing replication and integrity checks",
href: "#",
animation: SelfHealing,
},
{ id: "Residency",
title: "Residency + governance policies you actually control",
href: "#",
animation: Residency,
},
]
return (
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-100" />
{/* ✅ Boxed container */}
<div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-100">
<Container>
<div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-500">Featured Blueprint</Eyebrow>
<H3 className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900 mt-2">
Sovereign Storage That Heals Itself
</H3>
<P className="mt-6 text-lg text-gray-600">
Mycelium Storage continuously verifies integrity and restores replicas automatically, so data stays available without operational overhead.
</P>
</div>
{/* ✅ 3x2 logo grid */}
<div className="mt-12 grid grid-cols-3 gap-x-8 gap-y-12">
{values.map((value, i) => (
<a
key={i}
href={value.href}
target="_blank"
rel="noopener noreferrer"
className="flex flex-col items-center text-center p-6 border border-gray-200 rounded-lg transition-transform duration-300 hover:scale-105 hover:shadow-lg"
>
<value.animation />
<CT className="text-gray-900 mt-4 font-semibold">
{value.title}
</CT>
</a>
))}
</div>
</Container>
</div>
{/* ✅ Bottom line + bottom spacer */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100 bg-transparent" />
</section>
);
}

View File

@@ -8,7 +8,7 @@ export function StorageHero() {
<div className=""> <div className="">
{/* Boxed container */} {/* Boxed container */}
<div <div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-200 bg-white overflow-hidden bg-contain bg-right bg-no-repeat" className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/computehero11.webp')", backgroundSize: "contain" }} style={{ backgroundImage: "url('/images/computehero11.webp')", backgroundSize: "contain" }}
> >
{/* Inner padding */} {/* Inner padding */}
@@ -37,8 +37,8 @@ export function StorageHero() {
</div> </div>
</div> </div>
{/* ✅ Bottom horizontal line with spacing */} {/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-200" /> <div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div> </div>
) )
} }

View File

@@ -1,4 +1,3 @@
import { Container } from '@/components/Container'
import { Eyebrow, SectionHeader, P, Small } from '@/components/Texts' import { Eyebrow, SectionHeader, P, Small } from '@/components/Texts'
const highlights = [ const highlights = [
@@ -24,27 +23,17 @@ const highlights = [
export function StorageOverview() { export function StorageOverview() {
return ( return (
<section className="bg-gray-950 py-24 sm:py-32"> <section className="bg-[#121212] w-full max-w-8xl mx-auto">
<Container> {/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-800" />
<div className="w-full border-t border-l border-r border-gray-800" />
<div className="mx-auto max-w-3xl text-center"> <div className="bg-[#121212] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-800">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-300"> <div className="grid lg:grid-cols-3">
Platform Overview
</Eyebrow>
<SectionHeader as="h2" color="light" className="mt-6 font-medium">
Core Features
</SectionHeader>
<P color="lightSecondary" className="mt-6">
Built on sovereign infrastructure, Mycelium Storage keeps data
resilient, verifiable, and instantly accessible. Encryption,
replication, and governance are woven directly into the substrate.
</P>
</div>
<div className="mt-16 grid gap-8 lg:grid-cols-3">
{highlights.map((item) => ( {highlights.map((item) => (
<div <div
key={item.title} key={item.title}
className="group relative overflow-hidden rounded-3xl border border-white/10 bg-white/4 p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 hover:bg-white/8" className="group relative overflow-hidden border border-white/10 bg-white/4 p-8 backdrop-blur-sm transition hover:border-cyan-300/50 hover:bg-white/8"
> >
<div className="absolute inset-0 bg-linear-to-br from-cyan-500/0 via-white/5 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" /> <div className="absolute inset-0 bg-linear-to-br from-cyan-500/0 via-white/5 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative"> <div className="relative">
@@ -61,7 +50,9 @@ export function StorageOverview() {
</div> </div>
))} ))}
</div> </div>
</Container> </div>
<div className="w-full border-b border-gray-800 bg-[#121212]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
</section> </section>
) )
} }

View File

@@ -2,10 +2,10 @@ import { AnimatedSection } from '../../components/AnimatedSection'
import { StorageHero } from './StorageHero' import { StorageHero } from './StorageHero'
import { StorageOverview } from './StorageOverview' import { StorageOverview } from './StorageOverview'
import { StorageArchitecture } from './StorageArchitecture' import { StorageArchitecture } from './StorageArchitecture'
import { StorageUseCases } from './StorageUseCases'
import { CallToAction } from './CallToAction' import { CallToAction } from './CallToAction'
import { StorageCapabilities } from './StorageCapabilities' import { StorageCapabilitiesNew } from './StorageCapabilitiesNew'
import { StorageDesign } from './StorageDesign' import { StorageCoreValue } from './StorageCoreValue'
import { StorageUseCasesNew } from './StorageUseCasesNew'
export default function StoragePage() { export default function StoragePage() {
return ( return (
@@ -15,11 +15,11 @@ export default function StoragePage() {
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<StorageCapabilities /> <StorageCapabilitiesNew />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<StorageDesign /> <StorageCoreValue />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
@@ -31,9 +31,10 @@ export default function StoragePage() {
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<StorageUseCases /> <StorageUseCasesNew />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CallToAction /> <CallToAction />
</AnimatedSection> </AnimatedSection>

View File

@@ -0,0 +1,108 @@
"use client";
import { useState } from "react";
import { Eyebrow, H3, P } from "@/components/Texts";
const tabs = [
{
id: "distributed",
label: "Distributed Application Storage",
content: [
{
item: "Application-native storage",
desc: "Serve data to services, agents, clusters, or edge workloads.",
},
],
},
{
id: "sovereignty",
label: "Data Sovereignty & Compliance",
content: [
{
item: "Residency-aware storage",
desc: "Keep data under your control, choose residency per dataset.",
},
],
},
{
id: "distribution",
label: "Content Distribution",
content: [
{
item: "Decentralized delivery",
desc: "Serve public or private assets globally, without centralized hosting.",
},
],
},
];
export function StorageUseCasesNew() {
const [active, setActive] = useState("distributed");
const current = tabs.find((t) => t.id === active)!;
return (
<section className="relative w-full overflow-hidden">
{/* Top lines */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div>
<div className="w-full border-t border-l border-r border-gray-200" />
<div className="max-w-7xl mx-auto px-6 lg:px-8 py-12 border border-t-0 border-b-0 border-gray-200 bg-white overflow-hidden">
{/* ✅ Two columns: ALL TEXT LEFT, IMAGE RIGHT */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16">
{/* LEFT COLUMN: Full tab + content */}
<div className="w-full text-gray-900">
<Eyebrow color="accent">Use Cases</Eyebrow>
<H3>Built for Real Data Workloads</H3>
<P className="max-w-3xl text-gray-600 mt-4">
Mycelium Storage adapts to compliance-driven enterprise data, distributed application workloads,
and global asset delivery without giving up sovereignty.
</P>
{/* Tabs */}
<div className="flex gap-6 border-b border-gray-200 pb-2 overflow-x-auto mt-12">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActive(tab.id)}
className={`text-sm font-medium tracking-wide pb-2 whitespace-nowrap ${
active === tab.id
? "border-b-2 border-cyan-500 text-gray-900"
: "text-gray-500 hover:text-gray-900"
}`}
>
{tab.label}
</button>
))}
</div>
{/* Content always stacked in a single column */}
<div className="mt-6 space-y-6">
{current.content.map((c, i) => (
<div key={i}>
<p className="text-base font-medium text-gray-900">{c.item}</p>
<p className="text-sm text-gray-600 leading-relaxed">{c.desc}</p>
</div>
))}
</div>
</div>
{/* RIGHT COLUMN: Image */}
<div className="w-full">
<img
src="/images/testpic.png"
alt="Storage Illustration"
className="w-full h-auto rounded-xl border border-gray-200 object-cover"
/>
</div>
</div>
</div>
{/* Bottom lines */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
<div className="w-full border-b border-gray-200" />
</section>
);
}

View File

@@ -0,0 +1,193 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
gridStroke?: string;
stroke?: string;
};
const W = 760;
const H = 420;
export default function Encrypted({
className,
accent = "#00b8db",
gridStroke = "#e5e7eb",
stroke = "#111111",
}: Props) {
const prefers = useReducedMotion();
// positions of storage vaults (cylindrical stack illusion)
const vaults = [
{ x: 200, y: 220 },
{ x: 380, y: 180 },
{ x: 560, y: 220 },
];
// path representing encrypted data moving across storage nodes
const dataPath = `M ${vaults[0].x + 60} ${vaults[0].y}
C 280 160, 480 160, ${vaults[2].x} ${vaults[2].y}`;
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="Mycelium Storage: encrypted and verifiable at rest and in motion"
style={{ background: "transparent" }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* === Background Grid (light mode) === */}
<defs>
<pattern id="grid-light" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.6" />
</pattern>
<filter id="cyan-glow">
<feGaussianBlur stdDeviation="3" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect width={W} height={H} fill="url(#grid-light)" />
{/* === Storage Vaults (cylinders) === */}
{vaults.map((v, i) => (
<g key={i} transform={`translate(${v.x}, ${v.y})`}>
{/* Top ellipse */}
<ellipse cx="0" cy="-30" rx="50" ry="14" fill="none" stroke={stroke} strokeWidth="2" />
{/* Body */}
<rect
x="-50"
y="-30"
width="100"
height="60"
rx="12"
fill="none"
stroke={stroke}
strokeWidth="2"
/>
{/* Bottom ellipse (front face) */}
<ellipse cx="0" cy="30" rx="50" ry="14" fill="none" stroke={stroke} strokeWidth="2" />
{/* subtle cyan glow ring to mark encryption */}
<motion.ellipse
cx="0"
cy="0"
rx="55"
ry="18"
fill="none"
stroke={accent}
strokeWidth="2"
initial={{ opacity: 0 }}
animate={{ opacity: [0.15, 0.4, 0.15] }}
transition={{
delay: i * 0.3,
duration: 2.2,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
/>
</g>
))}
{/* === Encrypted data movement path === */}
<motion.path
d={dataPath}
fill="none"
stroke={stroke}
strokeWidth={2}
strokeLinecap="round"
strokeDasharray="6"
opacity="0.5"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 1.2, ease: [0.22, 1, 0.36, 1] }}
/>
{/* === Encrypted packets traveling === */}
{!prefers && (
<motion.circle
r={6}
fill={accent}
style={{ offsetPath: `path('${dataPath}')` }}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0.3, 1, 0.3],
}}
transition={{
duration: 2.8,
repeat: Infinity,
repeatType: "loop",
ease: "linear",
}}
filter="url(#cyan-glow)"
/>
)}
{/* === Verification shield (top-right) === */}
<motion.path
d={`M 620 120
L 645 135
L 640 165
L 620 175
L 600 165
L 595 135
Z`}
fill="none"
stroke={accent}
strokeWidth={2.5}
strokeLinecap="round"
strokeLinejoin="round"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{ duration: 1, delay: 0.6, ease: [0.22, 1, 0.36, 1] }}
filter="url(#cyan-glow)"
/>
{/* === Verification checkmark === */}
<motion.path
d="M 606 150 L 617 162 L 635 140"
fill="none"
stroke={accent}
strokeWidth={3}
strokeLinecap="round"
strokeLinejoin="round"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.8, delay: 1.2 }}
filter="url(#cyan-glow)"
/>
{/* === Cyan verification pulse === */}
{!prefers && (
<motion.circle
cx="620"
cy="150"
r="24"
stroke={accent}
strokeWidth="2"
fill="none"
initial={{ scale: 1, opacity: 0 }}
animate={{
scale: [1, 1.25, 1.4],
opacity: [0.25, 0.6, 0],
}}
transition={{
duration: 1.8,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
/>
)}
</svg>
</div>
);
}

View File

@@ -0,0 +1,223 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
gridStroke?: string;
stroke?: string;
};
const W = 760;
const H = 420;
export default function Residency({
className,
accent = "#00b8db",
gridStroke = "#e5e7eb",
stroke = "#111111",
}: Props) {
const prefers = useReducedMotion();
// Layout: central governance node + 3 regional nodes
const center = { x: 380, y: 200 };
const regions = [
{ x: 220, y: 120 },
{ x: 540, y: 120 },
{ x: 380, y: 300 },
];
// Path for data transfer (circular motion between regions)
const flowPath = `M ${regions[0].x} ${regions[0].y}
C 300 80, 460 80, ${regions[1].x} ${regions[1].y}
C 480 160, 420 260, ${regions[2].x} ${regions[2].y}
C 340 260, 280 160, ${regions[0].x} ${regions[0].y} Z`;
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
style={{ background: "transparent" }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* ✅ Subtle light grid (same as Encrypted.tsx) */}
<defs>
<pattern id="grid-residency" width="28" height="28" patternUnits="userSpaceOnUse">
<path
d="M 28 0 L 0 0 0 28"
fill="none"
stroke={gridStroke}
strokeWidth="1"
opacity="0.4"
/>
</pattern>
<filter id="res-glow">
<feGaussianBlur stdDeviation="3" result="b" />
<feMerge>
<feMergeNode in="b" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect width={W} height={H} fill="url(#grid-residency)" />
{/* ✅ Base dotted jurisdiction boundary */}
<circle
cx={center.x}
cy={center.y}
r={140}
fill="none"
stroke={stroke}
strokeWidth={2}
strokeDasharray="6 6"
opacity="0.3"
/>
{/* ✅ Cyan policy ring expanding + fading */}
{!prefers && (
<motion.circle
cx={center.x}
cy={center.y}
r={140}
stroke={accent}
strokeWidth={2}
fill="none"
initial={{ scale: 0.9, opacity: 0 }}
animate={{
scale: [1, 1.15, 1.3],
opacity: [0.15, 0.4, 0],
}}
transition={{
duration: 2.8,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
filter="url(#res-glow)"
/>
)}
{/* ✅ Cyan glow radius (policy control zone) */}
{!prefers && (
<motion.circle
cx={center.x}
cy={center.y}
r={60}
fill={accent}
opacity={0.08}
initial={{ scale: 1, opacity: 0.05 }}
animate={{
opacity: [0.05, 0.15, 0.05],
scale: [1, 1.05, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
/>
)}
{/* ✅ Central governance node */}
<circle
cx={center.x}
cy={center.y}
r={28}
fill="#fff"
stroke={stroke}
strokeWidth={2}
/>
<circle
cx={center.x}
cy={center.y}
r={12}
fill={accent}
stroke={stroke}
strokeWidth={2}
filter="url(#res-glow)"
/>
{/* ✅ Regional nodes */}
{regions.map((r, i) => (
<g key={i}>
<circle
cx={r.x}
cy={r.y}
r={22}
fill="#fff"
stroke={stroke}
strokeWidth={2}
/>
<circle
cx={r.x}
cy={r.y}
r={10}
fill="none"
stroke={stroke}
strokeWidth={1.5}
opacity="0.6"
/>
</g>
))}
{/* ✅ Data transfer flow (light dotted path) */}
<motion.path
d={flowPath}
fill="none"
stroke={stroke}
strokeWidth={1.5}
strokeDasharray="4 4"
opacity="0.3"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 1.4 }}
/>
{/* ✅ Cyan packet traveling within jurisdiction */}
{!prefers && (
<motion.circle
r={6}
fill={accent}
style={{ offsetPath: `path('${flowPath}')` }}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0.3, 1, 0.3],
}}
transition={{
duration: 4,
repeat: Infinity,
ease: "linear",
}}
filter="url(#res-glow)"
/>
)}
{/* ✅ Governance shield icon */}
<motion.path
d={`M ${center.x} ${center.y - 70}
L ${center.x + 20} ${center.y - 60}
L ${center.x + 16} ${center.y - 35}
L ${center.x} ${center.y - 25}
L ${center.x - 16} ${center.y - 35}
L ${center.x - 20} ${center.y - 60}
Z`}
fill="none"
stroke={accent}
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 1.2, ease: [0.22, 1, 0.36, 1] }}
filter="url(#res-glow)"
/>
</svg>
</div>
);
}

View File

@@ -0,0 +1,214 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
gridStroke?: string;
stroke?: string;
};
const W = 760;
const H = 420;
export default function SelfHealing({
className,
accent = "#00b8db",
gridStroke = "#e5e7eb",
stroke = "#111111",
}: Props) {
const prefers = useReducedMotion();
// diamond node layout
const nodes = [
{ x: 380, y: 130 }, // top
{ x: 240, y: 240 }, // left
{ x: 520, y: 240 }, // right
{ x: 380, y: 320 }, // bottom
];
// connection paths
const links = [
[0, 1],
[0, 2],
[1, 3],
[2, 3],
[1, 2],
];
// helper for path drawing
const drawLine = (i: number, j: number) => {
const a = nodes[i];
const b = nodes[j];
return `M ${a.x} ${a.y} L ${b.x} ${b.y}`;
};
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
style={{ background: "transparent" }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* ✅ Subtle grid (same as Encrypted.tsx) */}
<defs>
<pattern id="grid-heal" width="28" height="28" patternUnits="userSpaceOnUse">
<path
d="M 28 0 L 0 0 0 28"
fill="none"
stroke={gridStroke}
strokeWidth="1"
opacity="0.4"
/>
</pattern>
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="b" />
<feMerge>
<feMergeNode in="b" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect width={W} height={H} fill="url(#grid-heal)" />
{/* ✅ Static network links */}
{links.map(([i, j], idx) => (
<motion.path
key={idx}
d={drawLine(i, j)}
stroke={stroke}
strokeWidth={2}
strokeLinecap="round"
fill="none"
opacity="0.25"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.8, delay: idx * 0.1 }}
/>
))}
{/* ✅ Circulating health-check pulse */}
{!prefers &&
[0, 1, 2, 3].map((i) => {
const next = (i + 1) % 4;
const path = drawLine(i, next);
return (
<motion.circle
key={`pulse-${i}`}
r={5}
fill={accent}
style={{ offsetPath: `path('${path}')` }}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0.1, 0.9, 0.1],
}}
transition={{
duration: 2.8,
delay: i * 0.4,
repeat: Infinity,
ease: "linear",
}}
filter="url(#glow)"
/>
);
})}
{/* ✅ Nodes */}
{nodes.map((n, i) => (
<g key={`node-${i}`}>
<circle
cx={n.x}
cy={n.y}
r={26}
fill="none"
stroke={stroke}
strokeWidth={2}
opacity="0.8"
/>
<circle
cx={n.x}
cy={n.y}
r={12}
fill="#fff"
stroke={stroke}
strokeWidth={2}
/>
</g>
))}
{/* ✅ Simulated failure (bottom node flickers out, then heals) */}
{!prefers && (
<motion.circle
cx={nodes[3].x}
cy={nodes[3].y}
r={12}
fill="#fff"
stroke={stroke}
strokeWidth={2}
animate={{
opacity: [1, 0.2, 1, 1],
scale: [1, 0.9, 1, 1],
}}
transition={{
duration: 4,
repeat: Infinity,
ease: "easeInOut",
}}
/>
)}
{/* ✅ Healing pulse wave from neighbors → bottom node */}
{!prefers &&
[nodes[1], nodes[2]].map((n, i) => {
const path = `M ${n.x} ${n.y} L ${nodes[3].x} ${nodes[3].y}`;
return (
<motion.circle
key={`heal-${i}`}
r={5}
fill={accent}
style={{ offsetPath: `path('${path}')` }}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0, 1, 0],
}}
transition={{
delay: 1.5 + i * 0.2,
duration: 1.8,
repeat: Infinity,
repeatDelay: 2.2,
ease: "linear",
}}
filter="url(#glow)"
/>
);
})}
{/* ✅ Integrity halo on healed node */}
{!prefers && (
<motion.circle
cx={nodes[3].x}
cy={nodes[3].y}
r={32}
fill="none"
stroke={accent}
strokeWidth={2}
initial={{ opacity: 0 }}
animate={{ opacity: [0.15, 0.4, 0.15], scale: [1, 1.12, 1] }}
transition={{
duration: 2.8,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
filter="url(#glow)"
/>
)}
</svg>
</div>
);
}