diff --git a/src/pages/pods/PodsBento.tsx b/src/pages/pods/PodsBento.tsx
index ebdeb65..bb42f49 100644
--- a/src/pages/pods/PodsBento.tsx
+++ b/src/pages/pods/PodsBento.tsx
@@ -1,10 +1,10 @@
"use client";
import { Eyebrow, H3, P } from "@/components/Texts";
-import NoExtraction from "./animations/NoExtraction";
-import NoControl from "./animations/NoControl";
-import NoCentral from "./animations/NoCentral";
-import NoSinglePoint from "./animations/NoSinglePoint";
+import DataControl from "./animations/DataControl";
+import Connectivity from "./animations/Connectivity";
+import Security from "./animations/Security";
+import Resilience from "./animations/Resilience";
const deterministicCards = [
{
@@ -26,7 +26,7 @@ const deterministicCards = [
title: "Your Data Lives on Your Pods",
description:
"Full control of where your data is stored and how it’s shared.",
- animation: ,
+ animation: ,
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-tr-4xl max-lg:rounded-t-4xl",
@@ -40,7 +40,7 @@ const deterministicCards = [
title: "Direct Pod-to-Pod Networking",
description:
"Direct connections between Pods for faster, private communication.",
- animation: ,
+ animation: ,
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-bl-4xl max-lg:rounded-b-4xl",
@@ -54,7 +54,7 @@ const deterministicCards = [
title: "No One Can Spy or Shut You Down",
description:
"Independence from corporate servers or cloud outages.",
- animation: ,
+ animation: ,
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
rounded: "",
@@ -67,7 +67,7 @@ const deterministicCards = [
title: "Resilient Even if Nodes Disconnect",
description:
"Continuous availability even if one node disconnects.",
- animation: ,
+ animation: ,
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-br-4xl max-lg:rounded-b-4xl",
diff --git a/src/pages/pods/animations/Connectivity.tsx b/src/pages/pods/animations/Connectivity.tsx
new file mode 100644
index 0000000..8723156
--- /dev/null
+++ b/src/pages/pods/animations/Connectivity.tsx
@@ -0,0 +1,176 @@
+"use client";
+
+import { motion, useReducedMotion } from "framer-motion";
+import clsx from "clsx";
+
+type Props = {
+ className?: string;
+ accent?: string;
+ bg?: string;
+ gridStroke?: string;
+};
+
+const W = 720; // 4:3 width
+const H = 540; // 4:3 height
+
+export default function Connectivity({
+ className,
+ accent = "#00b8db",
+ bg = "#0b0b0b",
+ gridStroke = "#2b2a2a",
+}: Props) {
+ const prefers = useReducedMotion();
+
+ // Hex-like P2P topology — all peers connect *directly*
+ const pods = [
+ { x: 250, y: 160 },
+ { x: 470, y: 160 },
+ { x: 580, y: 290 },
+ { x: 470, y: 420 },
+ { x: 250, y: 420 },
+ { x: 140, y: 290 },
+ ];
+
+ // Every pod connects to every other pod = full direct mesh
+ const links: [number, number][] = [];
+ for (let i = 0; i < pods.length; i++) {
+ for (let j = i + 1; j < pods.length; j++) links.push([i, j]);
+ }
+
+ const line = (i: number, j: number) => {
+ const a = pods[i], b = pods[j];
+ return `M ${a.x} ${a.y} L ${b.x} ${b.y}`;
+ };
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/pods/animations/DataControl.tsx b/src/pages/pods/animations/DataControl.tsx
new file mode 100644
index 0000000..d3b4c85
--- /dev/null
+++ b/src/pages/pods/animations/DataControl.tsx
@@ -0,0 +1,239 @@
+"use client";
+
+import { motion, useReducedMotion } from "framer-motion";
+import clsx from "clsx";
+
+type Props = {
+ className?: string;
+ accent?: string; // cyan
+ bg?: string; // solid dark
+ gridStroke?: string; // grid color
+};
+
+const W = 720; // 4:3
+const H = 540; // 4:3
+
+export default function DataControl({
+ className,
+ accent = "#00b8db",
+ bg = "#0b0b0b",
+ gridStroke = "#2b2a2a",
+}: Props) {
+ const prefers = useReducedMotion();
+
+ // Central "Your Pod"
+ const center = { x: W / 2, y: H / 2 + 10 };
+
+ // Personal pods (owned) — left-bottom cluster
+ const owned = [
+ { x: 200, y: 380 },
+ { x: 260, y: 320 },
+ { x: 140, y: 320 },
+ ];
+
+ // External peers (share targets) — top-right cluster
+ const peers = [
+ { x: 520, y: 180 },
+ { x: 600, y: 140 },
+ { x: 580, y: 240 },
+ ];
+
+ // helper
+ const line = (a: {x:number;y:number}, b:{x:number;y:number}) => `M ${a.x} ${a.y} L ${b.x} ${b.y}`;
+
+ // "Gates" sit near the center to symbolize explicit permission before data leaves your pod
+ const gates = peers.map((p, i) => {
+ // point 30% of the way from center to peer
+ const gx = center.x + (p.x - center.x) * 0.28;
+ const gy = center.y + (p.y - center.y) * 0.28;
+ return { x: gx, y: gy };
+ });
+
+ // Paths for outbound shares (center -> gate -> peer)
+ const sharePaths = peers.map((p, i) =>
+ `M ${center.x} ${center.y} L ${gates[i].x} ${gates[i].y} L ${p.x} ${p.y}`
+ );
+
+ // Paths for local replication (center <-> owned pods)
+ const localPaths = owned.map((o) => line(center, o));
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/pods/animations/NoCentral.tsx b/src/pages/pods/animations/NoCentral.tsx
deleted file mode 100644
index d5220f6..0000000
--- a/src/pages/pods/animations/NoCentral.tsx
+++ /dev/null
@@ -1,238 +0,0 @@
-"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 (
- <>
-
-
- >
- );
-};
-
-const Packet = ({
- path,
- delay = 0,
- accent = "#00b8db",
- duration = 2.4,
-}: {
- path: string;
- delay?: number;
- accent?: string;
- duration?: number;
-}) => {
- const prefers = useReducedMotion();
- return (
-
- );
-};
-
-export default function NoCentral({
- className,
- accent = "#00b8db",
- bg = "#0a0a0a",
-}: Props) {
- const center = { x: 380, y: 210 };
- const nodes = [
- { x: 160, y: 100 },
- { x: 270, y: 70 },
- { x: 500, y: 90 },
- { x: 620, y: 150 },
- { x: 220, y: 300 },
- { x: 360, y: 340 },
- { x: 530, y: 290 },
- ];
-
- const links = [
- [nodes[0], nodes[1]],
- [nodes[1], nodes[2]],
- [nodes[2], nodes[3]],
- [nodes[0], nodes[4]],
- [nodes[4], nodes[5]],
- [nodes[5], nodes[6]],
- [nodes[1], nodes[5]],
- [nodes[3], nodes[6]],
- ];
-
- return (
-
-
-
- );
-}
diff --git a/src/pages/pods/animations/NoControl.tsx b/src/pages/pods/animations/NoControl.tsx
deleted file mode 100644
index 17d3be5..0000000
--- a/src/pages/pods/animations/NoControl.tsx
+++ /dev/null
@@ -1,175 +0,0 @@
-"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;
-
-/** Node component */
-const Node = ({
- x,
- y,
- r = 14,
- accent = "#00b8db",
- pulse = false,
- faded = false,
-}: {
- x: number;
- y: number;
- r?: number;
- accent?: string;
- pulse?: boolean;
- faded?: boolean;
-}) => {
- const prefers = useReducedMotion();
- return (
- <>
-
-
- >
- );
-};
-
-/** Moving packet along a path */
-const Packet = ({
- path,
- delay = 0,
- accent = "#00b8db",
-}: {
- path: string;
- delay?: number;
- accent?: string;
-}) => {
- const prefers = useReducedMotion();
- return (
-
- );
-};
-
-export default function NoControl({
- className,
- accent = "#00b8db",
- bg = "#0a0a0a",
-}: Props) {
- const center = { x: 380, y: 210 };
- const outer = [
- { x: 160, y: 120 },
- { x: 600, y: 120 },
- { x: 160, y: 300 },
- { x: 600, y: 300 },
- ];
-
- const link = (a: any, b: any) => `M ${a.x} ${a.y} L ${b.x} ${b.y}`;
-
- return (
-
-
-
- );
-}
diff --git a/src/pages/pods/animations/NoExtraction.tsx b/src/pages/pods/animations/NoExtraction.tsx
deleted file mode 100644
index 52c044b..0000000
--- a/src/pages/pods/animations/NoExtraction.tsx
+++ /dev/null
@@ -1,247 +0,0 @@
-"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;
-
-/** Node = local data cluster */
-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 glow */}
-
- {/* data core */}
-
- >
- );
-};
-
-/** A data particle traveling along a given path */
-const Particle = ({
- path,
- delay = 0,
- accent = "#00b8db",
- duration = 2,
- reverse = false,
-}: {
- path: string;
- delay?: number;
- accent?: string;
- duration?: number;
- reverse?: boolean;
-}) => {
- const prefers = useReducedMotion();
- return (
-
- );
-};
-
-export default function NoExtraction({
- className,
- accent = "#00b8db",
- bg = "#0a0a0a",
-}: Props) {
- const center = { x: 380, y: 210 };
- const WBOX = 360;
- const HBOX = 220;
- const boxX = center.x - WBOX / 2;
- const boxY = center.y - HBOX / 2;
-
- // local nodes within boundary
- const nodes = [
- { x: center.x - 80, y: center.y - 40 },
- { x: center.x + 60, y: center.y - 50 },
- { x: center.x, y: center.y + 50 },
- { x: center.x - 50, y: center.y + 30 },
- ];
-
- // internal circulation paths
- const internalPaths = [
- `M ${center.x - 80} ${center.y - 40} Q ${center.x} ${center.y - 80} ${center.x + 60} ${center.y - 50}`,
- `M ${center.x - 50} ${center.y + 30} Q ${center.x} ${center.y + 70} ${center.x} ${center.y + 50}`,
- ];
-
- // escape attempt path
- const attemptPath = `M ${center.x} ${center.y} Q ${center.x + 200} ${center.y - 50} ${center.x + 130} ${center.y}`;
-
- return (
-
-
-
- );
-}
diff --git a/src/pages/pods/animations/NoSinglePoint.tsx b/src/pages/pods/animations/NoSinglePoint.tsx
deleted file mode 100644
index 8d16498..0000000
--- a/src/pages/pods/animations/NoSinglePoint.tsx
+++ /dev/null
@@ -1,225 +0,0 @@
-"use client";
-
-import { motion, useReducedMotion } from "framer-motion";
-import clsx from "clsx";
-
-type Props = {
- className?: string;
- accent?: string; // cyan
- bg?: string; // solid dark background
- gridStroke?: string;
-};
-
-const W = 720; // 4:3
-const H = 540; // 4:3
-
-export default function NoSinglePoint({
- className,
- accent = "#00b8db",
- bg = "#0b0b0b",
- gridStroke = "#2b2a2a",
-}: Props) {
- const prefers = useReducedMotion();
-
- // Nodes (left source, right dest, top hub, bottom hub, plus two relays)
- const nodes = {
- left: { x: 120, y: H / 2 },
- right: { x: W - 120, y: H / 2 },
- top: { x: W / 2, y: 160 },
- bot: { x: W / 2, y: H - 160 },
- tl: { x: 240, y: 200 },
- br: { x: W - 240, y: H - 200 },
- };
-
- // Redundant paths from left → right
- const upperPath = `M ${nodes.left.x} ${nodes.left.y}
- L ${nodes.tl.x} ${nodes.tl.y}
- L ${nodes.top.x} ${nodes.top.y}
- L ${nodes.right.x} ${nodes.right.y}`;
-
- const lowerPath = `M ${nodes.left.x} ${nodes.left.y}
- L ${nodes.bot.x} ${nodes.bot.y}
- L ${nodes.br.x} ${nodes.br.y}
- L ${nodes.right.x} ${nodes.right.y}`;
-
- return (
-
-
-
- );
-}
diff --git a/src/pages/pods/animations/Resilience.tsx b/src/pages/pods/animations/Resilience.tsx
new file mode 100644
index 0000000..68b9adc
--- /dev/null
+++ b/src/pages/pods/animations/Resilience.tsx
@@ -0,0 +1,255 @@
+"use client";
+
+import { motion, useReducedMotion } from "framer-motion";
+import clsx from "clsx";
+
+type Props = {
+ className?: string;
+ accent?: string; // cyan
+ danger?: string; // failing node color
+ bg?: string; // dark background
+ gridStroke?: string; // grid
+};
+
+const W = 720;
+const H = 540;
+
+export default function Resilience({
+ className,
+ accent = "#00b8db",
+ danger = "#ff4d4d",
+ bg = "#0b0b0b",
+ gridStroke = "#2b2a2a",
+}: Props) {
+ const prefers = useReducedMotion();
+
+ // Primary healthy nodes
+ const nodes = [
+ { x: 220, y: 180 },
+ { x: 500, y: 180 },
+ { x: 580, y: 330 },
+ { x: 360, y: 420 },
+ { x: 160, y: 330 },
+ ];
+
+ // One failing node
+ const failing = { x: 360, y: 100 };
+
+ // Full mesh except failing node
+ const links: [number, number][] = [];
+ for (let i = 0; i < nodes.length; i++) {
+ for (let j = i + 1; j < nodes.length; j++) {
+ links.push([i, j]);
+ }
+ }
+
+ // Paths for fallback reroute (detour link when failing node disappears)
+ const reroute = `M ${nodes[0].x} ${nodes[0].y}
+ L ${nodes[3].x} ${nodes[3].y}
+ L ${nodes[2].x} ${nodes[2].y}`;
+
+ const line = (i: number, j: number) =>
+ `M ${nodes[i].x} ${nodes[i].y} L ${nodes[j].x} ${nodes[j].y}`;
+
+ const failRay = `M ${failing.x} ${failing.y} L ${nodes[1].x} ${nodes[1].y}`;
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/pods/animations/Security.tsx b/src/pages/pods/animations/Security.tsx
new file mode 100644
index 0000000..eec1e5e
--- /dev/null
+++ b/src/pages/pods/animations/Security.tsx
@@ -0,0 +1,231 @@
+"use client";
+
+import { motion, useReducedMotion } from "framer-motion";
+import clsx from "clsx";
+
+type Props = {
+ className?: string;
+ accent?: string; // cyan
+ danger?: string; // hostile color
+ bg?: string; // dark background
+ gridStroke?: string; // subtle grid
+};
+
+const W = 720;
+const H = 540;
+
+export default function Security({
+ className,
+ accent = "#00b8db",
+ danger = "#ff4d4d",
+ bg = "#0b0b0b",
+ gridStroke = "#2b2a2a",
+}: Props) {
+ const prefers = useReducedMotion();
+
+ // Central protected pod
+ const center = { x: W / 2, y: H / 2 };
+
+ // External hostile/corporate nodes
+ const hostile = [
+ { x: 160, y: 120 },
+ { x: 560, y: 120 },
+ { x: 120, y: 300 },
+ { x: 600, y: 380 },
+ { x: 350, y: 80 },
+ ];
+
+ // Helper function for attack rays
+ const attackRay = (h: { x: number; y: number }) =>
+ `M ${h.x} ${h.y} L ${center.x} ${center.y}`;
+
+ return (
+
+
+
+ );
+}