Compare commits
63 Commits
developmen
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
| fdd0109ffc | |||
| 1ec9741283 | |||
| 5d7272ff6c | |||
| c68b4e5de9 | |||
| c3b171e3b2 | |||
| ed995113df | |||
| 357b2f58c3 | |||
| 7d8ae1d26d | |||
| 3c4da26ecb | |||
| 023921a6cc | |||
| 8e033a3c21 | |||
| 01b1c20b60 | |||
| c962743737 | |||
| e62c4a5688 | |||
| 6b735b5a40 | |||
| 7b9cf135e4 | |||
| 544d7d541b | |||
| b21f874a05 | |||
| e6b194e8c7 | |||
| a8105a0551 | |||
| de5d990fc9 | |||
| 29d2b76db9 | |||
| a0beec808e | |||
| 96c445aa41 | |||
| ce4b4b3360 | |||
| c849c74a53 | |||
| 7bc895d8be | |||
| c0b84fd578 | |||
| 6d96ff9ea8 | |||
| f1e1721b25 | |||
| aed3e8ed25 | |||
| f126287018 | |||
| 9f1e78e116 | |||
| 97fdf3aa4f | |||
| c1ca5e35f0 | |||
| e5ed88b676 | |||
| 6beb9c1432 | |||
| a9f53224cf | |||
| 3df73ec418 | |||
| c6efc29ab6 | |||
| bec52e7185 | |||
| 29f713cd2f | |||
| d8a7a7331a | |||
| 00c5f7f880 | |||
| 2dbcda4997 | |||
| 979d151537 | |||
| 252e2335c2 | |||
| 9b2c406e9e | |||
| 791216433c | |||
| a4a6c95612 | |||
| da5cf2d4a2 | |||
| d2e2e87a0c | |||
| a8d91a1624 | |||
| f9ee299362 | |||
| 8509b80f47 | |||
| 7d6bbc2763 | |||
| 4cf6f63139 | |||
| ef9865862b | |||
| 503fe26303 | |||
| 39b20f30a4 | |||
| d53f2d943f | |||
| 3213179ff6 | |||
| c289c63856 |
1
google5dd3a8b700455c0e.html
Normal file
@@ -0,0 +1 @@
|
||||
google-site-verification: google5dd3a8b700455c0e.html
|
||||
@@ -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" />
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 922 KiB After Width: | Height: | Size: 618 KiB |
|
Before Width: | Height: | Size: 510 KiB After Width: | Height: | Size: 508 KiB |
|
Before Width: | Height: | Size: 306 KiB |
|
Before Width: | Height: | Size: 205 KiB |
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 228 KiB |
|
Before Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 988 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 780 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 796 KiB After Width: | Height: | Size: 792 KiB |
|
Before Width: | Height: | Size: 906 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 861 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 774 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/mainlogo.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/images/mediakit/logo_dark.zip
Normal file
BIN
public/images/mediakit/logo_dark/logo_dark.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
1
public/images/mediakit/logo_dark/logo_dark.svg
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
public/images/mediakit/logo_dark/logomark.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
1
public/images/mediakit/logo_dark/logomark.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" zoomAndPan="magnify" viewBox="0 0 75 74.999997" height="100" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><clipPath id="17cc7c511f"><path d="M 0.679688 0.28125 L 48.441406 0.28125 L 48.441406 5 L 0.679688 5 Z M 0.679688 0.28125 " clip-rule="nonzero"/></clipPath><clipPath id="871aafab52"><path d="M 0.679688 36 L 48.441406 36 L 48.441406 40.601562 L 0.679688 40.601562 Z M 0.679688 36 " clip-rule="nonzero"/></clipPath><clipPath id="08bb39558f"><rect x="0" width="49" y="0" height="41"/></clipPath></defs><g transform="matrix(1, 0, 0, 1, 13, 17)"><g clip-path="url(#08bb39558f)"><g clip-path="url(#17cc7c511f)"><path stroke-linecap="butt" transform="matrix(0.559221, 0, 0, 0.559221, 3.099571, 0.434943)" fill="none" stroke-linejoin="miter" d="M -0.00342307 4.000082 L 76.539934 4.000082 " stroke="#22d3ee" stroke-width="8" stroke-opacity="1" stroke-miterlimit="4"/></g><path fill="#22d3ee" d="M 3.097656 18.003906 L 29.941406 18.003906 L 29.941406 22.480469 L 3.097656 22.480469 M 34.414062 18.003906 L 45.902344 18.003906 L 45.902344 22.480469 L 34.414062 22.480469 " fill-opacity="1" fill-rule="nonzero"/><g clip-path="url(#871aafab52)"><path stroke-linecap="butt" transform="matrix(0.559221, 0, 0, 0.559221, 3.099571, 36.091279)" fill="none" stroke-linejoin="miter" d="M -0.00342307 3.999929 L 76.539934 3.999929 " stroke="#22d3ee" stroke-width="8" stroke-opacity="1" stroke-miterlimit="4"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/mediakit/logo_light.zip
Normal file
BIN
public/images/mediakit/logo_light/logo.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
1
public/images/mediakit/logo_light/logo.svg
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
public/images/mediakit/logo_light/logomark.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
1
public/images/mediakit/logo_light/logomark.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" zoomAndPan="magnify" viewBox="0 0 75 74.999997" height="100" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><clipPath id="17cc7c511f"><path d="M 0.679688 0.28125 L 48.441406 0.28125 L 48.441406 5 L 0.679688 5 Z M 0.679688 0.28125 " clip-rule="nonzero"/></clipPath><clipPath id="871aafab52"><path d="M 0.679688 36 L 48.441406 36 L 48.441406 40.601562 L 0.679688 40.601562 Z M 0.679688 36 " clip-rule="nonzero"/></clipPath><clipPath id="08bb39558f"><rect x="0" width="49" y="0" height="41"/></clipPath></defs><g transform="matrix(1, 0, 0, 1, 13, 17)"><g clip-path="url(#08bb39558f)"><g clip-path="url(#17cc7c511f)"><path stroke-linecap="butt" transform="matrix(0.559221, 0, 0, 0.559221, 3.099571, 0.434943)" fill="none" stroke-linejoin="miter" d="M -0.00342307 4.000082 L 76.539934 4.000082 " stroke="#22d3ee" stroke-width="8" stroke-opacity="1" stroke-miterlimit="4"/></g><path fill="#22d3ee" d="M 3.097656 18.003906 L 29.941406 18.003906 L 29.941406 22.480469 L 3.097656 22.480469 M 34.414062 18.003906 L 45.902344 18.003906 L 45.902344 22.480469 L 34.414062 22.480469 " fill-opacity="1" fill-rule="nonzero"/><g clip-path="url(#871aafab52)"><path stroke-linecap="butt" transform="matrix(0.559221, 0, 0, 0.559221, 3.099571, 36.091279)" fill="none" stroke-linejoin="miter" d="M -0.00342307 3.999929 L 76.539934 3.999929 " stroke="#22d3ee" stroke-width="8" stroke-opacity="1" stroke-miterlimit="4"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/mobile/agents.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/images/mobile/cloudpage.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/images/mobile/homepage.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/images/mobile/nodes.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/images/mobile/pods.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 874 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 156 KiB |
@@ -12,6 +12,7 @@ const StoragePage = lazy(() => import('./pages/storage/StoragePage'));
|
||||
const GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
|
||||
const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
|
||||
const NodesPage = lazy(() => import('./pages/nodes/NodesPage'));
|
||||
const MediaPage = lazy(() => import('./pages/mediakit/MediaPage'));
|
||||
|
||||
function ScrollToTop() {
|
||||
const { pathname, hash } = useLocation();
|
||||
@@ -49,6 +50,7 @@ function App() {
|
||||
<Route path="gpu" element={<GpuPage />} />
|
||||
<Route path="pods" element={<PodsPage />} />
|
||||
<Route path="nodes" element={<NodesPage />} />
|
||||
<Route path="mediakit" element={<MediaPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</Suspense>
|
||||
|
||||
BIN
src/assets/fonts/Mulish.zip
Normal file
BIN
src/assets/fonts/Mulish/Mulish-Italic-VariableFont_wght.ttf
Normal file
BIN
src/assets/fonts/Mulish/Mulish-VariableFont_wght.ttf
Normal file
93
src/assets/fonts/Mulish/OFL.txt
Normal file
@@ -0,0 +1,93 @@
|
||||
Copyright 2016 The Mulish Project Authors (https://github.com/googlefonts/mulish)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
79
src/assets/fonts/Mulish/README.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
Mulish Variable Font
|
||||
====================
|
||||
|
||||
This download contains Mulish as both variable fonts and static fonts.
|
||||
|
||||
Mulish is a variable font with this axis:
|
||||
wght
|
||||
|
||||
This means all the styles are contained in these files:
|
||||
Mulish/Mulish-VariableFont_wght.ttf
|
||||
Mulish/Mulish-Italic-VariableFont_wght.ttf
|
||||
|
||||
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||
in those cases you can use the static font files for Mulish:
|
||||
Mulish/static/Mulish-ExtraLight.ttf
|
||||
Mulish/static/Mulish-Light.ttf
|
||||
Mulish/static/Mulish-Regular.ttf
|
||||
Mulish/static/Mulish-Medium.ttf
|
||||
Mulish/static/Mulish-SemiBold.ttf
|
||||
Mulish/static/Mulish-Bold.ttf
|
||||
Mulish/static/Mulish-ExtraBold.ttf
|
||||
Mulish/static/Mulish-Black.ttf
|
||||
Mulish/static/Mulish-ExtraLightItalic.ttf
|
||||
Mulish/static/Mulish-LightItalic.ttf
|
||||
Mulish/static/Mulish-Italic.ttf
|
||||
Mulish/static/Mulish-MediumItalic.ttf
|
||||
Mulish/static/Mulish-SemiBoldItalic.ttf
|
||||
Mulish/static/Mulish-BoldItalic.ttf
|
||||
Mulish/static/Mulish-ExtraBoldItalic.ttf
|
||||
Mulish/static/Mulish-BlackItalic.ttf
|
||||
|
||||
Get started
|
||||
-----------
|
||||
|
||||
1. Install the font files you want to use
|
||||
|
||||
2. Use your app's font picker to view the font family and all the
|
||||
available styles
|
||||
|
||||
Learn more about variable fonts
|
||||
-------------------------------
|
||||
|
||||
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||
https://variablefonts.typenetwork.com
|
||||
https://medium.com/variable-fonts
|
||||
|
||||
In desktop apps
|
||||
|
||||
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||
|
||||
Online
|
||||
|
||||
https://developers.google.com/fonts/docs/getting_started
|
||||
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||
|
||||
Installing fonts
|
||||
|
||||
MacOS: https://support.apple.com/en-us/HT201749
|
||||
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||
|
||||
Android Apps
|
||||
|
||||
https://developers.google.com/fonts/docs/android
|
||||
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||
|
||||
License
|
||||
-------
|
||||
Please read the full license text (OFL.txt) to understand the permissions,
|
||||
restrictions and requirements for usage, redistribution, and modification.
|
||||
|
||||
You can use them in your products & projects – print or digital,
|
||||
commercial or otherwise.
|
||||
|
||||
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||
license for all details.
|
||||
BIN
src/assets/fonts/Mulish/static/Mulish-Black.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-BlackItalic.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-Bold.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-BoldItalic.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-ExtraBold.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-ExtraBoldItalic.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-ExtraLight.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-ExtraLightItalic.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-Italic.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-Light.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-LightItalic.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-Medium.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-MediumItalic.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-Regular.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-SemiBold.ttf
Normal file
BIN
src/assets/fonts/Mulish/static/Mulish-SemiBoldItalic.ttf
Normal file
@@ -3,23 +3,30 @@ 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 = {
|
||||
solid: {
|
||||
cyan: 'relative overflow-hidden bg-cyan-500 text-white before:absolute before:inset-0 active:before:bg-transparent hover:before:bg-white/10 active:bg-cyan-600 active:text-white/80 before:transition-colors',
|
||||
cyan: 'relative overflow-hidden bg-cyan-500 text-white before:absolute before:inset-0 hover:bg-cyan-400 active:before:bg-transparent hover:before:bg-white/10 active:bg-cyan-500 active:text-white/80 before:transition-colors',
|
||||
white:
|
||||
'bg-white text-cyan-900 hover:bg-white/90 active:bg-white/90 active:text-cyan-900/70',
|
||||
gray: 'bg-gray-800 text-white hover:bg-gray-900 active:bg-gray-800 active:text-white/80',
|
||||
green: 'bg-green-500 text-white hover:bg-green-600',
|
||||
},
|
||||
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',
|
||||
cyan: 'border-cyan-500 text-cyan-500 hover:border-cyan-400 hover:text-cyan-400 active:border-cyan-400',
|
||||
gray: 'border-gray-200 text-gray-600 hover:text-cyan-400 hover:border-cyan-400 active:border-cyan-400',
|
||||
white: 'border-gray-300 text-white hover:text-cyan-400 hover:border-cyan-400 active:border-cyan-400',
|
||||
},
|
||||
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-400',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
@@ -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" />
|
||||
<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>
|
||||
<img src="/images/logomark.svg" alt="Mycelium Logomark" className="h-20 w-20 flex-none" />
|
||||
<div className="">
|
||||
<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">
|
||||
@@ -30,6 +30,9 @@ export function Footer() {
|
||||
<Link to="/nodes" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
||||
Nodes
|
||||
</Link>
|
||||
<Link to="/mediakit" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
||||
Media Kit
|
||||
</Link>
|
||||
</nav>
|
||||
</div>
|
||||
<div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-100 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6">
|
||||
@@ -49,11 +52,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">
|
||||
© 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>
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ const colorVariants = {
|
||||
primary: 'text-gray-900',
|
||||
secondary: 'text-gray-600',
|
||||
light: 'text-gray-50',
|
||||
accent: 'text-cyan-500',
|
||||
cyan: 'text-cyan-50',
|
||||
accent: 'text-cyan-400',
|
||||
cyan: 'text-cyan-400',
|
||||
white: 'text-white',
|
||||
dark: 'text-gray-950',
|
||||
tertiary: 'text-gray-700',
|
||||
@@ -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')
|
||||
|
||||
@@ -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]"
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -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
|
||||
|
||||
// 🚨 Map the API response to your component's expected GeoNode format
|
||||
const data: RawNode[] = await response.json();
|
||||
|
||||
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),
|
||||
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;
|
||||
1
src/images/logos/logomark.svg
Normal 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 |
1
src/images/logos/mainlogo.svg
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 today’s 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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||