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

@@ -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>
);
}