23 Commits

Author SHA1 Message Date
c15b110afe feat: adjust hero section width on homepage
- Reduced max-width of hero content container from max-w-3xl to max-w-2xl for better content alignment and readability
- Content width now matches design specifications for desktop breakpoints
2025-11-01 21:08:51 +01:00
3564b5cb0f feat: enhance homepage with smooth scroll navigation
- Added scroll-to-slider functionality when clicking "Get Started" button
- Modified AnimatedSection to support ref forwarding for scroll targeting
- Updated HomeAurora component to accept click handler prop
- Refined homepage hero text and description for clearer value proposition
- Changed button from link to click handler for better user interaction
2025-11-01 21:08:42 +01:00
51ef8dffb5 feat: enhance UI components and layout styling
- Updated FeatureDescription text size to be larger on desktop (lg:text-base)
- Added rounded corners (rounded-3xl) to DarkCard component
- Modified CloudArchitecture section with wider container (max-w-5xl) and updated heading styles
- Adjusted mobile feature navigation indicators with darker colors (bg-gray-600/700)
- Improved hero section typography using H2 and H5 components for better hierarchy
- Refined padding and background styling in CloudFeatures mobile
2025-11-01 21:02:35 +01:00
9d8f1a6919 refactor: replace MagicCard with DarkCard component
- Replaced MagicCard with new DarkCard component across apple-cards-carousel and HomeGlobe
- Updated card styling and layout in apple-cards-carousel to work with DarkCard
- Removed gradient and border styling from globe stats cards
- Adjusted padding and margin values to maintain consistent appearance
- Fixed spacing and alignment of chevron icon in cards
2025-10-31 15:35:45 +01:00
0f93199aa4 feat: redesign card carousel with modern layout and improved visuals
- Updated card component design from image background to structured layout with separate content and image sections
- Added dedicated image container with proper scaling and positioning for product images
- Refined typography with new styling for category, title and description text
- Increased gap between carousel cards from 4 to 6 units for better spacing
- Adjusted card dimensions and padding for better responsive behavior
- Update
2025-10-31 14:35:45 +01:00
57fa97cc70 feat: update home slider images to PNG format
- Added new PNG format images for network, agent, cloud, GPU, compute and storage sections
- Updated image source paths in HomeSlider component to reference new PNG files
- Replaced legacy .webp gallery images with dedicated page-specific images for better quality and consistency
2025-10-31 14:11:52 +01:00
fa7c524b18 feat: remove cloud overview section from landing page
- Removed CloudOverview component from CloudPage to streamline the user experience
- Simplified page layout to focus on hero section and features content
- Maintained AnimatedSection wrapper structure for remaining components
2025-10-31 05:02:26 +01:00
f1c388cbab refactor: reorganize cloud page component structure
- Moved CloudOverview component into its own AnimatedSection for consistent layout
- Reordered imports to match component rendering sequence
- Fixed spacing and removed empty line in component structure
2025-10-31 05:02:02 +01:00
ea3ee4d455 feat: add dynamic header navigation with current page tracking
- Added useLocation hook to detect and display current page in header dropdown
- Extracted cloud navigation items into separate constant for reusability
- Implemented getCurrentPageName function to determine active page based on URL path
- Updated dropdown button to dynamically show current section instead of static "Cloud" text
2025-10-31 04:58:58 +01:00
24f6da37ed feat: enhance cloud features UI with improved image styling
- Removed CircleBackground component and its instances from desktop and mobile views for cleaner design
- Updated image shadows from shadow-xl to shadow-2xl for stronger depth effect
- Modified image positioning with -ml-32 margin for better layout alignment in tablet and desktop views
- Removed unnecessary background animations to improve visual focus on feature screenshots
2025-10-31 04:55:30 +01:00
c861f15492 feat: update hero images and adjust cloud features layout
- Changed cloud hero background image from cloudhero3.webp to cloudhero4.webp for improved visual appeal
- Updated compute hero image path from hero.webp to cloudhero.webp for consistency
- Increased max width of cloud features container from max-w-none to max-w-3xl on large screens for better content readability
2025-10-31 04:50:11 +01:00
bfe3c1e4bd feat: redesign cloud features section with new UI and content
- Replaced mobile phone mockups with full-width desktop screenshots for cloud platform features
- Updated feature descriptions to focus on cloud/Kubernetes capabilities instead of network features
- Changed section layout to improve desktop view with left-aligned feature tabs
- Removed unused phone frame component and related mobile UI elements
- Updated image assets from jpg to png format and reorganized image paths
- Reordered page
2025-10-31 04:40:14 +01:00
26ae2f156a feat: add mobile app UI screenshots and enhance text components
- Added new app UI screenshots for cloud features (connector, billing, kubeconfig, reserve)
- Added new hero image (cloudhero3.webp) for cloud section
- Enhanced Texts component with new cyan color variant and default props support
- Updated Eyebrow component to use consistent styling with accent color and tracking
- Simplified CloudArchitecture component by removing redundant style props
- Completely rebuilt CloudFeatures component with
2025-10-31 04:04:44 +01:00
33c940c604 feat: update cloud page hero and home slider components
- Replaced CloudHero with new CloudHeroNew component on cloud page
- Added new cloud-related images (cloudhero.webp, cloudhero2.webp, k82.png) to public assets
- Enhanced HomeSlider section with Eyebrow component for "Ecosystem" label
- Updated HomeSlider heading text from "Discover the Mycelium Ecosystem" to "Discover the Mycelium Components"
2025-10-31 03:36:19 +01:00
0837a8313c refactor: remove unused text component imports
- Removed unused H2 import from HomeAurora.tsx
- Removed unused SectionHeader import from StackSection.tsx
- Cleaned up import statements to only include components being used
2025-10-31 03:10:39 +01:00
b311cb22a4 feat: improve text styling and layout in home sections
- Replaced custom paragraph tags with CP component for consistent text styling
- Updated leading value from [1.525] to relaxed for better readability
- Simplified feature descriptions while maintaining key messaging
- Streamlined header styling in Stack section and removed redundant text classes
- Standardized text color and spacing across sections for visual consistency
2025-10-31 03:09:47 +01:00
b987f1a072 feat: enhance card component styling and responsiveness
- Added subtle border to cards with 30% opacity gray color for improved visual definition
- Increased description text size from sm to base on mobile and lg on desktop for better readability
- Maintained hover and transition effects while improving visual hierarchy
- Ensured consistent spacing and alignment across card elements
2025-10-31 03:09:07 +01:00
dd4eba2215 feat: update UI styling and add new page images
- Added new WebP images for different pages (agent, cloud, compute, gpu, network, storage)
- Updated benefits section images with optimized WebP versions
- Enhanced text styling:
  - Increased paragraph font size to text-xl on large screens
  - Adjusted H5 line height for better readability
  - Updated card paragraph text size to text-base
- Refined visual design elements:
  - Changed cube stroke color to gray-600 for subtler appearance
  - Adjusted glow effects and gradients to
2025-10-31 03:01:17 +01:00
ea1ef853f1 feat: add hero image for landing page
- Added hero11.webp image file to public/images directory for use in website landing page
2025-10-31 01:38:26 +01:00
5b05dababb style: adjust eyebrow text tracking for better readability
- Changed tracking property from 'tracking-wide' to 'tracking-wider' to increase letter spacing in eyebrow text component
- Improves visual hierarchy and text legibility for uppercase headings
2025-10-31 01:36:16 +01:00
ab5ac43793 feat: update website design and assets
- Replaced multiple hero and background images with new optimized versions
- Removed unused image assets from public/images directory
- Updated typography styles:
  - Removed italic styling from various text components
  - Made eyebrow text uppercase
  - Adjusted H1 font size from 6xl to 5xl on mobile
- Redesigned HomeAurora component with new layout and background
- Added Mulish as primary font family in Tailwind config
- Updated text formatting and spacing
2025-10-31 01:36:08 +01:00
fb9250c365 feat: add Mulish font family to website
- Added Google Fonts stylesheet link to load Mulish font with weights 400, 500, and 700
- Included preconnect links for optimal font loading performance
2025-10-31 01:35:03 +01:00
04d08a4265 feat: update docs button text for improved UI clarity
- Shortened "Read Docs" button text to "Docs" for cleaner, more concise presentation in the CallToAction component
- Maintains same button styling and positioning while reducing visual clutter
2025-10-30 14:34:34 +01:00
87 changed files with 701 additions and 294 deletions

View File

@@ -8,6 +8,7 @@
<meta name="description" content="Project Mycelium's technology enables anyone to deploy their own Internet infrastructure, anywhere." /> <meta name="description" content="Project Mycelium's technology enables anyone to deploy their own Internet infrastructure, anywhere." />
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@400;500;700&display=swap" rel="stylesheet" />
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 992 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 757 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

BIN
public/images/hero11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

BIN
public/images/k82.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 835 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

BIN
public/images/pages/gpu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

BIN
public/images/storage2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@@ -1,4 +1,5 @@
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { forwardRef } from 'react'
type AnimatedSectionProps = { type AnimatedSectionProps = {
children: React.ReactNode children: React.ReactNode
@@ -6,9 +7,11 @@ type AnimatedSectionProps = {
className?: string className?: string
} }
export function AnimatedSection({ children, id, className }: AnimatedSectionProps) { export const AnimatedSection = forwardRef<HTMLElement, AnimatedSectionProps>(
({ children, id, className }, ref) => {
return ( return (
<motion.section <motion.section
ref={ref}
id={id} id={id}
className={className} className={className}
initial={{ opacity: 0, y: 40 }} initial={{ opacity: 0, y: 40 }}
@@ -19,4 +22,5 @@ export function AnimatedSection({ children, id, className }: AnimatedSectionProp
{children} {children}
</motion.section> </motion.section>
) )
} },
)

View File

@@ -1,11 +1,30 @@
import { Link } from 'react-router-dom' import { Link, useLocation } from 'react-router-dom'
import { Dropdown } from './ui/Dropdown' import { Dropdown } from './ui/Dropdown'
import { ChevronDownIcon } from '@heroicons/react/20/solid' import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { Container } from './Container' import { Container } from './Container'
import { Button } from './Button' import { Button } from './Button'
import pmyceliumLogo from '../images/logos/logo_1.png' import pmyceliumLogo from '../images/logos/logo_1.png'
const cloudNavItems = [
{ name: 'Cloud', href: '/cloud' },
{ name: 'Compute', href: '/compute' },
{ name: 'Storage', href: '/storage' },
{ name: 'GPU', href: '/gpu' },
]
export function Header() { export function Header() {
const location = useLocation()
const getCurrentPageName = () => {
const currentPath = location.pathname;
if (currentPath.startsWith('/compute')) return 'Compute';
if (currentPath.startsWith('/storage')) return 'Storage';
if (currentPath.startsWith('/gpu')) return 'GPU';
if (currentPath.startsWith('/cloud')) return 'Cloud';
return 'Cloud';
};
return ( return (
<header> <header>
<nav> <nav>
@@ -18,16 +37,11 @@ export function Header() {
<Dropdown <Dropdown
buttonContent={ buttonContent={
<> <>
Cloud {getCurrentPageName()}
<ChevronDownIcon className="h-5 w-5" aria-hidden="true" /> <ChevronDownIcon className="h-5 w-5" aria-hidden="true" />
</> </>
} }
items={[ items={cloudNavItems}
{ name: 'Cloud', href: '/cloud' },
{ name: 'Compute', href: '/compute' },
{ name: 'Storage', href: '/storage' },
{ name: 'GPU', href: '/gpu' },
]}
/> />
<Link <Link
to="/network" to="/network"

View File

@@ -13,6 +13,7 @@ const colorVariants = {
secondary: 'text-gray-600', secondary: 'text-gray-600',
light: 'text-gray-50', light: 'text-gray-50',
accent: 'text-cyan-500', accent: 'text-cyan-500',
cyan: 'text-cyan-50',
white: 'text-white', white: 'text-white',
dark: 'text-gray-950', dark: 'text-gray-950',
tertiary: 'text-gray-700', tertiary: 'text-gray-700',
@@ -33,7 +34,8 @@ type PolymorphicProps<E extends React.ElementType, P> = P & {
const createTextComponent = <DefaultElement extends React.ElementType>( const createTextComponent = <DefaultElement extends React.ElementType>(
defaultElement: DefaultElement, defaultElement: DefaultElement,
defaultClassName: string defaultClassName: string,
defaultProps: Omit<TextOwnProps, 'className' | 'children'> = {}
) => { ) => {
type Props<E extends React.ElementType = DefaultElement> = PolymorphicProps< type Props<E extends React.ElementType = DefaultElement> = PolymorphicProps<
E, E,
@@ -41,9 +43,9 @@ const createTextComponent = <DefaultElement extends React.ElementType>(
> >
function Text<E extends React.ElementType = DefaultElement>({ function Text<E extends React.ElementType = DefaultElement>({
font = 'sans', font = defaultProps.font || 'sans',
as, as,
color = 'primary', color = defaultProps.color || 'primary',
className, className,
children, children,
...props ...props
@@ -72,7 +74,7 @@ const createTextComponent = <DefaultElement extends React.ElementType>(
// Exports based on your tailwind.css and the example // Exports based on your tailwind.css and the example
export const H1 = createTextComponent( export const H1 = createTextComponent(
'h1', 'h1',
'text-6xl lg:text-7xl font-medium leading-tight tracking-tight' 'text-5xl lg:text-7xl font-medium leading-tight tracking-tight'
) )
export const H2 = createTextComponent( export const H2 = createTextComponent(
'h2', 'h2',
@@ -88,7 +90,7 @@ export const H4 = createTextComponent(
) )
export const P = createTextComponent( export const P = createTextComponent(
'p', 'p',
'text-base lg:text-lg leading-relaxed' 'text-base lg:text-xl leading-relaxed'
) )
export const Small = createTextComponent( export const Small = createTextComponent(
'small', 'small',
@@ -100,11 +102,12 @@ export const Subtle = createTextComponent(
) )
export const H5 = createTextComponent( export const H5 = createTextComponent(
'h5', 'h5',
'text-xl lg:text-2xl font-light leading-snug tracking-normal' 'text-xl lg:text-2xl font-light lg:leading-snug leading-[0.85] tracking-normal'
) )
export const Eyebrow = createTextComponent( export const Eyebrow = createTextComponent(
'h2', 'h2',
'text-base/7 font-semibold tracking-wide' 'text-base/7 font-semibold tracking-[0.18em] uppercase',
{ color: 'accent' }
) )
export const SectionHeader = createTextComponent( export const SectionHeader = createTextComponent(
'p', 'p',
@@ -128,7 +131,7 @@ export const FeatureTitle = createTextComponent(
) )
export const FeatureDescription = createTextComponent( export const FeatureDescription = createTextComponent(
'p', 'p',
'text-sm leading-normal tracking-normal' 'lg:text-base text-sm leading-normal tracking-normal'
) )
export const MobileFeatureTitle = createTextComponent( export const MobileFeatureTitle = createTextComponent(
'h3', 'h3',
@@ -160,4 +163,4 @@ export const DownloadCardDescription = createTextComponent(
) )
export const CT = createTextComponent('span', 'text-lg lg:text-xl font-semibold') export const CT = createTextComponent('span', 'text-lg lg:text-xl font-semibold')
export const CP = createTextComponent('p', 'text-sm lg:text-sm tracking-wide leading-[1.525] font-light') export const CP = createTextComponent('p', 'text-sm lg:text-base tracking-wide leading-relaxed font-light')

View File

@@ -26,7 +26,7 @@ const CubeSvg: React.FC<React.SVGProps<SVGSVGElement> & { index: number }> = ({
<path <path
fill={`url(#cube-gradient-${index})`} fill={`url(#cube-gradient-${index})`}
d="M491.651 144.747L287.198 227.339C265.219 236.22 241.783 236.22 219.802 227.339L15.3486 144.747C-5.11621 136.479 -5.11621 97.5191 15.3486 89.2539L219.802 6.65884C241.783 -2.21961 265.219 -2.21961 287.198 6.65884L491.651 89.2539C512.116 97.5191 512.116 136.479 491.651 144.747Z" d="M491.651 144.747L287.198 227.339C265.219 236.22 241.783 236.22 219.802 227.339L15.3486 144.747C-5.11621 136.479 -5.11621 97.5191 15.3486 89.2539L219.802 6.65884C241.783 -2.21961 265.219 -2.21961 287.198 6.65884L491.651 89.2539C512.116 97.5191 512.116 136.479 491.651 144.747Z"
stroke="rgba(59, 130, 246, 0.25)" stroke="rgba(107, 114, 128, 0.3)"
strokeWidth="0.5" strokeWidth="0.5"
/> />
<defs> <defs>
@@ -79,8 +79,8 @@ export function CubeLight({
<div <div
className={`absolute inset-0 blur-3xl rounded-2xl transition-all duration-500 ${ className={`absolute inset-0 blur-3xl rounded-2xl transition-all duration-500 ${
isActive isActive
? "bg-blue-400/40 opacity-70" ? "bg-cyan-400/20 opacity-30"
: "bg-blue-200/20 opacity-40" : "bg-cyan-200/20 opacity-40"
}`} }`}
/> />
@@ -90,8 +90,8 @@ export function CubeLight({
className="w-48 sm:w-64 lg:w-80 h-auto relative" className="w-48 sm:w-64 lg:w-80 h-auto relative"
style={{ style={{
filter: isActive filter: isActive
? "drop-shadow(0 0 25px rgba(59, 130, 246, 0.4)) brightness(1.1)" ? "drop-shadow(0 0 15px rgba(34, 211, 238, 0.25)) brightness(1.05)"
: "drop-shadow(0 0 10px rgba(59, 130, 246, 0.15)) brightness(1)", : "drop-shadow(0 0 10px rgba(34, 211, 238, 0.15)) brightness(1)",
transition: "all 0.4s ease", transition: "all 0.4s ease",
}} }}
/> />
@@ -99,10 +99,10 @@ export function CubeLight({
{/* Title overlay */} {/* Title overlay */}
<div className="absolute inset-0 flex items-center justify-center"> <div className="absolute inset-0 flex items-center justify-center">
<h3 <h3
className="text-blue-900 text-sm lg:text-base font-medium text-center px-4" className="text-cyan-900 text-sm lg:text-base font-medium text-center px-4"
style={{ style={{
textShadow: textShadow:
"0 0 15px rgba(255,255,255,0.8), 0 0 25px rgba(59, 130, 246, 0.5)", "0 0 15px rgba(255,255,255,0.8), 0 0 25px rgba(34, 211, 238, 0.5)",
}} }}
> >
{title} {title}
@@ -131,7 +131,7 @@ export function CubeLight({
y1="1" y1="1"
x2="120" x2="120"
y2="1" y2="1"
stroke="rgba(59, 130, 246, 0.6)" stroke="rgba(34, 211, 238, 0.6)"
strokeWidth="1" strokeWidth="1"
opacity="0.8" opacity="0.8"
/> />

View File

@@ -35,8 +35,8 @@ const stackData = [
]; ];
export function StackedCubesLight() { export function StackedCubesLight() {
const [active, setActive] = useState<string | null>("agent"); const [active, setActive] = useState<string | null>("network");
const [selectedForMobile, setSelectedForMobile] = useState<string | null>("agent"); const [selectedForMobile, setSelectedForMobile] = useState<string | null>("network");
const handleCubeClick = (id: string) => { const handleCubeClick = (id: string) => {
setSelectedForMobile((prev) => (prev === id ? null : id)); setSelectedForMobile((prev) => (prev === id ? null : id));
@@ -49,10 +49,10 @@ export function StackedCubesLight() {
return ( return (
<div className="flex flex-col items-center relative"> <div className="flex flex-col items-center relative">
{/* ✨ Ambient cyan-white gradient background */} {/* ✨ Ambient cyan-white gradient background */}
<div className="absolute inset-0 bg-gradient-to-b from-white via-cyan-50/40 to-white blur-3xl opacity-70 pointer-events-none" /> <div className="absolute inset-0 bg-gradient-to-b from-white via-cyan-50/30 to-white blur-3xl opacity-70 pointer-events-none" />
<div <div
className="relative w-full flex items-center justify-center lg:justify-center min-h-[450px] lg:min-h-[400px]" className="relative w-full flex items-center justify-center lg:justify-center min-h-[450px] lg:min-h-[400px]"
onMouseLeave={() => setActive("agent")} onMouseLeave={() => setActive("network")}
> >
<motion.div <motion.div
className="relative lg:pl-0 pl-6 h-[300px] lg:h-[400px] w-64 sm:w-80 lg:w-96" className="relative lg:pl-0 pl-6 h-[300px] lg:h-[400px] w-64 sm:w-80 lg:w-96"
@@ -77,8 +77,8 @@ export function StackedCubesLight() {
<div <div
className={`absolute inset-0 blur-2xl rounded-3xl transition-all duration-500 ${ className={`absolute inset-0 blur-2xl rounded-3xl transition-all duration-500 ${
active === layer.id active === layer.id
? "bg-cyan-300/40 opacity-70" ? "bg-cyan-300/20 opacity-20"
: "bg-cyan-200/20 opacity-40" : "bg-cyan-200/20 opacity-20"
}`} }`}
/> />
<CubeLight <CubeLight

View File

@@ -11,6 +11,7 @@ import {
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { motion } from "motion/react"; import { motion } from "motion/react";
import { DarkCard } from "./cards";
interface CarouselProps { interface CarouselProps {
items: JSX.Element[]; items: JSX.Element[];
@@ -73,7 +74,7 @@ export const Carousel = ({ items, initialScroll = 0 }: CarouselProps) => {
<div <div
className={cn( className={cn(
"flex flex-row justify-start gap-4 pl-4", "flex flex-row justify-start gap-6 pl-4",
"mx-auto max-w-7xl", // remove max-w-4xl if you want the carousel to span the full width of its container "mx-auto max-w-7xl", // remove max-w-4xl if you want the carousel to span the full width of its container
)} )}
> >
@@ -93,7 +94,7 @@ export const Carousel = ({ items, initialScroll = 0 }: CarouselProps) => {
}, },
}} }}
key={"card" + index} key={"card" + index}
className="rounded-3xl last:pr-[5%] md:last:pr-[33%]" className="rounded-3xl last:pr-[5%] md:last:pr-[33%] "
> >
{item} {item}
</motion.div> </motion.div>
@@ -127,42 +128,44 @@ export const Card = ({
card: Card; card: Card;
layout?: boolean; layout?: boolean;
}) => { }) => {
return ( return (
<Link to={card.link}> <Link to={card.link}>
<motion.div <DarkCard className="p-0 rounded-3xl">
layoutId={layout ? `card-${card.title}` : undefined} <motion.div
className="relative z-10 flex h-60 w-56 flex-col items-start justify-start overflow-hidden rounded-3xl md:h-120 md:w-96 hover:scale-105 transition-transform duration-200" layoutId={layout ? `card-${card.title}` : undefined}
style={{ className="relative z-10 flex h-104 w-80 flex-col justify-between overflow-hidden rounded-3xl p-8 md:h-120 md:w-96"
backgroundImage: `url(${card.bg})`, >
backgroundSize: 'cover', <div className="flex h-2/5 flex-col justify-center py-6 px-4">
backgroundPosition: 'center',
}}
>
<div className="pointer-events-none absolute inset-x-0 top-0 z-30 h-full bg-gradient-to-b from-black/50 via-transparent to-transparent" />
<div className="relative z-40 p-8 w-full">
<motion.p <motion.p
layoutId={layout ? `category-${card.category}` : undefined} layoutId={layout ? `category-${card.category}` : undefined}
className="text-left font-sans text-sm font-medium text-white md:text-base" className="text-left font-sans font-semibold text-cyan-500 uppercase tracking-wider text-xs md:text-sm"
> >
{card.category} {card.category}
</motion.p> </motion.p>
<motion.p <motion.p
layoutId={layout ? `title-${card.title}` : undefined} layoutId={layout ? `title-${card.title}` : undefined}
className="mt-2 max-w-xs text-left font-sans text-xl font-semibold [text-wrap:balance] text-white md:text-3xl" className="mt-1 max-w-xs text-left font-sans text-xl font-semibold text-white [text-wrap:balance] lg:text-2xl"
> >
{card.title} {card.title}
</motion.p> </motion.p>
<div className="flex flex-row justify-between items-center w-full mt-4"> <div className="mt-2 flex w-full flex-row items-center justify-between md:mt-4">
<motion.p className="max-w-xs text-left font-sans text-sm text-neutral-300"> <motion.p className="max-w-xs text-left font-sans lg:text-xl text-lg text-neutral-300 lg:leading-normal leading-tight">
{card.description} {card.description}
</motion.p> </motion.p>
<div className="h-8 w-8 bg-[#212121] rounded-full flex items-center justify-center text-[#858585] shrink-0 hover:bg-[#262626] hover:text-white active:bg-[#262626] active:text-white transition-colors duration-200"> <div className="flex h-6 w-6 ml-2 shrink-0 items-center justify-center rounded-full bg-[#212121] text-[#858585] transition-colors duration-200 hover:bg-[#262626] hover:text-white md:h-8 md:w-8">
<IconChevronRight className="h-6 w-6" /> <IconChevronRight className="h-4 w-4 md:h-6 md:w-6 " />
</div> </div>
</div> </div>
</div> </div>
</motion.div> <div className="relative flex h-3/5 w-full items-end justify-end bg-transparent">
<img
src={card.src}
alt={card.title}
className="h-full w-full origin-bottom-right scale-75 object-contain mb-10"
/>
</div>
</motion.div>
</DarkCard>
</Link> </Link>
); );
}; };

View File

@@ -0,0 +1,19 @@
import * as React from "react";
import { cn } from "@/lib/utils";
const DarkCard = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"border border-white/10 bg-white/3 p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 rounded-3xl hover:bg-white/6 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/15",
className
)}
{...props}
/>
));
DarkCard.displayName = "DarkCard";
export { DarkCard };

View File

@@ -33,7 +33,7 @@ export const LayoutTextFlip = ({
<motion.span <motion.span
layout layout
className="relative w-fit overflow-hidden px-2 py-2 font-medium italic tracking-tight" className="relative w-fit overflow-hidden px-2 py-2 font-medium tracking-tight"
> >
<AnimatePresence mode="popLayout"> <AnimatePresence mode="popLayout">
<motion.span <motion.span

View File

@@ -7,7 +7,7 @@ export function AgentsHeroAlt() {
return ( return (
<div <div
style={{ style={{
backgroundImage: "url(/images/agentshero.png)", backgroundImage: "url(/images/agentshero2.png)",
backgroundSize: "cover", backgroundSize: "cover",
backgroundPosition: "center", backgroundPosition: "center",
}} }}

View File

@@ -1,5 +1,5 @@
import { Container } from '../../components/Container' import { Container } from '../../components/Container'
import { Eyebrow, SectionHeader, P } from '../../components/Texts' import { Eyebrow, H3, P } from '../../components/Texts'
const architectureSections = [ const architectureSections = [
{ {
@@ -39,15 +39,15 @@ const architectureSections = [
export function CloudArchitecture() { export function CloudArchitecture() {
return ( return (
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 lg:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-5xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Technical Architecture Technical Architecture
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <H3 className="mt-6 text-gray-900">
Built on a sovereign, encrypted delivery mesh. Built on a Sovereign, Encrypted Delivery Mesh.
</SectionHeader> </H3>
<P className="mt-6 text-gray-600"> <P className="mt-6 text-gray-600">
Mycelium Cloud rides on the ThreeFold Grid, pairing encrypted mesh Mycelium Cloud rides on the ThreeFold Grid, pairing encrypted mesh
networking with deterministic K3s orchestration. Every layer is networking with deterministic K3s orchestration. Every layer is

View File

@@ -1,125 +1,430 @@
import { Container } from '../../components/Container' 'use client'
import { Eyebrow, SectionHeader, P, Small } from '../../components/Texts'
const featureSections = [ import { Fragment, useEffect, useId, useRef, useState } from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import clsx from 'clsx'
import {
type MotionProps,
type Variant,
AnimatePresence,
motion,
} from 'framer-motion'
import { useDebouncedCallback } from 'use-debounce'
import {
Eyebrow,
FeatureDescription,
FeatureTitle,
MobileFeatureTitle,
P,
SectionHeader,
} from '@/components/Texts'
import { Container } from '@/components/Container'
import reservenodeimg from '/images/cloud/reserve.png'
import billingImg from '/images/cloud/billing.png'
import kubeconfigImg from '/images/cloud/kubeconfig.png'
interface CustomAnimationProps {
isForwards: boolean
changeCount: number
}
const features = [
{ {
title: 'Mycelium Networking', name: 'Decentralized Kubernetes',
description: description:
'Ultra-fast, decentralized networking inspired by nature to keep services reachable without exposing surfaces.', "Reserve a node and deploy sovereign Kubernetes clusters on decentralized infrastructure.",
bullets: [ icon: DeviceUserIcon,
'End-to-end encrypted mesh connectivity between every node.', screen: ReserveNodeScreen,
'Direct node communication without centralized intermediaries.',
'Self-optimizing routes that heal around failures automatically.',
'Secure peer-to-peer communication across the entire grid.',
],
}, },
{ {
title: 'Zero-Image Technology', name: 'Manage Your Cluster',
description: description:
'Metadata-first zero-images shrink artifacts up to 100x, reducing deployment time and bandwidth.', 'Manage your cluster with ease, with a simple and intuitive interface.',
bullets: [ icon: DeviceNotificationIcon,
'Deterministic deployments verified cryptographically.', screen: ManageClusterScreen,
'Run containers, VMs, and Linux workloads with secure boot.',
'Smart contract orchestration manages every workload lifecycle.',
'Minimal artifact footprint accelerates delivery everywhere.',
],
}, },
{ {
title: 'Quantum-Safe Storage (QSS)', name: 'Personalised Billings & Accounts',
description: description:
'Quantum-resistant encryption secures data beyond the application layer for complete ownership.', 'Easily manage your cluster billing and accounts with personalised configurations.',
bullets: [ icon: DeviceTouchIcon,
'Self-healing storage recovers instantly from corruption or failure.', screen: PersonalisedBillingsScreen,
'Serve the same data via IPFS, S3, WebDAV, HTTP, and native FS.',
'Geo-aware placement enforces residency and redundancy policies.',
'Autonomous replication keeps data resilient across the globe.',
],
},
{
title: 'Multi-Master Clusters',
description:
'High-availability Kubernetes with automatic failover and leadership orchestration.',
bullets: [
'Multi-master topologies orchestrated with zero downtime.',
'Automatic failover keeps control planes healthy and responsive.',
'HA operations managed without manual intervention or scripts.',
'Upgrades roll out seamlessly with continuous verification.',
],
},
{
title: 'Effortless Load Balancing & Scaling',
description:
'Adaptive automation balances traffic and scales workloads based on demand.',
bullets: [
'Built-in autoscaling that responds to real-time usage.',
'Native load balancing distributes traffic globally.',
'High availability delivered without custom controllers.',
'Elastic scaling keeps costs aligned with workload demand.',
],
},
{
title: 'Simple Web Gateway Access',
description:
'Expose services to the public web with declarative Kubernetes resources.',
bullets: [
'One resource publishes services without complex ingress rules.',
'Domain and prefix-based routing built into the platform.',
'No need to manage dedicated ingress controllers.',
'Consistent configuration across every cluster and region.',
],
}, },
] ]
function DeviceUserIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 32 32" aria-hidden="true" {...props}>
<circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M16 23a3 3 0 100-6 3 3 0 000 6zm-1 2a4 4 0 00-4 4v1a2 2 0 002 2h6a2 2 0 002-2v-1a4 4 0 00-4-4h-2z"
fill="#737373"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5 4a4 4 0 014-4h14a4 4 0 014 4v24a4.002 4.002 0 01-3.01 3.877c-.535.136-.99-.325-.99-.877s.474-.98.959-1.244A2 2 0 0025 28V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9a2 2 0 00-2 2v24a2 2 0 001.041 1.756C8.525 30.02 9 30.448 9 31s-.455 1.013-.99.877A4.002 4.002 0 015 28V4z"
fill="#A3A3A3"
/>
</svg>
)
}
function DeviceNotificationIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 32 32" aria-hidden="true" {...props}>
<circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9 0a4 4 0 00-4 4v24a4 4 0 004 4h14a4 4 0 004-4V4a4 4 0 00-4-4H9zm0 2a2 2 0 00-2 2v24a2 2 0 002 2h14a2 2 0 002-2V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9z"
fill="#A3A3A3"
/>
<path
d="M9 8a2 2 0 012-2h10a2 2 0 012 2v2a2 2 0 01-2 2H11a2 2 0 01-2-2V8z"
fill="#737373"
/>
</svg>
)
}
function DeviceTouchIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
let id = useId()
return (
<svg viewBox="0 0 32 32" fill="none" aria-hidden="true" {...props}>
<defs>
<linearGradient
id={`${id}-gradient`}
x1={14}
y1={14.5}
x2={7}
y2={17}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#737373" />
<stop offset={1} stopColor="#D4D4D4" stopOpacity={0} />
</linearGradient>
</defs>
<circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5 4a4 4 0 014-4h14a4 4 0 014 4v13h-2V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9a2 2 0 00-2 2v24a2 2 0 002 2h4v2H9a4 4 0 01-4-4V4z"
fill="#A3A3A3"
/>
<path
d="M7 22c0-4.694 3.5-8 8-8"
stroke={`url(#${id}-gradient)`}
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M21 20l.217-5.513a1.431 1.431 0 00-2.85-.226L17.5 21.5l-1.51-1.51a2.107 2.107 0 00-2.98 0 .024.024 0 00-.005.024l3.083 9.25A4 4 0 0019.883 32H25a4 4 0 004-4v-5a3 3 0 00-3-3h-5z"
fill="#A3A3A3"
/>
</svg>
)
}
const maxZIndex = 2147483647
const bodyVariantBackwards: Variant = {
opacity: 0.4,
scale: 0.8,
zIndex: 0,
filter: 'blur(4px)',
transition: { duration: 0.4 },
}
const bodyAnimation: MotionProps = {
initial: 'initial',
animate: 'animate',
exit: 'exit',
variants: {
initial: (custom: CustomAnimationProps) => (
custom.isForwards
? {
y: '100%',
zIndex: maxZIndex - custom.changeCount,
transition: { duration: 0.4 },
}
: bodyVariantBackwards
),
animate: (custom: CustomAnimationProps) => ({
y: '0%',
opacity: 1,
scale: 1,
zIndex: maxZIndex / 2 - custom.changeCount,
filter: 'blur(0px)',
transition: { duration: 0.4 },
}),
exit: (custom: CustomAnimationProps) => (
custom.isForwards
? bodyVariantBackwards
: {
y: '100%',
zIndex: maxZIndex - custom.changeCount,
transition: { duration: 0.4 },
}
),
},
}
function ReserveNodeScreen() {
return (
<img
src={reservenodeimg}
alt="Mycelium Reserve Node"
width={2432}
height={1442}
className="w-4xl max-w-none rounded-xl shadow-2xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-32 lg:-ml-32"
/>
);
}
function ManageClusterScreen() {
return (
<img
src={kubeconfigImg}
alt="Mycelium Kubeconfig"
width={2432}
height={1442}
className="w-4xl max-w-none rounded-xl shadow-2xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-32 lg:-ml-32"
/>
);
}
function PersonalisedBillingsScreen() {
return (
<img
src={billingImg}
alt="Mycelium Billing"
width={2432}
height={1442}
className="w-4xl max-w-none rounded-xl shadow-2xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-32 lg:-ml-32"
/>
);
}
function usePrevious<T>(value: T) {
const ref = useRef<T>()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
function CloudFeaturesDesktop() {
let [changeCount, setChangeCount] = useState(0)
let [selectedIndex, setSelectedIndex] = useState(0)
let prevIndex = usePrevious(selectedIndex)
let isForwards = prevIndex === undefined ? true : selectedIndex > prevIndex
let onChange = useDebouncedCallback(
(selectedIndex: number) => {
setSelectedIndex(selectedIndex)
setChangeCount((changeCount) => changeCount + 1)
},
100,
{ leading: true },
)
return (
<TabGroup
className="grid grid-cols-12 items-center gap-8 lg:gap-16"
selectedIndex={selectedIndex}
onChange={onChange}
vertical
>
<TabList className="z-10 col-span-6 space-y-6 pl-4 sm:pl-6 lg:pl-8">
{features.map((feature, featureIndex) => (
<div
key={feature.name}
className={clsx(
'relative rounded-2xl outline-2 transition-all duration-300 ease-in-out hover:scale-105 hover:bg-gray-800/30 ml-16',
selectedIndex === featureIndex
? 'outline-cyan-500'
: 'outline-transparent hover:outline-cyan-500',
)}
>
{featureIndex === selectedIndex && (
<motion.div
layoutId="activeBackground"
className="absolute inset-0 bg-gray-800 "
initial={{ borderRadius: 16 }}
/>
)}
<div className="relative z-10 p-8">
<feature.icon className="h-8 w-8" />
<FeatureTitle as="h3" color="white" className="mt-6">
<Tab className="text-left data-selected:not-data-focus:outline-hidden">
<span className="absolute inset-0 rounded-2xl" />
{feature.name}
</Tab>
</FeatureTitle>
<FeatureDescription color="secondary" className="mt-2">
{feature.description}
</FeatureDescription>
</div>
</div>
))}
</TabList>
<div className="relative col-span-6 overflow-hidden">
<div className="z-10 mx-auto w-full max-w-[366px]">
<TabPanels as={Fragment}>
<AnimatePresence
initial={false}
custom={{ isForwards, changeCount }}
>
{features.map((feature, featureIndex) =>
selectedIndex === featureIndex ? (
<TabPanel
static
key={feature.name + changeCount}
className="col-start-1 row-start-1 flex focus:outline-offset-32 data-selected:not-data-focus:outline-hidden"
>
<motion.div {...bodyAnimation} custom={{ isForwards, changeCount }}>
<feature.screen />
</motion.div>
</TabPanel>
) : null,
)}
</AnimatePresence>
</TabPanels>
</div>
</div>
</TabGroup>
)
}
function CloudFeaturesMobile() {
let [activeIndex, setActiveIndex] = useState(0)
let slideContainerRef = useRef<React.ElementRef<'div'>>(null)
let slideRefs = useRef<Array<React.ElementRef<'div'>>>([])
useEffect(() => {
let observer = new window.IntersectionObserver(
(entries) => {
for (let entry of entries) {
if (entry.isIntersecting && entry.target instanceof HTMLDivElement) {
setActiveIndex(slideRefs.current.indexOf(entry.target))
break
}
}
},
{
root: slideContainerRef.current,
threshold: 0.6,
},
)
for (let slide of slideRefs.current) {
if (slide) {
observer.observe(slide)
}
}
return () => {
observer.disconnect()
}
}, [slideContainerRef, slideRefs])
return (
<>
<div
ref={slideContainerRef}
className="-mb-4 flex snap-x snap-mandatory -space-x-4 overflow-x-auto overscroll-x-contain scroll-smooth pb-4 [scrollbar-width:none] sm:-space-x-6 [&::-webkit-scrollbar]:hidden"
>
{features.map((feature, featureIndex) => (
<div
key={featureIndex}
ref={(ref) => ref && (slideRefs.current[featureIndex] = ref)}
className="w-full flex-none snap-center px-4 sm:px-6 transition-all duration-300 ease-in-out hover:scale-105"
>
<div
className={clsx(
'relative transform overflow-hidden rounded-2xl bg-gray-800 px-5 py-6 outline-2 transition-colors',
activeIndex === featureIndex
? 'outline-transparent' // Remove outline for active mobile slide
: 'outline-transparent hover:outline-cyan-500',
)}
>
<div className="relative mx-auto w-full max-w-[366px]">
<feature.screen />
</div>
<div className="absolute inset-x-0 bottom-0 bg-gray-800 p-6 backdrop-blur-sm sm:p-10">
<feature.icon className="h-8 w-8" />
<MobileFeatureTitle color="white" className="mt-6">
{feature.name}
</MobileFeatureTitle>
<FeatureDescription color="secondary" className="mt-2">
{feature.description}
</FeatureDescription>
</div>
</div>
</div>
))}
</div>
<div className="mt-6 flex justify-center gap-3">
{features.map((_, featureIndex) => (
<button
type="button"
key={featureIndex}
className={clsx(
'relative h-0.5 w-4 rounded-full',
featureIndex === activeIndex ? 'bg-gray-600' : 'bg-gray-700',
)}
aria-label={`Go to slide ${featureIndex + 1}`}
onClick={() => {
slideRefs.current[featureIndex].scrollIntoView({
block: 'nearest',
inline: 'nearest',
})
}}
>
<span className="absolute -inset-x-1.5 -inset-y-3" />
</button>
))}
</div>
</>
)
}
export function CloudFeatures() { export function CloudFeatures() {
return ( return (
<section className="bg-gray-50 py-24 sm:py-32"> <section
id="overview"
aria-label="Features for investing all your money"
className="bg-gray-900 py-20 sm:py-32"
>
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow color="accent">Platform Overview</Eyebrow>
Core Features <SectionHeader color="white" className="mt-2">
</Eyebrow> A Decentralized Cloud that Operates Itself
<SectionHeader as="h2" className="mt-6 text-gray-900">
Infrastructure that verifies, heals, and scales itself.
</SectionHeader> </SectionHeader>
<P className="mt-6 text-gray-600"> <P color="light" className="mt-6">
From mesh networking to quantum-safe storage, every capability in Mycelium Cloud orchestrates Kubernetes clusters on the ThreeFold Grid with cryptographic certainty. Networking, storage, and orchestration are all built-in so developers can deploy critical workloads without wrestling infrastructure.
Mycelium Cloud is designed for sovereign control and autonomous
operationsso your teams focus on shipping workloads instead of
wiring infrastructure.
</P> </P>
</div> </div>
<div className="mt-16 grid gap-8 md:grid-cols-2 xl:grid-cols-3">
{featureSections.map((feature) => (
<div
key={feature.title}
className="flex h-full flex-col rounded-3xl border border-slate-200 bg-white p-8 shadow-sm transition hover:-translate-y-1 hover:border-cyan-300 hover:shadow-lg"
>
<div>
<Small className="text-xs uppercase tracking-[0.3em] text-cyan-500">
Capability
</Small>
<h3 className="mt-4 text-xl font-semibold text-gray-900">
{feature.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600">
{feature.description}
</p>
</div>
<ul className="mt-6 space-y-3 text-sm text-gray-600">
{feature.bullets.map((bullet) => (
<li
key={bullet}
className="flex items-start gap-3 rounded-2xl border border-cyan-100 bg-cyan-50/60 p-3 leading-relaxed"
>
<span className="mt-1 inline-block size-2 rounded-full bg-cyan-500" />
<span>{bullet}</span>
</li>
))}
</ul>
</div>
))}
</div>
</Container> </Container>
<div className="hidden md:mt-20 md:block">
<CloudFeaturesDesktop />
</div>
<div className="mt-16 md:hidden">
<CloudFeaturesMobile />
</div>
</section> </section>
) )
} }

View File

@@ -2,7 +2,7 @@ import { useId } from 'react'
import { Button } from '../../components/Button' import { Button } from '../../components/Button'
import { Container } from '../../components/Container' import { Container } from '../../components/Container'
import { Eyebrow, SectionHeader, P } from '../../components/Texts' import { Eyebrow, H2, P, H5 } from '../../components/Texts'
function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) { function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
const id = useId() const id = useId()
@@ -82,17 +82,17 @@ export function CloudHero() {
<Eyebrow className="tracking-[0.35em] uppercase text-cyan-500"> <Eyebrow className="tracking-[0.35em] uppercase text-cyan-500">
Mycelium Cloud Mycelium Cloud
</Eyebrow> </Eyebrow>
<SectionHeader as="h1" className="mt-6 text-gray-900"> <H2 as="h1" className="mt-6 text-gray-900">
Deploy sovereign Kubernetes clusters on decentralized Deploy sovereign Kubernetes clusters on decentralized
infrastructure. infrastructure.
</SectionHeader> </H2>
<P className="mt-6 text-gray-600"> <H5 className="mt-6 text-gray-600">
Mycelium Cloud turns the ThreeFold Grid into a programmable Mycelium Cloud turns the ThreeFold Grid into a programmable
substrate for K3s. Launch verifiable clusters with nature-inspired substrate for K3s. Launch verifiable clusters with nature-inspired
networking, quantum-safe storage, and zero-image delivery that networking, quantum-safe storage, and zero-image delivery that
keeps every workload deterministic. keeps every workload deterministic.
</P> </H5>
<P className="mt-6 italic text-gray-500"> <P className="mt-6 text-gray-500">
Developer guide to decentralized cloud computing. Developer guide to decentralized cloud computing.
</P> </P>
<div className="mt-10 flex flex-wrap gap-4"> <div className="mt-10 flex flex-wrap gap-4">

View File

@@ -0,0 +1,44 @@
import { H3, H5, Eyebrow } from "../../components/Texts"
import { Button } from "../../components/Button"
export function CloudHeroNew() {
return (
<div
className="relative bg-cover lg:bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/cloudhero4.webp')" }}
>
<div className="mx-auto max-w-7xl lg:px-8">
<div className="px-6 pt-12 pb-24 sm:pb-32 lg:col-span-5 lg:px-0 lg:pt-40 lg:pb-48 xl:col-span-5">
<div className="mx-auto max-w-2xl lg:mx-0">
<Eyebrow>
Mycelium Cloud
</Eyebrow>
<H3 className="mt-4">
Deploy sovereign Kubernetes clusters on decentralized infrastructure.
</H3>
<H5 className="mt-8 text-lg text-gray-600">
Mycelium Cloud turns the ThreeFold Grid into a programmable substrate for K3s.
</H5>
<H5 className="mt-4 text-lg text-gray-600">
Launch verifiable clusters with nature-inspired networking, quantum-safe storage, and zero-image delivery that keeps every workload deterministic.
</H5>
<div className="mt-10 flex items-center gap-x-6">
<Button
to="#"
variant="solid"
className=""
color="cyan"
>
Get started
</Button>
<Button to="#" variant="outline">
Explore Docs <span aria-hidden="true"> </span>
</Button>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -39,7 +39,7 @@ export function CloudOverview() {
</div> </div>
<Container className="relative"> <Container className="relative">
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-400"> <Eyebrow>
Platform Overview Platform Overview
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" color="light" className="mt-6 font-medium"> <SectionHeader as="h2" color="light" className="mt-6 font-medium">
@@ -51,7 +51,7 @@ export function CloudOverview() {
orchestration are all built-in so developers can deploy critical orchestration are all built-in so developers can deploy critical
workloads without wrestling infrastructure. workloads without wrestling infrastructure.
</P> </P>
<P color="lightSecondary" className="mt-6 italic"> <P color="lightSecondary" className="mt-6">
Declarative, sovereign, and ready for production workloads anywhere. Declarative, sovereign, and ready for production workloads anywhere.
</P> </P>
</div> </div>

View File

@@ -1,28 +1,28 @@
import { AnimatedSection } from '../../components/AnimatedSection' import { AnimatedSection } from '../../components/AnimatedSection'
import { CloudHero } from './CloudHero'
import { CloudOverview } from './CloudOverview'
import { CloudArchitecture } from './CloudArchitecture' import { CloudArchitecture } from './CloudArchitecture'
import { CloudFeatures } from './CloudFeatures' import { CloudFeatures } from './CloudFeatures'
import { CloudGettingStarted } from './CloudGettingStarted' import { CloudGettingStarted } from './CloudGettingStarted'
import { CloudUseCases } from './CloudUseCases' import { CloudUseCases } from './CloudUseCases'
import { SecurityPillars } from './SecurityPillars' import { SecurityPillars } from './SecurityPillars'
import { CloudCTA } from './CloudCTA' import { CloudCTA } from './CloudCTA'
import { CloudHeroNew } from './CloudHeroNew'
export default function CloudPage() { export default function CloudPage() {
return ( return (
<> <>
<AnimatedSection> <AnimatedSection>
<CloudHero /> <CloudHeroNew />
</AnimatedSection>
<AnimatedSection>
<CloudOverview />
</AnimatedSection>
<AnimatedSection>
<CloudArchitecture />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CloudFeatures /> <CloudFeatures />
</AnimatedSection> </AnimatedSection>
<AnimatedSection>
<CloudArchitecture />
</AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CloudGettingStarted /> <CloudGettingStarted />
</AnimatedSection> </AnimatedSection>

View File

@@ -41,7 +41,7 @@ export function CloudUseCases() {
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Use Cases Use Cases
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -8,7 +8,7 @@ export function ComputeHero() {
<div className="relative h-80 overflow-hidden bg-transparent md:absolute md:right-0 md:h-full md:w-1/3 lg:w-1/2"> <div className="relative h-80 overflow-hidden bg-transparent md:absolute md:right-0 md:h-full md:w-1/3 lg:w-1/2">
<img <img
alt="" alt=""
src="/images/computehero4.png" src="/images/cloudhero.webp"
className="size-full object-cover" className="size-full object-cover"
/> />

View File

@@ -43,7 +43,7 @@ export function ComputeOverview() {
precision, knowing the platform verifies, scales, and heals itself precision, knowing the platform verifies, scales, and heals itself
on your behalf. on your behalf.
</P> </P>
<P color="lightSecondary" className="mt-4 italic"> <P color="lightSecondary" className="mt-4">
Deterministic. Self-managing. Stateless by design. Deterministic. Self-managing. Stateless by design.
</P> </P>
</div> </div>

View File

@@ -31,7 +31,7 @@ export function GpuArchitecture() {
<section id="gpu-architecture" className="bg-white py-24 sm:py-32"> <section id="gpu-architecture" className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Technical Architecture Technical Architecture
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -28,7 +28,7 @@ export function GpuHero() {
planetary clusterswith deterministic performance and transparent planetary clusterswith deterministic performance and transparent
cost. cost.
</P> </P>
<P className="mt-4 italic text-gray-500"> <P className="mt-4 text-gray-500">
The energy behind intelligence, orchestrated entirely through code. The energy behind intelligence, orchestrated entirely through code.
</P> </P>
<div className="mt-10 flex flex-wrap gap-4"> <div className="mt-10 flex flex-wrap gap-4">

View File

@@ -37,7 +37,7 @@ export function GpuUseCases() {
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Use Cases Use Cases
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -6,26 +6,23 @@ export function CallToAction() {
return ( return (
<section <section
id="get-started" id="get-started"
className="relative overflow-hidden bg-gray-900 py-32" className="relative overflow-hidden bg-gray-900 lg:py-32 py-24"
> >
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"> <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<CircleBackground color="#06b6d4" className="animate-spin-slower" /> <CircleBackground color="#06b6d4" className="animate-spin-slower" />
</div> </div>
<Container className="relative"> <Container className="relative">
<div className="mx-auto max-w-2xl text-center"> <div className="mx-auto max-w-xl text-center">
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl"> <h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
Activate Your Sovereign <br />Mycelium Stack Activate Your Sovereign <br />Mycelium Stack
</h2> </h2>
<p className="mt-6 text-lg text-gray-300"> <p className="mt-6 text-lg text-gray-300">
Provision cloud workloads, mesh them through the encrypted Mycelium Network, and unlock AI experiences without surrendering control of your infrastructure or your data. Mesh cloud workloads through the encrypted Mycelium Network and unlock AI experiences without ever surrendering control of your infrastructure, performance, or data.
</p> </p>
<div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4"> <div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4">
<Button to="/cloud" variant="solid" color="white"> <Button to="/cloud" variant="solid" color="cyan">
Start Deployment Start Deployment
</Button> </Button>
<Button to="/download" variant="solid" color="cyan">
Get Mycelium Connector
</Button>
<Button <Button
to="https://threefold.info/mycelium_network/docs/" to="https://threefold.info/mycelium_network/docs/"
as="a" as="a"
@@ -33,7 +30,7 @@ export function CallToAction() {
variant="outline" variant="outline"
color="white" color="white"
> >
Read Docs Explore Docs
</Button> </Button>
</div> </div>
</div> </div>

View File

@@ -9,7 +9,7 @@ export function HomeAgent() {
<div className="mx-auto max-w-4xl text-center"> <div className="mx-auto max-w-4xl text-center">
<H2> <H2>
Deploy your own{" "} Deploy your own{" "}
<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"> <span className="text-left text-black font-medium text-7xl bg-clip-text bg-gradient-to-r from-blue-400 via-cyan-400 to-violet-400">
<LayoutTextFlip <LayoutTextFlip
text="" text=""
words={[ words={[

View File

@@ -1,35 +1,49 @@
"use client"; import { H1, H5 } from "@/components/Texts"
import { Button } from "@/components/Button"
import { H1, H5 } from "@/components/Texts";
import { ScrollDownArrow } from '@/components/ScrollDownArrow';
export function HomeAurora() { export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => void }) {
return ( return (
<div <div
style={{ className="relative bg-cover sm:bg-contain bg-right bg-no-repeat"
backgroundImage: "url(/images/homehero1.png)", style={{ backgroundImage: "url('/images/hero11.webp')" }}
backgroundSize: "cover",
backgroundPosition: "center",
}}
className="relative mx-auto flex min-h-screen flex-col items-center gap-6 px-4 pb-24 pt-[20vh] text-gray-800 lg:pb-0"
> >
<div className="text-center -mt-5"> <div className="mx-auto max-w-7xl lg:px-4">
<H1> <div className="px-6 pt-12 pb-24 sm:pb-32 lg:col-span-5 lg:px-0 lg:pt-40 lg:pb-48 xl:col-span-5">
<span className="text-bold lg:text-8xl"> <div className="mx-auto max-w-2xl lg:mx-0">
Full Sovereignty for<br />Cloud, Network & AI. <div className="hidden sm:flex">
</span> <div className="relative rounded-full px-3 py-1 text-sm/6 text-gray-500 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
</H1> Anim aute id magna aliqua ad ad non deserunt sunt.{' '}
</div> <a href="#" className="font-semibold whitespace-nowrap text-cyan-600">
<div className="max-w-4xl text-center font-light text-gray-500"> <span aria-hidden="true" className="absolute inset-0" />
<H5> Read more <span aria-hidden="trwhenue">&rarr;</span>
Build and run mission-critical workloads on distributed compute, </a>
encrypted networking, and sovereign AI orchestration all under your </div>
control, without centralized gatekeepers. </div>
</H5> <H1 className="mt-8">
</div> The Sovereign Agentic Cloud
<div className="pt-6"> </H1>
<ScrollDownArrow /> <H5 className="mt-8 text-lg text-gray-600">
A global, self-healing network you can join.
Host nodes, deploy workloads, or build private AI systems,
all on infrastructure you own and control.
</H5>
<div className="mt-10 flex items-center gap-x-6">
<Button
variant="solid"
className=""
color="cyan"
onClick={onGetStartedClick}
>
Get started
</Button>
<Button to="#" variant="outline">
Explore Docs <span aria-hidden="true"> </span>
</Button>
</div>
</div>
</div>
</div> </div>
</div> </div>
); )
} }

View File

@@ -2,7 +2,7 @@ import createGlobe from "cobe";
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import { motion } from "motion/react"; import { motion } from "motion/react";
import { IconBrandYoutubeFilled } from "@tabler/icons-react"; import { IconBrandYoutubeFilled } from "@tabler/icons-react";
import { H2, P } from '@/components/Texts' import { H2, P, CP, Eyebrow } from '@/components/Texts'
export function HomeBenefits() { export function HomeBenefits() {
@@ -16,13 +16,13 @@ export function HomeBenefits() {
{ {
title: "Autonomous", title: "Autonomous",
description: description:
"The cloud that runs itself. From deployment to scaling, Mycelium Cloud automates everything — so your systems stay fast, resilient, and adaptive.", "The cloud that runs itself. From deployment to scaling, Mycelium Cloud automates everything.",
image: "/images/benefits/autonomous.webp", image: "/images/benefits/autonomous.webp",
}, },
{ {
title: "Energy Efficient", title: "Energy Efficient",
description: description:
"Built on distributed nodes designed for minimal energy use, Mycelium Cloud redefines sustainability without compromising performance.", "Built on distributed nodes designed for minimal energy use, it redefines sustainability without compromising performance.",
image: "/images/benefits/energy.webp", image: "/images/benefits/energy.webp",
}, },
{ {
@@ -33,13 +33,16 @@ export function HomeBenefits() {
}, },
]; ];
return ( return (
<div className="relative z-20 py-10 lg:py-40 max-w-7xl mx-auto"> <div className="relative z-20 py-10 lg:py-24 max-w-7xl mx-auto">
<div className="px-12"> <div className="px-12">
<Eyebrow className="text-center text-cyan-500">
Benefits
</Eyebrow>
<H2 className="text-3xl lg:text-5xl lg:leading-tight max-w-5xl mx-auto text-center tracking-tight font-medium text-black dark:text-white"> <H2 className="text-3xl lg:text-5xl lg:leading-tight max-w-5xl mx-auto text-center tracking-tight font-medium text-black dark:text-white">
Why It Changes Everything Why It Changes Everything
</H2> </H2>
<P className="text-sm lg:text-base max-w-2xl my-4 mx-auto text-neutral-500 text-center font-normal dark:text-neutral-300"> <P className=" max-w-3xl my-4 mx-auto text-center text-gray-600">
Project Mycelium is a new foundation for digital independence. A self-governing, AI-powered infrastructure that gives you control, efficiency, and trust without compromise. Project Mycelium is a new foundation for digital independence. A self-governing, AI-powered infrastructure that gives you control, efficiency, and trust without compromise.
</P> </P>
</div> </div>
@@ -57,9 +60,9 @@ export function HomeBenefits() {
</div> </div>
<div className="w-2/3 p-2 pr-12"> <div className="w-2/3 p-2 pr-12">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[0].title}</h3> <h3 className="text-lg font-semibold text-black dark:text-white">{features[0].title}</h3>
<p className="mt-2 text-sm text-gray-600 dark:text-gray-300"> <CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[0].description} {features[0].description}
</p> </CP>
</div> </div>
</div> </div>
</div> </div>
@@ -76,9 +79,9 @@ export function HomeBenefits() {
</div> </div>
<div className="w-2/3 p-4"> <div className="w-2/3 p-4">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[1].title}</h3> <h3 className="text-lg font-semibold text-black dark:text-white">{features[1].title}</h3>
<p className="mt-2 text-sm text-gray-600 dark:text-gray-300"> <CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[1].description} {features[1].description}
</p> </CP>
</div> </div>
</div> </div>
</div> </div>
@@ -95,9 +98,9 @@ export function HomeBenefits() {
</div> </div>
<div className="w-2/3 p-4"> <div className="w-2/3 p-4">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[2].title}</h3> <h3 className="text-lg font-semibold text-black dark:text-white">{features[2].title}</h3>
<p className="mt-2 text-sm text-gray-600 dark:text-gray-300"> <CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[2].description} {features[2].description}
</p> </CP>
</div> </div>
</div> </div>
</div> </div>
@@ -114,9 +117,9 @@ export function HomeBenefits() {
</div> </div>
<div className="w-2/3 p-2 pr-12"> <div className="w-2/3 p-2 pr-12">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[3].title}</h3> <h3 className="text-lg font-semibold text-black dark:text-white">{features[3].title}</h3>
<p className="mt-2 text-sm text-gray-600 dark:text-gray-300"> <CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[3].description} {features[3].description}
</p> </CP>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -23,7 +23,7 @@ export function HomeCloud() {
/> />
<div className="w-full flex-auto"> <div className="w-full flex-auto">
<H2 className=""> <H2 className="">
Mycelium <span className="font-medium text-7xl italic">Cloud</span> Mycelium <span className="font-medium text-7xl">Cloud</span>
</H2> </H2>
<P className="mt-6 text-lg/8 text-pretty text-gray-600"> <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 A comprehensive platform for deploying and managing Kubernetes clusters on the decentralized Mycelium Grid infrastructure

View File

@@ -4,7 +4,7 @@ import { Globe } from "@/components/ui/Globe"
import { motion } from "framer-motion" import { motion } from "framer-motion"
import { P, CT, CP, SectionHeader, Eyebrow } from "@/components/Texts" import { P, CT, CP, SectionHeader, Eyebrow } from "@/components/Texts"
import { CountUpNumber } from '@/components/CountUpNumber' import { CountUpNumber } from '@/components/CountUpNumber'
import { MagicCard } from '@/components/magicui/magic-card' import { DarkCard } from "@/components/ui/cards";
export function WorldMap() { export function WorldMap() {
return ( return (
@@ -35,7 +35,7 @@ export function WorldMap() {
> >
<Eyebrow color="accent">Decentralized Network</Eyebrow> <Eyebrow color="accent">Decentralized Network</Eyebrow>
<SectionHeader color="light">Project Mycelium is Live.</SectionHeader> <SectionHeader color="light">Project Mycelium is Live.</SectionHeader>
<P className=" mt-4 text-base leading-relaxed" color="light"> <P className=" mt-4" color="light">
Project Mycelium enables anyone to deploy Project Mycelium enables anyone to deploy
their own Internet infrastructure, anywhere. their own Internet infrastructure, anywhere.
</P> </P>
@@ -65,16 +65,13 @@ export function WorldMap() {
transition={{ duration: 0.5, delay: 0.4, ease: "easeOut" }} transition={{ duration: 0.5, delay: 0.4, ease: "easeOut" }}
className="lg:absolute lg:top-12 lg:-left-12 w-80" className="lg:absolute lg:top-12 lg:-left-12 w-80"
> >
<MagicCard <DarkCard>
gradientColor="#334155"
className="shadow-xl shadow-cyan-500/15 border border-gray-500/50 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-xl hover:shadow-cyan-500/20"
>
<div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">CORES</CT></div> <div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">CORES</CT></div>
<div><CountUpNumber end={54958} className="mt-2 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div> <div><CountUpNumber end={54958} className="mt-2 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div>
<CP color="light" className="mt-2 text-sm"> <CP color="light" className="mt-2 text-sm">
Total Central Processing Unit Cores available on the grid. Total Central Processing Unit Cores available on the grid.
</CP> </CP>
</MagicCard> </DarkCard>
</motion.div> </motion.div>
<motion.div <motion.div
@@ -84,16 +81,13 @@ export function WorldMap() {
transition={{ duration: 0.5, delay: 0.5, ease: "easeOut" }} transition={{ duration: 0.5, delay: 0.5, ease: "easeOut" }}
className="lg:absolute lg:-top-10 lg:right-0 w-80" className="lg:absolute lg:-top-10 lg:right-0 w-80"
> >
<MagicCard <DarkCard>
gradientColor="#334155"
className="shadow-xl shadow-cyan-500/15 border border-gray-500/50 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-xl hover:shadow-cyan-500/20"
>
<div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">NODES</CT></div> <div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">NODES</CT></div>
<div><CountUpNumber end={1493} className="mt-4 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div> <div><CountUpNumber end={1493} className="mt-4 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div>
<CP color="light" className="mt-2 text-sm"> <CP color="light" className="mt-2 text-sm">
Total number of nodes on the grid. Total number of nodes on the grid.
</CP> </CP>
</MagicCard> </DarkCard>
</motion.div> </motion.div>
<motion.div <motion.div
@@ -103,16 +97,13 @@ export function WorldMap() {
transition={{ duration: 0.5, delay: 0.6, ease: "easeOut" }} transition={{ duration: 0.5, delay: 0.6, ease: "easeOut" }}
className="lg:absolute lg:bottom-28 lg:-left-12 w-80" className="lg:absolute lg:bottom-28 lg:-left-12 w-80"
> >
<MagicCard <DarkCard>
gradientColor="#334155"
className="shadow-xl shadow-cyan-500/15 border border-gray-500/50 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-xl hover:shadow-cyan-500/20"
>
<div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">SSD CAPACITY</CT></div> <div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">SSD CAPACITY</CT></div>
<div><CountUpNumber end={5388956} className="mt-2 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div> <div><CountUpNumber end={5388956} className="mt-2 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div>
<CP color="light" className="mt-2 text-sm"> <CP color="light" className="mt-2 text-sm">
Total GB amount of storage (SSD, HDD, & RAM) on the grid. Total GB amount of storage (SSD, HDD, & RAM) on the grid.
</CP> </CP>
</MagicCard> </DarkCard>
</motion.div> </motion.div>
<motion.div <motion.div
@@ -122,16 +113,13 @@ export function WorldMap() {
transition={{ duration: 0.5, delay: 0.7, ease: "easeOut" }} transition={{ duration: 0.5, delay: 0.7, ease: "easeOut" }}
className="lg:absolute lg:top-47 lg:right-0 w-80" className="lg:absolute lg:top-47 lg:right-0 w-80"
> >
<MagicCard <DarkCard>
gradientColor="#334155"
className="shadow-xl shadow-cyan-500/15 border border-gray-500/50 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-xl hover:shadow-cyan-500/20"
>
<div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">COUNTRIES</CT></div> <div><CT color="light" className="uppercase tracking-wide [text-shadow:0_0_12px_var(--color-cyan-500)]">COUNTRIES</CT></div>
<div><CountUpNumber end={44} className="mt-2 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div> <div><CountUpNumber end={44} className="mt-2 text-3xl font-bold text-white [text-shadow:0_0_12px_var(--color-cyan-500)]" /></div>
<CP color="light" className="mt-2 text-sm"> <CP color="light" className="mt-2 text-sm">
Total number of countries with active nodes. Total number of countries with active nodes.
</CP> </CP>
</MagicCard> </DarkCard>
</motion.div> </motion.div>
</div> </div>
</div> </div>

View File

@@ -9,7 +9,7 @@ export function HomeMapSection() {
<div className="max-w-7xl mx-auto text-center"> <div className="max-w-7xl mx-auto text-center">
<H2 className="font-medium text-xl md:text-4xl dark:text-white text-gray-800"> <H2 className="font-medium text-xl md:text-4xl dark:text-white text-gray-800">
Mycelium Network is{" "} Mycelium Network is{" "}
<span className="text-black text-bold italic"> <span className="text-black text-bold">
{"Live.".split("").map((word, idx) => ( {"Live.".split("").map((word, idx) => (
<motion.span <motion.span
key={idx} key={idx}

View File

@@ -1,3 +1,4 @@
import { useRef } from 'react'
import { AnimatedSection } from '../../components/AnimatedSection' import { AnimatedSection } from '../../components/AnimatedSection'
import { HomeAurora } from './HomeAurora' import { HomeAurora } from './HomeAurora'
import { StackSectionLight } from './StackSection' import { StackSectionLight } from './StackSection'
@@ -8,10 +9,15 @@ import { HomeSlider } from './HomeSlider'
export default function HomePage() { export default function HomePage() {
const sliderRef = useRef<HTMLDivElement>(null)
const handleScrollToSlider = () => {
sliderRef.current?.scrollIntoView({ behavior: 'smooth' })
}
return ( return (
<div> <div>
<AnimatedSection> <AnimatedSection>
<HomeAurora /> <HomeAurora onGetStartedClick={handleScrollToSlider} />
</AnimatedSection> </AnimatedSection>
<AnimatedSection id="next-section"> <AnimatedSection id="next-section">
@@ -23,7 +29,7 @@ export default function HomePage() {
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection ref={sliderRef}>
<HomeSlider /> <HomeSlider />
</AnimatedSection> </AnimatedSection>

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import { Carousel, Card } from "@/components/ui/apple-cards-carousel"; import { Carousel, Card } from "@/components/ui/apple-cards-carousel";
import { H3, P } from "@/components/Texts"; import { H3, P , Eyebrow} from "@/components/Texts";
export function HomeSlider() { export function HomeSlider() {
const cards = data.map((card) => ( const cards = data.map((card) => (
@@ -11,8 +11,11 @@ export function HomeSlider() {
return ( return (
<div className="w-full h-full py-20 bg-[#0b0b0b]"> <div className="w-full h-full py-20 bg-[#0b0b0b]">
<div className="max-w-7xl mx-auto pl-4"> <div className="max-w-7xl mx-auto pl-4">
<Eyebrow className="text-left">
Ecosystem
</Eyebrow>
<H3 className="text-left text-white"> <H3 className="text-left text-white">
Discover the Mycelium Ecosystem Discover the Mycelium Components
</H3> </H3>
<div className="mt-4 max-w-3xl"> <div className="mt-4 max-w-3xl">
<P className="text-left text-neutral-400"> <P className="text-left text-neutral-400">
@@ -26,19 +29,19 @@ export function HomeSlider() {
} }
import networkImage from "@/images/slider/network1.jpg"; import networkImage from "/images/pages/network.webp";
import agentImage from "@/images/slider/agent1.jpg"; import agentImage from "/images/pages/agent.webp";
import cloudImage from "@/images/slider/cloud1.jpg"; import cloudImage from "/images/pages/cloud.webp";
import gpuImage from "@/images/slider/gpu1.jpg"; import gpuImage from "/images/pages/gpu.webp";
import computeImage from "@/images/slider/compute1.jpg"; import computeImage from "/images/pages/compute.webp";
import storageImage from "@/images/slider/storage1.jpg"; import storageImage from "/images/pages/storage.png";
const data = [ const data = [
{ {
category: "DePIN", category: "DePIN",
title: "Mycelium Network", title: "Mycelium Network",
description: "A decentralized network for distributed computing.", description: "A decentralized network for distributed computing.",
src: "/images/gallery/9.webp", src: "/images/pages/network.png",
bg: networkImage, bg: networkImage,
link: "/network", link: "/network",
}, },
@@ -46,7 +49,7 @@ const data = [
category: "AI Agent", category: "AI Agent",
title: "Mycelium Agent", title: "Mycelium Agent",
description: "An intelligent agent for task automation.", description: "An intelligent agent for task automation.",
src: "/images/gallery/2.webp", src: "/images/pages/agent.png",
bg: agentImage, bg: agentImage,
link: "/agent", link: "/agent",
}, },
@@ -54,7 +57,7 @@ const data = [
category: "Cloud", category: "Cloud",
title: "Mycelium Cloud", title: "Mycelium Cloud",
description: "Decentralized cloud storage and services.", description: "Decentralized cloud storage and services.",
src: "/images/gallery/3.webp", src: "/images/pages/cloud.png",
bg: cloudImage, bg: cloudImage,
link: "/cloud", link: "/cloud",
}, },
@@ -63,7 +66,7 @@ const data = [
category: "GPU", category: "GPU",
title: "Mycelium GPU", title: "Mycelium GPU",
description: "Access to a global network of GPUs.", description: "Access to a global network of GPUs.",
src: "/images/gallery/4.webp", src: "/images/pages/gpu.png",
bg: gpuImage, bg: gpuImage,
link: "/gpu", link: "/gpu",
}, },
@@ -71,7 +74,7 @@ const data = [
category: "Compute", category: "Compute",
title: "Mycelium Compute", title: "Mycelium Compute",
description: "Run computations on a distributed network.", description: "Run computations on a distributed network.",
src: "/images/gallery/5.webp", src: "/images/pages/compute.png",
bg: computeImage, bg: computeImage,
link: "/compute", link: "/compute",
}, },
@@ -79,7 +82,7 @@ const data = [
category: "Storage", category: "Storage",
title: "Mycelium Storage", title: "Mycelium Storage",
description: "Secure and decentralized data storage.", description: "Secure and decentralized data storage.",
src: "/images/gallery/6.webp", src: "/images/pages/storage.png",
bg: storageImage, bg: storageImage,
link: "/storage", link: "/storage",
}, },

View File

@@ -2,12 +2,12 @@
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { StackedCubesLight } from "@/components/ui/StackedCubesLight"; import { StackedCubesLight } from "@/components/ui/StackedCubesLight";
import { P, SectionHeader, Eyebrow } from "@/components/Texts"; import { P, Eyebrow, H3 } from "@/components/Texts";
import { FadeIn } from "@/components/ui/FadeIn"; import { FadeIn } from "@/components/ui/FadeIn";
export function StackSectionLight() { export function StackSectionLight() {
return ( return (
<section className="relative w-full overflow-hidden py-24 lg:py-40 isolate"> <section className="relative w-full overflow-hidden py-24 isolate">
{/* === Background Layer === */} {/* === Background Layer === */}
<div className="absolute inset-0 z-0 bg-transparent"> <div className="absolute inset-0 z-0 bg-transparent">
{/* Central main aura */} {/* Central main aura */}
@@ -15,7 +15,7 @@ export function StackSectionLight() {
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[1200px] h-[1200px] rounded-full pointer-events-none" className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[1200px] h-[1200px] rounded-full pointer-events-none"
style={{ style={{
background: background:
"radial-gradient(circle, rgba(180,255,255,0.55) 0%, rgba(0,210,255,0.35) 35%, rgba(255,255,255,0) 55%)", "radial-gradient(circle, rgba(180,255,255,0.55) 0%, rgba(0,210,255,0.35) 5%, rgba(255,255,255,0) 10%)",
filter: "blur(140px)", filter: "blur(140px)",
}} }}
animate={{ animate={{
@@ -56,13 +56,13 @@ export function StackSectionLight() {
<div className="text-center lg:text-left z-10"> <div className="text-center lg:text-left z-10">
<FadeIn> <FadeIn>
<Eyebrow color="accent">Technology Layers</Eyebrow> <Eyebrow color="accent">Technology Layers</Eyebrow>
<SectionHeader color="dark" className="text-4xl sm:text-5xl font-semibold"> <H3 color="dark" className="">
The Mycelium Stack Mycelium Stack
</SectionHeader> </H3>
</FadeIn> </FadeIn>
<FadeIn> <FadeIn>
<P color="dark" className="mt-6 text-lg leading-relaxed text-gray-600"> <P color="dark" className="mt-6 text-gray-600">
Project Mycelium unifies compute, storage, networking, and AI into a resilient Project Mycelium unifies compute, storage, networking, and AI into a resilient
ecosystem that preserves data sovereignty, powers seamless collaboration, ecosystem that preserves data sovereignty, powers seamless collaboration,
and keeps every layer of your infrastructure secure end to end on decentralized infrastructure. and keeps every layer of your infrastructure secure end to end on decentralized infrastructure.

View File

@@ -53,7 +53,7 @@ export function StorageArchitecture() {
<section className="bg-gray-50 py-24 sm:py-32"> <section className="bg-gray-50 py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Technical Architecture Technical Architecture
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -64,7 +64,7 @@ export function StorageFeatures() {
<section id="storage-features" className="bg-white py-24 sm:py-32"> <section id="storage-features" className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Core Features Core Features
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -9,7 +9,7 @@ export function StorageHero() {
<div className="relative h-80 overflow-hidden bg-transparent md:absolute md:right-0 md:h-full md:w-1/3 lg:w-1/2"> <div className="relative h-80 overflow-hidden bg-transparent md:absolute md:right-0 md:h-full md:w-1/3 lg:w-1/2">
<img <img
alt="Mycelium Storage visual" alt="Mycelium Storage visual"
src="/images/storagehero2.png" src="/images/storage4.png"
className="size-full object-cover" className="size-full object-cover"
/> />
</div> </div>
@@ -27,7 +27,7 @@ export function StorageHero() {
data exactly where you need it while keeping ownership entirely in data exactly where you need it while keeping ownership entirely in
your hands. your hands.
</P> </P>
<P className="mt-4 italic text-gray-500"> <P className="mt-4 text-gray-500">
Quantum-safe. Self-healing. Universally accessible. Quantum-safe. Self-healing. Universally accessible.
</P> </P>
<div className="mt-10 flex flex-wrap gap-4"> <div className="mt-10 flex flex-wrap gap-4">

View File

@@ -43,11 +43,11 @@ export function StorageOverview() {
{highlights.map((item) => ( {highlights.map((item) => (
<div <div
key={item.title} key={item.title}
className="group relative overflow-hidden rounded-3xl border border-white/10 bg-white/[0.04] p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 hover:bg-white/[0.08]" className="group relative overflow-hidden rounded-3xl border border-white/10 bg-white/4 p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 hover:bg-white/8"
> >
<div className="absolute inset-0 bg-gradient-to-br from-cyan-500/0 via-white/[0.05] to-cyan-300/20 opacity-0 transition group-hover:opacity-100" /> <div className="absolute inset-0 bg-linear-to-br from-cyan-500/0 via-white/5 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative"> <div className="relative">
<Small className="text-xs uppercase tracking-[0.35em] text-cyan-200"> <Small className="text-xs uppercase tracking-[0.16em] text-cyan-200">
{item.label} {item.label}
</Small> </Small>
<h3 className="mt-4 text-lg font-semibold text-white"> <h3 className="mt-4 text-lg font-semibold text-white">

View File

@@ -84,7 +84,7 @@ export function StorageUseCases() {
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Use Cases Use Cases
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -6,6 +6,9 @@ export default {
], ],
theme: { theme: {
extend: { extend: {
fontFamily: {
sans: ['Mulish', 'system-ui', 'Avenir', 'Helvetica', 'Arial', 'sans-serif'],
},
keyframes: { keyframes: {
'glitch-1': { 'glitch-1': {
'0%': { transform: 'none' }, '0%': { transform: 'none' },