chore: remove Next.js dependencies and update UI components with standard React
This commit is contained in:
3748
package-lock.json
generated
3748
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -28,8 +28,6 @@
|
||||
"framer-motion": "^10.18.0",
|
||||
"lucide-react": "^0.544.0",
|
||||
"motion": "^12.23.24",
|
||||
"next": "^14.2.33",
|
||||
"next-themes": "^0.4.6",
|
||||
"popmotion": "^11.0.5",
|
||||
"react": "^18.3.1",
|
||||
"react-countup": "^6.5.3",
|
||||
@@ -49,7 +47,6 @@
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-next": "^14.2.33",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||
"sharp": "^0.33.1",
|
||||
|
||||
BIN
public/images/mchip2.webp
Normal file
BIN
public/images/mchip2.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
@@ -12,112 +12,111 @@ function NavLinks() {
|
||||
let [hoveredIndex, setHoveredIndex] = useState<number | null>(null)
|
||||
let timeoutRef = useRef<number | null>(null)
|
||||
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-x-5">
|
||||
<Link to="/" aria-label="Home">
|
||||
<img src="/src/images/logomark.svg" alt="Mycelium" className="h-10 w-auto" />
|
||||
</Link>
|
||||
<div className="flex items-center gap-x-5 border-l border-white/10 pl-5">
|
||||
{[
|
||||
['Home', '/'],
|
||||
['Cloud', '/cloud'],
|
||||
['Network', '/network'],
|
||||
['Agents', '/agents'],
|
||||
].map(([label, href], index) => (
|
||||
<Link
|
||||
key={label}
|
||||
to={href}
|
||||
className={clsx(
|
||||
'relative rounded-lg px-3 py-2 text-sm text-black transition-colors delay-150 hover:text-cyan-500 hover:delay-0',
|
||||
<>
|
||||
{[
|
||||
['Home', '/'],
|
||||
['Cloud', '/cloud'],
|
||||
['Network', '/network'],
|
||||
['Agents', '/agents'],
|
||||
].map(([label, href], index) => (
|
||||
<Link
|
||||
key={label}
|
||||
to={href}
|
||||
className={clsx(
|
||||
'relative rounded-lg px-3 py-2 text-sm text-black transition-colors delay-150 hover:text-cyan-500 hover:delay-0',
|
||||
)}
|
||||
onMouseEnter={() => {
|
||||
if (timeoutRef.current) {
|
||||
window.clearTimeout(timeoutRef.current)
|
||||
}
|
||||
setHoveredIndex(index)
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setHoveredIndex(null)
|
||||
}, 200)
|
||||
}}
|
||||
>
|
||||
<AnimatePresence>
|
||||
{hoveredIndex === index && (
|
||||
<motion.span
|
||||
className="absolute inset-0 rounded-lg bg-white/10"
|
||||
layoutId="hoverBackground"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1, transition: { duration: 0.15 } }}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
transition: { duration: 0.15 },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
onMouseEnter={() => {
|
||||
if (timeoutRef.current) {
|
||||
window.clearTimeout(timeoutRef.current)
|
||||
}
|
||||
setHoveredIndex(index)
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setHoveredIndex(null)
|
||||
}, 200)
|
||||
}}
|
||||
>
|
||||
<AnimatePresence>
|
||||
{hoveredIndex === index && (
|
||||
<motion.span
|
||||
className="absolute inset-0 rounded-lg bg-white/10"
|
||||
layoutId="hoverBackground"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1, transition: { duration: 0.15 } }}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
transition: { duration: 0.15 },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<span className="relative z-10">{label}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex items-center gap-6 max-lg:hidden">
|
||||
<Button
|
||||
to="https://threefold.info/mycelium_network/docs/"
|
||||
variant="outline"
|
||||
as="a"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Docs
|
||||
</Button>
|
||||
<Button to="/download" variant="solid" color="cyan">
|
||||
Get Mycelium
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AnimatePresence>
|
||||
<span className="relative z-10">{label}</span>
|
||||
</Link>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export function Header() {
|
||||
const [isVisible, setIsVisible] = useState(true);
|
||||
const [lastScrollY, setLastScrollY] = useState(0);
|
||||
|
||||
const [isVisible, setIsVisible] = useState(true)
|
||||
const [lastScrollY, setLastScrollY] = useState(0)
|
||||
|
||||
const controlHeader = () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
if (window.scrollY > lastScrollY && window.scrollY > 100) { // Hides when scrolling down past 100px
|
||||
setIsVisible(false);
|
||||
} else { // Shows when scrolling up
|
||||
setIsVisible(true);
|
||||
if (window.scrollY > lastScrollY && window.scrollY > 100) {
|
||||
// Hides when scrolling down past 100px
|
||||
setIsVisible(false)
|
||||
} else {
|
||||
// Shows when scrolling up
|
||||
setIsVisible(true)
|
||||
}
|
||||
setLastScrollY(window.scrollY);
|
||||
setLastScrollY(window.scrollY)
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('scroll', controlHeader);
|
||||
window.addEventListener('scroll', controlHeader)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', controlHeader);
|
||||
};
|
||||
window.removeEventListener('scroll', controlHeader)
|
||||
}
|
||||
}
|
||||
}, [lastScrollY]);
|
||||
|
||||
}, [lastScrollY])
|
||||
|
||||
return (
|
||||
<motion.header
|
||||
className="fixed top-4 left-0 right-0 z-50 flex justify-center"
|
||||
<motion.header
|
||||
className="fixed top-0 left-0 right-0 z-50 bg-white/10 shadow-lg ring-1 ring-white/10 backdrop-blur-sm"
|
||||
initial={{ y: 0, opacity: 1 }}
|
||||
animate={{ y: isVisible ? 0 : -100, opacity: isVisible ? 1 : 0 }}
|
||||
transition={{ duration: 0.3, ease: 'easeInOut' }}
|
||||
>
|
||||
<div className="rounded-full bg-white/10 px-5 py-3 shadow-lg ring-1 ring-white/10 backdrop-blur-sm">
|
||||
<NavLinks />
|
||||
<div className="mx-auto flex max-w-7xl items-center justify-between px-4 py-3 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center gap-x-5">
|
||||
<Link to="/" aria-label="Home">
|
||||
<img src="/src/images/logomark.svg" alt="Mycelium" className="h-10 w-auto" />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex items-center gap-x-5">
|
||||
<NavLinks />
|
||||
</div>
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex items-center gap-6 max-lg:hidden">
|
||||
<Button
|
||||
to="https://threefold.info/mycelium_network/docs/"
|
||||
variant="outline"
|
||||
as="a"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Docs
|
||||
</Button>
|
||||
<Button to="/download" variant="solid" color="cyan">
|
||||
Get Mycelium
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.header>
|
||||
)
|
||||
|
||||
18
src/components/ui/CountUpNumber.tsx
Normal file
18
src/components/ui/CountUpNumber.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
'use client'
|
||||
|
||||
import CountUp from 'react-countup'
|
||||
import { SectionHeader } from '@/components/Texts'
|
||||
|
||||
interface CountUpNumberProps {
|
||||
end: number
|
||||
className?: string
|
||||
color?: 'light' | 'primary' | 'secondary'
|
||||
}
|
||||
|
||||
export function CountUpNumber({ end, className, color }: CountUpNumberProps) {
|
||||
return (
|
||||
<SectionHeader color={color} className={className}>
|
||||
<CountUp end={end} duration={2.75} separator="," />
|
||||
</SectionHeader>
|
||||
)
|
||||
}
|
||||
28
src/components/ui/FadeIn.tsx
Normal file
28
src/components/ui/FadeIn.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
'use client'
|
||||
|
||||
import { motion, type Transition } from 'framer-motion'
|
||||
import React from 'react'
|
||||
import { useMediaQuery } from '@/hooks/useMediaQuery'
|
||||
|
||||
type FadeInProps = {
|
||||
children: React.ReactNode
|
||||
transition?: Transition
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function FadeIn({ children, transition, className }: FadeInProps) {
|
||||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className={className}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: false, margin: isMobile ? '0px 0px -50px 0px' : '0px 0px -100px 0px' }}
|
||||
transition={transition || { duration: 0.5 }}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
)
|
||||
}
|
||||
|
||||
47
src/components/ui/Globe2.tsx
Normal file
47
src/components/ui/Globe2.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import createGlobe from 'cobe'
|
||||
|
||||
export function Globe({ className }: { className?: string }) {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
let phi = 0
|
||||
|
||||
if (!canvasRef.current) return
|
||||
|
||||
const globe = createGlobe(canvasRef.current, {
|
||||
devicePixelRatio: 2,
|
||||
width: 600 * 2,
|
||||
height: 600 * 2,
|
||||
phi: 0,
|
||||
theta: 0,
|
||||
dark: 0,
|
||||
diffuse: 1.2,
|
||||
mapSamples: 16000,
|
||||
mapBrightness: 6,
|
||||
baseColor: [0.3, 0.3, 0.3],
|
||||
markerColor: [0.1, 0.8, 1],
|
||||
glowColor: [1, 1, 1],
|
||||
markers: [
|
||||
{ location: [37.7595, -122.4367], size: 0.03 },
|
||||
{ location: [40.7128, -74.006], size: 0.1 },
|
||||
],
|
||||
onRender: (state) => {
|
||||
state.phi = phi
|
||||
phi += 0.01
|
||||
},
|
||||
})
|
||||
|
||||
return () => {
|
||||
globe.destroy()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className={className}
|
||||
style={{ width: '100%', height: '100%', maxWidth: '100%', aspectRatio: 1 }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { CT, CP } from "@/components/Texts";
|
||||
import Image from 'next/image';
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
@@ -55,11 +54,9 @@ export const BentoGridItem = React.forwardRef<HTMLDivElement, BentoGridItemProps
|
||||
className="w-full h-full object-cover opacity-90 group-hover/bento:opacity-100 transition-opacity duration-300"
|
||||
/>
|
||||
) : img ? (
|
||||
<Image
|
||||
<img
|
||||
src={img}
|
||||
alt={title as string}
|
||||
width={300}
|
||||
height={300}
|
||||
className="w-full h-full object-cover opacity-90 group-hover/bento:opacity-100 transition-opacity duration-300"
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "motion/react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export const LayoutTextFlip = ({
|
||||
@@ -33,7 +33,7 @@ export const LayoutTextFlip = ({
|
||||
|
||||
<motion.span
|
||||
layout
|
||||
className="relative w-fit overflow-hidden px-2 py-2 font-neuton font-medium italic tracking-tight"
|
||||
className="relative w-fit overflow-hidden px-2 py-2 font-medium italic tracking-tight"
|
||||
>
|
||||
<AnimatePresence mode="popLayout">
|
||||
<motion.span
|
||||
|
||||
@@ -4,8 +4,6 @@ import { useRef } from "react";
|
||||
import { motion } from "motion/react";
|
||||
import DottedMap from "dotted-map";
|
||||
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
interface MapProps {
|
||||
dots?: Array<{
|
||||
start: { lat: number; lng: number; label?: string };
|
||||
@@ -21,13 +19,11 @@ export default function WorldMap({
|
||||
const svgRef = useRef<SVGSVGElement>(null);
|
||||
const map = new DottedMap({ height: 100, grid: "diagonal" });
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
const svgMap = map.getSVG({
|
||||
radius: 0.22,
|
||||
color: theme === "dark" ? "#FFFFFF40" : "#00000040",
|
||||
color: "#FFFFFF40", // Hardcoded for dark theme
|
||||
shape: "circle",
|
||||
backgroundColor: theme === "dark" ? "black" : "white",
|
||||
backgroundColor: "black", // Hardcoded for dark theme
|
||||
});
|
||||
|
||||
const projectPoint = (lat: number, lng: number) => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { motion } from 'framer-motion'
|
||||
import { Globe } from '../../components/ui/Globe'
|
||||
import { Globe } from '../../components/ui/Globe2'
|
||||
import { CountUpNumber } from '../../components/CountUpNumber'
|
||||
import { Container } from '../../components/Container'
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export function HomeAgent() {
|
||||
<div className="mx-auto max-w-4xl text-center">
|
||||
<H2>
|
||||
Deploy your own{" "}
|
||||
<span className="font-neuton text-left text-black font-medium text-7xl italic bg-clip-text bg-gradient-to-r from-blue-400 via-cyan-400 to-violet-400">
|
||||
<span className="text-left text-black font-medium text-7xl italic bg-clip-text bg-gradient-to-r from-blue-400 via-cyan-400 to-violet-400">
|
||||
<LayoutTextFlip
|
||||
text=""
|
||||
words={[
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "motion/react";
|
||||
import { motion } from "framer-motion";
|
||||
import { H1, H2, H3, H4, H5 } from "@/components/Texts";
|
||||
import { AuroraBackground } from "@/components/ui/aurora-background";
|
||||
import { ScrollDownArrow } from '@/components/ScrollDownArrow';
|
||||
|
||||
export function HomeAurora() {
|
||||
return (
|
||||
<AuroraBackground>
|
||||
<motion.div
|
||||
initial={{ opacity: 0.0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
@@ -16,10 +14,15 @@ export function HomeAurora() {
|
||||
duration: 1,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
className="relative mb-20 flex flex-col items-center justify-center gap-4 px-4 max-w-5xl"
|
||||
style={{
|
||||
backgroundImage: "url(/images/mchip2.webp)",
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
}}
|
||||
className="relative mx-auto py-24 h-screen flex flex-col items-center justify-center gap-4 px-4 max-w-5xl"
|
||||
>
|
||||
<div className="text-center text-gray-800">
|
||||
<H1>Decentralized Autonomous <span className="font-neuton text-bold lg:text-8xl italic">Agentic Cloud.</span></H1>
|
||||
<H1>Decentralized Autonomous <span className="text-bold lg:text-8xl">Agentic Cloud.</span></H1>
|
||||
</div>
|
||||
<div className="pt-8 text-center font-light text-gray-500 max-w-4xl">
|
||||
<H5>Mycelium Project is a decentralized platform for autonomous AI, powered by distributed compute, sovereign memory, encrypted networking, and stateless GPU orchestration.</H5>
|
||||
@@ -27,8 +30,6 @@ export function HomeAurora() {
|
||||
<div className="pt-8">
|
||||
<ScrollDownArrow />
|
||||
</div>
|
||||
|
||||
</motion.div>
|
||||
</AuroraBackground>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export function HomeCloud() {
|
||||
/>
|
||||
<div className="w-full flex-auto">
|
||||
<H2 className="">
|
||||
Mycelium <span className="font-neuton font-medium text-7xl italic">Cloud</span>
|
||||
Mycelium <span className="font-medium text-7xl italic">Cloud</span>
|
||||
</H2>
|
||||
<P className="mt-6 text-lg/8 text-pretty text-gray-600">
|
||||
A comprehensive platform for deploying and managing Kubernetes clusters on the decentralized Mycelium Grid infrastructure
|
||||
|
||||
@@ -49,7 +49,7 @@ export function HomeFeatures() {
|
||||
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-2xl lg:mx-0">
|
||||
<H2 className="">
|
||||
The Building Blocks of <span className="font-neuton font-medium text-7xl italic">Decentralized Future</span>
|
||||
The Building Blocks of <span className="font-medium text-7xl italic">Decentralized Future</span>
|
||||
</H2>
|
||||
<P className="mt-6 ">
|
||||
From compute and networking to intelligent automation, these components work together to empower users, developers, and organizations to build freely, without intermediaries.
|
||||
|
||||
@@ -5,11 +5,11 @@ import { H2, P } from "@/components/Texts";
|
||||
|
||||
export function HomeMapSection() {
|
||||
return (
|
||||
<div className=" py-24 dark:bg-black bg-white w-full">
|
||||
<div className=" py-24 dark:bg-black bg-tra w-full">
|
||||
<div className="max-w-7xl mx-auto text-center">
|
||||
<H2 className="font-medium text-xl md:text-4xl dark:text-white text-gray-800">
|
||||
Mycelium Network is{" "}
|
||||
<span className="text-black font-neuton text-bold italic">
|
||||
<span className="text-black text-bold italic">
|
||||
{"Live.".split("").map((word, idx) => (
|
||||
<motion.span
|
||||
key={idx}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { AnimatedSection } from '../../components/AnimatedSection'
|
||||
import { HomeHero } from './HomeHero'
|
||||
import { WorldMapSection } from './WorldMapSection'
|
||||
import { StackSection } from './StackSection'
|
||||
import { HomeHeroLight2 } from './HomeHeroLight2'
|
||||
import { HomeHeroDark } from './HomeHeroDark'
|
||||
import { HomeAurora } from './HomeAurora'
|
||||
import { HomeMapSection } from './HomeMap'
|
||||
import { HomeFeatures } from './HomeFeatures'
|
||||
import { HomeCloud } from './HomeCloud'
|
||||
import { HomeAgent } from './HomeAgent'
|
||||
import { StackSectionLight } from './StackSection'
|
||||
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
@@ -17,12 +14,12 @@ export default function HomePage() {
|
||||
<HomeAurora />
|
||||
</AnimatedSection>
|
||||
|
||||
<AnimatedSection id="next-section">
|
||||
<HomeFeatures />
|
||||
<AnimatedSection>
|
||||
<StackSectionLight />
|
||||
</AnimatedSection>
|
||||
|
||||
<AnimatedSection >
|
||||
<HomeMapSection />
|
||||
<AnimatedSection>
|
||||
<HomeFeatures />
|
||||
</AnimatedSection>
|
||||
|
||||
<AnimatedSection>
|
||||
|
||||
@@ -1,66 +1,75 @@
|
||||
import { motion } from 'framer-motion'
|
||||
import { Container } from '../../components/Container'
|
||||
"use client";
|
||||
|
||||
const stackData = [
|
||||
{
|
||||
id: 'agent',
|
||||
title: 'Agent Layer',
|
||||
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.',
|
||||
},
|
||||
{
|
||||
id: 'network',
|
||||
title: 'Network Layer',
|
||||
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.',
|
||||
},
|
||||
{
|
||||
id: 'cloud',
|
||||
title: 'Cloud Layer',
|
||||
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.',
|
||||
},
|
||||
]
|
||||
import { motion } from "framer-motion";
|
||||
import { StackedCubesLight } from "@/components/ui/StackedCubesLight";
|
||||
import { H2, P, SectionHeader, Eyebrow } from "@/components/Texts";
|
||||
import { FadeIn } from "@/components/ui/FadeIn";
|
||||
import { DottedGlowBackground } from '@/components/ui/dotted-glow-background';
|
||||
|
||||
export function StackSection() {
|
||||
export function StackSectionLight() {
|
||||
return (
|
||||
<section className="relative bg-black py-20 lg:py-32">
|
||||
<Container>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-12 items-start">
|
||||
{/* Left Column - Text */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="lg:col-span-1"
|
||||
>
|
||||
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white">
|
||||
The Mycelium Stack
|
||||
</h2>
|
||||
<p className="mt-6 text-lg text-gray-600">
|
||||
Built with Mycelium technology, our AI infrastructure ensures unbreakable networks, complete data sovereignty, ultra-secure agent-human communication, and unhackable data storage systems.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Column - Stack Cards */}
|
||||
<div className="lg:col-span-2 space-y-6">
|
||||
{stackData.map((layer, index) => (
|
||||
<motion.div
|
||||
key={layer.id}
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: index * 0.1 }}
|
||||
className="rounded-2xl bg-gray-50 border border-gray-200 p-6 hover:border-cyan-500 hover:shadow-lg transition-all duration-300"
|
||||
>
|
||||
<h3 className="text-xl font-semibold text-gray-900">{layer.title}</h3>
|
||||
<p className="mt-3 text-gray-600">{layer.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
<section className="relative w-full overflow-hidden py-24 lg:py-40">
|
||||
{/* === Background Layer === */}
|
||||
<div className="absolute inset-0 -z-10 bg-transparent">
|
||||
{/* Dotted Glow Background */}
|
||||
<DottedGlowBackground
|
||||
gap={15}
|
||||
radius={2}
|
||||
color="rgba(0,0,0,0.4)"
|
||||
glowColor="rgba(0,170,255,0.85)"
|
||||
opacity={0.2}
|
||||
/>
|
||||
{/* Faint 3D grid floor */}
|
||||
<div className="absolute inset-0 flex items-end justify-center overflow-hidden">
|
||||
<div className="w-[200vw] h-[200vh] bg-[linear-gradient(to_right,rgba(0,0,0,0.03)_1px,transparent_1px),linear-gradient(to_bottom,rgba(0,0,0,0.03)_1px,transparent_1px)] bg-[size:60px_60px] [transform:perspective(800px)_rotateX(70deg)] origin-bottom opacity-50" />
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
|
||||
{/* === Content === */}
|
||||
<div className="relative mx-auto max-w-7xl px-6 lg:px-8 grid grid-cols-1 lg:grid-cols-3 gap-16 items-center">
|
||||
{/* Left Column - Text */}
|
||||
<div className="text-center lg:text-left">
|
||||
<FadeIn>
|
||||
<Eyebrow color="accent">Technology Layers</Eyebrow>
|
||||
<SectionHeader color="dark" className="text-4xl sm:text-5xl font-semibold">
|
||||
The Mycelium Stack
|
||||
</SectionHeader>
|
||||
</FadeIn>
|
||||
|
||||
<FadeIn>
|
||||
<P color="dark" className="mt-6 text-lg leading-relaxed text-gray-600">
|
||||
Built with Mycelium technology, our AI infrastructure ensures
|
||||
unbreakable networks, complete data sovereignty, ultra-secure
|
||||
agent-human communication, and unhackable data storage systems.
|
||||
</P>
|
||||
</FadeIn>
|
||||
</div>
|
||||
|
||||
{/* Right Column - Animated Stack */}
|
||||
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start relative">
|
||||
<motion.div
|
||||
initial={{ y: 30, opacity: 0 }}
|
||||
whileInView={{ y: 0, opacity: 1 }}
|
||||
transition={{ duration: 1.2, ease: "easeOut" }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<motion.div
|
||||
animate={{
|
||||
y: [0, -10, 0],
|
||||
rotateZ: [0, 0.5, -0.5, 0],
|
||||
}}
|
||||
transition={{
|
||||
duration: 6,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
className="relative"
|
||||
>
|
||||
<StackedCubesLight />
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { motion } from 'framer-motion'
|
||||
import { Globe } from '../../components/ui/Globe'
|
||||
import { Globe } from '../../components/ui/Globe2'
|
||||
import { CountUpNumber } from '../../components/CountUpNumber'
|
||||
import { Container } from '../../components/Container'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user