diff --git a/.gitignore b/.gitignore index 3c3629e..ce50eae 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,83 @@ node_modules + +# Next.js build outputs and generated files +.next/ +next-env.d.ts + +# Environment variables +.env* + +# Logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ + +# nyc test coverage +.nyc_output + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt + +# Gatsby files +.cache/ +public + +# Storybook build outputs +.out +.storybook-out + +# Temporary folders +tmp/ +temp/ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Vercel +.vercel + +# Local Netlify folder +.netlify diff --git a/README.md b/README.md index 32268db..eded3e4 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,150 @@ -# Pocket +# Mycelium Network Website -Pocket is a [Tailwind Plus](https://tailwindcss.com/plus) site template built using [Tailwind CSS](https://tailwindcss.com) and [Next.js](https://nextjs.org). +- **Repository:** [https://git.ourworld.tf/ourworld_web/www_mycelium_net/](https://git.ourworld.tf/ourworld_web/www_mycelium_net/) -## Getting started +- **Main Branch (Production):** [https://network.mycelium.tf/](https://network.mycelium.tf/) +- **Dev Branch (Staging):** [https://www2.network.mycelium.tf/](https://www2.network.mycelium.tf/) -To get started with this template, first install the npm dependencies: -```bash -npm install -``` +--- -Next, run the development server: +## About -```bash -npm run dev -``` +This is the official website for Mycelium Network, built using Next.js and Tailwind CSS. -Finally, open [http://localhost:3000](http://localhost:3000) in your browser to view the website. +--- -## Customizing +## Technologies -You can start editing this template by modifying the files in the `/src` folder. The site will auto-update as you edit these files. +- **Framework**: [Next.js](https://nextjs.org/) +- **Language**: [TypeScript](https://www.typescriptlang.org/) +- **Styling**: [Tailwind CSS](https://tailwindcss.com/) -## License +--- -This site template is a commercial product and is licensed under the [Tailwind Plus license](https://tailwindcss.com/plus/license). +## Dependencies -## Learn more +- **UI**: [@headlessui/react](https://headlessui.com/) +- **Animation**: [framer-motion](https://www.framer.com/motion/) +- **Utilities**: [clsx](https://github.com/lukeed/clsx), [use-debounce](https://github.com/xnimorz/use-debounce) -To learn more about the technologies used in this site template, see the following resources: +--- -- [Tailwind CSS](https://tailwindcss.com/docs) - the official Tailwind CSS documentation -- [Next.js](https://nextjs.org/docs) - the official Next.js documentation -- [Headless UI](https://headlessui.dev) - the official Headless UI documentation +## File Structure + +- **Pages**: To edit the content of a specific page, navigate to `src/app/(main)/`. +- **Components**: Reusable components are located in `src/components/`. +- **Images**: Add or modify images in the `public/images/` directory. +- **CSS**: Global styles can be found in `src/styles/tailwind.css`. Most styling is done using Tailwind CSS utility classes directly in the `.tsx` files. + +--- + +## Branding + +- **Font**: The primary font used is [Inter](https://fonts.google.com/specimen/Inter). +- **Logos**: Project logos are stored in `public/images/`. + +--- + +## Get Started + +Follow these steps to get the project running locally: + +1. **Install Dependencies**: + + ```bash + npm install + ``` + +2. **Build the Project**: + + ```bash + npm run build + ``` + +3. **Start the Development Server**: + + ```bash + npm run start + ``` + +--- + +## Contributing + +- **Never update the `main` branch directly.** All changes must be reviewed and merged by the team through a pull request. +- **Always work on the `development` branch.** Create a feature branch from `development` and submit your pull request to `development`. +- **Request a review.** After submitting your pull request, ask the team to review and accept it into the `main` branch. + +--- + +## Report an Error + +To report an issue, please use the following link and provide the requested information: + +- **Issue Tracker**: [git.ourworld.tf/ourworld_web/HOME/issues/new](https://git.ourworld.tf/ourworld_web/HOME/issues/new) and tag **OW Website & Wiki Project 2025** + +- See the current web rpoject on [OW Website & Wiki Project 2025](https://git.ourworld.tf/ourworld_web/-/projects/153) + +When reporting an issue, please include: + +- **URL**: The page where the error occurred. +- **Repo**: The repository you are working with. +- **Branch**: The specific branch you are on. +- **Problem**: A detailed description of the problem. + +--- + +## Questions + +If you have any questions, you can reach out to [sashaastiadi](https://git.ourworld.tf/sashaastiadi). + +--- + +## Development Guide + +This project follows a modular, component-based architecture. Pages are assembled by combining reusable components into a single layout. + +### Homepage Structure + +The homepage (`src/app/(main)/page.tsx`) is composed of the following components: + +- `Hero` +- `About` +- `Features` +- `PrimaryFeatures` +- `SecondaryFeatures` +- `CallToAction` +- `Faqs` + +To edit a specific section of the homepage, navigate to `src/components/` and modify the corresponding component file. + +### Base Layout + +The main layout for the application is defined in `src/components/Layout.tsx`. This file includes the `Header` and `Footer` and wraps the primary content of each page. + +### Creating a New Page + +To create a new page, follow these steps: + +1. **Create a Folder**: Inside the `src/app/(main)/` directory, create a new folder with the desired URL slug for your page (e.g., `new-page`). + +2. **Create the Page File**: Inside the new folder, create a `page.tsx` file. + +3. **Add Page Content**: Compose your page by importing and using the reusable components from `src/components/`. For example: + + ```tsx + import { Hero } from '@/components/Hero' + import { Faqs } from '@/components/Faqs' + + export default function NewPage() { + return ( + <> + + + + ) + } + ``` + +The new page will be accessible at `http://localhost:3000/new-page`. diff --git a/connector.png b/connector.png new file mode 100644 index 0000000..1311e26 Binary files /dev/null and b/connector.png differ diff --git a/hooks/useScrollDirection.ts b/hooks/useScrollDirection.ts new file mode 100644 index 0000000..c360c5f --- /dev/null +++ b/hooks/useScrollDirection.ts @@ -0,0 +1,46 @@ +'use client'; + +import { useState, useEffect } from 'react'; + +export type ScrollDirection = 'up' | 'down'; + +/** + * A hook to detect the scroll direction. + * It uses requestAnimationFrame for performance, comparing the current scroll position + * with the previous one to determine if the user is scrolling up or down. + * + * @returns {ScrollDirection | null} The current scroll direction ('up' or 'down'), or null on the initial render. + */ +export function useScrollDirection(): ScrollDirection | null { + const [scrollDirection, setScrollDirection] = useState(null); + + useEffect(() => { + let lastScrollY = window.pageYOffset; + let ticking = false; + + const updateScrollDirection = () => { + const scrollY = window.pageYOffset; + + if (Math.abs(scrollY - lastScrollY) < 10) { + ticking = false; + return; + } + setScrollDirection(scrollY > lastScrollY ? 'down' : 'up'); + lastScrollY = scrollY > 0 ? scrollY : 0; + ticking = false; + }; + + const onScroll = () => { + if (!ticking) { + window.requestAnimationFrame(updateScrollDirection); + ticking = true; + } + }; + + window.addEventListener('scroll', onScroll); + + return () => window.removeEventListener('scroll', onScroll); + }, []); + + return scrollDirection; +} \ No newline at end of file diff --git a/next.config.js b/next.config.js index 767719f..1c89844 100644 --- a/next.config.js +++ b/next.config.js @@ -1,4 +1,9 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {} +const nextConfig = { + output: 'export', + images: { + unoptimized: true, + }, +} module.exports = nextConfig diff --git a/peers.png b/peers.png new file mode 100644 index 0000000..0066b57 Binary files /dev/null and b/peers.png differ diff --git a/setting.png b/setting.png new file mode 100644 index 0000000..be0b470 Binary files /dev/null and b/setting.png differ diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx deleted file mode 100644 index 013dbbd..0000000 --- a/src/app/(auth)/login/page.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { type Metadata } from 'next' -import Link from 'next/link' - -import { AuthLayout } from '@/components/AuthLayout' -import { Button } from '@/components/Button' -import { TextField } from '@/components/Fields' - -export const metadata: Metadata = { - title: 'Sign In', -} - -export default function Login() { - return ( - - Don’t have an account?{' '} - - Sign up - {' '} - for a free trial. - - } - > -
-
- - -
- -
-
- ) -} diff --git a/src/app/(auth)/register/page.tsx b/src/app/(auth)/register/page.tsx deleted file mode 100644 index 1434f9b..0000000 --- a/src/app/(auth)/register/page.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import { type Metadata } from 'next' -import Link from 'next/link' - -import { AuthLayout } from '@/components/AuthLayout' -import { Button } from '@/components/Button' -import { SelectField, TextField } from '@/components/Fields' - -export const metadata: Metadata = { - title: 'Sign Up', -} - -export default function Register() { - return ( - - Already registered?{' '} - - Sign in - {' '} - to your account. - - } - > -
-
- - - - - - - - - - -
- -
-
- ) -} diff --git a/src/app/(main)/download/page.tsx b/src/app/(main)/download/page.tsx new file mode 100644 index 0000000..ce61006 --- /dev/null +++ b/src/app/(main)/download/page.tsx @@ -0,0 +1,20 @@ +import { AnimatedSection } from '@/components/AnimatedSection' +import DownloadHero from '@/components/DownloadHero' +import { DevHub } from '@/components/DevHub' +import { Faqs } from '@/components/Faqs' + +export default function Download() { + return ( + <> + + + + + + + + + + + ) +} diff --git a/src/app/(main)/page.tsx b/src/app/(main)/page.tsx index b842a88..db00e55 100644 --- a/src/app/(main)/page.tsx +++ b/src/app/(main)/page.tsx @@ -1,21 +1,38 @@ +import { AnimatedSection } from '@/components/AnimatedSection' import { CallToAction } from '@/components/CallToAction' import { Faqs } from '@/components/Faqs' import { Hero } from '@/components/Hero' -import { Pricing } from '@/components/Pricing' import { PrimaryFeatures } from '@/components/PrimaryFeatures' -import { Reviews } from '@/components/Reviews' +import { UseCases } from '@/components/UseCases' import { SecondaryFeatures } from '@/components/SecondaryFeatures' +import { Benefits } from '@/components/Benefits' +import { About } from '@/components/About' +import { Features } from '@/components/Features' export default function Home() { return ( <> - - - - - - - + + + + + + + + + + + + + + + + + + + + + ) } diff --git a/src/app/favicon.ico b/src/app/favicon.ico index 88b1f7a..2c1a304 100644 Binary files a/src/app/favicon.ico and b/src/app/favicon.ico differ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 8aaba25..b06e386 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -12,11 +12,11 @@ const inter = Inter({ export const metadata: Metadata = { title: { - template: '%s - Pocket', - default: 'Pocket - Invest at the perfect time.', + template: '%s - Mycelium', + default: 'Mycelium - Unleash the Power of Decentralized Networks', }, description: - 'By leveraging insights from our network of industry insiders, you’ll know exactly when to buy to maximize profit, and exactly when to sell to avoid painful losses.', + 'Discover Mycelium, an end-to-end encrypted IPv6 overlay network. The future of secure, efficient, and scalable networking.', } export default function RootLayout({ diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 21704c6..357608e 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -9,7 +9,7 @@ export default function NotFound() {

404

-

+

Page not found

diff --git a/src/components/About.tsx b/src/components/About.tsx new file mode 100644 index 0000000..5f19f40 --- /dev/null +++ b/src/components/About.tsx @@ -0,0 +1,41 @@ +import { AppStoreLink } from '@/components/AppStoreLink' +import { Button } from '@/components/Button' +import { CircleBackground } from '@/components/CircleBackground' +import { Container } from '@/components/Container' + +export function About() { + return ( +

+
+ +
+ +
+

Our Mission

+

+ Discover Mycelium +

+

+ Mycelium is an unbreakable network, always finding the shortest path and providing 100% secure, peer-to-peer communication. But this is just the beginning. +

+

+ Our mission is to create a sustainable digital ecosystem where communication is seamless, data is secure, and scalability knows no bounds. +

+
+ +
+
+
+
+ ) +} diff --git a/src/components/AndroidLink.tsx b/src/components/AndroidLink.tsx new file mode 100644 index 0000000..eb1a12f --- /dev/null +++ b/src/components/AndroidLink.tsx @@ -0,0 +1,71 @@ +import Link from 'next/link' +import clsx from 'clsx' + +export function AndroidLink({ + color = 'black', +}: { + color?: 'black' | 'white' +}) { + return ( + + {/* Android SVG (converted for JSX) */} + + + {/* Text */} +
+ Download for + Android +
+ + ) +} diff --git a/src/components/AnimatedSection.tsx b/src/components/AnimatedSection.tsx new file mode 100644 index 0000000..ceb4684 --- /dev/null +++ b/src/components/AnimatedSection.tsx @@ -0,0 +1,23 @@ +'use client' + +import { useRef } from 'react' +import { motion, useInView } from 'framer-motion' + +export function AnimatedSection({ children }: { children: React.ReactNode }) { + const ref = useRef(null) + const isInView = useInView(ref, { once: true, margin: '-20% 0px -20% 0px' }) + + return ( + + {children} + + ) +} diff --git a/src/components/AppScreen.tsx b/src/components/AppScreen.tsx index 9f281a9..b2d1098 100644 --- a/src/components/AppScreen.tsx +++ b/src/components/AppScreen.tsx @@ -51,7 +51,7 @@ export function AppScreen({ }: React.ComponentPropsWithoutRef<'div'>) { return (
-
+
diff --git a/src/components/AppStoreLink.tsx b/src/components/AppStoreLink.tsx index a970540..24b4dc0 100644 --- a/src/components/AppStoreLink.tsx +++ b/src/components/AppStoreLink.tsx @@ -8,7 +8,7 @@ export function AppStoreLink({ }) { return ( +
+
+

+ Nature's Blueprint for Digital Connectivity +

+

+ Just as nature's mycelium network serves as a critical component in the ecosystems of forests, connecting trees and plants underground, the Mycelium technology offers reliable connectivity in an efficient and resilient way. +

+
+
    + {features.map((feature) => ( +
  • + {feature.name} +

    {feature.name}

    +

    {feature.description}

    +
  • + ))} +
+
+ + ) +} diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 27f88bf..99a630e 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -16,7 +16,8 @@ const variantStyles = { gray: 'bg-gray-800 text-white hover:bg-gray-900 active:bg-gray-800 active:text-white/80', }, outline: { - gray: 'border-gray-300 text-gray-700 hover:border-gray-400 active:bg-gray-100 active:text-gray-700/80', + gray: 'border-gray-300 text-gray-700 hover:text-gray-500 hover:border-gray-400 active:bg-gray-100 active:text-gray-700/80', + white: 'border-gray-300 text-white hover:text-gray-200 hover:border-gray-400 active:bg-gray-100 active:text-gray-700/80', }, } diff --git a/src/components/CallToAction.tsx b/src/components/CallToAction.tsx index 9a4f4ab..c8bc92b 100644 --- a/src/components/CallToAction.tsx +++ b/src/components/CallToAction.tsx @@ -1,4 +1,7 @@ import { AppStoreLink } from '@/components/AppStoreLink' +import { WindowsLink } from '@/components/WindowsLink' +import { AndroidLink } from './AndroidLink' +import { LinuxLink } from '@/components/LinuxLink' import { CircleBackground } from '@/components/CircleBackground' import { Container } from '@/components/Container' @@ -8,21 +11,22 @@ export function CallToAction() { id="get-free-shares-today" className="relative overflow-hidden bg-gray-900 py-20 sm:py-28" > -
+
-
-

- Get your first tips today +
+

+ Get Started Today

-

- It takes 30 seconds to sign up. Download the app and create an - account today and we’ll send you a tip guaranteed to double your - first investment. +

+ Download the Mycelium app and step into the future of secure, peer-to-peer networking; fast, private, and decentralized.

-
+
+ + +
diff --git a/src/components/Container.tsx b/src/components/Container.tsx index 7eb5c6f..9f5cfa5 100644 --- a/src/components/Container.tsx +++ b/src/components/Container.tsx @@ -6,7 +6,7 @@ export function Container({ }: React.ComponentPropsWithoutRef<'div'>) { return (
) diff --git a/src/components/ContentDistribution.tsx b/src/components/ContentDistribution.tsx new file mode 100644 index 0000000..af24c64 --- /dev/null +++ b/src/components/ContentDistribution.tsx @@ -0,0 +1,189 @@ +'use client'; + +import * as React from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; + +type Props = { + className?: string; // e.g. "w-full h-80" + bg?: string; // default white +}; + +/** Palette */ +const ACCENT = '#00b8db'; +const STROKE = '#111827'; +const GRAY = '#9CA3AF'; +const GRAY_LT = '#E5E7EB'; + +/* ---------- small generic icons (no brands) ---------- */ +const IconSquare = () => ( + +); +const IconTriangle = () => ( + +); +const IconHex = () => ( + +); +const IconBolt = () => ( + +); +const IconPlay = () => ( + +); +const IconDB = () => ( + <> + + + + +); + +/* icon inside white circular badge */ +function Badge({ children }: { children: React.ReactNode }) { + return ( + <> + + {children} + + + + + ); +} + +/* ---------- central cloud ---------- */ +function Cloud({ pulse = true }: { pulse?: boolean }) { + const prefersReduced = useReducedMotion(); + return ( + + + + + + + + {/* subtle accent aura */} + + + ); +} + +/* a small packet line from center to a node */ +function Beam({ + x2, + y2, + delay = 0, +}: { + x2: number; + y2: number; + delay?: number; +}) { + const prefersReduced = useReducedMotion(); + return ( + + ); +} + +export default function ContentDistribution({ className, bg = '#ffffff' }: Props) { + const W = 900; + const H = 560; + + // ring radii + const rings = [110, 190, 270]; + + // positions (angle degrees) for badges on rings + const layout = [ + { r: rings[1], a: -20, icon: }, + { r: rings[2], a: 20, icon: }, + { r: rings[0], a: 155, icon: }, + { r: rings[2], a: -145, icon: }, + { r: rings[1], a: 210, icon: }, + { r: rings[0], a: 60, icon: }, + ]; + + const prefersReduced = useReducedMotion(); + + return ( + + ); +} diff --git a/src/components/DevHub.tsx b/src/components/DevHub.tsx new file mode 100644 index 0000000..72eacfd --- /dev/null +++ b/src/components/DevHub.tsx @@ -0,0 +1,46 @@ +import { CheckIcon } from '@heroicons/react/20/solid' + +const features = [ + { + name: 'Documentation', + description: 'Documentation for Mycelium.', + }, + { name: 'Support', description: 'Talk to an expert.' }, + { + name: 'Forum', + description: 'Forum for all your questions.', + }, + { name: 'Community', description: 'Join our Developers community on telegram.' }, + +] + +export function DevHub() { + return ( +
+
+
+
+

Get Started

+

+ Developer Hub +

+

+ Our Developer Hub is a resource center for developers looking to build on top of Mycelium. Join our Developers community on telegram to get started. +

+
+
+ {features.map((feature) => ( +
+
+
+
{feature.description}
+
+ ))} +
+
+
+
+ ) +} diff --git a/src/components/DownloadHero.tsx b/src/components/DownloadHero.tsx new file mode 100644 index 0000000..197d44a --- /dev/null +++ b/src/components/DownloadHero.tsx @@ -0,0 +1,77 @@ +import Image from 'next/image'; +import appleIcon from '@/images/apple.svg'; +import windowsIcon from '@/images/windows.svg'; +import androidIcon from '@/images/android.svg'; +import linuxIcon from '@/images/linux.svg'; + +const features = [ + { + name: 'Download for iOS & MacOS', + description: 'Download Mycelium App from the Apple Store.', + href: 'https://apps.apple.com/us/app/mycelium-network/id6504277565', + icon: appleIcon, + }, + { + name: 'Download for Windows', + description: 'Download the Mycelium App for Windows directly from its Github repository.', + href: 'https://github.com/threefoldtech/myceliumflut/releases', + icon: windowsIcon, + }, + { + name: 'Download for Android', + description: 'Download Mycelium from the Google Play Store.', + href: 'https://play.google.com/store/apps/details?id=tech.threefold.mycelium&pli=1', + icon: androidIcon, + }, + { + name: 'Download for Linux', + description: 'Download the Mycelium binary for Linux directly from its Github repository.', + href: 'https://github.com/threefoldtech/mycelium/releases/tag/v0.6.1', + icon: linuxIcon, + }, +]; + +export default function DownloadHero() { + return ( +
+
+
+

+ Download Mycelium +

+

+ Get Mycelium for Android, Windows, macOS, and iOS to securely connect, store, and interact with the decentralized network—seamlessly and efficiently. Not sure how it works?{' '} + + Read the manual. + +

+
+
+
+ {features.map((feature) => ( +
+
+
+ +
+ {feature.name} +
+
+

{feature.description}

+

+ + Download Now + +

+
+
+ ))} +
+
+
+
+ ); +} diff --git a/src/components/DownloadLink.tsx b/src/components/DownloadLink.tsx new file mode 100644 index 0000000..ebaa618 --- /dev/null +++ b/src/components/DownloadLink.tsx @@ -0,0 +1,17 @@ +import Link from 'next/link' +import { ArrowDownTrayIcon } from '@heroicons/react/24/solid' + +export function DownloadLink() { + return ( + + + Get Mycelium + + ) +} diff --git a/src/components/Faqs.tsx b/src/components/Faqs.tsx index d76acee..5147309 100644 --- a/src/components/Faqs.tsx +++ b/src/components/Faqs.tsx @@ -3,53 +3,48 @@ import { Container } from '@/components/Container' const faqs = [ [ { - question: 'How do I know the tips are good?', + question: 'What is Mycelium?', answer: - 'Our whole business depends on our tips being good, so it’s in our best interest that they are. The results of our customers speak for themselves, just trust us.', + 'Mycelium is an end-to-end encrypted IPv6 overlay network written in Rust. Each node joining the network receives an IP in the 400::/7 range, facilitating secure and private communications.', }, { - question: 'Isn’t this insider trading?', + question: 'Is mycelium ready to scale to the world?', answer: - 'Yes exactly. But at scale! Historically you could only make insider trades with knowledge from your direct network. Pocket brings you insider trading tips from people you don’t even know.', + 'No, Mycelium is not yet fully scalable to a global level. Currently, each network can support around 100,000 users, but multiple networks can be deployed to expand capacity. We anticipate resolving these scalability challenges by 2025.', }, { - question: 'But isn’t insider trading illegal?', + question: 'How do I install Mycelium?', answer: - 'Here’s the thing: you’re the one doing the insider trading, not us. We’re just giving you the tips and some tools to make trades. We’re not doing anything wrong here.', + 'The Mycelium app supports iOS, macOS, Android and Windows. For Linux, a binary is available. Installation guides are available for both local machines and virtual machines running on the TFGrid. Note that Windows users need to have wintun.dll in the same directory as the Mycelium executable.', }, ], [ { - question: 'Do the people giving you tips realize what they are doing?', + question: 'How can I find and use my Mycelium address?', answer: - 'Again I would argue this isn’t really our responsibility. People make their own choices. If they don’t research the consequences that’s on them, not on us.', + 'Upon using the Mycelium app, you\'re assigned a unique Mycelium address. To copy this address, click the button located to the right of the displayed address in the app interface.', }, { - question: 'Where is Pocket based?', + question: 'Can I deploy workloads on the TFGrid using Mycelium?', answer: - 'Let’s just say it’s not somewhere where the SEC is going to find us.', + 'Yes, after installing Mycelium, you can deploy workloads on the TFGrid and connect to them using the Mycelium network. Detailed deployment guides are available in the documentation.', }, { - question: 'Is there any age limit to trading on Pocket?', + question: 'Is there an API available for Mycelium?', answer: - 'For our free plan, the age limit is based on the minimum age to trade in your country of residence. Our VIP plan uses advanced transaction anonymization though, so you can use that plan even if you’re 9 years old. Or a dog.', + 'Yes, Mycelium offers an API for administrative operations, peer management, and message subsystem operations. Comprehensive API documentation can be found in the official Mycelium GitHub repository.', }, ], [ { - question: 'How did you get this on the App Store?', + question: 'What should I do if I encounter issues during installation or usage?', answer: - 'Honestly we were surprised too, but eventually we found out that the app reviewer found the app so compelling they approved it just so they could use it themselves.', + 'If you face any challenges, refer to the troubleshooting section in the Mycelium documentation. Additionally, ensure that all prerequisites are met, such as having wintun.dll in the correct directory for Windows installations.', }, { - question: 'How do I explain the money I withdraw from Pocket to the IRS?', + question: 'How does Mycelium handle routing within its network?', answer: - 'This feels like one-hundred percent a you problem. Pocket is not responsible in any way for your tax returns.', - }, - { - question: 'How do I become an insider?', - answer: - 'Contact us with some details about your industry and the type of access you have to apply for an insider account. Once approved, we’ll send you a guide on collecting insider information without being detected at work.', + 'Mycelium incorporates core principles of the Babel routing protocol, enabling efficient and dynamic routing within its encrypted IPv6 overlay network.', }, ], ] @@ -65,7 +60,7 @@ export function Faqs() {

Frequently asked questions

diff --git a/src/components/Features.tsx b/src/components/Features.tsx new file mode 100644 index 0000000..5c2702b --- /dev/null +++ b/src/components/Features.tsx @@ -0,0 +1,111 @@ +import Pathfinding from '@/components/Pathfinding' +import MessageBus from '@/components/MessageBus' +import ProxyDetection from '@/components/ProxyDetection' +import ProxyForwarding from '@/components/ProxyForwarding' +import ContentDistribution from '@/components/ContentDistribution' + +export function Features() { + return ( +
+
+

Core Components

+

+ Network Capabilities +

+

+ Built for resilience and autonomy, the Mycelium Network dynamically connects nodes through intelligent routing, proxy discovery, and decentralized delivery. +

+

+Each component — from message passing to content distribution — works in harmony to create a fully self-healing, self-optimizing data mesh. +

+
+
+
+
+ +
+

Routing

+

+ Automatic pathfinding +

+

+ The Mycelium Network automatically discovers the shortest and fastest routes between nodes, + ensuring optimal data flow and network efficiency without manual configuration. +

+
+
+
+
+
+
+
+ +
+

Communication

+

+ Distributed message bus +

+

+ Acts as a global message layer that lets nodes exchange information seamlessly. + Enables resilient, asynchronous communication across the entire decentralized mesh. +

+
+
+
+
+
+
+
+ +
+

Discovery

+

+ Automatic proxy detection +

+

+ The system continuously scans for open SOCKS5 proxies within the network, + making it effortless to find available connection points without manual setup. +

+
+
+
+
+
+
+
+ +
+

Connectivity

+

+ Seamless proxy forwarding +

+

+ Local SOCKS5 connections can be forwarded through nearby nodes or remote proxies. + When browsers use the local proxy, traffic moves securely through the mesh—like a built-in VPN. +

+
+
+
+
+
+
+
+ +
+

Delivery

+

+ Decentralized content distribution +

+

+ Mycelium can serve data from distributed 0-DBs, creating a CDN-like layer that delivers + content faster and more reliably—without relying on centralized servers. +

+
+
+
+
+
+
+
+ ) +} diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 439307e..9ee891d 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -4,33 +4,20 @@ import Link from 'next/link' import { Button } from '@/components/Button' import { Container } from '@/components/Container' import { TextField } from '@/components/Fields' -import { Logomark } from '@/components/Logo' import { NavLinks } from '@/components/NavLinks' -import qrCode from '@/images/qr-code.svg' - -function QrCodeBorder(props: React.ComponentPropsWithoutRef<'svg'>) { - return ( - - ) -} +import github from '@/images/github.svg' export function Footer() { return (
-
+
- + Mycelium Logomark
-

Pocket

-

Invest at the perfect time.

+

Mycelium

+

Unleash the Power of Decentralized Networks

-
- - +
+ GitHub
-
+

- + - Download the app + Download Mycelium

- Scan the QR code to download the app from the App Store. + Head to the GitHub to access the latest Mycelium builds for your devices.

@@ -71,7 +57,7 @@ export function Footer() {

- © Copyright {new Date().getFullYear()}. All rights reserved. + © Copyright ThreeFold {new Date().getFullYear()}. All rights reserved.

diff --git a/src/components/Header.tsx b/src/components/Header.tsx index a89b0cc..350cd9d 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -107,23 +107,11 @@ export function Header() { }} className="absolute inset-x-0 top-0 z-0 origin-top rounded-b-2xl bg-gray-50 px-6 pt-32 pb-6 shadow-2xl shadow-gray-900/20" > -
- - Features - - - Reviews - - - Pricing - - FAQs -
-
- - +
@@ -133,10 +121,10 @@ export function Header() { )}
- - +
diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx index 50e9514..66de473 100644 --- a/src/components/Hero.tsx +++ b/src/components/Hero.tsx @@ -2,11 +2,9 @@ import { useId } from 'react' import Image from 'next/image' import clsx from 'clsx' -import { AppDemo } from '@/components/AppDemo' -import { AppStoreLink } from '@/components/AppStoreLink' +import { DownloadLink } from '@/components/DownloadLink' import { Button } from '@/components/Button' import { Container } from '@/components/Container' -import { PhoneFrame } from '@/components/PhoneFrame' import logoBbc from '@/images/logos/bbc.svg' import logoCbs from '@/images/logos/cbs.svg' import logoCnn from '@/images/logos/cnn.svg' @@ -100,38 +98,47 @@ function PlayIcon(props: React.ComponentPropsWithoutRef<'svg'>) { export function Hero() { return ( -
+
-
+
-

- Invest at the perfect time. +

+ Mycelium

-

- By leveraging insights from our network of industry insiders, - you’ll know exactly when to buy to maximize profit, and exactly - when to sell to avoid painful losses. +

+ Unleashing the Power of Decentralized Networks +

+

+ Discover Mycelium, an end-to-end encrypted IPv6 overlay network. The future of secure, efficient, and scalable networking. +

+

+ Coming Soon: New Decentralized Features

- +
-
- -
- - - +
+ +
+ Mycelium application demo
-
+ {/*

As featured in

@@ -154,7 +161,7 @@ export function Hero() { ))} -
+
*/}
diff --git a/src/components/LinuxLink.tsx b/src/components/LinuxLink.tsx new file mode 100644 index 0000000..1e0f251 --- /dev/null +++ b/src/components/LinuxLink.tsx @@ -0,0 +1,36 @@ +import Link from 'next/link' +import clsx from 'clsx' + +export function LinuxLink({ + color = 'black', +}: { + color?: 'black' | 'white' +}) { + return ( + + {/* Linux SVG */} + + + {/* Text */} +
+ Download for + Linux +
+ + ) +} diff --git a/src/components/Logo.tsx b/src/components/Logo.tsx index 8267549..b1255ff 100644 --- a/src/components/Logo.tsx +++ b/src/components/Logo.tsx @@ -1,23 +1,110 @@ export function Logomark(props: React.ComponentPropsWithoutRef<'svg'>) { return ( - + + + + + + + + + + + + + + + + + + + + + + + ) } export function Logo(props: React.ComponentPropsWithoutRef<'svg'>) { return ( - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) } diff --git a/src/components/MessageBus.tsx b/src/components/MessageBus.tsx new file mode 100644 index 0000000..b63c4ba --- /dev/null +++ b/src/components/MessageBus.tsx @@ -0,0 +1,150 @@ +'use client'; + +import * as React from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; + +type Props = { + className?: string; // e.g. "w-full h-72" + bg?: string; // default white +}; + +/** Palette (gray/black + accent only) */ +const ACCENT = '#00b8db'; +const STROKE = '#111827'; // black-ish +const GRAY = '#9CA3AF'; +const GRAY_LT = '#E5E7EB'; + +function Envelope({ + x, y, w = 88, h = 56, fill = GRAY_LT, accent = false, delay = 0, duration = 1.6, + path = 'none', // 'left1' | 'left2' | 'rightTop' | 'rightBottom' | 'none' + reverse = false, +}: { + x: number; y: number; w?: number; h?: number; fill?: string; accent?: boolean; + delay?: number; duration?: number; path?: 'left1'|'left2'|'rightTop'|'rightBottom'|'none'; reverse?: boolean; +}) { + const prefersReduced = useReducedMotion(); + + // simple keyframe paths (straight line segments) + const paths: Record = { + left1: { x: [x, 380], y: [y, 220] }, + left2: { x: [x, 380], y: [y, 220] }, + rightTop: { x: [380, 720], y: [220, 150] }, + rightBottom: { x: [380, 720], y: [220, 290] }, + none: { x: [x], y: [y] }, + }; + + const k = paths[path]; + + return ( + + {/* envelope body */} + + {/* flap */} + + + ); +} + +export default function MessageBus({ className, bg = '#ffffff' }: Props) { + const W = 900; + const H = 460; + + return ( + + ); +} diff --git a/src/components/NavLinks.tsx b/src/components/NavLinks.tsx index ea08e3b..d4c9f76 100644 --- a/src/components/NavLinks.tsx +++ b/src/components/NavLinks.tsx @@ -9,9 +9,10 @@ export function NavLinks() { let timeoutRef = useRef(null) return [ + ['About', '/#about'], ['Features', '/#features'], - ['Reviews', '/#reviews'], - ['Pricing', '/#pricing'], + ['How it Works', '/#howitworks'], + ['Coming Soon', '/#comingsoon'], ['FAQs', '/#faqs'], ].map(([label, href], index) => ( { timeoutRef.current = window.setTimeout(() => { setHoveredIndex(null) - }, 200) + }, 50) + }} + onClick={(e) => { + e.preventDefault() + const targetId = href.substring(2) + const targetElement = document.getElementById(targetId) + if (targetElement) { + targetElement.scrollIntoView({ behavior: 'smooth' }) + } }} > diff --git a/src/components/Pathfinding.tsx b/src/components/Pathfinding.tsx new file mode 100644 index 0000000..718c240 --- /dev/null +++ b/src/components/Pathfinding.tsx @@ -0,0 +1,233 @@ +// pathfinding.tsx +// Animated SVG illustrating "Automatic pathfinding" +// - Central hub + surrounding nodes +// - Arrows fade/slide in +// - Shortest path highlights on loop +// - Respects prefers-reduced-motion +'use client'; + +import * as React from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; +import clsx from 'clsx'; + + +type Props = { + className?: string; // e.g. "w-full h-64" + accent?: string; // main accent color + stroke?: string; // neutral stroke color + bg?: string; // background color +}; + +const Node = ({ + cx, + cy, + r = 16, + fill = "#00b8db", + ring = "#E5E7EB", + pulse = false, + rMotion = 2, +}: { + cx: number; + cy: number; + r?: number; + fill?: string; + ring?: string; + pulse?: boolean; + rMotion?: number; +}) => { + const prefersReduced = useReducedMotion(); + + return ( + <> + {/* outer ring */} + + {/* core node */} + + + ); +}; + +const Arrow = ({ + d, + color = "#111827", + delay = 0, +}: { + d: string; + color?: string; + delay?: number; +}) => ( + +); + +const DashedPath = ({ + d, + color = "#9CA3AF", + dash = 6, + delay = 0, + loop = false, +}: { + d: string; + color?: string; + dash?: number; + delay?: number; + loop?: boolean; +}) => { + const prefersReduced = useReducedMotion(); + + return ( + + ); +}; + +export default function Pathfinding({ + className, + accent = "#00b8db", // indigo-800 vibe + stroke = "#111827", // gray-900 + bg = "#FFFFFF", +}: Props) { + // Canvas + const W = 760; + const H = 420; + + // Layout (simple radial) + const center = { x: 380, y: 210 }; + const nodes = [ + { x: 130, y: 210 }, // left + { x: 670, y: 210 }, // right + { x: 380, y: 70 }, // top + { x: 280, y: 340 }, // bottom-left + { x: 500, y: 340 }, // bottom-right + ]; + + // Helper to make arrow path with a small head + const arrowTo = (from: { x: number; y: number }, to: { x: number; y: number }) => { + const dx = to.x - from.x; + const dy = to.y - from.y; + const len = Math.hypot(dx, dy); + const ux = dx / len; + const uy = dy / len; + const end = { x: to.x - ux * 18, y: to.y - uy * 18 }; // inset a bit + const headL = { + x: end.x - uy * 8 - ux * 6, + y: end.y + ux * 8 - uy * 6, + }; + const headR = { + x: end.x + uy * 8 - ux * 6, + y: end.y - ux * 8 - uy * 6, + }; + return `M ${from.x} ${from.y} L ${end.x} ${end.y} M ${headL.x} ${headL.y} L ${end.x} ${end.y} L ${headR.x} ${headR.y}`; + }; + + // "Shortest" highlighted route: left -> center -> bottom-right + const highlightA = `M ${nodes[0].x} ${nodes[0].y} L ${center.x} ${center.y}`; + const highlightB = `M ${center.x} ${center.y} L ${nodes[4].x} ${nodes[4].y}`; + + // Faint alternative routes + const alt1 = `M ${nodes[2].x} ${nodes[2].y} L ${center.x} ${center.y}`; + const alt2 = `M ${nodes[3].x} ${nodes[3].y} L ${center.x} ${center.y}`; + const alt3 = `M ${center.x} ${center.y} L ${nodes[1].x} ${nodes[1].y}`; + + return ( + + ); +} diff --git a/src/components/PhoneFrame.tsx b/src/components/PhoneFrame.tsx index 6ca4cb5..2e5096b 100644 --- a/src/components/PhoneFrame.tsx +++ b/src/components/PhoneFrame.tsx @@ -1,22 +1,6 @@ import Image from 'next/image' import clsx from 'clsx' -import frame from '@/images/phone-frame.svg' - -function PlaceholderFrame(props: React.ComponentPropsWithoutRef<'svg'>) { - return ( - - ) -} - export function PhoneFrame({ className, children, @@ -24,19 +8,17 @@ export function PhoneFrame({ ...props }: React.ComponentPropsWithoutRef<'div'> & { priority?: boolean }) { return ( -
-
-
- {children} -
- +
+
+ {children} +
) } diff --git a/src/components/Pricing.tsx b/src/components/Pricing.tsx index 70015cb..c2952d5 100644 --- a/src/components/Pricing.tsx +++ b/src/components/Pricing.tsx @@ -132,7 +132,7 @@ function Plan({

@@ -221,7 +221,7 @@ export function Pricing() {

Flat pricing, no management fees.

diff --git a/src/components/PrimaryFeatures.tsx b/src/components/PrimaryFeatures.tsx index c4b2f7b..1b4bbc1 100644 --- a/src/components/PrimaryFeatures.tsx +++ b/src/components/PrimaryFeatures.tsx @@ -15,6 +15,7 @@ import { useDebouncedCallback } from 'use-debounce' import { AppScreen } from '@/components/AppScreen' import { CircleBackground } from '@/components/CircleBackground' import { Container } from '@/components/Container' +import Image from 'next/image' import { PhoneFrame } from '@/components/PhoneFrame' import { DiageoLogo, @@ -37,23 +38,23 @@ interface CustomAnimationProps { const features = [ { - name: 'Invite friends for better returns', + name: 'Mycelium Connector', description: - 'For every friend you invite to Pocket, you get insider notifications 5 seconds sooner. And it’s 10 seconds if you invite an insider.', + "Start (and stop) your Mycelium connector to gain access to sites, apps, and workloads available exclusively on the Mycelium Network. View statistics around peers and traffic.", icon: DeviceUserIcon, screen: InviteScreen, }, { - name: 'Notifications on stock dips', + name: 'Mycelium Peers', description: - 'Get a push notification every time we find out something that’s going to lower the share price on your holdings so you can sell before the information hits the public markets.', + 'Search and discover active peers on the Mycelium Network, or add your own.', icon: DeviceNotificationIcon, screen: StocksScreen, }, { - name: 'Invest what you want', + name: 'Network Setting', description: - 'We hide your stock purchases behind thousands of anonymous trading accounts, so suspicious activity can never be traced back to you.', + 'Find version and network information and trigger light or dark mode.', icon: DeviceTouchIcon, screen: InvestScreen, }, @@ -193,35 +194,7 @@ type ScreenProps = function InviteScreen(props: ScreenProps) { return ( - - Invite people - - Get tips 5s sooner for every - invite. - - - -
-
- {[ - { label: 'Full name', value: 'Albert H. Wiggin' }, - { label: 'Email address', value: 'awiggin@chase.com' }, - ].map((field) => ( -
-
{field.label}
-
- {field.value} -
-
- ))} -
-
- Invite person -
-
-
+ Mycelium Connector
) } @@ -229,101 +202,7 @@ function InviteScreen(props: ScreenProps) { function StocksScreen(props: ScreenProps) { return ( - - Stocks - March 9, 2022 - - -
- {[ - { - name: 'Laravel', - price: '4,098.01', - change: '+4.98%', - color: '#F9322C', - logo: LaravelLogo, - }, - { - name: 'Tuple', - price: '5,451.10', - change: '-3.38%', - color: '#5A67D8', - logo: TupleLogo, - }, - { - name: 'Transistor', - price: '4,098.41', - change: '+6.25%', - color: '#2A5B94', - logo: TransistorLogo, - }, - { - name: 'Diageo', - price: '250.65', - change: '+1.25%', - color: '#3320A7', - logo: DiageoLogo, - }, - { - name: 'StaticKit', - price: '250.65', - change: '-3.38%', - color: '#2A3034', - logo: StaticKitLogo, - }, - { - name: 'Statamic', - price: '5,040.85', - change: '-3.11%', - color: '#0EA5E9', - logo: StatamicLogo, - }, - { - name: 'Mirage', - price: '140.44', - change: '+9.09%', - color: '#16A34A', - logo: MirageLogo, - }, - { - name: 'Reversable', - price: '550.60', - change: '-1.25%', - color: '#8D8D8D', - logo: ReversableLogo, - }, - ].map((stock) => ( -
-
- -
-
- {stock.name} -
-
-
- {stock.price} -
-
- {stock.change} -
-
-
- ))} -
-
+ Mycelium Peers
) } @@ -331,54 +210,7 @@ function StocksScreen(props: ScreenProps) { function InvestScreen(props: ScreenProps) { return ( - - Buy $LA - - $34.28 per share - - - -
-
- {[ - { label: 'Number of shares', value: '100' }, - { - label: 'Current market price', - value: ( -
- $34.28 - - - -
- ), - }, - { label: 'Estimated cost', value: '$3,428.00' }, - ].map((item) => ( -
-
{item.label}
-
- {item.value} -
-
- ))} -
- Buy shares -
-
-
-
+ Mycelium Settings
) } @@ -410,7 +242,7 @@ function FeaturesDesktop() { return ( (
{featureIndex === selectedIndex && ( ref && (slideRefs.current[featureIndex] = ref)} - className="w-full flex-none snap-center px-4 sm:px-6" + className="w-full flex-none snap-center px-4 sm:px-6 transition-all duration-300 ease-in-out hover:scale-105" >
@@ -570,20 +402,18 @@ function FeaturesMobile() { export function PrimaryFeatures() { return (
-

- Every feature you need to win. Try it for yourself. -

-

- Pocket was built for investors like you who play by their own rules - and aren’t going to let SEC regulations get in the way of their - dreams. If other investing tools are afraid to build it, Pocket has - it. +

How It Works

+

+ How Mycelium Operates +

+

+ Mycelium, like its natural namesake, thrives on decentralization, efficiency, and security, making it a truly powerful force in the world of decentralized networks.

diff --git a/src/components/ProxyDetection.tsx b/src/components/ProxyDetection.tsx new file mode 100644 index 0000000..6ddaeb7 --- /dev/null +++ b/src/components/ProxyDetection.tsx @@ -0,0 +1,194 @@ +'use client'; + +import * as React from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; + +type Props = { + className?: string; // e.g. "w-full h-64" + bg?: string; // defaults to white +}; + +// Palette (only these) +const ACCENT = '#00b8db'; +const STROKE = '#111827'; +const GRAY = '#9CA3AF'; +const GRAY_LT = '#E5E7EB'; + +function Magnifier({ + x = 0, + y = 0, + flip = false, + delay = 0, + duration = 3, +}: { + x?: number; + y?: number; + flip?: boolean; // rotate handle direction + delay?: number; + duration?: number; +}) { + const prefersReduced = useReducedMotion(); + + return ( + + {/* glass */} + + {/* subtle scanning pulse inside the glass */} + + {/* handle */} + + + + + + ); +} + +function ServerBox({ + x, + y, + w = 88, + h = 50, + delay = 0, + accentPulse = false, +}: { + x: number; + y: number; + w?: number; + h?: number; + delay?: number; + accentPulse?: boolean; +}) { + const prefersReduced = useReducedMotion(); + + return ( + + {/* outer box */} + + {/* top bar */} + + {/* activity line */} + + {/* “detected” indicator */} + + + ); +} + +export default function ProxyDetection({ className, bg = '#ffffff' }: Props) { + // Canvas + const W = 900; + const H = 180; + + // Layout: a row of proxy servers + const rowY = H / 2; + const xs = [180, 320, 460, 600, 740]; + + // Sequence timings so boxes light up as magnifier passes + const delays = [0.8, 0.6, 0.4, 0.2, 0.0]; + + return ( + + ); +} diff --git a/src/components/ProxyForwarding.tsx b/src/components/ProxyForwarding.tsx new file mode 100644 index 0000000..a76517e --- /dev/null +++ b/src/components/ProxyForwarding.tsx @@ -0,0 +1,175 @@ +'use client'; + +import * as React from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; + +type Props = { + className?: string; // e.g. "w-full h-72" + bg?: string; // default white +}; + +/** Palette */ +const ACCENT = '#00b8db'; +const STROKE = '#111827'; // black-ish +const GRAY = '#9CA3AF'; +const GRAY_LT = '#E5E7EB'; + +function Laptop({ x, y }: { x: number; y: number }) { + return ( + + {/* screen */} + + + {/* base */} + + + ); +} + +function ServerStack({ x, y }: { x: number; y: number }) { + return ( + + {[0, 1, 2].map((i) => ( + + + + + + + + ))} + {/* tiny rack base */} + + + + ); +} + +function Cloud({ x, y }: { x: number; y: number }) { + return ( + + + + + + + + ); +} + +function Arrow({ d, delay = 0 }: { d: string; delay?: number }) { + return ( + + ); +} + +/** Small packet traveling along keyframe x/y arrays */ +function Packet({ + xs, + ys, + delay = 0, + color = ACCENT, + duration = 2.2, +}: { + xs: number[]; + ys: number[]; + delay?: number; + color?: string; + duration?: number; +}) { + const prefersReduced = useReducedMotion(); + return ( + + ); +} + +export default function ProxyForwarding({ className, bg = '#ffffff' }: Props) { + const W = 1000; + const H = 420; + + // Key points + const C1 = { x: 140, y: 90 }; + const C2 = { x: 140, y: 210 }; + const C3 = { x: 140, y: 330 }; + + const PROXY = { x: 420, y: 210 }; + const CLOUD = { x: 640, y: 210 }; + const DEST = { x: 860, y: 210 }; + + return ( + + ); +} diff --git a/src/components/Reviews.tsx b/src/components/Reviews.tsx deleted file mode 100644 index 2e0bb02..0000000 --- a/src/components/Reviews.tsx +++ /dev/null @@ -1,294 +0,0 @@ -'use client' - -import { useEffect, useMemo, useRef, useState } from 'react' -import clsx from 'clsx' -import { useInView } from 'framer-motion' - -import { Container } from '@/components/Container' - -interface Review { - title: string - body: string - author: string - rating: 1 | 2 | 3 | 4 | 5 -} - -const reviews: Array = [ - { - title: 'It really works.', - body: 'I downloaded Pocket today and turned $5000 into $25,000 in half an hour.', - author: 'CrazyInvestor', - rating: 5, - }, - { - title: 'You need this app.', - body: 'I didn’t understand the stock market at all before Pocket. I still don’t, but at least I’m rich now.', - author: 'CluelessButRich', - rating: 5, - }, - { - title: 'This shouldn’t be legal.', - body: 'Pocket makes it so easy to win big in the stock market that I can’t believe it’s actually legal.', - author: 'LivingDaDream', - rating: 5, - }, - { - title: 'Screw financial advisors.', - body: 'I barely made any money investing in mutual funds. With Pocket, I’m doubling my net-worth every single month.', - author: 'JordanBelfort1962', - rating: 5, - }, - { - title: 'I love it!', - body: 'I started providing insider information myself and now I get new insider tips every 5 minutes. I don’t even have time to act on all of them. New Lamborghini is being delivered next week!', - author: 'MrBurns', - rating: 5, - }, - { - title: 'Too good to be true.', - body: 'I was making money so fast with Pocket that it felt like a scam. But I sold my shares and withdrew the money and it’s really there, right in my bank account. This app is crazy!', - author: 'LazyRich99', - rating: 5, - }, - { - title: 'Wish I could give 6 stars', - body: 'This is literally the most important app you will ever download in your life. Get on this before it’s so popular that everyone else is getting these tips too.', - author: 'SarahLuvzCash', - rating: 5, - }, - { - title: 'Bought an island.', - body: 'Yeah, you read that right. Want your own island too? Get Pocket.', - author: 'ScroogeMcduck', - rating: 5, - }, - { - title: 'No more debt!', - body: 'After 2 weeks of trading on Pocket I was debt-free. Why did I even go to school at all when Pocket exists?', - author: 'BruceWayne', - rating: 5, - }, - { - title: 'I’m 13 and I’m rich.', - body: 'I love that with Pocket’s transaction anonymization I could sign up and start trading when I was 12 years old. I had a million dollars before I had armpit hair!', - author: 'RichieRich', - rating: 5, - }, - { - title: 'Started an investment firm.', - body: 'I charge clients a 3% management fee and just throw all their investments into Pocket. Easy money!', - author: 'TheCountOfMonteChristo', - rating: 5, - }, - { - title: 'It’s like a superpower.', - body: 'Every tip Pocket has sent me has paid off. It’s like playing Blackjack but knowing exactly what card is coming next!', - author: 'ClarkKent', - rating: 5, - }, - { - title: 'Quit my job.', - body: 'I downloaded Pocket three days ago and quit my job today. I can’t believe no one else thought to build a stock trading app that works this way!', - author: 'GeorgeCostanza', - rating: 5, - }, - { - title: 'Don’t download this app', - body: 'Unless you want to have the best life ever! I am literally writing this from a yacht.', - author: 'JeffBezos', - rating: 5, - }, -] - -function StarIcon(props: React.ComponentPropsWithoutRef<'svg'>) { - return ( - - ) -} - -function StarRating({ rating }: { rating: Review['rating'] }) { - return ( -
- {[...Array(5).keys()].map((index) => ( - index ? 'fill-cyan-500' : 'fill-gray-300', - )} - /> - ))} -
- ) -} - -function Review({ - title, - body, - author, - rating, - className, - ...props -}: Omit, keyof Review> & Review) { - let animationDelay = useMemo(() => { - let possibleAnimationDelays = ['0s', '0.1s', '0.2s', '0.3s', '0.4s', '0.5s'] - return possibleAnimationDelays[ - Math.floor(Math.random() * possibleAnimationDelays.length) - ] - }, []) - - return ( -
-
- -

- {title} -

-

{body}

-
-
- {author} -
-
- ) -} - -function splitArray(array: Array, numParts: number) { - let result: Array> = [] - for (let i = 0; i < array.length; i++) { - let index = i % numParts - if (!result[index]) { - result[index] = [] - } - result[index].push(array[i]) - } - return result -} - -function ReviewColumn({ - reviews, - className, - reviewClassName, - msPerPixel = 0, -}: { - reviews: Array - className?: string - reviewClassName?: (reviewIndex: number) => string - msPerPixel?: number -}) { - let columnRef = useRef>(null) - let [columnHeight, setColumnHeight] = useState(0) - let duration = `${columnHeight * msPerPixel}ms` - - useEffect(() => { - if (!columnRef.current) { - return - } - - let resizeObserver = new window.ResizeObserver(() => { - setColumnHeight(columnRef.current?.offsetHeight ?? 0) - }) - - resizeObserver.observe(columnRef.current) - - return () => { - resizeObserver.disconnect() - } - }, []) - - return ( -
- {reviews.concat(reviews).map((review, reviewIndex) => ( - = reviews.length} - className={reviewClassName?.(reviewIndex % reviews.length)} - {...review} - /> - ))} -
- ) -} - -function ReviewGrid() { - let containerRef = useRef>(null) - let isInView = useInView(containerRef, { once: true, amount: 0.4 }) - let columns = splitArray(reviews, 3) - let column1 = columns[0] - let column2 = columns[1] - let column3 = splitArray(columns[2], 2) - - return ( -
- {isInView && ( - <> - - clsx( - reviewIndex >= column1.length + column3[0].length && - 'md:hidden', - reviewIndex >= column1.length && 'lg:hidden', - ) - } - msPerPixel={10} - /> - - reviewIndex >= column2.length ? 'lg:hidden' : '' - } - msPerPixel={15} - /> - - - )} -
-
-
- ) -} - -export function Reviews() { - return ( -
- -

- Everyone is changing their life with Pocket. -

-

- Thousands of people have doubled their net-worth in the last 30 days. -

- -
-
- ) -} diff --git a/src/components/SecondaryFeatures.tsx b/src/components/SecondaryFeatures.tsx index bae7900..9c8a400 100644 --- a/src/components/SecondaryFeatures.tsx +++ b/src/components/SecondaryFeatures.tsx @@ -4,39 +4,39 @@ import { Container } from '@/components/Container' const features = [ { - name: 'Invest any amount', + name: 'Quantum Safe Storage Functionality', description: - 'Whether it’s $1 or $1,000,000, we can put your money to work for you.', + "Mycelium's quantum safe storage enables flexible, scalable, and efficient data distribution across a decentralized network, ensuring redundancy and security.", icon: DeviceArrowIcon, }, { - name: 'Build a balanced portfolio', + name: 'Entry and Exit Points for AI Workloads', description: - 'Invest in different industries to find the most opportunities to win huge.', + 'Seamlessly connect AI applications to Mycelium, providing optimized and secured data pipelines for training, inference, and real-time processing.', icon: DeviceCardsIcon, }, { - name: 'Trade in real-time', + name: 'Data Storage and Retrieval Mechanisms', description: - 'Get insider tips on big stock moves and act on them within seconds.', + 'Users can choose between storing data locally for quick access or utilizing the distributed grid for enhanced scalability and resilience.', icon: DeviceClockIcon, }, { - name: 'Profit from your network', + name: 'Integrated Name Services (DNS)', description: - 'Invite new insiders to get tips faster and beat even other Pocket users.', + 'The Integrated DNS system efficiently finds the shortest path between users and websites, automatically balancing loads and identifying alternative routes in case of internet issues.', icon: DeviceListIcon, }, { - name: 'Encrypted and anonymized', + name: 'Frontend/Backend Integration', description: - 'Cutting-edge security technology that even the NSA doesn’t know about keeps you hidden.', + 'Mycelium provides seamless integration with existing applications, enabling developers to leverage decentralized storage across both frontend and backend architectures.', icon: DeviceLockIcon, }, { - name: 'Portfolio tracking', + name: 'CDN (Content Delivery Network)', description: - 'Watch your investments grow exponentially, leaving other investors in the dust.', + 'Mycelium accelerates data distribution by acting as a decentralized CDN, ensuring fast, secure, and efficient content delivery across global nodes with minimal latency.', icon: DeviceChartIcon, }, ] @@ -189,18 +189,18 @@ function DeviceChartIcon(props: React.ComponentPropsWithoutRef<'svg'>) { export function SecondaryFeatures() { return (
-
-

- Now is the time to build your portfolio. -

-

- With typical market returns, you have to start young to secure your - future. With Pocket, it’s never too late to build your nest egg. +

+

Roadmap

+

+ Coming Soon: The Future of Mycelium +

+

+ Mycelium is evolving to bring even more powerful decentralized features, designed to enhance your experience and expand possibilities. Be the first to explore what's coming next by staying connected with our latest updates.

    (
  • diff --git a/src/components/UseCases.tsx b/src/components/UseCases.tsx new file mode 100644 index 0000000..36e5289 --- /dev/null +++ b/src/components/UseCases.tsx @@ -0,0 +1,374 @@ +'use client' + +import React, { useEffect, useMemo, useRef, useState } from 'react' +import clsx from 'clsx' +import { useInView } from 'framer-motion' +import { + ArchiveBoxIcon, + ChatBubbleBottomCenterIcon, + CloudIcon, + CodeBracketIcon, + ComputerDesktopIcon, + CpuChipIcon, + DocumentIcon, + EnvelopeIcon, + GlobeAltIcon, + GlobeAmericasIcon, + PlayCircleIcon, + ShareIcon, + EyeSlashIcon, + UserGroupIcon, + VideoCameraIcon, +} from '@heroicons/react/24/solid' + +import { Container } from '@/components/Container' + +interface Review { + title: string + body: string + author: string + rating: 1 | 2 | 3 | 4 | 5 +} + +const reviews: Array = [ + { + title: 'Secure remote work collaboration.', + body: 'Mycelium provides a secure, encrypted network for a wide range of use cases, from private communication to decentralized infrastructure.', + author: 'CrazyInvestor', + rating: 5, + }, + { + title: 'Private file sharing between trusted nodes.', + body: 'Mycelium enables private file sharing between trusted nodes, ensuring that sensitive information remains confidential and secure.', + author: 'CluelessButRich', + rating: 5, + }, + { + title: 'Encrypted voice/video calls.', + body: 'Mycelium enables secure voice and video calls between users, ensuring that conversations remain private and protected from eavesdropping.', + author: 'LivingDaDream', + rating: 5, + }, + { + title: 'Self-hosted messaging systems.', + body: 'Mycelium allows users to create their own self-hosted messaging systems, ensuring complete control over their communications.', + author: 'JordanBelfort1962', + rating: 5, + }, + { + title: 'Secure document collaboration.', + body: 'Mycelium enables secure document collaboration between users, ensuring that sensitive information remains confidential and protected.', + author: 'MrBurns', + rating: 5, + }, + { + title: 'Private cloud computing resources.', + body: 'Mycelium provides private cloud computing resources, allowing users to run their applications in a secure and isolated environment.', + author: 'LazyRich99', + rating: 5, + }, + { + title: 'Secure IoT device networks.', + body: 'Mycelium provides secure IoT device networks, ensuring that all connected devices can communicate privately and securely.', + author: 'SarahLuvzCash', + rating: 5, + }, + { + title: 'Remote system administration.', + body: 'Mycelium enables secure remote system administration, allowing users to manage their systems from anywhere without compromising security.', + author: 'ScroogeMcduck', + rating: 5, + }, + { + title: 'Virtual private networks (VPNs).', + body: 'Mycelium enables the creation of virtual private networks (VPNs), allowing users to securely connect to remote networks and access resources without compromising their privacy.', + author: 'BruceWayne', + rating: 5, + }, + { + title: 'Secure backup systems.', + body: 'Mycelium provides secure backup systems, ensuring that users can easily and safely back up their important data without the risk of unauthorized access.', + author: 'RichieRich', + rating: 5, + }, + { + title: 'Self-hosted web services.', + body: 'Mycelium allows users to create their own self-hosted web services, ensuring complete control over their data and applications.', + author: 'TheCountOfMonteChristo', + rating: 5, + }, + { + title: 'Private file sharing between trusted nodes.', + body: 'Mycelium enables private file sharing between trusted nodes, ensuring that sensitive information remains confidential and secure.', + author: 'ClarkKent', + rating: 5, + }, + { + title: 'Private DNS systems.', + body: 'Mycelium enables the creation of private DNS systems, allowing users to maintain control over their domain name resolution and protect their privacy.', + author: 'GeorgeCostanza', + rating: 5, + }, + { + title: 'Personal email servers.', + body: 'Mycelium allows users to create their own personal email servers, ensuring complete control over their communications and data.', + author: 'JeffBezos', + rating: 5, + }, + { + title: 'Secure document collaboration.', + body: 'Mycelium enables secure document collaboration between users, ensuring that sensitive information remains confidential and protected.', + author: 'JeffBezos', + rating: 5, + }, + { + title: 'Private media streaming.', + body: 'Mycelium enables private media streaming between users, ensuring that sensitive content remains confidential and protected.', + author: 'JeffBezos', + rating: 5, + }, + { + title: 'Personal cloud storage.', + body: 'Mycelium allows users to create their own personal cloud storage solutions, ensuring complete control over their data and privacy.', + author: 'JeffBezos', + rating: 5, + }, + { + title: 'Personal email servers.', + body: 'Mycelium allows users to create their own personal email servers, ensuring complete control over their communications and data.', + author: 'JeffBezos', + rating: 5, + }, + { + title: 'Protected content distribution.', + body: 'Mycelium enables protected content distribution, allowing users to securely share and distribute sensitive information without compromising its confidentiality.', + author: 'JeffBezos', + rating: 5, + }, + { + title: 'Secure game servers.', + body: 'Mycelium enables the creation of secure game servers, allowing users to host and manage their own gaming environments with complete control over their data and privacy.', + author: 'JeffBezos', + rating: 5, + }, { + title: 'Private git repositories.', + body: 'Mycelium enables the creation of private git repositories, allowing users to host and manage their own version control systems with complete control over their data and privacy.', + author: 'JeffBezos', + rating: 5, + }, +] + +function StarIcon(props: React.ComponentPropsWithoutRef<'svg'>) { + return ( + + ) +} + +function StarRating({ rating }: { rating: Review['rating'] }) { + return ( +
    + {[...Array(5).keys()].map((index) => ( + index ? 'fill-cyan-500' : 'fill-gray-300', + )} + /> + ))} +
    + ) +} + +function getReviewIcon(title: string) { + if (title.toLowerCase().includes('collaboration')) return UserGroupIcon; + if (title.toLowerCase().includes('file sharing')) return ShareIcon; + if (title.toLowerCase().includes('voice') || title.toLowerCase().includes('video')) return VideoCameraIcon; + if (title.toLowerCase().includes('messaging')) return ChatBubbleBottomCenterIcon; + if (title.toLowerCase().includes('document')) return DocumentIcon; + if (title.toLowerCase().includes('cloud')) return CloudIcon; + if (title.toLowerCase().includes('iot')) return CpuChipIcon; + if (title.toLowerCase().includes('administration')) return ComputerDesktopIcon; + if (title.toLowerCase().includes('vpn')) return GlobeAmericasIcon; + if (title.toLowerCase().includes('backup')) return ArchiveBoxIcon; + if (title.toLowerCase().includes('web services')) return GlobeAltIcon; + if (title.toLowerCase().includes('dns')) return GlobeAmericasIcon; + if (title.toLowerCase().includes('email')) return EnvelopeIcon; + if (title.toLowerCase().includes('media streaming') || title.toLowerCase().includes('streaming')) return PlayCircleIcon; + if (title.toLowerCase().includes('storage')) return CloudIcon; + if (title.toLowerCase().includes('distribution')) return EyeSlashIcon; + if (title.toLowerCase().includes('game')) return ComputerDesktopIcon; + if (title.toLowerCase().includes('git')) return CodeBracketIcon; + return ComputerDesktopIcon; // default +} + +function Review({ + title, + body, + author, + rating, + className, + ...props +}: Omit, keyof Review> & Review) { + let animationDelay = useMemo(() => { + let possibleAnimationDelays = ['0s', '0.1s', '0.2s', '0.3s', '0.4s', '0.5s'] + return possibleAnimationDelays[ + Math.floor(Math.random() * possibleAnimationDelays.length) + ] + }, []) + + return ( +
    +
    + {React.createElement(getReviewIcon(title), { className: "h-6 w-6 text-gray-700 mb-2" })} +

    + {title} +

    +

    {body}

    +
    + +
    + ) +} + +function splitArray(array: Array, numParts: number) { + let result: Array> = [] + for (let i = 0; i < array.length; i++) { + let index = i % numParts + if (!result[index]) { + result[index] = [] + } + result[index].push(array[i]) + } + return result +} + +function ReviewColumn({ + reviews, + className, + reviewClassName, + msPerPixel = 0, +}: { + reviews: Array + className?: string + reviewClassName?: (reviewIndex: number) => string + msPerPixel?: number +}) { + let columnRef = useRef>(null) + let [columnHeight, setColumnHeight] = useState(0) + let duration = `${columnHeight * msPerPixel}ms` + + useEffect(() => { + if (!columnRef.current) { + return + } + + let resizeObserver = new window.ResizeObserver(() => { + setColumnHeight(columnRef.current?.offsetHeight ?? 0) + }) + + resizeObserver.observe(columnRef.current) + + return () => { + resizeObserver.disconnect() + } + }, []) + + return ( +
    + {reviews.concat(reviews).map((review, reviewIndex) => ( + = reviews.length} + className={reviewClassName?.(reviewIndex % reviews.length)} + {...review} + /> + ))} +
    + ) +} + +function ReviewGrid() { + let containerRef = useRef>(null) + let isInView = useInView(containerRef, { once: true, amount: 0.4 }) + let columns = splitArray(reviews, 3) + let column1 = columns[0] + let column2 = columns[1] + let column3 = splitArray(columns[2], 2) + + return ( +
    + {isInView && ( + <> + + clsx( + reviewIndex >= column1.length + column3[0].length && + 'md:hidden', + reviewIndex >= column1.length && 'lg:hidden', + ) + } + msPerPixel={10} + /> + + reviewIndex >= column2.length ? 'lg:hidden' : '' + } + msPerPixel={15} + /> + + + )} +
    +
    +
    + ) +} + +export function UseCases() { + return ( +
    + +
    +

    + Powering Secure & Decentralized Connectivity +

    +

    + The ThreeFold Dashboard offers dozens of applications with built-in Mycelium support, making it easy to deploy and utilize. Once installed, Mycelium provides a secure, encrypted network for a wide range of use cases, from private communication to decentralized infrastructure. +

    +
    + +
    +
    + ) +} diff --git a/src/components/WindowsLink.tsx b/src/components/WindowsLink.tsx new file mode 100644 index 0000000..df72ec6 --- /dev/null +++ b/src/components/WindowsLink.tsx @@ -0,0 +1,39 @@ +import Link from 'next/link' +import clsx from 'clsx' + +export function WindowsLink({ + color = 'black', +}: { + color?: 'black' | 'white' +}) { + return ( + + {/* Windows logo */} + + + {/* Text */} +
    + Download for + Windows +
    + + ) +} diff --git a/src/images/android.svg b/src/images/android.svg new file mode 100644 index 0000000..0f0c2f1 --- /dev/null +++ b/src/images/android.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/apple.svg b/src/images/apple.svg new file mode 100644 index 0000000..74c6984 --- /dev/null +++ b/src/images/apple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/connector.png b/src/images/connector.png new file mode 100644 index 0000000..500bf12 Binary files /dev/null and b/src/images/connector.png differ diff --git a/src/images/favicon.svg b/src/images/favicon.svg new file mode 100644 index 0000000..9c8883a --- /dev/null +++ b/src/images/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/github.svg b/src/images/github.svg new file mode 100644 index 0000000..daa8847 --- /dev/null +++ b/src/images/github.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/linux.png b/src/images/linux.png new file mode 100644 index 0000000..e0a349c Binary files /dev/null and b/src/images/linux.png differ diff --git a/src/images/linux.svg b/src/images/linux.svg new file mode 100644 index 0000000..ff15420 --- /dev/null +++ b/src/images/linux.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/mycelium.svg b/src/images/mycelium.svg new file mode 100644 index 0000000..4eb60f2 --- /dev/null +++ b/src/images/mycelium.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/peers.png b/src/images/peers.png new file mode 100644 index 0000000..ad9c29b Binary files /dev/null and b/src/images/peers.png differ diff --git a/src/images/phoneframe.png b/src/images/phoneframe.png new file mode 100644 index 0000000..ad5225f Binary files /dev/null and b/src/images/phoneframe.png differ diff --git a/src/images/setting.png b/src/images/setting.png new file mode 100644 index 0000000..d36e1d6 Binary files /dev/null and b/src/images/setting.png differ diff --git a/src/images/windows.svg b/src/images/windows.svg new file mode 100644 index 0000000..ba9ac2c --- /dev/null +++ b/src/images/windows.svg @@ -0,0 +1 @@ + \ No newline at end of file