diff --git a/public/images/agent_icon.png b/public/images/agent_icon.png new file mode 100644 index 0000000..6a0c9a2 Binary files /dev/null and b/public/images/agent_icon.png differ diff --git a/public/images/cloud1.png b/public/images/cloud1.png new file mode 100644 index 0000000..7747a3d Binary files /dev/null and b/public/images/cloud1.png differ diff --git a/public/images/cloud_icon.png b/public/images/cloud_icon.png new file mode 100644 index 0000000..dbf9330 Binary files /dev/null and b/public/images/cloud_icon.png differ diff --git a/public/images/cloudimg.png b/public/images/cloudimg.png new file mode 100644 index 0000000..ffb4d82 Binary files /dev/null and b/public/images/cloudimg.png differ diff --git a/public/images/network_icon.png b/public/images/network_icon.png new file mode 100644 index 0000000..2e0fc6d Binary files /dev/null and b/public/images/network_icon.png differ diff --git a/src/components/ui/card-stack.tsx b/src/components/ui/card-stack.tsx deleted file mode 100644 index 33de6cc..0000000 --- a/src/components/ui/card-stack.tsx +++ /dev/null @@ -1,48 +0,0 @@ -"use client"; -import { motion } from "framer-motion"; - -type Card = { - id: number; - name: string; - description: string; - icon: React.ReactNode; -}; - -export const CardStack = ({ - items, - offset, - scaleFactor, -}: { - items: Card[]; - offset?: number; - scaleFactor?: number; -}) => { - const CARD_OFFSET = offset || 10; - const HORIZONTAL_OFFSET = 336; // Adjusted for 1/8 overlap - const SCALE_FACTOR = scaleFactor || 0.06; - - return ( -
- {items.map((card, index) => ( - -
-

{card.name}

-

{card.description}

-
-
- ))} -
- ); -}; diff --git a/src/components/ui/glowing-stars.tsx b/src/components/ui/glowing-stars.tsx new file mode 100644 index 0000000..e16e3c7 --- /dev/null +++ b/src/components/ui/glowing-stars.tsx @@ -0,0 +1,158 @@ +"use client"; + +import React, { useEffect, useRef, useState } from "react"; +import { AnimatePresence, motion } from "motion/react"; +import { cn } from "@/lib/utils"; + +export const GlowingStarsBackgroundCard = ({ + className, + children, +}: { + className?: string; + children?: React.ReactNode; +}) => { + const [mouseEnter, setMouseEnter] = useState(false); + + return ( +
{ + setMouseEnter(true); + }} + onMouseLeave={() => { + setMouseEnter(false); + }} + className={cn( + "bg-[linear-gradient(110deg,#333_0.6%,#222)] p-4 max-w-md max-h-[20rem] h-full w-full rounded-xl border border-[#eaeaea] dark:border-neutral-600", + className + )} + > +
+ +
+
{children}
+
+ ); +}; + +export const GlowingStarsDescription = ({ + className, + children, +}: { + className?: string; + children?: React.ReactNode; +}) => { + return ( +

+ {children} +

+ ); +}; + +export const GlowingStarsTitle = ({ + className, + children, +}: { + className?: string; + children?: React.ReactNode; +}) => { + return ( +

+ {children} +

+ ); +}; + +export const Illustration = ({ mouseEnter }: { mouseEnter: boolean }) => { + const stars = 108; + const columns = 18; + + const [glowingStars, setGlowingStars] = useState([]); + + const highlightedStars = useRef([]); + + useEffect(() => { + const interval = setInterval(() => { + highlightedStars.current = Array.from({ length: 5 }, () => + Math.floor(Math.random() * stars) + ); + setGlowingStars([...highlightedStars.current]); + }, 3000); + + return () => clearInterval(interval); + }, []); + + return ( +
+ {[...Array(stars)].map((_, starIdx) => { + const isGlowing = glowingStars.includes(starIdx); + const delay = (starIdx % 10) * 0.1; + const staticDelay = starIdx * 0.01; + return ( +
+ + {mouseEnter && } + + {isGlowing && } + +
+ ); + })} +
+ ); +}; + +const Star = ({ isGlowing, delay }: { isGlowing: boolean; delay: number }) => { + return ( + + ); +}; + +const Glow = ({ delay }: { delay: number }) => { + return ( + + ); +}; diff --git a/src/pages/home/HomeFeatures.tsx b/src/pages/home/HomeFeatures.tsx index c9ea1b4..871349e 100644 --- a/src/pages/home/HomeFeatures.tsx +++ b/src/pages/home/HomeFeatures.tsx @@ -1,56 +1,80 @@ import { InboxIcon, TrashIcon, UsersIcon } from '@heroicons/react/24/outline' import { H2, P } from '@/components/Texts' -import { CardStack } from '@/components/ui/card-stack' const features = [ { - name: 'Network Layer', + name: 'Mycelium Network', description: - "A global, end-to-end encrypted overlay that simply doesn't break. Shortest-path routing moves your traffic the fastest way, every time with instant discovery.", - href: '#', + "A global, end-to-end encrypted overlay that simply doesn't break.", + href: '/network', icon: UsersIcon, + image: '/images/network_icon.png', }, { - name: 'Cloud Layer', + name: 'Mycelium Cloud', description: - 'An autonomous, stateless OS that enforces pre-deterministic deployments you define. Workloads are cryptographically bound to your private key—location and access are yours.', - href: '#', + 'An autonomous, stateless OS that enforces pre-deterministic deployments you define.', + href: '/cloud', icon: TrashIcon, + image: '/images/cloud_icon.png', }, { - name: 'Agent Layer', + name: 'Mycelium Agents', description: - 'Your sovereign agent with private memory and permissioned data access—always under your control. Choose from a wide library of open-source LLMs, paired with built-in semantic search and retrieval.', - href: '#', + 'Your sovereign agent with private memory and permissioned data access—always under your control.', + href: '/agents', icon: InboxIcon, + image: '/images/agent_icon.png', }, ] export function HomeFeatures() { - const cards = features.map((feature, index) => ({ - id: index, - name: feature.name, - description: feature.description, - icon: