From b320f3e506349bfeab87dd6ee17795cfc410959f Mon Sep 17 00:00:00 2001 From: sasha-astiadi Date: Mon, 13 Oct 2025 17:53:35 +0200 Subject: [PATCH] feat: replace placeholder image with ProxyForwarding component and add ContentDistribution section --- src/components/ContentDistribution.tsx | 182 +++++++++++++++++++++++++ src/components/Features.tsx | 9 +- 2 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 src/components/ContentDistribution.tsx diff --git a/src/components/ContentDistribution.tsx b/src/components/ContentDistribution.tsx new file mode 100644 index 0000000..c45af40 --- /dev/null +++ b/src/components/ContentDistribution.tsx @@ -0,0 +1,182 @@ +'use client'; + +import * as React from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; + +type Props = { + className?: string; // e.g. "w-full h-80" + bg?: string; // default white +}; + +/** Palette */ +const ACCENT = '#00b8db'; +const STROKE = '#111827'; +const GRAY = '#9CA3AF'; +const GRAY_LT = '#E5E7EB'; + +/* ---------- small generic icons (no brands) ---------- */ +const IconSquare = () => ( + +); +const IconTriangle = () => ( + +); +const IconHex = () => ( + +); +const IconBolt = () => ( + +); +const IconPlay = () => ( + +); +const IconDB = () => ( + <> + + + + +); + +/* icon inside white circular badge */ +function Badge({ children }: { children: React.ReactNode }) { + return ( + <> + + {children} + + + + + ); +} + +/* ---------- central cloud ---------- */ +function Cloud({ pulse = true }: { pulse?: boolean }) { + const prefersReduced = useReducedMotion(); + return ( + + + + + + + + {/* subtle accent aura */} + + + ); +} + +/* a small packet line from center to a node */ +function Beam({ + x2, + y2, + delay = 0, +}: { + x2: number; + y2: number; + delay?: number; +}) { + const prefersReduced = useReducedMotion(); + return ( + + ); +} + +export default function ContentDistribution({ className, bg = '#ffffff' }: Props) { + const W = 900; + const H = 560; + + // ring radii + const rings = [110, 190, 270]; + + // positions (angle degrees) for badges on rings + const layout = [ + { r: rings[1], a: -20, icon: }, + { r: rings[2], a: 20, icon: }, + { r: rings[0], a: 155, icon: }, + { r: rings[2], a: -145, icon: }, + { r: rings[1], a: 210, icon: }, + { r: rings[0], a: 60, icon: }, + ]; + + const prefersReduced = useReducedMotion(); + + return ( + + ); +} diff --git a/src/components/Features.tsx b/src/components/Features.tsx index 367e4d7..cc6614e 100644 --- a/src/components/Features.tsx +++ b/src/components/Features.tsx @@ -2,6 +2,7 @@ import Pathfinding from '@/components/Pathfinding' import MessageBus from '@/components/MessageBus' import ProxyDetection from '@/components/ProxyDetection' import ProxyForwarding from '@/components/ProxyForwarding' +import ContentDistribution from '@/components/ContentDistribution' export function Features() { return ( @@ -75,11 +76,7 @@ export function Features() {
- +

Connectivity

@@ -96,7 +93,7 @@ export function Features() {

- +

Delivery