diff --git a/public/images/audiences/1.jpg b/public/images/audiences/1.jpg new file mode 100644 index 0000000..0ab2043 Binary files /dev/null and b/public/images/audiences/1.jpg differ diff --git a/public/images/audiences/2.jpg b/public/images/audiences/2.jpg new file mode 100644 index 0000000..f160747 Binary files /dev/null and b/public/images/audiences/2.jpg differ diff --git a/public/images/audiences/3.jpg b/public/images/audiences/3.jpg new file mode 100644 index 0000000..7c7fe03 Binary files /dev/null and b/public/images/audiences/3.jpg differ diff --git a/public/images/audiences/4.jpg b/public/images/audiences/4.jpg new file mode 100644 index 0000000..ba4dbe1 Binary files /dev/null and b/public/images/audiences/4.jpg differ diff --git a/public/images/audiences/5.jpg b/public/images/audiences/5.jpg new file mode 100644 index 0000000..897c024 Binary files /dev/null and b/public/images/audiences/5.jpg differ diff --git a/public/images/audiences/6.jpg b/public/images/audiences/6.jpg new file mode 100644 index 0000000..4bf567e Binary files /dev/null and b/public/images/audiences/6.jpg differ diff --git a/public/images/audiences/7.jpg b/public/images/audiences/7.jpg new file mode 100644 index 0000000..74983b8 Binary files /dev/null and b/public/images/audiences/7.jpg differ diff --git a/public/images/audiences/8.jpg b/public/images/audiences/8.jpg new file mode 100644 index 0000000..fb8d937 Binary files /dev/null and b/public/images/audiences/8.jpg differ diff --git a/src/pages/home/CallToAction.tsx b/src/pages/home/CallToAction.tsx index e5e6238..53d6f42 100644 --- a/src/pages/home/CallToAction.tsx +++ b/src/pages/home/CallToAction.tsx @@ -3,48 +3,74 @@ import { Button } from '@/components/Button' export function CallToAction() { return ( -
- {/* ✅ Top horizontal line with spacing */} -
- {/* === Content === */} -
-
- -
-

- A Living Network +
+ {/* ✅ Top horizontal line with spacing */} +
-

-

- Mycelium isn’t a platform. -It’s the soil where a new internet grows — open, resilient, and alive. - -

-

- The self-sovereign network powering the next internet. -

-
- - + {/* === Content === */} +
+ +
+ {/* ✅ Cyan Radial Glow */} + + + +
+

+ A Living Network +

+ +

+ Mycelium isn’t a platform. + It’s the soil where a new internet grows — open, resilient, and alive. +

+ +

+ The self-sovereign network powering the next internet. +

+ +
+ + + +
-
- - -
- {/* ✅ Bottom horizontal line with spacing */} -
+ +
+ + {/* ✅ Bottom horizontal line */} +
) diff --git a/src/pages/home/HomeArchitecture.tsx b/src/pages/home/HomeArchitecture.tsx new file mode 100644 index 0000000..bb07639 --- /dev/null +++ b/src/pages/home/HomeArchitecture.tsx @@ -0,0 +1,126 @@ +"use client"; + +import { Eyebrow, H3, P } from "@/components/Texts"; +import MeshNetworking from "./animations/Meshnetworking"; +import NoExtraction from "./animations/NoExtraction"; +import NoControl from "./animations/NoControl"; +import NoCentral from "./animations/NoCentral"; + +const deterministicCards = [ + { + id: "core", + eyebrow: "Why It Matters", + title: "Built for a Sovereign Digital World", + description: + "The current internet is a rent-seeking one. Mycelium builds one that belongs to everyone — where infrastructure, data, and intelligence stay with the people and organizations who create them.", + animation: null, + colSpan: "lg:col-span-3", + rowSpan: "lg:row-span-1", + custom: true, + noBorder: true, + }, + { + id: "crypto", + title: "No central servers.", + description: + "Your devices form a distributed network, eliminating reliance on centralized data centers.", + animation: , // ✅ NEW + colSpan: "lg:col-span-3", + rowSpan: "lg:row-span-1", + rounded: "lg:rounded-tr-4xl max-lg:rounded-t-4xl", + innerRounded: "lg:rounded-tr-[calc(2rem+1px)] max-lg:rounded-t-[calc(2rem+1px)]", + }, + { + id: "stateless", + title: "No data extraction.", + description: + "You own your data. Run services and AI models on your own devices, ensuring privacy and control.", + animation: , // ✅ NEW + colSpan: "lg:col-span-3", + rowSpan: "lg:row-span-1", + rounded: "lg:rounded-bl-4xl max-lg:rounded-b-4xl", + innerRounded: "lg:rounded-bl-[calc(2rem+1px)] max-lg:rounded-b-[calc(2rem+1px)]", + }, + { + id: "healing", + title: "No single point of control.", + description: + "No single entity can dictate or censor your online experience.", + animation: , // ✅ NEW + colSpan: "lg:col-span-3", + rowSpan: "lg:row-span-1", + rounded: "lg:rounded-br-4xl max-lg:rounded-b-4xl", + innerRounded: "lg:rounded-br-[calc(2rem+1px)] max-lg:rounded-b-[calc(2rem+1px)]", + }, +]; + +export function HomeArchitecture() { + return ( +
+ {/* ✅ Top horizontal line */} +
+
+ +
+
+ {deterministicCards.map((card) => ( +
+ {/* ✅ Disable wrapper on first card */} + {!card.noBorder && ( +
+ )} + +
+ {/* ✅ SVG Animation instead of images */} + {card.animation ? ( +
+
+ {card.animation} +
+
+ ) : ( +
+ )} + +
+ {card.custom ? ( + <> + {card.eyebrow && {card.eyebrow}} +

{card.title}

+

{card.description}

+ + ) : ( + <> +

+ {card.title} +

+

+ {card.description} +

+ + )} +
+
+ + {!card.noBorder && ( +
+ )} +
+ ))} +
+
+ +
+
+
+ ); +} diff --git a/src/pages/home/HomeAudience.tsx b/src/pages/home/HomeAudience.tsx index fad79ac..8326942 100644 --- a/src/pages/home/HomeAudience.tsx +++ b/src/pages/home/HomeAudience.tsx @@ -17,14 +17,14 @@ const rotating = [ // ✅ Use local image files (1–8) const gallery = [ - "/images/audience/1.jpg", - "/images/audience/2.jpg", - "/images/audience/3.jpg", - "/images/audience/4.jpg", - "/images/audience/5.jpg", - "/images/audience/6.jpg", - "/images/audience/7.jpg", - "/images/audience/8.jpg", + "/images/audiences/1.jpg", + "/images/audiences/2.jpg", + "/images/audiences/3.jpg", + "/images/audiences/4.jpg", + "/images/audiences/5.jpg", + "/images/audiences/6.jpg", + "/images/audiences/7.jpg", + "/images/audiences/8.jpg", ]; export function HomeAudience() { diff --git a/src/pages/home/HomeBlink.tsx b/src/pages/home/HomeBlink.tsx index a1b2402..8a23d92 100644 --- a/src/pages/home/HomeBlink.tsx +++ b/src/pages/home/HomeBlink.tsx @@ -17,7 +17,7 @@ export function HomeBlink({ onGetStartedClick }: { onGetStartedClick: () => void
-

+

MYCELIUM

The Living Network of the Next Internet

diff --git a/src/pages/home/HomePage.tsx b/src/pages/home/HomePage.tsx index dc48879..58a92c5 100644 --- a/src/pages/home/HomePage.tsx +++ b/src/pages/home/HomePage.tsx @@ -3,10 +3,11 @@ import { useRef } from 'react' import { AnimatedSection } from '../../components/AnimatedSection' import { CallToAction } from './CallToAction' import { HomeTab } from './HomeTab' -import { HomeWhy} from './HomeWhy' import { HomeMap } from './HomeMap' import { HomeAudience } from './HomeAudience' import { HomeBlink } from './HomeBlink' +import { HomeArchitecture } from './HomeArchitecture' +s @@ -23,7 +24,7 @@ export default function HomePage() { - + diff --git a/src/pages/home/animations/Deterministic.tsx b/src/pages/home/animations/Deterministic.tsx new file mode 100644 index 0000000..6e55526 --- /dev/null +++ b/src/pages/home/animations/Deterministic.tsx @@ -0,0 +1,189 @@ +"use client"; + +import { motion, useReducedMotion } from "framer-motion"; +import clsx from "clsx"; + +type Props = { + className?: string; + accent?: string; + gridStroke?: string; +}; + +const W = 760; +const H = 420; + +export default function Deterministic({ + className, + accent = "#00b8db", + gridStroke = "#2b2a2a", +}: Props) { + const prefers = useReducedMotion(); + + const stages = [ + { x: 180, y: 180, w: 120, h: 80, label: "Build" }, + { x: 330, y: 180, w: 120, h: 80, label: "Package" }, + { x: 480, y: 180, w: 120, h: 80, label: "Deploy" }, + ]; + + // Packet path (deterministic flow) + const packetPath = `M ${stages[0].x + 120} ${stages[0].y + 40} + L ${stages[1].x + 0} ${stages[1].y + 40} + L ${stages[1].x + 120} ${stages[1].y + 40} + L ${stages[2].x + 0} ${stages[2].y + 40}`; + + // tiny arrow for each transition + const arrows = [ + `M ${stages[0].x + 120} ${stages[0].y + 40} L ${stages[1].x + 6} ${stages[1].y + 40}`, + `M ${stages[1].x + 120} ${stages[1].y + 40} L ${stages[2].x + 6} ${stages[2].y + 40}` + ]; + + return ( + + ); +} diff --git a/src/pages/home/animations/Meshnetworking.tsx b/src/pages/home/animations/Meshnetworking.tsx new file mode 100644 index 0000000..c55a2d8 --- /dev/null +++ b/src/pages/home/animations/Meshnetworking.tsx @@ -0,0 +1,151 @@ +"use client"; + +import { motion, useReducedMotion } from "framer-motion"; +import clsx from "clsx"; + +type Props = { + className?: string; + accent?: string; + stroke?: string; +}; + +const W = 760; +const H = 420; + +export default function MeshNetworking({ + className, + accent = "#00b8db", + stroke = "#4B5563", +}: Props) { + const prefersReduced = useReducedMotion(); + + // Nodes in a real mesh (hex pattern) + const nodes = [ + { x: 200, y: 120 }, + { x: 380, y: 100 }, + { x: 560, y: 120 }, + + { x: 130, y: 240 }, + { x: 320, y: 240 }, + { x: 540, y: 240 }, + { x: 630, y: 240 }, + + { x: 260, y: 340 }, + { x: 440, y: 340 }, + ]; + + // All connected pairs (mesh links) + const links = [ + [0,1],[1,2], + [0,3],[1,4],[2,5], + [3,4],[4,5],[5,6], + [3,7],[4,7],[4,8],[5,8], + [7,8] + ]; + + const drawLine = (i: number, j: number) => { + const a = nodes[i]; + const b = nodes[j]; + return `M ${a.x} ${a.y} L ${b.x} ${b.y}`; + }; + + return ( + + ); +} diff --git a/src/pages/home/animations/NoCentral.tsx b/src/pages/home/animations/NoCentral.tsx new file mode 100644 index 0000000..d5220f6 --- /dev/null +++ b/src/pages/home/animations/NoCentral.tsx @@ -0,0 +1,238 @@ +"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/home/animations/NoControl.tsx b/src/pages/home/animations/NoControl.tsx new file mode 100644 index 0000000..17d3be5 --- /dev/null +++ b/src/pages/home/animations/NoControl.tsx @@ -0,0 +1,175 @@ +"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/home/animations/NoExtraction.tsx b/src/pages/home/animations/NoExtraction.tsx new file mode 100644 index 0000000..52c044b --- /dev/null +++ b/src/pages/home/animations/NoExtraction.tsx @@ -0,0 +1,247 @@ +"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/home/animations/SovereignCompute.tsx b/src/pages/home/animations/SovereignCompute.tsx new file mode 100644 index 0000000..77f5438 --- /dev/null +++ b/src/pages/home/animations/SovereignCompute.tsx @@ -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 ( + + {/* chassis */} + + {/* bays */} + {Array.from({ length: rows }).map((_, i) => ( + + + {/* bay indicators */} + + + + + ))} + {/* subtle top highlight */} + + + ); +}; + +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 ( + + ); +}