20 Commits

Author SHA1 Message Date
a3028ff448 feat: add cyan glow effects and new network resilience animation
- Added cyan radial glow SVG to CallToAction components across all product pages for visual consistency
- Created NoSinglePoint animation demonstrating redundant network paths and resilience against single point failures
- Updated HomeArchitecture layout to better center and display animations with improved flex positioning
2025-11-14 22:23:11 +01:00
33821987aa refactor: streamline page components and simplify UI elements
- Removed unused HomeAudience component from HomePage
- Renamed NetworkPros to CloudPros for clarity
- Removed bullet point lists from PodsFeatures to simplify presentation
- Replaced PodCapabilities with PodsWhat and removed PodsComing section
2025-11-14 21:53:21 +01:00
678da4b66c feat: redesign cloud page with improved content structure and visual hierarchy
- Replaced CloudHostingNew with new CloudIntro component featuring tabbed interface for Kubernetes, VDC, and QSFS capabilities
- Added CloudCodeTabs component with interactive code examples and syntax highlighting
- Created CloudPros section highlighting platform architecture, reliability, compatibility, and scalability
- Updated hero section copy to emphasize sovereign edge infrastructure and simplified messaging
- Remove
2025-11-14 18:15:04 +01:00
326efc9fbd refactor: rename Node page to Nodes and reorganize network page sections
- Renamed NodePage component and directory to NodesPage/nodes for consistency
- Updated all navigation links from "Node" to "Nodes" across headers and footer
- Replaced anchor tags with React Router Link components for proper SPA navigation
- Reorganized NetworkPage component order and added NetworkPros section
- Converted NetworkUsecases from horizontal slider to responsive grid layout
- Added new use cases for adaptive mesh and compute fabric
- Update
2025-11-14 17:01:29 +01:00
3a656ef5e9 fix: correct node route path from /node to /nodes 2025-11-14 16:20:26 +01:00
cf32cd081c feat: update network CTA with improved messaging and navigation
- Changed heading from "Start" to "Connect" and refined description for clarity
- Replaced two-button layout with three-option navigation (Join Network, Deploy in Cloud, Host a Node)
- Updated button destinations and styling to better guide user journey
2025-11-14 16:16:08 +01:00
1950342b7a feat: simplify network page messaging and update feature descriptions
- Streamlined hero and features sections with clearer, more direct value propositions
- Updated network capabilities to emphasize unified connectivity over technical details
- Replaced technical feature descriptions with user-focused benefits (DNS, VPN, publishing, AI)
2025-11-14 16:16:00 +01:00
d1fc11ce80 refactor: simplify navigation structure and update homepage content
- Removed Cloud dropdown menu and flattened navigation to direct links (Network, Cloud, Pods, Agents, Node)
- Reordered navigation items for better flow and renamed "Nodes" to "Node" for consistency
- Updated homepage hero and CTA sections with clearer messaging focused on digital sovereignty and infrastructure control
- Added new bento grid images for visual refresh
2025-11-14 15:41:21 +01:00
48954151c9 Mycelium unifies everything 2025-11-14 13:39:25 +01:00
61e368e27e refactor: add type assertion for node selection 2025-11-14 13:07:25 +01:00
d8524ef181 feat: redesign node products section with interactive configuration selector
- Replaced static grid layout with dynamic two-column design featuring live product switching
- Added configuration selector allowing users to toggle between AI Node and Compute Node options
- Enhanced product information with detailed features, descriptions, and direct purchase/learn more CTAs
2025-11-14 13:03:06 +01:00
c44d9158f2 feat: add node setup guide and product recommendations
- Created NodeSteps component with 4-step horizontal stepper showing node hosting process
- Added NodeProducts component displaying recommended Edge AI and Edge Compute nodes
- Integrated new components into NodePage with supporting product images
2025-11-14 12:43:43 +01:00
359afc3360 feat: add nodes page with hosting information and benefits
- Created new NodePage with hero section explaining the Mycelium node network
- Added NodeBenefits component showcasing three key advantages of hosting nodes
- Integrated nodes route into navigation (header, footer, and routing configuration)
2025-11-14 12:14:28 +01:00
96a17a668a fix: improve text contrast in hero sections 2025-11-13 15:28:39 +01:00
c93974ea3e style: remove trailing whitespace and adjust background opacity 2025-11-13 15:27:33 +01:00
f1f8f50871 refactor: replace paragraph tag with P component in AgentHeroAlt 2025-11-13 15:27:00 +01:00
e4b2d66a76 fix: update homepage pod description text styling 2025-11-13 15:25:59 +01:00
b208fe7f2a refactor: convert agent bento cards from videos to React animation components
- Replaced video paths with imported animation components (Fungistor, Herodb, MOSSandboxes, etc.)
- Added new AgentDesign and AgentUseCase sections to agents page
- Updated hero copy to emphasize private, sovereign AI and 2026 timeline
- Reorganized page layout with new sections between existing components
2025-11-13 15:24:46 +01:00
7b80ab84c9 feat: add comprehensive Pods landing page sections
- Created new sections including benefits grid, federation design, upcoming features, and call-to-action
- Added pricing tiers component with three Pod subscription levels
- Updated existing sections with refined messaging and improved visual hierarchy
2025-11-13 14:52:24 +01:00
aa6f475050 feat: redesign pods page with enhanced UI and animations
- Replaced HomeBlink with HomeAurora component for improved visual experience
- Added PodCapabilities horizontal slider with interactive navigation controls
- Created PodsFeatures section showcasing use cases with hover animations
- Updated PodsHow layout with bullet points and new PodsFlow animation component
2025-11-13 14:04:13 +01:00
76 changed files with 4786 additions and 446 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
public/images/ainode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

BIN
public/images/cons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 KiB

BIN
public/images/dev.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 KiB

BIN
public/images/edgenode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 KiB

BIN
public/images/pod1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
public/images/podsimg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
public/images/seekers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 KiB

View File

@@ -11,6 +11,7 @@ const ComputePage = lazy(() => import('./pages/compute/ComputePage'));
const StoragePage = lazy(() => import('./pages/storage/StoragePage'));
const GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
const NodesPage = lazy(() => import('./pages/nodes/NodesPage'));
function App() {
return (
@@ -27,6 +28,7 @@ function App() {
<Route path="storage" element={<StoragePage />} />
<Route path="gpu" element={<GpuPage />} />
<Route path="pods" element={<PodsPage />} />
<Route path="nodes" element={<NodesPage />} />
</Route>
</Routes>
</Suspense>

View File

@@ -15,20 +15,20 @@ export function Footer() {
</div>
</div>
<nav className="mt-10 flex gap-8">
<Link to="/" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Home
<Link to="/network" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Network
</Link>
<Link to="/cloud" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Cloud
</Link>
<Link to="/network" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Network
<Link to="/pods" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Pods
</Link>
<Link to="/agents" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Agents
</Link>
<Link to="/pods" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Pods
<Link to="/nodes" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Nodes
</Link>
</nav>
</div>

View File

@@ -1,32 +1,14 @@
import { useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { Dropdown } from './ui/Dropdown'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { Link } from 'react-router-dom'
import { Container } from './Container'
import { Button } from './Button'
import pmyceliumLogo from '../images/logos/logo_1.png'
import { Dialog } from '@headlessui/react'
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
const cloudNavItems = [
{ name: 'Cloud', href: '/cloud' },
{ name: 'Compute', href: '/compute' },
{ name: 'Storage', href: '/storage' },
{ name: 'GPU', href: '/gpu' },
]
export function Header() {
const location = useLocation()
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const getCurrentPageName = () => {
const currentPath = location.pathname;
if (currentPath.startsWith('/compute')) return 'Compute';
if (currentPath.startsWith('/storage')) return 'Storage';
if (currentPath.startsWith('/gpu')) return 'GPU';
return 'Cloud';
};
return (
<header className="bg-white">
<nav className="border-b border-gray-100">
@@ -36,28 +18,24 @@ export function Header() {
<img src={pmyceliumLogo} alt="Mycelium" className="h-8 w-auto" />
</Link>
<div className="hidden lg:flex lg:gap-10">
<Dropdown
buttonContent={
<>
{['Compute', 'Storage', 'GPU'].includes(getCurrentPageName()) ? (
<>
<span className="text-gray-500">Cloud {' >'} </span>
<span>{getCurrentPageName()}</span>
</>
) : (
'Cloud'
)}
<ChevronDownIcon className="h-5 w-5" aria-hidden="true" />
</>
}
items={cloudNavItems}
/>
<Link
to="/network"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Network
</Link>
<Link
to="/cloud"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Cloud
</Link>
<Link
to="/pods"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Pods
</Link>
<Link
to="/agents"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
@@ -65,10 +43,10 @@ export function Header() {
Agents
</Link>
<Link
to="/pods"
to="/nodes"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Pods
Nodes
</Link>
</div>
</div>
@@ -124,16 +102,6 @@ export function Header() {
<div className="mt-6 flow-root">
<div className="-my-6 divide-y divide-gray-500/10">
<div className="space-y-2 py-6">
{cloudNavItems.map((item) => (
<Link
key={item.name}
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"
onClick={() => setMobileMenuOpen(false)}
>
{item.name}
</Link>
))}
<Link
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"
@@ -141,6 +109,20 @@ export function Header() {
>
Network
</Link>
<Link
to="/cloud"
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)}
>
Cloud
</Link>
<Link
to="/pods"
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)}
>
Pods
</Link>
<Link
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"
@@ -149,11 +131,11 @@ export function Header() {
Agents
</Link>
<Link
to="/pods"
to="/nodes"
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)}
>
Pods
Nodes
</Link>
</div>
<div className="py-6">

View File

@@ -1,32 +1,14 @@
import { useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { Dropdown } from './ui/Dropdown'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { Link } from 'react-router-dom'
import { Container } from './Container'
import { Button } from './Button'
import pmyceliumLogo from '../images/logos/logo_1.png'
import { Dialog } from '@headlessui/react'
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
const cloudNavItems = [
{ name: 'Cloud', href: '/cloud' },
{ name: 'Compute', href: '/compute' },
{ name: 'Storage', href: '/storage' },
{ name: 'GPU', href: '/gpu' },
]
export function HeaderDark() {
const location = useLocation()
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const getCurrentPageName = () => {
const currentPath = location.pathname;
if (currentPath.startsWith('/compute')) return 'Compute';
if (currentPath.startsWith('/storage')) return 'Storage';
if (currentPath.startsWith('/gpu')) return 'GPU';
return 'Cloud';
};
return (
<header className="bg-[#111111]">
<nav className="border-b border-gray-800">
@@ -36,28 +18,24 @@ export function HeaderDark() {
<img src={pmyceliumLogo} alt="Mycelium" className="h-8 w-auto" />
</Link>
<div className="hidden lg:flex lg:gap-10">
<Dropdown
buttonContent={
<>
{['Compute', 'Storage', 'GPU'].includes(getCurrentPageName()) ? (
<>
<span className="text-gray-400">Cloud {' >'} </span>
<span className="text-white">{getCurrentPageName()}</span>
</>
) : (
<span className="text-white">Cloud</span>
)}
<ChevronDownIcon className="h-5 w-5 text-white" aria-hidden="true" />
</>
}
items={cloudNavItems}
/>
<Link
to="/network"
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
>
Network
</Link>
<Link
to="/cloud"
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
>
Cloud
</Link>
<Link
to="/pods"
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
>
Pods
</Link>
<Link
to="/agents"
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
@@ -65,10 +43,10 @@ export function HeaderDark() {
Agents
</Link>
<Link
to="/pods"
to="/nodes"
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
>
Pods
Nodes
</Link>
</div>
</div>
@@ -124,16 +102,6 @@ export function HeaderDark() {
<div className="mt-6 flow-root">
<div className="-my-6 divide-y divide-gray-500/20">
<div className="space-y-2 py-6">
{cloudNavItems.map((item) => (
<Link
key={item.name}
to={item.href}
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
onClick={() => setMobileMenuOpen(false)}
>
{item.name}
</Link>
))}
<Link
to="/network"
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
@@ -141,6 +109,20 @@ export function HeaderDark() {
>
Network
</Link>
<Link
to="/cloud"
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
onClick={() => setMobileMenuOpen(false)}
>
Cloud
</Link>
<Link
to="/pods"
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
onClick={() => setMobileMenuOpen(false)}
>
Pods
</Link>
<Link
to="/agents"
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
@@ -149,11 +131,11 @@ export function HeaderDark() {
Agents
</Link>
<Link
to="/pods"
to="/nodes"
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
onClick={() => setMobileMenuOpen(false)}
>
Pods
Nodes
</Link>
</div>
<div className="py-6">

View File

@@ -1,15 +1,32 @@
"use client";
import { Eyebrow, H3, P } from "@/components/Texts";
import AgentCoordination from "./animations/AgentCoordination";
import DeterministicExecution from "./animations/DeterministicExecution";
import Fungistor from "./animations/Fungistor";
import Herodb from "./animations/Herodb";
import MOSSandboxes from "./animations/MOSSandboxes";
import MyceliumMesh from "./animations/MyceliumMesh";
const bentos = [
const bentos: {
id: string;
eyebrow?: string;
title: string;
subtitle?: string;
description: string;
animation: React.ComponentType | null;
colSpan: string;
rowSpan: string;
custom?: boolean;
noBorder?: boolean;
}[] = [
{
id: "core",
eyebrow: "ARCHITECTURE",
title: "Deterministic by Design",
title: "Augmented Intelligence Fabric",
description:
"Every workload runs exactly as declared: no drift, no hidden state, no surprises.",
video: null,
"The sovereign substrate for autonomous AI. Stateless, geo-aware, end-to-end encrypted—and verifiable from intent to execution.",
animation: null,
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
custom: true,
@@ -23,7 +40,7 @@ const bentos = [
subtitle: "Long-Term AI Memory",
description:
"Erasure coding + compression slash storage bloat by up to 10× vs basic replication. Source-encrypted shards are geo-dispersed—lose pieces, rebuild perfectly from a quorum.",
video: "/videos/fungistor.mp4",
animation: Fungistor,
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
},
@@ -33,7 +50,7 @@ const bentos = [
subtitle: "Active AI Memory",
description:
"Multimodal vector+keyword retrieval makes RAG feel instant across text, image, audio. Time-aware, policy-guarded context keeps results fresh while access stays governed.",
video: "/videos/herodb.mp4",
animation: Herodb,
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
},
@@ -43,7 +60,7 @@ const bentos = [
subtitle: "Secure Agent Workspaces",
description:
"Attested, signed workspaces spin up ≈5s worldwide—ready to execute. Hardware isolation and scoped egress: run hard, tear down clean, zero residue.",
video: "/videos/herodb.mp4",
animation: MOSSandboxes,
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
},
@@ -53,7 +70,7 @@ const bentos = [
subtitle: "Secure Communication Network",
description:
"A private, public-key fabric with self-healing multi-path routing. Glides through NATs and firewalls—direct, low-latency, no middlemen.",
video: "/videos/mesh.mp4",
animation: MyceliumMesh,
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
},
@@ -63,7 +80,7 @@ const bentos = [
subtitle: "Verifiable Code Execution",
description:
"Declare intent, get a hash; remote attestation proves that is what runs. Reproducible builds, signed artifacts, immutable logs—supply chain, sealed.",
video: "/videos/deterministic.mp4",
animation: DeterministicExecution,
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
},
@@ -73,7 +90,7 @@ const bentos = [
subtitle: "Sovereign Workflow Management",
description:
"Your private agent conducts swarms of specialists in parallel. Policies fan out work; human checkpoints keep you in command.",
video: "/videos/agent.mp4",
animation: AgentCoordination,
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
},
@@ -101,17 +118,9 @@ export function AgentBento() {
<div
className={`relative flex lg:h-90 flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] `}
>
{/* ✅ VIDEO instead of animation */}
{card.video ? (
{card.animation ? (
<div className="lg:h-64 h-48 w-full overflow-hidden bg-transparent flex items-center">
<video
src={card.video}
autoPlay
loop
muted
playsInline
className="w-full h-full object-cover"
/>
<card.animation />
</div>
) : (
<div className="h-48 w-full flex items-center justify-center bg-transparent" />

View File

@@ -0,0 +1,56 @@
import {
ComputerDesktopIcon,
ArrowsRightLeftIcon,
CircleStackIcon,
} from '@heroicons/react/24/solid'
const benefits = [
{
id: 1,
title: 'Each agent operates entirely inside your environment',
icon: ComputerDesktopIcon,
},
{
id: 2,
title: 'They communicate peer-to-peer across trusted nodes',
icon: ArrowsRightLeftIcon,
},
{
id: 3,
title: 'They access data locally without exposing it to external providers',
icon: CircleStackIcon,
},
]
export function AgentDesign() {
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 border-l border-r border-gray-100" />
{/* ✅ Main content */}
<div className="mx-auto max-w-7xl border-gray-100">
<dl className="grid grid-cols-1 gap-4 lg:gap-6 lg:grid-cols-3 text-center ">
{benefits.map((item) => (
<div
key={item.id}
className="flex flex-col items-center bg-white dark:bg-black/40 py-10 px-4 border border-gray-100 dark:border-gray-800 lg:border-t-0 lg:border-b-0"
>
<item.icon className="h-10 w-10 text-cyan-500 mb-4" />
<h3 className="text-base font-medium text-black dark:text-white max-w-xs">
{item.title}
</h3>
</div>
))}
</dl>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border 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>
)
}

View File

@@ -1,7 +1,7 @@
'use client'
import { Button } from '@/components/Button'
import { Eyebrow, H3 } from '@/components/Texts'
import { Eyebrow, H3, P } from '@/components/Texts'
export function AgentHeroAlt() {
return (
@@ -14,19 +14,18 @@ export function AgentHeroAlt() {
{/* Inner padding */}
<div className="px-6 py-16 lg:py-16">
<div className="max-w-2xl lg:pl-6">
<Eyebrow>MYCELIUM AGENTS</Eyebrow>
<Eyebrow>MYCELIUM AGENTS - COMING IN 2026</Eyebrow>
<H3 as="h1" className="mt-4">
Sovereign AI Agents, Coming Soon.
Private, Sovereign and Distributed AI You Control
</H3>
<p className="mt-6 text-lg">
The Agent layer will allow you to run autonomous, policy-governed AI that operates on infrastructure you control, with private memory, verifiable execution, and coordination across your personal or organizational environment.
</p>
<p className="mt-4 lg:text-base italic text-gray-600 text-sm">
Works Alone. Works Together. Use Agents on top of any Mycelium Cloud deployment or pair them with the Mycelium Network for private, encrypted collaboration across users and systems.
</p>
<P className="mt-6 text-gray-800">
Mycelium Agents let you deploy and run intelligent systems on your own infrastructure.
Private, local, and autonomous by design, they give you everything you need to build, host, and connect AI agents without relying on centralized clouds.
</P>
<div className="mt-10 flex items-center gap-x-6">
<Button href="#" variant="solid" color="cyan">
Follow Deployment
Follow Development
</Button>
<Button href="#" variant="outline">
Explore Docs <span aria-hidden="true"></span>

View File

@@ -0,0 +1,147 @@
"use client";
import { useRef } from "react";
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
import {
CpuChipIcon,
GlobeAltIcon,
LockClosedIcon,
ArrowPathIcon,
ShieldCheckIcon,
} from "@heroicons/react/24/solid";
const networkUseCases = [
{
isIntro: true,
eyebrow: "WHAT IT ENABLES",
title: "What It Enables",
description:
"The framework gives you full control over where agents live, how they connect, and what data they use.",
},
{
title: "Run agents on your own hardware",
description:
"Deploy AI processes on laptops, homelabs, edge nodes, or full clusters — no cloud dependency.",
icon: CpuChipIcon,
},
{
title: "Connect them over the secure Mycelium network",
description:
"Agents communicate privately across homes, clouds, countries, and environments in one address space.",
icon: GlobeAltIcon,
},
{
title: "Keep data and memory private by default",
description:
"Your datasets, tools, prompts, embeddings, and memory stay local unless you choose otherwise.",
icon: LockClosedIcon,
},
{
title: "Build workflows across cloud + edge",
description:
"Orchestrate multi-node jobs, pipelines, and real-time systems that live anywhere in your infrastructure.",
icon: ArrowPathIcon,
},
{
title: "Operate securely in regulated contexts",
description:
"Run agents in sectors requiring strict data residency, verified identity, and controlled connectivity.",
icon: ShieldCheckIcon,
},
];
export function AgentUsecase() {
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="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" />
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-slate-200 bg-white overflow-hidden">
<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 px-10 py-12 relative
${item.isIntro ? "bg-gray-50/80" : "bg-white"}`}
>
{/* INTRO CARD */}
{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>
<P className="mt-4 text-gray-600 text-sm lg:text-base">
{item.description}
</P>
</div>
{/* slider buttons */}
<div className="flex items-center gap-x-4 mt-6">
<button
onClick={scrollLeft}
className="h-8 w-8 flex items-center justify-center
border border-slate-300 rounded-md
hover:border-cyan-500 transition-colors"
>
<IoArrowBackOutline className="text-gray-600" size={16} />
</button>
<button
onClick={scrollRight}
className="h-8 w-8 flex items-center justify-center
border border-slate-300 rounded-md
hover:border-cyan-500 transition-colors"
>
<IoArrowForwardOutline className="text-gray-600" size={16} />
</button>
</div>
</div>
) : (
/* REGULAR CARD */
<div className="flex flex-col h-full">
{item.icon && (
<div className="h-12 w-12 flex items-center justify-center rounded-xl bg-gray-100 mb-6">
<item.icon className="h-6 w-6 text-cyan-600" />
</div>
)}
<p className="text-lg font-semibold text-gray-900">
{item.title}
</p>
<p className="mt-2 text-gray-600 leading-snug">
{item.description}
</p>
</div>
)}
</li>
))}
</ul>
</div>
{/* ✅ 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>
);
}

View File

@@ -1,10 +1,11 @@
import { AnimatedSection } from '../../components/AnimatedSection'
import { DeploySection } from './DeploySection'
import { GallerySection } from './GallerySection'
import { Companies } from './Companies'
import { AgentBento } from './AgentBento'
import { AgentHeroAlt } from './AgentHeroAlt'
import { CallToAction } from './CallToAction'
import { AgentUsecase } from './AgentUseCase'
import { AgentDesign } from './AgentDesign'
export default function AgentsPage() {
return (
@@ -22,13 +23,17 @@ export default function AgentsPage() {
</AnimatedSection>
<AnimatedSection>
<GallerySection />
<AgentUsecase />
</AnimatedSection>
<AnimatedSection>
<AgentBento />
</AnimatedSection>
<AnimatedSection>
<AgentDesign />
</AnimatedSection>
<AnimatedSection>
<CallToAction />
</AnimatedSection>

View File

@@ -15,14 +15,37 @@ export function CallToAction() {
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">
<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">
Start Building the Future of Sovereign AI
Start with Mycelium Today
</h2>
<p className="mt-6 text-lg text-gray-300">
Use todays components models, storage, compute, mesh and step into agents as they arrive.
The Agent Framework launches in H1 2026, but the foundation is ready now.
</p>
<p className="mt-6 text-lg text-gray-300">
Use todays components models, storage, compute, and network to deploy workloads, connect nodes, and prepare for the next generation of distributed AI.
</p>
{/* ✅ Two cards, stacked center with spacing */}

View File

@@ -37,7 +37,7 @@ const row2 = logos.slice(6);
export function Companies() {
return (
<div id="companies" className="relative bg-[#121212] flex flex-col items-center justify-center w-full overflow-hidden antialiased py-4 mb-12">
<div id="companies" className="relative bg-[#121212] flex flex-col items-center justify-center w-full overflow-hidden antialiased py-4">
<div className="relative z-10 mx-auto w-full max-w-7xl p-4">
{/* Logos grid */}
<div className="flex flex-col items-center gap-y-6 text-white ">

View File

@@ -0,0 +1,264 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
bg?: string;
};
const W = 760;
const H = 420;
const AgentNode = ({
x,
y,
r = 12,
accent = "#00b8db",
pulse = false,
delay = 0,
}: {
x: number;
y: number;
r?: number;
accent?: string;
pulse?: boolean;
delay?: number;
}) => {
const prefers = useReducedMotion();
return (
<>
<motion.circle
cx={x}
cy={y}
r={r + 10}
stroke="#1F2937"
strokeWidth={2}
fill="none"
initial={{ opacity: 0 }}
animate={{ opacity: 0.7 }}
transition={{ delay, duration: 0.6 }}
/>
<motion.circle
cx={x}
cy={y}
r={r}
fill={accent}
initial={{ opacity: 0, scale: 0.85 }}
animate={{
opacity: 1,
scale: pulse && !prefers ? [1, 1.12, 1] : 1,
}}
transition={{
delay,
duration: pulse ? 1.8 : 0.6,
repeat: pulse && !prefers ? Infinity : 0,
repeatType: "mirror",
ease: [0.22, 1, 0.36, 1],
}}
/>
</>
);
};
const Packet = ({
path,
delay = 0,
accent = "#00b8db",
duration = 2.2,
reverse = false,
}: {
path: string;
delay?: number;
accent?: string;
duration?: number;
reverse?: boolean;
}) => {
const prefers = useReducedMotion();
return (
<motion.circle
r={4}
fill={accent}
initial={{ offsetDistance: reverse ? "100%" : "0%", opacity: 0 }}
animate={{
offsetDistance: reverse ? ["100%", "0%"] : ["0%", "100%"],
opacity: [0, 1, 0],
}}
transition={{
delay,
duration,
repeat: !prefers ? Infinity : 0,
repeatType: "loop",
ease: "linear",
}}
style={{
offsetPath: `path('${path}')`,
}}
/>
);
};
export default function AgentCoordination({
className,
accent = "#00b8db",
bg = "#0a0a0a",
}: Props) {
const center = { x: 380, y: 210 };
// Specialist agents placed in a controlled orbit
const agents = [
{ x: 200, y: 120 },
{ x: 560, y: 120 },
{ x: 620, y: 260 },
{ x: 500, y: 330 },
{ x: 260, y: 330 },
{ x: 140, y: 260 },
];
const paths = agents.map(
(a) => `M ${center.x} ${center.y} Q ${(center.x + a.x) / 2} ${(center.y + a.y) / 2 - 40} ${a.x} ${a.y}`
);
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="Agent coordination and sovereign workflow management"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
{/* background */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" stroke="#0f0f0f" strokeWidth="1" />
</pattern>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor={accent} stopOpacity="0.20" />
<stop offset="100%" stopColor={accent} stopOpacity="0" />
</radialGradient>
</defs>
<rect width={W} height={H} fill="url(#grid-dark)" />
{/* global glow */}
<circle cx={center.x} cy={center.y} r={240} fill="url(#glow)" opacity={0.45} />
{/* POLICY RING */}
<motion.circle
cx={center.x}
cy={center.y}
r={110}
stroke={accent}
strokeWidth={2}
fill="none"
strokeDasharray="14 10"
animate={{ opacity: [0.25, 0.7, 0.25] }}
transition={{
duration: 3,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* CHECKPOINT GATE */}
<motion.rect
x={center.x - 50}
y={center.y - 130}
width={100}
height={22}
rx={6}
stroke={accent}
strokeWidth={2}
fill="none"
animate={{ opacity: [0.2, 0.7, 0.2] }}
transition={{
duration: 2.4,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* central conductor agent */}
<motion.circle
cx={center.x}
cy={center.y}
r={26}
fill={accent}
initial={{ opacity: 0, scale: 0.85 }}
animate={{
opacity: 1,
scale: [1, 1.06, 1],
}}
transition={{
duration: 1.8,
repeat: Infinity,
repeatType: "mirror",
ease: "easeInOut",
}}
/>
{/* inward → outward routing lines */}
{paths.map((p, i) => (
<motion.path
key={`p-${i}`}
d={p}
stroke="#1F2937"
strokeWidth={3}
strokeLinecap="round"
fill="none"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.4 }}
transition={{
delay: i * 0.1,
duration: 0.8,
ease: [0.22, 1, 0.36, 1],
}}
/>
))}
{/* OUTBOUND tasks */}
{paths.map((p, i) => (
<Packet
key={`out-${i}`}
path={p}
delay={0.3 * i}
accent={accent}
duration={2}
/>
))}
{/* INBOUND results */}
{paths.map((p, i) => (
<Packet
key={`in-${i}`}
path={p}
reverse
delay={0.5 * i}
accent={accent}
duration={2.2}
/>
))}
{/* specialist agents */}
{agents.map((a, i) => (
<AgentNode
key={`agent-${i}`}
x={a.x}
y={a.y}
pulse={i % 2 === 0}
delay={i * 0.1}
accent={accent}
/>
))}
</svg>
</div>
);
}

View File

@@ -0,0 +1,263 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
bg?: string;
};
const W = 760;
const H = 420;
const PulseCircle = ({
x,
y,
r,
accent,
delay = 0,
}: {
x: number;
y: number;
r: number;
accent: string;
delay?: number;
}) => {
const prefers = useReducedMotion();
return (
<motion.circle
cx={x}
cy={y}
r={r}
stroke={accent}
strokeWidth={2}
fill="none"
initial={{ scale: 0.8, opacity: 0 }}
animate={{
scale: !prefers ? [1, 1.25, 1] : 1,
opacity: !prefers ? [0.4, 0.9, 0.4] : 1,
}}
transition={{
delay,
duration: 2.2,
repeat: !prefers ? Infinity : 0,
repeatType: "mirror",
ease: "easeInOut",
}}
/>
);
};
const Packet = ({
path,
delay = 0,
duration = 2,
accent = "#00b8db",
}: {
path: string;
delay?: number;
duration?: number;
accent?: string;
}) => {
const prefers = useReducedMotion();
return (
<motion.circle
r={4}
fill={accent}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0, 1, 0],
}}
transition={{
delay,
duration,
repeat: !prefers ? Infinity : 0,
repeatType: "loop",
ease: "linear",
}}
style={{ offsetPath: `path('${path}')` }}
/>
);
};
export default function DeterministicExecution({
className,
accent = "#00b8db",
bg = "#0a0a0a",
}: Props) {
const left = { x: 200, y: 210 };
const center = { x: 380, y: 210 };
const right = { x: 560, y: 210 };
const leftToCenter = `M ${left.x} ${left.y} L ${center.x} ${center.y}`;
const centerToRight = `M ${center.x} ${center.y} L ${right.x} ${right.y}`;
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="Deterministic deployment and verifiable code execution"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
{/* background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" stroke="#0f0f0f" strokeWidth="1" />
</pattern>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor={accent} stopOpacity="0.18" />
<stop offset="100%" stopColor={accent} stopOpacity="0" />
</radialGradient>
</defs>
<rect width={W} height={H} fill="url(#grid-dark)" />
{/* global glow */}
<circle cx={center.x} cy={center.y} r={230} fill="url(#glow)" opacity={0.4} />
{/* LEFT: Declare Intent block */}
<motion.rect
x={left.x - 60}
y={left.y - 40}
width={120}
height={80}
rx={10}
stroke="#1F2937"
strokeWidth={3}
fill="none"
initial={{ opacity: 0 }}
animate={{ opacity: 0.8 }}
transition={{ duration: 0.6 }}
/>
<motion.rect
x={left.x - 45}
y={left.y - 25}
width={90}
height={50}
rx={6}
fill={accent}
initial={{ opacity: 0, scale: 0.85 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.8 }}
/>
{/* CENTER: Cryptographic hash */}
<motion.rect
x={center.x - 40}
y={center.y - 40}
width={80}
height={80}
rx={12}
stroke={accent}
strokeWidth={2}
strokeDasharray="10 6"
fill="none"
animate={{ opacity: [0.4, 0.9, 0.4] }}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* hash print */}
<motion.text
x={center.x}
y={center.y + 5}
textAnchor="middle"
fill={accent}
fontFamily="monospace"
fontSize="14"
initial={{ opacity: 0 }}
animate={{ opacity: 0.9 }}
transition={{ delay: 0.3 }}
>
9f1a..42c7
</motion.text>
{/* signature stamp */}
<motion.circle
cx={center.x + 55}
cy={center.y - 55}
r={14}
stroke={accent}
strokeWidth={2}
fill="none"
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ delay: 0.4, duration: 0.6 }}
/>
{/* RIGHT: Verified Execution Node */}
<motion.circle
cx={right.x}
cy={right.y}
r={24}
fill={accent}
initial={{ opacity: 0, scale: 0.8 }}
animate={{
opacity: 1,
scale: [1, 1.06, 1],
}}
transition={{
duration: 1.8,
repeat: Infinity,
repeatType: "mirror",
ease: "easeInOut",
}}
/>
{/* outer attestation ring */}
<PulseCircle x={right.x} y={right.y} r={40} accent={accent} delay={0.2} />
{/* immutable logs ring */}
<motion.circle
cx={right.x}
cy={right.y}
r={70}
stroke={accent}
strokeWidth={2}
strokeDasharray="14 12"
fill="none"
animate={{ opacity: [0.2, 0.6, 0.2] }}
transition={{
duration: 3,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* deterministic path lines */}
<motion.path
d={leftToCenter}
stroke="#1F2937"
strokeWidth={3}
fill="none"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.8 }}
/>
<motion.path
d={centerToRight}
stroke="#1F2937"
strokeWidth={3}
fill="none"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.8, delay: 0.2 }}
/>
{/* active cryptographic pulses */}
<Packet path={leftToCenter} delay={0.4} accent={accent} duration={1.8} />
<Packet path={centerToRight} delay={0.8} accent={accent} duration={1.8} />
</svg>
</div>
);
}

View File

@@ -0,0 +1,238 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
bg?: string;
};
const W = 760;
const H = 420;
const Node = ({
x,
y,
r = 10,
accent = "#00b8db",
pulse = false,
delay = 0,
}: {
x: number;
y: number;
r?: number;
accent?: string;
pulse?: boolean;
delay?: number;
}) => {
const prefers = useReducedMotion();
return (
<>
{/* outer faint ring */}
<motion.circle
cx={x}
cy={y}
r={r + 10}
stroke="#1F2937"
strokeWidth={2}
fill="none"
initial={{ opacity: 0 }}
animate={{ opacity: 0.6 }}
transition={{ delay, duration: 0.6 }}
/>
{/* glowing shard node */}
<motion.circle
cx={x}
cy={y}
r={r}
fill={accent}
initial={{ opacity: 0, scale: 0.8 }}
animate={{
opacity: 1,
scale: pulse && !prefers ? [1, 1.12, 1] : 1,
}}
transition={{
delay,
duration: pulse && !prefers ? 1.8 : 0.6,
repeat: pulse && !prefers ? Infinity : 0,
repeatType: "mirror",
ease: [0.22, 1, 0.36, 1],
}}
/>
</>
);
};
const Shard = ({
path,
delay = 0,
accent = "#00b8db",
duration = 2,
}: {
path: string;
delay?: number;
accent?: string;
duration?: number;
}) => {
const prefers = useReducedMotion();
return (
<motion.circle
r={4}
fill={accent}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0, 1, 0],
}}
transition={{
delay,
duration,
repeat: !prefers ? Infinity : 0,
repeatType: "loop",
ease: "linear",
}}
style={{ offsetPath: `path('${path}')` }}
/>
);
};
export default function FungiStor({
className,
accent = "#00b8db",
bg = "#0a0a0a",
}: Props) {
const center = { x: 380, y: 210 };
const shardNodes = [
{ x: 160, y: 100 },
{ x: 260, y: 70 },
{ x: 580, y: 100 },
{ x: 620, y: 250 },
{ x: 500, y: 330 },
{ x: 240, y: 320 },
];
// outgoing shard paths
const paths = shardNodes.map(
(n) => `M ${center.x} ${center.y} Q ${(n.x + center.x) / 2} ${(n.y + center.y) / 2 - 40} ${n.x} ${n.y}`
);
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="FungiStor — distributed long-term AI memory"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
{/* Background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" fill="none" stroke="#0f0f0f" strokeWidth="1" />
</pattern>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor={accent} stopOpacity="0.15" />
<stop offset="100%" stopColor={accent} stopOpacity="0" />
</radialGradient>
</defs>
<rect width={W} height={H} fill="url(#grid-dark)" />
{/* Soft global network glow */}
<circle cx={center.x} cy={center.y} r={180} fill="url(#glow)" opacity={0.4} />
{/* Source data core */}
<motion.rect
x={center.x - 40}
y={center.y - 40}
width={80}
height={80}
rx={12}
fill="none"
stroke={accent}
strokeWidth={2}
strokeDasharray="10 6"
initial={{ opacity: 0 }}
animate={{ opacity: [0.4, 0.9, 0.4] }}
transition={{ duration: 2, repeat: Infinity, ease: "easeInOut" }}
/>
<motion.rect
x={center.x - 20}
y={center.y - 20}
width={40}
height={40}
rx={6}
fill={accent}
initial={{ opacity: 0, scale: 0.8 }}
animate={{
opacity: 1,
scale: [1, 1.08, 1],
}}
transition={{
duration: 1.8,
repeat: Infinity,
repeatType: "mirror",
ease: "easeInOut",
}}
/>
{/* Outgoing shard connections */}
{paths.map((p, i) => (
<motion.path
key={`path-${i}`}
d={p}
stroke="#1F2937"
strokeWidth={2}
fill="none"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.4 }}
transition={{
delay: 0.05 * i,
duration: 0.8,
ease: [0.22, 1, 0.36, 1],
}}
/>
))}
{/* Animated data shards traveling */}
{paths.map((p, i) => (
<Shard key={`shard-${i}`} path={p} delay={i * 0.4} accent={accent} duration={2.6} />
))}
{/* Destination storage nodes */}
{shardNodes.map((n, i) => (
<Node
key={`node-${i}`}
x={n.x}
y={n.y}
accent={accent}
pulse={i % 2 === 0}
delay={i * 0.1}
/>
))}
{/* “Reconstruction glow” pulse ring */}
<motion.circle
cx={center.x}
cy={center.y}
r={110}
stroke={accent}
strokeWidth={2}
fill="none"
initial={{ scale: 0.9, opacity: 0 }}
animate={{
scale: [0.9, 1.2, 0.9],
opacity: [0.2, 0.6, 0.2],
}}
transition={{
duration: 3.2,
repeat: Infinity,
ease: "easeInOut",
}}
/>
</svg>
</div>
);
}

View File

@@ -0,0 +1,286 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
bg?: string;
};
const W = 760;
const H = 420;
const Node = ({
x,
y,
r = 12,
accent = "#00b8db",
pulse = false,
delay = 0,
type = "dot",
}: {
x: number;
y: number;
r?: number;
accent?: string;
pulse?: boolean;
delay?: number;
type?: "dot" | "text" | "image" | "audio";
}) => {
const prefers = useReducedMotion();
return (
<>
{/* faint ring */}
<motion.circle
cx={x}
cy={y}
r={r + 10}
stroke="#1F2937"
strokeWidth={2}
fill="none"
initial={{ opacity: 0 }}
animate={{ opacity: 0.7 }}
transition={{ delay, duration: 0.6 }}
/>
{/* inner icon shape to represent modality */}
{type === "text" && (
<motion.rect
x={x - r}
y={y - r / 2}
width={r * 2}
height={r}
rx={3}
fill={accent}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay }}
/>
)}
{type === "image" && (
<motion.path
d={`M ${x - r} ${y + r/2} L ${x - r} ${y - r/2} L ${x + r} ${y - r/2} L ${x + r} ${y + r/2} Z`}
stroke={accent}
strokeWidth={2}
fill="none"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay }}
/>
)}
{type === "audio" && (
<motion.path
d={`
M ${x - r/2} ${y - r/2}
L ${x - r/2} ${y + r/2}
M ${x} ${y - r/3}
L ${x} ${y + r/3}
M ${x + r/2} ${y - r/4}
L ${x + r/2} ${y + r/4}
`}
stroke={accent}
strokeWidth={2}
strokeLinecap="round"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay }}
/>
)}
{/* standard pulsing circle fallback */}
{type === "dot" && (
<motion.circle
cx={x}
cy={y}
r={r}
fill={accent}
initial={{ opacity: 0, scale: 0.85 }}
animate={{
opacity: 1,
scale: pulse && !prefers ? [1, 1.12, 1] : 1,
}}
transition={{
delay,
duration: pulse && !prefers ? 1.6 : 0.6,
repeat: pulse && !prefers ? Infinity : 0,
repeatType: "mirror",
ease: [0.22, 1, 0.36, 1],
}}
/>
)}
</>
);
};
// inward pulse particle
const Packet = ({
path,
delay = 0,
accent = "#00b8db",
duration = 1.8,
}: {
path: string;
delay?: number;
accent?: string;
duration?: number;
}) => {
const prefers = useReducedMotion();
return (
<motion.circle
r={4}
fill={accent}
initial={{ offsetDistance: "100%", opacity: 0 }}
animate={{
offsetDistance: ["100%", "0%"],
opacity: [0, 1, 0],
}}
transition={{
delay,
duration,
repeat: !prefers ? Infinity : 0,
repeatType: "loop",
ease: "linear",
}}
style={{ offsetPath: `path('${path}')` }}
/>
);
};
export default function Herodb({
className,
accent = "#00b8db",
bg = "#0a0a0a",
}: Props) {
const center = { x: 380, y: 210 };
const shardNodes = [
{ x: 160, y: 100, type: "text" },
{ x: 580, y: 120, type: "image" },
{ x: 620, y: 280, type: "audio" },
{ x: 420, y: 330, type: "text" },
{ x: 240, y: 320, type: "image" },
{ x: 150, y: 220, type: "dot" },
];
const paths = shardNodes.map(
(n) =>
`M ${n.x} ${n.y} Q ${(n.x + center.x) / 2} ${(n.y + center.y) / 2 - 40} ${center.x} ${center.y}`
);
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="HeroDB — active AI memory retrieval"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
{/* Background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" fill="none" stroke="#0f0f0f" strokeWidth="1" />
</pattern>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor={accent} stopOpacity="0.18" />
<stop offset="100%" stopColor={accent} stopOpacity="0" />
</radialGradient>
</defs>
<rect width={W} height={H} fill="url(#grid-dark)" />
{/* global halo */}
<circle
cx={center.x}
cy={center.y}
r={200}
fill="url(#glow)"
opacity={0.45}
/>
{/* core retrieval sphere */}
<motion.circle
cx={center.x}
cy={center.y}
r={22}
fill={accent}
initial={{ opacity: 0, scale: 0.85 }}
animate={{
opacity: 1,
scale: [1, 1.05, 1],
}}
transition={{
duration: 1.6,
repeat: Infinity,
repeatType: "mirror",
ease: "easeInOut",
}}
/>
{/* core aura ring */}
<motion.circle
cx={center.x}
cy={center.y}
r={40}
stroke={accent}
strokeWidth={2}
fill="none"
animate={{
opacity: [0.2, 0.7, 0.2],
}}
transition={{
duration: 2.2,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* inward paths */}
{paths.map((p, i) => (
<motion.path
key={`path-${i}`}
d={p}
stroke="#1F2937"
strokeWidth={2}
fill="none"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.4 }}
transition={{
delay: 0.05 * i,
duration: 0.7,
ease: [0.22, 1, 0.36, 1],
}}
/>
))}
{/* packets flowing inward */}
{paths.map((p, i) => (
<Packet
key={`pkt-${i}`}
path={p}
delay={i * 0.3}
accent={accent}
duration={1.8}
/>
))}
{/* modality nodes */}
{shardNodes.map((n, i) => (
<Node
key={`node-${i}`}
x={n.x}
y={n.y}
type={n.type as any}
r={12}
accent={accent}
pulse={i % 2 === 0}
delay={i * 0.1}
/>
))}
</svg>
</div>
);
}

View File

@@ -0,0 +1,231 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
bg?: string;
};
const W = 760;
const H = 420;
const PulseRing = ({
x,
y,
accent,
delay = 0,
}: {
x: number;
y: number;
accent: string;
delay?: number;
}) => {
const prefers = useReducedMotion();
return (
<motion.circle
cx={x}
cy={y}
r={42}
stroke={accent}
strokeWidth={2}
fill="none"
initial={{ scale: 0.85, opacity: 0 }}
animate={{
scale: !prefers ? [1, 1.12, 1] : 1,
opacity: !prefers ? [0.15, 0.6, 0.15] : 0.4,
}}
transition={{
delay,
duration: 2,
repeat: !prefers ? Infinity : 0,
repeatType: "mirror",
ease: "easeInOut",
}}
/>
);
};
const Egress = ({
from,
to,
delay = 0,
accent = "#00b8db",
}: {
from: { x: number; y: number };
to: { x: number; y: number };
delay?: number;
accent?: string;
}) => {
const path = `M ${from.x} ${from.y} L ${to.x} ${to.y}`;
const prefers = useReducedMotion();
return (
<>
<motion.path
d={path}
stroke="#1F2937"
strokeWidth={3}
strokeLinecap="round"
fill="none"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.4 }}
transition={{
delay,
duration: 0.8,
ease: [0.22, 1, 0.36, 1],
}}
/>
<motion.circle
r={4}
fill={accent}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0, 1, 0],
}}
transition={{
delay,
duration: 1.6,
repeat: !prefers ? Infinity : 0,
repeatType: "loop",
ease: "linear",
}}
style={{
offsetPath: `path('${path}')`,
}}
/>
</>
);
};
export default function MOSSandboxes({
className,
accent = "#00b8db",
bg = "#0a0a0a",
}: Props) {
const center = { x: 380, y: 210 };
// scoped egress ports
const egress = [
{ from: center, to: { x: 520, y: 140 } },
{ from: center, to: { x: 520, y: 280 } },
{ from: center, to: { x: 260, y: 320 } },
];
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="MOS Secure Agent Sandboxes"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
{/* BACKGROUND GRID */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" stroke="#0f0f0f" strokeWidth="1" />
</pattern>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor={accent} stopOpacity="0.20" />
<stop offset="100%" stopColor={accent} stopOpacity="0" />
</radialGradient>
</defs>
<rect width={W} height={H} fill="url(#grid-dark)" />
{/* GLOBAL GLOW */}
<circle cx={center.x} cy={center.y} r={200} fill="url(#glow)" opacity={0.45} />
{/* SANDBOX OUTER ENCLAVE */}
<motion.rect
x={center.x - 90}
y={center.y - 60}
width={180}
height={120}
rx={16}
stroke="#1F2937"
strokeWidth={3}
fill="none"
initial={{ opacity: 0 }}
animate={{ opacity: 0.7 }}
transition={{ duration: 0.6 }}
/>
{/* ATTESTATION RING */}
<PulseRing x={center.x} y={center.y} accent={accent} delay={0.3} />
{/* SIGNED WORKSPACE CORE */}
<motion.rect
x={center.x - 40}
y={center.y - 30}
width={80}
height={60}
rx={10}
stroke={accent}
strokeWidth={2}
strokeDasharray="10 6"
fill="none"
initial={{ opacity: 0, scale: 0.8 }}
animate={{
opacity: [0.4, 0.9, 0.4],
scale: [1, 1.06, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut",
}}
/>
{/* SANDBOX ACTIVE PAYLOAD */}
<motion.circle
cx={center.x}
cy={center.y}
r={18}
fill={accent}
initial={{ scale: 0.6, opacity: 0 }}
animate={{
opacity: 1,
scale: [1, 1.1, 1],
}}
transition={{
duration: 1.8,
repeat: Infinity,
repeatType: "mirror",
ease: "easeInOut",
}}
/>
{/* EGRESS PATHS */}
{egress.map((e, i) => (
<Egress key={i} from={e.from} to={e.to} delay={i * 0.2} accent={accent} />
))}
{/* “TEAR DOWN” FADE — ephemeral sandbox lifecycle */}
<motion.rect
x={center.x - 90}
y={center.y - 60}
width={180}
height={120}
rx={16}
fill={accent}
initial={{ opacity: 0 }}
animate={{
opacity: [0, 0, 0.12, 0],
}}
transition={{
duration: 4,
repeat: Infinity,
ease: "easeInOut",
}}
/>
</svg>
</div>
);
}

View File

@@ -0,0 +1,231 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
bg?: string;
};
const W = 760;
const H = 420;
const Node = ({
x,
y,
r = 12,
accent = "#00b8db",
pulse = false,
delay = 0,
}: {
x: number;
y: number;
r?: number;
accent?: string;
pulse?: boolean;
delay?: number;
}) => {
const prefers = useReducedMotion();
return (
<>
{/* Outer ring */}
<motion.circle
cx={x}
cy={y}
r={r + 8}
stroke="#1F2937"
strokeWidth={2}
fill="none"
initial={{ opacity: 0 }}
animate={{ opacity: 0.8 }}
transition={{ duration: 0.6, delay }}
/>
{/* Core node */}
<motion.circle
cx={x}
cy={y}
r={r}
fill={accent}
initial={{ opacity: 0, scale: 0.85 }}
animate={{
opacity: 1,
scale: pulse && !prefers ? [1, 1.1, 1] : 1,
}}
transition={{
duration: pulse ? 1.6 : 0.6,
repeat: pulse && !prefers ? Infinity : 0,
repeatType: "mirror",
ease: [0.22, 1, 0.36, 1],
delay,
}}
/>
</>
);
};
/* Animated encrypted packet */
const Packet = ({
path,
delay = 0,
accent = "#00b8db",
duration = 2.4,
}: {
path: string;
delay?: number;
accent?: string;
duration?: number;
}) => {
const prefers = useReducedMotion();
return (
<motion.circle
r={5}
fill={accent}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0, 1, 0],
}}
transition={{
delay,
duration,
repeat: !prefers ? Infinity : 0,
repeatType: "loop",
ease: "linear",
}}
style={{ offsetPath: `path('${path}')` }}
/>
);
};
export default function MyceliumMesh({
className,
accent = "#00b8db",
bg = "#0a0a0a",
}: Props) {
const center = { x: 380, y: 210 };
// Peer nodes forming a mesh
const nodes = [
{ x: 180, y: 120 },
{ x: 580, y: 100 },
{ x: 620, y: 260 },
{ x: 460, y: 330 },
{ x: 240, y: 320 },
{ x: 140, y: 240 },
];
// Multi-path routing (3 routes to illustrate "self-healing")
const routes = [
[nodes[0], nodes[1], nodes[2]], // path A→B→C
[nodes[0], nodes[5], nodes[4], nodes[3]], // path A→F→E→D
[nodes[1], nodes[4], nodes[3]], // path B→E→D
];
// Convert list of nodes → SVG path
const toPath = (list: any[]) =>
list
.map((p: any, i: number) =>
i === 0 ? `M ${p.x} ${p.y}` : `L ${p.x} ${p.y}`
)
.join(" ");
return (
<div
className={clsx(
"relative overflow-hidden",
className
)}
aria-hidden="true"
role="img"
aria-label="Mycelium Mesh — secure communication network"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
{/* Background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" stroke="#0f0f0f" strokeWidth="1" />
</pattern>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor={accent} stopOpacity="0.18" />
<stop offset="100%" stopColor={accent} stopOpacity="0" />
</radialGradient>
</defs>
<rect width={W} height={H} fill="url(#grid-dark)" />
{/* Wide ambient glow */}
<circle cx={center.x} cy={center.y} r={240} fill="url(#glow)" opacity={0.45} />
{/* Multi-path routing lines */}
{routes.map((pathNodes, i) => (
<motion.path
key={`line-${i}`}
d={toPath(pathNodes)}
stroke="#1F2937"
strokeWidth={3}
fill="none"
strokeLinecap="round"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.4 }}
transition={{
delay: 0.2 * i,
duration: 1,
ease: [0.22, 1, 0.36, 1],
}}
/>
))}
{/* Cyan “active” encrypted routing */}
{routes.map((pathNodes, i) => (
<motion.path
key={`signal-${i}`}
d={toPath(pathNodes)}
stroke={accent}
strokeWidth={2.5}
strokeDasharray="12 10"
strokeLinecap="round"
fill="none"
animate={{ opacity: [0.25, 0.8, 0.25] }}
transition={{
duration: 2.4,
repeat: Infinity,
delay: i * 0.3,
ease: "easeInOut",
}}
/>
))}
{/* Moving encrypted packets */}
{routes.map((pathNodes, i) => (
<Packet
key={`pkt-${i}`}
path={toPath(pathNodes)}
delay={i * 0.5}
duration={2.6}
accent={accent}
/>
))}
{/* Pulse nodes */}
{nodes.map((n, i) => (
<Node
key={`node-${i}`}
x={n.x}
y={n.y}
r={12}
accent={accent}
pulse={i % 2 === 0}
delay={i * 0.15}
/>
))}
</svg>
</div>
);
}

View File

@@ -15,6 +15,26 @@ export function CallToAction() {
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">

View File

@@ -0,0 +1,112 @@
"use client";
import { useState } from "react";
const files = [
{
id: "kube",
label: "kubernetes.yaml",
code: `apiVersion: apps/v1
kind: Deployment
metadata:
name: mycelium-app
spec:
replicas: 3
selector:
matchLabels:
app: mycelium-app
template:
metadata:
labels:
app: mycelium-app`,
},
{
id: "vdc",
label: "vdc.tf",
code: `provider "mycelium" {
identity = "~/.mycelium/id"
}
resource "mycelium_vdc" "production" {
name = "prod-vdc"
region = "eu-central"
nodes = 6
cpu_cores = 24
ram_gb = 128
storage = "10TB"
network_policies = ["private", "encrypted"]
}`,
},
{
id: "qsfs",
label: "qsfs.py",
code: `from qsfs import QSFS
# mount encrypted distributed filesystem
fs = QSFS.mount("/mnt/secure", key="my-private-key")
# write protected research data
with fs.open("dataset/raw-images/img001.png", "wb") as f:
f.write(b"...binary data...")
# list stored files via S3/IPFS/WebDAV compatibility layer
files = fs.list("dataset/raw-images/")
print("Stored files:", files)`,
},
];
export function CloudCodeTabs() {
const [active, setActive] = useState("kube");
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">
{/* Cyan skew background */}
<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-[#121212] 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 transition ${
active === f.id
? "border-b border-b-white/20 bg-white/5 text-white"
: "hover: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>
{/* Outer ring */}
<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

@@ -13,19 +13,17 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
<div className="px-6 py-16 lg:py-16">
<div className="max-w-2xl lg:pl-6">
<Eyebrow>
Mycelium Cloud
MYCELIUM CLOUD
</Eyebrow>
<H3 className="mt-4">
Run Kubernetes on the Sovereign Agentic Cloud
Sovereign Edge Cloud Infrastructure
</H3>
<p className="mt-6 text-lg">
Deploy K3s clusters on a global, self-healing mesh network.
Your workloads run on sovereign, encrypted infrastructure, without centralized cloud control.
Run compute, storage, and AI resources on infrastructure you control.
</p>
<p className="mt-4 lg:text-base italic text-gray-600 text-sm">
Works Alone. Works Together.
Mycelium Cloud can run on any network fabric, or pair with Mycelium Network
for sovereign connectivity.
<p className="mt-4 text-lg text-gray-600">
The Mycelium Cloud runs on a distributed grid of independent nodes,
delivering secure, scalable performance wherever your users or data live.
</p>
<div className="mt-10 flex items-center gap-x-6">
<Button
@@ -33,10 +31,10 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
variant="solid"
color="cyan"
>
Get started
Deploy Workloads
</Button>
<Button to="#" variant="outline">
Documentation <span aria-hidden="true"></span>
Explore Docs <span aria-hidden="true"></span>
</Button>
</div>
</div>

View File

@@ -13,7 +13,6 @@ import { Eyebrow, H3, H4 } from "@/components/Texts"
const product = {
subtitle: 'capabilities',
name: 'What You Can Run on Mycelium Cloud',
description: '<p>Host nodes, deploy workloads, or build private AI systems, all on infrastructure you own and control.</p>',
details: [
{
name: 'Kubernetes Clusters',
@@ -64,9 +63,6 @@ export function CloudHostingNew() {
<div className="mt-4 text-gray-300 text-xl"
dangerouslySetInnerHTML={{ __html: product.description }}
/>
{/* ✅ Details accordion */}

View File

@@ -0,0 +1,154 @@
"use client";
import { useState } from "react";
import { CloudCodeTabs } from "./CloudCodeTabs";
import { Eyebrow, H3, P } from "@/components/Texts";
const tabs = [
{
id: "kubernetes",
label: "Managed Kubernetes",
content: {
item: "Managed Kubernetes",
desc:
"Create and manage clusters across distributed environments using standard Kubernetes tools.",
bullets: [
"Create and manage clusters on distributed nodes",
"Run workloads at the edge or across enterprise sites",
"Keep full ownership of data and orchestration",
"Use the Kubernetes ecosystem without modification",
],
},
},
{
id: "vdc",
label: "Virtual Data Centers",
content: {
item: "Virtual Data Centers",
desc:
"Provision and manage full cloud environments without owning or maintaining servers.",
bullets: [
"Create dedicated environments for applications, databases, and internal services",
"Add or remove compute and storage resources instantly",
"Migrate workloads from cloud or on-prem systems",
"Meet compliance requirements by selecting where data resides",
"Benefit from continuous monitoring and automated recovery",
],
},
},
{
id: "qsfs",
label: "Quantum Safe File System (QSFS)",
content: {
item: "Quantum Safe File System (QSFS)",
desc:
"Encrypted, redundant storage designed for high-security and high-availability workloads. Data is distributed across independent nodes and remains accessible even during failures or outages.",
bullets: [
"Secure file storage with quantum-safe encryption",
"Distributed replication for durability",
"Standard protocol support: S3, IPFS, WebDAV",
"Automatic scaling as data grows",
"Consistent performance for research, enterprise, and AI workloads",
],
},
},
];
export function CloudIntro() {
const [active, setActive] = useState("kubernetes");
const current = tabs.find((t) => t.id === active)!.content;
return (
<section className="relative w-full bg-[#121212] overflow-hidden">
{/* Top Spacing Border */}
<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" />
<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">
{/* ================================
Header
================================= */}
<div className="mb-16">
<Eyebrow color="accent">Capabilities</Eyebrow>
<H3 color="white">What You Can Run on Mycelium Cloud</H3>
<P className="max-w-3xl text-gray-400 mt-6">
Host nodes, deploy workloads, or build private AI systems all on
infrastructure you own and control. Mycelium gives you scalable compute,
secure storage, and sovereign orchestration without depending on
hyperscalers.
</P>
</div>
{/* ================================
Two-column layout
================================= */}
<div className="flex flex-col lg:flex-row gap-16">
{/* Left: Code UI */}
<div className="w-full lg:w-1/2">
<CloudCodeTabs />
</div>
{/* Right: Tabs */}
<div className="w-full lg:w-1/2 text-white">
{/* Tabs Navigation */}
<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"
}`}
>
{tab.label}
</button>
))}
</div>
{/* Tab Content */}
<div className="mt-6 space-y-6">
<div>
<p className="text-lg font-medium text-white">{current.item}</p>
<p className="mt-2 text-base text-gray-400 leading-relaxed">
{current.desc}
</p>
</div>
<div className="mt-4 space-y-2">
<p className="text-sm uppercase tracking-wide text-cyan-400 font-semibold">
Key capabilities
</p>
<ul className="space-y-2">
{current.bullets.map((b, i) => (
<li key={i} className="text-base text-gray-300 flex gap-2">
<span className="text-cyan-500"></span>
{b}
</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
{/* Bottom Borders */}
<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>
);
}

View File

@@ -1,11 +1,9 @@
import { AnimatedSection } from '../../components/AnimatedSection'
import { CloudArchitecture } from './CloudArchitecture'
import { CloudUseCases } from './CloudUseCases'
import { CloudHeroNew } from './CloudHeroNew'
import { CloudBluePrint } from './CloudBluePrint'
import { CallToAction } from './CalltoAction'
import { CloudHostingNew } from './CloudHostingNew'
import { CloudIntro } from './CloudIntro'
import { CloudFeaturesLight } from './CloudFeaturesLight'
import { CloudPros } from './CloudPros'
export default function CloudPage() {
@@ -17,7 +15,7 @@ export default function CloudPage() {
</AnimatedSection>
<AnimatedSection>
<CloudHostingNew />
<CloudIntro />
</AnimatedSection>
<AnimatedSection>
@@ -25,15 +23,7 @@ export default function CloudPage() {
</AnimatedSection>
<AnimatedSection>
<CloudArchitecture />
</AnimatedSection>
<AnimatedSection>
<CloudUseCases />
</AnimatedSection>
<AnimatedSection>
<CloudBluePrint />
<CloudPros />
</AnimatedSection>
<AnimatedSection>

View File

@@ -0,0 +1,69 @@
import { Small } from '@/components/Texts'
const highlights = [
{
label: 'Platform Architecture',
title: 'Unified compute, storage & orchestration.',
description:
'One unified platform for compute, storage, and orchestration.',
},
{
label: 'Reliability',
title: 'Consistent performance everywhere.',
description:
'Runs reliably across distributed environments.',
},
{
label: 'Compatibility',
title: 'Works with your existing stack.',
description:
'Works with your existing tools and workflows.',
},
{
label: 'Scalability',
title: 'Grows with your needs.',
description:
'Scales from small projects to full environments.',
},
]
export function CloudPros() {
return (
<section className="relative w-full bg-[#FDFDFD] overflow-hidden">
{/* Top spacing line */}
<div className="max-w-7xl bg-[#FDFDFD] 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" />
<div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
<div className="grid lg:grid-cols-4">
{highlights.map((item) => (
<div
key={item.title}
className="group relative overflow-hidden border border-gray-100 bg-white p-8 transition hover:border-cyan-400/40 hover:bg-white"
>
{/* Hover glow */}
<div className="absolute inset-0 bg-linear-to-br from-cyan-200/0 via-cyan-100/20 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative">
<Small className="text-xs uppercase tracking-[0.16em] text-cyan-600">
{item.label}
</Small>
<h3 className="mt-4 text-lg font-semibold leading-tight text-black">
{item.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600">
{item.description}
</p>
</div>
</div>
))}
</div>
</div>
<div className="w-full border-b border-gray-100 bg-[#FDFDFD]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
</section>
)
}

View File

@@ -15,6 +15,26 @@ export function CallToAction() {
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">

View File

@@ -15,6 +15,26 @@ export function CallToAction() {
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">

View File

@@ -1,3 +1,4 @@
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container'
import { Button } from '@/components/Button'
import { H3, P } from '@/components/Texts'
@@ -37,34 +38,35 @@ export function CallToAction() {
</svg>
<Container className="relative">
<div className="mx-auto max-w-2xl text-center">
<div className="mx-auto max-w-3xl text-center">
<H3 className=" text-white ">
A Living Network
Use the Mycelium Stack Your Way
</H3>
<P className="mt-6 text-gray-300">
Mycelium isnt a platform.
Its the soil where a new internet grows open, resilient, and alive.
Deploy infrastructure, run workloads, connect environments, and build distributed AI systems, all on one network designed for autonomy and control.
</P>
<P className="mt-4 text-gray-300">
The self-sovereign network powering the next internet.
Start wherever you are. Scale on your own terms.
</P>
<div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4">
<Button to="/cloud" variant="solid" color="cyan">
Join Mycelium
<div className="mt-10 flex flex-wrap justify-center items-center gap-x-6 gap-y-4">
<Button to="/network" variant="solid" color="cyan">
Join the Network
</Button>
<Button
to="https://threefold.info/mycelium_network/docs/"
as="a"
target="_blank"
to="/cloud"
variant="outline"
color="white"
>
Join Early Cloud Access
Deploy in Cloud
</Button>
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
Host a Node &rarr;
</Link>
</div>
</div>
</Container>

View File

@@ -4,6 +4,7 @@ import { Eyebrow, H3, P } from "@/components/Texts";
import NoExtraction from "./animations/NoExtraction";
import NoControl from "./animations/NoControl";
import NoCentral from "./animations/NoCentral";
import NoSinglePoint from "./animations/NoSinglePoint";
const deterministicCards = [
{
@@ -11,7 +12,7 @@ const deterministicCards = [
eyebrow: "Why It Matters",
title: "Built for a Sovereign Digital World",
description:
"The current internet is a rent-seeking one. Mycelium builds one that belongs to everyone — where infrastructure, data, and intelligence stay with the people and organizations who create them.",
"The modern internet still runs on centralized platforms that own the servers, shape the rules, and extract the data. Mycelium gives you a way out. You operate the infrastructure. You keep the data. You decide the boundaries.",
animation: null,
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
@@ -35,18 +36,29 @@ const deterministicCards = [
description:
"You own your data. Run services and AI models on your own devices, ensuring privacy and control.",
animation: <NoExtraction className="lg:-mt-12" />, // ✅ NEW
colSpan: "lg:col-span-3",
colSpan: "lg:col-span-2",
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: "No single point of control.",
title: "No single point of failure.",
description:
"No single entity can dictate or censor your online experience.",
animation: <NoSinglePoint />, // ✅ NEW
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
rounded: "",
innerRounded: "",
},
{
id: "control",
title: "No single point of control.",
description:
"Infrastructure that moves with its operators, not a corporation.",
animation: <NoControl />, // ✅ NEW
colSpan: "lg:col-span-3",
colSpan: "lg:col-span-2",
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)]",
@@ -65,7 +77,7 @@ export function HomeArchitecture() {
{deterministicCards.map((card) => (
<div
key={card.id}
className={`relative ${card.colSpan} ${card.rowSpan} transition-transform duration-300 hover:scale-102 group`}
className={`relative flex flex-col ${card.colSpan} ${card.rowSpan} transition-transform duration-300 hover:scale-102 group`}
>
{/* ✅ Disable wrapper on first card */}
{!card.noBorder && (
@@ -79,8 +91,8 @@ export function HomeArchitecture() {
>
{/* ✅ 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">
<div className="lg:h-64 h-48 w-full overflow-hidden bg-transparent flex items-center justify-center">
<div className="w-full h-full object-cover">
{card.animation}
</div>
</div>

View File

@@ -72,7 +72,10 @@ export function HomeAudience() {
<P className="text-gray-800 mt-4">
The internet wasnt built for sovereignty. Today, data, AI models, and identity
live on centralized clouds owned by a few. Mycelium brings infrastructure back
live on centralized clouds and owned by a few.
</P>
<P className="text-gray-800 mt-4">
Mycelium brings infrastructure back
to people, communities, and nations: private, resilient, and cryptographically yours.
</P>

View File

@@ -6,7 +6,7 @@ export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => voi
<div className="px-4">
{/* Boxed container */}
<div
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"
className="relative mx-auto max-w-7xl border border-t-0 border-gray-100 bg-white overflow-hidden bg-size-[65%] bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/hero11.webp')" }}
>
{/* Inner padding */}
@@ -27,11 +27,15 @@ export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => voi
</H1>
<H4 className="mt-8">
The Living Network of the Next Internet
Private, distributed infrastructure built
for digital sovereignty
</H4>
<H5 className="mt-8 text-lg text-gray-600">
A new internet is emerging private, distributed, and self-sovereign. Mycelium is the living network that makes it possible. A peer-to-peer foundation where people, data, and intelligence connect directly without intermediaries, without compromise.
Run your apps, data, and intelligence on infrastructure that belongs to you
</H5>
<div className="mt-10 flex items-center gap-x-6">

View File

@@ -0,0 +1,69 @@
"use client";
const benefits = [
{
id: 1,
title: "For Integrators & Builders",
description:
"Deploy sovereign infrastructure for organizations, governments, and large-scale systems.",
image: "/images/dev.png",
},
{
id: 2,
title: "For Enterprises & Institutions",
description:
"Protect data, meet local compliance, and unlock new AI capabilities across distributed environments.",
image: "/images/cons.png",
},
{
id: 3,
title: "For Sovereignty Seekers",
description:
"Run nodes, build applications, and connect directly without relying on centralized platforms.",
image: "/images/seekers.png",
},
];
export function HomeDesign() {
return (
<section className="w-full max-w-8xl mx-auto bg-white dark:bg-transparent">
{/* Top spacing line */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200 dark:border-gray-800" />
<div className="w-full border border-l border-r border-gray-200 dark:border-gray-800" />
{/* Content */}
<div className="mx-auto max-w-7xl border-gray-200 dark:border-gray-800">
<dl className="grid grid-cols-1 lg:grid-cols-3 gap-4 lg:gap-0">
{benefits.map((item) => (
<div
key={item.id}
className="group flex items-start gap-2 bg-white/40 dark:bg-black/40 px-8 py-12 border border-gray-200 dark:border-gray-800 lg:border-t-0 lg:border-b-0"
>
{/* Image on the LEFT */}
<img
src={item.image}
alt={item.title}
className="h-30 w-30 object-contain opacity-90"
/>
{/* Text on the RIGHT */}
<div className="text-left">
<h3 className="text-base font-semibold tracking-wide text-gray-900 dark:text-white mb-2">
{item.title}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-300 leading-relaxed max-w-xs">
{item.description}
</p>
</div>
</div>
))}
</dl>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-t 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>
);
}

View File

@@ -2,6 +2,13 @@
import WorldMap from "@/components/ui/world-map";
import { Eyebrow, H3, P } from "@/components/Texts";
const stats = [
{ id: 1, name: 'CORES', value: '54,958', description: 'Total Central Processing Unit cores available on the grid.' },
{ id: 2, name: 'NODES', value: '1,493', description: 'Total number of nodes on the grid.' },
{ id: 3, name: 'SSD CAPACITY', value: '5,388,956', description: 'Total GB of storage (SSD, HDD, & RAM) on the grid.' },
{ id: 4, name: 'COUNTRIES', value: '44', description: 'Total number of countries with active nodes.' },
]
export function HomeMap() {
return (
<div className="bg-[#121212] w-full">
@@ -9,20 +16,22 @@ export function HomeMap() {
<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" />
<div className="max-w-7xl mx-auto text-center py-12 border border-t-0 border-b-0 border-gray-800">
<Eyebrow>Mycelium Nodes</Eyebrow>
<div className="max-w-7xl mx-auto text-center pt-12 border border-t-0 border-b-0 border-gray-800">
<Eyebrow>PROJECT MYCELIUM IS LIVE. </Eyebrow>
<H3 className="text-white">Host a Node, Grow the Network</H3>
<P className="text-sm md:text-lg text-gray-200 max-w-3xl mx-auto py-4">
Mycelium runs on real nodes hosted by people, communities, and enterprises across the world.
Each one adds capacity, resilience, and sovereignty to the network and earns rewards in return.
Mycelium runs on nodes hosted by people and organizations around the world.
Each node adds compute, storage, and bandwidth, expanding the networks capacity and resilience.
</P>
<P className="text-sm md:text-lg text-gray-200 max-w-3xl mx-auto py-4">
You can share your idle resources and earn rewards when they are used.
Configure it once. Your node takes over from there.
</P>
<p className="text-sm md:text-base text-gray-200 max-w-3xl mx-auto py-4">
Plug in once. It runs 24/7 powering the network and earning autonomously.
</p>
</div>
</div>
<div className="max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-800 ">
{/* ✅ Match same side margins */}
<div className="max-w-7xl mx-auto px-6 border border-t-0 border-b-0 border-gray-800">
<div className="max-w-5xl mx-auto px-6 ">
<WorldMap
dots={[
{ start: { lat: 64.2008, lng: -149.4937 }, end: { lat: 34.0522, lng: -118.2437 } }, // Alaska → LA
@@ -34,6 +43,33 @@ export function HomeMap() {
]}
/>
</div>
</div>
<div className="mx-auto max-w-7xl px-6 lg:px-8 border border-t-0 border-b-0 border-gray-800 pb-12">
<dl className="pt-6 grid grid-cols-1 gap-0.5 overflow-hidden rounded-md text-center sm:grid-cols-2 lg:grid-cols-4">
{stats.map((stat) => (
<div
key={stat.id}
className="flex flex-col bg-white/1 p-8"
>
<dt className="text-sm/6 font-semibold text-gray-300">
{stat.name}
</dt>
<dd className="order-first text-3xl font-semibold tracking-tight text-white">
{stat.value}
</dd>
<p className="mt-2 text-sm text-gray-400">
{stat.description}
</p>
</div>
))}
</dl>
</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>

View File

@@ -4,9 +4,9 @@ import { AnimatedSection } from '../../components/AnimatedSection'
import { CallToAction } from './CallToAction'
import { HomeTab } from './HomeTab'
import { HomeMap } from './HomeMap'
import { HomeAudience } from './HomeAudience'
import { HomeBlink } from './HomeBlink'
import { HomeAurora } from './HomeAurora'
import { HomeArchitecture } from './HomeArchitecture';
import { HomeDesign } from './HomeDesign';
@@ -19,7 +19,7 @@ export default function HomePage() {
return (
<div>
<AnimatedSection>
<HomeBlink onGetStartedClick={handleScrollToSlider} />
<HomeAurora onGetStartedClick={handleScrollToSlider} />
</AnimatedSection>
<AnimatedSection>
@@ -35,7 +35,7 @@ export default function HomePage() {
</AnimatedSection>
<AnimatedSection>
<HomeAudience />
<HomeDesign />
</AnimatedSection>
<AnimatedSection>

View File

@@ -3,125 +3,136 @@
import { Link } from "react-router-dom";
import { CP, CT, Eyebrow, H3, P } from "@/components/Texts";
const bentoCards = [
{
id: 'network',
title: 'Mycelium Network',
eyebrow: 'Network',
description: 'Encrypted peer-to-peer mesh networking across the globe.',
image: '/images/bento-network.png',
link: '/network',
colSpan: 'lg:col-span-3',
rowSpan: 'lg:row-span-1',
rounded: 'lg:rounded-tl-4xl max-lg:rounded-t-4xl',
innerRounded: 'lg:rounded-tl-[calc(2rem+1px)] max-lg:rounded-t-[calc(2rem+1px)]'
},
{
id: 'agents',
title: 'Mycelium Agents',
eyebrow: 'Agents',
description: 'Private, programmable AI systems that run on your hardware.',
image: '/images/bento-agent.jpg',
link: '/agents',
colSpan: 'lg:col-span-3',
rowSpan: 'lg:row-span-1',
rounded: 'lg:rounded-tr-4xl',
innerRounded: 'lg:rounded-tr-[calc(2rem+1px)]'
},
{
id: 'cloud',
title: 'Mycelium Cloud',
eyebrow: 'Cloud',
description: 'Deploy Kubernetes clusters on sovereign infrastructure.',
image: '/images/bento-cloud.jpg',
link: '/cloud',
colSpan: 'lg:col-span-6',
rowSpan: 'lg:row-span-1',
rounded: 'rounded-lg',
innerRounded: 'rounded-[calc(var(--radius-lg)+1px)]'
},
{
id: 'compute',
title: 'Mycelium Compute',
eyebrow: 'Compute',
description: 'The Compute resource layers powering the stack.',
image: '/images/bento-compute.png',
link: '/compute',
colSpan: 'lg:col-span-2',
rowSpan: 'lg:row-span-1',
rounded: 'lg:rounded-bl-4xl',
innerRounded: 'lg:rounded-bl-[calc(2rem+1px)]'
},
{
id: 'storage',
title: 'Mycelium Storage',
eyebrow: 'Storage',
description: 'The Storage resource layers powering the stack.',
image: '/images/bento-storage.png',
link: '/storage',
colSpan: 'lg:col-span-2',
rowSpan: 'lg:row-span-1',
rounded: 'rounded-lg',
innerRounded: 'rounded-[calc(var(--radius-lg)+1px)]'
},
{
id: 'gpu',
title: 'Mycelium GPU',
eyebrow: 'GPU',
description: 'The GPU resource layers powering the stack.',
image: '/images/bento-gpu.jpg',
link: '/gpu',
colSpan: 'lg:col-span-2',
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 HomeTab() {
return (
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* Top spacer + full-width line */}
{/* Top section separators */}
<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-100" />
{/* ✅ Section with vertical borders */}
{/* Main content */}
<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 ">Components</Eyebrow>
<Eyebrow className="pt-12">Components</Eyebrow>
<H3 className="mt-2">Explore the Stack</H3>
<P className="mt-6 max-w-4xl">
Mycelium unifies everything the next generation internet needs communication, cloud, and intelligence into one seamless, privacy-first network anyone can join.
From encrypted peer-to-peer communication to decentralized cloud and sovereign AI everything runs on one seamless system.
Myceliums technology stack gives you everything you need to build and run applications
on a distributed network, from connectivity and compute to personal environments and AI.
</P>
<div className="mt-8 grid grid-cols-1 gap-6 sm:mt-10 lg:grid-cols-6 lg:grid-rows-3 pb-12">
{bentoCards.map((card) => (
<Link to={card.link} key={card.id} className={`relative ${card.colSpan} ${card.rowSpan} transition-transform duration-300 hover:scale-102 cursor-pointer`}>
<div className={`absolute inset-0 rounded-md bg-white ${card.rounded}`} />
<div className={`relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] ${card.innerRounded}`}>
<img
alt={card.title}
src={card.image}
className="h-50 object-cover object-center"
/>
<div className="px-8 pt-4 pb-6">
<h3 className="text-sm/4 font-semibold text-cyan-500">{card.eyebrow}</h3>
<CT className="mt-2 text-lg lg:text-xl tracking-tight text-gray-950">{card.title}</CT>
<CP className="mt-1 max-w-lg text-gray-600">
{card.description}
{/* BENTO GRID LAYOUT — EXACT MATCH */}
<div className="mt-10 grid gap-4 sm:mt-16 lg:grid-cols-3 lg:grid-rows-2 pb-12">
{/* ------------------ LEFT TALL CARD ------------------ */}
<Link to="/network" className="relative lg:row-span-2 cursor-pointer">
<div className="absolute inset-px rounded-lg bg-white lg:rounded-l-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-l-[calc(2rem+1px)]">
<div className="px-8 pt-8 pb-3 sm:px-10 sm:pt-10 sm:pb-0">
<h3 className="text-sm/4 font-semibold text-cyan-500">LIVE</h3>
<CT className="mt-2 text-lg font-medium tracking-tight text-gray-950">Mycelium Network</CT>
<CP className="mt-2 max-w-lg text-sm/6 text-gray-600">
Peer-to-peer connectivity between users, nodes, and devices. The foundation for secure
communication and collaboration.
</CP>
</div>
{/* Tall image container */}
<div className="@container relative min-h-120 w-full grow max-lg:mx-auto max-lg:max-w-sm">
<div className="absolute inset-x-10 top-10 bottom-0 overflow-hidden
rounded-t-[12cqw] border-x-[3cqw] border-t-[3cqw]
border-gray-700 bg-gray-900 shadow-2xl">
<img
src="/images/bento-network.jpg"
className="size-full object-cover object-top"
/>
</div>
<div className={`pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 ${card.rounded}`} />
</Link>
))}
</div>
</div>
{/* ✅ Bottom full-width line + spacer */}
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5 lg:rounded-l-4xl" />
</Link>
{/* ------------------ MIDDLE TOP ------------------ */}
<Link to="/pods" className="relative cursor-pointer max-lg:row-start-1">
<div className="absolute inset-px rounded-lg bg-white max-lg:rounded-t-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)]">
<div className="px-8 pt-8 sm:px-10 sm:pt-10">
<h3 className="text-sm/4 font-semibold text-cyan-500">Coming Soon</h3>
<CT className="mt-2 text-lg font-medium tracking-tight text-gray-950">Mycelium Pods</CT>
<CP className="mt-2 max-w-lg text-sm/6 text-gray-600">
Personal digital environments that never reset and stay under your control. Build, deploy,
and connect on your own terms.
</CP>
</div>
<div className="flex flex-1 items-center justify-center px-8 max-lg:pt-10 sm:px-10 lg:pb-2">
<img
src="/images/bento-gpu.jpg"
className="w-full max-lg:max-w-xs"
/>
</div>
</div>
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5 max-lg:rounded-t-4xl" />
</Link>
{/* ------------------ MIDDLE BOTTOM ------------------ */}
<Link to="/agents" className="relative cursor-pointer max-lg:row-start-3 lg:col-start-2 lg:row-start-2">
<div className="absolute inset-px rounded-lg bg-white" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)]">
<div className="px-8 pt-8 sm:px-10 sm:pt-10">
<h3 className="text-sm/4 font-semibold text-cyan-500">Q1 2026</h3>
<CT className="mt-2 text-lg font-medium tracking-tight text-gray-950">Mycelium Agents</CT>
<CP className="mt-2 max-w-lg text-sm/6 text-gray-600">
Peer-to-peer AI that serves you, not your data. Train, deploy, and own your AI end-to-end.
</CP>
</div>
<div className="@container flex flex-1 items-center justify-center max-lg:py-6 lg:pb-2">
<img
src="/images/bento-agent.jpg"
className="h-[min(200px,40cqw)] object-cover"
/>
</div>
</div>
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5" />
</Link>
{/* ------------------ RIGHT TALL ------------------ */}
<Link to="/cloud" className="relative lg:row-span-2 cursor-pointer">
<div className="absolute inset-px rounded-lg bg-white max-lg:rounded-b-4xl lg:rounded-r-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-r-[calc(2rem+1px)]">
<div className="px-8 pt-8 pb-3 sm:px-10 sm:pt-10 sm:pb-0">
<h3 className="text-sm/4 font-semibold text-cyan-500">Early Access</h3>
<CT className="mt-2 text-lg font-medium tracking-tight text-gray-950">Mycelium Cloud</CT>
<CP className="mt-2 max-w-lg text-sm/6 text-gray-600">
Decentralized compute, storage, and orchestration. A full cloud service without a central operator.
</CP>
</div>
<div className="relative min-h-120 w-full grow">
<div className="absolute top-10 right-0 bottom-0 left-10 overflow-hidden
rounded-tl-xl bg-gray-900 shadow-2xl outline outline-white/10">
<img
src="/images/cloud/reserve.png"
className="size-full object-cover"
/>
</div>
</div>
</div>
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5 max-lg:rounded-b-4xl lg:rounded-r-4xl" />
</Link>
</div>
</div>
{/* Bottom separators */}
<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>

View File

@@ -0,0 +1,225 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string; // cyan
bg?: string; // solid dark background
gridStroke?: string;
};
const W = 720; // 4:3
const H = 540; // 4:3
export default function NoSinglePoint({
className,
accent = "#00b8db",
bg = "#0b0b0b",
gridStroke = "#2b2a2a",
}: Props) {
const prefers = useReducedMotion();
// Nodes (left source, right dest, top hub, bottom hub, plus two relays)
const nodes = {
left: { x: 120, y: H / 2 },
right: { x: W - 120, y: H / 2 },
top: { x: W / 2, y: 160 },
bot: { x: W / 2, y: H - 160 },
tl: { x: 240, y: 200 },
br: { x: W - 240, y: H - 200 },
};
// Redundant paths from left → right
const upperPath = `M ${nodes.left.x} ${nodes.left.y}
L ${nodes.tl.x} ${nodes.tl.y}
L ${nodes.top.x} ${nodes.top.y}
L ${nodes.right.x} ${nodes.right.y}`;
const lowerPath = `M ${nodes.left.x} ${nodes.left.y}
L ${nodes.bot.x} ${nodes.bot.y}
L ${nodes.br.x} ${nodes.br.y}
L ${nodes.right.x} ${nodes.right.y}`;
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* Subtle dark grid */}
<defs>
<pattern id="grid-dark-4x3" width="28" height="28" patternUnits="userSpaceOnUse">
<path d="M 28 0 L 0 0 0 28" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.35" />
</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-dark-4x3)" />
{/* Base links (all potential connectivity) */}
{[
`M ${nodes.left.x} ${nodes.left.y} L ${nodes.tl.x} ${nodes.tl.y}`,
`M ${nodes.tl.x} ${nodes.tl.y} L ${nodes.top.x} ${nodes.top.y}`,
`M ${nodes.top.x} ${nodes.top.y} L ${nodes.right.x} ${nodes.right.y}`,
`M ${nodes.left.x} ${nodes.left.y} L ${nodes.bot.x} ${nodes.bot.y}`,
`M ${nodes.bot.x} ${nodes.bot.y} L ${nodes.br.x} ${nodes.br.y}`,
`M ${nodes.br.x} ${nodes.br.y} L ${nodes.right.x} ${nodes.right.y}`,
// cross edges (mesh redundancy)
`M ${nodes.tl.x} ${nodes.tl.y} L ${nodes.bot.x} ${nodes.bot.y}`,
`M ${nodes.top.x} ${nodes.top.y} L ${nodes.br.x} ${nodes.br.y}`,
].map((d, i) => (
<motion.path
key={`base-${i}`}
d={d}
stroke="#1e1e1e"
strokeWidth={3}
strokeLinecap="round"
fill="none"
initial={{ pathLength: 0, opacity: 0.2 }}
animate={{ pathLength: 1, opacity: 0.5 }}
transition={{ duration: 0.8, delay: i * 0.05, ease: [0.22, 1, 0.36, 1] }}
/>
))}
{/* Highlight the two redundant main routes */}
<motion.path
d={upperPath}
fill="none"
stroke="#3a3a3a"
strokeWidth={4}
strokeLinecap="round"
initial={{ pathLength: 0, opacity: 0.6 }}
animate={{ pathLength: 1, opacity: 0.6 }}
transition={{ duration: 0.9 }}
/>
<motion.path
d={lowerPath}
fill="none"
stroke="#3a3a3a"
strokeWidth={4}
strokeLinecap="round"
initial={{ pathLength: 0, opacity: 0.6 }}
animate={{ pathLength: 1, opacity: 0.6 }}
transition={{ duration: 0.9, delay: 0.1 }}
/>
{/* Cyan accent dash showing “preferred/active” path(s) */}
<motion.path
d={upperPath}
fill="none"
stroke={accent}
strokeWidth={2}
strokeDasharray="10 8"
initial={{ pathLength: 0, opacity: 0.8 }}
animate={{ pathLength: 1, opacity: [0.8, 0.2, 0.8] }} // will fade as "blocked"
transition={{ duration: 1.1, repeat: Infinity, repeatType: "reverse" }}
filter="url(#glow)"
/>
<motion.path
d={lowerPath}
fill="none"
stroke={accent}
strokeWidth={2}
strokeDasharray="10 8"
initial={{ pathLength: 0, opacity: 1 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{ duration: 1 }}
filter="url(#glow)"
/>
{/* Moving packets: one tries upper (gets dimmed at top hub), one uses lower and continues */}
{!prefers && (
<>
{/* Upper path packet (dims near top hub to suggest block/censor but NOT stopping overall flow) */}
<motion.circle
r={5}
fill={accent}
style={{ offsetPath: `path('${upperPath}')` }}
initial={{ offsetDistance: "0%", opacity: 0.9 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0.9, 0.4, 0.9], // subtle dimming cycle
}}
transition={{ duration: 3.0, repeat: Infinity, ease: "linear" }}
filter="url(#glow)"
/>
{/* Lower path packet (stable flow) */}
<motion.circle
r={6}
fill={accent}
style={{ offsetPath: `path('${lowerPath}')` }}
initial={{ offsetDistance: "0%", opacity: 1 }}
animate={{ offsetDistance: ["0%", "100%"] }}
transition={{ duration: 2.4, repeat: Infinity, ease: "linear" }}
filter="url(#glow)"
/>
</>
)}
{/* Nodes */}
{Object.values(nodes).map((n, i) => (
<g key={`node-${i}`}>
<circle cx={n.x} cy={n.y} r={20} fill="#0f0f0f" stroke="#1f1f1f" strokeWidth={2} />
<motion.circle
cx={n.x}
cy={n.y}
r={8}
fill={i === 2 ? "#0f0f0f" : accent} // top hub inner is dark (to hint “blocked” moment)
stroke="#222"
strokeWidth={2}
animate={
!prefers
? i === 2 // top node (potential choke/attack point) pulses differently
? { opacity: [0.5, 0.25, 0.5], scale: [1, 0.95, 1] }
: { opacity: [0.9, 1, 0.9], scale: [1, 1.06, 1] }
: { opacity: 1 }
}
transition={{
duration: 2.2,
repeat: prefers ? 0 : Infinity,
ease: [0.22, 1, 0.36, 1],
delay: i * 0.05,
}}
filter="url(#glow)"
/>
</g>
))}
{/* A subtle “block” overlay on the top hub (appears/disappears) */}
{!prefers && (
<motion.g
initial={{ opacity: 0 }}
animate={{ opacity: [0, 0.7, 0] }}
transition={{ duration: 3.2, repeat: Infinity, ease: "easeInOut", delay: 0.8 }}
>
<circle
cx={nodes.top.x}
cy={nodes.top.y}
r={18}
fill="none"
stroke="#8b8b8b"
strokeWidth={2}
/>
<path
d={`M ${nodes.top.x - 10} ${nodes.top.y - 10} L ${nodes.top.x + 10} ${nodes.top.y + 10}
M ${nodes.top.x + 10} ${nodes.top.y - 10} L ${nodes.top.x - 10} ${nodes.top.y + 10}`}
stroke="#8b8b8b"
strokeWidth={2}
strokeLinecap="round"
/>
</motion.g>
)}
</svg>
</div>
);
}

View File

@@ -1,6 +1,7 @@
"use client";
import { Container } from "@/components/Container";
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container'
import { Button } from "@/components/Button";
export function CallToAction() {
@@ -15,31 +16,56 @@ export function CallToAction() {
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">
<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">
Choose How You Want to Start
Choose How You Want to Connect
</h2>
<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.
Choose How You Want to Connect
Use the network to link environments, deploy workloads, or host nodes to strengthen the mesh and run on your own hardware.
</p>
{/* ✅ 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
<div className="mt-10 flex flex-wrap justify-center items-center gap-x-6 gap-y-4">
<Button to="/network" variant="solid" color="cyan">
Join the Network
</Button>
</div>
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="https://threefold.info/mycelium_network/docs/" as="a" target="_blank" variant="outline" color="white" className="mt-4">
Host a Node
<Button
to="/cloud"
variant="outline"
color="white"
>
Deploy in Cloud
</Button>
</div>
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
Host a Node &rarr;
</Link>
</div>
</div>
</Container>

View File

@@ -18,10 +18,10 @@ export function Features() {
<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, performance, and autonomy.
</P>
<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.
<P className="mt-4 max-w-3xl text-lg text-gray-600">
Nodes connect through intelligent routing, peer discovery, and decentralized delivery to create a continuously optimized data mesh.
</P>
<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">

View File

@@ -2,7 +2,8 @@ import { useId } from 'react'
import { Container } from '@/components/Container'
import { Button } from '@/components/Button'
import phoneFrame from '../../images/phoneframe.png'
import { H3, P, CT } from "@/components/Texts";
import { H3, P
, Eyebrow } from "@/components/Texts";
function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
let id = useId()
@@ -79,23 +80,21 @@ export function Hero() {
<Container>
<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">
<H3 className="mb-4">
Mycelium Network
<Eyebrow className="mb-4">
MYCELIUM NETWORK
</Eyebrow>
<H3 className="mt-8 ">
The Network Stack for Private, Autonomous Networking
</H3>
<CT className="mt-8 font-medium text-gray-600 ">
Encrypted Peer-to-Peer Connectivity Across the Globe
</CT>
<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.
Connect once. Get private networking, censorship-resistant publishing, and on-network AI in one encrypted fabric.
</P>
<P className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
Works Alone. Works Together.
Mycelium Network can be used standalone, or together with Mycelium Cloud
for full-stack sovereignty.
Your Pod is your personal gateway to the network.
</P>
<div className="mt-8 flex flex-wrap gap-x-6 gap-y-4">
<Button to="/download" variant="solid" color="cyan">
Get Mycelium Connector
Get Started
</Button>
<Button to="/download" variant="outline" color="cyan">
Explore Docs

View File

@@ -23,17 +23,15 @@ export function NetworkCapabilities() {
<Eyebrow>WHAT IT ENABLES</Eyebrow>
<H4 className="mt-6 text-white">
A Private Networking Layer for Everything You Run
One Network. Many Capabilities.
</H4>
<P className="mt-6 text-gray-200">
Mycelium Network is the backbone for secure, autonomous connectivity
across devices, data centers, clusters, and self-hosted environments anywhere in the world.
One network for all your connectivity needs.
</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.
Mycelium replaces separate layers like VPNs, hosting, and DNS with a single encrypted, peer-to-peer system that links devices, apps, and environments directly.
</P>
</div>
@@ -47,7 +45,7 @@ export function NetworkCapabilities() {
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.
Every packet is encrypted and routed peer-to-peer. No intermediaries, no data sniffing, no compromise.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
@@ -59,7 +57,7 @@ export function NetworkCapabilities() {
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.
Every node, app, and microservice gets a unique global address. Permanently solves discovery, routing, and NAT issues.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
@@ -68,10 +66,10 @@ export function NetworkCapabilities() {
<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
Dynamic Pathfinding
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Traffic automatically finds the fastest path, dynamically re-routing around failures or congestion.
Traffic automatically finds the fastest route, re-routing around failures or congestion in real time.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
@@ -83,7 +81,7 @@ export function NetworkCapabilities() {
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.
No corporate servers, no authority that can disable or censor the network.
</p>
</div>
</div>

View File

@@ -6,6 +6,8 @@ import { SecondaryFeatures } from './SecondaryFeatures'
import { CallToAction } from './CallToAction'
import { NetworkCapabilities } from './NetworkCapabilities'
import { NetworkUsecases } from './NetworkUsecases'
import { CloudPros } from './NetworkPros'
export default function NetworkPage() {
return (
@@ -19,7 +21,7 @@ export default function NetworkPage() {
</AnimatedSection>
<AnimatedSection>
<Features />
<SecondaryFeatures />
</AnimatedSection>
<AnimatedSection>
@@ -27,13 +29,18 @@ export default function NetworkPage() {
</AnimatedSection>
<AnimatedSection>
<NetworkUsecases />
<Features />
</AnimatedSection>
<AnimatedSection>
<SecondaryFeatures />
<CloudPros />
</AnimatedSection>
<AnimatedSection>
<NetworkUsecases />
</AnimatedSection>
<AnimatedSection>
<CallToAction />
</AnimatedSection>

View File

@@ -0,0 +1,69 @@
import { Small } from '@/components/Texts'
const highlights = [
{
label: 'Network Advantage',
title: 'Fully peer-to-peer, no logins, no central cloud.',
description:
'Connectivity flows directly between users, nodes, and services without platform ownership.',
},
{
label: 'Platform',
title: 'One unified platform for compute, storage, and orchestration.',
description:
'Runs reliably across distributed environments. Works with your existing tools and workflows. Scales from small projects to full environments.',
},
{
label: 'Scale',
title: 'Scales instantly from one POD to thousands.',
description:
'Deploy locally or expand globally — the mesh routes and balances itself automatically.',
},
{
label: 'Security',
title: 'Secure, quantum-safe, and edge-ready for the next decade.',
description:
'Next-gen encryption, multipath routing, and attested nodes protect workloads everywhere.',
},
]
export function CloudPros() {
return (
<section className="relative w-full bg-[#FDFDFD] overflow-hidden">
{/* Top spacing line */}
<div className="max-w-7xl bg-[#FDFDFD] 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="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-200">
<div className="grid lg:grid-cols-4">
{highlights.map((item) => (
<div
key={item.title}
className="group relative overflow-hidden border border-gray-200 bg-white p-8 transition hover:border-cyan-400/40 hover:bg-white"
>
{/* Hover glow */}
<div className="absolute inset-0 bg-linear-to-br from-cyan-200/0 via-cyan-100/20 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative">
<Small className="text-xs uppercase tracking-[0.16em] text-cyan-600">
{item.label}
</Small>
<h3 className="mt-4 text-lg font-semibold leading-tight text-black">
{item.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600">
{item.description}
</p>
</div>
</div>
))}
</div>
</div>
<div className="w-full border-b border-gray-200 bg-[#FDFDFD]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
</section>
)
}

View File

@@ -1,12 +1,12 @@
"use client";
import { useRef } from "react";
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
import {
LockClosedIcon,
ArrowPathIcon,
GlobeAltIcon,
SignalIcon,
CpuChipIcon,
} from "@heroicons/react/24/solid";
const networkUseCases = [
@@ -27,46 +27,52 @@ const networkUseCases = [
{
title: "Service-to-Service Networking Across Environments",
description:
"Connect applications running across home labs, cloud regions, edge nodes, and data centers all on one address space.",
"Connect apps running across home labs, cloud regions, edge nodes, and datacenters all on one address space.",
ideal: "Ideal for: dev teams, distributed apps, container + K3s workloads",
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.",
"Automatically routes around ISP failures, censorship, and regional outages using multipath encrypted relays.",
ideal:
"Ideal for: research networks, cross-border orgs, distributed compute, off-grid / rural deployments",
"Ideal for: cross-border orgs, distributed compute, remote/off-grid deployments",
icon: ArrowPathIcon,
},
{
title: "Adaptive Mesh for Mobile & Edge Movement",
description:
"Devices moving between networks, cities, or countries maintain continuous secure connectivity with no reconnection steps.",
ideal: "Ideal for: mobile agents, field teams, robotics, vehicles, IoT",
icon: SignalIcon,
},
{
title: "Compute Fabric Linking Nodes & Agents",
description:
"Agents, jobs, and tasks can interact across nodes without exposing private IPs or opening firewalls.",
ideal: "Ideal for: agent networks, edge AI workloads, distributed computation",
icon: CpuChipIcon,
},
];
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 (
<section className="bg-white w-full max-w-8xl mx-auto">
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-slate-200" />
<div className="w-full border-t border-l border-r border-slate-200" />
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-slate-200 bg-white overflow-hidden">
<ul
ref={sliderRef}
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
>
<div className="mx-auto max-w-7xl border border-t-0 border-b-0 border-slate-200 bg-white">
{/* GRID 3 x 3 */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
{networkUseCases.map((item, idx) => (
<li
<div
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"
}`}
className={`
border border-slate-200 p-10 relative
${item.isIntro ? "bg-gray-50/80" : "bg-white"}
`}
>
{/* Intro Card */}
{item.isIntro ? (
<div className="flex flex-col justify-between h-full">
<div>
@@ -81,47 +87,39 @@ export function NetworkUsecases() {
{item.description}
</P>
</div>
<div className="flex items-center gap-x-4 mt-2">
<button
onClick={scrollLeft}
className="h-8 w-8 flex items-center justify-center border border-slate-300 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowBackOutline className="text-gray-600" size={16} />
</button>
<button
onClick={scrollRight}
className="h-8 w-8 flex items-center justify-center border border-slate-300 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowForwardOutline className="text-gray-600" size={16} />
</button>
</div>
</div>
) : (
<>
{/* Icon above title */}
{/* Icon */}
{item.icon && (
<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>
)}
{/* Title */}
<p className="text-lg font-semibold text-gray-900">
{item.title}
</p>
{/* Description */}
<p className="mt-2 text-gray-600 leading-snug">
{item.description}
</p>
{/* Ideal for */}
<p className="mt-3 text-xs font-medium text-cyan-700">
{item.ideal}
</p>
</>
)}
</li>
))}
</ul>
</div>
))}
</div>
</div>
<div className="w-full border-b border-slate-200 bg-white" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-slate-200" />
</section>
);
}

View File

@@ -264,7 +264,7 @@ function FeaturesDesktop() {
{feature.name}
</Tab>
</FeatureTitle>
<FeatureDescription color="secondary" className="mt-2">
<FeatureDescription color="white" className="mt-2">
{feature.description}
</FeatureDescription>
</div>
@@ -419,9 +419,7 @@ export function PrimaryFeatures() {
How Mycelium Operates
</SectionHeader>
<P color="light" className="mt-6">
Mycelium, like its natural namesake, thrives on decentralization,
efficiency, and security, making it a truly powerful force in the world
of decentralized networks.
Your device connects to an encrypted peer-to-peer mesh that automatically handles routing, discovery, and communication.
</P>
</div>
</Container>

View File

@@ -4,41 +4,41 @@ import { CP } from '@/components/Texts'
const features = [
{
name: 'Quantum Safe Storage Functionality',
name: 'Sovereign DNS',
description:
"Mycelium's quantum safe storage enables flexible, scalable, and efficient data distribution across a decentralized network, ensuring redundancy and security.",
icon: DeviceArrowIcon,
},
{
name: 'Entry and Exit Points for AI Workloads',
description:
'Seamlessly connect AI applications to Mycelium, providing optimized and secured data pipelines for training, inference, and real-time processing.',
icon: DeviceCardsIcon,
},
{
name: 'Data Storage and Retrieval Mechanisms',
description:
'Users can choose between storing data locally for quick access or utilizing the distributed grid for enhanced scalability and resilience.',
icon: DeviceClockIcon,
},
{
name: 'Integrated Name Services (DNS)',
description:
'The Integrated DNS system efficiently finds the shortest path between users and websites, automatically balancing loads and identifying alternative routes in case of internet issues.',
'Human-readable names secured by your keypair, not a registrar. Unblockable discovery, private namespaces, and instant resolution across PODs.',
icon: DeviceListIcon,
},
{
name: 'Frontend/Backend Integration',
name: 'Integrated VPN (Desktop)',
description:
'Mycelium provides seamless integration with existing applications, enabling developers to leverage decentralized storage across both frontend and backend architectures.',
'Connect securely from anywhere. No setup and no servers needed. Peer-to-peer routing delivers local speed and global reach.',
icon: DeviceLockIcon,
},
{
name: 'CDN (Content Delivery Network)',
name: 'Unstoppable Publishing',
description:
'Mycelium accelerates data distribution by acting as a decentralized CDN, ensuring fast, secure, and efficient content delivery across global nodes with minimal latency.',
'Host sites or services directly from your POD. Signed content, geo-aware delivery, and built-in resistance to takedowns.',
icon: DeviceChartIcon,
},
{
name: 'AI-Driven Search',
description:
'Private, semantic search across your own data and sites. Indexes locally, shares results securely, and retrieves instantly on-edge.',
icon: DeviceArrowIcon,
},
{
name: 'Private Chat',
description:
'Peer-to-peer messaging with zero metadata and zero servers. Works offline through nearby peers and is encrypted end-to-end.',
icon: DeviceCardsIcon,
},
{
name: 'On-Network AI',
description:
'Run LLMs and AI tools directly inside the network. Keep data local, distribute workloads, and build your own autonomous agents.',
icon: DeviceClockIcon,
},
]
function DeviceArrowIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
@@ -197,12 +197,12 @@ export function SecondaryFeatures() {
<Container className="py-12 border border-t-0 border-b-0 border-gray-100">
<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">FEATURES</h2>
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
Expanding the Network Layer
Core Features
</p>
<p className="mt-6 text-lg text-gray-600">
The Mycelium Network is evolving to support richer data movement, identity, and application connectivity across the mesh. These enhancements deepen autonomy and improve real-world usability.
The Mycelium Network is evolving with new features to support richer data movement, identity, and application connectivity across the mesh.
</p>
</div>
<ul

View File

@@ -0,0 +1,69 @@
"use client";
import { Container } from "@/components/Container";
import { Button } from "@/components/Button";
export function CallToAction() {
return (
<section className="relative overflow-hidden bg-[#121212]">
<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-800" />
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">
<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">
Join Mycelium Grid
</h2>
<p className="mt-6 text-lg text-gray-300">
Be part of a global network that powers private, distributed
infrastructure. Host a node, contribute resources, and earn rewards
while expanding the sovereign digital grid.
</p>
<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">
Join Mycelium
</Button>
</div>
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/docs" variant="outline" color="white" className="mt-4">
Explore docs
</Button>
</div>
</div>
</div>
</Container>
</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 bg-transparent" />
</section>
);
}

View File

@@ -0,0 +1,115 @@
"use client";
import { motion } from "framer-motion";
import { SectionHeader, P, Eyebrow, CT, CP } from "@/components/Texts";
import type { ComponentPropsWithoutRef } from "react";
type CircleIconProps = ComponentPropsWithoutRef<"svg">;
const CircleNumber1Icon = (props: CircleIconProps) => (
<svg viewBox="0 0 24 24" fill="currentColor" {...props}>
<path d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2zm.994 5.886c-.83-.777-1.755-.394-1.701.404l-.006.114v8l.007.117a1 1 0 001.986 0l.007-.117V9l-.006-.114z" />
</svg>
);
const CircleNumber2Icon = (props: CircleIconProps) => (
<svg viewBox="0 0 24 24" fill="currentColor" {...props}>
<path d="M12 2a10 10 0 110 20 10 10 0 010-20zm1 5h-3a1 1 0 100 2h3v2h-2a2 2 0 00-2 2v2a2 2 0 002 2h3a1 1 0 100-2h-3v-2h2a2 2 0 002-2V9a2 2 0 00-2-2z" />
</svg>
);
const CircleNumber3Icon = (props: CircleIconProps) => (
<svg viewBox="0 0 24 24" fill="currentColor" {...props}>
<path d="M12 2a10 10 0 110 20 10 10 0 010-20zm1 5h-2a2 2 0 00-2 2 1 1 0 102 0h2v2h-2c-1.39 0-2.103 1.67-1.11 2.588l.11.098h3v2h-2a1 1 0 100 2h2a2 2 0 002-2v-2a2 2 0 00-.25-.97l-.068-.115.068-.115A1.99 1.99 0 0015 11V9a2 2 0 00-2-2z" />
</svg>
);
const features = [
{
name: "Build Your Private Setup",
description:
"Run a node in your home or office and use it to host private workloads, models, and data. Experiment, deploy, or tinker locally, then offset your costs by sharing unused capacity with the network.",
icon: CircleNumber1Icon,
},
{
name: "Strengthen the Network",
description:
"Every node adds bandwidth, compute, and resilience to the Mycelium Grid. Together, hosts form the physical foundation for decentralized communication, storage, and AI.",
icon: CircleNumber2Icon,
},
{
name: "Earn Rewards",
description:
"Share storage, CPU, GPU, and bandwidth. When your resources are used, you earn network rewards based on real demand.",
icon: CircleNumber3Icon,
},
];
export function NodeBenefits() {
return (
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
{/* Top spacing + border */}
<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 px-6 lg:px-6 py-12 bg-[#111111] border border-t-0 border-b-0 border-gray-800 max-w-7xl mx-auto">
{/* Header */}
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.3 }}
transition={{ duration: 0.6, ease: "easeOut", delay: 0.1 }}
className="mx-auto max-w-5xl text-center"
>
<Eyebrow color="accent">Host</Eyebrow>
<SectionHeader
className="text-3xl font-medium tracking-tight"
color="light"
>
Benefits of Hosting Nodes
</SectionHeader>
<P className="mt-6" color="light">
Hosting a node gives you private compute, contributes to the global
Mycelium infrastructure, and unlocks ways to earn from real network
usage all while keeping sovereignty and control.
</P>
</motion.div>
{/* Features */}
<motion.ul
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true, amount: 0.2 }}
transition={{ duration: 0.5, delay: 0.2 }}
className="mx-auto mt-8 grid max-w-2xl grid-cols-1 gap-x-8 gap-y-8 text-base/7 sm:grid-cols-2 sm:gap-y-16 lg:mx-12 lg:mt-12 lg:max-w-7xl lg:grid-cols-3"
>
{features.map((feature, index) => (
<motion.li
key={feature.name}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.2 }}
transition={{
duration: 0.45,
delay: 0.3 + index * 0.15,
ease: "easeOut",
}}
className="rounded-2xl border border-gray-300 bg-white/5 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 backdrop-blur-md"
>
<feature.icon className="mb-4 h-8 w-8 text-white" />
<CT as="span" className="text-left font-semibold" color="light">
{feature.name}
</CT>
<CP className="mt-2 text-left text-sm" color="light">
{feature.description}
</CP>
</motion.li>
))}
</motion.ul>
</div>
<div className="w-full border-b border-gray-800 bg-[#121212]" />
</section>
);
}

View File

@@ -0,0 +1,40 @@
'use client'
import { Button } from '@/components/Button'
import { Eyebrow, H3 } from '@/components/Texts'
export function NodeHero() {
return (
<div className="">
{/* Boxed container */}
<div
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" }}
>
{/* Inner padding */}
<div className="px-6 py-16 lg:py-16">
<div className="max-w-2xl lg:pl-6">
<Eyebrow>MYCELIUM NODES</Eyebrow>
<H3 as="h1" className="mt-4">
Host a Node. Power the Network.
</H3>
<p className="mt-6 text-lg">
The Mycelium Network runs on nodes hosted by people and organizations around the world. Each node adds capacity, resilience, and sovereignty, expanding a global network for private, distributed compute and AI.
</p>
<div className="mt-10 flex items-center gap-x-6">
<Button to="#node-getting-started" as="a" variant="solid" color="cyan">
How it works
</Button>
<Button to="#node-architecture" as="a" variant="outline">
Explore Docs <span aria-hidden="true"></span>
</Button>
</div>
</div>
</div>
</div>
{/* ✅ 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>
</div>
)
}

View File

@@ -0,0 +1,224 @@
"use client";
import { useState } from "react";
import { motion } from "framer-motion";
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
import {
QuestionMarkCircleIcon,
ShieldCheckIcon,
CheckIcon,
} from "@heroicons/react/20/solid";
/* ------------------------------------------ */
/* PRODUCT DATA */
/* ------------------------------------------ */
const nodes = {
ainode: {
id: "ainode",
name: "Edge AI Node",
subtitle: "Based on Ryzen AI MAX+ 395 platform",
description:
"A compact AI-ready node designed for local inference, agent hosting, and sovereign edge compute. Equipped with a dedicated AI accelerator and optimized thermals.",
image: "/images/ainode.png",
features: [
"Run local AI and cloud workloads",
"Host Mycelium Slices and earn SPORE",
"Experiment with decentralized apps and LLM agents",
"Participate in the global Mycelium Network",
],
buyUrl:
"https://www.gmktec.com/products/amd-ryzen%E2%84%A2-ai-max-395-evo-x2-ai-mini-pc?variant=6f7af17b-b907-4a9d-9c7e-afecfb41ed98",
learnUrl:
"https://threefold.info/mycelium_economics/docs/recommended_nodes/edge_ai_node",
},
edgenode: {
id: "edgenode",
name: "Edge Compute Node",
subtitle: "Based on GMKtec NUCBox M6 Ultra (Ryzen 5 7640HS)",
description:
"High-performance edge compute for networking, local models, and multiple agents. Excellent balance of efficiency and compute density.",
image: "/images/edgenode.png",
features: [
"Efficient 6-core / 12-thread Zen 4 architecture at up to 5.0 GHz boost. (CPU Monkey)",
"Low power consumption (35 W class HS chip) conducive to continuous operation. (LaptopMedia)",
"Compact size → easier placement, less cooling overhead.",
"Full node owner flexibility: use it for private workloads, host slices, or a hybrid of both.",
],
buyUrl:
"https://www.gmktec.com/products/amd-ryzen-5-7640hs-mini-pc-nucbox-m6-ultra?spm=..product_ba613c14-a120-431b-af10-c5c5ca575d55.header_1.1&variant=35ad4a9a-3f31-490c-a2d1-ef9ea3773fe9",
learnUrl:
"https://threefold.info/mycelium_economics/docs/recommended_nodes/edge_node",
},
};
const configOptions = [
{
id: "ainode",
name: "EDGE AI Node",
description: "Optimized for local inference + AI acceleration",
},
{
id: "edgenode",
name: "EDGE Compute Node",
description: "Optimized for general-purpose compute + agent workloads",
},
];
/* ------------------------------------------ */
/* MAIN COMPONENT */
/* ------------------------------------------ */
export function NodeProducts() {
const [selectedNode, setSelectedNode] = useState(nodes.ainode);
return (
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
{/* Top spacing + border */}
<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" />
{/* MAIN SECTION */}
<div className="relative px-6 lg:px-12 py-16 bg-[#111111] border border-t-0 border-b-0 border-gray-800 max-w-7xl mx-auto">
{/* --------------------------------------- */}
{/* SECTION TITLE + INTRO PARAGRAPH */}
{/* --------------------------------------- */}
<div className="text-center max-w-3xl mx-auto mb-16">
<Eyebrow color="accent">Hardware</Eyebrow>
<SectionHeader className="text-3xl font-medium" color="light">
Recommended Nodes
</SectionHeader>
<P className="mt-4 text-gray-300">
Below are some of the best-performing and most commonly recommended nodes
for hosting agents, Mycelium workloads, and contributing compute to the network.
</P>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 lg:gap-24 max-w-6xl mx-auto">
{/* ------------------------------ */}
{/* LEFT — TEXT AREA */}
{/* ------------------------------ */}
<motion.div
key={selectedNode.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4 }}
className="flex flex-col justify-center"
>
<h1 className="text-3xl font-semibold text-white">
{selectedNode.name}
</h1>
<p className="mt-1 text-gray-400 text-base">
{selectedNode.subtitle}
</p>
{/* Description */}
<p className="mt-6 text-gray-300 text-base leading-relaxed">
{selectedNode.description}
</p>
{/* FEATURES */}
<ul className="mt-6 space-y-2">
{selectedNode.features.map((f, i) => (
<li key={i} className="flex items-start">
<CheckIcon className="w-5 h-5 text-green-500 mt-0.5" />
<p className="ml-2 text-sm text-gray-300 leading-relaxed">
{f}
</p>
</li>
))}
</ul>
{/* CONFIG SELECTOR */}
<fieldset className="mt-10">
<legend className="text-sm font-medium text-gray-200">
Choose Your Node Type
</legend>
<div className="mt-3 grid grid-cols-1 sm:grid-cols-2 gap-4">
{configOptions.map((opt) => (
<label
key={opt.id}
className={`group relative flex flex-col border rounded-xl p-4 cursor-pointer transition
${
selectedNode.id === opt.id
? "border-cyan-500 bg-white/5"
: "border-gray-700 hover:border-gray-500"
}`}
onClick={() => setSelectedNode(nodes[opt.id as keyof typeof nodes])}
>
<span className="text-white font-medium">{opt.name}</span>
<span className="mt-1 text-sm text-gray-400">{opt.description}</span>
</label>
))}
</div>
</fieldset>
<div className="mt-4">
<a href="https://threefold.info/mycelium_economics/docs/category/recommended-nodes" target="_blank" rel="noopener noreferrer" className="inline-flex text-sm text-gray-500 hover:text-gray-300 transition">
What config should I choose?
<QuestionMarkCircleIcon className="ml-1 w-5 h-5 text-gray-500" />
</a>
</div>
{/* ------------------------ */}
{/* BUTTONS AREA */}
{/* ------------------------ */}
<div className="mt-10 flex flex-col sm:flex-row gap-4">
{/* Outline Button */}
<a
href={selectedNode.learnUrl}
target="_blank"
rel="noopener noreferrer"
className="flex-1 sm:flex-none text-center border border-gray-700 hover:border-gray-500
text-gray-300 hover:text-white px-8 py-3 rounded-lg transition"
>
Learn More
</a>
{/* Solid Cyan Button */}
<a
href={selectedNode.buyUrl}
target="_blank"
rel="noopener noreferrer"
className="flex-1 sm:flex-none text-center bg-cyan-600 hover:bg-cyan-700
text-white px-8 py-3 rounded-lg font-medium transition"
>
Purchase Node
</a>
</div>
</motion.div>
{/* ------------------------------ */}
{/* RIGHT — IMAGE */}
{/* ------------------------------ */}
<motion.div
key={selectedNode.image}
initial={{ opacity: 0, scale: 0.92 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.35 }}
className="flex justify-center"
>
<img
src={selectedNode.image}
alt={selectedNode.name}
className="max-w-md rounded-2xl "
/>
</motion.div>
</div>
</div>
{/* Bottom border */}
<div className="w-full border-b border-gray-800 bg-[#121212]" />
</section>
);
}

View File

@@ -0,0 +1,115 @@
"use client";
import { Container } from "@/components/Container";
import { Small } from "@/components/Texts";
// Heroicons
import {
ShieldCheckIcon,
BoltIcon,
GlobeAltIcon,
ServerStackIcon,
CheckBadgeIcon,
CpuChipIcon,
} from "@heroicons/react/24/solid";
const nodeSpecs = [
{
title: "Autonomous Operation",
description: "Runs autonomously with no central control.",
icon: ServerStackIcon,
},
{
title: "Encrypted by Default",
description: "Fully encrypted and identity-based.",
icon: ShieldCheckIcon,
},
{
title: "Energy Efficient",
description: "Energy-efficient and quiet, designed for 24/7 uptime.",
icon: BoltIcon,
},
{
title: "Measured Uptime",
description: "Automatically measures uptime and contribution.",
icon: CheckBadgeIcon,
},
{
title: "Full Mycelium Stack Support",
description: "Supports Mycelium Network, Cloud, Pods, and Agents.",
icon: GlobeAltIcon,
},
// ✅ NEW 6th card (to complete the grid)
{
title: "Edge & Home Ready",
description:
"Runs seamlessly on compact hardware for edge, home, or micro-datacenter deployments.",
icon: CpuChipIcon,
},
];
export function NodeSpecs() {
return (
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* Top horizontal spacing */}
<div className="max-w-7xl 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 className="py-12 border border-t-0 border-b-0 border-gray-100">
{/* Header */}
<div className="mx-auto max-w-4xl sm:text-center">
<h2 className="text-base/7 font-semibold text-cyan-500">
NODE SPECIFICATIONS
</h2>
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
Built for Reliability and Control
</p>
<p className="mt-6 text-lg text-gray-600">
Each node strengthens the network and helps build a more open,
sovereign and distributed internet.
</p>
</div>
{/* Cards */}
<ul
role="list"
className="mx-auto mt-12 grid max-w-2xl grid-cols-1 gap-6
sm:grid-cols-2 lg:max-w-none lg:grid-cols-3 md:gap-y-10"
>
{nodeSpecs.map((item) => {
const Icon = item.icon;
return (
<li
key={item.title}
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"
>
{/* Title + label */}
<div className="flex items-center justify-between">
<h3 className="font-semibold text-gray-900">
{item.title}
</h3>
<Icon className="h-6 w-6 text-cyan-500" />
</div>
{/* Short description */}
<p className="mt-4 text-gray-700 leading-snug">
{item.description}
</p>
</li>
);
})}
</ul>
</Container>
{/* Bottom spacing */}
<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"></div>
</section>
);
}

View File

@@ -0,0 +1,87 @@
"use client";
import { Eyebrow, H3, P, CT, CP } from "@/components/Texts";
import {
CloudArrowDownIcon,
CpuChipIcon,
WalletIcon,
BoltIcon,
} from "@heroicons/react/24/solid";
const steps = [
{
name: "Buy a Node",
description:
"Choose your hardware setup. You can use your own device or one of the recommended models below.",
icon: CpuChipIcon,
},
{
name: "Download Mycelium OS",
description:
"Install the Mycelium OS to prepare your node for network access.",
icon: CloudArrowDownIcon,
},
{
name: "Link Your Wallet",
description:
"Connect your private key from your Mycelium account to enable rewards and authentication.",
icon: WalletIcon,
},
{
name: "Plug In and Go",
description:
"Connect to power and to the internet. Your node will join automatically and start contributing.",
icon: BoltIcon,
},
];
export function NodeSteps() {
return (
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* Top line */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
<div className="w-full border-t border-l border-r border-gray-100" />
<div className="max-w-7xl bg-white mx-auto py-16 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-500">HOW IT WORKS</Eyebrow>
<H3 className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
Host a Node
</H3>
<P className="mt-6 text-lg text-gray-600">
Hosting a node takes minutes, and it runs automatically once online.
</P>
</div>
{/* 🔹 Horizontal Stepper */}
<div className="relative mt-16 px-6 flex flex-col gap-8 lg:flex-row lg:items-start lg:justify-between">
{steps.map((step, i) => (
<div key={step.name} className="relative flex-1 px-4">
{/* 🔹 Horizontal connector line (desktop only) */}
{i < steps.length - 1 && (
<div className="hidden lg:block absolute top-5 left-[55%] w-full h-[4px] bg-gray-400 -z-10" />
)}
{/* 🔹 Step header with icon */}
<div className="flex items-center gap-3">
<div className="flex items-center justify-center w-8 h-8 rounded-full bg-cyan-100 text-cyan-600">
<step.icon className="w-5 h-5" />
</div>
<CT>{step.name}</CT>
</div>
{/* 🔹 Description */}
<CP className="mt-3">{step.description}</CP>
</div>
))}
</div>
</div>
{/* bottom line */}
{/* ✅ 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>
);
}

View File

@@ -0,0 +1,22 @@
import React from 'react';
import { NodeHero } from './NodeHero';
import { NodeBenefits } from './NodeBenefits';
import { NodeSteps } from './NodeSteps';
import { NodeProducts } from './NodeProducts';
import { NodeSpecs } from './NodeSpecs';
import { CallToAction } from './CallToAction';
const NodesPage: React.FC = () => {
return (
<>
<NodeHero />
<NodeBenefits />
<NodeSteps />
<NodeProducts />
<NodeSpecs />
<CallToAction />
</>
);
};
export default NodesPage;

View File

@@ -0,0 +1,71 @@
"use client";
import { Button } from "@/components/Button";
import { Container } from "@/components/Container";
export function CallToAction() {
return (
<section className="relative overflow-hidden bg-[#121212] ">
{/* ✅ 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-800"></div>
<div className="w-full border-t border-l border-r border-gray-800" />
{/* ✅ Main boxed area */}
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">
<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">
Join the First Wave
</h2>
<p className="mt-6 text-lg text-gray-300">
Pods are launching soon. Be among the first to claim your private space in the new internet.
</p>
{/* ✅ 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="#" variant="solid" color="cyan" className="mt-4">
Join the Waitlist
</Button>
</div>
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="#" variant="outline" color="white" className="mt-4">
Deploy Pods in Your Community
</Button>
</div>
</div>
</div>
</Container>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<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>
);
}

View File

@@ -1,4 +1,4 @@
import { H3, Eyebrow } from "@/components/Texts"
import { H3, Eyebrow, P } from "@/components/Texts"
export default function Homepod() {
return (
@@ -6,7 +6,7 @@ export default function Homepod() {
{/* Boxed container */}
<div
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/pods.png')", backgroundSize: "contain" }}
style={{ backgroundImage: "url('/images/computehero11.webp')", backgroundSize: "contain" }}
>
{/* Inner padding */}
<div className="px-6 py-16 lg:py-16">
@@ -17,11 +17,11 @@ export default function Homepod() {
<H3 className="mt-4">
Your Private Space in the New Internet
</H3>
<p className="mt-6 text-lg">
<P className="mt-6 text-gray-800">
Imagine having your own corner of the internet private, secure, and always online.
A Pod is your personal digital space on the Mycelium Network.
Its where your conversations, files, and digital tools live owned by you, connected to others directly.
</p>
</P>
</div>
</div>

View File

@@ -0,0 +1,151 @@
"use client";
import { useRef } from "react";
import { Eyebrow, CP, CT, H4 } from "@/components/Texts";
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
import {
HomeModernIcon,
CpuChipIcon,
ServerStackIcon,
ShieldCheckIcon,
} from "@heroicons/react/24/solid";
const capabilities = [
{
isIntro: true,
eyebrow: "CAPABILITIES",
title: "What is a Pod?",
description: "",
},
{
title: "Your private digital home on the decentralized internet",
description:
"Your Pod is a private digital home where apps, data, and identity live independently of Big Tech and central servers.",
icon: (
<div className="flex items-start justify-start">
<HomeModernIcon className="h-12 w-12 text-cyan-400" />
</div>
),
},
{
title: "An always-on space you fully control",
description:
"A dedicated, always-on environment you fully command — your own sovereign slice of the network that never goes offline.",
icon: (
<div className="flex items-start justify-start">
<CpuChipIcon className="h-12 w-12 text-cyan-400" />
</div>
),
},
{
title: "Runs communication, storage, and collaboration tools",
description:
"Runs your communication, storage, and collaboration tools in a secure local environment without reliance on outside platforms.",
icon: (
<div className="flex items-start justify-start">
<ServerStackIcon className="h-12 w-12 text-cyan-400" />
</div>
),
},
{
title: "Fully encrypted, federated peer-to-peer network",
description:
"Encrypted, federated peer-to-peer networking that links your Pod directly with trusted devices without intermediaries.",
icon: (
<div className="flex items-start justify-start">
<ShieldCheckIcon className="h-12 w-12 text-cyan-400" />
</div>
),
},
];
export function PodCapabilities() {
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 */}
<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-[#111]/60"
}`}
>
{/* INTRO CARD */}
{item.isIntro ? (
<div className="flex flex-col justify-between h-full">
<div>
<Eyebrow>{item.eyebrow}</Eyebrow>
<H4 className="text-white mt-0 max-w-lg">{item.title}</H4>
<p className="text-gray-400 lg:text-lg text-sm leading-relaxed">
{item.description}
</p>
</div>
{/* Arrow controls */}
<div className="flex items-center gap-x-4 mt-2">
<button
onClick={scrollLeft}
className="h-8 w-8 flex items-center justify-center border border-gray-800 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-800 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowForwardOutline
className="text-gray-300"
size={16}
/>
</button>
</div>
</div>
) : (
<>
{/* LEFT-ALIGNED ICON */}
{item.icon}
<br />
{/* LEFT-ALIGNED TEXT */}
<CT className="font-semibold leading-tight text-white text-left">
{item.title}
</CT>
<CP className="mt-2 text-gray-400 text-left">
{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,74 @@
import { Small } from '@/components/Texts'
const highlights = [
{
label: 'Identity',
title: 'Identity built on cryptographic keys',
description:
'combined with familiar logins for everyday access',
},
{
label: 'Network',
title: 'Runs on the Mycelium Network',
description:
'not on centralized cloud servers',
},
{
label: 'Privacy',
title: 'No data collection or tracking',
description:
'Your Pod decides what to share',
},
{
label: 'Resilience',
title: 'No single point of failure',
description:
'If one node goes offline, others keep you connected',
},
{
label: 'Scalability',
title: 'Expandable architecture',
description:
'Each Pod can host your personal AI Agent and scale with your needs',
},
]
export function PodsBenefits() {
return (
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
{/* Top line */}
<div className="max-w-7xl py-6 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="bg-[#121212] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-800">
<div className="grid lg:grid-cols-5">
{highlights.map((item) => (
<div
key={item.title}
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="relative">
<Small className="text-xs uppercase tracking-[0.16em] text-cyan-200">
{item.label}
</Small>
<h3 className="mt-4 text-lg font-semibold text-white">
{item.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-300">
{item.description}
</p>
</div>
</div>
))}
</div>
</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>
)
}

View File

@@ -0,0 +1,94 @@
import {
ChatBubbleLeftRightIcon,
CalendarDaysIcon,
UsersIcon,
CpuChipIcon,
} from '@heroicons/react/24/solid'
import { Eyebrow, H4, P } from '@/components/Texts'
export function PodsComing() {
return (
<section className="w-full max-w-8xl mx-auto bg-white">
{/* Top horizontal line */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
<div className="w-full border-t border-l border-r border-gray-200" />
{/* Main content */}
<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-200">
{/* LEFT SIDE Title + Intro */}
<div className="max-w-xl">
<Eyebrow className="text-cyan-600">COMING SOON</Eyebrow>
<H4 className="mt-6 text-gray-900">
Be Among The First
</H4>
<P className="mt-6 text-gray-700">
The first Pods are launching soon.
10,000 early Pods will be available for early adopters. Next, Pods will support peer-to-peer AI Agents that live inside your environment.
Your own AI, powered by your data without any data leaks.
</P>
</div>
{/* RIGHT SIDE — 4 upcoming features */}
<div className="space-y-10">
{/* 1 — Private Chat & Calls */}
<div>
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
<ChatBubbleLeftRightIcon className="h-6 w-6 text-cyan-600 mr-3" />
Private Chat & Calls
</h3>
<p className="mt-2 text-gray-700 max-w-2xl">
Peer-to-peer conversations and calling routed directly between Pods.
</p>
<div className="mt-8 h-px w-full bg-cyan-200" />
</div>
{/* 2 — Calendar & File Sync */}
<div>
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
<CalendarDaysIcon className="h-6 w-6 text-cyan-600 mr-3" />
Calendar & File Sync
</h3>
<p className="mt-2 text-gray-700 max-w-2xl">
Your schedules, documents, and files synced across your Pods with no central cloud.
</p>
<div className="mt-8 h-px w-full bg-cyan-200" />
</div>
{/* 3 — Secure Team Spaces */}
<div>
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
<UsersIcon className="h-6 w-6 text-cyan-600 mr-3" />
Secure Team Spaces
</h3>
<p className="mt-2 text-gray-700 max-w-2xl">
Create shared Pods for teams, communities, or groups fully encrypted, fully sovereign.
</p>
<div className="mt-8 h-px w-full bg-cyan-200" />
</div>
{/* 4 — Early AI Agent Integration */}
<div>
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
<CpuChipIcon className="h-6 w-6 text-cyan-600 mr-3" />
Early AI Agent Integration
<span className="ml-2 text-xs text-gray-400">🕒</span>
</h3>
<p className="mt-2 text-gray-700 max-w-2xl">
Host your personal AI agent inside your Pod private, local-first, and fully under your control.
</p>
</div>
</div>
</div>
{/* Bottom horizontal line */}
<div className="w-full border-b border-gray-200" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
</section>
)
}

View File

@@ -0,0 +1,121 @@
'use client'
import {
Disclosure,
DisclosureButton,
DisclosurePanel,
} from '@headlessui/react'
import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline'
import { Eyebrow, H3, H4 } from "@/components/Texts"
const product = {
subtitle: "Federation",
name: "Runs on Your Own Infrastructure",
description: `
<p>
Each Pod lives on your own hardware or on trusted local nodes in the Mycelium Network.
There is no central cloud and no company in the middle. You are not uploading your life to the cloud. You are running it yourself.
</p>
`,
details: [
{
name: "Your Data Lives on Your Pods",
description:
"Full control of where your data is stored and how its shared.",
},
{
name: "Direct Pod-to-Pod Networking",
description:
"Direct connections between Pods for faster, private communication.",
},
{
name: "No One Can Spy or Shut You Down",
description:
"Independence from corporate servers or cloud outages.",
},
{
name: "Resilient Even if Nodes Disconnect",
description:
"Continuous availability even if one node disconnects.",
},
],
}
export function PodsDesign() {
return (
<div className="bg-white text-gray-900">
{/* TOP LINE */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
<div className="w-full border-t border-l border-r border-gray-100" />
<main className="mx-auto max-w-7xl px-6 lg:px-12 py-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-2xl lg:max-w-none">
<div className="lg:grid lg:grid-cols-5 lg:items-start lg:gap-x-8">
{/* IMAGE */}
<div className="lg:col-span-2 lg:mt-8 mt-2">
<img
alt="Mycelium Federation"
src="/images/pod1.png"
className="aspect-square w-full object-cover rounded-md"
/>
</div>
{/* PRODUCT INFO */}
<div className="mt-8 px-4 sm:px-0 lg:mt-0 lg:col-span-3">
<Eyebrow className="text-cyan-600">
{product.subtitle}
</Eyebrow>
<H4 className="text-gray-900">
{product.name}
</H4>
<div
className="mt-4 text-gray-700 text-xl"
dangerouslySetInnerHTML={{ __html: product.description }}
/>
{/* DETAILS ACCORDION */}
<section className="mt-6">
<div className="divide-y divide-gray-200 border-t border-cyan-600/60">
{product.details.map((detail) => (
<Disclosure key={detail.name} as="div">
<H3>
<DisclosureButton className="group flex w-full items-center justify-between py-6 text-left">
<span className="text-lg font-medium text-gray-900">
{detail.name}
</span>
<span className="ml-6 flex items-center">
<PlusIcon className="block h-6 w-6 text-gray-500 group-open:hidden" />
<MinusIcon className="hidden h-6 w-6 text-cyan-600 group-open:block" />
</span>
</DisclosureButton>
</H3>
<DisclosurePanel className="pb-6">
<p className="text-gray-600 text-base">
{detail.description}
</p>
</DisclosurePanel>
</Disclosure>
))}
</div>
</section>
</div>
</div>
</div>
</main>
{/* BOTTOM LINE */}
<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" />
</div>
)
}

View File

@@ -0,0 +1,128 @@
"use client";
import { Container } from "@/components/Container";
import { Small } from "@/components/Texts";
const useCases = [
{
title: "Private Messaging & Calling",
description:
"Communicate directly Pod-to-Pod with no centralized routing.",
bullets: [
"End-to-end encrypted messaging and voice calling.",
"No intermediaries — connections flow directly between Pods.",
"Zero metadata profiling, tracking, or data resale.",
],
},
{
title: "Safe File Storage & Sharing",
description:
"Store and share files securely without exposing data to third parties.",
bullets: [
"Files remain private with no platform-level scanning or analysis.",
"Share documents and media directly with trusted contacts.",
"Full ownership of your content — no cloud vendor dependencies.",
],
},
{
title: "Personal Calendar & Meetings",
description:
"Manage your schedule within your own sovereign digital space.",
bullets: [
"Keep events, appointments, and reminders fully private.",
"Coordinate calls and meetings entirely inside your Pod.",
"No syncing with external servers or corporate platforms.",
],
},
{
title: "Private Communities & Teams",
description:
"Create groups or collaborative spaces without platform ownership.",
bullets: [
"Form teams, friendship circles, and micro-communities.",
"All interactions occur directly Pod-to-Pod.",
"No hosting company or service provider controls your group data.",
],
},
{
title: "Quantum Safe File System (QSFS)",
description:
"Store data using a self-healing, encrypted, quantum-resistant system.",
bullets: [
"Files are encrypted, split, and distributed across trusted nodes.",
"Designed to withstand future quantum-level attacks.",
"Automatic repair and reconstruction of data fragments.",
],
},
{
title: "Access From Any Device",
description:
"Your Pod travels with you — always accessible, always yours.",
bullets: [
"Use your Pod from phones, laptops, tablets, or shared machines.",
"Your identity, apps, and files follow you securely.",
"No syncing or duplicated copies — direct access to your environment.",
],
},
];
export function PodsFeatures() {
return (
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* Top horizontal 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" />
<Container className="py-12 border border-t-0 border-b-0 border-gray-100">
{/* Header */}
<div className="mx-auto max-w-4xl sm:text-center">
<h2 className="text-base/7 font-semibold text-cyan-500">
WHAT YOU CAN DO
</h2>
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
A Fully Personal, Sovereign Digital Environment
</p>
<p className="mt-6 text-lg text-gray-600">
Pods use open standard protocols like Matrix and Nostr. Everything runs directly through the Mycelium Network.
</p>
</div>
{/* Cards */}
<ul
role="list"
className="mx-auto mt-12 grid max-w-2xl grid-cols-1 gap-6
sm:grid-cols-2 lg:max-w-none lg:grid-cols-3 md:gap-y-10"
>
{useCases.map((useCase) => (
<li
key={useCase.title}
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"
>
{/* Title + label */}
<div className="flex items-center justify-between">
<h3 className="font-semibold text-gray-900">
{useCase.title}
</h3>
<Small className="uppercase tracking-[0.25em] text-cyan-500">
Feature
</Small>
</div>
{/* Short description */}
<p className="mt-4 text-gray-700 leading-snug">
{useCase.description}
</p>
</li>
))}
</ul>
</Container>
{/* Bottom 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>
);
}

View File

@@ -1,7 +1,7 @@
"use client";
import { Eyebrow, H3, P } from "@/components/Texts";
import CloudPods from "./animations/CloudPods";
import PodsFlow from "./animations/PodsFlow";
export function PodsHow() {
return (
@@ -13,34 +13,40 @@ export function PodsHow() {
<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">
{/* ✅ Two-column layout */}
<div className="flex flex-col lg:flex-row-reverse gap-16">
<div className="flex flex-col lg:flex-row-reverse gap-8">
{/* ✅ Right side animation */}
<div className="w-full lg:w-1/2">
<CloudPods />
<div className="w-full lg:w-4/9">
<PodsFlow />
</div>
{/* ✅ Left side content */}
<div className="w-full lg:w-1/2 text-white">
<div className="w-full lg:w-5/9 text-white">
<Eyebrow color="accent" className="">
How it works
</Eyebrow>
<H3 color="white" className="mt-6">
What Living in a Pod Feels Like
A Pod in Action
</H3>
<P className="max-w-3xl text-gray-400 mt-6">
When you use Mycelium, everything your messages, calls, files runs directly from your Pod.
<P className="max-w-4xl text-gray-400 mt-6">
When you use Mycelium, everything runs directly from your Pod.
</P>
<ul className="max-w-4xl text-gray-400 mt-6 space-y-2 ml-6">
<li className="flex items-start gap-2">
<span className="mt-1 inline-block size-2 rounded-full bg-cyan-400" />
<span>When you message someone, it goes Pod to Pod, not through a central server.</span>
</li>
<li className="flex items-start gap-3">
<span className="mt-1 inline-block size-2 rounded-full bg-cyan-400" />
<span>When you host a call, it runs on your Pod no third-party data centers.</span>
</li>
<li className="flex items-start gap-3">
<span className="mt-1 inline-block size-2 rounded-full bg-cyan-400" />
<span>When you save a file, it stays on your Pod, encrypted and always available.</span>
</li>
</ul>
<P className="max-w-3xl text-gray-400 mt-4">
Its your personal digital hub:
When you message someone, it goes Pod to Pod, not through a central server.
When you host a call, it runs on your Pod no third-party data centers.
</P>
<P className="max-w-3xl text-gray-400 mt-4">
When you save a file, it stays on your Pod, encrypted and always available.
No one else can read it, rent it, or switch it off.
</P>
<P className="max-w-3xl text-gray-400 mt-4">
You dont log in to the internet you are part of it.
</P>
</div>

View File

@@ -1,13 +1,21 @@
import Homepod from './Homepod';
import { PodsCapabilities } from './PodsCapabilities';
import { PodsHow } from './PodsHow';
import { PodsFeatures } from './PodsFeatures';
import { PodsDesign } from './PodsDesign';
import { PodsBenefits } from './PodsBenefits';
import { CallToAction } from './CallToAction';
import { PodsWhat } from './PodsWhat';
const PodsPage = () => {
return (
<>
<Homepod />
<PodsCapabilities />
<PodsWhat />
<PodsFeatures />
<PodsHow />
<PodsDesign />
<PodsBenefits />
<CallToAction />
</>
);
};

View File

@@ -0,0 +1,143 @@
import { CheckIcon } from "@heroicons/react/20/solid";
import { Eyebrow, H3 } from "@/components/Texts";
const tiers = [
{
name: "Pod Basic",
id: "pod-basic",
href: "#",
priceMonthly: "€3",
description:
"A sovereign starter Pod with private communication, storage, and local-first identity.",
features: [
"1 private space (chat, calls, storage)",
"Local-first identity (no sign-up)",
"Peer-to-peer encrypted networking",
],
mostPopular: false,
},
{
name: "Pod Plus",
id: "pod-plus",
href: "#",
priceMonthly: "€5",
description:
"A multi-device Pod with team spaces and expanded tools for encrypted collaboration.",
features: [
"Team spaces & multi-device sync",
"Shared encrypted folders",
"Priority relay paths for roaming devices",
],
mostPopular: true,
},
{
name: "Pod Pro",
id: "pod-pro",
href: "#",
priceMonthly: "€8",
description:
"Advanced Pod with AI Agent support and the upcoming private automation layer.",
features: [
"AI Agent layer (coming soon)",
"Federated compute support",
"Private AI memory stored on your Pod",
],
mostPopular: false,
},
];
export function PodsPricing() {
return (
<div className="bg-[#121212] text-white ">
{/* Top horizontal line */}
<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="mx-auto max-w-7xl px-6 lg:px-8 py-12 border border-t-0 border-b-0 border-gray-800">
{/* Header */}
<div className="mx-auto max-w-4xl text-center">
<Eyebrow>PLANS</Eyebrow>
<H3 className="mt-2 text-white">
Choose your Pod
</H3>
</div>
<p className="mx-auto mt-6 max-w-2xl text-center text-lg text-gray-400 sm:text-xl">
Personal, sovereign cloud environmentspriced for everyone.
</p>
{/* Pricing grid */}
<div className="isolate mx-auto mt-16 grid max-w-md grid-cols-1 gap-y-8
sm:mt-20 lg:max-w-none lg:grid-cols-3 lg:mx-0">
{tiers.map((tier, i) => (
<div
key={tier.id}
className={`flex flex-col justify-between rounded-3xl p-8 xl:p-10
bg-[#1a1a1a]/60 border border-gray-800 hover:border-cyan-500 transition
${tier.mostPopular ? "lg:z-10" : "lg:mt-8"}
${i === 0 ? "lg:rounded-r-none" : ""}
${i === tiers.length - 1 ? "lg:rounded-l-none" : ""}`}
>
<div>
<div className="flex items-center justify-between">
<h3
id={tier.id}
className={`text-lg font-semibold ${
tier.mostPopular ? "text-cyan-500" : "text-white"
}`}
>
{tier.name}
</h3>
{tier.mostPopular && (
<p className="rounded-full bg-cyan-500/10 px-2.5 py-1 text-xs font-semibold text-cyan-500">
Most popular
</p>
)}
</div>
<p className="mt-4 text-sm text-gray-300">{tier.description}</p>
<p className="mt-6 flex items-baseline gap-x-1">
<span className="text-4xl font-semibold">{tier.priceMonthly}</span>
<span className="text-sm font-semibold text-gray-400">/month</span>
</p>
<ul className="mt-8 space-y-3 text-sm text-gray-300">
{tier.features.map((feature) => (
<li key={feature} className="flex gap-x-3">
<CheckIcon className="h-5 w-5 flex-none text-cyan-500" />
{feature}
</li>
))}
</ul>
</div>
{/* CTA */}
<a
href={tier.href}
aria-describedby={tier.id}
className={`mt-8 block rounded-md px-3 py-2 text-center text-sm font-semibold
focus-visible:outline-2 focus-visible:outline-offset-2
${
tier.mostPopular
? "bg-cyan-500 text-white hover:bg-cyan-400 focus-visible:outline-cyan-500"
: "bg-white/10 text-white hover:bg-white/20 focus-visible:outline-cyan-500"
}`}
>
Choose Pod
</a>
</div>
))}
</div>
</div>
{/* Bottom horizontal line */}
<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" />
</div>
);
}

106
src/pages/pods/PodsWhat.tsx Normal file
View File

@@ -0,0 +1,106 @@
"use client";
import {
ServerIcon,
ShieldCheckIcon,
BoltIcon,
GlobeAltIcon,
} from "@heroicons/react/24/solid";
import { Eyebrow, H3 } from "@/components/Texts";
const podCards = [
{
id: "intro",
eyebrow: "Capabilities",
title: "What is a Pod?",
description: null,
icon: null,
custom: true,
noBorder: true,
colSpan: "lg:col-span-4",
},
{
id: "home",
title: "Your private digital home on the decentralized internet",
description:
"Your Pod is a private digital home where apps, data, and identity live independently of Big Tech and central servers.",
icon: ServerIcon,
},
{
id: "control",
title: "An always-on space you fully control",
description:
"A dedicated, always-on environment you fully command — your own sovereign slice of the network that never goes offline.",
icon: ShieldCheckIcon,
},
{
id: "tools",
title: "Runs communication, storage, and collaboration tools",
description:
"Runs your communication, storage, and collaboration tools in a secure local environment without reliance on outside platforms.",
icon: BoltIcon,
},
{
id: "networking",
title: "Fully encrypted, federated peer-to-peer network",
description:
"Encrypted, federated peer-to-peer networking that links your Pod directly with trusted devices without intermediaries.",
icon: GlobeAltIcon,
},
];
export function PodsWhat() {
return (
<section className="relative w-full bg-[#121212] overflow-hidden">
{/* Top horizontal line */}
<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" />
{/* Content container */}
<div className="mx-auto bg-[#111111] max-w-7xl px-6 lg:px-10 border border-t-0 border-b-0 border-gray-800">
{/* 4-column grid */}
<div className="grid grid-cols-1 gap-12 pt-12 lg:grid-cols-4 pb-20">
{podCards.map((card) => {
const Icon = card.icon;
return (
<div
key={card.id}
className={`${card.colSpan || ""} flex flex-col ${
card.custom ? "" : "transition-transform duration-300 hover:scale-[1.02]"
}`}
>
{/* Custom Intro Card */}
{card.custom ? (
<>
<Eyebrow>{card.eyebrow}</Eyebrow>
<H3 className="mt-2 text-white">{card.title}</H3>
</>
) : (
<>
{/* TITLE WITH ICON (matching the TL example) */}
<dt className="flex items-center gap-x-3 text-base font-semibold text-white">
<Icon className="h-6 w-6 text-cyan-500" aria-hidden="true" />
{card.title}
</dt>
{/* DESCRIPTION */}
<dd className="mt-4 text-base text-gray-300">
{card.description}
</dd>
</>
)}
</div>
);
})}
</div>
</div>
{/* Bottom border */}
<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>
);
}

View File

@@ -0,0 +1,192 @@
"use client";
import { motion } from "framer-motion";
import clsx from "clsx";
type Props = {
className?: string;
accent?: string;
gridStroke?: string;
};
const W = 760;
const H = 420;
export default function PodsFlow({
className,
accent = "#00b8db",
gridStroke = "#2b2a2a",
}: Props) {
const pods = [
{ x: 100, y: 180, label: "Pod 1" },
{ x: 260, y: 180, label: "Pod 2" },
{ x: 420, y: 180, label: "Pod 3" },
{ x: 580, y: 180, label: "Pod 4" },
];
// Pulse path
const path = `
M ${pods[0].x + 80} ${pods[0].y + 40}
L ${pods[1].x - 10} ${pods[1].y + 40}
L ${pods[1].x + 80} ${pods[1].y + 40}
L ${pods[2].x - 10} ${pods[2].y + 40}
L ${pods[2].x + 80} ${pods[2].y + 40}
L ${pods[3].x - 10} ${pods[3].y + 40}
`;
// Arrow segments
const arrows = [
{
d: `M ${pods[0].x + 80} ${pods[0].y + 40} L ${pods[1].x - 6} ${pods[1].y + 40}`,
end: { x: pods[1].x - 6, y: pods[1].y + 40 },
},
{
d: `M ${pods[1].x + 80} ${pods[1].y + 40} L ${pods[2].x - 6} ${pods[2].y + 40}`,
end: { x: pods[2].x - 6, y: pods[2].y + 40 },
},
{
d: `M ${pods[2].x + 80} ${pods[2].y + 40} L ${pods[3].x - 6} ${pods[3].y + 40}`,
end: { x: pods[3].x - 6, y: pods[3].y + 40 },
},
];
return (
<div
className={clsx("relative overflow-hidden", className)}
aria-hidden="true"
role="img"
aria-label="Pod-to-Pod signal transfer animation"
style={{ background: "transparent" }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
{/* GRID BG */}
<defs>
<pattern id="pods-grid" 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="pods-glow">
<feGaussianBlur stdDeviation="4" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect width={W} height={H} fill="url(#pods-grid)" />
{/* POD BOXES */}
{pods.map((p, i) => (
<motion.rect
key={i}
x={p.x}
y={p.y}
width={80}
height={80}
rx={14}
fill="#0d0d0d"
stroke="#1a1a1a"
strokeWidth={2}
initial={{ opacity: 0 }}
animate={{ opacity: 0.9 }}
transition={{ duration: 0.5 + i * 0.15 }}
/>
))}
{/* POD LABELS */}
{pods.map((p, i) => (
<motion.text
key={i}
x={p.x + 40}
y={p.y + 50}
textAnchor="middle"
fontSize="14"
fontFamily="Inter, sans-serif"
fill="#9ca3af"
initial={{ opacity: 0 }}
animate={{ opacity: 0.9 }}
transition={{ delay: 0.1 + i * 0.1, duration: 0.6 }}
>
{p.label}
</motion.text>
))}
{/* GREY LINES */}
{arrows.map((a, i) => (
<motion.path
key={`grey-${i}`}
d={a.d}
stroke="#333"
strokeWidth={4}
strokeLinecap="round"
fill="none"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 0.8 }}
transition={{ delay: 0.2 * i, duration: 0.7 }}
/>
))}
{/* CYAN LINES */}
{arrows.map((a, i) => (
<motion.path
key={`cyan-${i}`}
d={a.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.7 }}
/>
))}
{/* NEW: CYAN ENDPOINT PULSES */}
{arrows.map((a, i) => (
<motion.circle
key={`endpoint-${i}`}
cx={a.end.x}
cy={a.end.y}
r={10}
fill={accent}
opacity={0.12}
filter="url(#pods-glow)"
initial={{ scale: 0.8, opacity: 0 }}
animate={{
scale: [1, 1.2, 1],
opacity: [0.05, 0.25, 0.05],
}}
transition={{
duration: 1.5,
delay: i * 0.2,
repeat: Infinity,
repeatType: "mirror",
}}
/>
))}
{/* MAIN MOVING CYAN PULSE */}
<motion.circle
r={8}
fill={accent}
filter="url(#pods-glow)"
style={{
offsetPath: `path('${path.replace(/\s+/g, " ")}')`,
}}
initial={{ offsetDistance: "0%", opacity: 0.4 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0.4, 1, 0.4],
}}
transition={{
duration: 2.6,
repeat: Infinity,
ease: "linear",
}}
/>
</svg>
</div>
);
}

View File

@@ -15,6 +15,26 @@ export function CallToAction() {
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-full left-1/2 w-7xl h-320 -translate-x-1/2 -translate-y-1/2 mask-image mask-[radial-gradient(circle,white,transparent)]"
>
<circle
r={512}
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
<stop stopColor="#00e5ff" />
<stop offset="1" stopColor="transparent" />
</radialGradient>
</defs>
</svg>
<Container className="relative">
<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">