feat: redesign cloud page with improved content structure and visual hierarchy

- Replaced CloudHostingNew with new CloudIntro component featuring tabbed interface for Kubernetes, VDC, and QSFS capabilities
- Added CloudCodeTabs component with interactive code examples and syntax highlighting
- Created CloudPros section highlighting platform architecture, reliability, compatibility, and scalability
- Updated hero section copy to emphasize sovereign edge infrastructure and simplified messaging
- Remove
This commit is contained in:
2025-11-14 18:15:04 +01:00
parent 326efc9fbd
commit 678da4b66c
9 changed files with 435 additions and 45 deletions

View File

@@ -0,0 +1,112 @@
"use client";
import { useState } from "react";
const files = [
{
id: "kube",
label: "kubernetes.yaml",
code: `apiVersion: apps/v1
kind: Deployment
metadata:
name: mycelium-app
spec:
replicas: 3
selector:
matchLabels:
app: mycelium-app
template:
metadata:
labels:
app: mycelium-app`,
},
{
id: "vdc",
label: "vdc.tf",
code: `provider "mycelium" {
identity = "~/.mycelium/id"
}
resource "mycelium_vdc" "production" {
name = "prod-vdc"
region = "eu-central"
nodes = 6
cpu_cores = 24
ram_gb = 128
storage = "10TB"
network_policies = ["private", "encrypted"]
}`,
},
{
id: "qsfs",
label: "qsfs.py",
code: `from qsfs import QSFS
# mount encrypted distributed filesystem
fs = QSFS.mount("/mnt/secure", key="my-private-key")
# write protected research data
with fs.open("dataset/raw-images/img001.png", "wb") as f:
f.write(b"...binary data...")
# list stored files via S3/IPFS/WebDAV compatibility layer
files = fs.list("dataset/raw-images/")
print("Stored files:", files)`,
},
];
export function CloudCodeTabs() {
const [active, setActive] = useState("kube");
const file = files.find((f) => f.id === active)!;
return (
<div className="sm:px-6 lg:px-0">
<div className="relative isolate overflow-hidden bg-cyan-600 px-6 pt-8 sm:mx-auto sm:max-w-2xl sm:rounded-md sm:pt-16 sm:pr-0 sm:pl-16 lg:mx-0 lg:max-w-none">
{/* Cyan skew background */}
<div
aria-hidden="true"
className="absolute -inset-y-px -left-3 -z-10 w-full origin-bottom-left skew-x-[-30deg] bg-cyan-500 opacity-20 ring-1 ring-white ring-inset"
/>
<div className="mx-auto max-w-2xl sm:mx-0 sm:max-w-none">
<div className="w-screen overflow-hidden rounded-tl-xl bg-[#121212] ring-1 ring-white/10">
{/* File Tabs */}
<div className="flex bg-gray-800/40 ring-1 ring-white/5">
<div className="-mb-px flex text-sm font-medium text-gray-400">
{files.map((f) => (
<button
key={f.id}
onClick={() => setActive(f.id)}
className={`px-4 py-2 border-r border-white/10 transition ${
active === f.id
? "border-b border-b-white/20 bg-white/5 text-white"
: "hover:text-white"
}`}
>
{f.label}
</button>
))}
</div>
</div>
{/* Code Block */}
<div className="px-6 pt-6 pb-14 font-mono text-xs leading-relaxed text-gray-200 whitespace-pre overflow-x-auto">
{file.code}
</div>
</div>
</div>
{/* Outer ring */}
<div
aria-hidden="true"
className="pointer-events-none absolute inset-0 ring-1 ring-white/10 ring-inset sm:rounded-3xl"
/>
</div>
</div>
);
}

View File

@@ -13,19 +13,17 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
<div className="px-6 py-16 lg:py-16"> <div className="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">
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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,7 @@ import { HomeMap } from './HomeMap'
import { HomeAudience } from './HomeAudience' 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 +36,7 @@ export default function HomePage() {
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<HomeAudience /> <HomeDesign />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>

View File

@@ -8,10 +8,10 @@ const highlights = [
'Connectivity flows directly between users, nodes, and services without platform ownership.', 'Connectivity flows directly between users, nodes, and services without platform ownership.',
}, },
{ {
label: 'Identity', label: 'Platform',
title: 'One identity across all capabilities.', title: 'One unified platform for compute, storage, and orchestration.',
description: description:
'A single cryptographic identity governs your network, storage, agents, and deployments.', 'Runs reliably across distributed environments. Works with your existing tools and workflows. Scales from small projects to full environments.',
}, },
{ {
label: 'Scale', label: 'Scale',
@@ -27,32 +27,33 @@ const highlights = [
}, },
] ]
export function NetworkPros() { export function CloudPros() {
return ( return (
<section className="relative w-full bg-[#121212] overflow-hidden"> <section className="relative w-full bg-[#FDFDFD] overflow-hidden">
{/* Top horizontal line with spacing */} {/* Top spacing line */}
<div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div> <div className="max-w-7xl bg-[#FDFDFD] mx-auto py-6 border border-t-0 border-b-0 border-gray-200"></div>
<div className="w-full border-t border-l border-r border-gray-800" /> <div className="w-full border-t border-l border-r border-gray-200" />
<div className="bg-[#121212] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-800"> <div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-200">
<div className="grid lg:grid-cols-4"> <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-white/10 bg-white/4 p-8 backdrop-blur-sm transition hover:border-cyan-300/50 hover:bg-white/8" className="group relative overflow-hidden border border-gray-200 bg-white p-8 transition hover:border-cyan-400/40 hover:bg-white"
> >
<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" /> {/* Hover glow */}
<div className="absolute inset-0 bg-linear-to-br from-cyan-200/0 via-cyan-100/20 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative"> <div className="relative">
<Small className="text-xs uppercase tracking-[0.16em] text-cyan-200"> <Small className="text-xs uppercase tracking-[0.16em] text-cyan-600">
{item.label} {item.label}
</Small> </Small>
<h3 className="mt-4 text-lg font-semibold leading-tight text-white"> <h3 className="mt-4 text-lg font-semibold leading-tight text-black">
{item.title} {item.title}
</h3> </h3>
<p className="mt-4 text-sm leading-relaxed text-gray-300"> <p className="mt-4 text-sm leading-relaxed text-gray-600">
{item.description} {item.description}
</p> </p>
</div> </div>
@@ -61,8 +62,8 @@ export function NetworkPros() {
</div> </div>
</div> </div>
<div className="w-full border-b border-gray-800 bg-[#121212]" /> <div className="w-full border-b border-gray-200 bg-[#FDFDFD]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" /> <div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
</section> </section>
) )
} }