forked from emre/www_projectmycelium_com
Compare commits
16 Commits
d1fc11ce80
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
| 57c39a8b2b | |||
| 6ff539b3fc | |||
| 29e2d942de | |||
| def0972762 | |||
| 1c37cc08ee | |||
| 0eef2cd013 | |||
| 3cd41ab1d9 | |||
| 3121251272 | |||
| 56ceac1319 | |||
| a3028ff448 | |||
| 33821987aa | |||
| 678da4b66c | |||
| 326efc9fbd | |||
| 3a656ef5e9 | |||
| cf32cd081c | |||
| 1950342b7a |
BIN
public/images/Modern Metallic Home Symbol.png
Normal file
BIN
public/images/Modern Metallic Home Symbol.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/images/agent1.png
Normal file
BIN
public/images/agent1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 922 KiB |
BIN
public/images/cons.png
Normal file
BIN
public/images/cons.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 793 KiB |
BIN
public/images/dev.png
Normal file
BIN
public/images/dev.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 801 KiB |
BIN
public/images/pod1.png
Normal file
BIN
public/images/pod1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/images/seekers.png
Normal file
BIN
public/images/seekers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 990 KiB |
28
src/App.tsx
28
src/App.tsx
@@ -1,6 +1,6 @@
|
|||||||
import { HashRouter, Routes, Route } from 'react-router-dom';
|
import { HashRouter, Routes, Route, useLocation } from 'react-router-dom';
|
||||||
import { Layout } from './components/Layout';
|
import { Layout } from './components/Layout';
|
||||||
import { lazy, Suspense } from 'react';
|
import { lazy, Suspense, useEffect } from 'react';
|
||||||
|
|
||||||
const HomePage = lazy(() => import('./pages/home/HomePage'));
|
const HomePage = lazy(() => import('./pages/home/HomePage'));
|
||||||
const CloudPage = lazy(() => import('./pages/cloud/CloudPage'));
|
const CloudPage = lazy(() => import('./pages/cloud/CloudPage'));
|
||||||
@@ -11,11 +11,31 @@ const ComputePage = lazy(() => import('./pages/compute/ComputePage'));
|
|||||||
const StoragePage = lazy(() => import('./pages/storage/StoragePage'));
|
const StoragePage = lazy(() => import('./pages/storage/StoragePage'));
|
||||||
const GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
|
const GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
|
||||||
const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
|
const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
|
||||||
const NodePage = lazy(() => import('./pages/node/NodePage'));
|
const NodesPage = lazy(() => import('./pages/nodes/NodesPage'));
|
||||||
|
|
||||||
|
function ScrollToTop() {
|
||||||
|
const { pathname, hash } = useLocation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (hash) {
|
||||||
|
const id = hash.replace('#', '');
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
|
||||||
|
}, [pathname, hash]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
|
<ScrollToTop />
|
||||||
<Suspense fallback={<div>Loading...</div>}>
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Layout />}>
|
<Route path="/" element={<Layout />}>
|
||||||
@@ -28,7 +48,7 @@ function App() {
|
|||||||
<Route path="storage" element={<StoragePage />} />
|
<Route path="storage" element={<StoragePage />} />
|
||||||
<Route path="gpu" element={<GpuPage />} />
|
<Route path="gpu" element={<GpuPage />} />
|
||||||
<Route path="pods" element={<PodsPage />} />
|
<Route path="pods" element={<PodsPage />} />
|
||||||
<Route path="nodes" element={<NodePage />} />
|
<Route path="nodes" element={<NodesPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ export function Footer() {
|
|||||||
<Link to="/agents" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
<Link to="/agents" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
||||||
Agents
|
Agents
|
||||||
</Link>
|
</Link>
|
||||||
<Link to="/node" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
<Link to="/nodes" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
||||||
Node
|
Nodes
|
||||||
</Link>
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ export function Header() {
|
|||||||
Agents
|
Agents
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to="/node"
|
to="/nodes"
|
||||||
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
|
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
|
||||||
>
|
>
|
||||||
Node
|
Nodes
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,11 +131,11 @@ export function Header() {
|
|||||||
Agents
|
Agents
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to="/node"
|
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"
|
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)}
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
Node
|
Nodes
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="py-6">
|
<div className="py-6">
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ export function HeaderDark() {
|
|||||||
Agents
|
Agents
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to="/node"
|
to="/nodes"
|
||||||
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
|
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
|
||||||
>
|
>
|
||||||
Node
|
Nodes
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,11 +131,11 @@ export function HeaderDark() {
|
|||||||
Agents
|
Agents
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to="/node"
|
to="/nodes"
|
||||||
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
|
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)}
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
Node
|
Nodes
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="py-6">
|
<div className="py-6">
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
export const InfiniteMovingCards = ({
|
export const InfiniteMovingCards = ({
|
||||||
items,
|
items,
|
||||||
direction = "left",
|
direction = "left",
|
||||||
speed = "fast",
|
speed = "slow",
|
||||||
pauseOnHover = true,
|
pauseOnHover = true,
|
||||||
className,
|
className,
|
||||||
}: {
|
}: {
|
||||||
@@ -15,43 +15,39 @@ export const InfiniteMovingCards = ({
|
|||||||
speed?: "fast" | "normal" | "slow";
|
speed?: "fast" | "normal" | "slow";
|
||||||
pauseOnHover?: boolean;
|
pauseOnHover?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
}): JSX.Element => {
|
}) => {
|
||||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const scrollerRef = React.useRef<HTMLUListElement>(null);
|
const scrollerRef = useRef<HTMLUListElement>(null);
|
||||||
const [start, setStart] = useState(false);
|
const [isReady, setIsReady] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const getSpeed = useCallback(() => {
|
|
||||||
if (containerRef.current) {
|
|
||||||
if (speed === "fast") {
|
|
||||||
containerRef.current.style.setProperty("--animation-duration", "20s");
|
|
||||||
} else if (speed === "normal") {
|
|
||||||
containerRef.current.style.setProperty("--animation-duration", "40s");
|
|
||||||
} else {
|
|
||||||
containerRef.current.style.setProperty("--animation-duration", "80s");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [speed]);
|
|
||||||
|
|
||||||
const addAnimation = useCallback(() => {
|
|
||||||
if (containerRef.current && scrollerRef.current) {
|
|
||||||
const scrollerContent = Array.from(scrollerRef.current.children);
|
|
||||||
|
|
||||||
scrollerContent.forEach((item) => {
|
|
||||||
const duplicatedItem = item.cloneNode(true);
|
|
||||||
if (scrollerRef.current) {
|
|
||||||
scrollerRef.current.appendChild(duplicatedItem);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
getSpeed();
|
|
||||||
setStart(true);
|
|
||||||
}
|
|
||||||
}, [getSpeed]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
addAnimation();
|
if (!scrollerRef.current) return;
|
||||||
}, [addAnimation]);
|
|
||||||
|
const children = Array.from(scrollerRef.current.children);
|
||||||
|
|
||||||
|
// duplicate each item ONCE
|
||||||
|
children.forEach((item) => {
|
||||||
|
const clone = item.cloneNode(true);
|
||||||
|
scrollerRef.current!.appendChild(clone);
|
||||||
|
});
|
||||||
|
|
||||||
|
// set speed variable
|
||||||
|
const duration =
|
||||||
|
speed === "fast" ? "20s" : speed === "normal" ? "40s" : "80s";
|
||||||
|
|
||||||
|
containerRef.current?.style.setProperty(
|
||||||
|
"--animation-duration",
|
||||||
|
duration
|
||||||
|
);
|
||||||
|
|
||||||
|
// set direction variable
|
||||||
|
containerRef.current?.style.setProperty(
|
||||||
|
"--animation-direction",
|
||||||
|
direction === "left" ? "forwards" : "reverse"
|
||||||
|
);
|
||||||
|
|
||||||
|
setIsReady(true);
|
||||||
|
}, [direction, speed]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -61,16 +57,13 @@ export const InfiniteMovingCards = ({
|
|||||||
<ul
|
<ul
|
||||||
ref={scrollerRef}
|
ref={scrollerRef}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex min-w-full shrink-0 gap-16 py-4 w-max flex-nowrap",
|
"flex w-max shrink-0 gap-16 py-4",
|
||||||
start && "animate-scroll",
|
isReady && "animate-infinite-scroll",
|
||||||
pauseOnHover && "hover:[animation-play-state:paused]",
|
pauseOnHover && "hover:[animation-play-state:paused]"
|
||||||
)}
|
)}
|
||||||
style={{
|
|
||||||
"--animation-direction": direction === "left" ? "forwards" : "reverse",
|
|
||||||
} as React.CSSProperties}
|
|
||||||
>
|
>
|
||||||
{items.map((item, idx) => (
|
{items.map((item, i) => (
|
||||||
<li className="relative flex-shrink-0" key={idx}>
|
<li key={i} className="flex-shrink-0">
|
||||||
{item}
|
{item}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const bentos: {
|
|||||||
{
|
{
|
||||||
id: "core",
|
id: "core",
|
||||||
eyebrow: "ARCHITECTURE",
|
eyebrow: "ARCHITECTURE",
|
||||||
title: "Augmented Intelligence Fabric",
|
title: "Intelligence Fabric",
|
||||||
description:
|
description:
|
||||||
"The sovereign substrate for autonomous AI. Stateless, geo-aware, end-to-end encrypted—and verifiable from intent to execution.",
|
"The sovereign substrate for autonomous AI. Stateless, geo-aware, end-to-end encrypted—and verifiable from intent to execution.",
|
||||||
animation: null,
|
animation: null,
|
||||||
@@ -119,8 +119,8 @@ export function AgentBento() {
|
|||||||
className={`relative flex lg:h-90 flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] `}
|
className={`relative flex lg:h-90 flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] `}
|
||||||
>
|
>
|
||||||
{card.animation ? (
|
{card.animation ? (
|
||||||
<div className="lg:h-64 h-48 w-full overflow-hidden bg-transparent flex items-center">
|
<div className="lg:h-64 h-48 w-full overflow-hidden bg-transparent flex items-center justify-center">
|
||||||
<card.animation />
|
<div className="w-full h-full object-cover"><card.animation /></div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="h-48 w-full flex items-center justify-center bg-transparent" />
|
<div className="h-48 w-full flex items-center justify-center bg-transparent" />
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ export function AgentDesign() {
|
|||||||
{benefits.map((item) => (
|
{benefits.map((item) => (
|
||||||
<div
|
<div
|
||||||
key={item.id}
|
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"
|
className="flex flex-col items-center bg-white py-10 px-4 border border-gray-100 lg:border-t-0 lg:border-b-0"
|
||||||
>
|
>
|
||||||
<item.icon className="h-10 w-10 text-cyan-500 mb-4" />
|
<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">
|
<h3 className="text-base font-medium text-black max-w-xs">
|
||||||
{item.title}
|
{item.title}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export function AgentHeroAlt() {
|
|||||||
style={{ backgroundImage: "url('/images/agents.webp')", backgroundSize: "contain" }}
|
style={{ backgroundImage: "url('/images/agents.webp')", backgroundSize: "contain" }}
|
||||||
>
|
>
|
||||||
{/* Inner padding */}
|
{/* Inner padding */}
|
||||||
<div className="px-6 py-16 lg:py-16">
|
<div className="px-6 py-16 lg:py-24">
|
||||||
<div className="max-w-2xl lg:pl-6">
|
<div className="max-w-2xl lg:pl-6">
|
||||||
<Eyebrow>MYCELIUM AGENTS - COMING IN 2026</Eyebrow>
|
<Eyebrow>MYCELIUM AGENTS - COMING IN 2026</Eyebrow>
|
||||||
<H3 as="h1" className="mt-4">
|
<H3 as="h1" className="mt-4">
|
||||||
|
|||||||
90
src/pages/agents/AgentPro.tsx
Normal file
90
src/pages/agents/AgentPro.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import { Small } from "@/components/Texts";
|
||||||
|
import { Eyebrow, H3, P } from "@/components/Texts";
|
||||||
|
|
||||||
|
const highlights = [
|
||||||
|
{
|
||||||
|
label: "Local Execution",
|
||||||
|
title: "Agents run entirely inside your environment.",
|
||||||
|
description:
|
||||||
|
"Models, logic, and memory stay within your own trusted hardware—never behind third-party APIs.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Mesh Connectivity",
|
||||||
|
title: "They communicate peer-to-peer across trusted nodes.",
|
||||||
|
description:
|
||||||
|
"Agents form direct encrypted paths between environments, without relays or central servers.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Private Data Access",
|
||||||
|
title: "They use your data without sending it elsewhere.",
|
||||||
|
description:
|
||||||
|
"Your datasets, embeddings, and context never leave your boundaries—processing stays local.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Portability",
|
||||||
|
title: "They move with you, not with a cloud provider.",
|
||||||
|
description:
|
||||||
|
"Agents follow your devices, networks, and workflows, remaining sovereign across every location.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function AgentPro() {
|
||||||
|
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" />
|
||||||
|
|
||||||
|
{/* Intro Block */}
|
||||||
|
<div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
|
||||||
|
<div className="px-8 py-12 max-w-4xl mx-auto flex flex-col items-center justify-center min-h-[220px] text-center">
|
||||||
|
<Eyebrow className="uppercase tracking-[0.16em] text-cyan-600">
|
||||||
|
Advantages
|
||||||
|
</Eyebrow>
|
||||||
|
|
||||||
|
<H3 className="mt-4 text-black">
|
||||||
|
Why It’s Different
|
||||||
|
</H3>
|
||||||
|
|
||||||
|
<P className="mt-4 text-gray-700 text-base leading-relaxed">
|
||||||
|
Most AI systems run on centralized clouds, where the models, data, and
|
||||||
|
logic operate behind third-party APIs. Mycelium Agents flip that
|
||||||
|
architecture, it runs entirely inside your environment so control,
|
||||||
|
privacy, and autonomy stay with you.
|
||||||
|
</P>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Grid */}
|
||||||
|
<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"
|
||||||
|
>
|
||||||
|
{/* 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>
|
||||||
|
|
||||||
|
{/* Bottom spacing */}
|
||||||
|
<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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useRef } from "react";
|
|
||||||
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
|
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
|
||||||
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CpuChipIcon,
|
CpuChipIcon,
|
||||||
GlobeAltIcon,
|
GlobeAltIcon,
|
||||||
@@ -23,7 +20,7 @@ const networkUseCases = [
|
|||||||
{
|
{
|
||||||
title: "Run agents on your own hardware",
|
title: "Run agents on your own hardware",
|
||||||
description:
|
description:
|
||||||
"Deploy AI processes on laptops, homelabs, edge nodes, or full clusters — no cloud dependency.",
|
"Deploy AI processes on laptops, homelabs, edge nodes, or full clusters with no cloud dependency.",
|
||||||
icon: CpuChipIcon,
|
icon: CpuChipIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -50,98 +47,75 @@ const networkUseCases = [
|
|||||||
"Run agents in sectors requiring strict data residency, verified identity, and controlled connectivity.",
|
"Run agents in sectors requiring strict data residency, verified identity, and controlled connectivity.",
|
||||||
icon: ShieldCheckIcon,
|
icon: ShieldCheckIcon,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Blend local + remote intelligence",
|
||||||
|
description:
|
||||||
|
"Let lightweight agents run locally while offloading heavy tasks to trusted nodes, maintaining privacy and performance balance.",
|
||||||
|
icon: CpuChipIcon,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function AgentUsecase() {
|
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 (
|
return (
|
||||||
<section className="w-full max-w-8xl mx-auto bg-transparent">
|
<section className="w-full max-w-8xl mx-auto bg-transparent">
|
||||||
|
{/* Top horizontal spacing line */}
|
||||||
{/* ✅ Top horizontal line with spacing */}
|
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
|
||||||
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
|
|
||||||
<div className="w-full border-t border-l border-r border-gray-100" />
|
<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">
|
{/* Main framed section */}
|
||||||
<ul
|
<div className="border border-t-0 border-b-0 border-gray-100 bg-white">
|
||||||
ref={sliderRef}
|
<div className="mx-auto max-w-4xl sm:text-center py-12">
|
||||||
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
|
{/* Intro block (from isIntro item) */}
|
||||||
>
|
{networkUseCases[0].isIntro && (
|
||||||
{networkUseCases.map((item, idx) => (
|
<>
|
||||||
<li
|
<Eyebrow className="text-cyan-600">{networkUseCases[0].eyebrow}</Eyebrow>
|
||||||
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
|
<SectionHeader
|
||||||
as="h3"
|
as="h3"
|
||||||
className="mt-4 text-gray-900 text-xl lg:text-2xl"
|
className="mt-4 text-gray-900 text-3xl lg:text-4xl"
|
||||||
>
|
>
|
||||||
{item.title}
|
{networkUseCases[0].title}
|
||||||
</SectionHeader>
|
</SectionHeader>
|
||||||
<P className="mt-4 text-gray-600 text-sm lg:text-base">
|
<P className="mt-6 text-lg text-gray-600">
|
||||||
{item.description}
|
{networkUseCases[0].description}
|
||||||
</P>
|
</P>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* slider buttons */}
|
{/* Grid of features (excluding intro) */}
|
||||||
<div className="flex items-center gap-x-4 mt-6">
|
<ul
|
||||||
<button
|
role="list"
|
||||||
onClick={scrollLeft}
|
className="mx-auto mt-6 max-w-6xl grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-y-10 px-6 pb-16"
|
||||||
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} />
|
{networkUseCases.slice(1).map((item, idx) => (
|
||||||
</button>
|
<li
|
||||||
|
key={idx}
|
||||||
<button
|
className="rounded-2xl border border-gray-200 p-8 transition-all duration-300 ease-in-out hover:scale-[1.03] hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 bg-white"
|
||||||
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} />
|
{/* Icon */}
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
/* REGULAR CARD */
|
|
||||||
<div className="flex flex-col h-full">
|
|
||||||
{item.icon && (
|
{item.icon && (
|
||||||
<div className="h-12 w-12 flex items-center justify-center rounded-xl bg-gray-100 mb-6">
|
<div className="h-10 w-10 flex items-center justify-center rounded-xl bg-gray-100">
|
||||||
<item.icon className="h-6 w-6 text-cyan-600" />
|
<item.icon className="h-6 w-6 text-cyan-600" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<p className="text-lg font-semibold text-gray-900">
|
{/* Title */}
|
||||||
|
<p className="mt-6 text-lg font-semibold text-gray-900">
|
||||||
{item.title}
|
{item.title}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="mt-2 text-gray-600 leading-snug">
|
{/* Description */}
|
||||||
|
<p className="mt-2 text-gray-600 text-sm leading-snug">
|
||||||
{item.description}
|
{item.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* ✅ Bottom horizontal line with spacing */}
|
|
||||||
|
{/* Bottom horizontal line */}
|
||||||
<div className="w-full border-b border-gray-100" />
|
<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 className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import { AgentBento } from './AgentBento'
|
|||||||
import { AgentHeroAlt } from './AgentHeroAlt'
|
import { AgentHeroAlt } from './AgentHeroAlt'
|
||||||
import { CallToAction } from './CallToAction'
|
import { CallToAction } from './CallToAction'
|
||||||
import { AgentUsecase } from './AgentUseCase'
|
import { AgentUsecase } from './AgentUseCase'
|
||||||
import { AgentDesign } from './AgentDesign'
|
|
||||||
|
import { AgentPro } from './AgentPro'
|
||||||
|
|
||||||
export default function AgentsPage() {
|
export default function AgentsPage() {
|
||||||
return (
|
return (
|
||||||
@@ -31,7 +32,7 @@ export default function AgentsPage() {
|
|||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
<AgentDesign />
|
<AgentPro />
|
||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
|
|||||||
@@ -15,6 +15,26 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export default function FungiStor({
|
|||||||
className={clsx("relative overflow-hidden", className)}
|
className={clsx("relative overflow-hidden", className)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
role="img"
|
||||||
aria-label="FungiStor — distributed long-term AI memory"
|
aria-label="FungiStor, a distributed long-term AI memory"
|
||||||
style={{ background: bg }}
|
style={{ background: bg }}
|
||||||
>
|
>
|
||||||
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
|
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ export default function Herodb({
|
|||||||
className={clsx("relative overflow-hidden", className)}
|
className={clsx("relative overflow-hidden", className)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
role="img"
|
||||||
aria-label="HeroDB — active AI memory retrieval"
|
aria-label="HeroDB, active AI memory retrieval"
|
||||||
style={{ background: bg }}
|
style={{ background: bg }}
|
||||||
>
|
>
|
||||||
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
|
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ export default function MyceliumMesh({
|
|||||||
)}
|
)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
role="img"
|
||||||
aria-label="Mycelium Mesh — secure communication network"
|
aria-label="Mycelium Mesh, a secure communication network"
|
||||||
style={{ background: bg }}
|
style={{ background: bg }}
|
||||||
>
|
>
|
||||||
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
|
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
|
||||||
|
|||||||
@@ -15,6 +15,26 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function CloudBluePrint() {
|
|||||||
</H3>
|
</H3>
|
||||||
|
|
||||||
<P className="mt-6 text-lg text-gray-600">
|
<P className="mt-6 text-lg text-gray-600">
|
||||||
Digital Me is an example environment built to demonstrate what’s possible on top of the Mycelium Stack — a full personal cloud you can deploy, customize, or extend. Your files, communication, apps, and optional AI agent, all running privately on infrastructure you choose.
|
Digital Me is an example environment built to demonstrate what’s possible on top of the Mycelium Stack, which is a full personal cloud you can deploy, customize, or extend. Your files, communication, apps, and optional AI agent, all running privately on infrastructure you choose.
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
112
src/pages/cloud/CloudCodeTabs.tsx
Normal file
112
src/pages/cloud/CloudCodeTabs.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -257,7 +257,7 @@ export function CloudFeaturesLight() {
|
|||||||
</SectionHeader>
|
</SectionHeader>
|
||||||
<P className="mt-6 text-gray-600">
|
<P className="mt-6 text-gray-600">
|
||||||
Mycelium Cloud runs Kubernetes on a sovereign, self-healing network
|
Mycelium Cloud runs Kubernetes on a sovereign, self-healing network
|
||||||
with compute, storage, and networking built in — so you don’t need
|
with compute, storage, and networking built in, so you don’t need
|
||||||
external cloud dependencies.
|
external cloud dependencies.
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,19 +13,17 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
|
|||||||
<div className="px-6 py-16 lg:py-16">
|
<div className="px-6 py-16 lg:py-16">
|
||||||
<div className="max-w-2xl lg:pl-6">
|
<div className="max-w-2xl lg:pl-6">
|
||||||
<Eyebrow>
|
<Eyebrow>
|
||||||
Mycelium Cloud
|
MYCELIUM CLOUD
|
||||||
</Eyebrow>
|
</Eyebrow>
|
||||||
<H3 className="mt-4">
|
<H3 className="mt-4">
|
||||||
Run Kubernetes on the Sovereign Agentic Cloud
|
Sovereign Edge Cloud Infrastructure
|
||||||
</H3>
|
</H3>
|
||||||
<p className="mt-6 text-lg">
|
<p className="mt-6 text-lg text-gray-600">
|
||||||
Deploy K3s clusters on a global, self-healing mesh network.
|
Run compute, storage, and AI resources on infrastructure you control.
|
||||||
Your workloads run on sovereign, encrypted infrastructure, without centralized cloud control.
|
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-4 lg:text-base italic text-gray-600 text-sm">
|
<p className="mt-4 text-lg text-gray-600">
|
||||||
Works Alone. Works Together.
|
The Mycelium Cloud runs on a distributed grid of independent nodes,
|
||||||
Mycelium Cloud can run on any network fabric, or pair with Mycelium Network
|
delivering secure, scalable performance wherever your users or data live.
|
||||||
for sovereign connectivity.
|
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-10 flex items-center gap-x-6">
|
<div className="mt-10 flex items-center gap-x-6">
|
||||||
<Button
|
<Button
|
||||||
@@ -33,10 +31,10 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
|
|||||||
variant="solid"
|
variant="solid"
|
||||||
color="cyan"
|
color="cyan"
|
||||||
>
|
>
|
||||||
Get started
|
Deploy Workloads
|
||||||
</Button>
|
</Button>
|
||||||
<Button to="#" variant="outline">
|
<Button to="#" variant="outline">
|
||||||
Documentation <span aria-hidden="true">→</span>
|
Explore Docs <span aria-hidden="true">→</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { Eyebrow, H3, H4 } from "@/components/Texts"
|
|||||||
const product = {
|
const product = {
|
||||||
subtitle: 'capabilities',
|
subtitle: 'capabilities',
|
||||||
name: 'What You Can Run on Mycelium Cloud',
|
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: [
|
details: [
|
||||||
{
|
{
|
||||||
name: 'Kubernetes Clusters',
|
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 */}
|
{/* ✅ Details accordion */}
|
||||||
|
|||||||
194
src/pages/cloud/CloudIntro.tsx
Normal file
194
src/pages/cloud/CloudIntro.tsx
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Eyebrow, H3, P } from "@/components/Texts";
|
||||||
|
import { Button } from "@/components/Button";
|
||||||
|
|
||||||
|
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",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const tabButtons = {
|
||||||
|
kubernetes: {
|
||||||
|
primary: "Deploy a Cluster",
|
||||||
|
secondary: "Learn More",
|
||||||
|
},
|
||||||
|
vdc: {
|
||||||
|
primary: "Follow Development",
|
||||||
|
secondary: "Learn More",
|
||||||
|
},
|
||||||
|
qsfs: {
|
||||||
|
primary: "View Docs",
|
||||||
|
secondary: "Explore Integration",
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export function CloudIntro() {
|
||||||
|
const [active, setActive] = useState("kubernetes");
|
||||||
|
const current = tabs.find((t) => t.id === active)!.content;
|
||||||
|
const currentButtons = tabButtons[active as keyof typeof tabButtons];
|
||||||
|
|
||||||
|
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">
|
||||||
|
<img
|
||||||
|
src="/images/cloud/reserve.png"
|
||||||
|
alt="Mycelium Cloud reserve"
|
||||||
|
className="w-full h-auto rounded-xl border border-white/10 object-cover"
|
||||||
|
/>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
{currentButtons && (
|
||||||
|
<div className="mt-8 flex flex-wrap gap-4">
|
||||||
|
<Button
|
||||||
|
to="#"
|
||||||
|
variant="solid"
|
||||||
|
color="cyan"
|
||||||
|
>
|
||||||
|
{currentButtons.primary}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
to="#"
|
||||||
|
variant="outline"
|
||||||
|
color="white"
|
||||||
|
>
|
||||||
|
{currentButtons.secondary}
|
||||||
|
</Button>
|
||||||
|
</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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
import { AnimatedSection } from '../../components/AnimatedSection'
|
import { AnimatedSection } from '../../components/AnimatedSection'
|
||||||
import { CloudArchitecture } from './CloudArchitecture'
|
|
||||||
import { CloudUseCases } from './CloudUseCases'
|
|
||||||
import { CloudHeroNew } from './CloudHeroNew'
|
import { CloudHeroNew } from './CloudHeroNew'
|
||||||
import { CloudBluePrint } from './CloudBluePrint'
|
|
||||||
import { CallToAction } from './CalltoAction'
|
import { CallToAction } from './CalltoAction'
|
||||||
import { CloudHostingNew } from './CloudHostingNew'
|
import { CloudIntro } from './CloudIntro'
|
||||||
import { CloudFeaturesLight } from './CloudFeaturesLight'
|
import { CloudPros } from './CloudPros'
|
||||||
|
|
||||||
|
|
||||||
export default function CloudPage() {
|
export default function CloudPage() {
|
||||||
@@ -17,23 +14,11 @@ export default function CloudPage() {
|
|||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
<CloudHostingNew />
|
<CloudIntro />
|
||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
<CloudFeaturesLight />
|
<CloudPros />
|
||||||
</AnimatedSection>
|
|
||||||
|
|
||||||
<AnimatedSection>
|
|
||||||
<CloudArchitecture />
|
|
||||||
</AnimatedSection>
|
|
||||||
|
|
||||||
<AnimatedSection>
|
|
||||||
<CloudUseCases />
|
|
||||||
</AnimatedSection>
|
|
||||||
|
|
||||||
<AnimatedSection>
|
|
||||||
<CloudBluePrint />
|
|
||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
|
|||||||
89
src/pages/cloud/CloudPros.tsx
Normal file
89
src/pages/cloud/CloudPros.tsx
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { Small } from "@/components/Texts";
|
||||||
|
|
||||||
|
const highlights = [
|
||||||
|
{
|
||||||
|
label: "Local Execution",
|
||||||
|
title: "Agents run entirely inside your environment.",
|
||||||
|
description:
|
||||||
|
"Models, logic, and memory stay within your own trusted hardware—never behind third-party APIs.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Mesh Connectivity",
|
||||||
|
title: "They communicate peer-to-peer across trusted nodes.",
|
||||||
|
description:
|
||||||
|
"Agents form direct encrypted paths between environments, without relays or central servers.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Private Data Access",
|
||||||
|
title: "They use your data without sending it elsewhere.",
|
||||||
|
description:
|
||||||
|
"Your datasets, embeddings, and context never leave your boundaries—processing stays local.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Portability",
|
||||||
|
title: "They move with you, not with a cloud provider.",
|
||||||
|
description:
|
||||||
|
"Agents follow your devices, networks, and workflows, remaining sovereign across every location.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function AgentPro() {
|
||||||
|
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" />
|
||||||
|
|
||||||
|
{/* Intro Block */}
|
||||||
|
<div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
|
||||||
|
<div className="px-8 py-12 max-w-3xl">
|
||||||
|
<Small className="uppercase tracking-[0.16em] text-cyan-600">
|
||||||
|
Agent Advantage
|
||||||
|
</Small>
|
||||||
|
|
||||||
|
<h3 className="mt-4 text-2xl lg:text-3xl font-semibold text-black">
|
||||||
|
Why It’s Different
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p className="mt-4 text-gray-700 text-base leading-relaxed">
|
||||||
|
Most AI systems run on centralized clouds, where the models, data, and
|
||||||
|
logic operate behind third-party APIs. Mycelium Agents flip that
|
||||||
|
architecture—running entirely inside your environment so control,
|
||||||
|
privacy, and autonomy stay with you.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Grid */}
|
||||||
|
<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"
|
||||||
|
>
|
||||||
|
{/* 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>
|
||||||
|
|
||||||
|
{/* Bottom spacing */}
|
||||||
|
<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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -15,6 +15,26 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export function ComputeFeatures() {
|
|||||||
</P>
|
</P>
|
||||||
|
|
||||||
<P className="mt-3 text-lg text-gray-600">
|
<P className="mt-3 text-lg text-gray-600">
|
||||||
Each component — from message passing to content distribution — works in harmony
|
Each component, from message passing to content distribution — works in harmony
|
||||||
to create a fully self-healing, self-optimizing data mesh.
|
to create a fully self-healing, self-optimizing data mesh.
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ const tabs = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
item: "Zero cloud lock-in",
|
item: "Zero cloud lock-in",
|
||||||
desc: "Deploy containers, VMs, or full Kubernetes clusters — migrate off AWS/GCP/Azure with no code changes.",
|
desc: "Deploy containers, VMs, or full Kubernetes clusters, migrate off AWS/GCP/Azure with no code changes.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
item: "Encrypted networking",
|
item: "Encrypted networking",
|
||||||
desc: "All services communicate through Mycelium Mesh — no VPNs, no exposed ports.",
|
desc: "All services communicate through Mycelium Mesh without VPNs, no exposed ports.",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -48,11 +48,11 @@ const tabs = [
|
|||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
item: "Distributed workloads",
|
item: "Distributed workloads",
|
||||||
desc: "Run compute where data lives — homes, factories, hospitals, or remote regions.",
|
desc: "Run compute where data lives; homes, factories, hospitals, or remote regions.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
item: "Offline-first resilience",
|
item: "Offline-first resilience",
|
||||||
desc: "Nodes keep working even with weak internet or outages — ideal for mission-critical edge.",
|
desc: "Nodes keep working even with weak internet or outages, ideal for mission-critical edge.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
item: "Global deployment, local data",
|
item: "Global deployment, local data",
|
||||||
@@ -85,7 +85,7 @@ export function ComputeUseCases() {
|
|||||||
<P className="max-w-3xl text-gray-400 mt-6">
|
<P className="max-w-3xl text-gray-400 mt-6">
|
||||||
Mycelium Compute is a decentralized physical infrastructure network
|
Mycelium Compute is a decentralized physical infrastructure network
|
||||||
(DePIN) for high-performance workloads. Run reproducible AI/ML
|
(DePIN) for high-performance workloads. Run reproducible AI/ML
|
||||||
pipelines, host self-healing applications, or deploy to the edge — all
|
pipelines, host self-healing applications, or deploy to the edge, all
|
||||||
on a fabric that’s more resilient and private than the cloud.
|
on a fabric that’s more resilient and private than the cloud.
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,6 +15,26 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export function GpuArchitecture() {
|
|||||||
Sovereign Compute Nodes
|
Sovereign Compute Nodes
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-600 max-w-2xl">
|
<p className="mt-2 text-gray-600 max-w-2xl">
|
||||||
GPUs run only on hardware you control — eliminating reliance on centralized clouds.
|
GPUs run only on hardware you control, eliminating reliance on centralized clouds.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
||||||
</div>
|
</div>
|
||||||
@@ -52,7 +52,7 @@ export function GpuArchitecture() {
|
|||||||
Encrypted Mesh Networking
|
Encrypted Mesh Networking
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-600 max-w-2xl">
|
<p className="mt-2 text-gray-600 max-w-2xl">
|
||||||
Nodes form private, encrypted tunnels to workloads — no public exposure required.
|
Nodes form private, encrypted tunnels to workloads, no public exposure required.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const gpuCapabilities = [
|
|||||||
eyebrow: "CAPABILITIES",
|
eyebrow: "CAPABILITIES",
|
||||||
title: "What You Can Run on Mycelium Cloud",
|
title: "What You Can Run on Mycelium Cloud",
|
||||||
description:
|
description:
|
||||||
"GPU acceleration for inference, training, rendering, and agent workloads — on sovereign hardware.",
|
"GPU acceleration for inference, training, rendering, and agent workload on sovereign hardware.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "AI / ML Inference & Training",
|
name: "AI / ML Inference & Training",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Link } from 'react-router-dom';
|
||||||
import { Container } from '@/components/Container'
|
import { Container } from '@/components/Container'
|
||||||
import { Button } from '@/components/Button'
|
import { Button } from '@/components/Button'
|
||||||
import { H3, P } from '@/components/Texts'
|
import { H3, P } from '@/components/Texts'
|
||||||
@@ -63,9 +64,9 @@ export function CallToAction() {
|
|||||||
Deploy in Cloud
|
Deploy in Cloud
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<a href="/node" className="text-cyan-400 hover:text-cyan-300 transition-colors">
|
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
|
||||||
Host a Node →
|
Host a Node →
|
||||||
</a>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Eyebrow, H3, P } from "@/components/Texts";
|
|||||||
import NoExtraction from "./animations/NoExtraction";
|
import NoExtraction from "./animations/NoExtraction";
|
||||||
import NoControl from "./animations/NoControl";
|
import NoControl from "./animations/NoControl";
|
||||||
import NoCentral from "./animations/NoCentral";
|
import NoCentral from "./animations/NoCentral";
|
||||||
|
import NoSinglePoint from "./animations/NoSinglePoint";
|
||||||
|
|
||||||
const deterministicCards = [
|
const deterministicCards = [
|
||||||
{
|
{
|
||||||
@@ -45,7 +46,7 @@ const deterministicCards = [
|
|||||||
title: "No single point of failure.",
|
title: "No single point of failure.",
|
||||||
description:
|
description:
|
||||||
"No single entity can dictate or censor your online experience.",
|
"No single entity can dictate or censor your online experience.",
|
||||||
animation: <NoControl />, // ✅ NEW
|
animation: <NoSinglePoint />, // ✅ NEW
|
||||||
colSpan: "lg:col-span-2",
|
colSpan: "lg:col-span-2",
|
||||||
rowSpan: "lg:row-span-1",
|
rowSpan: "lg:row-span-1",
|
||||||
rounded: "",
|
rounded: "",
|
||||||
@@ -76,7 +77,7 @@ export function HomeArchitecture() {
|
|||||||
{deterministicCards.map((card) => (
|
{deterministicCards.map((card) => (
|
||||||
<div
|
<div
|
||||||
key={card.id}
|
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 */}
|
{/* ✅ Disable wrapper on first card */}
|
||||||
{!card.noBorder && (
|
{!card.noBorder && (
|
||||||
@@ -90,8 +91,8 @@ export function HomeArchitecture() {
|
|||||||
>
|
>
|
||||||
{/* ✅ SVG Animation instead of images */}
|
{/* ✅ SVG Animation instead of images */}
|
||||||
{card.animation ? (
|
{card.animation ? (
|
||||||
<div className="lg:h-64 h-48 w-full overflow-hidden bg-transparent flex items-center">
|
<div className="lg:h-64 h-48 w-full overflow-hidden bg-transparent flex items-center justify-center">
|
||||||
<div className="w-full h-full">
|
<div className="w-full h-full object-cover">
|
||||||
{card.animation}
|
{card.animation}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { H1, H4, H5 } from "@/components/Texts"
|
import { H1, H4, H3, H5, Eyebrow } from "@/components/Texts"
|
||||||
import { Button } from "@/components/Button"
|
import { Button } from "@/components/Button"
|
||||||
|
import { H3Icon } from "@heroicons/react/20/solid"
|
||||||
|
|
||||||
export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => void }) {
|
export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => void }) {
|
||||||
return (
|
return (
|
||||||
@@ -12,33 +13,17 @@ export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => voi
|
|||||||
{/* Inner padding */}
|
{/* Inner padding */}
|
||||||
<div className="px-6 py-16 lg:py-32 ">
|
<div className="px-6 py-16 lg:py-32 ">
|
||||||
<div className="max-w-2xl lg:pl-6">
|
<div className="max-w-2xl lg:pl-6">
|
||||||
<div className="hidden sm:flex">
|
<Eyebrow> Project MYCELIUM</Eyebrow>
|
||||||
<div className="relative rounded-full px-3 py-1 text-sm/6 text-gray-500 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
|
<H3 className="mt-4">
|
||||||
Deploying at scale?{' '}
|
Private, Distributed Infrastructure Built
|
||||||
<a href="#" className="font-semibold whitespace-nowrap text-cyan-600">
|
for Digital Sovereignty
|
||||||
<span aria-hidden="true" className="absolute inset-0" />
|
</H3>
|
||||||
Book a call <span>→</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<H1 className="mt-8">
|
|
||||||
MYCELIUM
|
|
||||||
</H1>
|
|
||||||
|
|
||||||
<H4 className="mt-8">
|
|
||||||
Private, distributed infrastructure built
|
|
||||||
for digital sovereignty
|
|
||||||
|
|
||||||
|
|
||||||
</H4>
|
|
||||||
|
|
||||||
<H5 className="mt-8 text-lg text-gray-600">
|
|
||||||
|
|
||||||
|
<H5 className="mt-4 text-lg text-gray-600 max-w-xl">
|
||||||
Run your apps, data, and intelligence on infrastructure that belongs to you
|
Run your apps, data, and intelligence on infrastructure that belongs to you
|
||||||
</H5>
|
</H5>
|
||||||
|
|
||||||
<div className="mt-10 flex items-center gap-x-6">
|
<div className="mt-8 flex items-center gap-x-6">
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="cyan"
|
color="cyan"
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ export function HomeBlink({ onGetStartedClick }: { onGetStartedClick: () => void
|
|||||||
<H4 className="text-center mt-8">The Living Network of the Next Internet</H4>
|
<H4 className="text-center mt-8">The Living Network of the Next Internet</H4>
|
||||||
|
|
||||||
<H5 className="mx-auto mt-6 max-w-4xl text-center font-normal text-neutral-500">
|
<H5 className="mx-auto mt-6 max-w-4xl text-center font-normal text-neutral-500">
|
||||||
A new internet is emerging — private, distributed, and self-sovereign.
|
A new internet is emerging, a private, distributed, and self-sovereign.
|
||||||
Mycelium is the living network that makes it possible.
|
Mycelium is the living network that makes it possible.
|
||||||
A peer-to-peer foundation where people, data, and intelligence connect
|
A peer-to-peer foundation where people, data, and intelligence connect
|
||||||
directly — without intermediaries, without compromise.
|
directly without intermediaries, without compromise.
|
||||||
</H5>
|
</H5>
|
||||||
|
|
||||||
<div className="mt-8 flex justify-center gap-6">
|
<div className="mt-8 flex justify-center gap-6">
|
||||||
|
|||||||
69
src/pages/home/HomeDesign.tsx
Normal file
69
src/pages/home/HomeDesign.tsx
Normal 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">
|
||||||
|
|
||||||
|
{/* Top spacing line */}
|
||||||
|
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
|
||||||
|
<div className="w-full border border-l border-r border-gray-200" />
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<div className="mx-auto max-w-7xl border-gray-200">
|
||||||
|
<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 px-8 py-12 border border-gray-200 0 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 mb-2">
|
||||||
|
{item.title}
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-gray-600 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,9 +4,9 @@ import { AnimatedSection } from '../../components/AnimatedSection'
|
|||||||
import { CallToAction } from './CallToAction'
|
import { CallToAction } from './CallToAction'
|
||||||
import { HomeTab } from './HomeTab'
|
import { HomeTab } from './HomeTab'
|
||||||
import { HomeMap } from './HomeMap'
|
import { HomeMap } from './HomeMap'
|
||||||
import { HomeAudience } from './HomeAudience'
|
|
||||||
import { HomeAurora } from './HomeAurora'
|
import { HomeAurora } from './HomeAurora'
|
||||||
import { HomeArchitecture } from './HomeArchitecture';
|
import { HomeArchitecture } from './HomeArchitecture';
|
||||||
|
import { HomeDesign } from './HomeDesign';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export default function HomePage() {
|
|||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
<HomeAudience />
|
<HomeDesign />
|
||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ export function HomeSpotlight({
|
|||||||
<H4 className="text-center mt-4">The Living Network of the Next Internet</H4>
|
<H4 className="text-center mt-4">The Living Network of the Next Internet</H4>
|
||||||
|
|
||||||
<H5 className="mx-auto mt-6 max-w-4xl text-center font-normal text-neutral-500">
|
<H5 className="mx-auto mt-6 max-w-4xl text-center font-normal text-neutral-500">
|
||||||
A new internet is emerging — private, distributed, and self-sovereign.
|
A new internet is emerging, a private, distributed, and self-sovereign.
|
||||||
Mycelium is the living network that makes it possible.
|
Mycelium is the living network that makes it possible.
|
||||||
A peer-to-peer foundation where people, data, and intelligence connect
|
A peer-to-peer foundation where people, data, and intelligence connect
|
||||||
directly — without intermediaries, without compromise.
|
directly without intermediaries, without compromise.
|
||||||
</H5>
|
</H5>
|
||||||
|
|
||||||
<div className="mt-8 flex justify-center gap-6">
|
<div className="mt-8 flex justify-center gap-6">
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function HomeWhy() {
|
|||||||
<Eyebrow>Why It Matters</Eyebrow>
|
<Eyebrow>Why It Matters</Eyebrow>
|
||||||
<H3 className="mt-2 text-gray-200">Why Mycelium?</H3>
|
<H3 className="mt-2 text-gray-200">Why Mycelium?</H3>
|
||||||
<P className="mx-auto mt-5 max-w-prose text-gray-400">
|
<P className="mx-auto mt-5 max-w-prose text-gray-400">
|
||||||
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 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.
|
||||||
|
|
||||||
</P>
|
</P>
|
||||||
<div className="mt-16">
|
<div className="mt-16">
|
||||||
|
|||||||
225
src/pages/home/animations/NoSinglePoint.tsx
Normal file
225
src/pages/home/animations/NoSinglePoint.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ const tabs = [
|
|||||||
label: "K8s Clusters",
|
label: "K8s Clusters",
|
||||||
title: "K8s Clusters",
|
title: "K8s Clusters",
|
||||||
description:
|
description:
|
||||||
"Deploy and scale containerized apps across your own hardware — enabling a world of possibilities.",
|
"Deploy and scale containerized apps across your own hardware, enabling a world of possibilities.",
|
||||||
link: "#",
|
link: "#",
|
||||||
icon: CubeIcon,
|
icon: CubeIcon,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Container } from "@/components/Container";
|
import { Link } from 'react-router-dom';
|
||||||
|
import { Container } from '@/components/Container'
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
|
|
||||||
export function CallToAction() {
|
export function CallToAction() {
|
||||||
@@ -15,31 +16,56 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
||||||
Choose How You Want to Start
|
Choose How You Want to Connect
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p className="mt-6 text-lg text-gray-300">
|
<p className="mt-6 text-lg text-gray-300">
|
||||||
Use the network to connect workloads or host nodes to deepen mesh resilience and run your environments on your own hardware.
|
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>
|
</p>
|
||||||
|
|
||||||
{/* ✅ Two cards, stacked center with spacing */}
|
{/* ✅ Two cards, stacked center with spacing */}
|
||||||
<div className="mt-10 flex flex-wrap justify-center gap-x-10 gap-y-8">
|
<div className="mt-10 flex flex-wrap justify-center items-center gap-x-6 gap-y-4">
|
||||||
<div className="flex flex-col items-center text-center max-w-xs">
|
<Button to="/network" variant="solid" color="cyan">
|
||||||
<Button to="/download" variant="solid" color="cyan" className="mt-4">
|
Join the Network
|
||||||
Get Mycelium Network
|
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col items-center text-center max-w-xs">
|
<Button
|
||||||
<Button to="https://threefold.info/mycelium_network/docs/" as="a" target="_blank" variant="outline" color="white" className="mt-4">
|
to="/cloud"
|
||||||
Host a Node
|
variant="outline"
|
||||||
|
color="white"
|
||||||
|
>
|
||||||
|
Deploy in Cloud
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
|
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
|
||||||
|
Host a Node →
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ export function Features() {
|
|||||||
<Eyebrow>Core Components</Eyebrow>
|
<Eyebrow>Core Components</Eyebrow>
|
||||||
<H3>Network Capabilities</H3>
|
<H3>Network Capabilities</H3>
|
||||||
<P className="mt-4 max-w-4xl text-lg text-gray-600">
|
<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>
|
||||||
<P className="mt-4 max-w-4xl text-lg text-gray-600">
|
<P className="mt-4 max-w-3xl 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.
|
Nodes connect through intelligent routing, peer discovery, and decentralized delivery to create a continuously optimized data mesh.
|
||||||
</P>
|
</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="mt-8 grid grid-cols-1 gap-x-4 gap-y-8 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2">
|
||||||
<div className="group relative lg:col-span-3 transition-all duration-300 ease-in-out hover:scale-105">
|
<div className="group relative lg:col-span-3 transition-all duration-300 ease-in-out hover:scale-105">
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import { useId } from 'react'
|
|||||||
import { Container } from '@/components/Container'
|
import { Container } from '@/components/Container'
|
||||||
import { Button } from '@/components/Button'
|
import { Button } from '@/components/Button'
|
||||||
import phoneFrame from '../../images/phoneframe.png'
|
import phoneFrame from '../../images/phoneframe.png'
|
||||||
import { H3, P, CT } from "@/components/Texts";
|
import { H3, P
|
||||||
|
, Eyebrow } from "@/components/Texts";
|
||||||
|
|
||||||
function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
|
function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
|
||||||
let id = useId()
|
let id = useId()
|
||||||
@@ -79,23 +80,21 @@ export function Hero() {
|
|||||||
<Container>
|
<Container>
|
||||||
<div className="flex flex-col-reverse gap-y-16 lg:grid lg:grid-cols-12 lg:gap-x-8 lg:gap-y-20 px-6 lg:px-8">
|
<div className="flex flex-col-reverse gap-y-16 lg:grid lg:grid-cols-12 lg:gap-x-8 lg:gap-y-20 px-6 lg:px-8">
|
||||||
<div className="relative z-10 mx-auto max-w-2xl lg:col-span-7 lg:max-w-none lg:pt-6 xl:col-span-6">
|
<div className="relative z-10 mx-auto max-w-2xl lg:col-span-7 lg:max-w-none lg:pt-6 xl:col-span-6">
|
||||||
<H3 className="mb-4">
|
<Eyebrow className="mb-4">
|
||||||
Mycelium Network
|
MYCELIUM NETWORK
|
||||||
|
</Eyebrow>
|
||||||
|
<H3 className="mt-8 ">
|
||||||
|
The Network Stack for Private, Autonomous Networking
|
||||||
</H3>
|
</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">
|
<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>
|
||||||
<P className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
|
<P className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
|
||||||
Works Alone. Works Together.
|
Your Pod is your personal gateway to the network.
|
||||||
Mycelium Network can be used standalone, or together with Mycelium Cloud
|
|
||||||
for full-stack sovereignty.
|
|
||||||
</P>
|
</P>
|
||||||
<div className="mt-8 flex flex-wrap gap-x-6 gap-y-4">
|
<div className="mt-8 flex flex-wrap gap-x-6 gap-y-4">
|
||||||
<Button to="/download" variant="solid" color="cyan">
|
<Button to="/download" variant="solid" color="cyan">
|
||||||
Get Mycelium Connector
|
Get Started
|
||||||
</Button>
|
</Button>
|
||||||
<Button to="/download" variant="outline" color="cyan">
|
<Button to="/download" variant="outline" color="cyan">
|
||||||
Explore Docs
|
Explore Docs
|
||||||
|
|||||||
@@ -23,17 +23,15 @@ export function NetworkCapabilities() {
|
|||||||
<Eyebrow>WHAT IT ENABLES</Eyebrow>
|
<Eyebrow>WHAT IT ENABLES</Eyebrow>
|
||||||
|
|
||||||
<H4 className="mt-6 text-white">
|
<H4 className="mt-6 text-white">
|
||||||
A Private Networking Layer for Everything You Run
|
One Network. Many Capabilities.
|
||||||
</H4>
|
</H4>
|
||||||
|
|
||||||
<P className="mt-6 text-gray-200">
|
<P className="mt-6 text-gray-200">
|
||||||
Mycelium Network is the backbone for secure, autonomous connectivity
|
One network for all your connectivity needs.
|
||||||
across devices, data centers, clusters, and self-hosted environments — anywhere in the world.
|
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
<P className="mt-3 text-lg text-gray-200">
|
<P className="mt-3 text-lg text-gray-200">
|
||||||
Every node gets its own encrypted identity and address space, forming a
|
Mycelium replaces separate layers like VPNs, hosting, and DNS with a single encrypted, peer-to-peer system that links devices, apps, and environments directly.
|
||||||
zero-trust mesh without any centralized controller.
|
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -47,7 +45,7 @@ export function NetworkCapabilities() {
|
|||||||
End-to-End Encrypted Mesh
|
End-to-End Encrypted Mesh
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-200 max-w-2xl">
|
<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>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +57,7 @@ export function NetworkCapabilities() {
|
|||||||
Global IPv6 Address Space
|
Global IPv6 Address Space
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-200 max-w-2xl">
|
<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>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
||||||
</div>
|
</div>
|
||||||
@@ -68,10 +66,10 @@ export function NetworkCapabilities() {
|
|||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-semibold text-white flex items-center">
|
<h3 className="text-lg font-semibold text-white flex items-center">
|
||||||
<ArrowPathRoundedSquareIcon className="h-6 w-6 text-cyan-500 mr-3" />
|
<ArrowPathRoundedSquareIcon className="h-6 w-6 text-cyan-500 mr-3" />
|
||||||
Self-Healing Routing
|
Dynamic Pathfinding
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-200 max-w-2xl">
|
<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>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
||||||
</div>
|
</div>
|
||||||
@@ -83,7 +81,7 @@ export function NetworkCapabilities() {
|
|||||||
No Central Control
|
No Central Control
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-200 max-w-2xl">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
114
src/pages/network/NetworkDownload.tsx
Normal file
114
src/pages/network/NetworkDownload.tsx
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion'
|
||||||
|
|
||||||
|
import appleIcon from '@/images/apple.svg'
|
||||||
|
import windowsIcon from '@/images/windows.svg'
|
||||||
|
import androidIcon from '@/images/android.svg'
|
||||||
|
import linuxIcon from '@/images/linux.svg'
|
||||||
|
|
||||||
|
import { H3, P, Eyebrow, CT, CP } from '@/components/Texts'
|
||||||
|
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
name: 'Download for iOS & MacOS',
|
||||||
|
description: 'Download Mycelium App from the Apple Store.',
|
||||||
|
href: 'https://apps.apple.com/us/app/mycelium-network/id6504277565',
|
||||||
|
icon: appleIcon,
|
||||||
|
alt: 'Apple logo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Download for Windows',
|
||||||
|
description: 'Download the Mycelium App for Windows directly from its Github repository.',
|
||||||
|
href: 'https://github.com/threefoldtech/myceliumflut/releases',
|
||||||
|
icon: windowsIcon,
|
||||||
|
alt: 'Windows logo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Download for Android',
|
||||||
|
description: 'Download Mycelium from the Google Play Store.',
|
||||||
|
href: 'https://play.google.com/store/apps/details?id=tech.threefold.mycelium&pli=1',
|
||||||
|
icon: androidIcon,
|
||||||
|
alt: 'Android logo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Download for Linux',
|
||||||
|
description: 'Download the Mycelium binary for Linux directly from its Github repository.',
|
||||||
|
href: 'https://github.com/threefoldtech/mycelium/releases',
|
||||||
|
icon: linuxIcon,
|
||||||
|
alt: 'Linux logo',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export function NetworkDownload() {
|
||||||
|
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" />
|
||||||
|
|
||||||
|
<div className="mx-auto max-w-7xl px-6 lg:px-8 bg-white py-12 border border-t-0 border-b-0 border-gray-100">
|
||||||
|
<div className="mx-auto max-w-2xl lg:mx-0">
|
||||||
|
<motion.H3
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className="text-5xl font-medium tracking-tight text-gray-900 lg:text-6xl"
|
||||||
|
>
|
||||||
|
Download Mycelium Network
|
||||||
|
</motion.H3>
|
||||||
|
<motion.P
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.2 }}
|
||||||
|
className="mt-8 text-lg text-gray-600 lg:leading-8"
|
||||||
|
>
|
||||||
|
Get Mycelium Network for Android, Windows, macOS, and iOS to securely connect, store, and interact with the decentralized network—seamlessly and efficiently. Not sure how it works?{' '}
|
||||||
|
<a
|
||||||
|
href="https://threefold.info/mycelium_network/docs/"
|
||||||
|
className="font-semibold text-gray-900 underline transition-colors hover:text-cyan-500"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Read the manual.
|
||||||
|
</a>
|
||||||
|
</motion.P>
|
||||||
|
</div>
|
||||||
|
<div className="mx-auto mt-8 max-w-2xl lg:mt-12 lg:max-w-none">
|
||||||
|
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 md:grid-cols-2 lg:max-w-none lg:grid-cols-4">
|
||||||
|
{features.map((feature) => (
|
||||||
|
<div
|
||||||
|
key={feature.name}
|
||||||
|
className="flex flex-col rounded-lg border border-gray-100 p-8 shadow-sm transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20"
|
||||||
|
>
|
||||||
|
<dt className="text-base font-semibold leading-7 text-gray-900">
|
||||||
|
<div className="mb-6 flex h-10 w-10 items-center justify-center">
|
||||||
|
<img src={feature.icon} alt={feature.alt} className="h-10 w-10" />
|
||||||
|
</div>
|
||||||
|
{feature.name}
|
||||||
|
</dt>
|
||||||
|
<dd className="mt-1 flex flex-auto flex-col text-base leading-7 text-gray-600">
|
||||||
|
<CP className="flex-auto mt-2">{feature.description}</CP>
|
||||||
|
<CT className="mt-4">
|
||||||
|
<a
|
||||||
|
href={feature.href}
|
||||||
|
className="text-sm font-semibold leading-6 text-cyan-500 transition-colors hover:text-cyan-400"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Download Now <span aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
|
</CT>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</dl>
|
||||||
|
</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>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -5,7 +5,9 @@ import { PrimaryFeatures } from './PrimaryFeatures'
|
|||||||
import { SecondaryFeatures } from './SecondaryFeatures'
|
import { SecondaryFeatures } from './SecondaryFeatures'
|
||||||
import { CallToAction } from './CallToAction'
|
import { CallToAction } from './CallToAction'
|
||||||
import { NetworkCapabilities } from './NetworkCapabilities'
|
import { NetworkCapabilities } from './NetworkCapabilities'
|
||||||
import { NetworkUsecases } from './NetworkUsecases'
|
import { NetworkDownload } from './NetworkDownload'
|
||||||
|
import { NetworkPros } from './NetworkPros'
|
||||||
|
|
||||||
|
|
||||||
export default function NetworkPage() {
|
export default function NetworkPage() {
|
||||||
return (
|
return (
|
||||||
@@ -19,7 +21,7 @@ export default function NetworkPage() {
|
|||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
<Features />
|
<SecondaryFeatures />
|
||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
@@ -27,11 +29,16 @@ export default function NetworkPage() {
|
|||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
<NetworkUsecases />
|
<Features />
|
||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
<SecondaryFeatures />
|
<NetworkPros />
|
||||||
|
</AnimatedSection>
|
||||||
|
|
||||||
|
|
||||||
|
<AnimatedSection>
|
||||||
|
<NetworkDownload />
|
||||||
</AnimatedSection>
|
</AnimatedSection>
|
||||||
|
|
||||||
<AnimatedSection>
|
<AnimatedSection>
|
||||||
|
|||||||
71
src/pages/network/NetworkPros.tsx
Normal file
71
src/pages/network/NetworkPros.tsx
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
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 NetworkPros() {
|
||||||
|
return (
|
||||||
|
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
|
||||||
|
{/* Top spacing 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" />
|
||||||
|
|
||||||
|
{/* Main framed content */}
|
||||||
|
<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-4">
|
||||||
|
{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"
|
||||||
|
>
|
||||||
|
{/* Hover glow */}
|
||||||
|
<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>
|
||||||
|
|
||||||
|
{/* Bottom spacing line */}
|
||||||
|
<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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useRef } from "react";
|
|
||||||
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
|
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
|
||||||
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
|
|
||||||
import {
|
import {
|
||||||
LockClosedIcon,
|
LockClosedIcon,
|
||||||
ArrowPathIcon,
|
ArrowPathIcon,
|
||||||
GlobeAltIcon,
|
GlobeAltIcon,
|
||||||
|
SignalIcon,
|
||||||
|
CpuChipIcon,
|
||||||
} from "@heroicons/react/24/solid";
|
} from "@heroicons/react/24/solid";
|
||||||
|
|
||||||
const networkUseCases = [
|
const networkUseCases = [
|
||||||
@@ -27,46 +27,52 @@ const networkUseCases = [
|
|||||||
{
|
{
|
||||||
title: "Service-to-Service Networking Across Environments",
|
title: "Service-to-Service Networking Across Environments",
|
||||||
description:
|
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",
|
ideal: "Ideal for: dev teams, distributed apps, container + K3s workloads",
|
||||||
icon: GlobeAltIcon,
|
icon: GlobeAltIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Resilient Connectivity Across Regions & Outages",
|
title: "Resilient Connectivity Across Regions & Outages",
|
||||||
description:
|
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:
|
||||||
"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,
|
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() {
|
export function NetworkUsecases() {
|
||||||
const sliderRef = useRef<HTMLUListElement>(null);
|
|
||||||
|
|
||||||
const scrollLeft = () =>
|
|
||||||
sliderRef.current?.scrollBy({ left: -400, behavior: "smooth" });
|
|
||||||
|
|
||||||
const scrollRight = () =>
|
|
||||||
sliderRef.current?.scrollBy({ left: 400, behavior: "smooth" });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="bg-white w-full max-w-8xl mx-auto">
|
<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="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="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">
|
<div className="mx-auto max-w-7xl border border-t-0 border-b-0 border-slate-200 bg-white">
|
||||||
<ul
|
{/* GRID 3 x 3 */}
|
||||||
ref={sliderRef}
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
|
|
||||||
>
|
|
||||||
{networkUseCases.map((item, idx) => (
|
{networkUseCases.map((item, idx) => (
|
||||||
<li
|
<div
|
||||||
key={idx}
|
key={idx}
|
||||||
className={`snap-start shrink-0 w-[85%] sm:w-[50%] lg:w-[33%] border border-slate-200 p-10 relative ${
|
className={`
|
||||||
item.isIntro ? "bg-gray-50/80" : "bg-white"
|
border border-slate-200 p-10 relative
|
||||||
}`}
|
${item.isIntro ? "bg-gray-50/80" : "bg-white"}
|
||||||
|
`}
|
||||||
>
|
>
|
||||||
|
{/* Intro Card */}
|
||||||
{item.isIntro ? (
|
{item.isIntro ? (
|
||||||
<div className="flex flex-col justify-between h-full">
|
<div className="flex flex-col justify-between h-full">
|
||||||
<div>
|
<div>
|
||||||
@@ -81,47 +87,39 @@ export function NetworkUsecases() {
|
|||||||
{item.description}
|
{item.description}
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{/* ✅ Icon above title */}
|
{/* Icon */}
|
||||||
{item.icon && (
|
{item.icon && (
|
||||||
<div className="h-10 w-10 flex items-center justify-center rounded-xl bg-gray-100 mb-4">
|
<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" />
|
<item.icon className="h-6 w-6 text-cyan-600" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Title */}
|
||||||
<p className="text-lg font-semibold text-gray-900">
|
<p className="text-lg font-semibold text-gray-900">
|
||||||
{item.title}
|
{item.title}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
{/* Description */}
|
||||||
<p className="mt-2 text-gray-600 leading-snug">
|
<p className="mt-2 text-gray-600 leading-snug">
|
||||||
{item.description}
|
{item.description}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
{/* Ideal for */}
|
||||||
<p className="mt-3 text-xs font-medium text-cyan-700">
|
<p className="mt-3 text-xs font-medium text-cyan-700">
|
||||||
{item.ideal}
|
{item.ideal}
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</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>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ function FeaturesDesktop() {
|
|||||||
{feature.name}
|
{feature.name}
|
||||||
</Tab>
|
</Tab>
|
||||||
</FeatureTitle>
|
</FeatureTitle>
|
||||||
<FeatureDescription color="secondary" className="mt-2">
|
<FeatureDescription color="white" className="mt-2">
|
||||||
{feature.description}
|
{feature.description}
|
||||||
</FeatureDescription>
|
</FeatureDescription>
|
||||||
</div>
|
</div>
|
||||||
@@ -419,9 +419,7 @@ export function PrimaryFeatures() {
|
|||||||
How Mycelium Operates
|
How Mycelium Operates
|
||||||
</SectionHeader>
|
</SectionHeader>
|
||||||
<P color="light" className="mt-6">
|
<P color="light" className="mt-6">
|
||||||
Mycelium, like its natural namesake, thrives on decentralization,
|
Your device connects to an encrypted peer-to-peer mesh that automatically handles routing, discovery, and communication.
|
||||||
efficiency, and security, making it a truly powerful force in the world
|
|
||||||
of decentralized networks.
|
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -4,41 +4,41 @@ import { CP } from '@/components/Texts'
|
|||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
name: 'Quantum Safe Storage Functionality',
|
name: 'Sovereign DNS',
|
||||||
description:
|
description:
|
||||||
"Mycelium's quantum safe storage enables flexible, scalable, and efficient data distribution across a decentralized network, ensuring redundancy and security.",
|
'Human-readable names secured by your keypair, not a registrar. Unblockable discovery, private namespaces, and instant resolution across PODs.',
|
||||||
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.',
|
|
||||||
icon: DeviceListIcon,
|
icon: DeviceListIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Frontend/Backend Integration',
|
name: 'Integrated VPN (Desktop)',
|
||||||
description:
|
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,
|
icon: DeviceLockIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CDN (Content Delivery Network)',
|
name: 'Unstoppable Publishing',
|
||||||
description:
|
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,
|
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'>) {
|
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">
|
<Container className="py-12 border border-t-0 border-b-0 border-gray-100">
|
||||||
<div className="mx-auto max-w-4xl sm:text-center">
|
<div className="mx-auto max-w-4xl sm:text-center">
|
||||||
<h2 className="text-base/7 font-semibold text-cyan-500">IN ACTIVE EVOLUTION</h2>
|
<h2 className="text-base/7 font-semibold text-cyan-500">FEATURES</h2>
|
||||||
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
|
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
|
||||||
Expanding the Network Layer
|
Core Features
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-6 text-lg text-gray-600">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Eyebrow, H3, CT, CP, P } from "@/components/Texts";
|
|
||||||
|
|
||||||
const nodeSpecs = [
|
|
||||||
{
|
|
||||||
id: "autonomous",
|
|
||||||
eyebrow: "Self-Running",
|
|
||||||
title: "Autonomous Operation",
|
|
||||||
description: "Runs autonomously with no central control.",
|
|
||||||
colSpan: "lg:col-span-3",
|
|
||||||
rounded: "max-lg:rounded-t-4xl lg:rounded-tl-4xl",
|
|
||||||
innerRounded: "max-lg:rounded-t-[calc(2rem+1px)] lg:rounded-tl-[calc(2rem+1px)]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "encrypted",
|
|
||||||
eyebrow: "Security",
|
|
||||||
title: "Encrypted by Default",
|
|
||||||
description: "Fully encrypted and identity-based.",
|
|
||||||
colSpan: "lg:col-span-3",
|
|
||||||
rounded: "lg:rounded-tr-4xl",
|
|
||||||
innerRounded: "lg:rounded-tr-[calc(2rem+1px)]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "efficient",
|
|
||||||
eyebrow: "Performance",
|
|
||||||
title: "Energy Efficient",
|
|
||||||
description: "Energy-efficient and quiet, designed for 24/7 uptime.",
|
|
||||||
colSpan: "lg:col-span-2",
|
|
||||||
rounded: "lg:rounded-bl-4xl",
|
|
||||||
innerRounded: "lg:rounded-bl-[calc(2rem+1px)]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "uptime",
|
|
||||||
eyebrow: "Reliability",
|
|
||||||
title: "Measured Uptime",
|
|
||||||
description: "Automatically measures uptime and contribution.",
|
|
||||||
colSpan: "lg:col-span-2",
|
|
||||||
rounded: "",
|
|
||||||
innerRounded: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "fullstack",
|
|
||||||
eyebrow: "Compatibility",
|
|
||||||
title: "Full Mycelium Stack Support",
|
|
||||||
description: "Supports Mycelium Network, Cloud, Pods, and Agents.",
|
|
||||||
colSpan: "lg:col-span-2",
|
|
||||||
rounded: "max-lg:rounded-b-4xl lg:rounded-br-4xl",
|
|
||||||
innerRounded: "max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-br-[calc(2rem+1px)]",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export function NodeSpecs() {
|
|
||||||
return (
|
|
||||||
<div className="bg-white py-24 sm:py-32">
|
|
||||||
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8">
|
|
||||||
<Eyebrow>Node Specifications</Eyebrow>
|
|
||||||
<H3 className="mt-2">Built for Reliability and Control</H3>
|
|
||||||
<P className="mt-6 max-w-xl">
|
|
||||||
Each node strengthens the network and helps build a more open, sovereign and
|
|
||||||
distributed internet.
|
|
||||||
</P>
|
|
||||||
|
|
||||||
<div className="mt-10 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2">
|
|
||||||
{nodeSpecs.map((item) => (
|
|
||||||
<div key={item.id} className={`relative ${item.colSpan}`}>
|
|
||||||
{/* BG LAYER */}
|
|
||||||
<div
|
|
||||||
className={`absolute inset-0 rounded-lg bg-white ${item.rounded}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* CONTENT LAYER */}
|
|
||||||
<div
|
|
||||||
className={`relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] ${item.innerRounded}`}
|
|
||||||
>
|
|
||||||
<div className="p-10 pt-6">
|
|
||||||
<h3 className="text-sm/4 font-semibold text-cyan-600">{item.eyebrow}</h3>
|
|
||||||
<CT className="mt-2 text-lg font-medium tracking-tight text-gray-950">
|
|
||||||
{item.title}
|
|
||||||
</CT>
|
|
||||||
<CP className="mt-2 max-w-lg text-sm/6 text-gray-600">
|
|
||||||
{item.description}
|
|
||||||
</CP>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* OUTLINE OVERLAY */}
|
|
||||||
<div
|
|
||||||
className={`pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 ${item.rounded}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,26 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
||||||
@@ -52,7 +52,7 @@ export function NodeBenefits() {
|
|||||||
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
|
<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="w-full border-t border-l border-r border-gray-800" />
|
||||||
|
|
||||||
<div className="relative px-6 lg:px-12 py-12 bg-[#111111] border border-t-0 border-b-0 border-gray-800 max-w-7xl mx-auto">
|
<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 */}
|
{/* Header */}
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
@@ -72,7 +72,7 @@ export function NodeBenefits() {
|
|||||||
<P className="mt-6" color="light">
|
<P className="mt-6" color="light">
|
||||||
Hosting a node gives you private compute, contributes to the global
|
Hosting a node gives you private compute, contributes to the global
|
||||||
Mycelium infrastructure, and unlocks ways to earn from real network
|
Mycelium infrastructure, and unlocks ways to earn from real network
|
||||||
usage — all while keeping sovereignty and control.
|
usage, all while keeping sovereignty and control.
|
||||||
</P>
|
</P>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
@@ -1,32 +1,32 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Button } from '@/components/Button'
|
import { Button } from '@/components/Button'
|
||||||
import { Eyebrow, H3, P } from '@/components/Texts'
|
import { Eyebrow, H3 } from '@/components/Texts'
|
||||||
|
|
||||||
export function NodeHero() {
|
export function NodeHero() {
|
||||||
return (
|
return (
|
||||||
<div className="">
|
<div className="">
|
||||||
{/* Boxed container */}
|
{/* Boxed container */}
|
||||||
<div
|
<div
|
||||||
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden"
|
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 */}
|
{/* Inner padding */}
|
||||||
<div className="px-6 py-16 lg:py-16">
|
<div className="px-6 py-16 lg:py-16">
|
||||||
<div className="max-w-3xl mx-auto text-center">
|
<div className="max-w-2xl lg:pl-6">
|
||||||
<Eyebrow>MYCELIUM NODES</Eyebrow>
|
<Eyebrow>MYCELIUM NODES</Eyebrow>
|
||||||
<H3 as="h1" className="mt-4">
|
<H3 as="h1" className="mt-4">
|
||||||
Host a Node. Power the Network.
|
Host a Node. Power the Network.
|
||||||
</H3>
|
</H3>
|
||||||
<P className="mt-6 text-gray-800">
|
<p className="mt-6 text-lg text-gray-800">
|
||||||
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.
|
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>
|
</p>
|
||||||
|
<div className="mt-10 flex items-center gap-x-6">
|
||||||
<div className="mt-10 flex items-center justify-center gap-x-6">
|
<Button to="#node-getting-started" as="a" variant="solid" color="cyan">
|
||||||
<Button href="/host" variant="solid" color="cyan">
|
How it works
|
||||||
Host a Node
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button href="#" variant="outline">
|
<Button to="#node-architecture" as="a" variant="outline">
|
||||||
Learn More
|
Explore Docs <span aria-hidden="true">→</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -5,7 +5,6 @@ import { motion } from "framer-motion";
|
|||||||
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
|
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
|
||||||
import {
|
import {
|
||||||
QuestionMarkCircleIcon,
|
QuestionMarkCircleIcon,
|
||||||
ShieldCheckIcon,
|
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
} from "@heroicons/react/20/solid";
|
} from "@heroicons/react/20/solid";
|
||||||
|
|
||||||
@@ -137,7 +136,7 @@ export function NodeProducts() {
|
|||||||
{/* CONFIG SELECTOR */}
|
{/* CONFIG SELECTOR */}
|
||||||
<fieldset className="mt-10">
|
<fieldset className="mt-10">
|
||||||
<legend className="text-sm font-medium text-gray-200">
|
<legend className="text-sm font-medium text-gray-200">
|
||||||
Configuration
|
Choose Your Node Type
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
<div className="mt-3 grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="mt-3 grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
@@ -160,7 +159,7 @@ export function NodeProducts() {
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<a className="inline-flex text-sm text-gray-500 hover:text-gray-300 transition">
|
<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?
|
What config should I choose?
|
||||||
<QuestionMarkCircleIcon className="ml-1 w-5 h-5 text-gray-500" />
|
<QuestionMarkCircleIcon className="ml-1 w-5 h-5 text-gray-500" />
|
||||||
</a>
|
</a>
|
||||||
@@ -194,11 +193,7 @@ export function NodeProducts() {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Guarantee */}
|
|
||||||
<div className="mt-6 flex items-center text-gray-400 text-sm">
|
|
||||||
<ShieldCheckIcon className="w-6 h-6 text-gray-500 mr-2" />
|
|
||||||
Lifetime Guarantee
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* ------------------------------ */}
|
{/* ------------------------------ */}
|
||||||
@@ -214,7 +209,7 @@ export function NodeProducts() {
|
|||||||
<img
|
<img
|
||||||
src={selectedNode.image}
|
src={selectedNode.image}
|
||||||
alt={selectedNode.name}
|
alt={selectedNode.name}
|
||||||
className="w-full max-w-md rounded-2xl border border-gray-800 object-cover"
|
className="max-w-md rounded-2xl "
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
114
src/pages/nodes/NodeSpecs.tsx
Normal file
114
src/pages/nodes/NodeSpecs.tsx
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
|
||||||
|
// 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import { NodeProducts } from './NodeProducts';
|
|||||||
import { NodeSpecs } from './NodeSpecs';
|
import { NodeSpecs } from './NodeSpecs';
|
||||||
import { CallToAction } from './CallToAction';
|
import { CallToAction } from './CallToAction';
|
||||||
|
|
||||||
const NodePage: React.FC = () => {
|
const NodesPage: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NodeHero />
|
<NodeHero />
|
||||||
@@ -19,4 +19,4 @@ const NodePage: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NodePage;
|
export default NodesPage;
|
||||||
@@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
import { Container } from "@/components/Container";
|
import { Container } from "@/components/Container";
|
||||||
|
import { CheckCircleIcon } from "@heroicons/react/20/solid";
|
||||||
|
|
||||||
|
const benefits = [
|
||||||
|
'Private chat and calls',
|
||||||
|
'Calendar and file sync',
|
||||||
|
'Secure team spaces',
|
||||||
|
'Early AI Agent integration',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function CallToAction() {
|
export function CallToAction() {
|
||||||
return (
|
return (
|
||||||
@@ -15,14 +25,59 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
||||||
Join the First Wave
|
Be Among The First
|
||||||
|
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p className="mt-6 text-lg text-gray-300">
|
<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.
|
The first Pods are launching soon.
|
||||||
|
10,000 early Pods will be available for early adopters.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-10 flex items-center justify-center">
|
||||||
|
<ul
|
||||||
|
role="list"
|
||||||
|
className="grid grid-cols-1 gap-x-8 gap-y-3 text-left text-base/7 text-gray-200 sm:grid-cols-2"
|
||||||
|
>
|
||||||
|
{benefits.map((benefit) => (
|
||||||
|
<li key={benefit} className="flex items-start gap-x-3">
|
||||||
|
<CheckCircleIcon
|
||||||
|
aria-hidden="true"
|
||||||
|
className="mt-1 h-7 w-5 flex-none text-gray-200"
|
||||||
|
/>
|
||||||
|
<span>{benefit}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="mt-6 text-lg text-gray-300">
|
||||||
|
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. Be among the first to claim
|
||||||
|
your private space on the Mycelium Network.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* ✅ Two cards, stacked center with spacing */}
|
{/* ✅ Two cards, stacked center with spacing */}
|
||||||
@@ -35,7 +90,7 @@ export function CallToAction() {
|
|||||||
|
|
||||||
<div className="flex flex-col items-center text-center max-w-xs">
|
<div className="flex flex-col items-center text-center max-w-xs">
|
||||||
<Button to="#" variant="outline" color="white" className="mt-4">
|
<Button to="#" variant="outline" color="white" className="mt-4">
|
||||||
Deploy Pods in Your Community
|
Learn More
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
import { H3, Eyebrow, P } from "@/components/Texts"
|
import { H3, Eyebrow, P } from "@/components/Texts"
|
||||||
|
import { Button } from "@/components/Button"
|
||||||
|
|
||||||
export default function Homepod() {
|
export default function Homepod() {
|
||||||
|
const onGetStartedClick = () => {
|
||||||
|
console.log("Get started clicked");
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="">
|
<div className="">
|
||||||
{/* Boxed container */}
|
{/* Boxed container */}
|
||||||
<div
|
<div
|
||||||
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
|
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
|
||||||
style={{ backgroundImage: "url('/images/pods.png')", backgroundSize: "contain" }}
|
style={{ backgroundImage: "url('/images/computehero11.webp')", backgroundSize: "contain" }}
|
||||||
>
|
>
|
||||||
{/* Inner padding */}
|
{/* Inner padding */}
|
||||||
<div className="px-6 py-16 lg:py-16">
|
<div className="px-6 py-16 lg:py-24">
|
||||||
<div className="max-w-2xl lg:pl-6">
|
<div className="max-w-2xl lg:pl-6">
|
||||||
<Eyebrow>
|
<Eyebrow>
|
||||||
MYCELIUM PODS
|
MYCELIUM PODS
|
||||||
@@ -18,10 +22,20 @@ export default function Homepod() {
|
|||||||
Your Private Space in the New Internet
|
Your Private Space in the New Internet
|
||||||
</H3>
|
</H3>
|
||||||
<P className="mt-6 text-gray-800">
|
<P className="mt-6 text-gray-800">
|
||||||
Imagine having your own corner of the internet — private, secure, and always online.
|
Pods are personal digital spaces on the Mycelium Network. They are private, persistent, and fully under your control. Run conversations, files, and tools directly on the network instead of through central servers
|
||||||
A Pod is your personal digital space on the Mycelium Network.
|
|
||||||
It’s where your conversations, files, and digital tools live — owned by you, connected to others directly.
|
|
||||||
</P>
|
</P>
|
||||||
|
<div className="mt-8 flex items-center gap-x-6">
|
||||||
|
<Button
|
||||||
|
variant="solid"
|
||||||
|
color="cyan"
|
||||||
|
onClick={onGetStartedClick}
|
||||||
|
>
|
||||||
|
Join the Waitlist
|
||||||
|
</Button>
|
||||||
|
<Button to="#" variant="outline">
|
||||||
|
Explore Docs →
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const capabilities = [
|
|||||||
{
|
{
|
||||||
title: "An always-on space you fully control",
|
title: "An always-on space you fully control",
|
||||||
description:
|
description:
|
||||||
"A dedicated, always-on environment you fully command — your own sovereign slice of the network that never goes offline.",
|
"A dedicated, always-on environment you fully command, your own sovereign slice of the network that never goes offline.",
|
||||||
icon: (
|
icon: (
|
||||||
<div className="flex items-start justify-start">
|
<div className="flex items-start justify-start">
|
||||||
<CpuChipIcon className="h-12 w-12 text-cyan-400" />
|
<CpuChipIcon className="h-12 w-12 text-cyan-400" />
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function PodsCapabilities() {
|
|||||||
</H3>
|
</H3>
|
||||||
|
|
||||||
<P className="mt-6 text-gray-200">
|
<P className="mt-6 text-gray-200">
|
||||||
Access everything from any device — your data follows you, not the other way around.
|
Access everything from any device, your data follows you, not the other way around.
|
||||||
💡 It’s like having your own tiny cloud that belongs only to you.
|
💡 It’s like having your own tiny cloud that belongs only to you.
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,7 +42,7 @@ export function PodsCapabilities() {
|
|||||||
Communicate
|
Communicate
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-200 max-w-2xl">
|
<p className="mt-2 text-gray-200 max-w-2xl">
|
||||||
Message, call, and share files privately — no tracking or ads.
|
Message, call, and share files privately with no tracking or ads.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
<div className="mt-8 h-px w-full bg-cyan-500/50" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Your own AI, powered by your data without any data leaks.
|
|||||||
Calendar & File Sync
|
Calendar & File Sync
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-700 max-w-2xl">
|
<p className="mt-2 text-gray-700 max-w-2xl">
|
||||||
Your schedules, documents, and files — synced across your Pods with no central cloud.
|
Your schedules, documents, and files synced across your Pods with no central cloud.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-200" />
|
<div className="mt-8 h-px w-full bg-cyan-200" />
|
||||||
</div>
|
</div>
|
||||||
@@ -66,7 +66,7 @@ Your own AI, powered by your data without any data leaks.
|
|||||||
Secure Team Spaces
|
Secure Team Spaces
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-700 max-w-2xl">
|
<p className="mt-2 text-gray-700 max-w-2xl">
|
||||||
Create shared Pods for teams, communities, or groups — fully encrypted, fully sovereign.
|
Create shared Pods for teams, communities, or groups. Fully encrypted, fully sovereign.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 h-px w-full bg-cyan-200" />
|
<div className="mt-8 h-px w-full bg-cyan-200" />
|
||||||
</div>
|
</div>
|
||||||
@@ -79,7 +79,7 @@ Your own AI, powered by your data without any data leaks.
|
|||||||
<span className="ml-2 text-xs text-gray-400">🕒</span>
|
<span className="ml-2 text-xs text-gray-400">🕒</span>
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-2 text-gray-700 max-w-2xl">
|
<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.
|
Host your personal AI agent inside your Pod. Private, local-first, and fully under your control.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ export function PodsDesign() {
|
|||||||
return (
|
return (
|
||||||
<div className="bg-white text-gray-900">
|
<div className="bg-white text-gray-900">
|
||||||
{/* TOP LINE */}
|
{/* TOP LINE */}
|
||||||
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
|
<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-200" />
|
<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-200">
|
<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="mx-auto max-w-2xl lg:max-w-none">
|
||||||
|
|
||||||
<div className="lg:grid lg:grid-cols-5 lg:items-start lg:gap-x-8">
|
<div className="lg:grid lg:grid-cols-5 lg:items-start lg:gap-x-8">
|
||||||
@@ -61,7 +61,7 @@ export function PodsDesign() {
|
|||||||
<div className="lg:col-span-2 lg:mt-8 mt-2">
|
<div className="lg:col-span-2 lg:mt-8 mt-2">
|
||||||
<img
|
<img
|
||||||
alt="Mycelium Federation"
|
alt="Mycelium Federation"
|
||||||
src="/images/cloudhosting.webp"
|
src="/images/pod1.png"
|
||||||
className="aspect-square w-full object-cover rounded-md"
|
className="aspect-square w-full object-cover rounded-md"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,8 +114,8 @@ export function PodsDesign() {
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
{/* BOTTOM LINE */}
|
{/* BOTTOM LINE */}
|
||||||
<div className="w-full border-b border-gray-200" />
|
<div className="w-full border-b border-gray-100" />
|
||||||
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
|
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const useCases = [
|
|||||||
"Communicate directly Pod-to-Pod with no centralized routing.",
|
"Communicate directly Pod-to-Pod with no centralized routing.",
|
||||||
bullets: [
|
bullets: [
|
||||||
"End-to-end encrypted messaging and voice calling.",
|
"End-to-end encrypted messaging and voice calling.",
|
||||||
"No intermediaries — connections flow directly between Pods.",
|
"No intermediaries, connections flow directly between Pods.",
|
||||||
"Zero metadata profiling, tracking, or data resale.",
|
"Zero metadata profiling, tracking, or data resale.",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -21,7 +21,7 @@ const useCases = [
|
|||||||
bullets: [
|
bullets: [
|
||||||
"Files remain private with no platform-level scanning or analysis.",
|
"Files remain private with no platform-level scanning or analysis.",
|
||||||
"Share documents and media directly with trusted contacts.",
|
"Share documents and media directly with trusted contacts.",
|
||||||
"Full ownership of your content — no cloud vendor dependencies.",
|
"Full ownership of your content, with no cloud vendor dependencies.",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -57,11 +57,11 @@ const useCases = [
|
|||||||
{
|
{
|
||||||
title: "Access From Any Device",
|
title: "Access From Any Device",
|
||||||
description:
|
description:
|
||||||
"Your Pod travels with you — always accessible, always yours.",
|
"Your Pod travels with you. Always accessible, always yours.",
|
||||||
bullets: [
|
bullets: [
|
||||||
"Use your Pod from phones, laptops, tablets, or shared machines.",
|
"Use your Pod from phones, laptops, tablets, or shared machines.",
|
||||||
"Your identity, apps, and files follow you securely.",
|
"Your identity, apps, and files follow you securely.",
|
||||||
"No syncing or duplicated copies — direct access to your environment.",
|
"No syncing or duplicated copies, direct access to your environment.",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -106,28 +106,12 @@ export function PodsFeatures() {
|
|||||||
<h3 className="font-semibold text-gray-900">
|
<h3 className="font-semibold text-gray-900">
|
||||||
{useCase.title}
|
{useCase.title}
|
||||||
</h3>
|
</h3>
|
||||||
<Small className="uppercase tracking-[0.25em] text-cyan-500">
|
|
||||||
Feature
|
|
||||||
</Small>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Short description */}
|
{/* Short description */}
|
||||||
<p className="mt-4 text-gray-700 leading-snug">
|
<p className="mt-4 text-gray-700 leading-snug">
|
||||||
{useCase.description}
|
{useCase.description}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* Bullet list */}
|
|
||||||
<ul className="mt-6 space-y-3 text-sm text-gray-600">
|
|
||||||
{useCase.bullets.map((bullet) => (
|
|
||||||
<li
|
|
||||||
key={bullet}
|
|
||||||
className="flex items-start gap-3 rounded-2xl border border-cyan-100 bg-cyan-50/60 p-3 leading-relaxed"
|
|
||||||
>
|
|
||||||
<span className="mt-1 inline-block size-2 rounded-full bg-cyan-500" />
|
|
||||||
<span>{bullet}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,57 +1,70 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Eyebrow, H3, P } from "@/components/Texts";
|
import { Eyebrow, H4, H5 } from "@/components/Texts";
|
||||||
import PodsFlow from "./animations/PodsFlow";
|
import PodsFlow from "./animations/PodsFlow";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { IconClockHour5 } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
const phrases = [
|
||||||
|
"everything runs directly from your Pod.",
|
||||||
|
"Messages travel from Pod to Pod, never through a server.",
|
||||||
|
"Calls are hosted on your Pod, not in a data center.",
|
||||||
|
"Files stay encrypted, available, and always yours.",
|
||||||
|
];
|
||||||
|
|
||||||
export function PodsHow() {
|
export function PodsHow() {
|
||||||
|
const [index, setIndex] = useState(0);
|
||||||
|
const [fade, setFade] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setFade(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIndex((prev) => (prev + 1) % phrases.length);
|
||||||
|
setFade(true);
|
||||||
|
}, 300);
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full bg-[#121212] overflow-hidden">
|
<section className="relative w-full bg-[#121212] overflow-hidden">
|
||||||
{/* ✅ Top horizontal line with spacing */}
|
|
||||||
<div className="max-w-7xl bg-[#121212] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
|
<div className="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="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">
|
<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 */}
|
{/* Two-column layout */}
|
||||||
<div className="flex flex-col lg:flex-row-reverse gap-8">
|
<div className="flex flex-col lg:flex-row-reverse gap-8">
|
||||||
|
|
||||||
{/* ✅ Right side animation */}
|
{/* Right: Animation */}
|
||||||
<div className="w-full lg:w-4/9">
|
<div className="w-full lg:w-4/9">
|
||||||
<PodsFlow />
|
<PodsFlow />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ✅ Left side content */}
|
{/* Left: JUST the H3 with auto-changing sentence */}
|
||||||
<div className="w-full lg:w-5/9 text-white">
|
<div className="w-full lg:w-5/9 text-white flex items-center">
|
||||||
<Eyebrow color="accent" className="">
|
|
||||||
How it works
|
<div>
|
||||||
</Eyebrow>
|
<Eyebrow color="accent">How it works</Eyebrow>
|
||||||
<H3 color="white" className="mt-6">
|
<H4 color="white">A Pod in Action</H4>
|
||||||
A Pod in Action
|
<H5 color="white" className="mt-4">
|
||||||
</H3>
|
When you use Mycelium,
|
||||||
<P className="max-w-4xl text-gray-400 mt-6">
|
<span
|
||||||
When you use Mycelium, everything runs directly from your Pod.
|
className={`inline-block transition-opacity duration-300 ${
|
||||||
</P>
|
fade ? "opacity-100" : "opacity-0"
|
||||||
<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" />
|
{phrases[index]}
|
||||||
<span>When you message someone, it goes Pod to Pod, not through a central server.</span>
|
</span>
|
||||||
</li>
|
</H5>
|
||||||
<li className="flex items-start gap-3">
|
</div>
|
||||||
<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">
|
|
||||||
No one else can read it, rent it, or switch it off.
|
|
||||||
You don’t log in to the internet — you are part of it.
|
|
||||||
</P>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
|
<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" />
|
<div className="w-full border-b border-gray-800" />
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
import Homepod from './Homepod';
|
import Homepod from './Homepod';
|
||||||
import { PodCapabilities } from './PodCapabilities';
|
|
||||||
import { PodsHow } from './PodsHow';
|
import { PodsHow } from './PodsHow';
|
||||||
import { PodsFeatures } from './PodsFeatures';
|
import { PodsFeatures } from './PodsFeatures';
|
||||||
import { PodsDesign } from './PodsDesign';
|
import { PodsDesign } from './PodsDesign';
|
||||||
import { PodsBenefits } from './PodsBenefits';
|
|
||||||
import { PodsComing } from './PodsComing';
|
|
||||||
import { CallToAction } from './CallToAction';
|
import { CallToAction } from './CallToAction';
|
||||||
|
import { PodsWhat } from './PodsWhat';
|
||||||
|
|
||||||
const PodsPage = () => {
|
const PodsPage = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Homepod />
|
<Homepod />
|
||||||
<PodCapabilities />
|
<PodsWhat />
|
||||||
<PodsFeatures />
|
<PodsFeatures />
|
||||||
<PodsHow />
|
<PodsHow />
|
||||||
<PodsDesign />
|
<PodsDesign />
|
||||||
<PodsBenefits />
|
|
||||||
<PodsComing />
|
|
||||||
<CallToAction />
|
<CallToAction />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
81
src/pages/pods/PodsWhat.tsx
Normal file
81
src/pages/pods/PodsWhat.tsx
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {
|
||||||
|
ServerIcon,
|
||||||
|
ShieldCheckIcon,
|
||||||
|
BoltIcon,
|
||||||
|
GlobeAltIcon,
|
||||||
|
} from "@heroicons/react/24/solid";
|
||||||
|
|
||||||
|
import { Eyebrow, H3, P } from "@/components/Texts";
|
||||||
|
|
||||||
|
const podCards = [
|
||||||
|
{
|
||||||
|
id: "tools",
|
||||||
|
title: "Runs communication, storage, and collaboration tools",
|
||||||
|
icon: ServerIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "p2p",
|
||||||
|
title: "Operates peer to peer on the network",
|
||||||
|
icon: ShieldCheckIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "encrypted",
|
||||||
|
title: "Uses encrypted identities and storage",
|
||||||
|
icon: BoltIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "fabric",
|
||||||
|
title: "Connects directly to other Pods through the network fabric",
|
||||||
|
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">
|
||||||
|
|
||||||
|
{/* Intro heading */}
|
||||||
|
<div className="pt-12 pb-10 max-w-3xl">
|
||||||
|
<Eyebrow>What</Eyebrow>
|
||||||
|
<H3 className="mt-2 text-white">What is a Pod?</H3>
|
||||||
|
<P className="mt-4 text-gray-300">
|
||||||
|
A Pod is an always-on digital environment that gives you a secure place to run your
|
||||||
|
applications and data.
|
||||||
|
</P>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 4-column grid */}
|
||||||
|
<div className="grid grid-cols-1 gap-12 lg:grid-cols-4 pb-20">
|
||||||
|
{podCards.map((card) => {
|
||||||
|
const Icon = card.icon;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={card.id}
|
||||||
|
className="flex flex-col transition-transform duration-300 hover:scale-[1.02]"
|
||||||
|
>
|
||||||
|
{/* TITLE WITH ICON */}
|
||||||
|
<dt className="flex items-center gap-x-3 text-base font-semibold text-white">
|
||||||
|
{Icon && <Icon className="h-6 w-6 text-cyan-500" aria-hidden="true" />}
|
||||||
|
{card.title}
|
||||||
|
</dt>
|
||||||
|
</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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -9,22 +9,23 @@ type Props = {
|
|||||||
gridStroke?: string;
|
gridStroke?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ▸ NEW: Cropped dimensions
|
||||||
const W = 760;
|
const W = 760;
|
||||||
const H = 420;
|
const H = 300; // was 420
|
||||||
|
|
||||||
export default function PodsFlow({
|
export default function PodsFlow({
|
||||||
className,
|
className,
|
||||||
accent = "#00b8db",
|
accent = "#00b8db",
|
||||||
gridStroke = "#2b2a2a",
|
gridStroke = "#3a3a3a", // lighter grid stroke
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const pods = [
|
const pods = [
|
||||||
{ x: 100, y: 180, label: "Pod 1" },
|
{ x: 100, y: 120, label: "Pod 1" }, // moved slightly up for new height
|
||||||
{ x: 260, y: 180, label: "Pod 2" },
|
{ x: 260, y: 120, label: "Pod 2" },
|
||||||
{ x: 420, y: 180, label: "Pod 3" },
|
{ x: 420, y: 120, label: "Pod 3" },
|
||||||
{ x: 580, y: 180, label: "Pod 4" },
|
{ x: 580, y: 120, label: "Pod 4" },
|
||||||
];
|
];
|
||||||
|
|
||||||
// Pulse path
|
// Pulse path (unchanged)
|
||||||
const path = `
|
const path = `
|
||||||
M ${pods[0].x + 80} ${pods[0].y + 40}
|
M ${pods[0].x + 80} ${pods[0].y + 40}
|
||||||
L ${pods[1].x - 10} ${pods[1].y + 40}
|
L ${pods[1].x - 10} ${pods[1].y + 40}
|
||||||
@@ -34,7 +35,7 @@ export default function PodsFlow({
|
|||||||
L ${pods[3].x - 10} ${pods[3].y + 40}
|
L ${pods[3].x - 10} ${pods[3].y + 40}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Arrow segments
|
// Line segments
|
||||||
const arrows = [
|
const arrows = [
|
||||||
{
|
{
|
||||||
d: `M ${pods[0].x + 80} ${pods[0].y + 40} L ${pods[1].x - 6} ${pods[1].y + 40}`,
|
d: `M ${pods[0].x + 80} ${pods[0].y + 40} L ${pods[1].x - 6} ${pods[1].y + 40}`,
|
||||||
@@ -54,15 +55,13 @@ export default function PodsFlow({
|
|||||||
<div
|
<div
|
||||||
className={clsx("relative overflow-hidden", className)}
|
className={clsx("relative overflow-hidden", className)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
|
||||||
aria-label="Pod-to-Pod signal transfer animation"
|
|
||||||
style={{ background: "transparent" }}
|
style={{ background: "transparent" }}
|
||||||
>
|
>
|
||||||
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
|
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
|
||||||
{/* GRID BG */}
|
{/* GRID BACKGROUND */}
|
||||||
<defs>
|
<defs>
|
||||||
<pattern id="pods-grid" width="28" height="28" patternUnits="userSpaceOnUse">
|
<pattern id="pods-grid" width="26" height="26" patternUnits="userSpaceOnUse">
|
||||||
<path d="M 28 0 L 0 0 0 28" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.6" />
|
<path d="M 26 0 L 0 0 0 26" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.9" />
|
||||||
</pattern>
|
</pattern>
|
||||||
|
|
||||||
<filter id="pods-glow">
|
<filter id="pods-glow">
|
||||||
@@ -85,8 +84,8 @@ export default function PodsFlow({
|
|||||||
width={80}
|
width={80}
|
||||||
height={80}
|
height={80}
|
||||||
rx={14}
|
rx={14}
|
||||||
fill="#0d0d0d"
|
fill="#0f0f0f"
|
||||||
stroke="#1a1a1a"
|
stroke="#fff" // brighter stroke
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
initial={{ opacity: 0 }}
|
initial={{ opacity: 0 }}
|
||||||
animate={{ opacity: 0.9 }}
|
animate={{ opacity: 0.9 }}
|
||||||
@@ -94,7 +93,7 @@ export default function PodsFlow({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* POD LABELS */}
|
{/* POD TEXT */}
|
||||||
{pods.map((p, i) => (
|
{pods.map((p, i) => (
|
||||||
<motion.text
|
<motion.text
|
||||||
key={i}
|
key={i}
|
||||||
@@ -103,26 +102,26 @@ export default function PodsFlow({
|
|||||||
textAnchor="middle"
|
textAnchor="middle"
|
||||||
fontSize="14"
|
fontSize="14"
|
||||||
fontFamily="Inter, sans-serif"
|
fontFamily="Inter, sans-serif"
|
||||||
fill="#9ca3af"
|
fill="#fff" // lighter text
|
||||||
initial={{ opacity: 0 }}
|
initial={{ opacity: 0 }}
|
||||||
animate={{ opacity: 0.9 }}
|
animate={{ opacity: 0.95 }}
|
||||||
transition={{ delay: 0.1 + i * 0.1, duration: 0.6 }}
|
transition={{ delay: 0.1 + i * 0.1 }}
|
||||||
>
|
>
|
||||||
{p.label}
|
{p.label}
|
||||||
</motion.text>
|
</motion.text>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* GREY LINES */}
|
{/* GREY LINES (lighter) */}
|
||||||
{arrows.map((a, i) => (
|
{arrows.map((a, i) => (
|
||||||
<motion.path
|
<motion.path
|
||||||
key={`grey-${i}`}
|
key={`grey-${i}`}
|
||||||
d={a.d}
|
d={a.d}
|
||||||
stroke="#333"
|
stroke="#444" // lighter grey
|
||||||
strokeWidth={4}
|
strokeWidth={4}
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
fill="none"
|
fill="none"
|
||||||
initial={{ pathLength: 0, opacity: 0 }}
|
initial={{ pathLength: 0, opacity: 0 }}
|
||||||
animate={{ pathLength: 1, opacity: 0.8 }}
|
animate={{ pathLength: 1, opacity: 0.9 }}
|
||||||
transition={{ delay: 0.2 * i, duration: 0.7 }}
|
transition={{ delay: 0.2 * i, duration: 0.7 }}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@@ -143,7 +142,7 @@ export default function PodsFlow({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* NEW: CYAN ENDPOINT PULSES */}
|
{/* ENDPOINT PULSES */}
|
||||||
{arrows.map((a, i) => (
|
{arrows.map((a, i) => (
|
||||||
<motion.circle
|
<motion.circle
|
||||||
key={`endpoint-${i}`}
|
key={`endpoint-${i}`}
|
||||||
@@ -151,23 +150,21 @@ export default function PodsFlow({
|
|||||||
cy={a.end.y}
|
cy={a.end.y}
|
||||||
r={10}
|
r={10}
|
||||||
fill={accent}
|
fill={accent}
|
||||||
opacity={0.12}
|
opacity={0.16} // slightly stronger
|
||||||
filter="url(#pods-glow)"
|
filter="url(#pods-glow)"
|
||||||
initial={{ scale: 0.8, opacity: 0 }}
|
|
||||||
animate={{
|
animate={{
|
||||||
scale: [1, 1.2, 1],
|
scale: [1, 1.2, 1],
|
||||||
opacity: [0.05, 0.25, 0.05],
|
opacity: [0.08, 0.28, 0.08],
|
||||||
}}
|
}}
|
||||||
transition={{
|
transition={{
|
||||||
duration: 1.5,
|
duration: 1.4,
|
||||||
delay: i * 0.2,
|
delay: i * 0.2,
|
||||||
repeat: Infinity,
|
repeat: Infinity,
|
||||||
repeatType: "mirror",
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* MAIN MOVING CYAN PULSE */}
|
{/* PULSE DOT */}
|
||||||
<motion.circle
|
<motion.circle
|
||||||
r={8}
|
r={8}
|
||||||
fill={accent}
|
fill={accent}
|
||||||
@@ -178,10 +175,10 @@ export default function PodsFlow({
|
|||||||
initial={{ offsetDistance: "0%", opacity: 0.4 }}
|
initial={{ offsetDistance: "0%", opacity: 0.4 }}
|
||||||
animate={{
|
animate={{
|
||||||
offsetDistance: ["0%", "100%"],
|
offsetDistance: ["0%", "100%"],
|
||||||
opacity: [0.4, 1, 0.4],
|
opacity: [0.5, 1, 0.5],
|
||||||
}}
|
}}
|
||||||
transition={{
|
transition={{
|
||||||
duration: 2.6,
|
duration: 2.4,
|
||||||
repeat: Infinity,
|
repeat: Infinity,
|
||||||
ease: "linear",
|
ease: "linear",
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -15,6 +15,26 @@ export function CallToAction() {
|
|||||||
id="get-started"
|
id="get-started"
|
||||||
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
|
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">
|
<Container className="relative">
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export function StorageUseCases() {
|
|||||||
<P className="mt-6 text-gray-600">
|
<P className="mt-6 text-gray-600">
|
||||||
Mycelium Storage adapts to compliance-driven enterprise data,
|
Mycelium Storage adapts to compliance-driven enterprise data,
|
||||||
distributed application workloads, and global asset delivery
|
distributed application workloads, and global asset delivery
|
||||||
— without giving up sovereignty.
|
without giving up sovereignty.
|
||||||
</P>
|
</P>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export function StorageUseCasesNew() {
|
|||||||
<H3>Built for Real Data Workloads</H3>
|
<H3>Built for Real Data Workloads</H3>
|
||||||
<P className="max-w-3xl text-gray-600 mt-4">
|
<P className="max-w-3xl text-gray-600 mt-4">
|
||||||
Mycelium Storage adapts to compliance-driven enterprise data, distributed application workloads,
|
Mycelium Storage adapts to compliance-driven enterprise data, distributed application workloads,
|
||||||
and global asset delivery — without giving up sovereignty.
|
and global asset delivery without giving up sovereignty.
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
|
|||||||
@@ -228,3 +228,17 @@
|
|||||||
filter: drop-shadow(0 0 6px #90f6ff);
|
filter: drop-shadow(0 0 6px #90f6ff);
|
||||||
transition: opacity 1s ease-out;
|
transition: opacity 1s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes infinite-scroll {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-infinite-scroll {
|
||||||
|
animation: infinite-scroll var(--animation-duration, 40s) linear infinite;
|
||||||
|
animation-direction: var(--animation-direction, forwards);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user