Compare commits
66 Commits
developmen
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 09ac38f598 | |||
| c68a46691f | |||
| 5a6d58dd85 | |||
| 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" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Project Mycelium - Unleash the Power of Decentralized Networks</title>
|
<meta name="google-site-verification" content="rRrZkMEhdC4yFe_BrENEzYmy2bRfD-VE6RTRiDJNLkg" />
|
||||||
<meta name="description" content="Project Mycelium's technology enables anyone to deploy their own Internet infrastructure, anywhere." />
|
<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.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@400;500;700&display=swap" rel="stylesheet" />
|
<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 GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
|
||||||
const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
|
const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
|
||||||
const NodesPage = lazy(() => import('./pages/nodes/NodesPage'));
|
const NodesPage = lazy(() => import('./pages/nodes/NodesPage'));
|
||||||
|
const MediaPage = lazy(() => import('./pages/mediakit/MediaPage'));
|
||||||
|
|
||||||
function ScrollToTop() {
|
function ScrollToTop() {
|
||||||
const { pathname, hash } = useLocation();
|
const { pathname, hash } = useLocation();
|
||||||
@@ -49,6 +50,7 @@ function App() {
|
|||||||
<Route path="gpu" element={<GpuPage />} />
|
<Route path="gpu" element={<GpuPage />} />
|
||||||
<Route path="pods" element={<PodsPage />} />
|
<Route path="pods" element={<PodsPage />} />
|
||||||
<Route path="nodes" element={<NodesPage />} />
|
<Route path="nodes" element={<NodesPage />} />
|
||||||
|
<Route path="mediakit" element={<MediaPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
</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 = {
|
const baseStyles = {
|
||||||
solid:
|
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:
|
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 = {
|
const variantStyles = {
|
||||||
solid: {
|
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:
|
white:
|
||||||
'bg-white text-cyan-900 hover:bg-white/90 active:bg-white/90 active:text-cyan-900/70',
|
'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',
|
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',
|
green: 'bg-green-500 text-white hover:bg-green-600',
|
||||||
},
|
},
|
||||||
outline: {
|
outline: {
|
||||||
cyan: 'border-cyan-500 text-cyan-500',
|
cyan: 'border-cyan-500 text-cyan-500 hover:border-cyan-400 hover:text-cyan-400 active:border-cyan-400',
|
||||||
gray: 'border-gray-300 text-gray-700 hover:border-cyan-500 active:border-cyan-500',
|
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:border-cyan-500 active:border-cyan-500',
|
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'
|
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) {
|
export function Button({ className, as, ...props }: ButtonProps) {
|
||||||
props.variant ??= 'solid'
|
// Set safe defaults per variant so color always matches a valid palette key
|
||||||
props.color ??= 'gray'
|
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(
|
className = clsx(
|
||||||
baseStyles[props.variant],
|
baseStyles[variant],
|
||||||
props.variant === 'outline'
|
variant === 'outline'
|
||||||
? variantStyles.outline[props.color]
|
? variantStyles.outline[color as keyof typeof variantStyles.outline]
|
||||||
: props.variant === 'solid'
|
: variant === 'solid'
|
||||||
? variantStyles.solid[props.color]
|
? variantStyles.solid[color as keyof typeof variantStyles.solid]
|
||||||
: undefined,
|
: variant === 'link'
|
||||||
|
? variantStyles.link[color as keyof typeof variantStyles.link]
|
||||||
|
: undefined,
|
||||||
className,
|
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 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>
|
||||||
<div className="flex items-center text-gray-900">
|
<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-20 w-20 flex-none" />
|
||||||
<div className="ml-4">
|
<div className="">
|
||||||
<p className="text-base font-semibold">Project Mycelium</p>
|
<p className="text-base lg:text-lg font-semibold">Project Mycelium</p>
|
||||||
<p className="mt-1 text-sm">Unleash the Power of Decentralization</p>
|
<p className="mt-1 text-sm">Built for Digital Sovereignty</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav className="mt-10 flex gap-8">
|
<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">
|
<Link to="/nodes" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
||||||
Nodes
|
Nodes
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link to="/mediakit" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
|
||||||
|
Media Kit
|
||||||
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</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">
|
<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>
|
||||||
</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">
|
<p className="mt-6 text-sm text-gray-500 md:mt-0">
|
||||||
© Copyright{' '}
|
© Copyright{' '}
|
||||||
<a href="https://www.threefold.io" target="_blank" rel="noopener noreferrer" className="hover:text-cyan-500 transition-colors">
|
<a href="https://ourworld.tf/" target="_blank" rel="noopener noreferrer" className="font-semibold hover:text-cyan-500 transition-colors">
|
||||||
ThreeFold
|
OurWorld
|
||||||
</a>{' '}
|
</a>{' '}
|
||||||
{new Date().getFullYear()}. All rights reserved.
|
{new Date().getFullYear()}. All rights reserved.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useState } from 'react'
|
|||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { Container } from './Container'
|
import { Container } from './Container'
|
||||||
import { Button } from './Button'
|
import { Button } from './Button'
|
||||||
import pmyceliumLogo from '../images/logos/logo_1.png'
|
import pmyceliumLogo from '../images/logos/mainlogo.svg'
|
||||||
import { Dialog } from '@headlessui/react'
|
import { Dialog } from '@headlessui/react'
|
||||||
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
|
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useState } from 'react'
|
|||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { Container } from './Container'
|
import { Container } from './Container'
|
||||||
import { Button } from './Button'
|
import { Button } from './Button'
|
||||||
import pmyceliumLogo from '../images/logos/logo_1.png'
|
import pmyceliumLogo from '../images/logos/mainlogo.svg'
|
||||||
import { Dialog } from '@headlessui/react'
|
import { Dialog } from '@headlessui/react'
|
||||||
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
|
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ const colorVariants = {
|
|||||||
primary: 'text-gray-900',
|
primary: 'text-gray-900',
|
||||||
secondary: 'text-gray-600',
|
secondary: 'text-gray-600',
|
||||||
light: 'text-gray-50',
|
light: 'text-gray-50',
|
||||||
accent: 'text-cyan-500',
|
accent: 'text-cyan-400',
|
||||||
cyan: 'text-cyan-50',
|
cyan: 'text-cyan-400',
|
||||||
white: 'text-white',
|
white: 'text-white',
|
||||||
dark: 'text-gray-950',
|
dark: 'text-gray-950',
|
||||||
tertiary: 'text-gray-700',
|
tertiary: 'text-gray-700',
|
||||||
@@ -162,5 +162,5 @@ export const DownloadCardDescription = createTextComponent(
|
|||||||
'text-base/7 leading-normal tracking-normal'
|
'text-base/7 leading-normal tracking-normal'
|
||||||
)
|
)
|
||||||
|
|
||||||
export const CT = createTextComponent('span', 'text-base lg:text-lg font-medium')
|
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-tight font-light')
|
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}
|
ref={scrollerRef}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex w-max shrink-0 gap-16 py-4",
|
"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]"
|
pauseOnHover && "hover:[animation-play-state:paused]"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -71,30 +71,27 @@ const clusterNodes = (nodeList: GeoNode[], cellSize = 2) => {
|
|||||||
function DynamicMapContainer() {
|
function DynamicMapContainer() {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [nodes, setNodes] = useState<GeoNode[]>([]);
|
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(() => {
|
useEffect(() => {
|
||||||
async function fetchNodeData() {
|
async function fetchNodeData() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(API_URL);
|
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
|
const geoNodes: GeoNode[] = data
|
||||||
.filter((node: RawNode) => node.location && node.location.latitude && node.location.longitude)
|
.filter((node: RawNode) => node.location && node.location.latitude && node.location.longitude)
|
||||||
.map((node: RawNode) => ({
|
.map((node: RawNode) => ({
|
||||||
// Convert string coordinates to numbers
|
|
||||||
lat: parseFloat(node.location.latitude),
|
lat: parseFloat(node.location.latitude),
|
||||||
lng: parseFloat(node.location.longitude),
|
lng: parseFloat(node.location.longitude),
|
||||||
label: `${node.location.city}, ${node.location.country} (${node.node_id})`,
|
label: `${node.location.city}, ${node.location.country} (${node.node_id})`,
|
||||||
// Optionally set color based on some node property if available
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const clusteredNodes = clusterNodes(geoNodes);
|
const clusteredNodes = clusterNodes(geoNodes);
|
||||||
setNodes(clusteredNodes);
|
setNodes(clusteredNodes);
|
||||||
setLoading(false);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch node data:", error);
|
console.error("Failed to fetch node data:", error);
|
||||||
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,30 +99,24 @@ function DynamicMapContainer() {
|
|||||||
fetchNodeData();
|
fetchNodeData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// --- RENDERING ---
|
// While fetching, show a loading state
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
// Show a loading state while data is being fetched
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center items-center w-full aspect-[2/1] bg-[#111111] rounded-lg text-cyan-500">
|
<div className="flex justify-center items-center w-full aspect-[2/1] bg-[#111111] rounded-lg text-cyan-500">
|
||||||
<motion.span
|
<motion.span
|
||||||
animate={{ rotate: 360 }}
|
animate={{ rotate: 360 }}
|
||||||
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
|
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
|
||||||
className="text-4xl"
|
className="text-4xl"
|
||||||
>
|
>
|
||||||
🌎
|
🌎
|
||||||
</motion.span>
|
</motion.span>
|
||||||
<p className="ml-4">Loading nodes...</p>
|
<p className="ml-4">Loading nodes...</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the dynamically fetched nodes to your WorldMap component
|
// After data is loaded, render the map
|
||||||
return (
|
return <WorldMap nodes={nodes} />;
|
||||||
<WorldMap
|
|
||||||
nodes={nodes}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DynamicMapContainer;
|
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 className="w-full h-full object-cover"><card.animation /></div>
|
||||||
</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">
|
<div className="px-8 pt-4 pb-6">
|
||||||
@@ -136,7 +136,7 @@ export function AgentBento() {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{/* ✅ NEW SUBTITLE */}
|
{/* ✅ 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">
|
<p className="mt-1 text-lg font-medium lg:text-xl tracking-tight text-white">
|
||||||
{card.title}
|
{card.title}
|
||||||
@@ -161,6 +161,9 @@ export function AgentBento() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Button } from '@/components/Button'
|
|
||||||
import { Eyebrow, H3, P } from '@/components/Texts'
|
import { Eyebrow, H3, P } from '@/components/Texts'
|
||||||
|
|
||||||
export function AgentHeroAlt() {
|
export function AgentHeroAlt() {
|
||||||
@@ -8,28 +7,32 @@ export function AgentHeroAlt() {
|
|||||||
<div className="">
|
<div className="">
|
||||||
{/* Boxed container */}
|
{/* Boxed container */}
|
||||||
<div
|
<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"
|
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"
|
||||||
style={{ backgroundImage: "url('/images/agents.webp')", backgroundSize: "contain" }}
|
|
||||||
>
|
>
|
||||||
{/* Inner padding */}
|
{/* Inner padding */}
|
||||||
<div className="px-6 py-16 lg:py-24">
|
<div className="px-6 pt-4 pb-12 lg:py-24">
|
||||||
<div className="max-w-2xl lg:pl-6">
|
{/* 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>
|
<Eyebrow>MYCELIUM AGENTS - COMING IN 2026</Eyebrow>
|
||||||
<H3 as="h1" className="mt-4">
|
<H3 as="h1" className="mt-4">
|
||||||
Private, Sovereign and Distributed AI You Control
|
Private, Sovereign and Distributed AI You Control
|
||||||
</H3>
|
</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.
|
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.
|
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>
|
</P>
|
||||||
|
|
||||||
<div className="mt-10 flex items-center gap-x-6">
|
<div className="mt-10 flex items-center gap-x-6">
|
||||||
<Button href="#" variant="solid" color="cyan">
|
{/* TODO: Hero CTAs (Follow Development / Explore Docs) to be added when links are ready.
|
||||||
Follow Development
|
Previously two Buttons here with href="#". */}
|
||||||
</Button>
|
|
||||||
<Button href="#" variant="outline">
|
|
||||||
Explore Docs <span aria-hidden="true">→</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ export function AgentPro() {
|
|||||||
<div className="w-full border-t border-l border-r border-gray-100" />
|
<div className="w-full border-t border-l border-r border-gray-100" />
|
||||||
|
|
||||||
{/* Intro Block */}
|
{/* 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">
|
<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
|
Advantages
|
||||||
</Eyebrow>
|
</Eyebrow>
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ export function AgentPro() {
|
|||||||
{item.title}
|
{item.title}
|
||||||
</h3>
|
</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}
|
{item.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
|
import { Eyebrow, P, CT, CP, H3} from "@/components/Texts";
|
||||||
import {
|
import {
|
||||||
CpuChipIcon,
|
CpuChipIcon,
|
||||||
GlobeAltIcon,
|
GlobeAltIcon,
|
||||||
@@ -63,19 +63,18 @@ export function AgentUsecase() {
|
|||||||
<div className="w-full border-t border-l border-r border-gray-100" />
|
<div className="w-full border-t border-l border-r border-gray-100" />
|
||||||
|
|
||||||
{/* Main framed section */}
|
{/* Main framed section */}
|
||||||
<div className="border border-t-0 border-b-0 border-gray-100 bg-white">
|
<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-4xl sm:text-center py-12">
|
<div className="mx-auto max-w-3xl sm:text-center px-6 lg:px-8">
|
||||||
{/* Intro block (from isIntro item) */}
|
{/* Intro block (from isIntro item) */}
|
||||||
{networkUseCases[0].isIntro && (
|
{networkUseCases[0].isIntro && (
|
||||||
<>
|
<>
|
||||||
<Eyebrow className="text-cyan-600">{networkUseCases[0].eyebrow}</Eyebrow>
|
<Eyebrow className="text-cyan-500">{networkUseCases[0].eyebrow}</Eyebrow>
|
||||||
<SectionHeader
|
<H3
|
||||||
as="h3"
|
className="mt-4 text-gray-900"
|
||||||
className="mt-4 text-gray-900 text-3xl lg:text-4xl"
|
|
||||||
>
|
>
|
||||||
{networkUseCases[0].title}
|
{networkUseCases[0].title}
|
||||||
</SectionHeader>
|
</H3>
|
||||||
<P className="mt-6 text-lg text-gray-600">
|
<P className="mt-4 text-lg text-gray-600">
|
||||||
{networkUseCases[0].description}
|
{networkUseCases[0].description}
|
||||||
</P>
|
</P>
|
||||||
</>
|
</>
|
||||||
@@ -85,7 +84,7 @@ export function AgentUsecase() {
|
|||||||
{/* Grid of features (excluding intro) */}
|
{/* Grid of features (excluding intro) */}
|
||||||
<ul
|
<ul
|
||||||
role="list"
|
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) => (
|
{networkUseCases.slice(1).map((item, idx) => (
|
||||||
<li
|
<li
|
||||||
@@ -94,20 +93,20 @@ export function AgentUsecase() {
|
|||||||
>
|
>
|
||||||
{/* Icon */}
|
{/* Icon */}
|
||||||
{item.icon && (
|
{item.icon && (
|
||||||
<div className="h-10 w-10 flex items-center justify-center rounded-xl bg-gray-100">
|
<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-600" />
|
<item.icon className="h-6 w-6 text-cyan-500" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<p className="mt-6 text-lg font-semibold text-gray-900">
|
<CT className="leading-normal text-gray-900">
|
||||||
{item.title}
|
{item.title}
|
||||||
</p>
|
</CT>
|
||||||
|
|
||||||
{/* Description */}
|
{/* 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}
|
{item.description}
|
||||||
</p>
|
</CP>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export function CallToAction() {
|
|||||||
{/* ✅ Main boxed area */}
|
{/* ✅ Main boxed area */}
|
||||||
<div
|
<div
|
||||||
id="get-started"
|
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 */}
|
{/* ✅ Cyan Radial Glow */}
|
||||||
<svg
|
<svg
|
||||||
@@ -26,7 +26,7 @@ export function CallToAction() {
|
|||||||
cx={512}
|
cx={512}
|
||||||
cy={512}
|
cy={512}
|
||||||
fill="url(#mycelium-cyan-glow)"
|
fill="url(#mycelium-cyan-glow)"
|
||||||
fillOpacity="0.2"
|
fillOpacity="0.3"
|
||||||
/>
|
/>
|
||||||
<defs>
|
<defs>
|
||||||
<radialGradient id="mycelium-cyan-glow">
|
<radialGradient id="mycelium-cyan-glow">
|
||||||
@@ -41,38 +41,42 @@ export function CallToAction() {
|
|||||||
Start with Mycelium Today
|
Start with Mycelium Today
|
||||||
</h2>
|
</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.
|
The Agent Framework launches in H1 2026, but the foundation is ready now.
|
||||||
</p>
|
</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.
|
Use today’s components —models, storage, compute, and network— to deploy workloads, connect nodes, and prepare for the next generation of distributed AI.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* ✅ Two cards, stacked center with spacing */}
|
{/* ✅ Button row – same structure as homepage CTA */}
|
||||||
<div className="mt-8 flex flex-wrap justify-center gap-x-10 gap-y-8">
|
<div className="mt-10 flex flex-wrap justify-center items-center gap-x-6 gap-y-4">
|
||||||
<div className="flex flex-col items-center text-center max-w-xs">
|
<Button
|
||||||
<Button to="/deploy" variant="solid" color="cyan" className="mt-4">
|
as="a"
|
||||||
Deploy a Model
|
to="https://myceliumcloud.tf"
|
||||||
</Button>
|
variant="solid"
|
||||||
</div>
|
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="/nodes" variant="outline" color="white">
|
||||||
<Button to="/host" as="a" variant="outline" color="white" className="mt-4">
|
Host a Node
|
||||||
Host a Node
|
</Button>
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col items-center text-center max-w-xs">
|
<Button
|
||||||
<a
|
as="a"
|
||||||
href="https://threefold.info/mycelium_network/docs/"
|
to="https://threefold.info/mycelium_network/docs/"
|
||||||
target="_blank"
|
variant="link"
|
||||||
rel="noopener noreferrer"
|
color="white"
|
||||||
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"
|
className="inline-flex items-center gap-1.5"
|
||||||
>
|
target="_blank"
|
||||||
Follow Development
|
rel="noopener noreferrer"
|
||||||
<span aria-hidden="true">→</span>
|
>
|
||||||
</a>
|
Follow Development
|
||||||
</div>
|
<span aria-hidden="true">→</span>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { useEffect, useMemo, useState } from 'react'
|
|||||||
import { useResponsiveCarousel } from '@/hooks/useResponsiveCarousel';
|
import { useResponsiveCarousel } from '@/hooks/useResponsiveCarousel';
|
||||||
import { motion, AnimatePresence } from 'framer-motion'
|
import { motion, AnimatePresence } from 'framer-motion'
|
||||||
import { wrap } from 'popmotion'
|
import { wrap } from 'popmotion'
|
||||||
import { Button } from '@/components/Button';
|
|
||||||
import { SectionHeader, P, Eyebrow, CP } from '@/components/Texts';
|
import { SectionHeader, P, Eyebrow, CP } from '@/components/Texts';
|
||||||
import { TypeAnimation } from 'react-type-animation'
|
import { TypeAnimation } from 'react-type-animation'
|
||||||
import { FadeIn } from '@/components/FadeIn';
|
import { FadeIn } from '@/components/FadeIn';
|
||||||
@@ -147,9 +146,8 @@ export function GallerySection() {
|
|||||||
repeat={0}
|
repeat={0}
|
||||||
/>
|
/>
|
||||||
</CP>
|
</CP>
|
||||||
<Button href="#" color="cyan" className="text-sm px-4 py-2 lg:text-base whitespace-nowrap">
|
{/* TODO: Desktop CTA (Start) button to be added when link target is defined.
|
||||||
Start
|
Previously: <Button href="#" color="cyan">Start</Button> */}
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -166,9 +164,8 @@ export function GallerySection() {
|
|||||||
repeat={0}
|
repeat={0}
|
||||||
/>
|
/>
|
||||||
</CP>
|
</CP>
|
||||||
<Button href="#" color="cyan" className="text-xs px-3 py-1.5 whitespace-nowrap">
|
{/* TODO: Mobile CTA (Start) button to be added when link target is defined.
|
||||||
Start
|
Previously: <Button href="#" color="cyan">Start</Button> */}
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</FadeIn>
|
</FadeIn>
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export default function AgentCoordination({
|
|||||||
aria-label="Agent coordination and sovereign workflow management"
|
aria-label="Agent coordination and sovereign workflow management"
|
||||||
style={{ background: bg }}
|
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 */}
|
{/* background */}
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export default function DeterministicExecution({
|
|||||||
aria-label="Deterministic deployment and verifiable code execution"
|
aria-label="Deterministic deployment and verifiable code execution"
|
||||||
style={{ background: bg }}
|
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 */}
|
{/* background grid */}
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default function FungiStor({
|
|||||||
aria-label="FungiStor, a distributed long-term AI memory"
|
aria-label="FungiStor, a distributed long-term AI memory"
|
||||||
style={{ background: bg }}
|
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 */}
|
{/* Background grid */}
|
||||||
<defs>
|
<defs>
|
||||||
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
|
<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"
|
aria-label="HeroDB, active AI memory retrieval"
|
||||||
style={{ background: bg }}
|
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 */}
|
{/* Background grid */}
|
||||||
<defs>
|
<defs>
|
||||||
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
|
<pattern id="grid-dark" width="28" height="28" patternUnits="userSpaceOnUse">
|
||||||
|
|||||||