feat: add Pods capabilities and how-it-works sections

- Created PodsCapabilities component showcasing four key features (communicate, organization, manage, storage) with icon-based layout
- Added PodsHow section with CloudPods animation demonstrating pod-to-pod communication concept
- Implemented animated CloudPods visualization with inter-cluster data flow and pulsing effects
This commit is contained in:
2025-11-12 12:49:16 +01:00
parent 8276ede9fd
commit aab7e66f29
5 changed files with 345 additions and 1 deletions

View File

@@ -0,0 +1,92 @@
import {
ChatBubbleLeftRightIcon,
CalendarDaysIcon,
UserGroupIcon,
ShieldCheckIcon,
} from '@heroicons/react/24/solid'
import { Eyebrow, H3, P } from '@/components/Texts'
export function PodsCapabilities() {
return (
<section className="w-full max-w-8xl mx-auto bg-[#121212]">
{/* ✅ 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-800"></div>
<div className="w-full border-t border-l border-r border-gray-800" />
{/* ✅ Main content */}
<div className="mx-auto max-w-7xl px-6 bg-[#111111] lg:px-8 grid grid-cols-1 lg:grid-cols-2 gap-20 py-12 border border-t-0 border-b-0 border-gray-800">
{/* ✅ LEFT SIDE — Title + Intro */}
<div className="max-w-xl ">
<Eyebrow>What You Can Do</Eyebrow>
<H3 className="mt-6 text-white">
Pods Features
</H3>
<P className="mt-6 text-gray-200">
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.
</P>
</div>
{/* ✅ RIGHT SIDE — 4 stacked features */}
<div className="space-y-8">
{/* 1 — Communicate */}
<div>
<h3 className="text-lg font-semibold text-white flex items-center">
<ChatBubbleLeftRightIcon className="h-6 w-6 text-cyan-500 mr-3" />
Communicate
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Message, call, and share files privately no tracking or ads.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
{/* 2 — Organization */}
<div>
<h3 className="text-lg font-semibold text-white flex items-center">
<CalendarDaysIcon className="h-6 w-6 text-cyan-500 mr-3" />
Organization
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Organize your calendar and meetings inside your own space.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
{/* 3 — Manage */}
<div>
<h3 className="text-lg font-semibold text-white flex items-center">
<UserGroupIcon className="h-6 w-6 text-cyan-500 mr-3" />
Manage
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Create small communities or teams that interact directly, Pod-to-Pod.
</p>
<div className="mt-8 h-px w-full bg-cyan-500/50" />
</div>
{/* 4 — Storage */}
<div>
<h3 className="text-lg font-semibold text-white flex items-center">
<ShieldCheckIcon className="h-6 w-6 text-cyan-500 mr-3" />
Storage
</h3>
<p className="mt-2 text-gray-200 max-w-2xl">
Store data safely with Quantum Safe File System (QSFS) built in.
</p>
</div>
</div>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</section>
)
}

View File

@@ -0,0 +1,53 @@
"use client";
import { Eyebrow, H3, P } from "@/components/Texts";
import CloudPods from "./animations/CloudPods";
export function PodsHow() {
return (
<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="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">
{/* ✅ Two-column layout */}
<div className="flex flex-col lg:flex-row-reverse gap-16">
{/* ✅ Right side animation */}
<div className="w-full lg:w-1/2">
<CloudPods />
</div>
{/* ✅ Left side content */}
<div className="w-full lg:w-1/2 text-white">
<Eyebrow color="accent" className="">
How it works
</Eyebrow>
<H3 color="white" className="mt-6">
What Living in a Pod Feels Like
</H3>
<P className="max-w-3xl text-gray-400 mt-6">
When you use Mycelium, everything your messages, calls, files runs directly from your Pod.
</P>
<P className="max-w-3xl text-gray-400 mt-4">
Its your personal digital hub:
When you message someone, it goes Pod to Pod, not through a central server.
When you host a call, it runs on your Pod no third-party data centers.
</P>
<P className="max-w-3xl text-gray-400 mt-4">
When you save a file, it stays on your Pod, encrypted and always available.
No one else can read it, rent it, or switch it off.
</P>
<P className="max-w-3xl text-gray-400 mt-4">
You dont log in to the internet you are part of it.
</P>
</div>
</div>
</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>
);
}

View File

@@ -1,9 +1,13 @@
import Homepod from './Homepod';
import { PodsCapabilities } from './PodsCapabilities';
import { PodsHow } from './PodsHow';
const PodsPage = () => {
return (
<>
<Homepod />
<Homepod />
<PodsCapabilities />
<PodsHow />
</>
);
};

View File

@@ -0,0 +1,195 @@
"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;
export default function CloudPods({
className,
accent = "#00b8db",
bg = "#0b0b0b",
}: Props) {
const prefers = useReducedMotion();
// Pods: 2 clusters (top-right & bottom-left)
const clusterA = [
{ x: 180, y: 300 },
{ x: 240, y: 330 },
{ x: 300, y: 290 },
];
const clusterB = [
{ x: 480, y: 100 },
{ x: 540, y: 130 },
{ x: 600, y: 90 },
];
// Combine all pods for rendering
const pods = [...clusterA, ...clusterB];
// Inter-cluster communication paths (cross connections)
const links = [
[0, 3],
[1, 4],
[2, 5],
[0, 4],
[1, 5],
];
const drawLink = (i: number, j: number) => {
const a = pods[i];
const b = pods[j];
return `M ${a.x} ${a.y} L ${b.x} ${b.y}`;
};
return (
<div className={clsx("relative overflow-hidden", className)}>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" style={{ background: bg }}>
<defs>
{/* Subtle cyan glow */}
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="b" />
<feMerge>
<feMergeNode in="b" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
{/* Cyan gradient for pods */}
<radialGradient id="podGradient" cx="50%" cy="50%" r="60%">
<stop offset="0%" stopColor={accent} stopOpacity="0.9" />
<stop offset="100%" stopColor={accent} stopOpacity="0.05" />
</radialGradient>
</defs>
{/* ✅ Static base links between clusters */}
{links.map(([i, j], idx) => (
<motion.path
key={idx}
d={drawLink(i, j)}
stroke="#1f2937"
strokeWidth={1.8}
strokeLinecap="round"
fill="none"
opacity="0.5"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 1.2, delay: idx * 0.05 }}
/>
))}
{/* ✅ Cyan data signals moving across clusters */}
{!prefers &&
links.map(([i, j], idx) => (
<motion.circle
key={`pulse-${idx}`}
r={4}
fill={accent}
style={{ offsetPath: `path('${drawLink(i, j)}')` }}
initial={{ offsetDistance: "0%", opacity: 0 }}
animate={{
offsetDistance: ["0%", "100%"],
opacity: [0.2, 1, 0.2],
}}
transition={{
duration: 2.6,
delay: idx * 0.25,
repeat: Infinity,
ease: "linear",
}}
filter="url(#glow)"
/>
))}
{/* ✅ Cloud Pods */}
{pods.map((p, i) => (
<g key={i}>
<motion.ellipse
cx={p.x}
cy={p.y}
rx={34}
ry={22}
fill="url(#podGradient)"
stroke="#1f2937"
strokeWidth={1.6}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.6, delay: 0.05 * i }}
filter="url(#glow)"
/>
{/* Soft inner cyan pulse */}
{!prefers && (
<motion.ellipse
cx={p.x}
cy={p.y}
rx={18}
ry={12}
fill={accent}
opacity={0.08}
animate={{ opacity: [0.05, 0.3, 0.05], scale: [1, 1.1, 1] }}
transition={{
duration: 2.4,
delay: i * 0.15,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
/>
)}
</g>
))}
{/* ✅ Cluster halos */}
{!prefers && (
<>
<motion.circle
cx="250"
cy="310"
r="100"
fill="none"
stroke={accent}
strokeWidth={1.2}
opacity={0.1}
animate={{
scale: [1, 1.1, 1.2],
opacity: [0.05, 0.2, 0],
}}
transition={{
duration: 3.8,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
/>
<motion.circle
cx="560"
cy="110"
r="100"
fill="none"
stroke={accent}
strokeWidth={1.2}
opacity={0.1}
animate={{
scale: [1, 1.1, 1.2],
opacity: [0.05, 0.2, 0],
}}
transition={{
duration: 3.8,
delay: 1.2,
repeat: Infinity,
ease: [0.22, 1, 0.36, 1],
}}
/>
</>
)}
</svg>
</div>
);
}