diff --git a/package-lock.json b/package-lock.json index 89885c0..e7bcea2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "framer-motion": "^10.18.0", "lucide-react": "^0.544.0", "motion": "^12.23.24", + "next-themes": "^0.4.6", "popmotion": "^11.0.5", "react": "^18.3.1", "react-countup": "^6.5.3", @@ -9417,6 +9418,16 @@ "dev": true, "license": "MIT" }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/node-releases": { "version": "2.0.26", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", diff --git a/package.json b/package.json index 351525c..e453902 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "framer-motion": "^10.18.0", "lucide-react": "^0.544.0", "motion": "^12.23.24", + "next-themes": "^0.4.6", "popmotion": "^11.0.5", "react": "^18.3.1", "react-countup": "^6.5.3", diff --git a/public/images/audience/1.jpg b/public/images/audience/1.jpg new file mode 100644 index 0000000..9368e18 Binary files /dev/null and b/public/images/audience/1.jpg differ diff --git a/public/images/audience/2.jpg b/public/images/audience/2.jpg new file mode 100644 index 0000000..fc351e3 Binary files /dev/null and b/public/images/audience/2.jpg differ diff --git a/public/images/audience/3.jpg b/public/images/audience/3.jpg new file mode 100644 index 0000000..683a17f Binary files /dev/null and b/public/images/audience/3.jpg differ diff --git a/public/images/audience/4.jpg b/public/images/audience/4.jpg new file mode 100644 index 0000000..2018bff Binary files /dev/null and b/public/images/audience/4.jpg differ diff --git a/public/images/audience/5.jpg b/public/images/audience/5.jpg new file mode 100644 index 0000000..4b97274 Binary files /dev/null and b/public/images/audience/5.jpg differ diff --git a/public/images/audience/6.jpg b/public/images/audience/6.jpg new file mode 100644 index 0000000..a8708f2 Binary files /dev/null and b/public/images/audience/6.jpg differ diff --git a/public/images/audience/7.jpg b/public/images/audience/7.jpg new file mode 100644 index 0000000..b47800d Binary files /dev/null and b/public/images/audience/7.jpg differ diff --git a/public/images/audience/8.jpg b/public/images/audience/8.jpg new file mode 100644 index 0000000..46f426e Binary files /dev/null and b/public/images/audience/8.jpg differ diff --git a/src/App.css b/src/App.css index b9d355d..f633e36 100644 --- a/src/App.css +++ b/src/App.css @@ -14,6 +14,8 @@ .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } + + .logo.react:hover { filter: drop-shadow(0 0 2em #61dafbaa); } diff --git a/src/components/ui/GridBlink.tsx b/src/components/ui/GridBlink.tsx new file mode 100644 index 0000000..4db4b33 --- /dev/null +++ b/src/components/ui/GridBlink.tsx @@ -0,0 +1,64 @@ +"use client"; + +import { useEffect, useRef } from "react"; + +export function GridBlink() { + const svgRef = useRef(null); + const maxActive = 3; // ✅ limit active squares + + useEffect(() => { + const svg = svgRef.current; + if (!svg) return; + + const squares = Array.from(svg.querySelectorAll(".blink-square")); + + function scheduleBlink() { + // ✅ only blink if we have too few active + const currentlyActive = squares.filter(sq => sq.classList.contains("active")); + if (currentlyActive.length < maxActive) { + const sq = squares[Math.floor(Math.random() * squares.length)]; + sq.classList.add("active"); + + const duration = 800 + Math.random() * 1000; // ✅ slower fade-out + setTimeout(() => { + sq.classList.remove("active"); + }, duration); + } + + // ✅ slower scheduling + setTimeout(scheduleBlink, 300 + Math.random() * 600); + } + + scheduleBlink(); + }, []); + + const rows = 20; + const cols = 32; + const size = 40; + + return ( + + {Array.from({ length: rows * cols }).map((_, i) => { + const x = (i % cols) * size; + const y = Math.floor(i / cols) * size; + return ( + + ); + })} + + ); +} diff --git a/src/components/ui/spotlight.tsx b/src/components/ui/spotlight.tsx new file mode 100644 index 0000000..3b16f0f --- /dev/null +++ b/src/components/ui/spotlight.tsx @@ -0,0 +1,63 @@ + +import { cn } from "@/lib/utils"; + +type SpotlightProps = { + className?: string; + fill?: string; +}; + +export const Spotlight = ({ className, fill }: SpotlightProps) => { + return ( + + + + + + + {/* ✅ Cyan radial gradient */} + + + + + + + + + + + + + + ); +}; diff --git a/src/components/ui/world-map.tsx b/src/components/ui/world-map.tsx index 2fabb39..64e30c8 100644 --- a/src/components/ui/world-map.tsx +++ b/src/components/ui/world-map.tsx @@ -14,152 +14,111 @@ interface MapProps { export default function WorldMap({ dots = [], - lineColor = "#06b6d4", + lineColor = "#06b6d4", // cyan-500 }: MapProps) { const svgRef = useRef(null); - const map = new DottedMap({ height: 100, grid: "diagonal" }); + // ✅ Force dark-dotted map theme + const map = new DottedMap({ height: 100, grid: "diagonal" }); const svgMap = map.getSVG({ radius: 0.22, - color: "#FFFFFF40", // Hardcoded for dark theme + color: "#06b6d480", // cyan-500 at 50% opacity shape: "circle", - backgroundColor: "black", // Hardcoded for dark theme + backgroundColor: "#111111", }); + // ✅ Point projection stays the same const projectPoint = (lat: number, lng: number) => { const x = (lng + 180) * (800 / 360); const y = (90 - lat) * (400 / 180); return { x, y }; }; - const createCurvedPath = ( - start: { x: number; y: number }, - end: { x: number; y: number } - ) => { + const createCurvedPath = (start: any, end: any) => { const midX = (start.x + end.x) / 2; const midY = Math.min(start.y, end.y) - 50; return `M ${start.x} ${start.y} Q ${midX} ${midY} ${end.x} ${end.y}`; }; return ( -
+
world map + + {/* ✅ Lines + points */} + {/* ✅ animated curved travel lines */} {dots.map((dot, i) => { const startPoint = projectPoint(dot.start.lat, dot.start.lng); const endPoint = projectPoint(dot.end.lat, dot.end.lng); + return ( - - - + ); })} + {/* ✅ glowing path gradient */} - + - + - {dots.map((dot, i) => ( - - - - - - - + {/* ✅ start & end points with pulsing cyan glow */} + {dots.map((dot, i) => { + const s = projectPoint(dot.start.lat, dot.start.lng); + const e = projectPoint(dot.end.lat, dot.end.lng); + + return ( + + {[s, e].map((p, idx) => ( + + + + + + + + ))} - - - - - - - - - ))} + ); + })}
); diff --git a/src/main.tsx b/src/main.tsx index b0c72c4..64cdfc4 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,13 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' +import { ThemeProvider } from 'next-themes' import './styles/tailwind.css' import App from './App' createRoot(document.getElementById('root')!).render( - + + + , ) diff --git a/src/pages/home/CallToAction.tsx b/src/pages/home/CallToAction.tsx index ad052c3..e5e6238 100644 --- a/src/pages/home/CallToAction.tsx +++ b/src/pages/home/CallToAction.tsx @@ -14,17 +14,20 @@ export function CallToAction() {

- Use the Mycelium Stack Your Way + A Living Network +

- Run workloads, connect environments, host nodes, and build agentic systems, all on one sovereign, self-healing network. + Mycelium isn’t a platform. +It’s the soil where a new internet grows — open, resilient, and alive. +

- Start wherever you are. Scale however you choose. + The self-sovereign network powering the next internet.

diff --git a/src/pages/home/HomeAudience.tsx b/src/pages/home/HomeAudience.tsx new file mode 100644 index 0000000..fad79ac --- /dev/null +++ b/src/pages/home/HomeAudience.tsx @@ -0,0 +1,118 @@ +"use client"; +import { useEffect, useState } from "react"; +import { motion, AnimatePresence } from "motion/react"; +import { H3, P } from "@/components/Texts"; +import { Button } from "@/components/Button"; + +const rotating = [ + "Communities", + "Integrators", + "Builders", + "Enterprises", + "Institutions", + "Creators", + "Researchers", + "Individuals", +]; + +// ✅ 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", +]; + +export function HomeAudience() { + const [index, setIndex] = useState(0); + + useEffect(() => { + const timer = setInterval(() => { + setIndex((prev) => (prev + 1) % rotating.length); + }, 3200); + return () => clearInterval(timer); + }, []); + + return ( +
+ {/* ✅ Top horizontal line + container border */} +
+
+ + {/* ✅ Main content */} +
+
+ + {/* ✅ LEFT — Text & rotating headline */} +
+

+ Sovereign Infrastructure for{" "} + + + + {rotating[index]} + + + + {/* Invisible placeholder to avoid layout jump */} + {rotating[index]} + +

+ +

+ The internet wasn’t built for sovereignty. Today, data, AI models, and identity + live on centralized clouds — owned by a few. Mycelium brings infrastructure back + to people, communities, and nations: private, resilient, and cryptographically yours. +

+ +
+ + + Live demo + +
+
+ + {/* ✅ RIGHT — Landscape image gallery synced with title */} +
+ + + +
+ +
+
+ + {/* ✅ Bottom border */} +
+
+
+ ); +} diff --git a/src/pages/home/HomeAurora.tsx b/src/pages/home/HomeAurora.tsx index 9615acf..d77af34 100644 --- a/src/pages/home/HomeAurora.tsx +++ b/src/pages/home/HomeAurora.tsx @@ -1,4 +1,4 @@ -import { H1, H5 } from "@/components/Texts" +import { H1, H4, H5 } from "@/components/Texts" import { Button } from "@/components/Button" export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => void }) { @@ -23,12 +23,15 @@ export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => voi

- The Sovereign Agentic Cloud + MYCELIUM

+

+ The Living Network of the Next Internet +

+
- Host nodes, deploy workloads, or build private AI systems, - all on infrastructure you own and control. + A new internet is emerging — private, distributed, and self-sovereign. Mycelium is the living network that makes it possible. A peer-to-peer foundation where people, data, and intelligence connect directly — without intermediaries, without compromise.
diff --git a/src/pages/home/HomeBlink.tsx b/src/pages/home/HomeBlink.tsx new file mode 100644 index 0000000..a1b2402 --- /dev/null +++ b/src/pages/home/HomeBlink.tsx @@ -0,0 +1,44 @@ +"use client"; + +import { Button } from "@/components/Button"; +import { Spotlight } from "@/components/ui/spotlight"; +import { GridBlink } from "@/components/ui/GridBlink"; +import { H1, H4, H5 } from "@/components/Texts"; + +export function HomeBlink({ onGetStartedClick }: { onGetStartedClick: () => void }) { + return ( +
+
+ + {/* ✅ Animated blinking grid */} + + + {/* ✅ Cyan Spotlight */} + + +
+

+ MYCELIUM +

+

The Living Network of the Next Internet

+ +
+ A new internet is emerging — private, distributed, and self-sovereign. + Mycelium is the living network that makes it possible. + A peer-to-peer foundation where people, data, and intelligence connect + directly — without intermediaries, without compromise. +
+ +
+ + +
+
+
+
+ ); +} diff --git a/src/pages/home/archive/HomeHostingDark.tsx b/src/pages/home/HomeHostingDark.tsx similarity index 100% rename from src/pages/home/archive/HomeHostingDark.tsx rename to src/pages/home/HomeHostingDark.tsx diff --git a/src/pages/home/HomeMap.tsx b/src/pages/home/HomeMap.tsx new file mode 100644 index 0000000..fab26f3 --- /dev/null +++ b/src/pages/home/HomeMap.tsx @@ -0,0 +1,42 @@ +"use client"; +import WorldMap from "@/components/ui/world-map"; +import { Eyebrow, H3, P } from "@/components/Texts"; + +export function HomeMap() { + return ( +
+ {/* ✅ Top horizontal line with spacing */} +
+
+ +
+ Mycelium Nodes +

Host a Node, Grow the Network

+

+ Mycelium runs on real nodes — hosted by people, communities, and enterprises across the world. + Each one adds capacity, resilience, and sovereignty to the network — and earns rewards in return. +

+

+ Plug in once. It runs 24/7 — powering the network and earning autonomously. +

+
+ + {/* ✅ Match same side margins */} +
+ +
+ {/* ✅ Bottom horizontal line with spacing */} +
+
+
+ ); +} diff --git a/src/pages/home/HomePage.tsx b/src/pages/home/HomePage.tsx index c0a74bb..dc48879 100644 --- a/src/pages/home/HomePage.tsx +++ b/src/pages/home/HomePage.tsx @@ -1,13 +1,13 @@ import { useRef } from 'react' import { AnimatedSection } from '../../components/AnimatedSection' -import { StackSectionDark } from './StackSectionDark' -import { WorldMap } from './HomeGlobe' import { CallToAction } from './CallToAction' -import { HomeHosting } from './HomeHosting' -import { HomeAurora } from './HomeAurora' import { HomeTab } from './HomeTab' -import { HomeBenefits } from './HomeBenefits' +import { HomeWhy} from './HomeWhy' +import { HomeMap } from './HomeMap' +import { HomeAudience } from './HomeAudience' +import { HomeBlink } from './HomeBlink' + export default function HomePage() { @@ -19,26 +19,23 @@ export default function HomePage() { return (
- - - - - + - - - - - + + - + + + + + diff --git a/src/pages/home/HomeSpotlight.tsx b/src/pages/home/HomeSpotlight.tsx new file mode 100644 index 0000000..90eee64 --- /dev/null +++ b/src/pages/home/HomeSpotlight.tsx @@ -0,0 +1,55 @@ +"use client"; + +import { Button } from "@/components/Button"; +import { Spotlight } from "@/components/ui/spotlight"; +import { cn } from "@/lib/utils"; +import { H1, H4, H5 } from "@/components/Texts"; + +export function HomeSpotlight({ + onGetStartedClick, +}: { + onGetStartedClick: () => void; +}) { + return ( +
+ {/* Boxed container */} +
+ + {/* ✅ Grid background */} +
+ + {/* ✅ Cyan Spotlight */} + + + {/* ✅ Foreground content */} +
+

+ MYCELIUM +

+

The Living Network of the Next Internet

+ +
+ A new internet is emerging — private, distributed, and self-sovereign. + Mycelium is the living network that makes it possible. + A peer-to-peer foundation where people, data, and intelligence connect + directly — without intermediaries, without compromise. +
+ +
+ + +
+
+
+
+ ); +} diff --git a/src/pages/home/HomeTab.tsx b/src/pages/home/HomeTab.tsx index 1f38902..d12625e 100644 --- a/src/pages/home/HomeTab.tsx +++ b/src/pages/home/HomeTab.tsx @@ -89,10 +89,12 @@ export function HomeTab() { {/* ✅ Section with vertical borders */}
- Deploy faster -

Mycelium Components

-

- Each component can be used on its own or combined into a fully sovereign cloud. + Components +

Explore the Stack

+

+ Mycelium unifies everything the next generation internet needs — communication, cloud, and intelligence — into one seamless, privacy-first network anyone can join. +From encrypted peer-to-peer communication to decentralized cloud and sovereign AI — everything runs on one seamless system. +

diff --git a/src/pages/home/HomeWhy.tsx b/src/pages/home/HomeWhy.tsx new file mode 100644 index 0000000..641c960 --- /dev/null +++ b/src/pages/home/HomeWhy.tsx @@ -0,0 +1,72 @@ +import { + GlobeAltIcon, + KeyIcon, + ServerStackIcon, + ShieldCheckIcon, +} from '@heroicons/react/24/outline' +import { CP, CT, Eyebrow, H3, P } from '@/components/Texts' +import { DarkCard } from '@/components/ui/cards' + +const features = [ + { + name: 'No central servers.', + description: 'Your devices form a distributed network, eliminating reliance on centralized data centers.', + icon: GlobeAltIcon, + }, + { + name: 'No data extraction.', + description: 'You own your data. Run services and AI models on your own devices, ensuring privacy and control.', + icon: KeyIcon, + }, + { + name: 'No single point of control.', + description: 'A decentralized architecture means no single entity can dictate or censor your online experience.', + icon: ServerStackIcon, + }, + { + name: 'Mesh VPN & Zero-Trust Networking', + description: 'Create a secure, private network between your devices, accessible from anywhere.', + icon: ShieldCheckIcon, + }, +] + +export function HomeWhy() { + return ( +
+ {/* ✅ Top horizontal line with spacing */} +
+
+ +
+ Why It Matters +

Why Mycelium?

+

+ 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. + +

+
+
+ {features.map((feature) => ( +
+ + + + + {feature.name} + + + {feature.description} + + +
+ ))} +
+
+
+ {/* ✅ Bottom horizontal line with spacing */} +
+
+
+ ) +} diff --git a/src/styles/tailwind.css b/src/styles/tailwind.css index 9dde88e..16c23d9 100644 --- a/src/styles/tailwind.css +++ b/src/styles/tailwind.css @@ -221,3 +221,10 @@ @apply bg-background text-foreground; } } + +.blink-square.active { + fill: #79f4ff; + opacity: 0.15; + filter: drop-shadow(0 0 6px #90f6ff); + transition: opacity 1s ease-out; +} diff --git a/tailwind.config.js b/tailwind.config.js index c812a14..7ea2ec9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,5 +1,6 @@ /** @type {import('tailwindcss').Config} */ export default { + darkMode: 'class', content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}",