60 Commits

Author SHA1 Message Date
c68b4e5de9 Merge branch 'development' 2025-11-20 13:37:31 +01:00
c3b171e3b2 refactor: update cyan accent colors from cyan-400 to cyan-500 across multiple components for improved contrast
- Changed AgentBento subtitle text from text-cyan-400 to text-cyan-500
- Changed CloudIntro key capabilities label from text-cyan-400 to text-cyan-500
- Changed ComputeCapabilities eyebrow from text-cyan-400 to text-cyan-500
- Changed GpuCapabilities link from text-cyan-400/hover:text-cyan-300 to text-cyan-500/hover:text-cyan-400
- Changed GpuOverview eyebrow from text-cyan-400 to text-cyan-500
2025-11-20 13:35:10 +01:00
ed995113df remove nvm 2025-11-20 13:20:23 +02:00
357b2f58c3 update SEO 2025-11-20 13:14:14 +02:00
7d8ae1d26d refactor: add responsive vertical translation to animation SVGs with lg breakpoint
- Changed vertical translate classes to only apply on large screens (lg:) across agent animations (AgentCoordination, DeterministicExecution, Fungistor, Herodb, MOSSandboxes, MyceliumMesh)
- Changed NoCentral home animation from -translate-y-10 to lg:-translate-y-10
- Updated pods animations with mobile-first approach: Connectivity (-translate-y-12 mobile, lg:translate-y-0), DataControl (maintains -translate-y-12 on
2025-11-19 19:01:17 +01:00
3c4da26ecb refactor: reduce cyan glow opacity in CallToAction components across all pages for subtler visual effect
- Changed fillOpacity from 0.4 to 0.3 in mycelium-cyan-glow radial gradient circles across agents, cloud, compute, gpu, home, network, nodes, pods, and storage CallToAction components
2025-11-19 18:49:53 +01:00
023921a6cc refactor: adjust NoSinglePoint animation width from 720 to 760 for improved aspect ratio alignment
- Changed W constant from 720 to 760 to better match aspect ratio with other home animations
2025-11-19 18:45:34 +01:00
8e033a3c21 refactor: add vertical translation to agent animation SVGs for improved positioning
- Added -translate-y-6 to AgentCoordination and DeterministicExecution SVGs
- Added -translate-y-16 to Fungistor and MOSSandboxes SVGs
- Added -translate-y-18 to Herodb SVG
- Added -translate-y-4 to MyceliumMesh SVG
2025-11-19 18:43:54 +01:00
01b1c20b60 refactor: adjust AgentHeroAlt text container width and split description into two paragraphs
- Changed max-w-2xl to max-w-xl for narrower text container
- Split description text into two separate P components with mt-4 spacing between them for improved readability
2025-11-19 18:37:36 +01:00
c962743737 refactor: adjust text colors, animation positioning, and hover effects across multiple components
- Changed AgentHeroAlt and Homepod description text from text-gray-800 to text-gray-600 for softer contrast
- Added vertical translation to animation SVGs: NoCentral (-translate-y-10), DataControl (-translate-y-12), Security (translate-y-6), Resilience (translate-y-5)
- Updated Resilience and Security danger color from red (#ff4d4d) to gray (#9ca3af)
- Changed NodeBenefits card border from border-gray-300
2025-11-19 18:33:56 +01:00
e62c4a5688 refactor: standardize background color from off-white to pure white across multiple components
- Changed bg-[#FDFDFD] to bg-white in AgentPro, CloudPros, and PodsPro intro sections
- Added explicit bg-white class to PodsFeatures Container component for consistency
2025-11-19 18:19:04 +01:00
6b735b5a40 refactor: update line-height in CP text component and increase vertical padding in NodeSpecs cards
- Changed CP component line-height from leading-tight to leading-normal for improved readability
- Increased NodeSpecs inner card vertical padding from py-4 to py-6 for better spacing
2025-11-19 18:15:54 +01:00
7b9cf135e4 refactor: update button colors in CallToAction and Hero components for improved contrast
- Changed link button color from cyan to white in agents, home, and network CallToAction components
- Updated network Hero secondary button from dark to gray outline variant
2025-11-19 18:13:30 +01:00
544d7d541b refactor: remove unused video assets from public directory
- Deleted 14 unused MP4 video files (agent, benefits, chip_vid, cloud, cta, deterministic, fungistor, herodb, mesh, mhero, mycelium2, sandbox, universal)
- Removed 1 unused JPG image file (benefits.jpg)
2025-11-19 18:05:36 +01:00
b21f874a05 refactor: adjust spacing and text styling in network feature components
- Reduced NetworkCapabilities description margin from mt-3 to mt-2 and removed text-lg class
- Changed PrimaryFeatures mobile description from color="secondary" to text-gray-200 with mt-2 (note: appears to have typo "mt-" instead of "mt-2")
2025-11-19 18:04:06 +01:00
e6b194e8c7 refactor: adjust spacing and styling across multiple components for visual consistency
- Increased HomeAurora subtitle margin from mt-4 to mt-6 for better spacing
- Added bg-white to HomeDesign content container for explicit background
- Removed bg-white from HomeTab top separator div
- Reduced network Hero title margin from mt-8 to mt-4 and second paragraph margin from mt-6 to mt-4
- Changed network Hero secondary button variant from cyan to dark
- Reduced NetworkPros title margin from mt-4 to mt-2
2025-11-19 18:00:35 +01:00
a8105a0551 refactor: replace custom links with Button component in CallToAction components
- Replaced custom <a> tag with Button component (as="a", variant="link", color="cyan") in agents CallToAction
- Replaced Link component with Button component (variant="link", color="cyan") in network CallToAction
- Removed unused Link import from network CallToAction
- Standardized link styling across CallToAction components for consistency
2025-11-19 17:51:30 +01:00
de5d990fc9 refactor: update page title/description and enhance HomeTab card hover effects
- Changed page title from "Unleash the Power of Decentralized Networks" to "Built for Digital Sovereignty"
- Updated meta description to emphasize sovereign peer-to-peer network and user-controlled infrastructure
- Refactored HomeTab card hover effects: moved scale transform from inner div to parent Link element
- Added border-transparent with hover:border-cyan-500 to card outline divs for cleaner hover state
- Remove
2025-11-19 17:45:39 +01:00
29d2b76db9 refactor: adjust PodsHow layout spacing and reorder bottom border elements
- Added lg:-mt-8 negative margin to left content div for better vertical alignment on large screens
- Reordered bottom border elements: moved full-width border-b before max-w-7xl container
- Added bg-transparent class to max-w-7xl container div
- Added descriptive comment for bottom horizontal line section
2025-11-19 17:34:32 +01:00
a0beec808e refactor: adjust PodsWhat grid gap and icon size for better visual balance
- Reduced grid gap from gap-12 to gap-8 for tighter spacing between pod cards
- Increased icon dimensions from h-6 w-6 to h-10 w-10 for improved visual prominence
2025-11-19 17:31:52 +01:00
96c445aa41 refactor: update outline gray button border color from gray-300 to gray-200
- Changed border-gray-300 to border-gray-200 in outline gray variant for consistency with other border color updates across the application
2025-11-19 17:29:30 +01:00
ce4b4b3360 refactor: update border colors from gray-200 to gray-100 in HomeDesign and add overflow-hidden to pods CallToAction
- Changed border-gray-200 to border-gray-100 across HomeDesign component borders and benefit cards
- Added overflow-hidden class to pods CallToAction main container div
2025-11-19 17:25:34 +01:00
c849c74a53 refactor: enhance CallToAction cyan glow visibility and add overflow-hidden across all pages
- Increased cyan radial glow fillOpacity from 0.2 to 0.4 for better visibility
- Added overflow-hidden class to main container div to prevent glow overflow
- Applied changes consistently across agents, cloud, compute, gpu, network, nodes, pods, and storage CallToAction components
2025-11-19 17:23:08 +01:00
7bc895d8be refactor: update favicon and adjust Footer tagline and NoSinglePoint animation dimensions
- Replaced favicon.ico with new version
- Changed Footer tagline from "Unleash the Power of Decentralization" to "Built for Digital Sovereignty"
- Adjusted NoSinglePoint animation dimensions from 720x540 to 720x420 for better alignment with other home animations
- Updated dimension comments to reflect aspect ratio and visual height alignment goals
2025-11-19 17:15:03 +01:00
c0b84fd578 refactor: optimize logomark.svg file size and structure
- Minified SVG markup by removing unnecessary whitespace and line breaks
- Consolidated SVG definition into single line for improved loading performance
- Maintained all visual attributes and rendering properties
- No changes to actual logo appearance or dimensions
2025-11-19 16:49:53 +01:00
6d96ff9ea8 refactor: remove placeholder CTAs and links across multiple pages
- Removed unused Button imports from AgentHeroAlt, GallerySection, ComputeCapabilities, and StorageCapabilitiesNew
- Replaced placeholder buttons/links with TODO comments indicating future implementation
- Changed StorageCoreValue value items from <a> to <div> and removed href/target/rel attributes
- Added descriptive TODO comments explaining what was previously rendered and what needs to be added
- Affected components: AgentHeroAlt (
2025-11-19 16:42:48 +01:00
f1e1721b25 refactor: simplify MailerLite integration in Homepod component
- Removed unused React import
- Removed comments about global types file setup
- Replaced window.ml_account type checking with inline type assertion using (window as any)
- Simplified function existence check to use typeof === 'function'
- Streamlined inline comments for clarity
2025-11-19 16:09:47 +01:00
aed3e8ed25 Merge branch 'development_ehab' into development 2025-11-19 16:07:45 +01:00
f126287018 refactor: add line break to HomeAurora heading for improved readability
- Added <br /> tag to split "Private, Distributed Infrastructure Built" and "for Digital Sovereignty" across two lines
- Removed trailing whitespace from first line of heading text
2025-11-19 16:05:15 +01:00
9f1e78e116 refactor: hide empty architecture card placeholder on mobile
- Added hidden md:flex classes to empty architecture card placeholder div
- Maintains desktop visibility while hiding on mobile for better responsive layout
2025-11-19 16:03:05 +01:00
97fdf3aa4f Merge remote-tracking branch 'origin/development_ehab' into development 2025-11-19 13:10:57 +01:00
c1ca5e35f0 refactor: add link variant to Button component and enhance CallToAction and HomeDesign styling
- Added 'link' variant to Button with baseStyles and variantStyles for cyan, white, and dark colors
- Updated Button type definitions to include link variant with proper color options
- Refactored default variant/color logic to use explicit conditionals for type safety
- Changed outline variant border from single to border-2 and added font-semibold
- Updated outline variant hover states to include text
2025-11-19 13:09:29 +01:00
e5ed88b676 refactor: update DevHub and DownloadHero layout with consistent borders and spacing
- Changed DevHub from div to section with max-w-8xl container
- Added top spacing divider with py-6 and gray-800 borders to DevHub
- Added top and side borders (border-t, border-l, border-r) to DevHub content area
- Changed DevHub background to #111111 with reduced padding (py-12)
- Added bottom border and spacing divider to DevHub matching NetworkDownload pattern
- Changed DownloadHero from div to section with i
2025-11-19 12:56:36 +01:00
6beb9c1432 refactor: update logo assets and fix logo paths in Header and Footer components
- Added mainlogo.png to public/images directory
- Created mainlogo.svg and logomark.svg in src/images/logos directory
- Updated Header and HeaderDark to use mainlogo.svg instead of logo_1.png
- Fixed Footer logomark path from /images/logomark.svg to src/images/logos/logomark.svg
2025-11-19 12:48:55 +01:00
a9f53224cf refactor: add spacing divider below NodeProducts bottom border
- Removed bg-[#121212] from bottom border div
- Added transparent spacing divider with py-6 padding and gray-800 side borders
- Updated comment to indicate spacing addition
2025-11-19 12:33:28 +01:00
3df73ec418 refactor: add mobile hero images to AgentHeroAlt, NodeHero, and Homepod and adjust padding
- Added mobile-only hero images with mb-8 spacing and md:hidden visibility
  - AgentHeroAlt: /images/mobile/agents.jpg
  - NodeHero: /images/mobile/nodes.jpg
  - Homepod: /images/mobile/pods.jpg
- Changed vertical padding from py-16 to pb-12 pt-4 for mobile, maintaining lg:py-24 for desktop
- Positioned mobile images above content with w-full and object-cover styling
2025-11-19 12:32:07 +01:00
c6efc29ab6 refactor: add mobile hero image to CloudHeroNew and adjust padding
- Added mobile-only hero image (/images/mobile/cloudpage.jpg) with mb-8 spacing and md:hidden visibility
- Changed vertical padding from py-16 to pb-12 pt-4 for mobile, maintaining lg:py-24 for desktop
- Positioned mobile image above content with w-full and object-cover styling
2025-11-19 12:27:06 +01:00
bec52e7185 refactor: add mobile hero image to HomeAurora and adjust padding
- Added mobile-only hero image (/images/mobile/homepage.jpg) with mb-8 spacing and md:hidden visibility
- Changed vertical padding from py-16 to pb-12 pt-8 for mobile, maintaining lg:py-32 for desktop
- Positioned mobile image above content with w-full and object-cover styling
2025-11-19 12:24:22 +01:00
29f713cd2f refactor: make CallToAction description text responsive across all pages
- Changed text-lg to lg:text-lg text-base for responsive font sizing on mobile
- Applied to description paragraphs in CallToAction components across agents, compute, gpu, home, network, nodes, pods, and storage pages
- Added leading-normal class to PodsHow animated text span for consistent line height
2025-11-19 12:11:27 +01:00
d8a7a7331a refactor: add device icons to PodsFeatures cards and wrap PodsPage sections with AnimatedSection
- Added useId import for unique gradient IDs in SVG icons
- Created six device icon components: DeviceArrowIcon, DeviceCardsIcon, DeviceClockIcon, DeviceListIcon, DeviceLockIcon, DeviceChartIcon
- Mapped icons array to use cases with corresponding device icons
- Updated PodsFeatures to render icons above card titles with h-8 w-8 sizing
- Added mt-6 spacing to card titles for icon separation
- Wrapped all
2025-11-19 12:11:19 +01:00
00c5f7f880 refactor: revert border colors from gray-200 to gray-100 in SecondaryFeatures
- Changed border-gray-200 back to border-gray-100 for top/bottom horizontal lines and spacing dividers
- Maintained border-gray-200 for main container borders
2025-11-18 14:56:28 +01:00
2dbcda4997 refactor: update border colors from gray-100 to gray-200 in SecondaryFeatures
- Changed all border-gray-100 classes to border-gray-200 for increased contrast
- Applied to top/bottom horizontal lines, container borders, and feature card borders
2025-11-18 14:55:27 +01:00
979d151537 refactor: reduce top margin in Nodes CallToAction CTA section
- Changed top margin from mt-10 to mt-6 for CTA cards container for tighter spacing
2025-11-18 14:54:04 +01:00
252e2335c2 refactor: add text-black color to NodeSteps circle numbers for better contrast
- Added text-black class to step number circles to ensure proper text visibility against white background
2025-11-18 14:53:18 +01:00
9b2c406e9e refactor: update HomeGlobe grid statistics values
- Updated CORES count from 54958 to 31611
- Updated NODES count from 1493 to 1153
- Updated SSD CAPACITY from 5388956 to 4203991 GB
2025-11-18 14:48:12 +01:00
791216433c refactor: add bottom border and spacing to AgentBento section
- Added horizontal border line with border-gray-800 styling
- Added transparent spacer div with py-6 padding and max-w-7xl container
- Applied vertical borders (left/right only) to spacer using border-t-0 border-b-0
2025-11-18 14:45:29 +01:00
a4a6c95612 refactor: add bidirectional scrolling support to InfiniteMovingCards component
- Added infinite-scroll-right keyframe animation with 50% translateX for right direction
- Updated InfiniteMovingCards to conditionally apply animate-infinite-scroll or animate-infinite-scroll-right based on direction prop
- Added animate-infinite-scroll-right class with linear infinite animation using CSS variable duration
2025-11-18 14:43:53 +01:00
da5cf2d4a2 refactor: remove unused props and imports, standardize Eyebrow styling in SecondaryFeatures and StorageFeatures
- Removed unused onGetStartedClick prop from CloudHeroNew component
- Removed unused H3 and P imports from NetworkDownload
- Added H3, P, and Eyebrow imports to SecondaryFeatures
- Replaced generic elements with typography components (Eyebrow, H3, P) in SecondaryFeatures
- Changed Eyebrow styling to text-cyan-500 uppercase tracking-[0.16em] in SecondaryFeatures
- Updated description text
2025-11-18 14:36:58 +01:00
d2e2e87a0c refactor: improve NodeProducts, NodeSpecs, and NodeSteps layout and styling with optimized images
- Optimized binary images: agent1.png, ainode.png, autonomous.png, edge.png, edgenode.png, encryptednode.png, energy.png, fullstack.png, uptime.png
- Changed NodeProducts grid gap from gap-16 lg:gap-24 to gap-4 lg:gap-24 for tighter mobile spacing
- Added order-2 lg:order-1 to text area and order-1 lg:order-2 to image for mobile layout swap
- Replaced custom button styles with Button component using
2025-11-18 14:26:52 +01:00
a8d91a1624 refactor: improve NodeHero and NodeBenefits typography and layout with AnimatedSection wrappers
- Changed NodeBenefits from SectionHeader to H3 component with mt-2 and text-white
- Updated NodeBenefits description from P color="light" to text-gray-200
- Changed benefit cards border-radius from rounded-2xl to rounded-md
- Added responsive padding to benefit cards: lg:p-8 p-6
- Updated benefit description from text-gray-200 to font-light text-gray-300
- Removed NodeHero background image inline style in
2025-11-18 12:59:48 +01:00
f9ee299362 refactor: improve CallToAction typography and AgentBento mobile layout across pages
- Added leading-normal to all CallToAction description paragraphs for better readability
- Changed AgentBento empty animation placeholder to hidden on mobile using hidden md:flex
- Reduced top margin from mt-8 to mt-6 for agents CallToAction CTA cards
- Changed "Follow Development" link margin from mt-5 to lg:mt-5 mt-0 for responsive spacing
- Applied leading-normal changes to agents, compute, gpu, home, network, nodes
2025-11-18 12:50:36 +01:00
8509b80f47 refactor: improve AgentUseCase layout and typography with responsive background image
- Added leading-normal to CT text component for better readability
- Changed AgentHeroAlt background image to only display on md+ screens using md:bg-[url(...)] classes
- Removed inline style attribute in favor of Tailwind classes for background image
- Updated AgentUseCase to use typography components (H3, CT, CP) instead of generic elements
- Changed Eyebrow color from text-cyan-600 to text-cyan-500
- Adjuste
2025-11-18 12:47:51 +01:00
7d6bbc2763 refactor: improve spacing and typography in Pods CallToAction section
- Added leading-normal to description paragraphs for better readability
- Reduced top margin from mt-10 to mt-6 for benefits list and CTA cards
- Changed benefits grid gap from gap-y-3 to gap-y-1 lg:gap-y-3 for tighter mobile spacing
- Reduced horizontal gap between CTA cards from gap-x-10 to gap-x-8
2025-11-18 12:38:41 +01:00
4cf6f63139 refactor: increase description text size and restore Eyebrow styling in AgentPro and CloudPros
- Changed description text from text-sm to text-base in both AgentPro and CloudPros
- Restored uppercase tracking-[0.16em] styling to CloudPros Eyebrow component
2025-11-18 12:31:18 +01:00
ef9865862b refactor: standardize Eyebrow styling and improve CloudHeroNew typography across pages
- Changed all Eyebrow components from uppercase tracking-[0.16em] text-cyan-600 to text-cyan-500
- Applied changes to AgentPro, CloudPros, HomeDesign, NetworkPros, PodsDesign, and PodsPro
- Updated CloudHeroNew to hide background image on mobile using md:bg-[url(...)] classes
- Replaced inline style with Tailwind classes for background image in CloudHeroNew
- Converted CloudHeroNew description from two separate
2025-11-18 12:30:55 +01:00
503fe26303 refactor: improve Hero and NetworkDownload mobile responsiveness and layout
- Reduced Hero section bottom padding from pb-24 to pb-12 on mobile
- Added mt-8 top margin to Hero image container on mobile
- Hidden BackgroundIllustration on mobile using hidden md:block
- Removed fixed height from Hero image container and added flex centering
- Changed Hero image from w-auto to w-full for better mobile scaling
- Removed manual link and simplified NetworkDownload description text
- Reduced NetworkDownload gri
2025-11-18 12:23:16 +01:00
39b20f30a4 refactor: reduce gap spacing in HomeDesign benefits grid from gap-4 to gap-2
- Changed mobile grid gap from gap-4 to gap-2 while maintaining lg:gap-0 for desktop
2025-11-18 12:13:46 +01:00
d53f2d943f refactor: make Button text responsive and hide HomeAurora background on mobile
- Changed Button text size from text-base to text-sm md:text-base for both solid and outline variants
- Updated HomeAurora background image to only display on md+ screens using bg-none md:bg-[url(...)]
- Removed inline style attribute in favor of Tailwind class for background image
- Cleaned up extra spacing in className
2025-11-18 12:12:05 +01:00
3213179ff6 refactor: convert "Deploy in Cloud" buttons to external links across home and network pages
- Changed all "Deploy in Cloud" buttons from internal /cloud routes to external myceliumcloud.tf links
- Updated Button components to use as="a" with target="_blank" and rel="noopener noreferrer"
- Removed arrow character from some button labels for consistency
- Applied changes to CallToAction, HomeAurora, HomeHero, and HomeNew components
2025-11-18 12:00:22 +01:00
c289c63856 refactor: update CTA buttons with external links and navigation improvements
- Changed "Deploy a Model" button in agents CallToAction to external link (myceliumcloud.tf) with target="_blank"
- Updated "Host a Node" button path from /host to /nodes in agents and cloud CallToAction
- Changed cloud CallToAction "Start Deploying" button to external link with target="_blank"
- Updated CloudHeroNew buttons to external links for myceliumcloud.tf and docs
- Removed onGetStartedClick handler from CloudHeroNew in
2025-11-18 11:56:33 +01:00
116 changed files with 868 additions and 499 deletions

View File

@@ -0,0 +1 @@
google-site-verification: google5dd3a8b700455c0e.html

View File

@@ -4,8 +4,10 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Project Mycelium - Unleash the Power of Decentralized Networks</title>
<meta name="description" content="Project Mycelium's technology enables anyone to deploy their own Internet infrastructure, anywhere." />
<meta name="google-site-verification" content="rRrZkMEhdC4yFe_BrENEzYmy2bRfD-VE6RTRiDJNLkg" />
<title>Project Mycelium - Built for Digital Sovereignty</title>
<meta name="description" content="Discover Project Mycelium. A sovereign peer-to-peer network for private communication, storage, and compute. Build and run your digital environment on infrastructure you control." />
<meta name="keywords" content="Project Mycelium, Mycelium, digital sovereignty, decentralized network, peer-to-peer infrastructure, private storage, secure compute, sovereign cloud, edge cloud" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<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" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 922 KiB

After

Width:  |  Height:  |  Size: 618 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 KiB

After

Width:  |  Height:  |  Size: 508 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 988 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 KiB

After

Width:  |  Height:  |  Size: 792 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 861 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 KiB

After

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
public/images/mainlogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3,9 +3,11 @@ import clsx from 'clsx'
const baseStyles = {
solid:
'inline-flex justify-center rounded-full py-2 px-5 text-base font-semibold transition-colors',
'inline-flex justify-center rounded-full py-2 px-5 text-sm md:text-base font-semibold transition-colors',
outline:
'inline-flex justify-center bg-transparent rounded-full border py-[calc(--spacing(2)-1px)] px-[calc(--spacing(5)-1px)] text-base transition-colors',
'inline-flex justify-center bg-transparent font-semibold rounded-full border border-2 py-[calc(--spacing(2)-1px)] px-[calc(--spacing(5)-1px)] text-sm md:text-base transition-colors',
link:
'inline-flex items-center text-sm md:text-base font-semibold transition-colors',
}
const variantStyles = {
@@ -18,8 +20,13 @@ const variantStyles = {
},
outline: {
cyan: 'border-cyan-500 text-cyan-500',
gray: 'border-gray-300 text-gray-700 hover:border-cyan-500 active:border-cyan-500',
white: 'border-gray-300 text-white hover:border-cyan-500 active:border-cyan-500',
gray: 'border-gray-200 text-gray-600 hover:text-cyan-500 hover:border-cyan-500 active:border-cyan-500',
white: 'border-gray-300 text-white hover:text-cyan-500 hover:border-cyan-500 active:border-cyan-500',
},
link: {
cyan: 'text-cyan-400 underline hover:text-cyan-300',
white: 'text-white underline hover:text-cyan-300',
dark: 'text-gray-900 underline hover:text-cyan-500',
},
}
@@ -30,7 +37,11 @@ type ButtonProps = (
}
| {
variant: 'outline'
color?: (keyof typeof variantStyles.outline) | 'cyan'
color?: keyof typeof variantStyles.outline
}
| {
variant: 'link'
color?: keyof typeof variantStyles.link
}
) &
(
@@ -43,16 +54,33 @@ type ButtonProps = (
)
export function Button({ className, as, ...props }: ButtonProps) {
props.variant ??= 'solid'
props.color ??= 'gray'
// Set safe defaults per variant so color always matches a valid palette key
if (!props.variant) {
props.variant = 'solid'
}
if (!props.color) {
if (props.variant === 'solid') {
props.color = 'gray'
} else if (props.variant === 'outline') {
props.color = 'gray'
} else if (props.variant === 'link') {
props.color = 'cyan'
}
}
const variant = props.variant
const color = props.color as string
className = clsx(
baseStyles[props.variant],
props.variant === 'outline'
? variantStyles.outline[props.color]
: props.variant === 'solid'
? variantStyles.solid[props.color]
: undefined,
baseStyles[variant],
variant === 'outline'
? variantStyles.outline[color as keyof typeof variantStyles.outline]
: variant === 'solid'
? variantStyles.solid[color as keyof typeof variantStyles.solid]
: variant === 'link'
? variantStyles.link[color as keyof typeof variantStyles.link]
: undefined,
className,
)

View File

@@ -8,10 +8,10 @@ export function Footer() {
<div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-8">
<div>
<div className="flex items-center text-gray-900">
<img src="/images/logomark.svg" alt="Mycelium Logomark" className="h-15 w-15 flex-none" />
<img src="/images/logomark.svg" alt="Mycelium Logomark" className="h-13 w-13 flex-none" />
<div className="ml-4">
<p className="text-base font-semibold">Project Mycelium</p>
<p className="mt-1 text-sm">Unleash the Power of Decentralization</p>
<p className="text-base lg:text-lg font-semibold">Project Mycelium</p>
<p className="mt-1 text-sm">Built for Digital Sovereignty</p>
</div>
</div>
<nav className="mt-10 flex gap-8">
@@ -49,11 +49,11 @@ export function Footer() {
</div>
</div>
</div>
<div className="flex flex-col items-center border-t border-gray-100 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6">
<div className="flex flex-col items-center border-t border-gray-100 py-8 md:flex-row-reverse md:justify-between md:pt-6">
<p className="mt-6 text-sm text-gray-500 md:mt-0">
&copy; Copyright{' '}
<a href="https://www.threefold.io" target="_blank" rel="noopener noreferrer" className="hover:text-cyan-500 transition-colors">
ThreeFold
<a href="https://ourworld.tf/" target="_blank" rel="noopener noreferrer" className="font-semibold hover:text-cyan-500 transition-colors">
OurWorld
</a>{' '}
{new Date().getFullYear()}. All rights reserved.
</p>

View File

@@ -2,7 +2,7 @@ import { useState } from 'react'
import { Link } from 'react-router-dom'
import { Container } from './Container'
import { Button } from './Button'
import pmyceliumLogo from '../images/logos/logo_1.png'
import pmyceliumLogo from '../images/logos/mainlogo.svg'
import { Dialog } from '@headlessui/react'
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'

View File

@@ -2,7 +2,7 @@ import { useState } from 'react'
import { Link } from 'react-router-dom'
import { Container } from './Container'
import { Button } from './Button'
import pmyceliumLogo from '../images/logos/logo_1.png'
import pmyceliumLogo from '../images/logos/mainlogo.svg'
import { Dialog } from '@headlessui/react'
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'

View File

@@ -162,5 +162,5 @@ export const DownloadCardDescription = createTextComponent(
'text-base/7 leading-normal tracking-normal'
)
export const CT = createTextComponent('span', 'text-base lg:text-lg font-medium')
export const CP = createTextComponent('p', 'text-sm lg:text-base tracking-wide leading-tight font-light')
export const CT = createTextComponent('span', 'text-base lg:text-lg leading-normal font-medium')
export const CP = createTextComponent('p', 'text-sm lg:text-base tracking-wide leading-normal font-light')

View File

@@ -58,7 +58,10 @@ export const InfiniteMovingCards = ({
ref={scrollerRef}
className={cn(
"flex w-max shrink-0 gap-16 py-4",
isReady && "animate-infinite-scroll",
isReady &&
(direction === "left"
? "animate-infinite-scroll"
: "animate-infinite-scroll-right"),
pauseOnHover && "hover:[animation-play-state:paused]"
)}
>

View File

@@ -71,30 +71,27 @@ const clusterNodes = (nodeList: GeoNode[], cellSize = 2) => {
function DynamicMapContainer() {
const [loading, setLoading] = useState(true);
const [nodes, setNodes] = useState<GeoNode[]>([]);
const API_URL = "https://gridproxy.grid.tf/nodes?healthy=true&size=99999";
const API_URL = "https://gridproxy.grid.tf/nodes?healthy=true&size=500";
useEffect(() => {
async function fetchNodeData() {
try {
const response = await fetch(API_URL);
const data: RawNode[] = await response.json(); // Type the incoming data
const data: RawNode[] = await response.json();
// 🚨 Map the API response to your component's expected GeoNode format
const geoNodes: GeoNode[] = data
.filter((node: RawNode) => node.location && node.location.latitude && node.location.longitude)
.map((node: RawNode) => ({
// Convert string coordinates to numbers
lat: parseFloat(node.location.latitude),
lng: parseFloat(node.location.longitude),
label: `${node.location.city}, ${node.location.country} (${node.node_id})`,
// Optionally set color based on some node property if available
}));
const clusteredNodes = clusterNodes(geoNodes);
setNodes(clusteredNodes);
setLoading(false);
} catch (error) {
console.error("Failed to fetch node data:", error);
} finally {
setLoading(false);
}
}
@@ -102,30 +99,24 @@ function DynamicMapContainer() {
fetchNodeData();
}, []);
// --- RENDERING ---
// While fetching, show a loading state
if (loading) {
// Show a loading state while data is being fetched
return (
<div className="flex justify-center items-center w-full aspect-[2/1] bg-[#111111] rounded-lg text-cyan-500">
<motion.span
animate={{ rotate: 360 }}
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
className="text-4xl"
>
🌎
</motion.span>
<p className="ml-4">Loading nodes...</p>
</div>
<div className="flex justify-center items-center w-full aspect-[2/1] bg-[#111111] rounded-lg text-cyan-500">
<motion.span
animate={{ rotate: 360 }}
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
className="text-4xl"
>
🌎
</motion.span>
<p className="ml-4">Loading nodes...</p>
</div>
);
}
// Pass the dynamically fetched nodes to your WorldMap component
return (
<WorldMap
nodes={nodes}
/>
);
// After data is loaded, render the map
return <WorldMap nodes={nodes} />;
}
export default DynamicMapContainer;

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="77" zoomAndPan="magnify" viewBox="0 0 57.75 54" height="72" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><clipPath id="6b820d2194"><path d="M 0.402344 0 L 57.101562 0 L 57.101562 6 L 0.402344 6 Z M 0.402344 0 " clip-rule="nonzero"/></clipPath><clipPath id="3794aac157"><path d="M 0.402344 23 L 57 23 L 57 30 L 0.402344 30 Z M 0.402344 23 " clip-rule="nonzero"/></clipPath><clipPath id="a8068b094c"><path d="M 0.402344 46 L 57.101562 46 L 57.101562 53 L 0.402344 53 Z M 0.402344 46 " clip-rule="nonzero"/></clipPath></defs><g clip-path="url(#6b820d2194)"><path stroke-linecap="butt" transform="matrix(0.736364, 0, 0, 0.736364, 0.402273, 0.00000196364)" fill="none" stroke-linejoin="miter" d="M 0.000096737 3.999805 L 76.537522 3.999805 " stroke="#43d7ff" stroke-width="8" stroke-opacity="1" stroke-miterlimit="4"/></g><g clip-path="url(#3794aac157)"><path fill="#43d7ff" d="M 0.402344 23.136719 L 35.746094 23.136719 L 35.746094 29.027344 L 0.402344 29.027344 M 41.636719 23.136719 L 56.761719 23.136719 L 56.761719 29.027344 L 41.636719 29.027344 " fill-opacity="1" fill-rule="nonzero"/></g><g clip-path="url(#a8068b094c)"><path stroke-linecap="butt" transform="matrix(0.736364, 0, 0, 0.736364, 0.402273, 46.951043)" fill="none" stroke-linejoin="miter" d="M 0.000096737 4.002635 L 76.537522 4.002635 " stroke="#43d7ff" stroke-width="8" stroke-opacity="1" stroke-miterlimit="4"/></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -123,7 +123,7 @@ export function AgentBento() {
<div className="w-full h-full object-cover"><card.animation /></div>
</div>
) : (
<div className="h-48 w-full flex items-center justify-center bg-transparent" />
<div className="hidden md:flex md:h-48 w-full items-center justify-center bg-transparent" />
)}
<div className="px-8 pt-4 pb-6">
@@ -136,7 +136,7 @@ export function AgentBento() {
) : (
<>
{/* ✅ NEW SUBTITLE */}
<p className="text-sm text-cyan-400">{card.subtitle}</p>
<p className="text-sm text-cyan-500">{card.subtitle}</p>
<p className="mt-1 text-lg font-medium lg:text-xl tracking-tight text-white">
{card.title}
@@ -161,6 +161,9 @@ export function AgentBento() {
))}
</div>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</section>
);
}

View File

@@ -1,6 +1,5 @@
'use client'
import { Button } from '@/components/Button'
import { Eyebrow, H3, P } from '@/components/Texts'
export function AgentHeroAlt() {
@@ -8,28 +7,32 @@ export function AgentHeroAlt() {
<div className="">
{/* Boxed container */}
<div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/agents.webp')", backgroundSize: "contain" }}
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden md:bg-[url('/images/agents.webp')] md:bg-contain md:bg-right md:bg-no-repeat"
>
{/* Inner padding */}
<div className="px-6 py-16 lg:py-24">
<div className="max-w-2xl lg:pl-6">
<div className="px-6 pt-4 pb-12 lg:py-24">
{/* Mobile-only hero image */}
<img
src="/images/mobile/agents.jpg"
alt="Mycelium Agents visual"
className="mb-8 w-full object-cover md:hidden"
/>
<div className="max-w-xl lg:pl-6">
<Eyebrow>MYCELIUM AGENTS - COMING IN 2026</Eyebrow>
<H3 as="h1" className="mt-4">
Private, Sovereign and Distributed AI You Control
</H3>
<P className="mt-6 text-gray-800">
<P className="mt-6 text-gray-600">
Mycelium Agents let you deploy and run intelligent systems on your own infrastructure.
</P>
<P className="mt-4 text-gray-600">
Private, local, and autonomous by design, they give you everything you need to build, host, and connect AI agents without relying on centralized clouds.
</P>
<div className="mt-10 flex items-center gap-x-6">
<Button href="#" variant="solid" color="cyan">
Follow Development
</Button>
<Button href="#" variant="outline">
Explore Docs <span aria-hidden="true"></span>
</Button>
{/* TODO: Hero CTAs (Follow Development / Explore Docs) to be added when links are ready.
Previously two Buttons here with href="#". */}
</div>
</div>
</div>

View File

@@ -36,9 +36,9 @@ export function AgentPro() {
<div className="w-full border-t border-l border-r border-gray-100" />
{/* Intro Block */}
<div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
<div className="bg-white w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
<div className="px-8 py-12 max-w-4xl mx-auto flex flex-col items-center justify-center min-h-[220px] text-center">
<Eyebrow className="uppercase tracking-[0.16em] text-cyan-600">
<Eyebrow className="text-cyan-500">
Advantages
</Eyebrow>
@@ -73,7 +73,7 @@ export function AgentPro() {
{item.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600">
<p className="mt-4 text-base leading-relaxed text-gray-600">
{item.description}
</p>
</div>

View File

@@ -1,6 +1,6 @@
"use client";
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
import { Eyebrow, P, CT, CP, H3} from "@/components/Texts";
import {
CpuChipIcon,
GlobeAltIcon,
@@ -63,19 +63,18 @@ export function AgentUsecase() {
<div className="w-full border-t border-l border-r border-gray-100" />
{/* Main framed section */}
<div className="border border-t-0 border-b-0 border-gray-100 bg-white">
<div className="mx-auto max-w-4xl sm:text-center py-12">
<div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-3xl sm:text-center px-6 lg:px-8">
{/* Intro block (from isIntro item) */}
{networkUseCases[0].isIntro && (
<>
<Eyebrow className="text-cyan-600">{networkUseCases[0].eyebrow}</Eyebrow>
<SectionHeader
as="h3"
className="mt-4 text-gray-900 text-3xl lg:text-4xl"
<Eyebrow className="text-cyan-500">{networkUseCases[0].eyebrow}</Eyebrow>
<H3
className="mt-4 text-gray-900"
>
{networkUseCases[0].title}
</SectionHeader>
<P className="mt-6 text-lg text-gray-600">
</H3>
<P className="mt-4 text-lg text-gray-600">
{networkUseCases[0].description}
</P>
</>
@@ -85,7 +84,7 @@ export function AgentUsecase() {
{/* Grid of features (excluding intro) */}
<ul
role="list"
className="mx-auto mt-6 max-w-6xl grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-y-10 px-6 pb-16"
className="mx-auto mt-8 max-w-6xl grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-y-10 px-6"
>
{networkUseCases.slice(1).map((item, idx) => (
<li
@@ -94,20 +93,20 @@ export function AgentUsecase() {
>
{/* Icon */}
{item.icon && (
<div className="h-10 w-10 flex items-center justify-center rounded-xl bg-gray-100">
<item.icon className="h-6 w-6 text-cyan-600" />
<div className="h-10 w-10 mb-2 flex items-center justify-center rounded-xl bg-gray-100">
<item.icon className="h-6 w-6 text-cyan-500" />
</div>
)}
{/* Title */}
<p className="mt-6 text-lg font-semibold text-gray-900">
<CT className="leading-normal text-gray-900">
{item.title}
</p>
</CT>
{/* Description */}
<p className="mt-2 text-gray-600 text-sm leading-snug">
<CP className="mt-2 text-gray-600 text-sm leading-snug">
{item.description}
</p>
</CP>
</li>
))}
</ul>

View File

@@ -13,7 +13,7 @@ export function CallToAction() {
{/* ✅ Main boxed area */}
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
className="relative py-18 max-w-7xl mx-auto overflow-hidden bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
@@ -26,7 +26,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -41,38 +41,42 @@ export function CallToAction() {
Start with Mycelium Today
</h2>
<p className="mt-6 text-lg text-gray-300">
<p className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
The Agent Framework launches in H1 2026, but the foundation is ready now.
</p>
<p className="mt-2 text-lg text-gray-300">
<p className="mt-2 lg:text-lg text-base leading-normal text-gray-300">
Use todays components models, storage, compute, and network to deploy workloads, connect nodes, and prepare for the next generation of distributed AI.
</p>
{/* ✅ Two cards, stacked center with spacing */}
<div className="mt-8 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/deploy" variant="solid" color="cyan" className="mt-4">
Deploy a Model
</Button>
</div>
{/* ✅ Button row same structure as homepage CTA */}
<div className="mt-10 flex flex-wrap justify-center items-center gap-x-6 gap-y-4">
<Button
as="a"
to="https://myceliumcloud.tf"
variant="solid"
color="cyan"
target="_blank"
rel="noopener noreferrer"
>
Deploy a Model
</Button>
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/host" as="a" variant="outline" color="white" className="mt-4">
Host a Node
</Button>
</div>
<Button to="/nodes" variant="outline" color="white">
Host a Node
</Button>
<div className="flex flex-col items-center text-center max-w-xs">
<a
href="https://threefold.info/mycelium_network/docs/"
target="_blank"
rel="noopener noreferrer"
className="mt-5 font-semibold text-white underline underline-offset-4 decoration-white/70 hover:text-cyan-200 hover:decoration-cyan-200 transition-colors inline-flex items-center gap-1.5"
>
Follow Development
<span aria-hidden="true"></span>
</a>
</div>
<Button
as="a"
to="https://threefold.info/mycelium_network/docs/"
variant="link"
color="white"
className="inline-flex items-center gap-1.5"
target="_blank"
rel="noopener noreferrer"
>
Follow Development
<span aria-hidden="true"></span>
</Button>
</div>
</div>
</Container>

View File

@@ -4,7 +4,6 @@ import { useEffect, useMemo, useState } from 'react'
import { useResponsiveCarousel } from '@/hooks/useResponsiveCarousel';
import { motion, AnimatePresence } from 'framer-motion'
import { wrap } from 'popmotion'
import { Button } from '@/components/Button';
import { SectionHeader, P, Eyebrow, CP } from '@/components/Texts';
import { TypeAnimation } from 'react-type-animation'
import { FadeIn } from '@/components/FadeIn';
@@ -147,9 +146,8 @@ export function GallerySection() {
repeat={0}
/>
</CP>
<Button href="#" color="cyan" className="text-sm px-4 py-2 lg:text-base whitespace-nowrap">
Start
</Button>
{/* TODO: Desktop CTA (Start) button to be added when link target is defined.
Previously: <Button href="#" color="cyan">Start</Button> */}
</div>
</div>
</section>
@@ -166,9 +164,8 @@ export function GallerySection() {
repeat={0}
/>
</CP>
<Button href="#" color="cyan" className="text-xs px-3 py-1.5 whitespace-nowrap">
Start
</Button>
{/* TODO: Mobile CTA (Start) button to be added when link target is defined.
Previously: <Button href="#" color="cyan">Start</Button> */}
</div>
</div>
</FadeIn>

View File

@@ -132,7 +132,7 @@ export default function AgentCoordination({
aria-label="Agent coordination and sovereign workflow management"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full lg:-translate-y-6" preserveAspectRatio="xMidYMid slice">
{/* background */}
<defs>

View File

@@ -103,7 +103,7 @@ export default function DeterministicExecution({
aria-label="Deterministic deployment and verifiable code execution"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full lg:-translate-y-6" preserveAspectRatio="xMidYMid slice">
{/* background grid */}
<defs>

View File

@@ -126,7 +126,7 @@ export default function FungiStor({
aria-label="FungiStor, a distributed long-term AI memory"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full lg:-translate-y-16" preserveAspectRatio="xMidYMid slice">
{/* Background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">

View File

@@ -178,7 +178,7 @@ export default function Herodb({
aria-label="HeroDB, active AI memory retrieval"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full lg:-translate-y-18" preserveAspectRatio="xMidYMid slice">
{/* Background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">

View File

@@ -124,7 +124,7 @@ export default function MOSSandboxes({
aria-label="MOS Secure Agent Sandboxes"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full lg:-translate-y-16" preserveAspectRatio="xMidYMid slice">
{/* BACKGROUND GRID */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">

View File

@@ -145,7 +145,7 @@ export default function MyceliumMesh({
aria-label="Mycelium Mesh, a secure communication network"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" preserveAspectRatio="xMidYMid slice">
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full lg:-translate-y-4" preserveAspectRatio="xMidYMid slice">
{/* Background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">

View File

@@ -13,7 +13,7 @@ export function CallToAction() {
{/* ✅ Main boxed area */}
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
className="relative py-18 max-w-7xl overflow-hidden mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
@@ -26,7 +26,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -52,13 +52,21 @@ export function CallToAction() {
{/* ✅ Two cards, stacked center with spacing */}
<div className="mt-10 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/host" variant="solid" color="cyan" className="mt-4">
<Button to="/nodes" variant="solid" color="cyan" className="mt-4">
Host a Node
</Button>
</div>
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/cloud" variant="outline" color="white" className="mt-4">
<Button
as="a"
to="https://myceliumcloud.tf"
variant="outline"
color="white"
className="mt-4"
target="_blank"
rel="noopener noreferrer"
>
Start Deploying
</Button>
</div>

View File

@@ -40,7 +40,7 @@ export function CloudArchitecture() {
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-800 bg-[#111111] py-12">
<Container>
<div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-400">ARCHITECTURE</Eyebrow>
<Eyebrow className="">ARCHITECTURE</Eyebrow>
<H3 className="text-3xl lg:text-4xl font-medium tracking-tight text-white">
How Mycelium Cloud Works

View File

@@ -1,16 +1,22 @@
import { H3, Eyebrow } from "@/components/Texts"
import { H3, Eyebrow, P } from "@/components/Texts"
import { Button } from "@/components/Button"
export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedClick?: () => void }) {
export function CloudHeroNew() {
return (
<div className="">
{/* Boxed container */}
<div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/cloudhero4.webp')", backgroundSize: "contain" }}
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden md:bg-[url('/images/cloudhero4.webp')] md:bg-contain md:bg-right md:bg-no-repeat"
>
{/* Inner padding */}
<div className="px-6 py-16 lg:py-24">
<div className="px-6 pt-4 pb-12 lg:py-24">
{/* Mobile-only hero image */}
<img
src="/images/mobile/cloudpage.jpg"
alt="Mycelium Cloud page visual"
className="mb-8 w-full object-cover md:hidden"
/>
<div className="max-w-2xl lg:pl-6">
<Eyebrow>
MYCELIUM CLOUD
@@ -18,30 +24,36 @@ export function CloudHeroNew({ onGetStartedClick = () => {} }: { onGetStartedCli
<H3 className="mt-4">
Sovereign Edge Cloud Infrastructure
</H3>
<p className="mt-6 text-lg text-gray-600">
<P className="mt-6 text-gray-600">
Run compute, storage, and AI resources on infrastructure you control.
</p>
<p className="mt-2 text-lg text-gray-600">
The Mycelium Cloud runs on a distributed grid of independent nodes,
delivering secure, scalable performance wherever your users or data live.
</p>
</P>
<div className="mt-10 flex items-center gap-x-6">
<Button
onClick={onGetStartedClick}
as="a"
to="https://myceliumcloud.tf"
variant="solid"
color="cyan"
target="_blank"
rel="noopener noreferrer"
>
Deploy Workloads
</Button>
<Button to="#" variant="outline">
<Button
as="a"
to="https://myceliumcloud.tf/docs"
variant="outline"
target="_blank"
rel="noopener noreferrer"
>
Explore Docs <span aria-hidden="true"></span>
</Button>
</div>
</div>
</div>
</div>
{/* Bottom horizontal line with spacing */}
{/* Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</div>

View File

@@ -79,6 +79,18 @@ export function CloudIntro() {
const current = tabs.find((t) => t.id === active)!.content;
const currentButtons = tabButtons[active as keyof typeof tabButtons];
const primaryLinks: Record<string, string | undefined> = {
kubernetes: "https://myceliumcloud.tf",
vdc: undefined,
qsfs: undefined,
};
const secondaryLinks: Record<string, string | undefined> = {
kubernetes: "https://myceliumcloud.tf/docs",
vdc: "https://threefold.info/mycelium_vdc/docs/",
qsfs: undefined,
};
return (
<section className="relative w-full bg-[#121212] overflow-hidden">
{/* Top Spacing Border */}
@@ -95,7 +107,7 @@ export function CloudIntro() {
<H3 color="white">What You Can Run on Mycelium Cloud</H3>
<P className="max-w-3xl text-gray-400 mt-6">
<P className="max-w-3xl text-gray-200 mt-6">
Host nodes, deploy workloads, or build private AI systems all on
infrastructure you own and control. Mycelium gives you scalable compute,
secure storage, and sovereign orchestration without depending on
@@ -126,7 +138,7 @@ export function CloudIntro() {
<button
key={tab.id}
onClick={() => setActive(tab.id)}
className={`text-sm font-medium tracking-wide pb-2 ${
className={`text-sm font-medium tracking-wide leading-tight pb-2 ${
active === tab.id
? "border-b-2 border-cyan-500 text-white"
: "text-gray-400 hover:text-white"
@@ -140,20 +152,20 @@ export function CloudIntro() {
{/* Tab Content */}
<div className="mt-6 space-y-6">
<div>
<p className="text-lg font-medium text-white">{current.item}</p>
<p className="mt-2 text-base text-gray-400 leading-relaxed">
<p className="text-lg lg:text-xl font-medium text-white">{current.item}</p>
<p className="mt-2 text-base text-gray-300 leading-relaxed">
{current.desc}
</p>
</div>
<div className="mt-4 space-y-2">
<p className="text-sm uppercase tracking-wide text-cyan-400 font-semibold">
<p className="text-sm uppercase tracking-wide text-cyan-500 font-semibold">
Key capabilities
</p>
<ul className="space-y-2">
{current.bullets.map((b, i) => (
<li key={i} className="text-base text-gray-300 flex gap-2">
<li key={i} className="text-base text-gray-400 flex gap-2">
<span className="text-cyan-500"></span>
{b}
</li>
@@ -164,17 +176,25 @@ export function CloudIntro() {
{currentButtons && (
<div className="mt-8 flex flex-wrap gap-4">
<Button
to="#"
as={primaryLinks[active] ? "a" : undefined}
to={primaryLinks[active] ?? "#"}
variant="solid"
color="cyan"
{...(primaryLinks[active]
? { target: "_blank", rel: "noopener noreferrer" }
: {})}
>
{currentButtons.primary}
</Button>
<Button
to="#"
as={secondaryLinks[active] ? "a" : undefined}
to={secondaryLinks[active] ?? "#"}
variant="outline"
color="white"
{...(secondaryLinks[active]
? { target: "_blank", rel: "noopener noreferrer" }
: {})}
>
{currentButtons.secondary}
</Button>

View File

@@ -35,9 +35,9 @@ export function CloudPros() {
<div className="w-full border-t border-l border-r border-gray-100" />
{/* Intro Block */}
<div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
<div className="bg-white w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
<div className="px-8 py-12 max-w-4xl">
<Eyebrow className="uppercase tracking-[0.16em] text-cyan-600">
<Eyebrow className="uppercase tracking-[0.16em] text-cyan-500">
Cloud Advantages
</Eyebrow>
@@ -72,7 +72,7 @@ export function CloudPros() {
{item.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600">
<p className="mt-4 text-base leading-relaxed text-gray-600">
{item.description}
</p>
</div>

View File

@@ -13,7 +13,7 @@ export function CallToAction() {
{/* ✅ Main boxed area */}
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
className="relative py-18 max-w-7xl overflow-hidden mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
@@ -26,7 +26,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -43,7 +43,7 @@ export function CallToAction() {
Choose How You Want to Start
</h2>
<p className="mt-6 text-lg text-gray-300">
<p className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
Host your own node to contribute capacity or deploy workloads using the Mycelium Cloud.
You dont need to host before deploying, and you dont need to deploy before hosting.

View File

@@ -2,7 +2,6 @@
import { Container } from '@/components/Container'
import { Eyebrow, H3, P } from '@/components/Texts'
import { Button } from '@/components/Button'
const capabilities = [
{
@@ -48,7 +47,7 @@ export function ComputeCapabilities() {
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-800 bg-[#111111] py-12">
<Container>
<div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-400">CAPABILITIES</Eyebrow>
<Eyebrow className="text-cyan-500">CAPABILITIES</Eyebrow>
<H3 className="text-3xl lg:text-4xl font-medium tracking-tight text-white">
What You Can Run
</H3>
@@ -76,14 +75,8 @@ export function ComputeCapabilities() {
</ul>
{/* Button section */}
<div className="mx-auto mt-12 flex justify-center gap-6">
<Button variant="solid" color="cyan" href="#">
Get Started
</Button>
<Button variant="outline" color="white" href="#">
Explore Docs
</Button>
</div>
{/* TODO: CTA buttons (Get Started / Explore Docs) to be re-enabled when real links are available.
Previously rendered here as two Buttons with href="#". */}
</Container>
</div>

View File

@@ -78,12 +78,8 @@ export function ComputeCapabilitiesNew() {
{/* Arrows inside first card */}
<div className="flex items-center gap-x-4 mt-2">
<a
href="#"
className="inline-flex items-center gap-1 text-cyan-400 hover:text-cyan-300 text-sm font-medium mr-auto"
>
Learn more
</a>
{/* TODO: Intro card CTA (Learn more) to be added here when destination is defined.
Previously: <a href="#" className="inline-flex items-center ...">Learn more →</a> */}
<button
onClick={scrollLeft}
className="h-8 w-8 flex items-center justify-center border border-gray-800 rounded-md hover:border-cyan-500 transition-colors"

View File

@@ -35,9 +35,8 @@ export function ComputeHero({ onGetStartedClick = () => {} }: { onGetStartedClic
>
Get started
</Button>
<Button to="#" variant="outline">
Documentation <span aria-hidden="true"></span>
</Button>
{/* TODO: Secondary CTA (Documentation) link to be wired when docs route is ready.
Previously: <Button to="#" variant="outline">Documentation →</Button> */}
</div>
</div>
</div>

View File

@@ -36,8 +36,12 @@ const features = [
export function DevHub() {
return (
<div className="bg-[#121212] py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<section className="bg-[#121212] w-full max-w-8xl mx-auto">
{/* Top spacing + border */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
<div className="w-full border-t border-l border-r border-gray-800" />
<div className="relative px-6 lg:px-6 py-12 bg-[#111111] border border-t-0 border-b-0 border-gray-800 max-w-7xl mx-auto">
<div className="mx-auto grid max-w-2xl grid-cols-1 gap-x-8 gap-y-16 sm:gap-y-20 lg:mx-0 lg:max-w-none lg:grid-cols-5">
<div className="col-span-2">
<h2 className="mb-2 text-base font-semibold leading-7 text-cyan-500">Get Started</h2>
@@ -63,7 +67,11 @@ export function DevHub() {
))}
</dl>
</div>
</div>
</div>
</div>
{/* Bottom horizontal line with spacing (match NetworkDownload) */}
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</section>
)
}

View File

@@ -40,14 +40,14 @@ const features = [
export function DownloadHero() {
return (
<div className="py-16 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<section id="download" className="w-full max-w-8xl mx-auto bg-transparent">
<div className="mx-auto max-w-7xl px-6 lg:px-8 bg-white pt-24 pb-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-2xl lg:mx-0">
<motion.h2
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className="text-5xl font-medium tracking-tight text-gray-900 lg:text-6xl"
className="text-4xl font-medium tracking-tight text-gray-900 lg:text-5xl"
>
Download Mycelium Network
</motion.h2>
@@ -55,7 +55,7 @@ export function DownloadHero() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }}
className="mt-6 text-lg text-gray-600 lg:leading-8"
className="mt-8 text-lg text-gray-600 lg:leading-8"
>
Get Mycelium Network for Android, Windows, macOS, and iOS to securely connect, store, and interact with the decentralized networkseamlessly and efficiently. Not sure how it works?{' '}
<a
@@ -68,8 +68,9 @@ export function DownloadHero() {
</a>
</motion.p>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 md:grid-cols-2 lg:max-w-none lg:grid-cols-4">
<div className="mx-auto mt-8 max-w-2xl lg:mt-12 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 lg:gap-y-16 gap-y-8 md:grid-cols-2 lg:max-w-none lg:grid-cols-4">
{features.map((feature) => (
<div
key={feature.name}
@@ -99,6 +100,10 @@ export function DownloadHero() {
</dl>
</div>
</div>
</div>
{/* Bottom horizontal line with spacing (match NetworkDownload) */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</section>
)
}

View File

@@ -13,7 +13,7 @@ export function CallToAction() {
{/* ✅ Main boxed area */}
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
className="relative py-18 max-w-7xl overflow-hidden mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
@@ -26,7 +26,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -43,7 +43,7 @@ export function CallToAction() {
Choose How You Want to Start
</h2>
<p className="mt-6 text-lg text-gray-300">
<p className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
Use GPUs through Mycelium Cloud, or contribute GPU nodes to the mesh and run your own workloads.
</p>

View File

@@ -84,7 +84,7 @@ export function GpuCapabilities() {
<div className="flex items-center gap-x-4 mt-3">
<a
href="#"
className="inline-flex items-center gap-1 text-cyan-400 hover:text-cyan-300 text-sm font-medium mr-auto"
className="inline-flex items-center gap-1 text-cyan-500 hover:text-cyan-400 text-sm font-medium mr-auto"
>
Learn more
</a>

View File

@@ -42,7 +42,7 @@ export function GpuOverview() {
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-800 bg-[#111111] py-12">
<Container>
<div className="mx-auto max-w-3xl text-center">
<Eyebrow className="text-cyan-400 tracking-[0.32em] uppercase">
<Eyebrow className="text-cyan-500 tracking-[0.32em] uppercase">
PLATFORM OVERVIEW
</Eyebrow>

View File

@@ -1,4 +1,3 @@
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container'
import { Button } from '@/components/Button'
import { H3, P } from '@/components/Texts'
@@ -27,7 +26,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -43,30 +42,33 @@ export function CallToAction() {
Use the Mycelium Stack Your Way
</H3>
<P className="mt-6 text-gray-300">
<P className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
Deploy infrastructure, run workloads, connect environments, and build distributed AI systems, all on one network designed for autonomy and control.
</P>
<P className="mt-4 text-gray-300">
<P className="mt-4 lg:text-lg text-base leading-normal text-gray-300">
Start wherever you are. Scale on your own terms.
</P>
<div className="mt-10 flex flex-wrap justify-center items-center gap-x-6 gap-y-4">
<Button to="/network" variant="solid" color="cyan">
<Button to="/network#download" variant="solid" color="cyan">
Join the Network
</Button>
<Button
to="/cloud"
as="a"
to="https://myceliumcloud.tf"
variant="outline"
color="white"
target="_blank"
rel="noopener noreferrer"
>
Deploy in Cloud
</Button>
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
<Button to="/nodes" variant="link" color="white">
Host a Node &rarr;
</Link>
</Button>
</div>
</div>
</Container>

View File

@@ -24,7 +24,7 @@ const deterministicCards = [
title: "No central servers.",
description:
"Your devices form a distributed network, eliminating reliance on centralized data centers.",
animation: <NoCentral className="lg:-mt-12" />, // ✅ NEW
animation: <NoCentral />, // ✅ NEW
colSpan: "lg:col-span-3",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-tr-4xl max-lg:rounded-t-4xl",
@@ -35,7 +35,7 @@ const deterministicCards = [
title: "No data extraction.",
description:
"You own your data. Run services and AI models on your own devices, ensuring privacy and control.",
animation: <NoExtraction className="lg:-mt-12" />, // ✅ NEW
animation: <NoExtraction />, // ✅ NEW
colSpan: "lg:col-span-2",
rowSpan: "lg:row-span-1",
rounded: "lg:rounded-bl-4xl max-lg:rounded-b-4xl",
@@ -97,7 +97,7 @@ export function HomeArchitecture() {
</div>
</div>
) : (
<div className="h-48 w-full flex items-center justify-center bg-transparent" />
<div className="h-48 w-full items-center justify-center bg-transparent hidden md:flex" />
)}
<div className="px-8 pt-4 pb-6">

View File

@@ -1,37 +1,50 @@
import { H3, H5, Eyebrow } from "@/components/Texts"
import { Button } from "@/components/Button"
export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => void }) {
export function HomeAurora() {
return (
<div className="px-4">
{/* Boxed container */}
<div
className="relative mx-auto max-w-7xl border border-t-0 border-gray-100 bg-white overflow-hidden bg-size-[65%] bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/hero11.webp')" }}
className="relative mx-auto max-w-7xl border border-t-0 border-gray-100 bg-white overflow-hidden bg-size-[65%] bg-right bg-no-repeat bg-none md:bg-[url('/images/hero11.webp')]"
>
{/* Inner padding */}
<div className="px-6 py-16 lg:py-32 ">
<div className="px-6 pb-12 pt-8 lg:py-32 ">
{/* Mobile-only hero image */}
<img
src="/images/mobile/homepage.jpg"
alt="Mycelium homepage visual"
className="mb-8 w-full object-cover md:hidden"
/>
<div className="max-w-2xl lg:pl-6">
<Eyebrow> Project MYCELIUM</Eyebrow>
<H3 className="mt-4">
Private, Distributed Infrastructure Built
Secure, Distributed Infrastructure Built
<br />
for Digital Sovereignty
</H3>
<H5 className="mt-4 text-lg text-gray-600 max-w-xl">
<H5 className="mt-6 text-lg text-gray-600 max-w-xl">
Run your apps, data, and intelligence on infrastructure that belongs to you
</H5>
<div className="mt-8 flex items-center gap-x-6">
<Button
to="/nodes"
variant="solid"
color="cyan"
onClick={onGetStartedClick}
>
Start Hosting
</Button>
<Button to="#" variant="outline">
Deploy in Cloud
<Button
as="a"
to="https://myceliumcloud.tf"
variant="outline"
target="_blank"
rel="noopener noreferrer"
>
Deploy in Cloud
</Button>
</div>
</div>

View File

@@ -30,14 +30,14 @@ export function HomeDesign() {
return (
<section className="w-full max-w-8xl mx-auto bg-white">
{/* Top spacing line */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-200" />
<div className="w-full border border-l border-r border-gray-200" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
<div className="w-full border border-l border-r border-gray-100" />
{/* Content */}
<div className="mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-200">
<div className="mx-auto max-w-7xl border border-t-0 border-b-0 bg-white border-gray-100">
{/* Centered intro */}
<div className="px-6 pt-12 pb-4 text-center max-w-4xl mx-auto ">
<Eyebrow className="uppercase tracking-[0.16em] text-cyan-600">
<Eyebrow className="text-cyan-500">
Who's it For
</Eyebrow>
@@ -50,11 +50,11 @@ export function HomeDesign() {
</P>
</div>
<dl className="grid grid-cols-1 lg:grid-cols-3 gap-4 lg:gap-0">
<dl className="grid grid-cols-1 lg:grid-cols-3 gap-2 lg:gap-0">
{benefits.map((item) => (
<div
key={item.id}
className="mt-8 group flex items-start gap-2 bg-white px-8 py-12 border border-gray-200 lg:border-t lg:border-b border-l-0.5 border-r-0.5"
className="mt-8 group flex items-start gap-2 bg-white px-8 py-12 border border-gray-100 lg:border-t lg:border-b border-l-0.5 border-r-0.5 transition-all duration-300 ease-in-out hover:scale-[1.02] hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20"
>
{/* Image on the LEFT */}
<img

View File

@@ -67,7 +67,7 @@ export function WorldMap() {
>
<DarkCard>
<div><CT color="light" className="uppercase tracking-wide ">CORES</CT></div>
<div><CountUpNumber end={54958} className="mt-2 text-3xl font-bold text-white" /></div>
<div><CountUpNumber end={31611} className="mt-2 text-3xl font-bold text-white" /></div>
<CP color="light" className="mt-2 text-sm">
Total Central Processing Unit Cores available on the grid.
</CP>
@@ -83,7 +83,7 @@ export function WorldMap() {
>
<DarkCard>
<div><CT color="light" className="uppercase tracking-wide">NODES</CT></div>
<div><CountUpNumber end={1493} className="mt-4 text-3xl font-bold text-white" /></div>
<div><CountUpNumber end={1153} className="mt-4 text-3xl font-bold text-white" /></div>
<CP color="light" className="mt-2 text-sm">
Total number of nodes on the grid.
</CP>
@@ -99,7 +99,7 @@ export function WorldMap() {
>
<DarkCard>
<div><CT color="light" className="uppercase tracking-wide">SSD CAPACITY</CT></div>
<div><CountUpNumber end={5388956} className="mt-2 text-3xl font-bold text-white" /></div>
<div><CountUpNumber end={4203991} className="mt-2 text-3xl font-bold text-white" /></div>
<CP color="light" className="mt-2 text-sm">
Total GB amount of storage (SSD, HDD, & RAM) on the grid.
</CP>

View File

@@ -103,7 +103,7 @@ export function HomeMap() {
Mycelium runs on nodes hosted by people and organizations around the world.
Each node adds compute, storage, and bandwidth, expanding the networks capacity and resilience.
</P>
<P className="text-sm md:text-lg text-gray-200 max-w-3xl mx-auto py-4">
<P className="text-sm md:text-lg text-gray-200 max-w-3xl mx-auto mt-2 mb-6">
You can share your idle resources and earn rewards when they are used.
Configure it once. Your node takes over from there.
</P>

View File

@@ -1,5 +1,4 @@
import { useRef } from 'react'
import { useEffect, useRef, useState } from 'react'
import { AnimatedSection } from '../../components/AnimatedSection'
import { CallToAction } from './CallToAction'
import { HomeTab } from './HomeTab'
@@ -8,22 +7,60 @@ import { HomeAurora } from './HomeAurora'
import { HomeArchitecture } from './HomeArchitecture';
import { HomeDesign } from './HomeDesign';
function LazyHomeMapSection() {
const [isVisible, setIsVisible] = useState(false)
const containerRef = useRef<HTMLDivElement | null>(null)
useEffect(() => {
const el = containerRef.current
if (!el || isVisible) return
const observer = new IntersectionObserver(
(entries) => {
const [entry] = entries
if (entry.isIntersecting) {
setIsVisible(true)
observer.disconnect()
}
},
{
root: null,
rootMargin: '200px 0px',
threshold: 0.1,
},
)
observer.observe(el)
return () => {
observer.disconnect()
}
}, [isVisible])
return (
<div ref={containerRef}>
{isVisible ? (
<HomeMap />
) : (
<div className="max-w-7xl mx-auto px-6 py-16 text-center text-gray-400">
<p className="text-sm md:text-base">
Loading live node map when you scroll here
</p>
</div>
)}
</div>
)
}
export default function HomePage() {
const sliderRef = useRef<HTMLDivElement>(null)
const handleScrollToSlider = () => {
sliderRef.current?.scrollIntoView({ behavior: 'smooth' })
}
return (
<div>
<AnimatedSection>
<HomeAurora onGetStartedClick={handleScrollToSlider} />
<HomeAurora />
</AnimatedSection>
<AnimatedSection>
<HomeArchitecture/>
<HomeArchitecture />
</AnimatedSection>
<AnimatedSection>
@@ -31,16 +68,16 @@ export default function HomePage() {
</AnimatedSection>
<AnimatedSection>
<HomeMap />
<LazyHomeMapSection />
</AnimatedSection>
<AnimatedSection>
<HomeDesign />
</AnimatedSection>
<AnimatedSection>
<CallToAction />
</AnimatedSection>
</div>
)
}

View File

@@ -8,7 +8,7 @@ export function HomeTab() {
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* Top section separators */}
<div className="max-w-7xl mx-auto py-6 border-x border-gray-100 bg-white border-t-0 border-b-0" />
<div className="max-w-7xl mx-auto py-6 border-x border-gray-100 border-t-0 border-b-0" />
<div className="w-full border-t border-l border-r border-gray-100" />
{/* Main content */}
@@ -24,9 +24,9 @@ export function HomeTab() {
<div className="mt-10 grid gap-4 sm:mt-16 lg:grid-cols-3 lg:grid-rows-2 pb-12">
{/* ------------------ LEFT TALL CARD ------------------ */}
<Link to="/network" className="relative lg:row-span-2 cursor-pointer">
<Link to="/network" className="relative lg:row-span-2 cursor-pointer transition-transform duration-300 ease-in-out hover:scale-105">
<div className="absolute inset-px rounded-lg bg-white lg:rounded-l-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-l-[calc(2rem+1px)] transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-l-[calc(2rem+1px)]">
<div className="px-8 pt-8 pb-3 sm:px-10 sm:pt-10 sm:pb-0">
<h3 className="text-sm/4 font-semibold text-cyan-500">LIVE</h3>
@@ -50,13 +50,13 @@ export function HomeTab() {
</div>
</div>
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5 lg:rounded-l-4xl" />
<div className="pointer-events-none absolute inset-px rounded-lg border border-transparent shadow-sm outline outline-black/5 lg:rounded-l-4xl hover:border-cyan-500" />
</Link>
{/* ------------------ MIDDLE TOP ------------------ */}
<Link to="/pods" className="relative cursor-pointer max-lg:row-start-1">
<Link to="/pods" className="relative cursor-pointer max-lg:row-start-1 transition-transform duration-300 ease-in-out hover:scale-105">
<div className="absolute inset-px rounded-lg bg-white max-lg:rounded-t-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)] transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)]">
<div className="px-8 pt-8 sm:px-10 sm:pt-10">
<h3 className="text-sm/4 font-semibold text-cyan-500">Coming Soon</h3>
@@ -75,13 +75,13 @@ export function HomeTab() {
</div>
</div>
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5 max-lg:rounded-t-4xl" />
<div className="pointer-events-none absolute inset-px rounded-lg border border-transparent shadow-sm outline outline-black/5 max-lg:rounded-t-4xl hover:border-cyan-500" />
</Link>
{/* ------------------ MIDDLE BOTTOM ------------------ */}
<Link to="/agents" className="relative cursor-pointer max-lg:row-start-3 lg:col-start-2 lg:row-start-2">
<Link to="/agents" className="relative cursor-pointer max-lg:row-start-3 lg:col-start-2 lg:row-start-2 transition-transform duration-300 ease-in-out hover:scale-105">
<div className="absolute inset-px rounded-lg bg-white" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)]">
<div className="px-8 pt-8 sm:px-10 sm:pt-10">
<h3 className="text-sm/4 font-semibold text-cyan-500">Q1 2026</h3>
@@ -99,13 +99,13 @@ export function HomeTab() {
</div>
</div>
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5" />
<div className="pointer-events-none absolute inset-px rounded-lg border border-transparent shadow-sm outline outline-black/5 hover:border-cyan-500" />
</Link>
{/* ------------------ RIGHT TALL ------------------ */}
<Link to="/cloud" className="relative lg:row-span-2 cursor-pointer">
<Link to="/cloud" className="relative lg:row-span-2 cursor-pointer transition-transform duration-300 ease-in-out hover:scale-105">
<div className="absolute inset-px rounded-lg bg-white max-lg:rounded-b-4xl lg:rounded-r-4xl" />
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-r-[calc(2rem+1px)] transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20">
<div className="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-r-[calc(2rem+1px)]">
<div className="px-8 pt-8 pb-3 sm:px-10 sm:pt-10 sm:pb-0">
<h3 className="text-sm/4 font-semibold text-cyan-500">Early Access</h3>
@@ -126,7 +126,7 @@ export function HomeTab() {
</div>
</div>
<div className="pointer-events-none absolute inset-px rounded-lg shadow-sm outline outline-black/5 max-lg:rounded-b-4xl lg:rounded-r-4xl" />
<div className="pointer-events-none absolute inset-px rounded-lg border border-transparent shadow-sm outline outline-black/5 max-lg:rounded-b-4xl lg:rounded-r-4xl hover:border-cyan-500" />
</Link>
</div>

View File

@@ -131,7 +131,7 @@ export default function NoCentral({
aria-label="Distributed network illustration"
style={{ background: bg }}
>
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full lg:-translate-y-10">
{/* Background grid */}
<defs>
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
@@ -210,13 +210,13 @@ export default function NoCentral({
/>
))}
{/* Faded red “no central” mark at middle */}
{/* Faded grey “no central” mark at middle */}
<motion.circle
cx={center.x}
cy={center.y}
r={18}
fill="none"
stroke="#FF4D4D"
stroke="#8B8B8B"
strokeWidth={3}
strokeDasharray="6 4"
initial={{ scale: 0, opacity: 0 }}
@@ -225,7 +225,7 @@ export default function NoCentral({
/>
<motion.path
d={`M ${center.x - 10} ${center.y - 10} L ${center.x + 10} ${center.y + 10} M ${center.x - 10} ${center.y + 10} L ${center.x + 10} ${center.y - 10}`}
stroke="#FF4D4D"
stroke="#8B8B8B"
strokeWidth={3}
strokeLinecap="round"
initial={{ opacity: 0, scale: 0 }}

View File

@@ -162,7 +162,7 @@ export default function NoControl({
{/* Cross mark over center node (control denied) */}
<motion.path
d={`M ${center.x - 12} ${center.y - 12} L ${center.x + 12} ${center.y + 12} M ${center.x - 12} ${center.y + 12} L ${center.x + 12} ${center.y - 12}`}
stroke="#FF4D4D"
stroke="#8B8B8B"
strokeWidth={3}
strokeLinecap="round"
initial={{ opacity: 0, scale: 0 }}

View File

@@ -230,7 +230,7 @@ export default function NoExtraction({
cx={center.x + 130}
cy={center.y - 10}
r={10}
fill="#FF4D4D"
fill="#8B8B8B"
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: [0, 1.2, 0.8], opacity: [0, 1, 0] }}
transition={{

View File

@@ -10,8 +10,8 @@ type Props = {
gridStroke?: string;
};
const W = 720; // 4:3
const H = 540; // 4:3
const W = 760; // match aspect ratio closer to other home animations
const H = 420; // align visual height with other cards
export default function NoSinglePoint({
className,

View File

@@ -19,7 +19,14 @@ export function HomeHero() {
Start Hosting
</Button>
<Button href="#" variant="outline" color="white">
<Button
as="a"
to="https://myceliumcloud.tf"
variant="outline"
color="white"
target="_blank"
rel="noopener noreferrer"
>
Deploy in Cloud <span aria-hidden="true"></span>
</Button>
</div>

View File

@@ -39,8 +39,14 @@ export function HomeAurora({ onGetStartedClick }: { onGetStartedClick: () => voi
>
Start Hosting
</Button>
<Button to="#" variant="outline">
Deploy in Cloud
<Button
as="a"
to="https://myceliumcloud.tf"
variant="outline"
target="_blank"
rel="noopener noreferrer"
>
Deploy in Cloud
</Button>
</div>
</div>

View File

@@ -1,6 +1,5 @@
"use client";
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container'
import { Button } from "@/components/Button";
@@ -14,7 +13,7 @@ export function CallToAction() {
{/* ✅ Main boxed area */}
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
className="relative py-18 max-w-7xl mx-auto overflow-hidden bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
@@ -27,7 +26,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -44,7 +43,7 @@ export function CallToAction() {
Choose How You Want to Connect
</h2>
<p className="mt-6 text-lg text-gray-300">
<p className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
Choose How You Want to Connect
Use the network to link environments, deploy workloads, or host nodes to strengthen the mesh and run on your own hardware.
</p>
@@ -56,16 +55,19 @@ Use the network to link environments, deploy workloads, or host nodes to strengt
</Button>
<Button
to="/cloud"
as="a"
to="https://myceliumcloud.tf"
variant="outline"
color="white"
target="_blank"
rel="noopener noreferrer"
>
Deploy in Cloud
</Button>
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
<Button to="/nodes" variant="link" color="white">
Host a Node &rarr;
</Link>
</Button>
</div>
</div>
</Container>

View File

@@ -76,38 +76,45 @@ function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
export function Hero() {
return (
<div className="overflow-hidden pb-24 lg:py-12 mt-10 lg:pb-0 border border-t-0 border-b border-gray-100">
<div className="overflow-hidden pb-12 lg:py-12 mt-10 lg:pb-0 border border-t-0 border-b border-gray-100">
<Container>
<div className="flex flex-col-reverse gap-y-16 lg:grid lg:grid-cols-12 lg:gap-x-8 lg:gap-y-20 px-6 lg:px-8">
<div className="relative z-10 mx-auto max-w-2xl lg:col-span-7 lg:max-w-none lg:pt-6 xl:col-span-6">
<Eyebrow className="mb-4">
MYCELIUM NETWORK
</Eyebrow>
<H3 className="mt-8 ">
<H3 className="mt-4">
The Network Stack for Private, Autonomous Networking
</H3>
<P className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
Connect once. Get private networking, censorship-resistant publishing, and on-network AI in one encrypted fabric.
</P>
<P className="mt-6 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
<P className="mt-4 text-lg leading-tight text-gray-600 lg:text-xl lg:leading-normal">
Your Pod is your personal gateway to the network.
</P>
<div className="mt-8 flex flex-wrap gap-x-6 gap-y-4">
<Button to="/download" variant="solid" color="cyan">
Get Started
</Button>
<Button to="/download" variant="outline" color="cyan">
Explore Docs
<Button
as="a"
to="https://threefold.info/mycelium_network/docs/"
variant="outline"
color="gray"
target="_blank"
rel="noopener noreferrer"
>
Explore Docs
</Button>
</div>
</div>
<div className="relative mt-0 lg:mt-10 lg:col-span-5 lg:row-span-2 xl:col-span-6">
<BackgroundIllustration className="absolute left-1/2 top-4 h-[1026px] w-[1026px] -translate-x-1/2 stroke-gray-300/70 sm:top-16 lg:-top-12 lg:ml-12" />
<div className="mx-auto h-[460px] max-w-[520px] mask-[linear-gradient(to_bottom,white_60%,transparent)] lg:absolute lg:-inset-x-10 lg:-top-24 lg:h-auto lg:pt-10 xl:-bottom-32">
<div className="relative mt-8 lg:mt-10 lg:col-span-5 lg:row-span-2 xl:col-span-6">
<BackgroundIllustration className="hidden md:block absolute left-1/2 top-4 h-[1026px] w-[1026px] -translate-x-1/2 stroke-gray-300/70 sm:top-16 lg:-top-12 lg:ml-12" />
<div className="mx-auto max-w-[520px] flex items-center justify-center mask-[linear-gradient(to_bottom,white_60%,transparent)] lg:absolute lg:-inset-x-10 lg:-top-24 lg:h-auto lg:pt-10 xl:-bottom-32">
<img
src={phoneFrame}
alt="Mycelium application demo"
className="mx-auto w-auto max-w-[366px]"
className="mx-auto w-full max-w-[366px] h-auto"
width={366}
height={729}
/>

View File

@@ -30,7 +30,7 @@ export function NetworkCapabilities() {
One network for all your connectivity needs.
</P>
<P className="mt-3 text-lg text-gray-200">
<P className="mt-2 text-gray-200">
Mycelium replaces separate layers like VPNs, hosting, and DNS with a single encrypted, peer-to-peer system that links devices, apps, and environments directly.
</P>
</div>

View File

@@ -7,7 +7,7 @@ import windowsIcon from '@/images/windows.svg'
import androidIcon from '@/images/android.svg'
import linuxIcon from '@/images/linux.svg'
import { CT, CP } from '@/components/Texts'
import { CT, CP, Eyebrow } from '@/components/Texts'
const features = [
{
@@ -42,7 +42,7 @@ const features = [
export function NetworkDownload() {
return (
<section className="w-full max-w-8xl mx-auto bg-transparent">
<section id="download" className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
@@ -50,11 +50,12 @@ export function NetworkDownload() {
<div className="mx-auto max-w-7xl px-6 lg:px-8 bg-white py-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-2xl lg:mx-0">
<Eyebrow color="accent">Get Started</Eyebrow>
<motion.h3
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className="text-4xl font-medium tracking-tight text-gray-900 lg:text-5xl"
className="text-4xl font-medium tracking-tight mt-2 text-gray-900 lg:text-5xl"
>
Download Mycelium Network
</motion.h3>
@@ -64,19 +65,11 @@ export function NetworkDownload() {
transition={{ duration: 0.5, delay: 0.2 }}
className="mt-8 text-lg text-gray-600 lg:leading-8"
>
Get Mycelium Network for Android, Windows, macOS, and iOS to securely connect, store, and interact with the decentralized networkseamlessly and efficiently. Not sure how it works?{' '}
<a
href="https://threefold.info/mycelium_network/docs/"
className="font-semibold text-gray-900 underline transition-colors hover:text-cyan-500"
target="_blank"
rel="noopener noreferrer"
>
Read the manual.
</a>
Get Mycelium Network for Android, Windows, macOS, and iOS to securely connect, store, and interact with the decentralized network seamlessly and efficiently.
</motion.p>
</div>
<div className="mx-auto mt-8 max-w-2xl lg:mt-12 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 md:grid-cols-2 lg:max-w-none lg:grid-cols-4">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 lg:gap-y-16 gap-y-8 md:grid-cols-2 lg:max-w-none lg:grid-cols-4">
{features.map((feature) => (
<div
key={feature.name}

View File

@@ -38,11 +38,11 @@ export function NetworkPros() {
<div className="bg-[#121212] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-800">
{/* Centered intro */}
<div className="px-6 pt-12 pb-4 text-center max-w-4xl mx-auto ">
<Eyebrow className="uppercase tracking-[0.16em] text-cyan-600">
<Eyebrow className="text-cyan-500">
WHY
</Eyebrow>
<H3 className="mt-4 text-white">
<H3 className="mt-2 text-white">
Why Its Revolutionary
</H3>

View File

@@ -369,7 +369,7 @@ function FeaturesMobile() {
<MobileFeatureTitle color="white" className="mt-6">
{feature.name}
</MobileFeatureTitle>
<FeatureDescription color="secondary" className="mt-2">
<FeatureDescription className="mt- text-gray-200">
{feature.description}
</FeatureDescription>
</div>

View File

@@ -1,6 +1,6 @@
import { useId } from 'react'
import { Container } from '@/components/Container'
import { CP } from '@/components/Texts'
import { CP, H3, P, Eyebrow } from '@/components/Texts'
const features = [
{
@@ -197,13 +197,13 @@ export function SecondaryFeatures() {
<Container className="py-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-4xl sm:text-center">
<h2 className="text-base/7 font-semibold text-cyan-500">FEATURES</h2>
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
Core Features
</p>
<p className="mt-6 text-lg text-gray-600">
<Eyebrow className="text-cyan-500 uppercase tracking-[0.16em]">FEATURES</Eyebrow>
<H3 className="mt-2 text-black">
Core Features
</H3>
<P className="mt-4 text-gray-700 text-base leading-relaxed">
The Mycelium Network is evolving with new features to support richer data movement, identity, and application connectivity across the mesh.
</p>
</P>
</div>
<ul
role="list"
@@ -212,7 +212,7 @@ export function SecondaryFeatures() {
{features.map((feature) => (
<li
key={feature.name}
className="rounded-2xl border border-gray-100 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20"
className="rounded-2xl border border-gray-200 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20"
>
<feature.icon className="h-8 w-8" />
<CP className="mt-6 font-semibold text-gray-900">

View File

@@ -11,7 +11,7 @@ export function CallToAction() {
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
className="relative py-18 max-w-7xl overflow-hidden mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
@@ -24,7 +24,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -39,13 +39,13 @@ export function CallToAction() {
Join Mycelium Grid
</h2>
<p className="mt-6 text-lg text-gray-300">
<p className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
Be part of a global network that powers private, distributed
infrastructure. Host a node, contribute resources, and earn rewards
while expanding the sovereign digital grid.
</p>
<div className="mt-10 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="mt-6 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/host" variant="solid" color="cyan" className="mt-4">
Join Mycelium
@@ -54,7 +54,7 @@ export function CallToAction() {
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="/docs" variant="outline" color="white" className="mt-4">
Explore docs
Explore Docs
</Button>
</div>
</div>

View File

@@ -1,7 +1,7 @@
"use client";
import { motion } from "framer-motion";
import { SectionHeader, P, Eyebrow, CT, CP } from "@/components/Texts";
import { H3, P, Eyebrow, CT, CP } from "@/components/Texts";
import type { ComponentPropsWithoutRef } from "react";
type CircleIconProps = ComponentPropsWithoutRef<"svg">;
@@ -62,14 +62,13 @@ export function NodeBenefits() {
className="mx-auto max-w-5xl text-center"
>
<Eyebrow color="accent">Host</Eyebrow>
<SectionHeader
className="text-3xl font-medium tracking-tight"
color="light"
<H3
className="mt-2 text-white"
>
Benefits of Hosting Nodes
</SectionHeader>
</H3>
<P className="mt-6" color="light">
<P className="mt-6 text-gray-200">
Hosting a node gives you private compute, contributes to the global
Mycelium infrastructure, and unlocks ways to earn from real network
usage, all while keeping sovereignty and control.
@@ -95,13 +94,13 @@ export function NodeBenefits() {
delay: 0.3 + index * 0.15,
ease: "easeOut",
}}
className="rounded-2xl border border-gray-300 bg-white/5 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 backdrop-blur-md"
className="rounded-md border border-gray-100 bg-white/5 lg:p-8 p-6 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 backdrop-blur-md"
>
<feature.icon className="mb-4 h-8 w-8 text-white" />
<CT as="span" className="text-left font-semibold" color="light">
{feature.name}
</CT>
<CP className="mt-2 text-left text-gray-200">
<CP className="mt-2 text-left font-light text-gray-300">
{feature.description}
</CP>
</motion.li>

View File

@@ -1,32 +1,38 @@
'use client'
import { Button } from '@/components/Button'
import { Eyebrow, H3 } from '@/components/Texts'
import { Eyebrow, H3, P } from '@/components/Texts'
export function NodeHero() {
return (
<div className="">
{/* Boxed container */}
<div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/gpuhero2.png')", backgroundSize: "contain" }}
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden md:bg-[url('/images/gpuhero2.png')] md:bg-contain md:bg-right md:bg-no-repeat"
>
{/* Inner padding */}
<div className="px-6 py-16 lg:py-24">
<div className="px-6 pt-4 pb-12 lg:py-24">
{/* Mobile-only hero image */}
<img
src="/images/mobile/nodes.jpg"
alt="Mycelium Nodes visual"
className="mb-8 w-full object-cover md:hidden"
/>
<div className="max-w-2xl lg:pl-6">
<Eyebrow>MYCELIUM NODES</Eyebrow>
<H3 as="h1" className="mt-4">
Host a Node. Power the Network.
</H3>
<p className="mt-6 text-lg text-gray-800">
<P className="mt-6 text-gray-600">
The Mycelium Network runs on nodes hosted by people and organizations around the world. Each node adds capacity, resilience, and sovereignty, expanding a global network for private, distributed compute and AI.
</p>
</P>
<div className="mt-10 flex items-center gap-x-6">
<Button to="#node-getting-started" as="a" variant="solid" color="cyan">
How it works
</Button>
<Button to="#node-architecture" as="a" variant="outline">
Explore Docs <span aria-hidden="true"></span>
Explore Docs
</Button>
</div>
</div>

View File

@@ -3,6 +3,7 @@
import { useState } from "react";
import { motion } from "framer-motion";
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
import { Button } from "@/components/Button";
import {
QuestionMarkCircleIcon,
CheckIcon,
@@ -96,7 +97,7 @@ export function NodeProducts() {
</P>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 lg:gap-24 max-w-6xl mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 lg:gap-24 max-w-6xl mx-auto">
{/* ------------------------------ */}
{/* LEFT — TEXT AREA */}
@@ -106,7 +107,7 @@ export function NodeProducts() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4 }}
className="flex flex-col justify-center"
className="order-2 lg:order-1 flex flex-col justify-center"
>
<h1 className="text-3xl font-semibold text-white">
{selectedNode.name}
@@ -168,29 +169,35 @@ export function NodeProducts() {
{/* ------------------------ */}
{/* BUTTONS AREA */}
{/* ------------------------ */}
<div className="mt-10 flex flex-col sm:flex-row gap-4">
<div className="mt-8 flex flex-col sm:flex-row gap-8">
{/* Outline Button */}
<a
href={selectedNode.learnUrl}
{/* Solid Cyan Button */}
<Button
as="a"
to={selectedNode.buyUrl}
variant="solid"
color="cyan"
target="_blank"
rel="noopener noreferrer"
className="flex-1 sm:flex-none text-center border border-gray-700 hover:border-gray-500
text-gray-300 hover:text-white px-8 py-3 rounded-lg transition"
>
Learn More
</a>
{/* Solid Cyan Button */}
<a
href={selectedNode.buyUrl}
target="_blank"
rel="noopener noreferrer"
className="flex-1 sm:flex-none text-center bg-cyan-600 hover:bg-cyan-700
text-white px-8 py-3 rounded-lg font-medium transition"
className="flex-1 sm:flex-none text-center"
>
Purchase Node
</a>
</Button>
{/* Outline Button */}
<Button
as="a"
to={selectedNode.learnUrl}
variant="outline"
color="white"
target="_blank"
rel="noopener noreferrer"
className="flex-1 sm:flex-none text-center"
>
Learn More
</Button>
</div>
@@ -204,20 +211,20 @@ export function NodeProducts() {
initial={{ opacity: 0, scale: 0.92 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.35 }}
className="flex justify-center"
className="order-1 lg:order-2 flex justify-center"
>
<img
src={selectedNode.image}
alt={selectedNode.name}
className="max-w-md rounded-2xl "
className="max-w-md rounded-2xl object-contain lg:px-0 px-6 lg:top-0 -top-10"
/>
</motion.div>
</div>
</div>
{/* Bottom border */}
<div className="w-full border-b border-gray-800 bg-[#121212]" />
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-800" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
</section>
);
}

View File

@@ -4,7 +4,7 @@ import { Eyebrow, H3, P, Small, CT, CP } from "@/components/Texts";
const cards = [
{
category: "Autonomous",
category: "AUTONOMY",
title: "Autonomous Operation",
description: "Runs autonomously with no central control.",
image: "/images/autonomous.png",
@@ -12,13 +12,13 @@ const cards = [
innerRounded: "lg:rounded-tl-[calc(2rem+1px)]",
},
{
category: "Security",
category: "SECURITY",
title: "Encrypted by Default",
description: "Fully encrypted and identity-based.",
image: "/images/encryptednode.png",
},
{
category: "Efficiency",
category: "EFFICIENCY",
title: "Energy Efficient",
description: "Energy-efficient and quiet, designed for 24/7 uptime.",
image: "/images/energy.png",
@@ -26,7 +26,7 @@ const cards = [
innerRounded: "lg:rounded-tr-[calc(2rem+1px)]",
},
{
category: "Monitoring",
category: "MONITORING",
title: "Measured Uptime",
description: "Automatically measures uptime and contribution.",
image: "/images/uptime.png",
@@ -34,13 +34,13 @@ const cards = [
innerRounded: "lg:rounded-bl-[calc(2rem+1px)]",
},
{
category: "Full Stack",
category: "SUPPORT",
title: "Full Mycelium Stack Support",
description: "Supports Mycelium Network, Cloud, Pods, and Agents.",
image: "/images/fullstack.png",
},
{
category: "Edge & Home",
category: "DEPLOYMENT",
title: "Edge & Home Ready",
description:
"Runs seamlessly on compact hardware for edge, home, or micro-datacenter deployments.",
@@ -52,9 +52,15 @@ const cards = [
export function NodeSpecs() {
return (
<section className="bg-white py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-100" />
{/* ✅ Inner content container */}
<div className="max-w-7xl bg-white mx-auto py-12 border border-t-0 border-b-0 border-gray-100 px-6 lg:px-8">
<Eyebrow>Node Specifications</Eyebrow>
<H3 className="mt-2">Built for Reliability and Control</H3>
<P className="mt-4 max-w-2xl">
@@ -63,9 +69,9 @@ export function NodeSpecs() {
</P>
{/* BENTO GRID */}
<div className="mt-12 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-3 lg:grid-rows-2">
<div className="mt-8 grid grid-cols-1 gap-4 lg:grid-cols-3 lg:grid-rows-2">
{cards.map((item, index) => (
<div key={index} className="relative">
<div key={index} className="relative group">
{/* OUTER BACKPLATE */}
<div
@@ -76,7 +82,7 @@ export function NodeSpecs() {
{/* INNER CARD */}
<div
className={`relative flex h-full flex-row items-center gap-6 overflow-hidden rounded-[calc(var(--radius-lg)+1px)] p-8 ${
className={`relative flex h-full flex-row items-center gap-3 overflow-hidden rounded-[calc(var(--radius-lg)+1px)] px-8 py-6 transition-transform duration-300 group-hover:scale-102 group-hover:shadow-lg group-hover:shadow-cyan-500/20 ${
item.innerRounded || ""
}`}
>
@@ -89,15 +95,15 @@ export function NodeSpecs() {
{/* RIGHT TEXT */}
<div className="flex flex-col">
<Small className="text-gray-500">{item.category}</Small>
<Small className="text-cyan-500 uppercase tracking-[0.16em]">{item.category}</Small>
<CT className="mt-1">{item.title}</CT>
<CP className="mt-2 max-w-sm">{item.description}</CP>
<CP className="mt-1 max-w-sm">{item.description}</CP>
</div>
</div>
{/* OUTLINE */}
<div
className={`pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 ${
className={`pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 transition-transform duration-300 group-hover:scale-102 group-hover:shadow-lg group-hover:shadow-cyan-500/20 ${
item.rounded || ""
}`}
/>
@@ -105,6 +111,9 @@ export function NodeSpecs() {
))}
</div>
</div>
{/* ✅ Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
</section>
);
}

View File

@@ -1,6 +1,6 @@
"use client";
import { Eyebrow, H3, P, CT, CP } from "@/components/Texts";
import { Eyebrow, H3, P, CT } from "@/components/Texts";
import {
CloudArrowDownIcon,
CpuChipIcon,
@@ -16,7 +16,7 @@ const steps = [
icon: CpuChipIcon,
},
{
name: "Download Mycelium OS",
name: "Download Mycelium",
description:
"Install the Mycelium OS to prepare your node for network access.",
icon: CloudArrowDownIcon,
@@ -38,50 +38,74 @@ const steps = [
export function NodeSteps() {
return (
<section className="w-full max-w-8xl mx-auto bg-transparent">
{/* Top line */}
{/* Header spacing + borders */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
<div className="w-full border-t border-l border-r border-gray-100" />
<div className="max-w-7xl bg-white mx-auto py-16 border border-t-0 border-b-0 border-gray-100">
{/* Content */}
<div className="max-w-7xl bg-white mx-auto px-6 lg:px-6 py-16 border border-t-0 border-b-0 border-gray-100">
{/* HEADER */}
<div className="mx-auto max-w-4xl sm:text-center">
<Eyebrow className="text-cyan-500">HOW IT WORKS</Eyebrow>
<H3 className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
Host a Node
</H3>
<P className="mt-6 text-lg text-gray-600">
<H3 className="text-gray-900">Host a Node</H3>
<P className="mt-4 text-gray-600">
Hosting a node takes minutes, and it runs automatically once online.
</P>
</div>
{/* 🔹 Horizontal Stepper */}
<div className="relative mt-16 px-6 flex flex-col gap-8 lg:flex-row lg:items-start lg:justify-between">
{steps.map((step, i) => (
<div key={step.name} className="relative flex-1 px-4">
{/* 🔹 Horizontal connector line (desktop only) */}
{i < steps.length - 1 && (
<div className="hidden lg:block absolute top-5 left-[55%] w-full h-[4px] bg-gray-400 -z-10" />
)}
{/* STEPS */}
<ul className="relative mt-12 flex flex-col gap-14 max-w-md mx-auto lg:max-w-none lg:flex-row lg:gap-6">
{/* 🔹 Step header with icon */}
<div className="flex items-center gap-3">
<div className="flex items-center justify-center w-8 h-8 rounded-full bg-cyan-100 text-cyan-600">
<step.icon className="w-5 h-5" />
{steps.map((step, i) => (
<li key={step.name} className="relative flex lg:flex-col lg:items-center">
{/* LEFT COLUMN — circle + MOBILE vertical line */}
<div className="relative flex flex-col items-center">
{/* Circle */}
<div className="w-10 h-10 text-black bg-white border border-gray-300 rounded-full shadow-sm flex items-center justify-center z-10">
{i + 1}
</div>
<CT>{step.name}</CT>
</div>
{/* 🔹 Description */}
<CP className="mt-3">{step.description}</CP>
</div>
{/* CONTENT */}
<div className="ml-4 lg:ml-0 lg:mt-8 max-w-xs">
<div className="flex items-center gap-2 lg:justify-center">
<step.icon className="w-6 h-6 text-cyan-500" />
<CT>{step.name}</CT>
</div>
<p className="mt-2 text-base leading-snug text-gray-600 lg:text-center">
{step.description}
</p>
</div>
{/* DESKTOP horizontal line — perfectly centered */}
{i < steps.length - 1 && (
<span
className="
hidden lg:block
absolute
top-[20px] /* Circle center */
left-[50%]
w-full
h-[1px]
bg-gray-200
"
/>
)}
</li>
))}
</div>
</ul>
</div>
{/* bottom line */}
{/* Bottom horizontal line with spacing */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl bg-transparent mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
{/* Bottom border */}
<div className="w-full border-b border-gray-100" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
</section>
);
}

View File

@@ -1,4 +1,5 @@
import React from 'react';
import { AnimatedSection } from '@/components/AnimatedSection';
import { NodeHero } from './NodeHero';
import { NodeBenefits } from './NodeBenefits';
import { NodeSteps } from './NodeSteps';
@@ -9,12 +10,29 @@ import { CallToAction } from './CallToAction';
const NodesPage: React.FC = () => {
return (
<>
<NodeHero />
<NodeBenefits />
<NodeSteps />
<NodeProducts />
<NodeSpecs />
<CallToAction />
<AnimatedSection>
<NodeHero />
</AnimatedSection>
<AnimatedSection>
<NodeBenefits />
</AnimatedSection>
<AnimatedSection>
<NodeSteps />
</AnimatedSection>
<AnimatedSection>
<NodeProducts />
</AnimatedSection>
<AnimatedSection>
<NodeSpecs />
</AnimatedSection>
<AnimatedSection>
<CallToAction />
</AnimatedSection>
</>
);
};

View File

@@ -23,7 +23,7 @@ export function CallToAction() {
{/* ✅ Main boxed area */}
<div
id="get-started"
className="relative py-18 max-w-7xl mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
className="relative py-18 max-w-7xl overflow-hidden mx-auto bg-[#111111] border border-t-0 border-b-0 border-gray-800"
>
{/* ✅ Cyan Radial Glow */}
<svg
@@ -36,7 +36,7 @@ export function CallToAction() {
cx={512}
cy={512}
fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2"
fillOpacity="0.3"
/>
<defs>
<radialGradient id="mycelium-cyan-glow">
@@ -52,15 +52,15 @@ export function CallToAction() {
</h2>
<p className="mt-6 text-lg text-gray-300">
<p className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
The first Pods are launching soon.
10,000 early Pods will be available for early adopters.
</p>
<div className="mt-10 flex items-center justify-center">
<div className="mt-6 flex items-center justify-center">
<ul
role="list"
className="grid grid-cols-1 gap-x-8 gap-y-3 text-left text-base/7 text-gray-200 sm:grid-cols-2"
className="grid grid-cols-1 gap-x-8 gap-y-1 lg:gap-y-3 text-left text-base/7 text-gray-200 sm:grid-cols-2"
>
{benefits.map((benefit) => (
<li key={benefit} className="flex items-start gap-x-3">
@@ -74,14 +74,14 @@ export function CallToAction() {
</ul>
</div>
<p className="mt-6 text-lg text-gray-300">
<p className="mt-6 lg:text-lg text-base leading-normal text-gray-300">
Next, Pods will support peer-to-peer AI Agents that live inside your environment.
Your own AI, powered by your data without any data leaks. Be among the first to claim
your private space on the Mycelium Network.
</p>
{/* ✅ Two cards, stacked center with spacing */}
<div className="mt-10 flex flex-wrap justify-center gap-x-10 gap-y-8">
<div className="mt-6 flex flex-wrap justify-center gap-x-8 gap-y-8">
<div className="flex flex-col items-center text-center max-w-xs">
<Button to="#" variant="solid" color="cyan" className="mt-4">
Join the Waitlist

View File

@@ -1,22 +1,13 @@
import { H3, Eyebrow, P } from "@/components/Texts"
import { Button } from "@/components/Button"
import React from 'react';
// NOTE: Ensure your global types file (global.d.ts) is set up
// to avoid TypeScript errors on window.ml_account
export default function Homepod() {
const onGetStartedClick = () => {
// 1. Ensure we are in a browser environment (client-side)
// and the ml_account function is available globally.
if (typeof window !== 'undefined' && window.ml_account) {
// 2. Execute the MailerLite pop-up trigger function using the specific snippet you provided.
// TypeScript is happy if you defined the global type in step 1.
window.ml_account('webforms', '6108375', 'l9m8g1', 'show');
// Ensure we are in a browser environment and ml_account exists before calling it
if (typeof window !== 'undefined' && typeof (window as any).ml_account === 'function') {
(window as any).ml_account('webforms', '6108375', 'l9m8g1', 'show')
} else {
console.log("MailerLite script (ml_account) not fully loaded or not in browser.");
console.log("MailerLite script (ml_account) not fully loaded or not in browser.")
}
};
@@ -24,11 +15,17 @@ export default function Homepod() {
<div className="">
{/* Boxed container */}
<div
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/computehero11.webp')", backgroundSize: "contain" }}
className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-gray-100 bg-white overflow-hidden md:bg-[url('/images/computehero11.webp')] md:bg-contain md:bg-right md:bg-no-repeat"
>
{/* Inner padding */}
<div className="px-6 py-16 lg:py-24">
<div className="px-6 pt-4 pb-12 lg:py-24">
{/* Mobile-only hero image */}
<img
src="/images/mobile/pods.jpg"
alt="Mycelium Pods visual"
className="mb-8 w-full object-cover md:hidden"
/>
<div className="max-w-2xl lg:pl-6">
<Eyebrow>
Mycelium Pods - Coming Soon
@@ -36,7 +33,7 @@ export default function Homepod() {
<H3 className="mt-4">
Your Private Space in the New Internet
</H3>
<P className="mt-6 text-gray-800">
<P className="mt-6 text-gray-600">
Pods are personal digital spaces on the Mycelium Network. They are private, persistent, and fully under your control. Run conversations, files, and tools directly on the network instead of through central servers
</P>
<div className="mt-8 flex items-center gap-x-6">
@@ -49,7 +46,7 @@ export default function Homepod() {
Join the Waitlist
</Button>
<Button to="#" variant="outline">
Explore Docs
Explore Docs
</Button>
</div>
</div>

View File

@@ -108,7 +108,7 @@ export function PodsBento() {
</div>
</div>
) : (
<div className="h-48 w-full flex items-center justify-center bg-transparent" />
<div className="hidden md:flex md:h-48 w-full items-center justify-center bg-transparent" />
)}
{/* TEXT AREA */}

View File

@@ -20,7 +20,7 @@ export function PodsCapabilities() {
{/* ✅ LEFT SIDE — Title + Intro */}
<div className="max-w-xl ">
<Eyebrow>What You Can Do</Eyebrow>
<Eyebrow className="text-cyan-500 tracking-[0.16em]">What You Can Do</Eyebrow>
<H3 className="mt-6 text-white">
Pods Features

Some files were not shown because too many files have changed in this diff Show More