31 Commits

Author SHA1 Message Date
1792262f49 feat: add About page components with Journey and Team sections 2025-10-16 21:09:17 +02:00
b203e29593 feat: add team member gallery with profile images and randomized grid layout 2025-10-16 21:09:11 +02:00
aa6c12e749 feat: add team section and call-to-action components to About page 2025-10-16 21:08:58 +02:00
1a7a52aaf4 feat: add animated grid background with randomly activating cells in AboutSolutions 2025-10-16 17:48:58 +02:00
093546d017 refactor: move BackgroundIllustration to separate component and add new gradient styles 2025-10-16 17:39:56 +02:00
ab42093c78 style: adjust hero heading line height from tight to none 2025-10-16 16:21:02 +02:00
40e616fa83 feat: add animated hero section with TypeAnimation component on About page 2025-10-16 16:06:35 +02:00
4ef0b3918b fix: remove duplicate text-base class and update navigation links in header 2025-10-16 14:55:08 +02:00
cd8687db54 add favico 2025-09-09 16:04:02 +02:00
c59c905945 ok 2025-09-08 17:48:06 +02:00
14435d8f63 ok 2025-09-08 17:42:19 +02:00
987550c7c6 ok 2025-09-08 17:22:33 +02:00
ecd52b6ada ok 2025-09-08 17:19:59 +02:00
7e2b30fbcc add 2025-09-08 17:18:54 +02:00
a69f35c9a7 ALL 2025-09-08 15:27:33 +02:00
4bea627e6d add -a 2025-09-05 16:39:35 +02:00
6d35b9dd05 add 2025-09-05 16:23:53 +02:00
40d1d5ed24 add 2025-09-05 15:44:26 +02:00
ddbe3c795d add 2025-09-05 15:35:19 +02:00
1df765c4aa ok 2025-09-05 15:28:52 +02:00
c8a3b455fe ok 2025-09-05 14:35:51 +02:00
75aa34ae6f add chmod +x *.sh 2025-08-14 15:33:24 +02:00
0310ecfb31 ... 2025-08-14 12:56:26 +02:00
3657932051 add icons 2025-08-07 17:33:28 +02:00
f63e3229c7 add pngs 2025-08-07 17:22:35 +02:00
b9b2148417 ok 2025-08-06 17:03:14 +02:00
8f54a11b1e k 2025-08-06 16:33:17 +02:00
6eadc482eb add 2025-08-05 16:41:17 +02:00
045486365d add all 2025-08-04 16:57:37 +02:00
0eee1629c6 add spotlight 2025-08-03 16:40:51 +02:00
663fd167b7 dark mode 2025-08-02 19:40:54 +02:00
117 changed files with 10666 additions and 1070 deletions

View File

@@ -1,6 +1,6 @@
# EngageOS
# ThreeFold
EngageOS is a [Tailwind Plus](https://tailwindcss.com/plus) site template built using [Tailwind CSS](https://tailwindcss.com) and [Next.js](https://nextjs.org).
ThreeFold is a [Tailwind Plus](https://tailwindcss.com/plus) site template built using [Tailwind CSS](https://tailwindcss.com) and [Next.js](https://nextjs.org).
## Getting started

19
build.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
cd "$(dirname "$0")"
# Ensure all shell scripts are executable
chmod +x *.sh
PREFIX="threefold"
echo "building for folder: /$PREFIX/"
export NEXT_PUBLIC_BASE_PATH="/$PREFIX"
# mkdir -p "out"
# pnpm install --frozen-lockfile
pnpm run build
# local mirror (optional)
# rsync -rav --delete dist/ "${HOME}/hero/var/www/$PREFIX/"

21
components.json Normal file
View File

@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/tailwind.css",
"baseColor": "stone",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}

View File

@@ -0,0 +1,92 @@
'use client';
import React, { useEffect, useRef, useState } from 'react';
import createGlobe from 'cobe';
import { cn } from '@/lib/utils';
interface EarthProps {
className?: string;
theta?: number;
dark?: number;
scale?: number;
diffuse?: number;
mapSamples?: number;
mapBrightness?: number;
baseColor?: [number, number, number];
markerColor?: [number, number, number];
glowColor?: [number, number, number];
}
const Earth: React.FC<EarthProps> = ({
className,
theta = 0.25,
dark = 1,
scale = 1.1,
diffuse = 1.2,
mapSamples = 40000,
mapBrightness = 6,
baseColor = [0.4, 0.6509, 1],
markerColor = [1, 0, 0],
glowColor = [0.2745, 0.5765, 0.898],
}) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
let width = 0;
const onResize = () =>
canvasRef.current && (width = canvasRef.current.offsetWidth);
window.addEventListener('resize', onResize);
onResize();
let phi = 0;
onResize();
const globe = createGlobe(canvasRef.current!, {
devicePixelRatio: 2,
width: width * 2,
height: width * 2,
phi: 0,
theta: theta,
dark: dark,
scale: scale,
diffuse: diffuse,
mapSamples: mapSamples,
mapBrightness: mapBrightness,
baseColor: baseColor,
markerColor: markerColor,
glowColor: glowColor,
opacity: 1,
offset: [0, 0],
markers: [
// longitude latitude
],
onRender: (state: Record<string, any>) => {
// Called on every animation frame.
// `state` will be an empty object, return updated params.\
state.phi = phi;
phi += 0.003;
},
});
return () => {
globe.destroy();
};
}, []);
return (
<div
className={cn(
'flex items-center justify-center z-[10] w-full max-w-[350px] mx-auto',
className
)}
>
<canvas
ref={canvasRef}
style={{
width: '100%',
height: '100%',
maxWidth: '100%',
aspectRatio: '1',
}}
/>
</div>
);
};
export default Earth;

24
install.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/bash
# HERO Personal Agent Website - Installation Script
# This script installs all dependencies using pnpm
# Check if Node.js is installed
if ! command -v node &> /dev/null; then
echo "❌ Node.js is not installed. Please install Node.js first."
exit 1
fi
# Check if pnpm is installed
if ! command -v pnpm &> /dev/null; then
echo "📦 Installing pnpm..."
npm install -g pnpm
fi
echo "📋 Node.js version: $(node --version)"
echo "📋 pnpm version: $(pnpm --version)"
# Install dependencies
echo "📦 Installing project dependencies..."
pnpm install

6
lib/utils.ts Normal file
View File

@@ -0,0 +1,6 @@
import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

2
next-env.d.ts vendored
View File

@@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@@ -1,4 +1,10 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}
const nextConfig = {
basePath: process.env.NEXT_PUBLIC_BASE_PATH || '',
output: 'export',
images: {
unoptimized: true,
},
}
module.exports = nextConfig

2300
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,17 +12,28 @@
"dependencies": {
"@headlessui/react": "^2.1.0",
"@heroicons/react": "^2.2.0",
"@react-three/drei": "^9.88.13",
"@react-three/fiber": "^8.15.11",
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/postcss": "^4.1.7",
"@types/node": "^20.10.8",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"clsx": "^2.1.0",
"framer-motion": "^10.15.0",
"next": "^14.0.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@types/react": "^18.3.23",
"@types/react-dom": "^18.3.7",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cobe": "^0.6.4",
"framer-motion": "^12.23.12",
"lucide-react": "^0.536.0",
"motion": "^12.23.12",
"next": "^15.4.5",
"react": "^18.3.1",
"react-countup": "^6.5.3",
"react-dom": "^18.3.1",
"react-type-animation": "^3.2.0",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^4.1.7",
"three": "^0.179.1",
"three-globe": "^2.27.2",
"typescript": "^5.3.3",
"use-debounce": "^10.0.0"
},
@@ -31,6 +42,7 @@
"eslint-config-next": "^14.0.4",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.11",
"sharp": "0.33.1"
"sharp": "0.33.1",
"tw-animate-css": "^1.3.6"
}
}

5581
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

BIN
public/images/3nodes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 KiB

BIN
public/images/3phone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/images/3router.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/images/aibox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

74
public/images/build.svg Normal file
View File

@@ -0,0 +1,74 @@
<svg width="601" height="600" viewBox="0 0 601 600" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_266_24)">
<path opacity="0.07" d="M546.232 252.902C546.232 256.16 546.16 259.418 545.943 262.459C577.053 286.135 601 336.889 601 381.561C601 430.216 572.567 453.167 537.478 432.895C537.406 432.822 537.333 432.822 537.261 432.75L316.815 305.539C316.742 305.466 316.67 305.466 316.525 305.394C277.095 282.587 245.117 219.814 245.117 165.15C245.117 113.961 273.188 87.9689 309.146 103.68C313.559 68.565 337.072 53.4329 365.433 69.8683C379.035 77.7602 391.551 91.589 401.318 108.242C415.498 87.1725 439.663 81.8147 467.01 97.5984C510.781 122.795 546.232 192.373 546.232 252.902Z" fill="url(#paint0_linear_266_24)"/>
<path opacity="0.4" d="M510.058 287.655C510.058 290.913 509.986 294.172 509.769 297.212C540.879 320.888 564.826 371.642 564.826 416.315C564.826 464.969 536.393 487.921 501.304 467.648C501.232 467.576 501.159 467.576 501.087 467.503L280.641 340.292C280.569 340.22 280.496 340.22 280.351 340.147C240.921 317.34 208.943 254.567 208.943 199.903C208.943 148.715 237.015 122.722 272.972 138.434C277.385 103.318 300.898 88.1863 329.259 104.622C342.861 112.514 355.377 126.342 365.144 142.995C379.324 121.926 403.489 116.568 430.837 132.352C474.608 157.548 510.058 227.127 510.058 287.655Z" fill="url(#paint1_linear_266_24)"/>
<path opacity="0.2" d="M161.048 349.632L127.479 330.228V318.861L161.048 338.265C163.798 339.858 167.777 343.043 171.177 347.967C174.867 353.252 177.471 359.913 177.471 367.153C177.471 375.118 175.446 379.679 171.539 380.982C167.921 382.213 163.653 380.113 160.976 378.593L147.157 370.629L147.085 370.556C145.927 369.832 144.046 369.181 142.527 369.615C141.297 369.977 139.922 371.208 139.922 375.624C139.922 380.041 141.297 382.792 142.455 384.385C143.902 386.412 145.783 387.86 146.94 388.44L147.085 388.512L189.264 412.912V424.279L147.302 400.024C144.408 398.504 140.284 395.318 136.667 390.25C132.76 384.747 130.011 377.724 130.083 369.905C130.083 362.158 132.76 358.175 136.667 357.089C140.284 356.076 144.408 357.524 147.302 359.334L160.976 367.226C162.929 368.384 164.449 368.891 165.389 368.529C166.113 368.312 167.56 367.226 167.56 361.434C167.56 357.741 166.33 355.279 165.245 353.614C163.942 351.732 162.134 350.284 161.048 349.632Z" fill="white"/>
<path d="M134.714 327.404C134.714 336.744 129.215 341.161 122.487 337.323C115.758 333.414 110.26 322.698 110.26 313.286C110.26 303.946 115.758 299.529 122.487 303.367C129.215 307.276 134.714 318.064 134.714 327.404Z" fill="#595959"/>
<path d="M206.339 428.044C206.339 437.384 200.84 441.8 194.112 437.963C187.383 434.053 181.885 423.338 181.885 413.925C181.885 404.585 187.383 400.169 194.112 404.006C200.84 407.916 206.339 418.704 206.339 428.044Z" fill="#595959"/>
<path opacity="0.07" d="M264.145 187.522L481.118 312.851V427.754L264.072 302.425L264.145 187.522Z" fill="url(#paint2_linear_266_24)"/>
<path opacity="0.3" d="M235.133 202.003L452.106 327.332V442.235L235.133 316.906V202.003Z" fill="url(#paint3_linear_266_24)"/>
<path d="M254.594 270.424C254.594 279.691 260.092 290.335 266.821 294.244C273.549 298.154 279.048 293.81 279.048 284.542C279.048 275.275 273.549 264.632 266.821 260.722C260.092 256.812 254.594 261.156 254.594 270.424Z" fill="#595959"/>
<path opacity="0.15" d="M285.199 288.307C285.199 292.579 287.731 297.575 290.915 299.385C294.026 301.195 296.558 299.168 296.558 294.896C296.558 290.624 294.026 285.628 290.842 283.818C287.731 282.008 285.199 284.035 285.199 288.307Z" fill="white"/>
<path opacity="0.15" d="M302.635 298.371C302.635 302.642 305.167 307.638 308.35 309.448C311.461 311.258 313.994 309.231 313.994 304.959C313.994 300.688 311.461 295.692 308.278 293.882C305.167 292.072 302.635 294.099 302.635 298.371Z" fill="white"/>
<path opacity="0.15" d="M397.338 317.919V383.299L388.801 378.376V312.996L397.338 317.919Z" fill="white"/>
<path opacity="0.15" d="M416.004 328.78V394.159L407.467 389.236V323.856L416.004 328.78Z" fill="white"/>
<path opacity="0.15" d="M434.742 339.64V405.02L426.205 400.096V334.717L434.742 339.64Z" fill="white"/>
<path opacity="0.07" d="M264.072 344.563L481.046 469.892V584.795L264.072 459.466V344.563Z" fill="url(#paint4_linear_266_24)"/>
<path opacity="0.3" d="M235.133 359.768L452.106 485.097V600L235.133 474.671V359.768Z" fill="url(#paint5_linear_266_24)"/>
<path d="M254.594 428.188C254.594 437.456 260.092 448.099 266.821 452.009C273.549 455.919 279.048 451.574 279.048 442.307C279.048 433.039 273.549 422.396 266.821 418.487C260.092 414.577 254.594 418.921 254.594 428.188Z" fill="#565656"/>
<path opacity="0.15" d="M285.199 446.145C285.199 450.416 287.731 455.412 290.915 457.222C294.026 459.032 296.558 457.005 296.558 452.733C296.558 448.461 294.026 443.466 290.842 441.656C287.731 439.846 285.199 441.8 285.199 446.145Z" fill="white"/>
<path opacity="0.15" d="M302.562 456.208C302.562 460.48 305.096 465.476 308.279 467.286C311.39 469.096 313.921 467.069 313.921 462.797C313.921 458.525 311.389 453.53 308.206 451.719C305.095 449.837 302.562 451.864 302.562 456.208Z" fill="white"/>
<path opacity="0.15" d="M397.338 477.929V543.309L388.801 538.385V473.006L397.338 477.929Z" fill="white"/>
<path opacity="0.15" d="M416.004 488.79V554.169L407.467 549.246V483.866L416.004 488.79Z" fill="white"/>
<path opacity="0.15" d="M434.742 499.65V565.029L426.205 560.106V494.727L434.742 499.65Z" fill="white"/>
<path opacity="0.3" d="M42.4688 31.7847L177.688 109.907V360.637L42.4688 282.442V31.7847Z" fill="url(#paint6_linear_266_24)"/>
<path d="M125.959 122.577C125.959 135.103 118.724 141.04 109.825 135.827C100.926 130.614 93.6914 116.278 93.6914 103.753C93.6914 91.2272 100.926 85.2901 109.825 90.5031C118.724 95.7161 125.959 110.052 125.959 122.577Z" fill="#595959"/>
<path d="M109.825 145.891C95.4274 137.493 83.5622 145.384 81.4641 163.485C81.1024 166.598 83.4899 170.798 86.3838 172.463L133.338 199.904C136.232 201.569 138.62 200.266 138.258 196.645C136.087 176.011 124.15 154.29 109.825 145.891Z" fill="#595959"/>
<path opacity="0.15" d="M69.5996 194.401L150.196 240.956V250.802L69.5996 204.248V194.401Z" fill="white"/>
<path opacity="0.15" d="M77.7754 218.656L141.659 255.509V265.355L77.7754 228.502V218.656Z" fill="white"/>
<path d="M94.0532 260.07L0 205.696V233.716L94.0532 288.09V260.07Z" fill="#363636"/>
<path opacity="0.2" d="M206.845 0L226.958 39.5318C229.707 44.962 229.273 50.3922 225.945 51.6954C222.617 52.9987 217.698 49.5957 214.948 44.1656L214.731 43.6587V87.5347C214.731 92.5305 211.259 94.5577 206.918 92.096C202.577 89.5619 199.104 83.5525 199.104 78.5568V34.6808L198.887 34.898C196.138 37.1425 191.146 34.8256 187.89 29.685C184.562 24.5445 184.128 18.6075 186.877 16.363L206.845 0Z" fill="url(#paint7_linear_266_24)"/>
<path opacity="0.2" d="M206.845 583.709L186.733 544.177C183.983 538.747 184.417 533.317 187.745 532.014C191.073 530.711 195.993 534.113 198.742 539.544L198.959 540.05V496.174C198.959 491.179 202.432 489.151 206.773 491.613C211.114 494.147 214.587 500.157 214.587 505.152V549.028L214.804 548.811C217.553 546.567 222.545 548.884 225.801 554.024C229.129 559.165 229.563 565.102 226.814 567.346L206.845 583.709Z" fill="url(#paint8_linear_266_24)"/>
</g>
<defs>
<linearGradient id="paint0_linear_266_24" x1="588.058" y1="114.638" x2="364.033" y2="326.972" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_266_24" x1="551.876" y1="149.392" x2="327.852" y2="361.726" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_266_24" x1="368.16" y1="196.711" x2="376.256" y2="399.958" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint3_linear_266_24" x1="339.219" y1="211.191" x2="347.315" y2="414.438" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint4_linear_266_24" x1="368.144" y1="353.776" x2="376.24" y2="557.023" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint5_linear_266_24" x1="339.204" y1="368.981" x2="347.3" y2="572.227" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint6_linear_266_24" x1="192.18" y1="53.8207" x2="72.0119" y2="261.857" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint7_linear_266_24" x1="221.158" y1="39.8764" x2="184.449" y2="60.3243" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint8_linear_266_24" x1="192.494" y1="543.86" x2="229.203" y2="523.412" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0_266_24">
<rect width="601" height="600" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
public/images/capacity.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
public/images/hgu-04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
public/images/kds.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 83 KiB

BIN
public/images/net.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
public/images/rewards.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
public/images/solution1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
public/images/tfdash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

View File

@@ -0,0 +1,15 @@
import { AboutHero } from "@/components/AboutHero"
import { AboutSolutions } from "@/components/AboutSolutions"
import { AboutTeam } from "@/components/AboutTeam"
import { AboutCTA } from "@/components/AboutCTA"
export default function About() {
return (
<div>
<AboutHero />
<AboutSolutions />
<AboutTeam />
<AboutCTA />
</div>
)
}

View File

@@ -0,0 +1,12 @@
import BuildHero from "@/components/BuildHero";
import BuildStack from "@/components/BuildStack";
export default function Build() {
return (
<div>
<BuildHero />
<BuildStack />
</div>
)
}

View File

@@ -1,5 +1,4 @@
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'
@@ -8,18 +7,30 @@ import { SecondaryFeatures } from '@/components/SecondaryFeatures'
import Tractions from '@/components/Tractions'
import Benefits from '@/components/Benefits'
import Cta from '@/components/Cta'
import { SpotlightPreview } from '@/components/Spotlight'
import { StackSectionPreview } from '@/components/StackSection'
import GlobeDemo from '@/components/GlobeDemo'
import { Dashboard } from '@/components/Dashboard'
import { AppsPreview } from '@/components/Apps'
import { FarmerPreview } from '@/components/Farmer'
import { TfDashboard } from '@/components/TfDashboard'
import { ProductsPreview } from '@/components/Products'
import { CallTo } from '@/components/CallTo'
import { Faqss } from '@/components/Faqs'
export default function Home() {
return (
<>
<Hero />
<Tractions />
<Benefits />
<SecondaryFeatures />
<Reviews />
<Pricing />
<Cta />
<Faqs />
<SpotlightPreview />
<StackSectionPreview />
<Dashboard />
<FarmerPreview />
<TfDashboard />
<AppsPreview />
<ProductsPreview />
<CallTo />
<Faqss />
</>
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -12,11 +12,11 @@ const inter = Inter({
export const metadata: Metadata = {
title: {
template: '%s - EngageOS',
default: 'EngageOS - Invest at the perfect time.',
template: '%s - ThreeFold',
default: 'ThreeFold - Decentralized internet by everyone, for everyone.',
},
description:
'By leveraging insights from our network of industry insiders, youll know exactly when to buy to maximize profit, and exactly when to sell to avoid painful losses.',
'ThreeFold is a fully operational, decentralized internet infrastructure deployed locally, scalable globally, and owned and powered by the people.',
}
export default function RootLayout({
@@ -25,8 +25,10 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
<html lang="en" className={clsx('bg-white antialiased', inter.variable)}>
<body>{children}</body>
<html lang="en" className={clsx('antialiased', inter.variable)} suppressHydrationWarning>
<body className="bg-[#121212] text-white" suppressHydrationWarning>
{children}
</body>
</html>
)
}

View File

@@ -0,0 +1,44 @@
export function AboutCTA() {
return (
<div className="bg-transparent">
<div className="mx-auto max-w-7xl py-24 px-6 lg:px-4">
<div className="relative isolate overflow-hidden bg-stat-gradient py-16 text-center after:pointer-events-none after:absolute after:inset-0 sm:rounded-3xl sm:px-16">
<div className="mx-auto max-w-2xl lg:max-w-2xl">
<h2 className="text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl">
Be Part of the Change
</h2>
<p className="mx-auto mt-6 max-w-xl text-sm font-light text-pretty text-white lg:text-base">
Contribute your resources, build decentralized applications, or simply learn more about how you can get involved
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
<a
href="#"
className="rounded-md bg-white/10 px-3.5 py-2.5 text-sm font-semibold text-white hover:bg-white/15"
>
{' '}
Get started{' '}
</a>
<a href="#" className="text-sm/6 font-semibold text-white">
Learn more
<span aria-hidden="true"></span>
</a>
</div>
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-1/2 left-1/2 -z-10 size-256 -translate-x-1/2 mask-[radial-gradient(closest-side,white,transparent)]"
>
<circle r={512} cx={512} cy={512} fill="url(#827591b1-ce8c-4110-b064-7cb85a0b1217)" fillOpacity="0.7" />
<defs>
<radialGradient id="827591b1-ce8c-4110-b064-7cb85a0b1217">
<stop stopColor="#fff4f8" />
<stop offset={1} stopColor="#97979d" />
</radialGradient>
</defs>
</svg>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,50 @@
"use client";
import { TypeAnimation } from 'react-type-animation';
const rotatingWords = [
"everyone",
1500,
"creators",
1500,
"dreamers",
1500,
"developers",
1500,
"communities",
1500,
"humanity",
1500,
"builders",
1500,
"thinkers",
1500,
"doers",
1500,
"pioneers",
1500,
"the next billion",
1500,
"All",
1500,
];
export function AboutHero() {
return (
<section className="flex flex-col items-start justify-center min-h-[70vh] px-6 md:px-16 text-white">
<h1 className="text-5xl lg:text-8xl font-medium leading-none">
Building a Decentralized Internet for{" "}
<TypeAnimation
sequence={rotatingWords}
wrapper="span"
speed={50}
className="relative inline-block text-[#00FFD1]"
repeat={Infinity}
/> .
</h1>
<p className="max-w-3xl mt-6 text-lg md:text-2xl text-gray-800">
At <span className="text-[#00FFD1] font-medium">ThreeFold</span>, we are empowering
individuals and organizations to shape an open, resilient, and sustainable internet.
</p>
</section>
);
}

View File

@@ -0,0 +1,38 @@
import Image from 'next/image'
const featuredPost = {
id: 1,
title: 'Our Journey',
href: '#',
description:
'For decades, weve tackled challenges in data storage, secure networking, and autonomous cloud systems. These experiences, combined with our vision for a better internet, have shaped ThreeFold and continue to guide our growth.',
}
export function AboutJourney() {
return (
<div className=" py-24 sm:py-32">
<div className="mx-auto grid max-w-7xl grid-cols-1 gap-x-8 gap-y-12 px-6 sm:gap-y-16 lg:grid-cols-2 lg:px-8">
<article className="mx-auto my-auto w-full max-w-2xl lg:mx-0 lg:max-w-lg">
<h2
id="featured-post"
className="mt-4 text-3xl font-semibold tracking-tight text-pretty text-white sm:text-4xl"
>
{featuredPost.title}
</h2>
<p className="mt-4 text-sm font-light text-pretty lg:text-base text-gray-600">{featuredPost.description}</p>
<div className="mt-4 flex flex-col justify-between gap-6 sm:mt-8 sm:flex-row-reverse sm:gap-8 lg:mt-4 lg:flex-col">
</div>
</article>
<div className="relative lg:col-span-1">
<Image
src="/images/solution1.jpg"
alt="Our Solution"
width={1000}
height={1000}
className="w-full h-auto object-cover rounded-lg"
/>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,89 @@
"use client";
import { useEffect, useState } from "react";
export function AboutSolutions() {
const totalCells = 2000;
const [active, setActive] = useState<number[]>([]);
// randomly activate some squares every 0.8 s
useEffect(() => {
const interval = setInterval(() => {
const newActive = Array.from({ length: 20 }, () =>
Math.floor(Math.random() * totalCells)
);
setActive(newActive);
}, 800);
return () => clearInterval(interval);
}, []);
return (
<section
className="relative bg-[#121212] text-gray-200 overflow-hidden"
style={
{
"--cell": "4rem",
height: "74vh",
} as React.CSSProperties
}
>
{/* Animated grid background */}
<div
className="absolute inset-0 z-0 grid"
style={{
gridTemplateColumns: "repeat(auto-fill, var(--cell))",
gridAutoRows: "var(--cell)",
justifyContent: "center",
}}
aria-hidden="true"
>
{Array.from({ length: totalCells }).map((_, i) => (
<div
key={i}
className={`border border-[#1f1f1f] transition-colors duration-500 cursor-pointer ${
active.includes(i) ? "bg-[#00FFD1]" : "bg-transparent"
}`}
/>
))}
</div>
{/* Foreground content aligned to same grid */}
<div
className="relative z-10 grid grid-cols-[repeat(auto-fill,var(--cell))] auto-rows-[var(--cell)] gap-0 pointer-events-none w-full h-full"
style={{ justifyContent: "center" }}
>
{/* Top-left card */}
<div className="col-start-2 row-start-2 col-span-5 row-span-3 pointer-events-auto">
<div className="bg-[#121212] w-full h-full flex items-center p-6 shadow-lg">
<p className="text-sm text-gray-600 leading-normal">
Unlike traditional internet infrastructure, ThreeFold runs on a
global mesh of independent cloud providers, individuals and
organizations contributing compute, storage, and network power.
</p>
</div>
</div>
{/* Center card */}
<div className="col-start-9 row-start-3 col-span-6 row-span-5 pointer-events-auto">
<div className="bg-[#121212] w-full h-full flex items-center justify-center text-center shadow-lg">
<p className="text-2xl md:text-3xl font-medium text-white leading-tight">
A Decentralized Foundation for the Internet.
</p>
</div>
</div>
{/* Bottom-right card */}
<div className="col-start-17 row-start-6 col-span-5 row-span-3 pointer-events-auto">
<div className="bg-[#121212] w-full h-full flex items-center p-6 shadow-lg">
<p className="text-sm text-gray-600 leading-normal">
This physical decentralization removes bottlenecks, in creases
resilience, and protects privacy. ThreeFold is a neutral, scalable
foundation for the next-generation internet, where digital
sovereignty and collaboration come first.
</p>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,22 @@
import { Gallery } from './Gallery'
export function AboutTeam() {
return (
<div className="relative my-16 mx-6">
<Gallery />
<div className="mx-auto grid max-w-7xl lg:grid-cols-2">
<div className="px-6 pt-16 pb-24 sm:pt-20 sm:pb-32 lg:col-start-2 lg:px-8 lg:pt-32">
<div className="mx-auto max-w-2xl lg:mr-0 lg:max-w-lg">
<h1 className="mt-2 text-3xl font-medium tracking-tight text-pretty text-white lg:text-4xl">
Founded by Internet Pioneers and Powered by the Community
</h1>
<p className="mt-6 text-sm font-light text-pretty text-gray-600 lg:text-base">
ThreeFold was started by pioneers from the early days of the internet, when it was a true peer-to-peer network. Today, its an open-source movement supported by a dedicated team and a vibrant community of contributors. Over 50 full-time developers and countless Hosters worldwide help bring our shared vision to life.
</p>
</div>
</div>
</div>
</div>
)
}

78
src/components/Apps.tsx Normal file
View File

@@ -0,0 +1,78 @@
"use client";
import React from "react";
import Image from 'next/image'
import { motion } from "framer-motion";
import Algorand from '@/images/logos/algorand.svg'
import Casperlabs from '@/images/logos/casperlabs.svg'
import Discourse from '@/images/logos/discourse.svg'
import gitea from '@/images/logos/gitea.svg'
import Jenkins from '@/images/logos/jenkins.svg'
import Jitsi from '@/images/logos/jitsi.svg'
import Mattermost from '@/images/logos/mattermost.svg'
import Nextcloud from '@/images/logos/nextcloud.svg'
const logos = [
Algorand, Casperlabs, Discourse, gitea,
Jenkins, Jitsi, Mattermost, Nextcloud,
];
export function AppsPreview() {
return (
<div className="relative flex h-[40rem] w-full overflow-hidden rounded-md bg-transparent antialiased md:items-center md:justify-center">
<div className="relative z-10 mx-auto w-full max-w-3xl p-4 pt-16">
{/* Heading */}
<motion.div
className="flex flex-col justify-center items-center mb-6"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1 }}
>
<h1 className="bg-opacity-50 bg-gradient-to-b from-neutral-50 to-neutral-400 bg-clip-text tracking-tighter text-center text-4xl font-semibold text-transparent lg:text-5xl">
Anything That Runs on Linux Can Run on ThreeFold
</h1>
</motion.div>
{/* Animated Line */}
<motion.div
className="h-[2px] bg-neutral-400 rounded-full mx-auto mb-12"
initial={{ width: 0 }}
animate={{ width: "100%" }}
transition={{ duration: 2, delay: 1 }}
/>
{/* Logos grid */}
<motion.div
className="mx-auto grid grid-cols-2 items-start gap-x-8 gap-y-10 sm:gap-x-10 lg:mx-0 lg:grid-cols-4"
initial="hidden"
animate="visible"
variants={{
visible: {
transition: {
staggerChildren: 0.15,
delayChildren: 2.8,
},
},
}}
>
{logos.map((logo, i) => (
<motion.div
key={i}
className="flex justify-center"
variants={{
hidden: { opacity: 0, y: 30 },
visible: { opacity: 1, y: 0 },
}}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<Image src={logo} alt="" unoptimized className="hover:backdrop-opacity-100 opacity-90" />
</motion.div>
))}
</motion.div>
</div>
</div>
);
}

View File

@@ -0,0 +1,70 @@
import { useId } from 'react'
export function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
let id = useId()
return (
<div {...props}>
<svg
viewBox="0 0 1026 1026"
fill="none"
aria-hidden="true"
className="absolute inset-0 h-full w-full animate-spin-slow"
>
<path
d="M1025 513c0 282.77-229.23 512-512 512S1 795.77 1 513 230.23 1 513 1s512 229.23 512 512Z"
stroke="#D4D4D4"
strokeOpacity="0.7"
/>
<path
d="M513 1025C230.23 1025 1 795.77 1 513"
stroke={`url(#${id}-gradient-1)`}
strokeLinecap="round"
/>
<defs>
<linearGradient
id={`${id}-gradient-1`}
x1="1"
y1="513"
x2="1"
y2="1025"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#06b6d4" />
<stop offset="1" stopColor="#06b6d4" stopOpacity="0" />
</linearGradient>
</defs>
</svg>
<svg
viewBox="0 0 1026 1026"
fill="none"
aria-hidden="true"
className="absolute inset-0 h-full w-full animate-spin-reverse-slower"
>
<path
d="M913 513c0 220.914-179.086 400-400 400S113 733.914 113 513s179.086-400 400-400 400 179.086 400 400Z"
stroke="#D4D4D4"
strokeOpacity="0.7"
/>
<path
d="M913 513c0 220.914-179.086 400-400 400"
stroke={`url(#${id}-gradient-2)`}
strokeLinecap="round"
/>
<defs>
<linearGradient
id={`${id}-gradient-2`}
x1="913"
y1="513"
x2="913"
y2="913"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#06b6d4" />
<stop offset="1" stopColor="#06b6d4" stopOpacity="0" />
</linearGradient>
</defs>
</svg>
</div>
)
}

28
src/components/Banner.tsx Normal file
View File

@@ -0,0 +1,28 @@
import { XMarkIcon } from '@heroicons/react/20/solid'
export function Banner() {
return (
<div className="relative flex items-center gap-x-6 bg-gray-200 px-6 py-2.5 after:absolute after:inset-x-0 after:bottom-0 after:h-px after:bg-white/10 sm:px-3.5 sm:before:flex-1">
<p className="text-sm/6 text-white">
<strong className="font-semibold">ThreeFold is going commercial!</strong>
<svg viewBox="0 0 2 2" aria-hidden="true" className="mx-2 inline size-0.5 fill-current">
<circle r={1} cx={1} cy={1} />
</svg>
Read our <a
href="https://www.threefold.io/newsroom/summer-2025-roundup/"
target="_blank"
rel="noopener noreferrer"
className="underline hover:text-white hover:font-semibold"
>
2025 Summer Round Up
</a>
</p>
<div className="flex flex-1 justify-end">
<button type="button" className="-m-3 p-3 focus-visible:-outline-offset-4">
<span className="sr-only">Dismiss</span>
<XMarkIcon aria-hidden="true" className="size-5 text-white" />
</button>
</div>
</div>
)
}

View File

@@ -8,79 +8,79 @@ import Benefits4 from '@/images/benefits/benefits4.jpg'
export default function Benefits() {
return (
<div className="bg-white py-12">
<div style={{ backgroundColor: '#121212' }} className="py-12">
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8">
<Container>
<div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl">
<h2 className="lg:text-4xl text-3xl font-medium tracking-tight text-gray-900">
<h2 className="lg:text-4xl text-3xl font-medium tracking-tight text-white">
Built Different. For a Change.
</h2>
<p className="mt-6 lg:text-lg text-base text-gray-600">
EngageOS isnt just another tech platform its a digital infrastructure built from the ground up for purpose-driven organizations. From white-label sovereignty to field-ready resilience, every element of EngageOS is designed to meet the real-world challenges of civil society.
<p className="mt-6 lg:text-lg text-base text-gray-300">
ThreeFold isn't just another tech platform — it's a digital infrastructure built from the ground up for purpose-driven organizations. From white-label sovereignty to field-ready resilience, every element of ThreeFold is designed to meet the real-world challenges of civil society.
</p>
</div>
</Container>
<div className="mt-10 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2">
<div className="flex p-px lg:col-span-4">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 max-lg:rounded-t-4xl lg:rounded-tl-4xl">
<div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 max-lg:rounded-t-4xl lg:rounded-tl-4xl">
<Image
alt=""
src={Benefits1}
className="h-80 object-cover object-left"
/>
<div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900"> Built for Civil Society</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Purpose-First, Not Profit-First</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600">
Unlike traditional SaaS built for commercial scale, EngageOS was born from the realities of NGOs, grassroots coalitions, and purpose-led institutions. Every module, flow, and metric is optimized to serve impact not ad revenue or venture capital.
<h3 className="text-sm/4 font-semibold text-white"> Built for Civil Society</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-white">Purpose-First, Not Profit-First</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
Unlike traditional SaaS built for commercial scale, ThreeFold was born from the realities of NGOs, grassroots coalitions, and purpose-led institutions. Every module, flow, and metric is optimized to serve impact not ad revenue or venture capital.
</p>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-2">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 lg:rounded-tr-4xl">
<div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 lg:rounded-tr-4xl">
<Image
alt=""
src={Benefits2}
className="h-80 object-cover"
/>
<div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900">White-Label, Zero-Code</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Your Brand, Your Movements</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600">
EngageOS empowers organizations to fully own their digital identity. From Red Cross OS to Montessori OS, each instance is custom-branded no tech team required. You launch a platform that looks and feels like you, not us.
<h3 className="text-sm/4 font-semibold text-white">White-Label, Zero-Code</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-white">Your Brand, Your Movements</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
ThreeFold empowers organizations to fully own their digital identity. From Red Cross OS to Montessori OS, each instance is custom-branded no tech team required. You launch a platform that looks and feels like you, not us.
</p>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-2">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 lg:rounded-bl-4xl">
<div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 lg:rounded-bl-4xl">
<Image
alt=""
src={Benefits3}
className="h-80 object-cover"
/>
<div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900">Sovereign & Ethical Infrastructure</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Own Your Data. Always.</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600">
We dont mine or monetize user data. EngageOS runs on decentralized, privacy-respecting infrastructure built for trust, compliance, and sovereignty. You control where your data lives and who sees it.
<h3 className="text-sm/4 font-semibold text-white">Sovereign & Ethical Infrastructure</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-white">Own Your Data. Always.</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
We don't mine or monetize user data. ThreeFold runs on decentralized, privacy-respecting infrastructure built for trust, compliance, and sovereignty. You control where your data lives and who sees it.
</p>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-4">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 max-lg:rounded-b-4xl lg:rounded-br-4xl">
<div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 max-lg:rounded-b-4xl lg:rounded-br-4xl">
<Image
alt=""
src={Benefits4}
className="h-80 object-cover object-left"
/>
<div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900">Mutualized Model</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Share Infrastructure. Multiply Impact.</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600">
By pooling tech costs across aligned organizations, EngageOS offers enterprise-grade functionality at a fraction of the price. When one partner grows, the entire ecosystem benefits through shared modules, updates, and insights.
<h3 className="text-sm/4 font-semibold text-white">Mutualized Model</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-white">Share Infrastructure. Multiply Impact.</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
By pooling tech costs across aligned organizations, ThreeFold offers enterprise-grade functionality at a fraction of the price. When one partner grows, the entire ecosystem benefits through shared modules, updates, and insights.
</p>
</div>
</div>

View File

@@ -0,0 +1,45 @@
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react'
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
import { ChevronRightIcon } from '@heroicons/react/20/solid'
import { Button } from './Button'
export default function BuildHero() {
return (
<div className="relative overflow-hidden">
<main>
<div className="bg-transparent pt-10 sm:pt-16 lg:overflow-hidden lg:pt-8 lg:pb-14">
<div className="mx-auto max-w-7xl lg:px-4">
<div className="lg:grid lg:grid-cols-2 lg:gap-16">
<div className="mx-auto max-w-md px-6 sm:max-w-2xl sm:text-center lg:flex lg:items-center lg:px-0 lg:text-left">
<div className="lg:py-24">
<div className="hidden sm:mb-5 sm:flex sm:justify-center lg:justify-start">
</div>
<h1 className="text-xl font-medium tracking-tight text-white lg:text-5xl">
<span className="block">Build on a Decentralized Internet Infrastructure</span>
</h1>
<p className="mt-3 text-base text-gray-700 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
Our unique technology enables anyone to become a provider of network, storage and compute capacity.
</p>
<div className="mt-10 sm:mt-12">
<Button color="gradient" href="https://docs.threefold.io/docs/introduction/">Dive Deeper</Button>
</div>
</div>
</div>
<div className="mt-12 -mb-16 sm:-mb-48 lg:relative lg:m-0 flex items-center justify-center">
<div className="mx-auto max-w-md px-6 sm:max-w-2xl lg:max-w-none lg:px-0">
{/* Illustration taken from Lucid Illustrations: https://lucid.pixsellz.io/ */}
<img
alt=""
src="/images/build.svg"
className="w-full lg:h-full lg:w-auto lg:max-w-none transform lg:scale-110"
/>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
)
}

View File

@@ -0,0 +1,163 @@
"use client";
import { Button } from "./Button";
import Image from "next/image";
import {
CpuChipIcon,
CircleStackIcon,
CurrencyDollarIcon,
ShareIcon,
ShieldCheckIcon,
LinkIcon,
ServerStackIcon,
WifiIcon,
ComputerDesktopIcon,
UsersIcon,
DevicePhoneMobileIcon,
} from "@heroicons/react/24/solid";
const posts = [
{
id: 1,
title: 'ZERO-OS V3',
href: '#',
description1:
'A stateless and lightweight operating system that allows for an improved efficiency of up to 10x for certain workloads.',
description2: '',
icon: <CpuChipIcon className="h-6 w-6 text-white" />,
},
{
id: 2,
title: 'MYCELIUM NETWORK',
href: '#',
description1: 'Decentralized communication layer of TF Grid that connects and coordinates nodes on the ThreeFold Grid, enabling secure and efficient peer-to-peer interactions.',
description2: '',
icon: <ShareIcon className="h-6 w-6 text-white" />,
},
{
id: 3,
title: 'QUANTUM SAFE STORAGE',
href: '#',
description1:
'QSS is a decentralized, globally distributed data storage system. It is unbreakable, self-healing, append-only, and immutable.',
description2: '',
icon: <ShieldCheckIcon className="h-6 w-6 text-white" />,
},
{
id: 4,
title: 'TF CHAIN',
href: '#',
description1:
'An application-specific blockchain customized for the operation of a single application provisioning decentralized compute, storage, and network capacity.',
description2: '',
icon: <LinkIcon className="h-6 w-6 text-white" />,
},
{
id: 5,
title: '3NODES',
href: '#',
description1:
'Decentralized, user-owned hardware devices that provides computing, storage, and networking resources to power the TF Grid.',
description2: '',
icon: <ServerStackIcon className="h-6 w-6 text-white" />,
},
{
id: 6,
title: 'GATEWAY NODES',
href: '#',
description1:
'Specialized nodes that provide secure access points to the ThreeFold Grid, enabling decentralized networking, private data communication, and seamless interaction between users and applications.',
description2: '',
icon: <WifiIcon className="h-6 w-6 text-white" />,
},
{
id: 7,
title: 'TF DASHBOARD',
href: '#',
description1:
'A user-friendly interface for monitoring, managing, and deploying resources on the ThreeFold Grid.',
description2: '',
icon: <ComputerDesktopIcon className="h-6 w-6 text-white" />,
},
{
id: 8,
title: 'TF DAO',
href: '#',
description1:
'A community-driven governance model that allows farmers to participate in decision-making processes related to the development and direction of the ThreeFold ecosystem.',
description2: '',
icon: <UsersIcon className="h-6 w-6 text-white" />,
},
{
id: 9,
title: 'TF CONNECT APP',
href: '#',
description1:
'A mobile app that serves as a gateway to the ThreeFold ecosystem and its various ThreeFold products and services.',
description2: '',
icon: <DevicePhoneMobileIcon className="h-6 w-6 text-white" />,
},
]
export default function BuildStack() {
return (
<section className="w-full bg-transparent px-4 py-8 sm:px-6 mt-12 sm:pb-12 lg:px-8 relative">
{/* Gradient Blob Component */}
<div className="absolute w-[400px] h-[200px] bg-gradient-to-br from-[#535353] to-[#7e7e7e] opacity-60 rounded-full blur-[150px] bottom-[200px] left-[-150px] z-0" />
<div className="absolute w-[200px] h-[100px] bg-gradient-to-br from-[#505050] to-[#7e7e7e] opacity-50 rounded-full blur-[150px] top-[200px] right-[-150px] z-0" />
<div className="mx-auto max-w-7xl">
<div className="lg:flex lg:items-center lg:justify-between lg:px-8">
{/* Left Column - Text (1/3 width) */}
<div className="lg:col-span-1 flex max text-center lg:text-left order-1 lg:order-1">
<div className="max-w-xl">
<h2 className="text-xl sm:text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl">
The ThreeFold Stack
</h2>
<p className="mt-3 text-base text-gray-700 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
Products designed to power a decentralized, sustainable digital future.
</p>
</div>
</div>
{/* Right Column - Stacked Cubes (2/3 width) */}
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start order-2 lg:order-2">
<Button variant="outline">
Become A Farmer
</Button>
</div>
</div>
<div className="mx-auto mt-10 grid max-w-2xl h-3/4 grid-cols-1 gap-8 lg:mt-10 lg:mx-0 lg:max-w-none lg:grid-cols-3">
{posts.map((post) => (
<article
key={post.id}
className="relative isolate flex flex-col justify-end overflow-hidden rounded-2xl bg-stat-gradient p-8"
>
<div className="absolute inset-0 -z-10 bg-linear-to-t from-gray-200 via-gray-300/10"
style={{
filter: 'brightness(1)',
}}
onMouseEnter={(e) => {
e.currentTarget.style.filter = 'brightness(0.8) drop-shadow(0 0 20px rgba(156, 163, 175, 0.5))';
}}
onMouseLeave={(e) => {
e.currentTarget.style.filter = 'brightness(1)';
}}
>
</div>
<div className="flex items-start gap-x-3 text-lg/6 font-semibold text-white">
{post.icon}
{post.title}
</div>
< div className="max-w-2/3">
<p className="mt-4 text-sm font-light text-gray-700">{post.description1}</p>
<p className=" text-sm font-light text-gray-700">{post.description2}</p>
</div>
</article>
))}
</div>
</div>
</section>
);
}

View File

@@ -4,6 +4,8 @@ import clsx from 'clsx'
const baseStyles = {
solid:
'inline-flex justify-center rounded-lg py-2 px-3 text-sm font-semibold transition-colors',
glass:
'rounded-md bg-white/10 px-3.5 py-2.5 text-sm font-semibold text-white hover:bg-white/15',
outline:
'inline-flex justify-center rounded-lg border py-[calc(--spacing(2)-1px)] px-[calc(--spacing(3)-1px)] text-sm transition-colors',
}
@@ -11,14 +13,14 @@ const baseStyles = {
const variantStyles = {
solid: {
gradient:
'bg-gradient-to-r from-[#caa5f0] via-[#8f79f9] to-[#3c82f5] text-white hover:brightness-110 active:brightness-95',
'btn-new-gradient',
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',
white:
'bg-white text-cyan-900 hover:bg-white/90 active:bg-white/90 active:text-cyan-900/70',
'bg-white text-black hover:bg-white/90 active:bg-white/90 active:text-gray-400',
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:border-gray-600 hover:text-white active:bg-gray-100 active:text-gray-600/80',
},
}
@@ -27,6 +29,9 @@ type ButtonProps = (
variant?: 'solid'
color?: keyof typeof variantStyles.solid
}
| {
variant: 'glass'
}
| {
variant: 'outline'
color?: keyof typeof variantStyles.outline
@@ -41,15 +46,22 @@ type ButtonProps = (
export function Button({ className, ...props }: ButtonProps) {
props.variant ??= 'solid'
props.color ??= 'gray'
if (props.variant !== 'glass') {
props.color ??= 'gray'
}
let variantClass: string | undefined = undefined
if (props.variant === 'outline' && props.color) {
variantClass = variantStyles.outline[props.color]
} else if (props.variant === 'solid' && props.color) {
variantClass = variantStyles.solid[props.color]
}
className = clsx(
baseStyles[props.variant],
props.variant === 'outline'
? variantStyles.outline[props.color]
: props.variant === 'solid'
? variantStyles.solid[props.color]
: undefined,
variantClass,
className,
)

47
src/components/CallTo.tsx Normal file
View File

@@ -0,0 +1,47 @@
export function CallTo() {
return (
<div className="bg-transparent">
<div className="mx-auto max-w-7xl py-24 px-6 lg:px-4">
<div className="relative isolate overflow-hidden bg-stat-gradient py-16 text-center after:pointer-events-none after:absolute after:inset-0 sm:rounded-3xl sm:px-16">
<div className="mx-auto max-w-2xl lg:max-w-2xl">
<h2 className="text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl">
More Resilient, More Powerful, More Diverse With You
</h2>
<p className="mx-auto mt-6 max-w-xl text-sm font-light text-pretty text-white lg:text-base">
Unlike the corporate internet, where users are the product, in the new internet, participants are the owners and beneficiaries.
</p>
<p className="mx-auto mt-6 max-w-xl text-sm font-light text-pretty text-white lg:text-base">
By participating, you're not just using the technology, you're also helping to build a digital world that protects privacy, promotes fairness, and returns control to the people.
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
<a
href="#"
className="rounded-md bg-white/10 px-3.5 py-2.5 text-sm font-semibold text-white hover:bg-white/15"
>
{' '}
Get started{' '}
</a>
<a href="#" className="text-sm/6 font-semibold text-white">
Learn more
<span aria-hidden="true"></span>
</a>
</div>
<svg
viewBox="0 0 1024 1024"
aria-hidden="true"
className="absolute top-1/2 left-1/2 -z-10 size-256 -translate-x-1/2 mask-[radial-gradient(closest-side,white,transparent)]"
>
<circle r={512} cx={512} cy={512} fill="url(#827591b1-ce8c-4110-b064-7cb85a0b1217)" fillOpacity="0.7" />
<defs>
<radialGradient id="827591b1-ce8c-4110-b064-7cb85a0b1217">
<stop stopColor="#fff4f8" />
<stop offset={1} stopColor="#97979d" />
</radialGradient>
</defs>
</svg>
</div>
</div>
</div>
</div>
)
}

View File

@@ -1,13 +1,13 @@
export default function Cta() {
return (
<div className="bg-white">
<div style={{ backgroundColor: '#121212' }}>
<div className="mx-auto max-w-7xl py-24 sm:px-6 sm:py-32 lg:px-8">
<div className="relative isolate overflow-hidden bg-gray-900 px-6 py-24 text-center shadow-2xl sm:rounded-3xl sm:px-16">
<h2 className="text-4xl font-semibold tracking-tight text-balance text-white sm:text-5xl">
Scale Your Impact, Not Your Costs
</h2>
<p className="mx-auto mt-6 max-w-xl text-lg/8 text-pretty text-gray-300">
EngageOS gives purpose-driven teams the power to mobilize communities, grow movements, and fundraise faster
ThreeFold gives purpose-driven teams the power to mobilize communities, grow movements, and fundraise faster
all from one unified platform.
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
@@ -30,9 +30,9 @@ export default function Cta() {
<circle r={512} cx={512} cy={512} fill="url(#engage-gradient)" fillOpacity="0.7" />
<defs>
<radialGradient id="engage-gradient">
<stop offset="0%" stop-color="#caa5f0" />
<stop offset="50%" stop-color="#8f79f9" />
<stop offset="100%" stop-color="#5d84e1" />
<stop offset="0%" stopColor="#caa5f0" />
<stop offset="50%" stopColor="#8f79f9" />
<stop offset="100%" stopColor="#5d84e1" />
</radialGradient>
</defs>

View File

@@ -0,0 +1,119 @@
"use client";
import CountUp from "react-countup";
import React from "react";
import { Button } from "./Button";
export function Dashboard() {
return (
<div className="py-24 bg-transparent relative">
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8">
<div className="grid grid-cols-1 gap-8 lg:grid-cols-3">
{/* Column 1: Title & NODES */}
<div className="flex flex-col space-y-10">
{/* Title + Description */}
<div>
<h2 className="text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl">
Powered by a Global Community
</h2>
<p className="mt-4 sm:mt-6 text-sm font-light text-pretty text-white lg:text-base">
ThreeFolds groundbreaking technology enables anyone individuals, organizations, and communities to deploy their own Internet infrastructure.
</p>
<Button className="mt-8" variant="outline" href="https://threefold.io/build" >Explore TFGrid </Button>
</div>
</div>
{/* Column 2: CORES (staggered) + SSD */}
<div className="flex flex-col space-y-10">
<StatCard
label="CORES"
description="A globally distributed mesh of CPU cores powering decentralized applications, AI workloads, and edge computing — without central bottlenecks."
value={<CountUp end={54_958} duration={2.5} separator="," />}
note="Total Central Processing Unit Cores available on the grid."
className="mt-24"
/>
<StatCard
label="SSD CAPACITY"
description="A distributed network of storage capacity — ready to support Web3, AI, and edge computing workloads around the world."
value={<CountUp end={7_364_506} duration={2.5} separator="," />}
unit="GB"
note="The total amount of storage (SSD, HDD, & RAM) on the grid."
/>
</div>
{/* Column 3: nodes countries */}
<div className="flex flex-col space-y-10 justify-start">
<StatCard
label="NODES"
description="A computer server 100% dedicated to the network. It is a building block of the ThreeFold Grid, providing compute, storage, and network resources."
value={<CountUp end={1778} duration={2.5} separator="," />}
note="The total number of nodes on the grid."
/>
<StatCard
label="COUNTRIES"
description="The number of countries where at least one node is connected and operational on the grid."
value={<CountUp end={51} duration={2.5} separator="," />}
note="The total number of countries with active nodes."
/>
</div>
</div>
</div>
</div>
);
}
// 🧱 Stat Card Component
function StatCard({
label,
description,
value,
unit,
note,
className = "",
}: {
label: string;
description: string;
value: React.ReactNode;
unit?: string;
note: string;
className?: string;
}) {
return (
<div
className={`relative flex flex-col overflow-hidden rounded-2xl bg-stat-gradient p-8 transition-all duration-300 ease-out hover:scale-105 ${className}`}
style={{
filter: 'brightness(1)',
}}
onMouseEnter={(e) => {
e.currentTarget.style.filter = 'brightness(0.8)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.filter = 'brightness(1)';
}}
>
<h3 className="text-lg font-semibold text-gradient-neutral-vertical" style={{ textShadow: '0 0 12px rgba(255, 255, 255, 0.4), 0 0 24px rgba(255, 255, 255, 0.2)' }}>{label}</h3>
<p className="mt-2 text-sm font-light text-pretty text-white lg:text-base">
{description}
</p>
<div className="mt-8 flex items-center space-x-3">
<span className="text-gradient-neutral-vertical text-3xl"></span>
<div className="text-5xl font-semibold tracking-tight text-white tabular-nums">
{value}
{unit && (
<span className="ml-2 text-lg font-normal text-gray-400">{unit}</span>
)}
</div>
</div>
<p className="mt-2 text-sm text-gray-400 uppercase tracking-wider">
{note}
</p>
</div>
);
}

63
src/components/Faq.tsx Normal file
View File

@@ -0,0 +1,63 @@
const faqs = [
{
question: 'Is this a separate new Internet?',
answer: 'ThreeFold creates a decentralized internet infrastructure that can operate independently, offering alternatives to traditional centralized systems while maintaining compatibility with existing internet protocols.',
},
{
question: 'Why do we need a new Internet?',
answer: 'The current internet is increasingly centralized and controlled by few entities. ThreeFold provides a more democratic, private, and secure alternative where users and developers have full control over their data and applications.',
},
{
question: 'How can I participate?',
answer: 'You can participate by becoming a farmer, a user, a partner or by developing apps. Provide capacity to the ThreeFold Grid, Use capacity, build solutions, develop applications, and many more.',
},
{
question: 'How can I get V4 nodes?',
answer: 'Our partners are selling V4 nodes with a new reward scheme and ready to grow to millions of nodes. Click here to get V4 nodes.',
},
{
question: 'What can I do with the ThreeFold Grid?',
answer: 'ThreeFold grid can be used to host any web2, web3 and future workload. For more details see our docs.',
},
{
question: 'How secure and private is my data?',
answer: 'ThreeFold is designed to be secure and private by default. We use end-to-end encryption to protect your data and ensure that only you have access to your data.',
},
{
question: 'Who should use the ThreeFold Grid?',
answer: 'Individuals, businesses, and organizations who want to be autonomous and have full control over their data and applications. Security is a very big problem today, Technology as used by ThreeFold has the potential to resolve this if used properly. We are building a channel of solution providers and integrators who want to build on top of ThreeFold.',
},
]
export function Faq () {
return (
<div className="bg-transparent">
<div className="mx-auto max-w-7xl px-6 py-24 sm:pt-32 lg:px-8 lg:py-40">
<div className="lg:grid lg:grid-cols-12 lg:gap-8">
<div className="lg:col-span-5">
<h2 className="text-3xl font-semibold tracking-tight text-pretty text-white sm:text-4xl">
Frequently asked questions
</h2>
<p className="mt-4 text-base/7 text-pretty text-gray-400">
Cant find the answer youre looking for? Reach out to our{' '}
<a href="#" className="font-semibold text-indigo-400 hover:text-indigo-300">
customer support
</a>{' '}
team.
</p>
</div>
<div className="mt-10 lg:col-span-7 lg:mt-0">
<dl className="space-y-10">
{faqs.map((faq) => (
<div key={faq.question}>
<dt className="text-base/7 font-semibold text-white">{faq.question}</dt>
<dd className="mt-2 text-base/7 text-gray-400">{faq.answer}</dd>
</div>
))}
</dl>
</div>
</div>
</div>
</div>
)
}

View File

@@ -3,48 +3,48 @@ import { Container } from '@/components/Container'
const faqs = [
[
{
question: 'What is EngageOS?',
question: 'What is ThreeFold?',
answer:
'EngageOS is a white-label engagement platform built specifically for purpose-driven organizations. It allows NGOs, foundations, and impact coalitions to launch their own branded platforms to engage communities, deliver training, and mobilize support.',
'ThreeFold is a white-label engagement platform built specifically for purpose-driven organizations. It allows NGOs, foundations, and impact coalitions to launch their own branded platforms to engage communities, deliver training, and mobilize support.',
},
{
question: 'Do I need a tech team to use EngageOS?',
question: 'Do I need a tech team to use ThreeFold?',
answer:
'No. EngageOS is fully plug-and-play. Its designed so any organization—regardless of technical capacity—can deploy and customize their own platform without writing a line of code.',
'No. ThreeFold is fully plug-and-play. Its designed so any organization—regardless of technical capacity—can deploy and customize their own platform without writing a line of code.',
},
{
question: 'Can we fully customize the platforms look and feel?',
answer:
'Absolutely. From logos and colors to navigation and community features, EngageOS supports full white-label customization so the platform feels like your own digital headquarters.',
'Absolutely. From logos and colors to navigation and community features, ThreeFold supports full white-label customization so the platform feels like your own digital headquarters.',
},
],
[
{
question: 'What kinds of organizations use EngageOS?',
question: 'What kinds of organizations use ThreeFold?',
answer:
'We work with NGOs, educational networks, development agencies, faith-based groups, and mission-aligned coalitions that want to better engage, train, and mobilize their communities at scale.',
},
{
question: 'Is EngageOS multilingual and accessible offline?',
question: 'Is ThreeFold multilingual and accessible offline?',
answer:
'Yes. The platform supports multilingual content and offline-friendly delivery—ideal for reaching underserved communities with limited connectivity.',
},
{
question: 'Can we use EngageOS for fundraising?',
question: 'Can we use ThreeFold for fundraising?',
answer:
'Yes. EngageOS includes built-in fundraising tools, including peer-to-peer, micro-donation, and pay-it-forward models—plus full donor engagement capabilities.',
'Yes. ThreeFold includes built-in fundraising tools, including peer-to-peer, micro-donation, and pay-it-forward models—plus full donor engagement capabilities.',
},
],
[
{
question: 'How is EngageOS different from other platforms?',
question: 'How is ThreeFold different from other platforms?',
answer:
'Unlike general-purpose platforms, EngageOS is mission-built for civil society. It integrates engagement, learning, and fundraising in one secure, ethical platform—hosted on sovereign infrastructure.',
'Unlike general-purpose platforms, ThreeFold is mission-built for civil society. It integrates engagement, learning, and fundraising in one secure, ethical platform—hosted on sovereign infrastructure.',
},
{
question: 'What is the pricing model?',
answer:
'EngageOS operates on a flexible SaaS model, with plans ranging from €30K to €300K annually depending on features and user scale. For grassroots initiatives, pay-it-forward and sponsorship models are also available.',
'ThreeFold operates on a flexible SaaS model, with plans ranging from €30K to €300K annually depending on features and user scale. For grassroots initiatives, pay-it-forward and sponsorship models are also available.',
},
{
question: 'How do we get started?',
@@ -55,7 +55,7 @@ const faqs = [
]
export function Faqs() {
export function Faqss () {
return (
<section
id="faqs"
@@ -66,14 +66,14 @@ export function Faqs() {
<div className="mx-auto max-w-2xl lg:mx-0">
<h2
id="faqs-title"
className="text-3xl font-medium tracking-tight text-gray-900"
className="text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl"
>
Frequently asked questions
</h2>
<p className="mt-2 lg:text-lg text-base text-gray-600">
If you have anything else you want to ask,{' '}
<a
href="mailto:info@example.com"
href="mailto:info@threefold.io"
className="text-gray-900 underline"
>
reach out to us
@@ -83,7 +83,7 @@ export function Faqs() {
</div>
<ul
role="list"
className="mx-auto mt-16 grid max-w-2xl grid-cols-1 gap-8 sm:mt-20 lg:max-w-none lg:grid-cols-3"
className="mx-auto mt-12 grid max-w-2xl grid-cols-1 gap-8 lg:max-w-none lg:grid-cols-3"
>
{faqs.map((column, columnIndex) => (
<li key={columnIndex}>

102
src/components/Farmer.tsx Normal file
View File

@@ -0,0 +1,102 @@
"use client";
import { Button } from "./Button";
import Image from "next/image";
import { CpuChipIcon } from "@heroicons/react/24/solid";
import { CircleStackIcon } from "@heroicons/react/24/solid";
import { CurrencyDollarIcon } from "@heroicons/react/24/solid";
const posts = [
{
id: 1,
title: 'Host A Node',
href: '#',
description1:
'All you need to get started is a modern computer, electricity and network. Once booted with Zero OS, a computer becomes a ThreeFold Node.',
description2: '',
imageUrl:
'./images/3nodes.png',
icon: <CpuChipIcon className="h-6 w-6 text-white" />,
},
{
id: 2,
title: 'Offer Capacity',
href: '#',
description1: 'The capacity of the node gets registered on the ThreeFold Blockchain and is available for users on the TF Marketplace.',
description2: '',
imageUrl:
'./images/capacity.png',
icon: <CircleStackIcon className="h-6 w-6 text-white" />,
},
{
id: 3,
title: 'Earn Rewards',
href: '#',
description1:
'Farmers earn rewards for their used resources, enabling a fair and transparent peer-to-peer economy.',
description2: '',
imageUrl:
'./images/rewards.png',
icon: <CurrencyDollarIcon className="h-6 w-6 text-white" />,
},
]
export function FarmerPreview() {
return (
<section className="w-full bg-transparent px-4 py-8 sm:px-6 mt-12 sm:pb-12 lg:px-8 relative">
{/* Gradient Blob Component */}
<div className="absolute w-[400px] h-[200px] bg-gradient-to-br from-[#535353] to-[#7e7e7e] opacity-60 rounded-full blur-[150px] bottom-[200px] left-[-150px] z-0" />
<div className="absolute w-[200px] h-[100px] bg-gradient-to-br from-[#505050] to-[#7e7e7e] opacity-50 rounded-full blur-[150px] top-[200px] right-[-150px] z-0" />
<div className="mx-auto max-w-7xl">
<div className="lg:flex lg:items-center lg:justify-between lg:px-8">
{/* Left Column - Text (1/3 width) */}
<div className="lg:col-span-1 flex max text-center lg:text-left order-1 lg:order-1">
<div className="max-w-xl">
<h2 className="text-xl sm:text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl">
Contribute to the Decentralized Internet in 3 Steps
</h2>
</div>
</div>
{/* Right Column - Stacked Cubes (2/3 width) */}
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start order-2 lg:order-2">
<Button variant="outline">
Become A Farmer
</Button>
</div>
</div>
<div className="mx-auto mt-10 grid max-w-2xl h-3/4 grid-cols-1 gap-8 lg:mt-10 lg:mx-0 lg:max-w-none lg:grid-cols-3">
{posts.map((post) => (
<article
key={post.id}
className="relative isolate flex flex-col justify-end overflow-hidden rounded-2xl bg-stat-gradient px-8 lg:pt-12"
>
<div className="absolute inset-0 -z-10 bg-linear-to-t from-gray-200 via-gray-300/10"
style={{
filter: 'brightness(1)',
}}
onMouseEnter={(e) => {
e.currentTarget.style.filter = 'brightness(0.8) drop-shadow(0 0 20px rgba(156, 163, 175, 0.5))';
}}
onMouseLeave={(e) => {
e.currentTarget.style.filter = 'brightness(1)';
}}
>
</div>
<div className="mt-12 flex items-start gap-x-3 text-lg/6 font-semibold text-white">
{post.icon}
{post.title}
</div>
< div className="max-w-2/3">
<p className="mt-4 text-sm font-light text-gray-700">{post.description1}</p>
<p className=" text-sm font-light text-gray-700">{post.description2}</p>
</div>
<img alt="" src={post.imageUrl} className="w-1/2 h-full translate-x-20 -translate-32 transform object-cover object-top-left lg:translate-x-50 lg:-translate-20 opacity-70 hover:opacity-95" />
</article>
))}
</div>
</div>
</section>
);
}

View File

@@ -6,7 +6,6 @@ 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 (
@@ -22,40 +21,23 @@ function QrCodeBorder(props: React.ComponentPropsWithoutRef<'svg'>) {
export function Footer() {
return (
<footer className="border-t border-gray-200">
<footer className="border-t border-gray-700" style={{ backgroundColor: '#121212' }}>
<Container>
<div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-16">
<div>
<div className="flex items-center text-gray-900">
<div className="flex items-center text-white">
<Logomark className="h-10 w-10 flex-none fill-cyan-500" />
<div className="ml-4">
<p className="text-base font-semibold">EngageOS</p>
<p className="mt-1 text-sm">Empowering Purpose-Driven Organizations.</p>
<p className="text-base font-semibold">ThreeFold</p>
<p className="mt-1 text-sm">Decentralized internet infrastructure by everyone, for everyone.</p>
</div>
</div>
<nav className="mt-11 flex gap-8">
<nav className="mt-8 flex gap-8">
<NavLinks />
</nav>
</div>
<div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-100 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6">
<div className="relative flex h-24 w-24 flex-none items-center justify-center">
<QrCodeBorder className="absolute inset-0 h-full w-full stroke-gray-300 transition-colors group-hover:stroke-cyan-500" />
<Image src={qrCode} alt="" unoptimized />
</div>
<div className="ml-8 lg:w-64">
<p className="text-base font-semibold text-gray-900">
<Link href="#">
<span className="absolute inset-0 sm:rounded-2xl" />
Download the app
</Link>
</p>
<p className="mt-1 text-sm text-gray-700">
Scan the QR code to download the app from the App Store.
</p>
</div>
</div>
</div>
<div className="flex flex-col items-center border-t border-gray-200 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-700 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6">
<form className="flex w-full justify-center md:w-auto">
<TextField
type="email"
@@ -65,12 +47,12 @@ export function Footer() {
required
className="w-60 min-w-0 shrink"
/>
<Button type="submit" color="cyan" className="ml-4 flex-none">
<Button type="submit" variant='glass' className="ml-4 flex-none">
<span className="hidden lg:inline">Join our newsletter</span>
<span className="lg:hidden">Join newsletter</span>
</Button>
</form>
<p className="mt-6 text-sm text-gray-500 md:mt-0">
<p className="mt-6 text-sm text-gray-400 md:mt-0">
&copy; Copyright {new Date().getFullYear()}. All rights reserved.
</p>
</div>

View File

@@ -0,0 +1,43 @@
import Image from 'next/image'
const images = [
'/images/people/abdulrahman_elawady.jpg',
'/images/people/adnan_fatayerji.jpg',
'/images/people/ahmed_hanafy.jpg',
'/images/people/ahmed_thabet.jpg',
'/images/people/alaa_mahmoud.jpg',
'/images/people/alexandre_hannelas.jpeg',
'/images/people/amira_abouhadid.jpg',
'/images/people/ashraf_fouda.jpeg',
'/images/people/atef_nazmy.jpg',
'/images/people/bernadette_amanda_caster.jpg',
'/images/people/cameron_ramraichan_labeyrie.jpg',
'/images/people/ehab_hassan.jpg',
'/images/people/eslam_nawara.jpg',
'/images/people/evon_yacoub.jpg',
'/images/people/florian_fournier.jpeg',
'/images/people/gregory_flipo.jpg',
'/images/people/jan_de_landtsheer.jpeg',
'/images/people/karoline_zizka.jpeg',
'/images/people/khaled.jpg',
'/images/people/kristof_de_spiegeleer.jpeg',
].sort(() => Math.random() - 0.5) // Shuffle the array
export function Gallery() {
return (
<div className="hidden lg:absolute lg:inset-y-0 lg:left-0 lg:block lg:w-1/2">
<div className="grid h-full grid-cols-5 grid-rows-4">
{images.map((src, index) => (
<Image
key={index}
src={src}
alt={`Team member ${index + 1}`}
width={129}
height={129}
className="object-cover"
/>
))}
</div>
</div>
)
}

121
src/components/Globe.tsx Normal file
View File

@@ -0,0 +1,121 @@
"use client";
import createGlobe, { COBEOptions } from "cobe";
import { useMotionValue, useSpring } from "framer-motion";
import { useEffect, useRef } from "react";
const MOVEMENT_DAMPING = 1400;
const GLOBE_CONFIG: COBEOptions = {
width: 800,
height: 800,
onRender: () => {},
devicePixelRatio: 2,
phi: 0,
theta: 0.3,
dark: 1,
diffuse: 1.2,
mapSamples: 16000,
mapBrightness: 0.5,
baseColor: [1, 1, 1], // tailwind gray-700
markerColor: [1, 1, 1], // white dots
glowColor: [0.6, 0.6, 0.6],
markers: [
{ location: [14.5995, 120.9842], size: 0.03 },
{ location: [19.076, 72.8777], size: 0.1 },
{ location: [23.8103, 90.4125], size: 0.05 },
{ location: [30.0444, 31.2357], size: 0.07 },
{ location: [39.9042, 116.4074], size: 0.08 },
{ location: [-23.5505, -46.6333], size: 0.1 },
{ location: [19.4326, -99.1332], size: 0.1 },
{ location: [40.7128, -74.006], size: 0.1 },
{ location: [34.6937, 135.5022], size: 0.05 },
{ location: [41.0082, 28.9784], size: 0.06 },
],
};
export function Globe({
className,
config = GLOBE_CONFIG,
}: {
className?: string;
config?: COBEOptions;
}) {
let phi = 0;
let width = 0;
const canvasRef = useRef<HTMLCanvasElement>(null);
const pointerInteracting = useRef<number | null>(null);
const pointerInteractionMovement = useRef(0);
const r = useMotionValue(0);
const rs = useSpring(r, {
mass: 1,
damping: 30,
stiffness: 100,
});
const updatePointerInteraction = (value: number | null) => {
pointerInteracting.current = value;
if (canvasRef.current) {
canvasRef.current.style.cursor = value !== null ? "grabbing" : "grab";
}
};
const updateMovement = (clientX: number) => {
if (pointerInteracting.current !== null) {
const delta = clientX - pointerInteracting.current;
pointerInteractionMovement.current = delta;
r.set(r.get() + delta / MOVEMENT_DAMPING);
}
};
useEffect(() => {
const onResize = () => {
if (canvasRef.current) {
width = canvasRef.current.offsetWidth;
}
};
window.addEventListener("resize", onResize);
onResize();
const globe = createGlobe(canvasRef.current!, {
...config,
width: width * 2,
height: width * 2,
onRender: (state) => {
if (!pointerInteracting.current) phi += 0.005;
state.phi = phi + rs.get();
state.width = width * 2;
state.height = width * 2;
},
});
setTimeout(() => (canvasRef.current!.style.opacity = "1"), 0);
return () => {
globe.destroy();
window.removeEventListener("resize", onResize);
};
}, [rs, config]);
return (
<div
className={`absolute inset-0 mx-auto aspect-[1/1] w-full max-w-[600px] ${className}`}
>
<canvas
className="size-full opacity-0 transition-opacity duration-500 [contain:layout_paint_size]"
ref={canvasRef}
onPointerDown={(e) => {
pointerInteracting.current = e.clientX;
updatePointerInteraction(e.clientX);
}}
onPointerUp={() => updatePointerInteraction(null)}
onPointerOut={() => updatePointerInteraction(null)}
onMouseMove={(e) => updateMovement(e.clientX)}
onTouchMove={(e) =>
e.touches[0] && updateMovement(e.touches[0].clientX)
}
/>
</div>
);
}

View File

@@ -0,0 +1,9 @@
import { Globe } from "@/components/Globe";
export default function GlobeDemo() {
return (
<main className="relative min-h-screen bg-transparent flex items-center justify-center">
<Globe />
</main>
);
}

View File

@@ -49,7 +49,7 @@ function MobileNavLink(
return (
<PopoverButton
as={Link}
className="block text-base/7 tracking-tight text-gray-700"
className="block text-base/7 tracking-tight text-gray-300"
{...props}
/>
)
@@ -59,7 +59,7 @@ export function Header() {
return (
<header>
<nav>
<Container className="relative z-50 flex justify-between py-8">
<Container className="relative z-50 flex justify-between py-4">
<div className="relative z-10 flex items-center gap-16">
<Link href="/" aria-label="Home">
<Logo className="h-10 w-auto" />
@@ -73,7 +73,7 @@ export function Header() {
{({ open }) => (
<>
<PopoverButton
className="relative z-10 -m-2 inline-flex items-center rounded-lg stroke-gray-900 p-2 hover:bg-gray-200/50 hover:stroke-gray-600 focus:not-data-focus:outline-hidden active:stroke-gray-900"
className="relative z-10 -m-2 inline-flex items-center rounded-lg stroke-white p-2 hover:bg-transparent hover:stroke-gray-200 focus:not-data-focus:outline-hidden active:stroke-white"
aria-label="Toggle site navigation"
>
{({ open }) =>
@@ -93,7 +93,7 @@ export function Header() {
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 z-0 bg-gray-300/60 backdrop-blur-sm"
className="fixed inset-0 z-0 bg-black/60 backdrop-blur-sm"
/>
<PopoverPanel
static
@@ -134,9 +134,11 @@ export function Header() {
</Popover>
<div className="flex items-center gap-6 max-lg:hidden">
<Button href="/login" variant="outline">
Log in
Info
</Button>
<Button href="#" variant="glass">
Participate
</Button>
<Button href="#">Download</Button>
</div>
</div>
</Container>

View File

@@ -6,6 +6,7 @@ import { AppDemo } from '@/components/AppDemo'
import { AppStoreLink } from '@/components/AppStoreLink'
import HeroHome from './HeroHome'
import { Button } from '@/components/Button'
import { BackgroundIllustration } from '@/components/BackgroundIllustration'
import { Container } from '@/components/Container'
import { PhoneFrame } from '@/components/PhoneFrame'
import logoBbc from '@/images/logos/bbc.svg'
@@ -17,75 +18,6 @@ import logoHuffpost from '@/images/logos/huffpost.svg'
import logoTechcrunch from '@/images/logos/techcrunch.svg'
import logoWired from '@/images/logos/wired.svg'
function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
let id = useId()
return (
<div {...props}>
<svg
viewBox="0 0 1026 1026"
fill="none"
aria-hidden="true"
className="absolute inset-0 h-full w-full animate-spin-slow"
>
<path
d="M1025 513c0 282.77-229.23 512-512 512S1 795.77 1 513 230.23 1 513 1s512 229.23 512 512Z"
stroke="#D4D4D4"
strokeOpacity="0.7"
/>
<path
d="M513 1025C230.23 1025 1 795.77 1 513"
stroke={`url(#${id}-gradient-1)`}
strokeLinecap="round"
/>
<defs>
<linearGradient
id={`${id}-gradient-1`}
x1="1"
y1="513"
x2="1"
y2="1025"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#06b6d4" />
<stop offset="1" stopColor="#06b6d4" stopOpacity="0" />
</linearGradient>
</defs>
</svg>
<svg
viewBox="0 0 1026 1026"
fill="none"
aria-hidden="true"
className="absolute inset-0 h-full w-full animate-spin-reverse-slower"
>
<path
d="M913 513c0 220.914-179.086 400-400 400S113 733.914 113 513s179.086-400 400-400 400 179.086 400 400Z"
stroke="#D4D4D4"
strokeOpacity="0.7"
/>
<path
d="M913 513c0 220.914-179.086 400-400 400"
stroke={`url(#${id}-gradient-2)`}
strokeLinecap="round"
/>
<defs>
<linearGradient
id={`${id}-gradient-2`}
x1="913"
y1="513"
x2="913"
y2="913"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#06b6d4" />
<stop offset="1" stopColor="#06b6d4" stopOpacity="0" />
</linearGradient>
</defs>
</svg>
</div>
)
}
function PlayIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" {...props}>

View File

@@ -4,6 +4,7 @@ import Image from 'next/image'
import { Button } from './Button'
import Engage from '@/images/engage.svg'
import { gradientText, gradientDark } from '@/components/Gradients'
import { h1 as H1 } from '@/components/ui/Text'
const navigation = [
{ name: 'Product', href: '#' },
@@ -14,15 +15,15 @@ const navigation = [
export default function HeroHome() {
return (
<div className="bg-white">
<div style={{ backgroundColor: '#121212' }}>
<div className="">
<div className="mx-auto max-w-7xl px-8 lg:px-8">
<div className="mx-auto max-w-3xl text-center">
<h1 className="text-3xl font-medium tracking-tight text-gray-900 lg:text-5xl">
<H1 className="text-white">
Empowering Purpose-Driven Organizations.
</h1>
<p className="mt-8 lg:lg:text-lg text-base text-base text-gray-600">
Welcome to <span className={`font-semibold ${gradientText}`}>EngageOS</span>: the first all-in-one, white-label engagement platform to mobilize communities, engage supporters, scale impact, and fundraiseat a fraction of the cost.
</H1>
<p className="mt-8 lg:lg:text-lg text-base text-gray-300">
Welcome to <span className={`font-semibold ${gradientText}`}>ThreeFold</span>: the first all-in-one, white-label engagement platform to mobilize communities, engage supporters, scale impact, and fundraiseat a fraction of the cost.
</p>
<div className="mt-12 flex items-center justify-center gap-x-6 relative z-10">
<Button color="gradient">Get in Touch</Button>

View File

@@ -1,10 +1,12 @@
import { Footer } from '@/components/Footer'
import { Header } from '@/components/Header'
import { Banner } from '@/components/Banner'
export function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<Header />
<Banner />
<main className="flex-auto">{children}</main>
<Footer />
</>

File diff suppressed because one or more lines are too long

View File

@@ -9,15 +9,14 @@ export function NavLinks() {
let timeoutRef = useRef<number | null>(null)
return [
['Features', '/#features'],
['Reviews', '/#reviews'],
['Pricing', '/#pricing'],
['FAQs', '/#faqs'],
['About', '/about'],
['Build', '/build'],
['Host', '/#pricing'],
].map(([label, href], index) => (
<Link
key={label}
href={href}
className="relative -mx-3 -my-2 rounded-lg px-3 py-2 text-sm text-gray-700 transition-colors delay-150 hover:text-gray-900 hover:delay-0"
className="relative -mx-3 -my-2 rounded-lg px-3 py-2 text-sm text-gray-700 transition-colors delay-150 hover:text-white hover:delay-0"
onMouseEnter={() => {
if (timeoutRef.current) {
window.clearTimeout(timeoutRef.current)
@@ -33,7 +32,7 @@ export function NavLinks() {
<AnimatePresence>
{hoveredIndex === index && (
<motion.span
className="absolute inset-0 rounded-lg bg-gray-100"
className="absolute inset-0 rounded-lg bg-transparent"
layoutId="hoverBackground"
initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { duration: 0.15 } }}

View File

@@ -25,7 +25,7 @@ const plans = [
'Basic learning paths',
'Donations & campaigns',
'Your logo & colors',
'EngageOS subdomain (yourname.engageos.org)',
'ThreeFold subdomain (yourname.ThreeFold.org)',
'Email support',
],
logomarkClassName: 'fill-gray-300',
@@ -126,14 +126,14 @@ function Plan({
return (
<section
className={clsx(
'flex flex-col overflow-hidden rounded-3xl p-6 shadow-lg shadow-gray-900/5',
featured ? 'order-first bg-gray-900 lg:order-none' : 'bg-white',
'flex flex-col overflow-hidden rounded-3xl p-6 shadow-lg shadow-black/20',
featured ? 'order-first bg-cyan-600 lg:order-none' : 'bg-gray-900',
)}
>
<h3
className={clsx(
'flex items-center text-sm font-semibold',
featured ? 'text-white' : 'text-gray-900',
featured ? 'text-white' : 'text-white',
)}
>
<Logomark className={clsx('h-6 w-6 flex-none', logomarkClassName)} />
@@ -142,7 +142,7 @@ function Plan({
<p
className={clsx(
'relative mt-5 flex text-3xl tracking-tight',
featured ? 'text-white' : 'text-gray-900',
featured ? 'text-white' : 'text-white',
)}
>
{price.Monthly === price.Annually ? (
@@ -175,7 +175,7 @@ function Plan({
<p
className={clsx(
'mt-3 text-sm',
featured ? 'text-gray-300' : 'text-gray-700',
featured ? 'text-gray-100' : 'text-gray-300',
)}
>
{description}
@@ -186,8 +186,8 @@ function Plan({
className={clsx(
'-my-2 divide-y text-sm',
featured
? 'divide-gray-800 text-gray-300'
: 'divide-gray-200 text-gray-700',
? 'divide-gray-700 text-gray-100'
: 'divide-gray-700 text-gray-300',
)}
>
{features.map((feature) => (
@@ -195,7 +195,7 @@ function Plan({
<CheckIcon
className={clsx(
'h-6 w-6 flex-none',
featured ? 'text-white' : 'text-cyan-500',
featured ? 'text-white' : 'text-cyan-400',
)}
/>
<span className="ml-4">{feature}</span>
@@ -205,7 +205,7 @@ function Plan({
</div>
<Button
href={button.href}
color={featured ? 'cyan' : 'gray'}
color={featured ? 'white' : 'cyan'}
className="mt-6"
aria-label={`Get started with the ${name} plan for ${price}`}
>
@@ -224,19 +224,20 @@ export function Pricing() {
<section
id="pricing"
aria-labelledby="pricing-title"
className="border-t border-gray-200 bg-white py-24"
className="border-t border-gray-800 py-24"
style={{ backgroundColor: '#121212' }}
>
<Container>
<div className="mx-auto max-w-2xl text-center">
<h2
id="pricing-title"
className="text-3xl font-medium tracking-tight text-gray-900"
className="text-3xl font-medium tracking-tight text-white"
>
Flat pricing, no management fees.
</h2>
<p className="mt-2 lg:text-lg text-base text-gray-600">
Whether youre one person trying to get ahead or a big firm trying
to take over the world, weve got a plan for you.
<p className="mt-2 lg:text-lg text-base text-gray-300">
Whether you're one person trying to get ahead or a big firm trying
to take over the world, we've got a plan for you.
</p>
</div>
@@ -252,7 +253,7 @@ export function Pricing() {
key={period}
value={period}
className={clsx(
'cursor-pointer border border-gray-300 px-[calc(--spacing(3)-1px)] py-[calc(--spacing(2)-1px)] text-sm text-gray-700 transition-colors hover:border-gray-400 data-focus:outline-2 data-focus:outline-offset-2',
'cursor-pointer border border-gray-600 px-[calc(--spacing(3)-1px)] py-[calc(--spacing(2)-1px)] text-sm text-gray-300 transition-colors hover:border-gray-500 data-focus:outline-2 data-focus:outline-offset-2 bg-gray-800',
period === 'Monthly'
? 'rounded-l-lg'
: '-ml-px rounded-r-lg',
@@ -286,7 +287,7 @@ export function Pricing() {
</div>
</div>
<div className="mx-auto bg-white mt-16 grid max-w-2xl grid-cols-1 items-start gap-x-8 gap-y-10 sm:mt-20 lg:max-w-none lg:grid-cols-3">
<div className="mx-auto mt-16 grid max-w-2xl grid-cols-1 items-start gap-x-8 gap-y-10 sm:mt-20 lg:max-w-none lg:grid-cols-3">
{plans.map((plan) => (
<Plan key={plan.name} {...plan} activePeriod={activePeriod} />
))}

View File

@@ -39,7 +39,7 @@ const features = [
{
name: 'Invite friends for better returns',
description:
'For every friend you invite to EngageOS, you get insider notifications 5 seconds sooner. And its 10 seconds if you invite an insider.',
'For every friend you invite to ThreeFold, you get insider notifications 5 seconds sooner. And its 10 seconds if you invite an insider.',
icon: DeviceUserIcon,
screen: InviteScreen,
},
@@ -516,7 +516,11 @@ function FeaturesMobile() {
{features.map((feature, featureIndex) => (
<div
key={featureIndex}
ref={(ref) => ref && (slideRefs.current[featureIndex] = ref)}
ref={(ref) => {
if (ref) {
slideRefs.current[featureIndex] = ref
}
}}
className="w-full flex-none snap-center px-4 sm:px-6"
>
<div className="relative transform overflow-hidden rounded-2xl bg-gray-800 px-5 py-6">
@@ -580,9 +584,9 @@ export function PrimaryFeatures() {
Every feature you need to win. Try it for yourself.
</h2>
<p className="mt-2 lg:text-lg text-base text-gray-400">
EngageOS was built for investors like you who play by their own rules
ThreeFold was built for investors like you who play by their own rules
and arent going to let SEC regulations get in the way of their
dreams. If other investing tools are afraid to build it, EngageOS has
dreams. If other investing tools are afraid to build it, ThreeFold has
it.
</p>
</div>

119
src/components/Products.tsx Normal file
View File

@@ -0,0 +1,119 @@
"use client";
import { Button } from "./Button";
import Image from "next/image";
const products = [
{
id: 1,
colSpan: "lg:col-span-3",
rounded: "rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)] lg:rounded-tl-[calc(2rem+1px)]",
img: "/images/3nodes.png",
title: "3Nodes",
desc: "The backbone of storage and infrastructure, providing compute and data resources.",
color: "indigo-400",
bgRounded: "max-lg:rounded-t-4xl lg:rounded-tl-4xl"
},
{
id: 2,
colSpan: "lg:col-span-3",
rounded: "rounded-[calc(var(--radius-lg)+1px)] lg:rounded-tr-[calc(2rem+1px)]",
img: "/images/mycelium.svg",
title: "Mycelium",
desc: "End-to-end encrypted overlay network, always looking for the shortest possible path between participants",
color: "indigo-400",
bgRounded: "lg:rounded-tr-4xl"
},
{
id: 3,
colSpan: "lg:col-span-2",
rounded: "rounded-[calc(var(--radius-lg)+1px)] lg:rounded-bl-[calc(2rem+1px)]",
img: "/images/aibox.png",
title: "AIBox",
desc: "A self-hosted AI compute solution powered by ThreeFold.",
color: "indigo-400",
bgRounded: "lg:rounded-bl-4xl"
},
{
id: 4,
colSpan: "lg:col-span-2",
rounded: "rounded-[calc(var(--radius-lg)+1px)]",
img: "/images/3phone.png",
title: "3Phone",
desc: "OwnPhone is the first secure device in the 3Phone family designed to work seamlessly with the ThreeFold Grid.",
color: "indigo-400",
bgRounded: ""
},
{
id: 5,
colSpan: "lg:col-span-2",
rounded: "rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-br-[calc(2rem+1px)]",
img: "/images/3router.png",
title: "3Router",
desc: "Smart routers ensure shortest-path connections between nodes and phones with end-to-end encryption.",
color: "indigo-400",
bgRounded: "max-lg:rounded-b-4xl lg:rounded-br-4xl"
}
];
export function ProductsPreview() {
return (
<section className="w-full bg-transparent px-4 py-8 sm:px-6 mt-12 sm:pb-12 lg:px-6 relative">
<div className="mx-auto max-w-7xl">
<div className="lg:flex lg:items-center lg:justify-between lg:px-8">
{/* Left Column - Text (1/3 width) */}
<div className="lg:col-span-1 flex max text-center lg:text-left order-1 lg:order-1">
<div className="max-w-4xl">
<h2 className="text-xl sm:text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl">
Join the Movement to Build a New Internet
</h2>
<p className="mt-4 lg:mt-6 text-sm font-light text-pretty text-white lg:text-base">
There are many ways to be part of our mission to create a more open, autonomous, and interconnected digital world. Farming is just one pillar of our ecosystem. Explore all the products that are driving this transformation.
</p>
</div>
</div>
{/* Right Column - Stacked Cubes (2/3 width) */}
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start order-2 lg:order-2">
<Button variant="outline">
Join the Ecosystem
</Button>
</div>
</div>
<div className="mt-10 grid grid-cols-1 gap-6 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2">
{products.map(product => (
<div
key={product.id}
className={`rounded-2xl bg-stat-gradient p-8 shadow-sm backdrop-blur transition-all duration-300 ease-out hover:scale-105 ${product.colSpan}`}
style={{
filter: 'brightness(1)',
}}
onMouseEnter={(e) => {
e.currentTarget.style.filter = 'brightness(0.8) drop-shadow(0 0 20px rgba(156, 163, 175, 0.5))';
}}
onMouseLeave={(e) => {
e.currentTarget.style.filter = 'brightness(1)';
}}
>
<div className="flex h-full flex-col lg:flex-row items-center lg:items-start gap-6">
<div className="flex-shrink-0">
<img
alt={`${product.title} screenshot`}
src={product.img}
className="w-20 h-20 lg:w-24 lg:h-24 object-contain"
/>
</div>
<div className="flex-1 text-center lg:text-left">
<h3 className="text-xl lg:text-2xl font-semibold text-white mb-3">{product.title}</h3>
<p className="text-gray-700 text-sm font-light text-pretty lg:text-base">
{product.desc}
</p>
</div>
</div>
</div>
))}
</div>
</div>
</section>
);
}

View File

@@ -16,67 +16,66 @@ interface Review {
const reviews: Array<Review> = [
{
title: 'A true game-changer for nonprofits.',
body: 'EngageOS allowed us to centralize our volunteer hub, training, and crowdfunding into one platform. Weve seen a 3x jump in community engagement.',
body: 'ThreeFold allowed us to centralize our volunteer hub, training, and crowdfunding into one platform. We have seen a 3x jump in community engagement.',
author: 'Sarah D., Program Director at WomenRise',
rating: 5,
},
{
title: 'No tech team needed.',
body: 'Launching our own branded platform felt intimidating—until EngageOS. Its intuitive, scalable, and beautifully designed.',
body: 'Launching our own branded platform felt intimidating—until ThreeFold. It is intuitive, scalable, and beautifully designed.',
author: 'Ahmed K., Director at The Green Schools Alliance',
rating: 5,
},
{
title: 'Empowered our youth programs.',
body: 'Thanks to EngageOS, we built a digital home for our learning initiatives with AI-powered content in three languages.',
body: 'Thanks to ThreeFold, we built a digital home for our learning initiatives with AI-powered content in three languages.',
author: 'Maria T., Learning Lead at Global Youth Voices',
rating: 5,
},
{
title: 'Secure and sovereign.',
body: 'As a human rights coalition, data privacy is critical. EngageOS is the only platform that met our ethical tech standards.',
body: 'As a human rights coalition, data privacy is critical. ThreeFold is the only platform that met our ethical tech standards.',
author: 'Lukas M., CTO at Liberty Commons',
rating: 5,
},
{
title: 'Decentralized. Local-first. Exactly what we needed.',
body: 'EngageOS helped us launch a regional platform for community-led health training across East Africa—with full offline access.',
body: 'ThreeFold helped us launch a regional platform for community-led health training across East Africa—with full offline access.',
author: 'Grace N., Digital Programs at Umoja Health Network',
rating: 5,
},
{
title: 'The best decision we made this year.',
body: 'Instead of duct-taping tools together, EngageOS gave us one powerful stack to engage, fundraise, and scale impact.',
body: 'Instead of duct-taping tools together, ThreeFold gave us one powerful stack to engage, fundraise, and scale impact.',
author: 'Jonas F., COO at Youth in Action Europe',
rating: 5,
},
{
title: 'Highly recommend for grassroots orgs.',
body: 'Even with limited staff, we launched a branded hub in 10 days. Its helping our community organize and train in ways we never imagined.',
body: 'Even with limited staff, we launched a branded hub in 10 days. It is helping our community organize and train in ways we never imagined.',
author: 'Tania B., Founder of SpeakUp Brazil',
rating: 5,
},
{
title: 'Our community feels seen and heard.',
body: 'With EngageOS, we integrated storytelling, campaigns, and microdonations into a single, smooth experience.',
body: 'With ThreeFold, we integrated storytelling, campaigns, and microdonations into a single, smooth experience.',
author: 'Nicolas R., Communications Lead at OurStories Foundation',
rating: 5,
},
{
title: 'EngageOS scales with us.',
title: 'ThreeFold scales with us.',
body: 'We piloted in 2 cities and now run campaigns across 7 countries—all on the same platform. It grows with our ambition.',
author: 'Delphine A., Global Lead at Future Farmers',
rating: 5,
},
{
title: 'This platform *is* our movement.',
body: 'Before EngageOS, our digital presence was scattered. Now we have a true home where our supporters connect and take action.',
title: 'This platform is our movement.',
body: 'Before ThreeFold, our digital presence was scattered. Now we have a true home where our supporters connect and take action.',
author: 'Ravi P., Strategy Director at Clean Energy for All',
rating: 5,
},
]
function StarIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
@@ -119,21 +118,21 @@ function Review({
return (
<figure
className={clsx(
'animate-fade-in rounded-3xl bg-white p-6 opacity-0 shadow-md shadow-gray-900/5',
'animate-fade-in rounded-3xl bg-gray-900 p-6 opacity-0 shadow-md shadow-black/20',
className,
)}
style={{ animationDelay }}
{...props}
>
<blockquote className="text-gray-900">
<blockquote className="text-white">
<StarRating rating={rating} />
<p className="mt-4 lg:text-lg text-base/6 font-semibold before:content-['“'] after:content-['”']">
{title}
<p className="mt-4 lg:text-lg text-base/6 font-semibold">
"{title}"
</p>
<p className="mt-3 text-base/7">{body}</p>
</blockquote>
<figcaption className="mt-3 text-sm text-gray-600 before:content-['_']">
{author}
<figcaption className="mt-3 text-sm text-gray-300">
{author}
</figcaption>
</figure>
)
@@ -241,8 +240,8 @@ function ReviewGrid() {
/>
</>
)}
<div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-gray-50" />
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-linear-to-t from-gray-50" />
<div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-gradient-to-b from-gray-950" />
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-gray-950" />
</div>
)
}
@@ -253,15 +252,16 @@ export function Reviews() {
id="reviews"
aria-labelledby="reviews-title"
className="pt-20 pb-16 sm:pt-32 sm:pb-24"
style={{ backgroundColor: '#121212' }}
>
<Container>
<h2
id="reviews-title"
className="text-3xl font-medium tracking-tight text-gray-900 sm:text-center"
className="text-3xl font-medium tracking-tight text-white sm:text-center"
>
Everyone is changing their life with EngageOS.
Everyone is changing their life with ThreeFold.
</h2>
<p className="mt-2 lg:text-lg text-base text-gray-600 sm:text-center">
<p className="mt-2 lg:text-lg text-base text-gray-300 sm:text-center">
Thousands of people have doubled their net-worth in the last 30 days.
</p>
<ReviewGrid />

View File

@@ -58,7 +58,7 @@ export function SecondaryFeatures() {
The Platform Built for Purpose-driven Organizations
</h2>
<p className="mt-4 lg:text-lg text-base text-gray-600">
EngageOS is the first plug-and-play engagement infrastructure built for civil society. From Red Cross OS to Montessori OS, any org can launch their own digital headquartersno tech team needed.
ThreeFold is the first plug-and-play engagement infrastructure built for civil society. From Red Cross OS to Montessori OS, any org can launch their own digital headquartersno tech team needed.
</p>
</div>
<div className="relative overflow-hidden pt-16">

View File

@@ -0,0 +1,51 @@
"use client";
import React from "react";
import { cn } from "@/lib/utils";
import { Spotlight } from "@/components/ui/Spotlight";
import { Logomark } from "@/components/Logo";
import { Button } from "@/components/Button";
export function SpotlightPreview() {
return (
<div className="relative flex h-[40rem] w-full overflow-hidden rounded-md bg-transparent antialiased md:items-center md:justify-center">
<div
className={cn(
"pointer-events-none absolute inset-0 [background-size:40px_40px] select-none",
"[background-image:linear-gradient(to_right,#171717_1px,transparent_1px),linear-gradient(to_bottom,#171717_1px,transparent_1px)]",
)}
/>
<Spotlight
className="-top-40 left-0 md:-top-20 md:left-60"
fill="white"
/>
<div className="relative z-10 mx-auto w-full max-w-7xl p-4 pt-20 md:pt-0">
<div className="flex justify-center mb-6">
<div className="mb-4 relative rounded-full px-3 py-1 text-sm/6 text-gray-700 ring-1 ring-gray-900/10 hover:ring-gray-900/20 animate-fade-in-delay-1">
Announcing The New TF Marketplace.{' '}
<a href="#" className="font-semibold text-white hover:text-gray-800">
<span aria-hidden="true" className="absolute inset-0" />
Read more <span aria-hidden="true">&rarr;</span>
</a>
</div>
</div>
<h1 className="bg-opacity-50 bg-gradient-to-b from-neutral-50 to-neutral-400 bg-clip-text tracking-tighter text-center text-4xl font-semibold text-transparent lg:text-6xl animate-fade-in-delay-2">
Built by Everyone <br /> for Everyone.
</h1>
<p className="mx-auto mt-8 max-w-lg text-center text-base lg:text-xl font-light text-neutral-200 animate-fade-in-delay-3">
ThreeFold is a fully operational, decentralized internet infrastructure deployed locally, scalable globally, and owned and powered by the people.
</p>
<div className="mt-8 flex flex-col sm:flex-row justify-center gap-4 animate-fade-in-delay-4">
<Button href="/login" variant="glass">
Start Building
</Button>
<Button href="#" variant="outline" color="gray">
Start Hosting
</Button>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,60 @@
"use client";
import { StackedCubes } from "@/components/ui/StackedCubes";
import { Button } from "@/components/Button";
import { motion, useInView } from "framer-motion";
import { useRef } from "react";
export function StackSectionPreview() {
const ref = useRef(null);
const isInView = useInView(ref);
return (
<section ref={ref} className="w-full bg-transparent px-4 py-8 sm:px-6 sm:pb-12 lg:px-8 relative">
{/* Gradient Blob Component */}
<div className="absolute w-[400px] h-[200px] bg-gradient-to-br from-[#505050] to-[#7e7e7e] opacity-40 rounded-full blur-[150px] bottom-[200px] left-[-150px] z-0" />
<div className="absolute w-[200px] h-[100px] bg-gradient-to-br from-[#505050] to-[#7e7e7e] opacity-50 rounded-full blur-[150px] top-[200px] right-[-150px] z-0" />
<div className="mx-auto max-w-7xl">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 lg:gap-16 items-center lg:items-start">
{/* Left Column - Text (1/3 width) */}
<div className="text-center lg:text-left lg:col-span-1 order-1 lg:order-1">
<motion.h2
className="text-xl sm:text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl"
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.8, delay: 0.2 }}
>
A Decentralized Infrastructure Layer
</motion.h2>
<motion.p
className="mt-4 lg:mt-6 text-sm font-light text-pretty text-white lg:text-base"
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.8, delay: 0.4 }}
>
We have built a foundational platform that runs directly on bare metal, offering a scalable solution focused on the essential building blocks of the Internet and Cloud: compute, data, and network.
</motion.p>
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.8, delay: 0.6 }}
>
<Button className="mt-12" variant="outline" href="https://threefold.io/build" >Discover How It Works </Button>
</motion.div>
</div>
{/* Right Column - Stacked Cubes (2/3 width) */}
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start order-2 lg:order-2">
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.8, delay: 0.3 }}
>
<StackedCubes />
</motion.div>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,91 @@
'use client'
import { CloudArrowUpIcon, LockClosedIcon, ServerIcon } from '@heroicons/react/20/solid'
import { motion } from 'framer-motion'
import { Button } from './Button'
const features = [
{
name: 'Push to deploy.',
description: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit aute id magna.',
icon: CloudArrowUpIcon,
},
{
name: 'SSL certificates.',
description: 'Anim aute id magna aliqua ad ad non deserunt sunt. Qui irure qui lorem cupidatat commodo.',
icon: LockClosedIcon,
},
{
name: 'Database backups.',
description: 'Ac tincidunt sapien vehicula erat auctor pellentesque rhoncus.',
icon: ServerIcon,
},
]
export function TfDashboard() {
return (
<div className="bg-transparent pt-24 pb-0">
<div className="mx-auto max-w-7xl px-4 lg:px-2">
<div className="relative isolate overflow-hidden bg-stat-gradient px-6 py-12 after:pointer-events-none after:absolute lg:rounded-3xl sm:px-10 sm:py-24 after:lg:rounded-3xl lg:py-24 xl:px-24">
<div className="mx-auto grid max-w-2xl grid-cols-1 gap-x-8 gap-y-16 sm:gap-y-20 lg:mx-0 lg:max-w-none lg:grid-cols-2 lg:items-center lg:gap-y-0">
<div className="lg:row-start-2 lg:max-w-md">
<motion.h2
className="text-3xl font-semibold tracking-tight text-balance text-white sm:text-4xl"
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{delay: 0.5, duration: 0.5}}
>
Threefold Dashboard
</motion.h2>
<motion.p
className="mt-4 lg:mt-6 text-sm font-light text-pretty text-white lg:text-base"
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{delay: 1, duration: 0.5}}
>
ThreeFold is open for developers and system administrators. Deploy virtual machines, containers, Kubernetes clusters, web gateways, and more on top of a best-effort decentralized open source cloud.
</motion.p>
<motion.p
className="mt-6 text-sm font-light text-pretty text-white lg:text-base"
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{delay: 1.5, duration: 0.5}}
>
The ThreeFold Dashboard is your gateway to the new internet infrastructure. It can be used by any Web2, Web3, AI, or Edge IT workload enabling a world of possibilities.
</motion.p>
<motion.div
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{delay: 2, duration: 1}}
>
<Button className="mt-8" variant="outline" href="https://dashboard.threefold.io" >Explore the Dashboard </Button>
</motion.div>
</div>
<motion.img
alt="Product screenshot"
src="/images/tfdash.png"
width={2432}
height={1442}
className="relative z-0 max-w-xl min-w-full rounded-xl shadow-xl ring-1 ring-white/10 lg:row-span-4 lg:w-5xl lg:max-w-none"
whileHover={{scale: 1.05}}
transition={{duration: 0.5}}
/>
</div>
<div
aria-hidden="true"
className="pointer-events-none absolute top-1/2 left-12 -z-10 -translate-y-1/2 transform-gpu blur-3xl lg:top-auto lg:-bottom-48 lg:translate-y-0"
>
<div
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
className="aspect-1155/678 w-288.75 bg-linear-to-tr from-[#fff4f8] to-[#97979d] opacity-20"
/>
</div>
</div>
</div>
</div>
)
}

View File

@@ -19,11 +19,11 @@ const stats = [
export default function Tractions() {
return (
<div className="relative bg-white py-12">
<div className="relative py-12" style={{ backgroundColor: '#121212' }}>
<div className="mx-auto grid max-w-7xl lg:grid-cols-2">
{/* LEFT IMAGE + LOGO */}
<div className="flex flex-col items-center lg:items-start gap-8 px-6 pb-12 lg:px-8">
<div className="w-full ring-1 ring-black/15 rounded-3xl overflow-hidden max-lg:rounded-t-4xl lg:rounded-tl-4xl">
<div className="w-full ring-1 ring-gray-700 rounded-3xl overflow-hidden max-lg:rounded-t-4xl lg:rounded-tl-4xl">
<Image
alt=""
src={Traction}
@@ -56,18 +56,18 @@ export default function Tractions() {
{/* RIGHT TEXT BLOCK */}
<div className="px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:mr-0 lg:max-w-lg">
<h2 className="text-base/8 font-semibold text-gray-900">Our track record</h2>
<p className="mt-2 text-3xl font-medium tracking-tight text-gray-900 sm:text-4xl">
<h2 className="text-base/8 font-semibold text-white">Our track record</h2>
<p className="mt-2 text-3xl font-medium tracking-tight text-white sm:text-4xl">
Trusted by Changemakers worldwide
</p>
<p className="mt-6 lg:text-lg text-base text-gray-600">
EngageOS powers the digital headquarters for over 300,000 users across 50+ countries. From grassroots NGOs to global movements, our platform is built to scale impact, not just numbers.
<p className="mt-6 lg:text-lg text-base text-gray-300">
ThreeFold powers the digital headquarters for over 300,000 users across 50+ countries. From grassroots NGOs to global movements, our platform is built to scale impact, not just numbers.
</p>
<dl className="mt-16 grid max-w-xl grid-cols-1 gap-8 sm:mt-20 sm:grid-cols-2 xl:mt-16">
{stats.map((stat) => (
<div key={stat.id} className="flex flex-col gap-y-3 border-l border-gray-900/10 pl-6">
<dt className="text-sm/6 text-gray-600">{stat.name}</dt>
<dd className="order-first text-3xl font-semibold tracking-tight text-gray-900">{stat.value}</dd>
<div key={stat.id} className="flex flex-col gap-y-3 border-l border-gray-600 pl-6">
<dt className="text-sm/6 text-gray-300">{stat.name}</dt>
<dd className="order-first text-3xl font-semibold tracking-tight text-white">{stat.value}</dd>
</div>
))}
</dl>

View File

@@ -0,0 +1,97 @@
const posts = [
{
id: 1,
title: 'Boost your conversion rate',
href: '#',
description:
'Illo sint voluptas. Error voluptates culpa eligendi. Hic vel totam vitae illo. Non aliquid explicabo necessitatibus unde. Sed exercitationem placeat consectetur nulla deserunt vel. Iusto corrupti dicta.',
imageUrl:
'https://images.unsplash.com/photo-1496128858413-b36217c2ce36?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3603&q=80',
date: 'Mar 16, 2020',
datetime: '2020-03-16',
author: {
name: 'Michael Foster',
imageUrl:
'https://images.unsplash.com/photo-1519244703995-f4e0f30006d5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
},
{
id: 2,
title: 'How to use search engine optimization to drive sales',
href: '#',
description: 'Optio cum necessitatibus dolor voluptatum provident commodi et. Qui aperiam fugiat nemo cumque.',
imageUrl:
'https://images.unsplash.com/photo-1547586696-ea22b4d4235d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
date: 'Mar 10, 2020',
datetime: '2020-03-10',
author: {
name: 'Lindsay Walton',
imageUrl:
'https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
},
{
id: 3,
title: 'Improve your customer experience',
href: '#',
description:
'Cupiditate maiores ullam eveniet adipisci in doloribus nulla minus. Voluptas iusto libero adipisci rem et corporis.',
imageUrl:
'https://images.unsplash.com/photo-1492724441997-5dc865305da7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
date: 'Feb 12, 2020',
datetime: '2020-02-12',
author: {
name: 'Tom Cook',
imageUrl:
'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
},
]
export default function Example() {
return (
<div className="bg-white py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl text-center">
<h2 className="text-4xl font-semibold tracking-tight text-balance text-gray-900 sm:text-5xl">
From the blog
</h2>
<p className="mt-2 text-lg/8 text-gray-600">Learn how to grow your business with our expert advice.</p>
</div>
<div className="mx-auto mt-16 grid max-w-2xl auto-rows-fr grid-cols-1 gap-8 sm:mt-20 lg:mx-0 lg:max-w-none lg:grid-cols-3">
{posts.map((post) => (
<article
key={post.id}
className="relative isolate flex flex-col justify-end overflow-hidden rounded-2xl bg-gray-900 px-8 pt-80 pb-8 sm:pt-48 lg:pt-80"
>
<img alt="" src={post.imageUrl} className="absolute inset-0 -z-10 size-full object-cover" />
<div className="absolute inset-0 -z-10 bg-linear-to-t from-gray-900 via-gray-900/40" />
<div className="absolute inset-0 -z-10 rounded-2xl inset-ring inset-ring-gray-900/10" />
<div className="flex flex-wrap items-center gap-y-1 overflow-hidden text-sm/6 text-gray-300">
<time dateTime={post.datetime} className="mr-8">
{post.date}
</time>
<div className="-ml-4 flex items-center gap-x-4">
<svg viewBox="0 0 2 2" className="-ml-0.5 size-0.5 flex-none fill-white/50">
<circle r={1} cx={1} cy={1} />
</svg>
<div className="flex gap-x-2.5">
<img alt="" src={post.author.imageUrl} className="size-6 flex-none rounded-full bg-white/10" />
{post.author.name}
</div>
</div>
</div>
<h3 className="mt-3 text-lg/6 font-semibold text-white">
<a href={post.href}>
<span className="absolute inset-0" />
{post.title}
</a>
</h3>
</article>
))}
</div>
</div>
</div>
)
}

147
src/components/ui/Cube.tsx Normal file
View File

@@ -0,0 +1,147 @@
"use client";
import React from "react";
import { motion } from "framer-motion";
interface CubeProps {
title: string;
descriptionTitle: string;
description: string;
isActive: boolean;
index: number;
onHover: () => void;
onLeave: () => void;
}
const CubeSvg: React.FC<React.SVGProps<SVGSVGElement> & { index: number }> = ({ index, ...props }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="507"
height="234"
fill="none"
viewBox="0 0 507 234"
{...props}
>
<path
fill={`url(#cube-gradient-${index})`}
d="M491.651 144.747L287.198 227.339C265.219 236.22 241.783 236.22 219.802 227.339L15.3486 144.747C-5.11621 136.479 -5.11621 97.5191 15.3486 89.2539L219.802 6.65884C241.783 -2.21961 265.219 -2.21961 287.198 6.65884L491.651 89.2539C512.116 97.5191 512.116 136.479 491.651 144.747Z"
/>
<defs>
<linearGradient
id={`cube-gradient-${index}`}
x1="185.298"
x2="185.298"
y1="-27.5515"
y2="206.448"
gradientUnits="userSpaceOnUse"
>
<stop />
<stop offset="1" stopColor="#3F3B3E" />
</linearGradient>
</defs>
</svg>
);
export function Cube({ title, descriptionTitle, description, isActive, index, onHover, onLeave }: CubeProps) {
return (
<div className="relative flex flex-col items-center">
<motion.div
className="relative cursor-pointer"
onMouseEnter={onHover}
onMouseLeave={onLeave}
style={{
zIndex: 10 - index,
}}
animate={{
scale: isActive ? 1.05 : 1,
}}
transition={{
duration: 0.3,
ease: "easeOut",
}}
>
{/* SVG Cube */}
<CubeSvg
index={index}
className="w-48 sm:w-64 lg:w-80 h-auto drop-shadow-lg opacity-50"
style={{
filter: isActive ? 'brightness(1.2) drop-shadow(0 0 20px rgba(156, 163, 175, 0.5))' : 'brightness(0.9)',
}}
/>
{/* Title overlay */}
<div className="absolute inset-0 flex items-center justify-center">
<h3
className="text-white text-sm lg:text-base font-medium text-center px-4 drop-shadow-lg"
style={{
transform: 'rotate(0deg) skewX(0deg)',
transformOrigin: 'center'
}}
>
{title}
</h3>
</div>
{/* Description with arrow line - Desktop */}
{isActive && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
className="hidden lg:block absolute left-full top-1/2 -translate-y-1/2 z-50"
>
{/* Arrow line */}
<svg
className="absolute left-0 top-1/2 -translate-y-1/2"
width="120"
height="2"
viewBox="0 0 120 2"
fill="none"
>
<line
x1="0"
y1="1"
x2="120"
y2="1"
stroke="white"
strokeWidth="1"
opacity="0.6"
/>
</svg>
{/* Description text */}
<div className="ml-32 w-80">
<h4 className="text-white text-base font-semibold mb-2">
{descriptionTitle}
</h4>
<p className="text-white text-sm leading-relaxed font-light">
{description}
</p>
</div>
</motion.div>
)}
{/* Description for Mobile - Below cube */}
{isActive && (
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
transition={{ duration: 0.3 }}
className="lg:hidden absolute top-full left-1/2 -translate-x-1/2 mt-8 z-50"
>
<div className="w-64 sm:w-80 px-4">
<h4 className="text-white text-base font-semibold mb-2 text-center">
{descriptionTitle}
</h4>
<p className="text-white text-sm leading-relaxed font-light text-center">
{description}
</p>
</div>
</motion.div>
)}
</motion.div>
</div>
);
}

View File

@@ -0,0 +1,58 @@
"use client";
import React from "react";
import { cn } from "@/lib/utils";
type SpotlightProps = {
className?: string;
fill?: string;
};
export const Spotlight = ({ className, fill }: SpotlightProps) => {
return (
<svg
className={cn(
"animate-spotlight pointer-events-none absolute z-[1] h-[169%] w-[138%] lg:w-[84%] opacity-0",
className
)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 3787 2842"
fill="none"
>
<g filter="url(#filter)">
<ellipse
cx="1924.71"
cy="273.501"
rx="1924.71"
ry="273.501"
transform="matrix(-0.822377 -0.568943 -0.568943 0.822377 3631.88 2291.09)"
fill={fill || "white"}
fillOpacity="0.21"
></ellipse>
</g>
<defs>
<filter
id="filter"
x="0.860352"
y="0.838989"
width="3785.16"
height="2840.26"
filterUnits="userSpaceOnUse"
colorInterpolationFilters="sRGB"
>
<feFlood floodOpacity="0" result="BackgroundImageFix"></feFlood>
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
></feBlend>
<feGaussianBlur
stdDeviation="151"
result="effect1_foregroundBlur_1065_8"
></feGaussianBlur>
</filter>
</defs>
</svg>
);
};

View File

@@ -0,0 +1,61 @@
"use client";
import { useState } from "react";
import { Cube } from "@/components/ui/Cube";
const stackData = [
{
id: "network",
title: "Network",
descriptionTitle: "Secure Network",
description:
"End-to-end encrypted overlay network, always looking for the shortest possible path between participants. Logical Internet address securely linked to a private key. Unlimited scale and performance optimizations.",
position: "top",
},
{
id: "data",
title: "Data",
descriptionTitle: "Unbreakable Data",
description:
"Private, distributed, and AI-native storage with user sovereignty at its core. End-to-end encryption and redundancy, with no central control. Optimized for performance and sustainability, far surpassing traditional cloud.",
position: "middle",
},
{
id: "compute",
title: "Compute",
descriptionTitle: "Bare Metal OS",
description:
"Zero OS, an efficient and secure operating system, runs directly on the hardware enabling an autonomous cloud. Can run any Web2, Web3, or AI workload at the edge of the Internet, with more scalability and reliability.",
position: "bottom",
},
];
export function StackedCubes() {
const [active, setActive] = useState<string | null>("compute");
return (
<div className="relative w-full flex items-center justify-center lg:justify-start min-h-[600px] sm:min-h-[700px] lg:min-h-[600px]">
<div className="relative ml-0 sm:ml-4 lg:ml-8 flex flex-col items-center -space-y-4 sm:-space-y-6 lg:-space-y-8">
{stackData.map((layer, index) => (
<div
key={layer.id}
className="relative"
style={{
zIndex: 10 - index,
}}
>
<Cube
title={layer.title}
descriptionTitle={layer.descriptionTitle}
description={layer.description}
isActive={active === layer.id}
index={index}
onHover={() => setActive(layer.id)}
onLeave={() => setActive("compute")}
/>
</div>
))}
</div>
</div>
);
}

View File

@@ -0,0 +1,9 @@
import { cn } from '@/lib/utils'
import React from 'react'
const h1 = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(({ className, ...props }, ref) => (
<h1 ref={ref} className={cn('text-4xl font-medium tracking-tight lg:text-5xl', className)} {...props} />
))
h1.displayName = 'H1'
export { h1 }

182
src/data/globe.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -0,0 +1,17 @@
<svg width="166" height="45" viewBox="0 0 166 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_233_31)">
<path d="M43.7405 8.94043V35.7474H38.2617V8.94043H43.7405Z" fill="white"/>
<path d="M66.1022 17.6732V35.8069C66.1022 41.4356 61.7103 44.896 56.3358 44.896C51.1548 44.896 47.2839 41.6881 46.9117 37.1584L52.3756 37.1881C52.5989 39.1188 54.2961 39.9505 56.5293 39.9505C58.6434 39.9505 60.6086 38.8218 60.6086 35.8812V33.5643C59.2091 34.4703 57.4226 35.0049 55.4276 35.0049C50.4253 35.0049 46.4204 30.9653 46.4204 26.3168C46.4204 20.9109 50.4401 17.2871 55.4276 17.2871C57.4375 17.2871 59.2091 17.8218 60.6086 18.7277V17.7475L66.1022 17.6732ZM60.6235 28.3515V23.9406C59.5069 22.3218 57.9585 21.7871 56.4251 21.7871C53.7304 21.7871 51.8545 23.5841 51.8545 26.3168C51.8545 28.3218 53.7304 30.5198 56.4251 30.5198C57.9585 30.5049 59.5069 29.9554 60.6235 28.3515Z" fill="white"/>
<path d="M87.9575 26.4949C87.9575 32.0791 83.8187 36.0593 78.2655 36.0593C72.6676 36.0593 68.5288 32.0791 68.5288 26.4949C68.5288 20.9553 72.6676 16.9009 78.2655 16.9009C83.8187 16.9009 87.9575 20.9553 87.9575 26.4949ZM82.6723 26.4949C82.6723 23.8662 80.9453 21.7425 78.2655 21.7425C75.5559 21.7425 73.8289 23.8662 73.8289 26.4949C73.8289 29.1979 75.5559 31.2177 78.2655 31.2177C80.9304 31.2029 82.6723 29.1979 82.6723 26.4949Z" fill="white"/>
<path d="M121.976 17.7032V35.718L116.602 35.7477V34.723C115.202 35.6289 113.416 36.1933 111.421 36.1933C106.418 36.1933 102.414 31.9606 102.414 26.7477C102.414 21.5051 106.433 17.2725 111.421 17.2725C113.431 17.2725 115.202 17.8368 116.602 18.7428V17.718L121.976 17.7032ZM116.602 29.5101V23.9853C115.47 22.3814 113.892 21.9358 112.314 21.9358C109.56 21.9358 107.654 24.1339 107.654 26.7626C107.654 29.3616 109.56 31.5596 112.314 31.5596C113.892 31.5447 115.47 31.114 116.602 29.5101Z" fill="white"/>
<path d="M144.07 25.9604V35.7475H138.785V26.599C138.785 23.6584 137.311 22.099 134.691 22.099C133.321 22.099 131.817 22.8861 130.522 24.401V35.7475H125.118V17.7327H130.522V19.099C131.996 17.9257 133.708 17.2871 135.748 17.2871C140.571 17.2871 144.07 20.6732 144.07 25.9604Z" fill="white"/>
<path d="M35.7605 35.7327H30.1776L26.5449 22.2624L18.7288 35.7327H12.4907L24.5499 14.8812L22.6145 7.63371L6.34203 35.7476H0.104004L20.7237 0.104004H26.1876L28.5845 8.95549H34.2271L30.3711 15.6387L35.7605 35.7327Z" fill="white"/>
<path d="M165.895 8.94063V35.7476H160.417V34.7228C159.017 35.6287 157.231 36.1931 155.236 36.1931C150.233 36.1931 146.229 31.9604 146.229 26.7179C146.229 21.505 150.248 17.2723 155.236 17.2723C157.246 17.2723 159.017 17.8367 160.417 18.7426V8.92578L165.895 8.94063ZM160.417 29.5248V23.9555C159.27 22.3367 157.677 21.8911 156.099 21.8911C153.33 21.8911 151.41 24.104 151.41 26.7179C151.41 29.3763 153.33 31.5891 156.099 31.5891C157.677 31.5891 159.27 31.1436 160.417 29.5248Z" fill="white"/>
<path d="M101.431 22.2774C100.24 22.4259 97.4409 22.5596 95.8032 24.817V35.7626H90.3989V17.7626H95.8032V19.114C97.0389 18.0596 98.8999 17.4358 101.431 17.6883V22.2774Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_233_31">
<rect width="166" height="45" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,5 +0,0 @@
<svg width="83" height="32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M0 15.531v11.531h24.771V4H0v11.531Zm29.042 0v11.531h24.771V4H29.041v11.531Zm29.041 0v11.531h24.771V4H58.083v11.531ZM14.807 7.817c.979.444 1.988 1.197 2.242 1.67.254.475.461 1.43.461 2.125 0 .694-.364 1.713-.81 2.263l-.81 1 1.548 1.34c1.307 1.13 1.548 1.608 1.548 3.079 0 1.25-.29 2.049-1.026 2.834-.565.6-1.714 1.283-2.553 1.516-.84.233-3.208.425-5.264.426l-3.737.003V6.99l3.31.009c2.32.006 3.843.251 5.09.818Zm28.763-.134c1.045.418 1.982 1.173 2.358 1.9.343.665.624 1.677.624 2.25 0 .572-.365 1.492-.81 2.042-.81 1-.81 1 .68 2.29 1.18 1.02 1.5 1.621 1.535 2.888.028 1-.281 2.041-.827 2.776-.48.647-1.526 1.406-2.326 1.686s-3.233.52-5.406.534l-3.95.024V6.99h3.194c1.952 0 3.87.27 4.928.693Zm32.237-.116c1.566.47 1.72.65 1.844 2.148.1 1.222-.007 1.577-.427 1.402-.31-.128-1.59-.551-2.846-.94-1.556-.484-2.896-.618-4.206-.421-1.325.198-2.407.732-3.482 1.717-1.464 1.342-1.56 1.588-1.56 3.997 0 2.26.151 2.725 1.257 3.88.692.721 1.94 1.501 2.776 1.734.836.232 2.096.418 2.8.414.705-.004 2.387-.463 3.738-1.018l2.455-1.01v1.592c0 1.318-.202 1.688-1.174 2.148-.646.306-2.667.65-4.492.765-2.484.156-3.79.027-5.204-.512-1.038-.397-2.562-1.468-3.387-2.38-.824-.913-1.715-2.46-1.978-3.44-.264-.98-.36-2.496-.211-3.37.148-.874.624-2.175 1.06-2.892.436-.717 1.434-1.781 2.217-2.366.783-.584 2.001-1.264 2.706-1.51.704-.246 2.434-.448 3.844-.449 1.409 0 3.33.23 4.27.511ZM9.48 12.007l.13 2.03 1.685-.057c1.182-.039 1.915-.34 2.456-1.008.424-.523.77-1.11.77-1.301 0-.192-.301-.651-.67-1.02-.411-.411-1.415-.672-2.586-.672H9.349l.13 2.029Zm29.042 0 .13 2.03 1.594-.048c.876-.027 1.886-.29 2.242-.587.357-.296.648-.956.648-1.468 0-.511-.23-1.16-.512-1.442-.282-.282-1.35-.513-2.372-.513h-1.86l.13 2.029ZM9.48 19.056l.128 2.242 2.45-.05c1.347-.026 2.74-.29 3.096-.585.356-.296.647-.983.647-1.529 0-.545-.427-1.29-.95-1.655-.57-.4-1.855-.666-3.225-.666H9.351l.13 2.243Zm29.041 0c.123 2.136.189 2.249 1.403 2.387.7.08 1.995-.072 2.878-.337 1.184-.354 1.68-.776 1.887-1.604.217-.864.06-1.305-.683-1.907-.672-.543-1.674-.782-3.29-.782h-2.324l.13 2.243Z"
fill="#737373" />
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,22 @@
<svg width="257" height="45" viewBox="0 0 257 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_233_44)">
<path d="M55.423 37.0956C46.2054 37.0956 40.4639 30.5608 40.4639 21.7956C40.4639 13.1087 46.2835 6.49561 55.5011 6.49561C62.9221 6.49561 67.2575 10.3695 69.0541 16.0826H64.0938C62.5315 12.5217 59.9927 10.7217 55.462 10.7217C49.2128 10.7217 45.4633 15.6521 45.4633 21.7956C45.4633 27.9782 49.2128 32.8695 55.462 32.8695C60.2661 32.8695 62.883 30.7173 64.0938 27.5086H69.0541C67.6481 33.026 62.7658 37.0956 55.423 37.0956Z" fill="white"/>
<path d="M89.9498 36.5871H85.1066C84.9504 35.7263 84.9113 34.748 84.9113 33.7306V33.1437H84.8723C84.1302 35.1002 82.1773 37.1741 78.1153 37.1741C73.3112 37.1741 70.6162 34.2002 70.6162 30.7958C70.6162 24.5741 77.881 24.4176 80.9275 23.9089C83.7396 23.4393 84.8723 23.048 84.8723 21.248C84.8723 19.4871 83.31 18.2741 80.7712 18.2741C78.4668 18.2741 76.8264 19.5654 76.6702 21.6784H72.0223C72.2176 18.1567 74.9907 14.5176 80.6931 14.5176C87.8016 14.5176 89.5983 18.7828 89.5983 23.3611V31.5784C89.5592 33.2611 89.6764 35.4132 89.9498 36.5871ZM85.0285 24.4958C84.5208 25.7871 83.31 26.7654 79.8338 27.3915C76.8654 27.9393 75.3813 28.761 75.3813 30.6393C75.3813 32.361 76.8655 33.6132 79.3261 33.6132C82.2945 33.6132 85.0285 31.5002 85.0285 26.7263V24.4958Z" fill="white"/>
<path d="M100.496 18.2348C98.6598 18.2348 97.0584 19.3305 97.0584 20.8957C97.0584 22.9696 99.5191 23.5566 103.112 24.3392C106.862 25.1609 109.557 26.9609 109.557 30.3653C109.557 34.6305 105.456 37.0957 100.73 37.0957C96.3554 37.0957 92.2153 35.1001 91.7075 29.974H96.4726C96.8631 32.3218 98.3083 33.3783 100.847 33.3783C102.839 33.3783 104.753 32.5566 104.753 30.5609C104.753 28.4479 102.644 28.0957 99.2457 27.3131C95.8476 26.4914 92.3715 24.887 92.3715 21.0522C92.3715 17.1783 96.1601 14.5957 100.535 14.5957C105.143 14.5957 108.659 16.9435 109.088 21.5609H104.518C104.284 19.2131 102.448 18.2348 100.496 18.2348Z" fill="white"/>
<path d="M133.538 25.787C133.538 32.4783 129.476 37.174 123.813 37.174C120.142 37.174 117.759 35.2174 116.9 32.674H116.861V44.8044H111.939V15.1827H116.9V19.0566C117.72 16.7479 120.142 14.5957 123.813 14.5957C129.476 14.5957 133.538 19.174 133.538 25.787ZM128.734 25.787C128.734 21.7174 126.43 18.5087 122.68 18.5087C119.009 18.5087 116.704 21.3653 116.587 25.3175V25.787C116.587 30.0131 118.54 33.2218 122.68 33.2218C126.469 33.2218 128.734 29.974 128.734 25.787Z" fill="white"/>
<path d="M156.036 27.1566H139.592C139.944 31.0305 142.404 33.2609 145.763 33.2609C148.224 33.2609 150.216 32.3609 151.036 30.2088H155.801C154.512 34.5914 150.841 37.1348 145.841 37.1348C139.436 37.1348 135.062 32.5174 135.062 25.787C135.062 19.3305 139.631 14.5957 145.841 14.5957C153.106 14.5957 156.075 20.2305 156.114 26.2174V27.1174C156.075 27.1566 156.036 27.1566 156.036 27.1566ZM151.27 23.674C150.919 20.3088 148.966 18.3131 145.646 18.3131C142.326 18.3131 140.139 20.4261 139.631 23.674H151.27Z" fill="white"/>
<path d="M163.34 26.452V36.5867H158.536V15.1433H163.262V19.7215H163.379C164.199 16.8259 166.269 14.9085 169.628 14.752V19.565C165.605 19.6041 163.34 22.1867 163.34 26.452Z" fill="white"/>
<path d="M192.32 32.361V36.5871H173.417V6.96533H178.416V32.361H192.32Z" fill="white"/>
<path d="M212.67 36.5871H207.748C207.592 35.7262 207.553 34.7479 207.553 33.7306V33.1436H207.514C206.772 35.1001 204.819 37.174 200.718 37.174C195.914 37.174 193.219 34.161 193.219 30.7958C193.219 24.574 200.523 24.4175 203.569 23.9088C206.381 23.4392 207.514 23.0479 207.514 21.2479C207.514 19.4479 205.952 18.274 203.374 18.274C201.069 18.274 199.429 19.5653 199.273 21.7175H194.625C194.82 18.1958 197.632 14.5566 203.335 14.5566C210.443 14.5566 212.318 18.8219 212.318 23.4392V31.7349C212.279 33.261 212.357 35.4914 212.67 36.5871ZM207.67 24.4958C207.162 25.7871 205.952 26.7653 202.475 27.3914C199.507 27.9392 198.023 28.761 198.023 30.6392C198.023 32.361 199.507 33.6132 201.968 33.6132C204.936 33.6132 207.67 31.5001 207.67 26.7262V24.4958Z" fill="white"/>
<path d="M237.666 25.7871C237.666 32.5958 233.721 37.174 228.019 37.174C224.504 37.174 221.926 35.061 220.95 32.674H220.911V36.5871H215.989V6.96533H220.95V19.0566C221.809 16.7871 224.504 14.5566 228.019 14.5566C233.682 14.5566 237.666 19.0175 237.666 25.7871ZM232.784 25.7871C232.784 21.4045 230.323 18.4697 226.691 18.4697C222.981 18.4697 220.715 21.3262 220.598 25.2784V25.7479C220.598 29.974 222.902 33.1827 226.691 33.1827C230.441 33.2219 232.784 30.2088 232.784 25.7871Z" fill="white"/>
<path d="M247.626 18.2349C245.791 18.2349 244.189 19.3305 244.189 20.8958C244.189 22.9697 246.689 23.5566 250.282 24.3392C254.032 25.2001 256.805 26.961 256.805 30.4045C256.805 34.6697 252.704 37.174 247.978 37.174C243.564 37.174 239.463 35.1784 238.956 30.0523H243.721C244.111 32.4001 245.556 33.4958 248.095 33.4958C250.165 33.4958 252.04 32.6349 252.04 30.6784C252.04 28.5653 249.931 28.2132 246.494 27.4306C243.057 26.6088 239.62 25.0045 239.62 21.0914C239.62 17.1784 243.408 14.5566 247.822 14.5566C252.47 14.5566 255.946 16.9045 256.453 21.6001H251.884C251.415 19.2132 249.579 18.2349 247.626 18.2349Z" fill="white"/>
<path d="M29.7619 36.7827L19.1772 18.0001V6.10443H20.1146C21.1301 6.10443 21.9112 5.28269 21.9112 4.30443C21.9112 3.28703 21.091 2.50442 20.1146 2.50442H18.9819L19.4506 1.83921C19.6459 1.01747 19.06 0.234863 18.2008 0.234863H12.5374C11.6781 0.234863 11.0923 1.0566 11.2875 1.87834L11.7953 2.54356H10.6626C9.64712 2.54356 8.86596 3.3653 8.86596 4.34356C8.86596 5.36095 9.68618 6.14356 10.6626 6.14356H11.6V18.0392L0.976296 36.7827C0.0389104 38.4262 0.0779676 40.3827 1.01535 42.0653C1.95274 43.7088 3.67128 44.687 5.58511 44.687H25.2702C27.184 44.687 28.8635 43.7479 29.84 42.0653C30.7383 40.3827 30.7383 38.4262 29.7619 36.7827ZM29.176 41.7131C28.3167 43.1218 26.8716 43.9827 25.2312 43.9827H5.54605C3.90563 43.9827 2.38237 43.1218 1.60122 41.7131C0.741949 40.3044 0.74195 38.5436 1.56216 37.1349L12.264 18.1566V5.47834H10.6236C10.0377 5.47834 9.52994 4.96964 9.52994 4.38269C9.52994 3.79573 10.0377 3.28703 10.6236 3.28703H20.1537C20.7395 3.28703 21.2473 3.79573 21.2473 4.38269C21.2473 4.96964 20.7395 5.47834 20.1537 5.47834H18.5132V18.1566L29.215 37.1349C30.0353 38.5436 30.0353 40.3044 29.176 41.7131Z" fill="white"/>
<path d="M23.5517 32.3999C20.8958 33.5347 17.8102 33.9651 14.8028 32.1651C12.3421 30.7173 10.1549 30.326 8.28011 30.4434L3.78847 38.3869C3.28072 39.2869 3.63224 40.1086 3.78847 40.3825C3.9447 40.6956 4.49151 41.3999 5.50701 41.3999H25.1921C26.2467 41.3999 26.7544 40.6956 26.9107 40.3825C27.1059 40.0695 27.4184 39.2869 26.9107 38.3869L23.5517 32.3999Z" fill="white"/>
<path d="M13.4359 26.2958C13.475 26.2958 13.5531 26.2958 13.5922 26.2958L15.3888 28.2524C15.3498 28.4089 15.2717 28.5654 15.2717 28.7611C15.2717 29.4263 15.8185 29.9741 16.4824 29.9741C17.1464 29.9741 17.6932 29.4263 17.6932 28.7611C17.6932 28.0958 17.1464 27.548 16.4824 27.548C16.2481 27.548 15.9747 27.6654 15.7794 27.7437L14.0609 25.8263C14.0609 25.7871 14.0999 25.7089 14.0999 25.6698L15.7404 24.9263C16.0528 25.3958 16.5996 25.6306 17.1464 25.6306C18.0838 25.6306 18.904 24.8089 18.904 23.8698C18.904 22.9306 18.0838 22.1089 17.1464 22.1089C16.209 22.1089 15.3888 22.9306 15.3888 23.8698C15.3888 24.0263 15.3888 24.1828 15.4279 24.2611L13.7875 25.0045C13.6703 24.8871 13.5531 24.848 13.3969 24.848C13.0063 24.848 12.6938 25.1611 12.6938 25.5524C12.811 25.9828 13.0844 26.2958 13.4359 26.2958Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_233_44">
<rect width="257" height="45" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,5 +0,0 @@
<svg width="101" height="32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M15.072 1C6.675 1 0 7.855 0 16.205c0 8.44 6.676 15.297 15.072 15.297 8.44 0 15.026-6.855 15.026-15.295C30.099 7.857 23.51 1 15.072 1Zm0 6.454c6.855 0 11.876 4.353 13.998 8.753-2.122 4.467-7.143 8.841-13.998 8.841-6.9 0-11.881-4.375-14.002-8.84 2.12-4.4 7.104-8.751 14.002-8.751v-.003Zm0 .692c-4.466 0-8.107 3.614-8.107 8.059a8.092 8.092 0 0 0 8.107 8.106c4.465 0 8.058-3.595 8.058-8.104a8.055 8.055 0 0 0-8.058-8.061ZM44.506 2.81c-7.883 0-13.376 5.983-13.376 13.261v.088c0 7.368 5.606 13.198 13.177 13.198 4.934 0 7.882-1.765 10.517-4.601L51.23 21.14c-2.01 1.83-3.822 3.016-6.747 3.016-4.398 0-7.457-3.689-7.457-8.086v-.066c0-4.399 3.126-7.995 7.457-7.995 2.568 0 4.578 1.094 6.566 2.904l3.595-4.155c-2.389-2.344-5.291-3.95-10.137-3.95ZM56.951 3.254v25.653h12.213c5.782 0 9.6-2.341 9.6-7.029v-.09c0-3.438-1.829-5.16-4.801-6.297 1.832-1.026 3.372-2.633 3.372-5.536V9.89c0-1.767-.581-3.195-1.765-4.378-1.472-1.45-3.772-2.257-6.698-2.257h-11.92Zm5.49 4.934h5.584c2.39 0 3.705.96 3.705 2.635v.09c0 1.898-1.585 2.702-4.085 2.702l-5.203.002V8.188Zm0 10.119h6.545c2.878 0 4.173 1.073 4.173 2.792v.087c0 1.898-1.517 2.768-3.995 2.768l-6.722.003v-5.65ZM89.833 2.876c-5.224 0-8.974 3.08-8.974 7.745v.069c0 5.093 3.347 6.523 8.506 7.84 4.287 1.115 5.179 1.829 5.179 3.258v.09c0 1.495-1.408 2.412-3.707 2.412-2.948 0-5.36-1.209-7.66-3.106L79.83 25.18c3.081 2.747 7.01 4.088 10.896 4.088v-.003c5.537 0 9.421-2.86 9.421-7.946v-.067c0-4.487-2.946-6.344-8.149-7.705-4.42-1.14-5.538-1.697-5.538-3.372v-.066c0-1.25 1.139-2.255 3.305-2.255 2.166 0 4.4.959 6.678 2.542l2.924-4.26c-2.59-2.077-5.781-3.261-9.533-3.261Z"
fill="#737373" />
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,11 +0,0 @@
<svg width="68" height="32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.155 15.807c0 5.795 4.715 10.51 10.51 10.51h9.817c.617 0 1.095-.586 1.095-1.09V5.966a2.21 2.21 0 0 1 2.206-2.207c.78 0 1.508.414 1.897 1.08a91573.874 91573.874 0 0 1 12.332 21.263.918.918 0 0 0 1.701-.476V5.968c0-1.217.99-2.207 2.206-2.207.78 0 1.508.414 1.897 1.08.05.084 3.02 5.208 6.164 10.634l6.16 10.63a.918.918 0 0 0 1.7-.476V.138h-3.87V15.31S51.96 3.243 51.734 2.855C50.709 1.105 48.768 0 46.703 0a5.861 5.861 0 0 0-5.86 5.86v9.45s-7.01-12.067-7.238-12.455C32.582 1.105 30.641 0 28.575 0a5.861 5.861 0 0 0-5.86 5.86V21.39c.003.565-.422 1.057-1.04 1.059h-5.968a6.64 6.64 0 0 1 0-13.282h4.998V5.297h-5.04c-5.795 0-10.51 4.715-10.51 10.51Z"
fill="#737373" />
<path
d="M64.13.137v25.49c0 1.217-.989 2.207-2.206 2.207-.78 0-1.508-.414-1.897-1.08-.05-.084-3.02-5.209-6.163-10.634l-6.16-10.63a.918.918 0 0 0-1.7.475v19.662c-.001 1.217-.99 2.207-2.208 2.207-.78 0-1.507-.414-1.897-1.08L35.732 16.12 29.567 5.49a.917.917 0 0 0-1.7.475v19.26c0 1.269-1.115 2.381-2.385 2.381h-9.816c-6.507 0-11.8-5.293-11.8-11.8 0-6.506 5.293-11.8 11.8-11.8h5.04V.136H15.67C7.016.137 0 7.153 0 15.807c0 8.655 7.016 15.67 15.67 15.67h9.911c3.754.002 6.169-2.198 6.164-6.255v-8.938s7.06 12.153 7.238 12.456a5.86 5.86 0 0 0 10.89-3.006v-9.45s7.01 12.068 7.238 12.456c1.023 1.75 2.964 2.855 5.03 2.855A5.86 5.86 0 0 0 68 25.734V.136h-3.87Z"
fill="#737373" />
<path
d="M3.865 15.807c0 6.507 5.294 11.8 11.8 11.8h9.817c1.27 0 2.384-1.112 2.384-2.38V5.966a.917.917 0 0 1 1.7-.475c.05.084 3.159 5.445 6.165 10.629L41.9 26.755a2.202 2.202 0 0 0 1.897 1.08 2.21 2.21 0 0 0 2.207-2.207V5.967a.917.917 0 0 1 1.7-.475l6.16 10.629 6.163 10.634a2.201 2.201 0 0 0 1.897 1.08c1.218 0 2.207-.99 2.207-2.207V.138h-1.29v25.49a.918.918 0 0 1-1.7.475l-6.16-10.629c-3.145-5.426-6.114-10.55-6.164-10.634a2.201 2.201 0 0 0-1.897-1.08 2.21 2.21 0 0 0-2.206 2.207v19.66a.918.918 0 0 1-1.701.476A344293.41 344293.41 0 0 1 30.68 4.84a2.201 2.201 0 0 0-1.897-1.08 2.21 2.21 0 0 0-2.207 2.207v19.26c0 .504-.478 1.09-1.094 1.09h-9.817c-5.795 0-10.51-4.715-10.51-10.51s4.715-10.51 10.51-10.51h5.04v-1.29h-5.04c-6.506 0-11.8 5.294-11.8 11.8Z"
fill="#fff" />
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

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