forked from emre/www_projectmycelium_com
feat: add architecture section with animated illustrations
- Created HomeArchitecture component showcasing decentralized network principles with SVG animations - Added animated illustrations for mesh networking, no extraction, no control, and no central servers - Enhanced CallToAction with cyan radial glow effect for visual emphasis - Fixed audience gallery image paths to use correct /images/audiences/ directory
This commit is contained in:
236
src/pages/home/animations/SovereignCompute.tsx
Normal file
236
src/pages/home/animations/SovereignCompute.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
"use client";
|
||||
|
||||
import { motion, useReducedMotion } from "framer-motion";
|
||||
import clsx from "clsx";
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
accent?: string; // cyan highlight
|
||||
gridStroke?: string; // grid color (default #2b2a2a as requested)
|
||||
};
|
||||
|
||||
const W = 760;
|
||||
const H = 420;
|
||||
|
||||
const Server = ({
|
||||
x,
|
||||
y,
|
||||
w = 140,
|
||||
h = 90,
|
||||
rows = 3,
|
||||
}: {
|
||||
x: number;
|
||||
y: number;
|
||||
w?: number;
|
||||
h?: number;
|
||||
rows?: number;
|
||||
}) => {
|
||||
const rowH = (h - 24) / rows;
|
||||
|
||||
return (
|
||||
<g>
|
||||
{/* chassis */}
|
||||
<rect x={x} y={y} width={w} height={h} rx={12} fill="#0d0d0d" stroke="#1a1a1a" strokeWidth={2} />
|
||||
{/* bays */}
|
||||
{Array.from({ length: rows }).map((_, i) => (
|
||||
<g key={i}>
|
||||
<rect
|
||||
x={x + 12}
|
||||
y={y + 12 + i * rowH}
|
||||
width={w - 24}
|
||||
height={rowH - 10}
|
||||
rx={8}
|
||||
fill="#111111"
|
||||
stroke="#1f1f1f"
|
||||
strokeWidth={1}
|
||||
/>
|
||||
{/* bay indicators */}
|
||||
<rect x={x + 20} y={y + 22 + i * rowH} width={10} height={6} rx={2} fill="#16a34a" opacity={0.8} />
|
||||
<rect x={x + 36} y={y + 22 + i * rowH} width={10} height={6} rx={2} fill="#9ca3af" opacity={0.6} />
|
||||
<rect x={x + 52} y={y + 22 + i * rowH} width={10} height={6} rx={2} fill="#9ca3af" opacity={0.6} />
|
||||
</g>
|
||||
))}
|
||||
{/* subtle top highlight */}
|
||||
<rect x={x + 2} y={y + 2} width={w - 4} height={10} rx={5} fill="#0f0f0f" />
|
||||
</g>
|
||||
);
|
||||
};
|
||||
|
||||
export default function SovereignCompute({
|
||||
className,
|
||||
accent = "#00b8db",
|
||||
gridStroke = "#2b2a2a",
|
||||
}: Props) {
|
||||
const prefers = useReducedMotion();
|
||||
|
||||
// Positions
|
||||
const left = { x: 140, y: 120 };
|
||||
const mid = { x: 310, y: 150 };
|
||||
const right= { x: 500, y: 120 };
|
||||
|
||||
// Shield position (trust boundary)
|
||||
const shield = { cx: 600, cy: 250, r: 38 };
|
||||
|
||||
// Attestation paths from racks to shield
|
||||
const pathFromLeft = `M ${left.x + 140} ${left.y + 45} C 330 150, 470 200, ${shield.cx - 50} ${shield.cy}`;
|
||||
const pathFromMid = `M ${mid.x + 140} ${mid.y + 45} C 420 190, 500 215, ${shield.cx - 50} ${shield.cy}`;
|
||||
const pathFromRight = `M ${right.x + 140} ${right.y + 45} C 520 180, 560 220, ${shield.cx - 50} ${shield.cy}`;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx("relative overflow-hidden", className)}
|
||||
aria-hidden="true"
|
||||
role="img"
|
||||
aria-label="Sovereign compute: execution only on hardware you control"
|
||||
style={{ background: "transparent" }}
|
||||
>
|
||||
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
|
||||
{/* GRID (transparent bg, subtle dark grid) */}
|
||||
<defs>
|
||||
<pattern id="grid-secure" width="28" height="28" patternUnits="userSpaceOnUse">
|
||||
<path d="M 28 0 L 0 0 0 28" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.45" />
|
||||
</pattern>
|
||||
|
||||
{/* soft glow filter for shield */}
|
||||
<filter id="glow">
|
||||
<feGaussianBlur stdDeviation="6" result="coloredBlur" />
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<rect width={W} height={H} fill="url(#grid-secure)" />
|
||||
|
||||
{/* RACKS (hardware you control) */}
|
||||
<Server x={left.x} y={left.y} />
|
||||
<Server x={mid.x} y={mid.y} />
|
||||
<Server x={right.x} y={right.y} />
|
||||
|
||||
{/* BASELINES for attestation links */}
|
||||
{[pathFromLeft, pathFromMid, pathFromRight].map((d, i) => (
|
||||
<motion.path
|
||||
key={`base-${i}`}
|
||||
d={d}
|
||||
fill="none"
|
||||
stroke="#303030"
|
||||
strokeWidth={3}
|
||||
strokeLinecap="round"
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 0.6 }}
|
||||
transition={{ delay: 0.15 * i, duration: 0.8, ease: [0.22, 1, 0.36, 1] }}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* MOVING ATTESTATION TOKENS (signatures/hashes) */}
|
||||
{!prefers && [pathFromLeft, pathFromMid, pathFromRight].map((d, i) => (
|
||||
<motion.circle
|
||||
key={`token-${i}`}
|
||||
r={5}
|
||||
fill={accent}
|
||||
style={{ offsetPath: `path('${d}')` }}
|
||||
initial={{ offsetDistance: "0%", opacity: 0 }}
|
||||
animate={{ offsetDistance: ["0%", "100%"], opacity: [0, 1, 0] }}
|
||||
transition={{
|
||||
delay: 0.25 * i,
|
||||
duration: 2.0,
|
||||
repeat: Infinity,
|
||||
repeatType: "loop",
|
||||
ease: "linear",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* TRUST BOUNDARY + SHIELD (hardware attestation target) */}
|
||||
<motion.circle
|
||||
cx={shield.cx}
|
||||
cy={shield.cy}
|
||||
r={shield.r + 18}
|
||||
fill="none"
|
||||
stroke="#1f1f1f"
|
||||
strokeWidth={2}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 0.9 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
/>
|
||||
|
||||
{/* cyan halo */}
|
||||
{!prefers && (
|
||||
<motion.circle
|
||||
cx={shield.cx}
|
||||
cy={shield.cy}
|
||||
r={shield.r + 6}
|
||||
fill={accent}
|
||||
opacity={0.12}
|
||||
initial={{ scale: 0.95, opacity: 0 }}
|
||||
animate={{ scale: [1, 1.12, 1], opacity: [0.1, 0.35, 0.1] }}
|
||||
transition={{ duration: 1.8, repeat: Infinity, repeatType: "mirror", ease: [0.22, 1, 0.36, 1] }}
|
||||
filter="url(#glow)"
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Shield outline */}
|
||||
<motion.path
|
||||
d={`M ${shield.cx} ${shield.cy - 30}
|
||||
L ${shield.cx + 28} ${shield.cy - 15}
|
||||
L ${shield.cx + 22} ${shield.cy + 24}
|
||||
L ${shield.cx} ${shield.cy + 34}
|
||||
L ${shield.cx - 22} ${shield.cy + 24}
|
||||
L ${shield.cx - 28} ${shield.cy - 15}
|
||||
Z`}
|
||||
fill="none"
|
||||
stroke={accent}
|
||||
strokeWidth={3}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 1 }}
|
||||
transition={{ duration: 0.9, ease: [0.22, 1, 0.36, 1] }}
|
||||
filter="url(#glow)"
|
||||
/>
|
||||
|
||||
{/* Check mark (verified hardware) */}
|
||||
<motion.path
|
||||
d={`M ${shield.cx - 14} ${shield.cy + 6} L ${shield.cx - 2} ${shield.cy + 18} L ${shield.cx + 18} ${shield.cy - 6}`}
|
||||
fill="none"
|
||||
stroke={accent}
|
||||
strokeWidth={4}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 0.9, delay: 0.2, ease: [0.22, 1, 0.36, 1] }}
|
||||
filter="url(#glow)"
|
||||
/>
|
||||
|
||||
{/* LOCKED EXECUTION BOUNDARY (subtle arc) */}
|
||||
<motion.path
|
||||
d={`M ${shield.cx - 70} ${shield.cy + 46} Q ${shield.cx} ${shield.cy + 76} ${shield.cx + 70} ${shield.cy + 46}`}
|
||||
fill="none"
|
||||
stroke="#2e2e2e"
|
||||
strokeWidth={2}
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 0.6 }}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
/>
|
||||
|
||||
{/* Cyan confirmation pulses emanating out (execution allowed) */}
|
||||
{!prefers && [0, 1].map((i) => (
|
||||
<motion.circle
|
||||
key={`emit-${i}`}
|
||||
cx={shield.cx}
|
||||
cy={shield.cy}
|
||||
r={shield.r + 12}
|
||||
fill="none"
|
||||
stroke={accent}
|
||||
strokeWidth={2}
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: [0.0, 0.5, 0.0], scale: [1, 1.15, 1.3] }}
|
||||
transition={{ duration: 1.8, delay: i * 0.3, repeat: Infinity, ease: [0.22, 1, 0.36, 1] }}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user