9 Commits

Author SHA1 Message Date
57c39a8b2b feat: refactor pods page with simplified content and improved animations
- Added agent1.png image asset
- Refactored InfiniteMovingCards component with cleaner animation logic and improved duplication handling
- Changed default speed from "fast" to "slow" and simplified animation setup
- Updated AgentBento title from "Augmented Intelligence Fabric" to "Intelligence Fabric"
- Increased Homepod vertical padding on large screens (lg:py-16 to lg:py-24)
- Removed "Feature" label from PodsFeatures use
2025-11-17 14:39:23 +01:00
6ff539b3fc feat: add AgentPro section and refactor AgentUsecase layout
- Created AgentPro component highlighting local execution, mesh connectivity, private data access, and portability advantages
- Replaced horizontal scrolling carousel in AgentUsecase with responsive grid layout
- Added "Blend local + remote intelligence" use case to AgentUsecase
- Removed slider navigation buttons and replaced with static grid display
- Replaced AgentDesign with AgentPro in AgentsPage component order
- Increased hero section padding on
2025-11-17 14:12:17 +01:00
29e2d942de refactor: improve punctuation and grammar consistency across components
- Replaced em dashes with commas for better readability in descriptions
- Standardized punctuation in aria-labels (changed "—" to ",")
- Removed unnecessary em dashes in favor of commas or removed punctuation
- Fixed inconsistent spacing around punctuation marks
- Improved sentence flow in multiple component descriptions
2025-11-17 13:52:42 +01:00
def0972762 feat: streamline cloud and pods pages with improved CTAs and content
- Replaced CloudCodeTabs with static reserve image in CloudIntro
- Added dynamic action buttons (Deploy, Follow Development, View Docs) to CloudIntro tabs
- Removed CloudFeaturesLight section from CloudPage
- Enhanced Pods CallToAction with benefits checklist and expanded early adopter messaging
- Added CTA buttons to Homepod component with waitlist and docs links
- Removed PodsBenefits section from PodsPage
- Updated Homepod description
2025-11-17 13:01:56 +01:00
1c37cc08ee feat: add network download section and update network page styling
- Created NetworkDownload component with platform-specific download cards for iOS, macOS, Windows, Android, and Linux
- Added hover effects and external links to app stores and GitHub releases
- Replaced NetworkUsecases with NetworkDownload in NetworkPage component order
- Renamed CloudPros to NetworkPros for consistency
- Updated NetworkPros styling from light theme to dark theme with improved contrast and hover states
- Change
2025-11-17 12:44:23 +01:00
0eef2cd013 feat: add scroll-to-top behavior and hash anchor navigation
- Added ScrollToTop component to handle navigation scroll behavior
- Implemented smooth scrolling to hash anchors when present in URL
- Added automatic scroll to top on route changes
- Imported useLocation and useEffect hooks for scroll management
2025-11-17 12:27:24 +01:00
3cd41ab1d9 refactor: simplify hero section with updated typography and spacing
- Replaced H1 with H3 and added Eyebrow component for "Project MYCELIUM" label
- Removed promotional banner about booking a call
- Improved text hierarchy and reduced vertical spacing (mt-8 to mt-4)
- Added max-width constraint to description text for better readability
- Removed unused H3Icon import
2025-11-17 12:23:27 +01:00
3121251272 refactor: remove unused imports and add icon null check
- Removed unused ShieldCheckIcon import from NodeProducts
- Removed unused Small component import from NodeSpecs
- Added conditional rendering for Icon in PodsWhat to prevent errors when icon is undefined
2025-11-14 22:59:24 +01:00
56ceac1319 refactor: remove dark mode styling from agent and home pages
- Simplified styling by removing dark mode classes (dark:bg-*, dark:text-*, dark:border-*)
- Added explicit text color classes for better consistency
- Fixed animation container layout with proper centering and sizing
2025-11-14 22:51:19 +01:00
48 changed files with 648 additions and 373 deletions

BIN
public/images/agent1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 KiB

View File

@@ -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'));
@@ -13,9 +13,29 @@ const GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
const PodsPage = lazy(() => import('./pages/pods/PodsPage')); const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
const NodesPage = lazy(() => import('./pages/nodes/NodesPage')); 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 />}>

View File

@@ -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>
))} ))}

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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">

View 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 Its 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>
);
}

View File

@@ -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>
); );
} }

View File

@@ -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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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 whats 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 whats 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>

View File

@@ -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 dont need with compute, storage, and networking built in, so you dont need
external cloud dependencies. external cloud dependencies.
</P> </P>
</div> </div>

View File

@@ -18,7 +18,7 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
<H3 className="mt-4"> <H3 className="mt-4">
Sovereign Edge Cloud Infrastructure Sovereign Edge Cloud Infrastructure
</H3> </H3>
<p className="mt-6 text-lg"> <p className="mt-6 text-lg text-gray-600">
Run compute, storage, and AI resources on infrastructure you control. Run compute, storage, and AI resources on infrastructure you control.
</p> </p>
<p className="mt-4 text-lg text-gray-600"> <p className="mt-4 text-lg text-gray-600">

View File

@@ -1,8 +1,8 @@
"use client"; "use client";
import { useState } from "react"; import { useState } from "react";
import { CloudCodeTabs } from "./CloudCodeTabs";
import { Eyebrow, H3, P } from "@/components/Texts"; import { Eyebrow, H3, P } from "@/components/Texts";
import { Button } from "@/components/Button";
const tabs = [ const tabs = [
{ {
@@ -59,9 +59,25 @@ const tabs = [
}, },
]; ];
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() { export function CloudIntro() {
const [active, setActive] = useState("kubernetes"); const [active, setActive] = useState("kubernetes");
const current = tabs.find((t) => t.id === active)!.content; const current = tabs.find((t) => t.id === active)!.content;
const currentButtons = tabButtons[active as keyof typeof tabButtons];
return ( return (
<section className="relative w-full bg-[#121212] overflow-hidden"> <section className="relative w-full bg-[#121212] overflow-hidden">
@@ -80,7 +96,7 @@ export function CloudIntro() {
<H3 color="white">What You Can Run on Mycelium Cloud</H3> <H3 color="white">What You Can Run on Mycelium Cloud</H3>
<P className="max-w-3xl text-gray-400 mt-6"> <P className="max-w-3xl text-gray-400 mt-6">
Host nodes, deploy workloads, or build private AI systems all on Host nodes, deploy workloads, or build private AI systems all on
infrastructure you own and control. Mycelium gives you scalable compute, infrastructure you own and control. Mycelium gives you scalable compute,
secure storage, and sovereign orchestration without depending on secure storage, and sovereign orchestration without depending on
hyperscalers. hyperscalers.
@@ -94,7 +110,11 @@ export function CloudIntro() {
{/* Left: Code UI */} {/* Left: Code UI */}
<div className="w-full lg:w-1/2"> <div className="w-full lg:w-1/2">
<CloudCodeTabs /> <img
src="/images/cloud/reserve.png"
alt="Mycelium Cloud reserve"
className="w-full h-auto rounded-xl border border-white/10 object-cover"
/>
</div> </div>
{/* Right: Tabs */} {/* Right: Tabs */}
@@ -141,6 +161,26 @@ export function CloudIntro() {
</ul> </ul>
</div> </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>
</div> </div>

View File

@@ -2,7 +2,6 @@ import { AnimatedSection } from '../../components/AnimatedSection'
import { CloudHeroNew } from './CloudHeroNew' import { CloudHeroNew } from './CloudHeroNew'
import { CallToAction } from './CalltoAction' import { CallToAction } from './CalltoAction'
import { CloudIntro } from './CloudIntro' import { CloudIntro } from './CloudIntro'
import { CloudFeaturesLight } from './CloudFeaturesLight'
import { CloudPros } from './CloudPros' import { CloudPros } from './CloudPros'
@@ -18,10 +17,6 @@ export default function CloudPage() {
<CloudIntro /> <CloudIntro />
</AnimatedSection> </AnimatedSection>
<AnimatedSection>
<CloudFeaturesLight />
</AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CloudPros /> <CloudPros />
</AnimatedSection> </AnimatedSection>

View File

@@ -1,47 +1,66 @@
import { Small } from '@/components/Texts' import { Small } from "@/components/Texts";
const highlights = [ const highlights = [
{ {
label: 'Platform Architecture', label: "Local Execution",
title: 'Unified compute, storage & orchestration.', title: "Agents run entirely inside your environment.",
description: description:
'One unified platform for compute, storage, and orchestration.', "Models, logic, and memory stay within your own trusted hardware—never behind third-party APIs.",
}, },
{ {
label: 'Reliability', label: "Mesh Connectivity",
title: 'Consistent performance everywhere.', title: "They communicate peer-to-peer across trusted nodes.",
description: description:
'Runs reliably across distributed environments.', "Agents form direct encrypted paths between environments, without relays or central servers.",
}, },
{ {
label: 'Compatibility', label: "Private Data Access",
title: 'Works with your existing stack.', title: "They use your data without sending it elsewhere.",
description: description:
'Works with your existing tools and workflows.', "Your datasets, embeddings, and context never leave your boundaries—processing stays local.",
}, },
{ {
label: 'Scalability', label: "Portability",
title: 'Grows with your needs.', title: "They move with you, not with a cloud provider.",
description: description:
'Scales from small projects to full environments.', "Agents follow your devices, networks, and workflows, remaining sovereign across every location.",
}, },
] ];
export function CloudPros() { export function AgentPro() {
return ( return (
<section className="relative w-full bg-[#FDFDFD] overflow-hidden"> <section className="relative w-full bg-[#FDFDFD] overflow-hidden">
{/* Top spacing line */} {/* 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="max-w-7xl bg-[#FDFDFD] mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-100" /> <div className="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="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 Its 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
architecturerunning entirely inside your environment so control,
privacy, and autonomy stay with you.
</p>
</div>
{/* Grid */}
<div className="grid lg:grid-cols-4"> <div className="grid lg:grid-cols-4">
{highlights.map((item) => ( {highlights.map((item) => (
<div <div
key={item.title} 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" className="group relative overflow-hidden border border-gray-100 bg-white p-8 transition hover:border-cyan-400/40 hover:bg-white"
> >
{/* Hover glow */} {/* 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="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"> <div className="relative">
@@ -62,8 +81,9 @@ export function CloudPros() {
</div> </div>
</div> </div>
{/* Bottom spacing */}
<div className="w-full border-b border-gray-100 bg-[#FDFDFD]" /> <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" /> <div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
</section> </section>
) );
} }

View File

@@ -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>

View File

@@ -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 thats more resilient and private than the cloud. on a fabric thats more resilient and private than the cloud.
</P> </P>
</div> </div>

View File

@@ -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>

View File

@@ -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",

View File

@@ -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>&rarr;</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"

View File

@@ -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">

View File

@@ -26,19 +26,19 @@ const benefits = [
export function HomeDesign() { export function HomeDesign() {
return ( return (
<section className="w-full max-w-8xl mx-auto bg-white dark:bg-transparent"> <section className="w-full max-w-8xl mx-auto bg-white">
{/* Top spacing line */} {/* Top spacing line */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200 dark:border-gray-800" /> <div className="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 dark:border-gray-800" /> <div className="w-full border border-l border-r border-gray-200" />
{/* Content */} {/* Content */}
<div className="mx-auto max-w-7xl border-gray-200 dark:border-gray-800"> <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"> <dl className="grid grid-cols-1 lg:grid-cols-3 gap-4 lg:gap-0">
{benefits.map((item) => ( {benefits.map((item) => (
<div <div
key={item.id} key={item.id}
className="group flex items-start gap-2 bg-white/40 dark:bg-black/40 px-8 py-12 border border-gray-200 dark:border-gray-800 lg:border-t-0 lg:border-b-0" 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 */} {/* Image on the LEFT */}
<img <img
@@ -49,10 +49,10 @@ export function HomeDesign() {
{/* Text on the RIGHT */} {/* Text on the RIGHT */}
<div className="text-left"> <div className="text-left">
<h3 className="text-base font-semibold tracking-wide text-gray-900 dark:text-white mb-2"> <h3 className="text-base font-semibold tracking-wide text-gray-900 mb-2">
{item.title} {item.title}
</h3> </h3>
<p className="text-sm text-gray-600 dark:text-gray-300 leading-relaxed max-w-xs"> <p className="text-sm text-gray-600 leading-relaxed max-w-xs">
{item.description} {item.description}
</p> </p>
</div> </div>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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,
}, },

View 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 networkseamlessly 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>
)
}

View File

@@ -5,8 +5,8 @@ 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 { CloudPros } from './NetworkPros' import { NetworkPros } from './NetworkPros'
export default function NetworkPage() { export default function NetworkPage() {
@@ -33,14 +33,14 @@ export default function NetworkPage() {
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CloudPros /> <NetworkPros />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<NetworkUsecases /> <NetworkDownload />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CallToAction /> <CallToAction />
</AnimatedSection> </AnimatedSection>

View File

@@ -17,7 +17,7 @@ const highlights = [
label: 'Scale', label: 'Scale',
title: 'Scales instantly from one POD to thousands.', title: 'Scales instantly from one POD to thousands.',
description: description:
'Deploy locally or expand globally the mesh routes and balances itself automatically.', 'Deploy locally or expand globally, the mesh routes and balances itself automatically.',
}, },
{ {
label: 'Security', label: 'Security',
@@ -27,33 +27,34 @@ const highlights = [
}, },
] ]
export function CloudPros() { export function NetworkPros() {
return ( return (
<section className="relative w-full bg-[#FDFDFD] overflow-hidden"> <section className="bg-[#121212] w-full max-w-8xl mx-auto">
{/* Top spacing line */} {/* Top spacing line */}
<div className="max-w-7xl bg-[#FDFDFD] mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div> <div className="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-200" /> <div className="w-full border-t border-l border-r border-gray-800" />
<div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-200"> {/* 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"> <div className="grid lg:grid-cols-4">
{highlights.map((item) => ( {highlights.map((item) => (
<div <div
key={item.title} key={item.title}
className="group relative overflow-hidden border border-gray-200 bg-white p-8 transition hover:border-cyan-400/40 hover:bg-white" 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 */} {/* Hover glow */}
<div className="absolute inset-0 bg-linear-to-br from-cyan-200/0 via-cyan-100/20 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" /> <div className="absolute inset-0 bg-linear-to-br from-cyan-500/0 via-white/5 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative"> <div className="relative">
<Small className="text-xs uppercase tracking-[0.16em] text-cyan-600"> <Small className="text-xs uppercase tracking-[0.16em] text-cyan-200">
{item.label} {item.label}
</Small> </Small>
<h3 className="mt-4 text-lg font-semibold leading-tight text-black"> <h3 className="mt-4 text-lg font-semibold text-white">
{item.title} {item.title}
</h3> </h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600"> <p className="mt-4 text-sm leading-relaxed text-gray-300">
{item.description} {item.description}
</p> </p>
</div> </div>
@@ -62,8 +63,9 @@ export function CloudPros() {
</div> </div>
</div> </div>
<div className="w-full border-b border-gray-200 bg-[#FDFDFD]" /> {/* Bottom 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-b border-gray-800 bg-[#121212]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
</section> </section>
) )
} }

View File

@@ -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>

View File

@@ -18,7 +18,7 @@ export function NodeHero() {
<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-lg"> <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 gap-x-6">

View File

@@ -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";

View File

@@ -1,7 +1,6 @@
"use client"; "use client";
import { Container } from "@/components/Container"; import { Container } from "@/components/Container";
import { Small } from "@/components/Texts";
// Heroicons // Heroicons
import { import {

View File

@@ -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 (
@@ -38,11 +48,36 @@ export function CallToAction() {
<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 */}
@@ -55,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>

View File

@@ -1,6 +1,10 @@
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 */}
@@ -9,7 +13,7 @@ export default function Homepod() {
style={{ backgroundImage: "url('/images/computehero11.webp')", 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.
Its 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>

View File

@@ -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" />

View File

@@ -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.
💡 Its like having your own tiny cloud that belongs only to you. 💡 Its 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>

View File

@@ -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>

View File

@@ -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,9 +106,6 @@ 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 */}

View File

@@ -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,&nbsp;
<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 dont 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>

View File

@@ -2,7 +2,6 @@ import Homepod from './Homepod';
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 { CallToAction } from './CallToAction'; import { CallToAction } from './CallToAction';
import { PodsWhat } from './PodsWhat'; import { PodsWhat } from './PodsWhat';
@@ -14,7 +13,6 @@ const PodsPage = () => {
<PodsFeatures /> <PodsFeatures />
<PodsHow /> <PodsHow />
<PodsDesign /> <PodsDesign />
<PodsBenefits />
<CallToAction /> <CallToAction />
</> </>
); );

View File

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

View File

@@ -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",
}} }}

View File

@@ -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>

View File

@@ -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 */}

View File

@@ -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);
}