refactor: convert agent bento cards from videos to React animation components

- Replaced video paths with imported animation components (Fungistor, Herodb, MOSSandboxes, etc.)
- Added new AgentDesign and AgentUseCase sections to agents page
- Updated hero copy to emphasize private, sovereign AI and 2026 timeline
- Reorganized page layout with new sections between existing components
This commit is contained in:
2025-11-13 15:24:46 +01:00
parent 7b80ab84c9
commit b208fe7f2a
18 changed files with 1770 additions and 36 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,11 +18,14 @@ export function CallToAction() {
<Container className="relative">
<div className="mx-auto max-w-3xl text-center">
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
Start Building the Future of Sovereign AI
Start with Mycelium Today
</h2>
<p className="mt-6 text-lg text-gray-300">
Use todays components models, storage, compute, mesh and step into agents as they arrive.
The Agent Framework launches in H1 2026, but the foundation is ready now.
</p>
<p className="mt-6 text-lg text-gray-300">
Use todays components models, storage, compute, and network to deploy workloads, connect nodes, and prepare for the next generation of distributed AI.
</p>
{/* ✅ Two cards, stacked center with spacing */}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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