diff --git a/public/images/agent1.png b/public/images/agent1.png new file mode 100644 index 0000000..27de355 Binary files /dev/null and b/public/images/agent1.png differ diff --git a/src/components/magicui/infinite-moving-cards.tsx b/src/components/magicui/infinite-moving-cards.tsx index 0cd023e..a07dc3d 100644 --- a/src/components/magicui/infinite-moving-cards.tsx +++ b/src/components/magicui/infinite-moving-cards.tsx @@ -1,12 +1,12 @@ "use client"; import { cn } from "@/lib/utils"; -import React, { useCallback, useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; export const InfiniteMovingCards = ({ items, direction = "left", - speed = "fast", + speed = "slow", pauseOnHover = true, className, }: { @@ -15,43 +15,39 @@ export const InfiniteMovingCards = ({ speed?: "fast" | "normal" | "slow"; pauseOnHover?: boolean; className?: string; -}): JSX.Element => { - const containerRef = React.useRef(null); - const scrollerRef = React.useRef(null); - const [start, setStart] = useState(false); - - - const getSpeed = useCallback(() => { - if (containerRef.current) { - if (speed === "fast") { - containerRef.current.style.setProperty("--animation-duration", "20s"); - } else if (speed === "normal") { - containerRef.current.style.setProperty("--animation-duration", "40s"); - } else { - containerRef.current.style.setProperty("--animation-duration", "80s"); - } - } - }, [speed]); - - const addAnimation = useCallback(() => { - if (containerRef.current && scrollerRef.current) { - const scrollerContent = Array.from(scrollerRef.current.children); - - scrollerContent.forEach((item) => { - const duplicatedItem = item.cloneNode(true); - if (scrollerRef.current) { - scrollerRef.current.appendChild(duplicatedItem); - } - }); - - getSpeed(); - setStart(true); - } - }, [getSpeed]); +}) => { + const containerRef = useRef(null); + const scrollerRef = useRef(null); + const [isReady, setIsReady] = useState(false); useEffect(() => { - addAnimation(); - }, [addAnimation]); + if (!scrollerRef.current) return; + + const children = Array.from(scrollerRef.current.children); + + // duplicate each item ONCE + children.forEach((item) => { + const clone = item.cloneNode(true); + scrollerRef.current!.appendChild(clone); + }); + + // set speed variable + const duration = + speed === "fast" ? "20s" : speed === "normal" ? "40s" : "80s"; + + containerRef.current?.style.setProperty( + "--animation-duration", + duration + ); + + // set direction variable + containerRef.current?.style.setProperty( + "--animation-direction", + direction === "left" ? "forwards" : "reverse" + ); + + setIsReady(true); + }, [direction, speed]); return (
- {items.map((item, idx) => ( -
  • + {items.map((item, i) => ( +
  • {item}
  • ))} diff --git a/src/pages/agents/AgentBento.tsx b/src/pages/agents/AgentBento.tsx index 26980e5..f7cbb91 100644 --- a/src/pages/agents/AgentBento.tsx +++ b/src/pages/agents/AgentBento.tsx @@ -23,7 +23,7 @@ const bentos: { { id: "core", eyebrow: "ARCHITECTURE", - title: "Augmented Intelligence Fabric", + title: "Intelligence Fabric", description: "The sovereign substrate for autonomous AI. Stateless, geo-aware, end-to-end encrypted—and verifiable from intent to execution.", animation: null, diff --git a/src/pages/pods/Homepod.tsx b/src/pages/pods/Homepod.tsx index 44305a6..d3b0b94 100644 --- a/src/pages/pods/Homepod.tsx +++ b/src/pages/pods/Homepod.tsx @@ -13,7 +13,7 @@ export default function Homepod() { style={{ backgroundImage: "url('/images/computehero11.webp')", backgroundSize: "contain" }} > {/* Inner padding */} -
    +
    MYCELIUM PODS diff --git a/src/pages/pods/PodsFeatures.tsx b/src/pages/pods/PodsFeatures.tsx index ca9130a..95c229a 100644 --- a/src/pages/pods/PodsFeatures.tsx +++ b/src/pages/pods/PodsFeatures.tsx @@ -106,9 +106,6 @@ export function PodsFeatures() {

    {useCase.title}

    - - Feature -
    {/* Short description */} diff --git a/src/pages/pods/PodsHow.tsx b/src/pages/pods/PodsHow.tsx index 99330b4..ce993e6 100644 --- a/src/pages/pods/PodsHow.tsx +++ b/src/pages/pods/PodsHow.tsx @@ -1,57 +1,70 @@ "use client"; -import { Eyebrow, H3, P } from "@/components/Texts"; +import { Eyebrow, H4, H5 } from "@/components/Texts"; import PodsFlow from "./animations/PodsFlow"; +import { useEffect, useState } from "react"; +import { IconClockHour5 } from "@tabler/icons-react"; + +const phrases = [ + "everything runs directly from your Pod.", + "Messages travel from Pod to Pod, never through a server.", + "Calls are hosted on your Pod, not in a data center.", + "Files stay encrypted, available, and always yours.", +]; export function PodsHow() { + const [index, setIndex] = useState(0); + const [fade, setFade] = useState(true); + + useEffect(() => { + const interval = setInterval(() => { + setFade(false); + setTimeout(() => { + setIndex((prev) => (prev + 1) % phrases.length); + setFade(true); + }, 300); + }, 3000); + + return () => clearInterval(interval); + }, []); + return (
    - {/* ✅ Top horizontal line with spacing */}
    - {/* ✅ Two-column layout */} + {/* Two-column layout */}
    - {/* ✅ Right side animation */} + {/* Right: Animation */}
    - {/* ✅ Left side content */} -
    - - How it works - -

    - A Pod in Action -

    -

    - When you use Mycelium, everything runs directly from your Pod. -

    -
      -
    • - - When you message someone, it goes Pod to Pod, not through a central server. -
    • -
    • - - When you host a call, it runs on your Pod. No third-party data centers involved. -
    • -
    • - - When you save a file, it stays on your Pod, encrypted and always available. -
    • -
    -

    - No one else can read it, rent it, or switch it off. - You don’t log in to the internet, you are part of it. -

    + {/* Left: JUST the H3 with auto-changing sentence */} +
    + +
    + How it works +

    A Pod in Action

    +
    + When you use Mycelium,  + + {phrases[index]} + +
    +
    +
    +
    diff --git a/src/pages/pods/PodsWhat.tsx b/src/pages/pods/PodsWhat.tsx index f8bf68a..6332bf8 100644 --- a/src/pages/pods/PodsWhat.tsx +++ b/src/pages/pods/PodsWhat.tsx @@ -7,45 +7,27 @@ import { GlobeAltIcon, } from "@heroicons/react/24/solid"; -import { Eyebrow, H3 } from "@/components/Texts"; +import { Eyebrow, H3, P } from "@/components/Texts"; const podCards = [ { - id: "intro", - eyebrow: "Capabilities", - title: "What is a Pod?", - description: null, - icon: null, - custom: true, - noBorder: true, - colSpan: "lg:col-span-4", - }, - { - id: "home", - title: "Your private digital home on the decentralized internet", - description: - "Your Pod is a private digital home where apps, data, and identity live independently of Big Tech and central servers.", + id: "tools", + title: "Runs communication, storage, and collaboration tools", icon: ServerIcon, }, { - id: "control", - title: "An always-on space you fully control", - description: - "A dedicated, always-on environment you fully command. Your own sovereign slice of the network that never goes offline.", + id: "p2p", + title: "Operates peer to peer on the network", icon: ShieldCheckIcon, }, { - id: "tools", - title: "Runs communication, storage, and collaboration tools", - description: - "Runs your communication, storage, and collaboration tools in a secure local environment without reliance on outside platforms.", + id: "encrypted", + title: "Uses encrypted identities and storage", icon: BoltIcon, }, { - id: "networking", - title: "Fully encrypted, federated peer-to-peer network", - description: - "Encrypted, federated peer-to-peer networking that links your Pod directly with trusted devices without intermediaries.", + id: "fabric", + title: "Connects directly to other Pods through the network fabric", icon: GlobeAltIcon, }, ]; @@ -60,38 +42,31 @@ export function PodsWhat() { {/* Content container */}
    + {/* Intro heading */} +
    + What +

    What is a Pod?

    +

    + A Pod is an always-on digital environment that gives you a secure place to run your + applications and data. +

    +
    + {/* 4-column grid */} -
    +
    {podCards.map((card) => { const Icon = card.icon; return (
    - {/* Custom Intro Card */} - {card.custom ? ( - <> - {card.eyebrow} -

    {card.title}

    - - ) : ( - <> - {/* TITLE WITH ICON (matching the TL example) */} -
    - {Icon &&
    - - {/* DESCRIPTION */} -
    - {card.description} -
    - - )} + {/* TITLE WITH ICON */} +
    + {Icon &&
    ); })} diff --git a/src/pages/pods/animations/PodsFlow.tsx b/src/pages/pods/animations/PodsFlow.tsx index 62ce539..6e6bd50 100644 --- a/src/pages/pods/animations/PodsFlow.tsx +++ b/src/pages/pods/animations/PodsFlow.tsx @@ -9,22 +9,23 @@ type Props = { gridStroke?: string; }; +// ▸ NEW: Cropped dimensions const W = 760; -const H = 420; +const H = 300; // was 420 export default function PodsFlow({ className, accent = "#00b8db", - gridStroke = "#2b2a2a", + gridStroke = "#3a3a3a", // lighter grid stroke }: Props) { const pods = [ - { x: 100, y: 180, label: "Pod 1" }, - { x: 260, y: 180, label: "Pod 2" }, - { x: 420, y: 180, label: "Pod 3" }, - { x: 580, y: 180, label: "Pod 4" }, + { x: 100, y: 120, label: "Pod 1" }, // moved slightly up for new height + { x: 260, y: 120, label: "Pod 2" }, + { x: 420, y: 120, label: "Pod 3" }, + { x: 580, y: 120, label: "Pod 4" }, ]; - // Pulse path + // Pulse path (unchanged) const path = ` M ${pods[0].x + 80} ${pods[0].y + 40} L ${pods[1].x - 10} ${pods[1].y + 40} @@ -34,7 +35,7 @@ export default function PodsFlow({ L ${pods[3].x - 10} ${pods[3].y + 40} `; - // Arrow segments + // Line segments const arrows = [ { d: `M ${pods[0].x + 80} ${pods[0].y + 40} L ${pods[1].x - 6} ${pods[1].y + 40}`, @@ -54,15 +55,13 @@ export default function PodsFlow({