forked from emre/www_projectmycelium_com
feat: redesign compute page sections with interactive code examples
- Replaced static use cases section with tabbed interface showing AI/ML, application hosting, and edge compute capabilities - Added ComputeCodeTabs component with interactive code examples (train.py, deploy.yaml, edge.ts) - Updated CallToAction section with new bordered layout and restructured CTA buttons for hosting and deploying
This commit is contained in:
@@ -1,42 +1,55 @@
|
|||||||
import { CircleBackground } from '../../components/CircleBackground'
|
"use client";
|
||||||
import { Container } from '@/components/Container'
|
|
||||||
import { Button } from '@/components/Button'
|
import { Container } from "@/components/Container";
|
||||||
|
import { Button } from "@/components/Button";
|
||||||
|
|
||||||
export function CallToAction() {
|
export function CallToAction() {
|
||||||
return (
|
return (
|
||||||
<section
|
<section className="relative overflow-hidden bg-gray-900">
|
||||||
id="get-started"
|
{/* ✅ Top horizontal line with spacing */}
|
||||||
className="relative overflow-hidden bg-gray-900 py-20 sm:py-28"
|
<div className="max-w-7xl bg-[#090909] mx-auto py-6 border border-t-0 border-b-0 border-gray-700"></div>
|
||||||
>
|
<div className="w-full border-t border-l border-r border-gray-700" />
|
||||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
|
||||||
<CircleBackground color="#06b6d4" className="animate-spin-slower" />
|
|
||||||
</div>
|
|
||||||
<Container className="relative">
|
|
||||||
<div className="mx-auto max-w-2xl text-center">
|
|
||||||
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
|
||||||
Choose How You Want to Start
|
|
||||||
</h2>
|
|
||||||
<p className="mt-6 text-lg text-gray-300">
|
|
||||||
Run workloads using Mycelium Cloud, or host your own compute node.
|
|
||||||
Both use the same deterministic execution fabric.
|
|
||||||
|
|
||||||
</p>
|
{/* ✅ Main boxed area */}
|
||||||
<div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4">
|
<div
|
||||||
<Button to="/download" variant="solid" color="white">
|
id="get-started"
|
||||||
Deploy Workloads
|
className="relative py-18 max-w-7xl mx-auto bg-[#090909] border border-t-0 border-b-0 border-gray-700"
|
||||||
</Button>
|
>
|
||||||
<Button
|
|
||||||
to="https://threefold.info/mycelium_network/docs/"
|
|
||||||
as="a"
|
<Container className="relative">
|
||||||
target="_blank"
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
variant="outline"
|
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
|
||||||
color="white"
|
Choose How You Want to Start
|
||||||
>
|
</h2>
|
||||||
Host A Node
|
|
||||||
</Button>
|
<p className="mt-6 text-lg text-gray-300">
|
||||||
|
Host your own node to contribute capacity or deploy workloads using the Mycelium Cloud.
|
||||||
|
You don’t need to host before deploying, and you don’t need to deploy before hosting.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* ✅ Two cards, stacked center with spacing */}
|
||||||
|
<div className="mt-10 flex flex-wrap justify-center gap-x-10 gap-y-8">
|
||||||
|
<div className="flex flex-col items-center text-center max-w-xs">
|
||||||
|
<Button to="/host" variant="solid" color="cyan" className="mt-4">
|
||||||
|
Host a Node
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col items-center text-center max-w-xs">
|
||||||
|
<Button to="/cloud" variant="outline" color="white" className="mt-4">
|
||||||
|
Start Deploying
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Container>
|
||||||
</Container>
|
</div>
|
||||||
|
|
||||||
|
{/* ✅ Bottom horizontal line with spacing */}
|
||||||
|
<div className="w-full border-b border-gray-700" />
|
||||||
|
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-700 bg-transparent" />
|
||||||
</section>
|
</section>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ export function ComputeCapabilitiesNew() {
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full border-b border-gray-800" />
|
<div className="w-full border-b border-gray-800" />
|
||||||
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
|
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
112
src/pages/compute/ComputeCodeTabs.tsx
Normal file
112
src/pages/compute/ComputeCodeTabs.tsx
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
const files = [
|
||||||
|
{
|
||||||
|
id: "train",
|
||||||
|
label: "train.py",
|
||||||
|
code: `from mycelium import GPUCluster, Dataset
|
||||||
|
|
||||||
|
# connect to private GPU cluster
|
||||||
|
cluster = GPUCluster("secure://my-node")
|
||||||
|
|
||||||
|
# load training data
|
||||||
|
data = Dataset.load("s3://models/private-dataset")
|
||||||
|
|
||||||
|
# run a reproducible training job
|
||||||
|
job = cluster.train(
|
||||||
|
model="resnet50",
|
||||||
|
dataset=data,
|
||||||
|
epochs=40,
|
||||||
|
deterministic=True
|
||||||
|
)
|
||||||
|
|
||||||
|
job.save("s3://models/checkpoints/resnet-private")`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "deploy",
|
||||||
|
label: "deploy.yaml",
|
||||||
|
code: `apiVersion: mycelium/v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: vector-api
|
||||||
|
spec:
|
||||||
|
image: registry.mycelium/vector:latest
|
||||||
|
replicas: 3
|
||||||
|
selfHeal: true
|
||||||
|
mesh: private
|
||||||
|
resources:
|
||||||
|
gpu: 1
|
||||||
|
cpu: 2
|
||||||
|
memory: 4Gi`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "edge",
|
||||||
|
label: "edge.ts",
|
||||||
|
code: `import { EdgeClient } from "@mycelium/sdk"
|
||||||
|
|
||||||
|
// deploy inference to nearest node
|
||||||
|
const client = new EdgeClient()
|
||||||
|
|
||||||
|
await client.deploy({
|
||||||
|
model: "resnet-private",
|
||||||
|
region: "eu-home-nodes",
|
||||||
|
autoscale: true,
|
||||||
|
cache: "on-device"
|
||||||
|
})`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function ComputeCodeTabs() {
|
||||||
|
const [active, setActive] = useState("train");
|
||||||
|
const file = files.find((f) => f.id === active)!;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="sm:px-6 lg:px-0">
|
||||||
|
<div className="relative isolate overflow-hidden bg-indigo-500 px-6 pt-8 sm:mx-auto sm:max-w-2xl sm:rounded-3xl sm:pt-16 sm:pr-0 sm:pl-16 lg:mx-0 lg:max-w-none">
|
||||||
|
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
className="absolute -inset-y-px -left-3 -z-10 w-full origin-bottom-left skew-x-[-30deg] bg-indigo-100 opacity-20 ring-1 ring-white ring-inset"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="mx-auto max-w-2xl sm:mx-0 sm:max-w-none">
|
||||||
|
<div className="w-screen overflow-hidden rounded-tl-xl bg-gray-900 ring-1 ring-white/10">
|
||||||
|
|
||||||
|
{/* FILE TABS */}
|
||||||
|
<div className="flex bg-gray-800/40 ring-1 ring-white/5">
|
||||||
|
<div className="-mb-px flex text-sm font-medium text-gray-400">
|
||||||
|
|
||||||
|
{files.map((f) => (
|
||||||
|
<button
|
||||||
|
key={f.id}
|
||||||
|
onClick={() => setActive(f.id)}
|
||||||
|
className={`px-4 py-2 border-r border-white/10 ${
|
||||||
|
active === f.id
|
||||||
|
? "border-b border-b-white/20 bg-white/5 text-white"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{f.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* CODE BLOCK */}
|
||||||
|
<div className="px-6 pt-6 pb-14 font-mono text-xs leading-relaxed text-gray-200 whitespace-pre overflow-x-auto">
|
||||||
|
{file.code}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
className="pointer-events-none absolute inset-0 ring-1 ring-white/10 ring-inset sm:rounded-3xl"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,53 +1,137 @@
|
|||||||
import { Container } from '@/components/Container'
|
"use client";
|
||||||
import { Eyebrow, SectionHeader } from '@/components/Texts'
|
|
||||||
|
|
||||||
const useCases = [
|
import { useState } from "react";
|
||||||
|
import { ComputeCodeTabs } from "./ComputeCodeTabs"; // ✅ Make sure path is correct
|
||||||
|
import { Eyebrow, SectionHeader, H3, P } from "@/components/Texts";
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
{
|
{
|
||||||
title: 'AI / ML Training',
|
id: "ai",
|
||||||
description:
|
label: "AI / ML TRAINING",
|
||||||
'Reproducible pipelines, private model execution, scalable GPU orchestration.',
|
content: [
|
||||||
|
{
|
||||||
|
item: "Reproducible pipelines",
|
||||||
|
desc: "Build deterministic, version-locked training pipelines that produce the same result every time.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
|
||||||
|
item: "Private model execution",
|
||||||
|
desc: "Train sensitive models on hardware you control, keeping datasets and checkpoints off hyperscalers.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Scalable GPU orchestration",
|
||||||
|
desc: "Scale training and inference across decentralized GPU nodes with automated orchestration.",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Application Hosting',
|
id: "apps",
|
||||||
description:
|
label: "APPLICATION HOSTING",
|
||||||
'Private, reliable, self-healing services – without cloud vendor lock-in.',
|
content: [
|
||||||
|
{
|
||||||
|
item: "Self-healing services",
|
||||||
|
desc: "Private, reliable services that repair automatically without cloud vendor lock-in.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Zero cloud lock-in",
|
||||||
|
desc: "Deploy containers, VMs, or full Kubernetes clusters — migrate off AWS/GCP/Azure with no code changes.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Encrypted networking",
|
||||||
|
desc: "All services communicate through Mycelium Mesh — no VPNs, no exposed ports.",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Distributed & Edge Compute',
|
id: "edge",
|
||||||
description:
|
label: "DISTRIBUTED & EDGE COMPUTE",
|
||||||
'Run workloads where data lives, in homes, offices, datacenters, or remote regions.',
|
content: [
|
||||||
|
{
|
||||||
|
item: "Distributed workloads",
|
||||||
|
desc: "Run compute where data lives — homes, factories, hospitals, or remote regions.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Offline-first resilience",
|
||||||
|
desc: "Nodes keep working even with weak internet or outages — ideal for mission-critical edge.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Global deployment, local data",
|
||||||
|
desc: "Keep data in-country or on-prem for compliance, privacy, and regulated industries.",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
export function ComputeUseCases() {
|
export function ComputeUseCases() {
|
||||||
|
const [active, setActive] = useState("ai");
|
||||||
|
const current = tabs.find((t) => t.id === active)!;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="bg-gray-950 py-24 sm:py-32">
|
<section className="relative w-full bg-[#171717] overflow-hidden">
|
||||||
<Container>
|
{/* ✅ Top horizontal line with spacing */}
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
|
||||||
<Eyebrow color="accent" className="tracking-[0.32em] uppercase">
|
<div className="w-full border-t border-l border-r border-gray-800" />
|
||||||
|
|
||||||
|
<div className="max-w-7xl mx-auto px-6 lg:px-8 py-12 border border-t-0 border-b-0 border-gray-800 bg-[#111111] overflow-hidden">
|
||||||
|
|
||||||
|
{/* ✅ H3 on own row */}
|
||||||
|
<div className="mb-16">
|
||||||
|
<Eyebrow color="accent" className="">
|
||||||
Use Cases
|
Use Cases
|
||||||
</Eyebrow>
|
</Eyebrow>
|
||||||
<SectionHeader as="h2" color="light" className="mt-6">
|
<H3 color="white">
|
||||||
Built for Serious Workloads
|
Built for Serious Workloads
|
||||||
</SectionHeader>
|
</H3>
|
||||||
|
<P className="max-w-3xl text-gray-400 mt-6">
|
||||||
|
Mycelium Compute is a decentralized physical infrastructure network
|
||||||
|
(DePIN) for high-performance workloads. Run reproducible AI/ML
|
||||||
|
pipelines, host self-healing applications, or deploy to the edge — all
|
||||||
|
on a fabric that’s more resilient and private than the cloud.
|
||||||
|
</P>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx-auto mt-16 max-w-4xl space-y-6">
|
{/* ✅ Two-column layout */}
|
||||||
{useCases.map((useCase) => (
|
<div className="flex flex-col lg:flex-row gap-16">
|
||||||
<div
|
|
||||||
key={useCase.title}
|
{/* ✅ Replace image with CodeTabs */}
|
||||||
className="rounded-3xl border border-white/10 bg-white/5 p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-200/40 hover:bg-white/10"
|
<div className="w-full lg:w-1/2">
|
||||||
>
|
<ComputeCodeTabs />
|
||||||
<h3 className="text-xl font-semibold text-white">
|
</div>
|
||||||
{useCase.title}
|
|
||||||
</h3>
|
{/* ✅ Right side tabs & content */}
|
||||||
<p className="mt-3 text-sm leading-relaxed text-gray-200">
|
<div className="w-full lg:w-1/2 text-white">
|
||||||
{useCase.description}
|
|
||||||
</p>
|
{/* Tabs Nav */}
|
||||||
|
<div className="flex gap-6 border-b border-white/10 pb-2">
|
||||||
|
{tabs.map((tab) => (
|
||||||
|
<button
|
||||||
|
key={tab.id}
|
||||||
|
onClick={() => setActive(tab.id)}
|
||||||
|
className={`text-sm font-medium tracking-wide pb-2 ${
|
||||||
|
active === tab.id
|
||||||
|
? "border-b-2 border-cyan-500 text-white"
|
||||||
|
: "text-gray-400 hover:text-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{tab.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
|
||||||
|
{/* Tab Content */}
|
||||||
|
<div className="mt-6 space-y-6">
|
||||||
|
{current.content.map((c, i) => (
|
||||||
|
<div key={i} className="space-y-1">
|
||||||
|
<p className="text-base font-medium text-white">{c.item}</p>
|
||||||
|
<p className="text-sm text-gray-400 leading-relaxed">{c.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</div>
|
||||||
|
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
|
||||||
|
<div className="w-full border-b border-gray-800" />
|
||||||
</section>
|
</section>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user