Compare commits
23 Commits
developmen
...
1792262f49
| Author | SHA1 | Date | |
|---|---|---|---|
| 1792262f49 | |||
| b203e29593 | |||
| aa6c12e749 | |||
| 1a7a52aaf4 | |||
| 093546d017 | |||
| ab42093c78 | |||
| 40e616fa83 | |||
| 4ef0b3918b | |||
| cd8687db54 | |||
| c59c905945 | |||
| 14435d8f63 | |||
| 987550c7c6 | |||
| ecd52b6ada | |||
| 7e2b30fbcc | |||
| a69f35c9a7 | |||
| 4bea627e6d | |||
| 6d35b9dd05 | |||
| 40d1d5ed24 | |||
| ddbe3c795d | |||
| 1df765c4aa | |||
| c8a3b455fe | |||
| 75aa34ae6f | |||
| 0310ecfb31 |
@@ -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
|
## Getting started
|
||||||
|
|
||||||
|
|||||||
19
build.sh
Executable 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/"
|
||||||
|
|
||||||
24
install.sh
Executable 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
|
||||||
|
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {}
|
const nextConfig = {
|
||||||
|
basePath: process.env.NEXT_PUBLIC_BASE_PATH || '',
|
||||||
|
output: 'export',
|
||||||
|
images: {
|
||||||
|
unoptimized: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-countup": "^6.5.3",
|
"react-countup": "^6.5.3",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-type-animation": "^3.2.0",
|
||||||
"tailwind-merge": "^2.6.0",
|
"tailwind-merge": "^2.6.0",
|
||||||
"tailwindcss": "^4.1.7",
|
"tailwindcss": "^4.1.7",
|
||||||
"three": "^0.179.1",
|
"three": "^0.179.1",
|
||||||
|
|||||||
5581
pnpm-lock.yaml
generated
Normal file
|
Before Width: | Height: | Size: 1017 KiB After Width: | Height: | Size: 1017 KiB |
BIN
public/images/3phone.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/images/3router.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/images/aibox.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
74
public/images/build.svg
Normal 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/hgu-04.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
public/images/kds.jpeg
Normal file
|
After Width: | Height: | Size: 202 KiB |
1
public/images/mycelium.svg
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
public/images/net.jpeg
Normal file
|
After Width: | Height: | Size: 295 KiB |
BIN
public/images/people/abdulrahman_elawady.jpg
Normal file
|
After Width: | Height: | Size: 3.4 MiB |
BIN
public/images/people/adnan_fatayerji.jpg
Normal file
|
After Width: | Height: | Size: 219 KiB |
BIN
public/images/people/ahmed_hanafy.jpg
Normal file
|
After Width: | Height: | Size: 439 KiB |
BIN
public/images/people/ahmed_thabet.jpg
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
public/images/people/alaa_mahmoud.jpg
Normal file
|
After Width: | Height: | Size: 318 KiB |
BIN
public/images/people/alexandre_hannelas.jpeg
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
public/images/people/amira_abouhadid.jpg
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
public/images/people/ashraf_fouda.jpeg
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
public/images/people/atef_nazmy.jpg
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
public/images/people/bernadette_amanda_caster.jpg
Normal file
|
After Width: | Height: | Size: 259 KiB |
BIN
public/images/people/cameron_ramraichan_labeyrie.jpg
Normal file
|
After Width: | Height: | Size: 562 KiB |
BIN
public/images/people/ehab_hassan.jpg
Normal file
|
After Width: | Height: | Size: 191 KiB |
BIN
public/images/people/eslam_nawara.jpg
Normal file
|
After Width: | Height: | Size: 483 KiB |
BIN
public/images/people/evon_yacoub.jpg
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
public/images/people/florian_fournier.jpeg
Normal file
|
After Width: | Height: | Size: 525 KiB |
BIN
public/images/people/gregory_flipo.jpg
Normal file
|
After Width: | Height: | Size: 364 KiB |
BIN
public/images/people/jan_de_landtsheer.jpeg
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
public/images/people/karoline_zizka.jpeg
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
public/images/people/khaled.jpg
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
public/images/people/kristof_de_spiegeleer.jpeg
Normal file
|
After Width: | Height: | Size: 202 KiB |
BIN
public/images/solution1.jpg
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
public/images/tfdash.png
Normal file
|
After Width: | Height: | Size: 634 KiB |
15
src/app/(main)/about/page.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
12
src/app/(main)/build/page.tsx
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import BuildHero from "@/components/BuildHero";
|
||||||
|
import BuildStack from "@/components/BuildStack";
|
||||||
|
|
||||||
|
export default function Build() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<BuildHero />
|
||||||
|
<BuildStack />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { CallToAction } from '@/components/CallToAction'
|
import { CallToAction } from '@/components/CallToAction'
|
||||||
import { Faqs } from '@/components/Faqs'
|
|
||||||
import { Hero } from '@/components/Hero'
|
import { Hero } from '@/components/Hero'
|
||||||
import { Pricing } from '@/components/Pricing'
|
import { Pricing } from '@/components/Pricing'
|
||||||
import { PrimaryFeatures } from '@/components/PrimaryFeatures'
|
import { PrimaryFeatures } from '@/components/PrimaryFeatures'
|
||||||
@@ -14,6 +13,10 @@ import GlobeDemo from '@/components/GlobeDemo'
|
|||||||
import { Dashboard } from '@/components/Dashboard'
|
import { Dashboard } from '@/components/Dashboard'
|
||||||
import { AppsPreview } from '@/components/Apps'
|
import { AppsPreview } from '@/components/Apps'
|
||||||
import { FarmerPreview } from '@/components/Farmer'
|
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() {
|
export default function Home() {
|
||||||
@@ -23,8 +26,11 @@ export default function Home() {
|
|||||||
<StackSectionPreview />
|
<StackSectionPreview />
|
||||||
<Dashboard />
|
<Dashboard />
|
||||||
<FarmerPreview />
|
<FarmerPreview />
|
||||||
|
<TfDashboard />
|
||||||
<AppsPreview />
|
<AppsPreview />
|
||||||
|
<ProductsPreview />
|
||||||
|
<CallTo />
|
||||||
|
<Faqss />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -12,11 +12,11 @@ const inter = Inter({
|
|||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: {
|
title: {
|
||||||
template: '%s - EngageOS',
|
template: '%s - ThreeFold',
|
||||||
default: 'EngageOS - Invest at the perfect time.',
|
default: 'ThreeFold - Decentralized internet by everyone, for everyone.',
|
||||||
},
|
},
|
||||||
description:
|
description:
|
||||||
'By leveraging insights from our network of industry insiders, you’ll know exactly when to buy to maximize profit, and exactly when to sell to avoid painful losses.',
|
'ThreeFold is a fully operational, decentralized internet infrastructure – deployed locally, scalable globally, and owned and powered by the people.',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
@@ -25,8 +25,10 @@ export default function RootLayout({
|
|||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="en" className={clsx('antialiased', inter.variable)} style={{ backgroundColor: '#121212' }}>
|
<html lang="en" className={clsx('antialiased', inter.variable)} suppressHydrationWarning>
|
||||||
<body style={{ backgroundColor: '#121212', color: '#ffffff' }}>{children}</body>
|
<body className="bg-[#121212] text-white" suppressHydrationWarning>
|
||||||
|
{children}
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/components/AboutCTA.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
50
src/components/AboutHero.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
38
src/components/AboutJourney.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import Image from 'next/image'
|
||||||
|
|
||||||
|
const featuredPost = {
|
||||||
|
id: 1,
|
||||||
|
title: 'Our Journey',
|
||||||
|
href: '#',
|
||||||
|
description:
|
||||||
|
'For decades, we’ve 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
89
src/components/AboutSolutions.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
22
src/components/AboutTeam.tsx
Normal 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, it’s 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ const logos = [
|
|||||||
export function AppsPreview() {
|
export function AppsPreview() {
|
||||||
return (
|
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 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-4xl p-4 pt-24">
|
<div className="relative z-10 mx-auto w-full max-w-3xl p-4 pt-16">
|
||||||
|
|
||||||
{/* Heading */}
|
{/* Heading */}
|
||||||
<motion.div
|
<motion.div
|
||||||
@@ -31,7 +31,7 @@ export function AppsPreview() {
|
|||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 1 }}
|
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-6xl">
|
<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
|
Anything That Runs on Linux Can Run on ThreeFold
|
||||||
</h1>
|
</h1>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|||||||
70
src/components/BackgroundIllustration.tsx
Normal 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
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ export default function Benefits() {
|
|||||||
Built Different. For a Change.
|
Built Different. For a Change.
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-6 lg:text-lg text-base text-gray-300">
|
<p className="mt-6 lg:text-lg text-base text-gray-300">
|
||||||
EngageOS 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 EngageOS is designed to meet the real-world challenges of civil society.
|
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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
@@ -32,7 +32,7 @@ export default function Benefits() {
|
|||||||
<h3 className="text-sm/4 font-semibold text-white"> Built for Civil Society</h3>
|
<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 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">
|
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
|
||||||
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.
|
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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +48,7 @@ export default function Benefits() {
|
|||||||
<h3 className="text-sm/4 font-semibold text-white">White-Label, Zero-Code</h3>
|
<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 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">
|
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
|
||||||
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.
|
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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -64,7 +64,7 @@ export default function Benefits() {
|
|||||||
<h3 className="text-sm/4 font-semibold text-white">Sovereign & Ethical Infrastructure</h3>
|
<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 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">
|
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
|
||||||
We don't 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.
|
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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -80,7 +80,7 @@ export default function Benefits() {
|
|||||||
<h3 className="text-sm/4 font-semibold text-white">Mutualized Model</h3>
|
<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 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">
|
<p className="mt-2 max-w-lg text-sm/6 text-gray-300">
|
||||||
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.
|
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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
45
src/components/BuildHero.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
163
src/components/BuildStack.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ import clsx from 'clsx'
|
|||||||
const baseStyles = {
|
const baseStyles = {
|
||||||
solid:
|
solid:
|
||||||
'inline-flex justify-center rounded-lg py-2 px-3 text-sm font-semibold transition-colors',
|
'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:
|
outline:
|
||||||
'inline-flex justify-center rounded-lg border py-[calc(--spacing(2)-1px)] px-[calc(--spacing(3)-1px)] text-sm transition-colors',
|
'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 = {
|
const variantStyles = {
|
||||||
solid: {
|
solid: {
|
||||||
gradient:
|
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',
|
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:
|
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',
|
gray: 'bg-gray-800 text-white hover:bg-gray-900 active:bg-gray-800 active:text-white/80',
|
||||||
},
|
},
|
||||||
outline: {
|
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'
|
variant?: 'solid'
|
||||||
color?: keyof typeof variantStyles.solid
|
color?: keyof typeof variantStyles.solid
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
variant: 'glass'
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
variant: 'outline'
|
variant: 'outline'
|
||||||
color?: keyof typeof variantStyles.outline
|
color?: keyof typeof variantStyles.outline
|
||||||
@@ -41,15 +46,22 @@ type ButtonProps = (
|
|||||||
|
|
||||||
export function Button({ className, ...props }: ButtonProps) {
|
export function Button({ className, ...props }: ButtonProps) {
|
||||||
props.variant ??= 'solid'
|
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(
|
className = clsx(
|
||||||
baseStyles[props.variant],
|
baseStyles[props.variant],
|
||||||
props.variant === 'outline'
|
variantClass,
|
||||||
? variantStyles.outline[props.color]
|
|
||||||
: props.variant === 'solid'
|
|
||||||
? variantStyles.solid[props.color]
|
|
||||||
: undefined,
|
|
||||||
className,
|
className,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
47
src/components/CallTo.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ export default function Cta() {
|
|||||||
Scale Your Impact, Not Your Costs
|
Scale Your Impact, Not Your Costs
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mx-auto mt-6 max-w-xl text-lg/8 text-pretty text-gray-300">
|
<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.
|
all from one unified platform.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-10 flex items-center justify-center gap-x-6">
|
<div className="mt-10 flex items-center justify-center gap-x-6">
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
import CountUp from "react-countup";
|
import CountUp from "react-countup";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { Button } from "./Button";
|
||||||
|
|
||||||
export function Dashboard() {
|
export function Dashboard() {
|
||||||
return (
|
return (
|
||||||
<div className="py-24 bg-transparent">
|
<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="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">
|
<div className="grid grid-cols-1 gap-8 lg:grid-cols-3">
|
||||||
{/* Column 1: Title & NODES */}
|
{/* Column 1: Title & NODES */}
|
||||||
@@ -18,7 +19,7 @@ export function Dashboard() {
|
|||||||
<p className="mt-4 sm:mt-6 text-sm font-light text-pretty text-white lg:text-base">
|
<p className="mt-4 sm:mt-6 text-sm font-light text-pretty text-white lg:text-base">
|
||||||
ThreeFold’s groundbreaking technology enables anyone – individuals, organizations, and communities – to deploy their own Internet infrastructure.
|
ThreeFold’s groundbreaking technology enables anyone – individuals, organizations, and communities – to deploy their own Internet infrastructure.
|
||||||
</p>
|
</p>
|
||||||
<button className="mt-6" variant="primary" color="transparent" href="https://threefold.io/build" >Explore TFGrid →</button>
|
<Button className="mt-8" variant="outline" href="https://threefold.io/build" >Explore TFGrid →</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -86,23 +87,23 @@ function StatCard({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`relative flex flex-col overflow-hidden rounded-2xl bg-stat-gradient p-8 shadow-sm backdrop-blur transition-all duration-300 ease-out hover:scale-105 ${className}`}
|
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={{
|
style={{
|
||||||
filter: 'brightness(1)',
|
filter: 'brightness(1)',
|
||||||
}}
|
}}
|
||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
e.currentTarget.style.filter = 'brightness(0.8) drop-shadow(0 0 20px rgba(156, 163, 175, 0.5))';
|
e.currentTarget.style.filter = 'brightness(0.8)';
|
||||||
}}
|
}}
|
||||||
onMouseLeave={(e) => {
|
onMouseLeave={(e) => {
|
||||||
e.currentTarget.style.filter = 'brightness(1)';
|
e.currentTarget.style.filter = 'brightness(1)';
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h3 className="text-lg font-semibold text-cyan-400">{label}</h3>
|
<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">
|
<p className="mt-2 text-sm font-light text-pretty text-white lg:text-base">
|
||||||
{description}
|
{description}
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 flex items-center space-x-3">
|
<div className="mt-8 flex items-center space-x-3">
|
||||||
<span className="text-cyan-400 text-3xl">•</span>
|
<span className="text-gradient-neutral-vertical text-3xl">•</span>
|
||||||
<div className="text-5xl font-semibold tracking-tight text-white tabular-nums">
|
<div className="text-5xl font-semibold tracking-tight text-white tabular-nums">
|
||||||
{value}
|
{value}
|
||||||
{unit && (
|
{unit && (
|
||||||
|
|||||||
63
src/components/Faq.tsx
Normal 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">
|
||||||
|
Can’t find the answer you’re 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -3,48 +3,48 @@ import { Container } from '@/components/Container'
|
|||||||
const faqs = [
|
const faqs = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
question: 'What is EngageOS?',
|
question: 'What is ThreeFold?',
|
||||||
answer:
|
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:
|
answer:
|
||||||
'No. EngageOS is fully plug-and-play. It’s 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. It’s 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 platform’s look and feel?',
|
question: 'Can we fully customize the platform’s look and feel?',
|
||||||
answer:
|
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:
|
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.',
|
'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:
|
answer:
|
||||||
'Yes. The platform supports multilingual content and offline-friendly delivery—ideal for reaching underserved communities with limited connectivity.',
|
'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:
|
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:
|
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?',
|
question: 'What is the pricing model?',
|
||||||
answer:
|
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?',
|
question: 'How do we get started?',
|
||||||
@@ -55,7 +55,7 @@ const faqs = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
export function Faqs() {
|
export function Faqss () {
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
id="faqs"
|
id="faqs"
|
||||||
@@ -66,14 +66,14 @@ export function Faqs() {
|
|||||||
<div className="mx-auto max-w-2xl lg:mx-0">
|
<div className="mx-auto max-w-2xl lg:mx-0">
|
||||||
<h2
|
<h2
|
||||||
id="faqs-title"
|
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
|
Frequently asked questions
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-2 lg:text-lg text-base text-gray-600">
|
<p className="mt-2 lg:text-lg text-base text-gray-600">
|
||||||
If you have anything else you want to ask,{' '}
|
If you have anything else you want to ask,{' '}
|
||||||
<a
|
<a
|
||||||
href="mailto:info@example.com"
|
href="mailto:info@threefold.io"
|
||||||
className="text-gray-900 underline"
|
className="text-gray-900 underline"
|
||||||
>
|
>
|
||||||
reach out to us
|
reach out to us
|
||||||
@@ -83,7 +83,7 @@ export function Faqs() {
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
role="list"
|
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) => (
|
{faqs.map((column, columnIndex) => (
|
||||||
<li key={columnIndex}>
|
<li key={columnIndex}>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export function FarmerPreview() {
|
|||||||
return (
|
return (
|
||||||
<section className="w-full bg-transparent px-4 py-8 sm:px-6 mt-12 sm:pb-12 lg:px-8 relative">
|
<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 */}
|
{/* 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-[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="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="mx-auto max-w-7xl">
|
||||||
<div className="lg:flex lg:items-center lg:justify-between lg:px-8">
|
<div className="lg:flex lg:items-center lg:justify-between lg:px-8">
|
||||||
@@ -61,7 +61,7 @@ export function FarmerPreview() {
|
|||||||
</div>
|
</div>
|
||||||
{/* Right Column - Stacked Cubes (2/3 width) */}
|
{/* 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">
|
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start order-2 lg:order-2">
|
||||||
<Button variant="outline" className=" text-black px-4 py-2 rounded-md hover:bg-gray-700 transition-colors">
|
<Button variant="outline">
|
||||||
Become A Farmer
|
Become A Farmer
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -70,7 +70,7 @@ export function FarmerPreview() {
|
|||||||
{posts.map((post) => (
|
{posts.map((post) => (
|
||||||
<article
|
<article
|
||||||
key={post.id}
|
key={post.id}
|
||||||
className="relative isolate flex flex-col justify-end overflow-hidden rounded-2xl bg-state-gradient px-8 lg:pt-12"
|
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"
|
<div className="absolute inset-0 -z-10 bg-linear-to-t from-gray-200 via-gray-300/10"
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { Container } from '@/components/Container'
|
|||||||
import { TextField } from '@/components/Fields'
|
import { TextField } from '@/components/Fields'
|
||||||
import { Logomark } from '@/components/Logo'
|
import { Logomark } from '@/components/Logo'
|
||||||
import { NavLinks } from '@/components/NavLinks'
|
import { NavLinks } from '@/components/NavLinks'
|
||||||
import qrCode from '@/images/qr-code.svg'
|
|
||||||
|
|
||||||
function QrCodeBorder(props: React.ComponentPropsWithoutRef<'svg'>) {
|
function QrCodeBorder(props: React.ComponentPropsWithoutRef<'svg'>) {
|
||||||
return (
|
return (
|
||||||
@@ -29,31 +28,14 @@ export function Footer() {
|
|||||||
<div className="flex items-center text-white">
|
<div className="flex items-center text-white">
|
||||||
<Logomark className="h-10 w-10 flex-none fill-cyan-500" />
|
<Logomark className="h-10 w-10 flex-none fill-cyan-500" />
|
||||||
<div className="ml-4">
|
<div className="ml-4">
|
||||||
<p className="text-base font-semibold">EngageOS</p>
|
<p className="text-base font-semibold">ThreeFold</p>
|
||||||
<p className="mt-1 text-sm">Empowering Purpose-Driven Organizations.</p>
|
<p className="mt-1 text-sm">Decentralized internet infrastructure by everyone, for everyone.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav className="mt-11 flex gap-8">
|
<nav className="mt-8 flex gap-8">
|
||||||
<NavLinks />
|
<NavLinks />
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-800 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-600 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-white">
|
|
||||||
<Link href="#">
|
|
||||||
<span className="absolute inset-0 sm:rounded-2xl" />
|
|
||||||
Download the app
|
|
||||||
</Link>
|
|
||||||
</p>
|
|
||||||
<p className="mt-1 text-sm text-gray-300">
|
|
||||||
Scan the QR code to download the app from the App Store.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<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">
|
<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">
|
<form className="flex w-full justify-center md:w-auto">
|
||||||
@@ -65,7 +47,7 @@ export function Footer() {
|
|||||||
required
|
required
|
||||||
className="w-60 min-w-0 shrink"
|
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="hidden lg:inline">Join our newsletter</span>
|
||||||
<span className="lg:hidden">Join newsletter</span>
|
<span className="lg:hidden">Join newsletter</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
43
src/components/Gallery.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -73,7 +73,7 @@ export function Header() {
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<PopoverButton
|
<PopoverButton
|
||||||
className="relative z-10 -m-2 inline-flex items-center rounded-lg stroke-white p-2 hover:bg-gray-800/50 hover:stroke-gray-300 focus:not-data-focus:outline-hidden active:stroke-white"
|
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"
|
aria-label="Toggle site navigation"
|
||||||
>
|
>
|
||||||
{({ open }) =>
|
{({ open }) =>
|
||||||
@@ -134,9 +134,11 @@ export function Header() {
|
|||||||
</Popover>
|
</Popover>
|
||||||
<div className="flex items-center gap-6 max-lg:hidden">
|
<div className="flex items-center gap-6 max-lg:hidden">
|
||||||
<Button href="/login" variant="outline">
|
<Button href="/login" variant="outline">
|
||||||
Log in
|
Info
|
||||||
|
</Button>
|
||||||
|
<Button href="#" variant="glass">
|
||||||
|
Participate
|
||||||
</Button>
|
</Button>
|
||||||
<Button href="#">Download</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { AppDemo } from '@/components/AppDemo'
|
|||||||
import { AppStoreLink } from '@/components/AppStoreLink'
|
import { AppStoreLink } from '@/components/AppStoreLink'
|
||||||
import HeroHome from './HeroHome'
|
import HeroHome from './HeroHome'
|
||||||
import { Button } from '@/components/Button'
|
import { Button } from '@/components/Button'
|
||||||
|
import { BackgroundIllustration } from '@/components/BackgroundIllustration'
|
||||||
import { Container } from '@/components/Container'
|
import { Container } from '@/components/Container'
|
||||||
import { PhoneFrame } from '@/components/PhoneFrame'
|
import { PhoneFrame } from '@/components/PhoneFrame'
|
||||||
import logoBbc from '@/images/logos/bbc.svg'
|
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 logoTechcrunch from '@/images/logos/techcrunch.svg'
|
||||||
import logoWired from '@/images/logos/wired.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'>) {
|
function PlayIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
|
||||||
return (
|
return (
|
||||||
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" {...props}>
|
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" {...props}>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Image from 'next/image'
|
|||||||
import { Button } from './Button'
|
import { Button } from './Button'
|
||||||
import Engage from '@/images/engage.svg'
|
import Engage from '@/images/engage.svg'
|
||||||
import { gradientText, gradientDark } from '@/components/Gradients'
|
import { gradientText, gradientDark } from '@/components/Gradients'
|
||||||
|
import { h1 as H1 } from '@/components/ui/Text'
|
||||||
|
|
||||||
const navigation = [
|
const navigation = [
|
||||||
{ name: 'Product', href: '#' },
|
{ name: 'Product', href: '#' },
|
||||||
@@ -18,11 +19,11 @@ export default function HeroHome() {
|
|||||||
<div className="">
|
<div className="">
|
||||||
<div className="mx-auto max-w-7xl px-8 lg:px-8">
|
<div className="mx-auto max-w-7xl px-8 lg:px-8">
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<h1 className="text-3xl font-medium tracking-tight text-white lg:text-5xl">
|
<H1 className="text-white">
|
||||||
Empowering Purpose-Driven Organizations.
|
Empowering Purpose-Driven Organizations.
|
||||||
</h1>
|
</H1>
|
||||||
<p className="mt-8 lg:lg:text-lg text-base text-base text-gray-300">
|
<p className="mt-8 lg:lg:text-lg text-base text-gray-300">
|
||||||
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 fundraise—at a fraction of the cost.
|
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 fundraise—at a fraction of the cost.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-12 flex items-center justify-center gap-x-6 relative z-10">
|
<div className="mt-12 flex items-center justify-center gap-x-6 relative z-10">
|
||||||
<Button color="gradient">Get in Touch</Button>
|
<Button color="gradient">Get in Touch</Button>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { Footer } from '@/components/Footer'
|
import { Footer } from '@/components/Footer'
|
||||||
import { Header } from '@/components/Header'
|
import { Header } from '@/components/Header'
|
||||||
|
import { Banner } from '@/components/Banner'
|
||||||
|
|
||||||
export function Layout({ children }: { children: React.ReactNode }) {
|
export function Layout({ children }: { children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
|
<Banner />
|
||||||
<main className="flex-auto">{children}</main>
|
<main className="flex-auto">{children}</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -9,15 +9,14 @@ export function NavLinks() {
|
|||||||
let timeoutRef = useRef<number | null>(null)
|
let timeoutRef = useRef<number | null>(null)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
['Features', '/#features'],
|
['About', '/about'],
|
||||||
['Reviews', '/#reviews'],
|
['Build', '/build'],
|
||||||
['Pricing', '/#pricing'],
|
['Host', '/#pricing'],
|
||||||
['FAQs', '/#faqs'],
|
|
||||||
].map(([label, href], index) => (
|
].map(([label, href], index) => (
|
||||||
<Link
|
<Link
|
||||||
key={label}
|
key={label}
|
||||||
href={href}
|
href={href}
|
||||||
className="relative -mx-3 -my-2 rounded-lg px-3 py-2 text-sm text-gray-300 transition-colors delay-150 hover:text-white 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={() => {
|
onMouseEnter={() => {
|
||||||
if (timeoutRef.current) {
|
if (timeoutRef.current) {
|
||||||
window.clearTimeout(timeoutRef.current)
|
window.clearTimeout(timeoutRef.current)
|
||||||
@@ -33,7 +32,7 @@ export function NavLinks() {
|
|||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{hoveredIndex === index && (
|
{hoveredIndex === index && (
|
||||||
<motion.span
|
<motion.span
|
||||||
className="absolute inset-0 rounded-lg bg-gray-800"
|
className="absolute inset-0 rounded-lg bg-transparent"
|
||||||
layoutId="hoverBackground"
|
layoutId="hoverBackground"
|
||||||
initial={{ opacity: 0 }}
|
initial={{ opacity: 0 }}
|
||||||
animate={{ opacity: 1, transition: { duration: 0.15 } }}
|
animate={{ opacity: 1, transition: { duration: 0.15 } }}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const plans = [
|
|||||||
'Basic learning paths',
|
'Basic learning paths',
|
||||||
'Donations & campaigns',
|
'Donations & campaigns',
|
||||||
'Your logo & colors',
|
'Your logo & colors',
|
||||||
'EngageOS subdomain (yourname.engageos.org)',
|
'ThreeFold subdomain (yourname.ThreeFold.org)',
|
||||||
'Email support',
|
'Email support',
|
||||||
],
|
],
|
||||||
logomarkClassName: 'fill-gray-300',
|
logomarkClassName: 'fill-gray-300',
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const features = [
|
|||||||
{
|
{
|
||||||
name: 'Invite friends for better returns',
|
name: 'Invite friends for better returns',
|
||||||
description:
|
description:
|
||||||
'For every friend you invite to EngageOS, you get insider notifications 5 seconds sooner. And it’s 10 seconds if you invite an insider.',
|
'For every friend you invite to ThreeFold, you get insider notifications 5 seconds sooner. And it’s 10 seconds if you invite an insider.',
|
||||||
icon: DeviceUserIcon,
|
icon: DeviceUserIcon,
|
||||||
screen: InviteScreen,
|
screen: InviteScreen,
|
||||||
},
|
},
|
||||||
@@ -516,7 +516,11 @@ function FeaturesMobile() {
|
|||||||
{features.map((feature, featureIndex) => (
|
{features.map((feature, featureIndex) => (
|
||||||
<div
|
<div
|
||||||
key={featureIndex}
|
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"
|
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">
|
<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.
|
Every feature you need to win. Try it for yourself.
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-2 lg:text-lg text-base text-gray-400">
|
<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 aren’t going to let SEC regulations get in the way of their
|
and aren’t 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.
|
it.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
119
src/components/Products.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -16,37 +16,37 @@ interface Review {
|
|||||||
const reviews: Array<Review> = [
|
const reviews: Array<Review> = [
|
||||||
{
|
{
|
||||||
title: 'A true game-changer for nonprofits.',
|
title: 'A true game-changer for nonprofits.',
|
||||||
body: 'EngageOS allowed us to centralize our volunteer hub, training, and crowdfunding into one platform. We have 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',
|
author: 'Sarah D., Program Director at WomenRise',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'No tech team needed.',
|
title: 'No tech team needed.',
|
||||||
body: 'Launching our own branded platform felt intimidating—until EngageOS. It is 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',
|
author: 'Ahmed K., Director at The Green Schools Alliance',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Empowered our youth programs.',
|
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',
|
author: 'Maria T., Learning Lead at Global Youth Voices',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Secure and sovereign.',
|
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',
|
author: 'Lukas M., CTO at Liberty Commons',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Decentralized. Local-first. Exactly what we needed.',
|
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',
|
author: 'Grace N., Digital Programs at Umoja Health Network',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'The best decision we made this year.',
|
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',
|
author: 'Jonas F., COO at Youth in Action Europe',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
@@ -58,19 +58,19 @@ const reviews: Array<Review> = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Our community feels seen and heard.',
|
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',
|
author: 'Nicolas R., Communications Lead at OurStories Foundation',
|
||||||
rating: 5,
|
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.',
|
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',
|
author: 'Delphine A., Global Lead at Future Farmers',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'This platform is our movement.',
|
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.',
|
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',
|
author: 'Ravi P., Strategy Director at Clean Energy for All',
|
||||||
rating: 5,
|
rating: 5,
|
||||||
},
|
},
|
||||||
@@ -259,7 +259,7 @@ export function Reviews() {
|
|||||||
id="reviews-title"
|
id="reviews-title"
|
||||||
className="text-3xl font-medium tracking-tight text-white 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>
|
</h2>
|
||||||
<p className="mt-2 lg:text-lg text-base text-gray-300 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.
|
Thousands of people have doubled their net-worth in the last 30 days.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export function SecondaryFeatures() {
|
|||||||
The Platform Built for Purpose-driven Organizations
|
The Platform Built for Purpose-driven Organizations
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-4 lg:text-lg text-base text-gray-600">
|
<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 headquarters—no 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 headquarters—no tech team needed.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative overflow-hidden pt-16">
|
<div className="relative overflow-hidden pt-16">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Spotlight } from "@/components/ui/spotlight";
|
import { Spotlight } from "@/components/ui/Spotlight";
|
||||||
import { Logomark } from "@/components/Logo";
|
import { Logomark } from "@/components/Logo";
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
|
|
||||||
@@ -22,23 +22,23 @@ export function SpotlightPreview() {
|
|||||||
/>
|
/>
|
||||||
<div className="relative z-10 mx-auto w-full max-w-7xl p-4 pt-20 md:pt-0">
|
<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="flex justify-center mb-6">
|
||||||
<div className="mb-4 relative rounded-full px-3 py-1 text-sm/6 text-gray-600 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
|
<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.{' '}
|
Announcing The New TF Marketplace.{' '}
|
||||||
<a href="#" className="font-semibold text-white hover:text-gray-200">
|
<a href="#" className="font-semibold text-white hover:text-gray-800">
|
||||||
<span aria-hidden="true" className="absolute inset-0" />
|
<span aria-hidden="true" className="absolute inset-0" />
|
||||||
Read more <span aria-hidden="true">→</span>
|
Read more <span aria-hidden="true">→</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<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.
|
Built by Everyone <br /> for Everyone.
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mx-auto mt-8 max-w-lg text-center text-base lg:text-xl font-light text-neutral-300">
|
<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.
|
ThreeFold is a fully operational, decentralized internet infrastructure – deployed locally, scalable globally, and owned and powered by the people.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 flex flex-col sm:flex-row justify-center gap-4">
|
<div className="mt-8 flex flex-col sm:flex-row justify-center gap-4 animate-fade-in-delay-4">
|
||||||
<Button href="/login" variant="outline" color="gray">
|
<Button href="/login" variant="glass">
|
||||||
Start Building
|
Start Building
|
||||||
</Button>
|
</Button>
|
||||||
<Button href="#" variant="outline" color="gray">
|
<Button href="#" variant="outline" color="gray">
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { StackedCubes } from "@/components/ui/StackedCubes";
|
import { StackedCubes } from "@/components/ui/StackedCubes";
|
||||||
|
import { Button } from "@/components/Button";
|
||||||
|
import { motion, useInView } from "framer-motion";
|
||||||
|
import { useRef } from "react";
|
||||||
|
|
||||||
export function StackSectionPreview() {
|
export function StackSectionPreview() {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="w-full bg-transparent px-4 py-8 sm:px-6 sm:pb-12 lg:px-8 relative">
|
<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 */}
|
{/* 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-[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="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" />
|
||||||
@@ -13,18 +18,40 @@ export function StackSectionPreview() {
|
|||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 lg:gap-16 items-center lg:items-start">
|
<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) */}
|
{/* Left Column - Text (1/3 width) */}
|
||||||
<div className="text-center lg:text-left lg:col-span-1 order-1 lg:order-1">
|
<div className="text-center lg:text-left lg:col-span-1 order-1 lg:order-1">
|
||||||
<h2 className="text-xl sm:text-2xl font-semibold tracking-tight leading-tight text-white lg:text-4xl">
|
<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
|
A Decentralized Infrastructure Layer
|
||||||
</h2>
|
</motion.h2>
|
||||||
<p className="mt-4 sm:mt-6 text-sm font-light text-pretty text-white lg:text-base">
|
<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.
|
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.
|
||||||
</p>
|
</motion.p>
|
||||||
<button className="mt-4" variant="primary" color="transparent" href="https://threefold.io/build" >Discover How It Works →</button>
|
<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>
|
</div>
|
||||||
|
|
||||||
{/* Right Column - Stacked Cubes (2/3 width) */}
|
{/* 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">
|
<div className="lg:col-span-2 flex items-center justify-center lg:justify-start order-2 lg:order-2">
|
||||||
<StackedCubes />
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
91
src/components/TfDashboard.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@ export default function Tractions() {
|
|||||||
Trusted by Changemakers worldwide
|
Trusted by Changemakers worldwide
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-6 lg:text-lg text-base text-gray-300">
|
<p className="mt-6 lg:text-lg text-base text-gray-300">
|
||||||
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.
|
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>
|
</p>
|
||||||
<dl className="mt-16 grid max-w-xl grid-cols-1 gap-8 sm:mt-20 sm:grid-cols-2 xl:mt-16">
|
<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) => (
|
{stats.map((stat) => (
|
||||||
|
|||||||
9
src/components/ui/Text.tsx
Normal 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 }
|
||||||
|
Before Width: | Height: | Size: 4.0 MiB |
|
Before Width: | Height: | Size: 1.7 MiB |
@@ -1,231 +0,0 @@
|
|||||||
<svg width="366" height="729" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g mask="url(#mask)">
|
|
||||||
<g filter="url(#a)">
|
|
||||||
<path
|
|
||||||
d="M363.315 64.213C363.315 22.99 341.312 1 300.092 1H66.751C25.53 1 3.528 22.99 3.528 64.213v44.68l-.857.143A2 2 0 0 0 1 111.009v24.611a2 2 0 0 0 1.671 1.973l.95.158a2.26 2.26 0 0 1-.093.236v26.173c.212.1.398.296.541.643l-1.398.233A2 2 0 0 0 1 167.009v47.611a2 2 0 0 0 1.671 1.973l1.368.228c-.139.319-.314.533-.511.653v16.637c.221.104.414.313.56.689l-1.417.236A2 2 0 0 0 1 237.009v47.611a2 2 0 0 0 1.671 1.973l1.347.225c-.135.294-.302.493-.49.607v377.681c0 41.213 22 63.208 63.223 63.208h95.074c.947-.504 2.717-.843 4.745-.843l.141.001h.194l.086-.001 33.704.005c1.849.043 3.442.37 4.323.838h95.074c41.222 0 63.223-21.999 63.223-63.212v-394.63c-.259-.275-.48-.796-.63-1.47l-.011-.133 1.655-.276A2 2 0 0 0 366 266.62v-77.611a2 2 0 0 0-1.671-1.973l-1.712-.285c.148-.839.396-1.491.698-1.811V64.213Z"
|
|
||||||
fill="url(#b)" />
|
|
||||||
<path
|
|
||||||
d="M363.315 64.213C363.315 22.99 341.312 1 300.092 1H66.751C25.53 1 3.528 22.99 3.528 64.213v44.68l-.857.143A2 2 0 0 0 1 111.009v24.611a2 2 0 0 0 1.671 1.973l.95.158a2.26 2.26 0 0 1-.093.236v26.173c.212.1.398.296.541.643l-1.398.233A2 2 0 0 0 1 167.009v47.611a2 2 0 0 0 1.671 1.973l1.368.228c-.139.319-.314.533-.511.653v16.637c.221.104.414.313.56.689l-1.417.236A2 2 0 0 0 1 237.009v47.611a2 2 0 0 0 1.671 1.973l1.347.225c-.135.294-.302.493-.49.607v377.681c0 41.213 22 63.208 63.223 63.208h95.074c.947-.504 2.717-.843 4.745-.843l.141.001h.194l.086-.001 33.704.005c1.849.043 3.442.37 4.323.838h95.074c41.222 0 63.223-21.999 63.223-63.212v-394.63c-.259-.275-.48-.796-.63-1.47l-.011-.133 1.655-.276A2 2 0 0 0 366 266.62v-77.611a2 2 0 0 0-1.671-1.973l-1.712-.285c.148-.839.396-1.491.698-1.811V64.213Z"
|
|
||||||
fill="url(#c)" />
|
|
||||||
</g>
|
|
||||||
<g filter="url(#d)">
|
|
||||||
<path
|
|
||||||
d="M5 133.772v-21.15c0-1.359-.54-2.661-1.5-3.622-.844-.073-2.496.257-2.496 2.157v24.562c.406 2.023 2.605 2.023 2.605 2.023A6.363 6.363 0 0 0 5 133.772Z"
|
|
||||||
fill="url(#e)" />
|
|
||||||
<path
|
|
||||||
d="M5 133.772v-21.15c0-1.359-.54-2.661-1.5-3.622-.844-.073-2.496.257-2.496 2.157v24.562c.406 2.023 2.605 2.023 2.605 2.023A6.363 6.363 0 0 0 5 133.772Z"
|
|
||||||
fill="url(#f)" fill-opacity=".1" />
|
|
||||||
</g>
|
|
||||||
<g filter="url(#g)">
|
|
||||||
<path
|
|
||||||
d="M5 213.772v-46.15c0-1.359-.54-2.661-1.5-3.622-.844-.073-2.496.257-2.496 2.157v49.562c.406 2.023 2.605 2.023 2.605 2.023A6.363 6.363 0 0 0 5 213.772Z"
|
|
||||||
fill="url(#h)" />
|
|
||||||
<path
|
|
||||||
d="M5 213.772v-46.15c0-1.359-.54-2.661-1.5-3.622-.844-.073-2.496.257-2.496 2.157v49.562c.406 2.023 2.605 2.023 2.605 2.023A6.363 6.363 0 0 0 5 213.772Z"
|
|
||||||
fill="url(#i)" fill-opacity=".1" />
|
|
||||||
</g>
|
|
||||||
<g filter="url(#j)">
|
|
||||||
<path
|
|
||||||
d="M5 283.772v-46.15c0-1.359-.54-2.661-1.5-3.622-.844-.073-2.496.257-2.496 2.157v49.562c.406 2.023 2.605 2.023 2.605 2.023A6.363 6.363 0 0 0 5 283.772Z"
|
|
||||||
fill="url(#k)" />
|
|
||||||
<path
|
|
||||||
d="M5 283.772v-46.15c0-1.359-.54-2.661-1.5-3.622-.844-.073-2.496.257-2.496 2.157v49.562c.406 2.023 2.605 2.023 2.605 2.023A6.363 6.363 0 0 0 5 283.772Z"
|
|
||||||
fill="url(#l)" fill-opacity=".1" />
|
|
||||||
</g>
|
|
||||||
<g filter="url(#m)">
|
|
||||||
<path
|
|
||||||
d="M362.004 266.772v-78.15a5.12 5.12 0 0 1 1.5-3.622c.844-.073 2.496.257 2.496 2.157v81.562c-.406 2.023-2.605 2.023-2.605 2.023a6.359 6.359 0 0 1-1.391-3.97Z"
|
|
||||||
fill="url(#n)" />
|
|
||||||
<path
|
|
||||||
d="M362.004 266.772v-78.15a5.12 5.12 0 0 1 1.5-3.622c.844-.073 2.496.257 2.496 2.157v81.562c-.406 2.023-2.605 2.023-2.605 2.023a6.359 6.359 0 0 1-1.391-3.97Z"
|
|
||||||
fill="url(#o)" fill-opacity=".1" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
d="M305 14.5H59c-24.577 0-44.5 19.923-44.5 44.5v615c0 23.472 19.028 42.5 42.5 42.5h250c23.472 0 42.5-19.028 42.5-42.5V59c0-24.577-19.923-44.5-44.5-44.5Z"
|
|
||||||
stroke="url(#p)" stroke-opacity=".5" />
|
|
||||||
<g filter="url(#q)" shape-rendering="crispEdges">
|
|
||||||
<path
|
|
||||||
d="M16 59c0-23.748 19.252-43 43-43h246c23.748 0 43 19.252 43 43v615c0 23.196-18.804 42-42 42H58c-23.196 0-42-18.804-42-42V59Z"
|
|
||||||
fill="url(#r)" fill-opacity=".3" />
|
|
||||||
<path
|
|
||||||
d="M305 15.5H59c-24.024 0-43.5 19.476-43.5 43.5v615c0 23.472 19.028 42.5 42.5 42.5h248c23.472 0 42.5-19.028 42.5-42.5V59c0-24.024-19.476-43.5-43.5-43.5Z"
|
|
||||||
stroke="#000" stroke-opacity=".07" />
|
|
||||||
</g>
|
|
||||||
<g filter="url(#s)">
|
|
||||||
<rect x="154" y="29" width="56" height="5" rx="2.5" fill="#D4D4D4" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<mask id="mask">
|
|
||||||
<rect width="366" height="729" fill="#fff" />
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
||||||
d="M89.728 24a4.213 4.213 0 0 1 4.213 4.212v2.527c0 10.235 8.3 18.532 18.539 18.532h139.04c10.239 0 18.539-8.297 18.539-18.532v-2.527A4.212 4.212 0 0 1 274.272 24h32.864C325.286 24 340 38.71 340 56.853v618.295c0 18.144-14.714 32.853-32.864 32.853H56.864c-18.15 0-32.864-14.709-32.864-32.853V56.853C24 38.709 38.714 24 56.864 24h32.864Z"
|
|
||||||
fill="#000" />
|
|
||||||
</mask>
|
|
||||||
<linearGradient id="e" x1="1.004" y1="123.367" x2="5" y2="123.367" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#D4D4D4" />
|
|
||||||
<stop offset="1" stop-color="#E6E6E6" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="f" x1="3.002" y1="108.991" x2="3.002" y2="116.75" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#171717" />
|
|
||||||
<stop offset=".783" stop-color="#171717" stop-opacity="0" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="h" x1="1.004" y1="190.867" x2="5" y2="190.867" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#D4D4D4" />
|
|
||||||
<stop offset="1" stop-color="#E6E6E6" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="i" x1="3.002" y1="163.991" x2="3.002" y2="178.497" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#171717" />
|
|
||||||
<stop offset=".783" stop-color="#171717" stop-opacity="0" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="k" x1="1.004" y1="260.867" x2="5" y2="260.867" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#D4D4D4" />
|
|
||||||
<stop offset="1" stop-color="#E6E6E6" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="l" x1="3.002" y1="233.991" x2="3.002" y2="248.497" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#171717" />
|
|
||||||
<stop offset=".783" stop-color="#171717" stop-opacity="0" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="n" x1="362.004" y1="226.25" x2="366" y2="226.25" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop offset=".124" stop-color="#E6E6E6" />
|
|
||||||
<stop offset="1" stop-color="#D4D4D4" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="o" x1="364.002" y1="184.991" x2="364.002" y2="208.134" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#171717" />
|
|
||||||
<stop offset=".783" stop-color="#171717" stop-opacity="0" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="p" x1="182" y1="15" x2="182" y2="716" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#fff" />
|
|
||||||
<stop offset=".381" stop-color="#fff" stop-opacity="0" />
|
|
||||||
</linearGradient>
|
|
||||||
<filter id="a" x="-1" y="-1" width="367" height="730.314" filterUnits="userSpaceOnUse"
|
|
||||||
color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
||||||
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dy="-2" />
|
|
||||||
<feGaussianBlur stdDeviation="1.5" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" />
|
|
||||||
<feBlend in2="shape" result="effect1_innerShadow_104_2007" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="-2" />
|
|
||||||
<feGaussianBlur stdDeviation="2" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0.0901961 0 0 0 0 0.0901961 0 0 0 0 0.0901961 0 0 0 0.17 0" />
|
|
||||||
<feBlend in2="effect1_innerShadow_104_2007" result="effect2_innerShadow_104_2007" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dy="2" />
|
|
||||||
<feGaussianBlur stdDeviation=".5" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.6 0" />
|
|
||||||
<feBlend in2="effect2_innerShadow_104_2007" result="effect3_innerShadow_104_2007" />
|
|
||||||
</filter>
|
|
||||||
<filter id="d" x="1.004" y="108.991" width="4.996" height="28.751" filterUnits="userSpaceOnUse"
|
|
||||||
color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="out" />
|
|
||||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0" />
|
|
||||||
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_104_2007" />
|
|
||||||
<feBlend in="SourceGraphic" in2="effect1_dropShadow_104_2007" result="shape" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="-1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
|
|
||||||
<feBlend in2="shape" result="effect2_innerShadow_104_2007" />
|
|
||||||
</filter>
|
|
||||||
<filter id="g" x="1.004" y="163.991" width="4.996" height="53.751" filterUnits="userSpaceOnUse"
|
|
||||||
color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="out" />
|
|
||||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0" />
|
|
||||||
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_104_2007" />
|
|
||||||
<feBlend in="SourceGraphic" in2="effect1_dropShadow_104_2007" result="shape" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="-1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
|
|
||||||
<feBlend in2="shape" result="effect2_innerShadow_104_2007" />
|
|
||||||
</filter>
|
|
||||||
<filter id="j" x="1.004" y="233.991" width="4.996" height="53.751" filterUnits="userSpaceOnUse"
|
|
||||||
color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="out" />
|
|
||||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0" />
|
|
||||||
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_104_2007" />
|
|
||||||
<feBlend in="SourceGraphic" in2="effect1_dropShadow_104_2007" result="shape" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="-1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
|
|
||||||
<feBlend in2="shape" result="effect2_innerShadow_104_2007" />
|
|
||||||
</filter>
|
|
||||||
<filter id="m" x="361.004" y="184.991" width="4.996" height="85.751" filterUnits="userSpaceOnUse"
|
|
||||||
color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="-1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="out" />
|
|
||||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0" />
|
|
||||||
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_104_2007" />
|
|
||||||
<feBlend in="SourceGraphic" in2="effect1_dropShadow_104_2007" result="shape" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dx="1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
|
|
||||||
<feBlend in2="shape" result="effect2_innerShadow_104_2007" />
|
|
||||||
</filter>
|
|
||||||
<filter id="q" x="15" y="15" width="334" height="703" filterUnits="userSpaceOnUse"
|
|
||||||
color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dy="1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="out" />
|
|
||||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0" />
|
|
||||||
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_104_2007" />
|
|
||||||
<feBlend in="SourceGraphic" in2="effect1_dropShadow_104_2007" result="shape" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dy="1" />
|
|
||||||
<feGaussianBlur stdDeviation="2.5" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0" />
|
|
||||||
<feBlend in2="shape" result="effect2_innerShadow_104_2007" />
|
|
||||||
</filter>
|
|
||||||
<filter id="s" x="154" y="29" width="56" height="6" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dy="1" />
|
|
||||||
<feComposite in2="hardAlpha" operator="out" />
|
|
||||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.3 0" />
|
|
||||||
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_104_2007" />
|
|
||||||
<feBlend in="SourceGraphic" in2="effect1_dropShadow_104_2007" result="shape" />
|
|
||||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
|
|
||||||
<feOffset dy="1" />
|
|
||||||
<feGaussianBlur stdDeviation=".5" />
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
||||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0" />
|
|
||||||
<feBlend in2="shape" result="effect2_innerShadow_104_2007" />
|
|
||||||
</filter>
|
|
||||||
<radialGradient id="b" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(0 727 -642 0 184 1)">
|
|
||||||
<stop stop-color="#FAFAFA" />
|
|
||||||
<stop offset="1" stop-color="#E6E6E6" />
|
|
||||||
</radialGradient>
|
|
||||||
<radialGradient id="c" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(0 319 -295.5 0 183.5 1)">
|
|
||||||
<stop stop-color="#fff" />
|
|
||||||
<stop offset=".533" stop-color="#fff" stop-opacity="0" />
|
|
||||||
</radialGradient>
|
|
||||||
<radialGradient id="r" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(0 689 -326.783 0 182 27)">
|
|
||||||
<stop offset=".319" stop-color="#D4D4D4" />
|
|
||||||
<stop offset="1" stop-color="#E6E6E6" />
|
|
||||||
</radialGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,118 +0,0 @@
|
|||||||
<svg width="80" height="80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M3.2 0H0v3.2h3.2V0ZM3.2 3.2H0v3.2h3.2V3.2ZM3.2 6.4H0v3.2h3.2V6.4Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M3.2 9.6H0v3.2h3.2V9.6ZM3.2 12.8H0V16h3.2v-3.2ZM3.2 16H0v3.2h3.2V16ZM3.2 19.2H0v3.2h3.2v-3.2ZM3.2 25.6H0v3.2h3.2v-3.2ZM3.2 35.2H0v3.2h3.2v-3.2ZM3.2 57.6H0v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M3.2 60.8H0V64h3.2v-3.2ZM3.2 64H0v3.2h3.2V64ZM3.2 67.2H0v3.2h3.2v-3.2ZM3.2 70.4H0v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M3.2 73.6H0v3.2h3.2v-3.2ZM3.2 76.8H0V80h3.2v-3.2ZM6.4 0H3.2v3.2h3.2V0ZM6.4 19.2H3.2v3.2h3.2v-3.2ZM6.4 25.6H3.2v3.2h3.2v-3.2ZM6.4 28.8H3.2V32h3.2v-3.2ZM6.4 32H3.2v3.2h3.2V32ZM6.4 35.2H3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M6.4 38.4H3.2v3.2h3.2v-3.2ZM6.4 48H3.2v3.2h3.2V48ZM6.4 51.2H3.2v3.2h3.2v-3.2ZM6.4 57.6H3.2v3.2h3.2v-3.2ZM6.4 76.8H3.2V80h3.2v-3.2ZM9.6 0H6.4v3.2h3.2V0ZM9.6 6.4H6.4v3.2h3.2V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M9.6 9.6H6.4v3.2h3.2V9.6ZM9.6 12.8H6.4V16h3.2v-3.2ZM9.6 19.2H6.4v3.2h3.2v-3.2ZM9.6 28.8H6.4V32h3.2v-3.2ZM9.6 32H6.4v3.2h3.2V32ZM9.6 41.6H6.4v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M9.6 44.8H6.4V48h3.2v-3.2ZM9.6 57.6H6.4v3.2h3.2v-3.2ZM9.6 64H6.4v3.2h3.2V64ZM9.6 67.2H6.4v3.2h3.2v-3.2ZM9.6 70.4H6.4v3.2h3.2v-3.2ZM9.6 76.8H6.4V80h3.2v-3.2ZM12.8 0H9.6v3.2h3.2V0ZM12.8 6.4H9.6v3.2h3.2V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M12.8 9.6H9.6v3.2h3.2V9.6ZM12.8 12.8H9.6V16h3.2v-3.2ZM12.8 19.2H9.6v3.2h3.2v-3.2ZM12.8 25.6H9.6v3.2h3.2v-3.2ZM12.8 38.4H9.6v3.2h3.2v-3.2ZM12.8 48H9.6v3.2h3.2V48ZM12.8 51.2H9.6v3.2h3.2v-3.2ZM12.8 57.6H9.6v3.2h3.2v-3.2ZM12.8 64H9.6v3.2h3.2V64ZM12.8 67.2H9.6v3.2h3.2v-3.2ZM12.8 70.4H9.6v3.2h3.2v-3.2ZM12.8 76.8H9.6V80h3.2v-3.2ZM16 0h-3.2v3.2H16V0ZM16 6.4h-3.2v3.2H16V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M16 9.6h-3.2v3.2H16V9.6ZM16 12.8h-3.2V16H16v-3.2ZM16 19.2h-3.2v3.2H16v-3.2ZM16 25.6h-3.2v3.2H16v-3.2ZM16 41.6h-3.2v3.2H16v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M16 44.8h-3.2V48H16v-3.2ZM16 57.6h-3.2v3.2H16v-3.2ZM16 64h-3.2v3.2H16V64ZM16 67.2h-3.2v3.2H16v-3.2ZM16 70.4h-3.2v3.2H16v-3.2ZM16 76.8h-3.2V80H16v-3.2ZM19.2 0H16v3.2h3.2V0ZM19.2 19.2H16v3.2h3.2v-3.2ZM19.2 28.8H16V32h3.2v-3.2ZM19.2 44.8H16V48h3.2v-3.2ZM19.2 57.6H16v3.2h3.2v-3.2ZM19.2 76.8H16V80h3.2v-3.2ZM22.4 0h-3.2v3.2h3.2V0ZM22.4 3.2h-3.2v3.2h3.2V3.2ZM22.4 6.4h-3.2v3.2h3.2V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M22.4 9.6h-3.2v3.2h3.2V9.6ZM22.4 12.8h-3.2V16h3.2v-3.2ZM22.4 16h-3.2v3.2h3.2V16ZM22.4 19.2h-3.2v3.2h3.2v-3.2ZM22.4 25.6h-3.2v3.2h3.2v-3.2ZM22.4 32h-3.2v3.2h3.2V32ZM22.4 38.4h-3.2v3.2h3.2v-3.2ZM22.4 44.8h-3.2V48h3.2v-3.2ZM22.4 51.2h-3.2v3.2h3.2v-3.2ZM22.4 57.6h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M22.4 60.8h-3.2V64h3.2v-3.2ZM22.4 64h-3.2v3.2h3.2V64ZM22.4 67.2h-3.2v3.2h3.2v-3.2ZM22.4 70.4h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M22.4 73.6h-3.2v3.2h3.2v-3.2ZM22.4 76.8h-3.2V80h3.2v-3.2ZM25.6 28.8h-3.2V32h3.2v-3.2ZM25.6 32h-3.2v3.2h3.2V32ZM25.6 35.2h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M25.6 38.4h-3.2v3.2h3.2v-3.2ZM25.6 44.8h-3.2V48h3.2v-3.2ZM25.6 48h-3.2v3.2h3.2V48ZM25.6 51.2h-3.2v3.2h3.2v-3.2ZM28.8 0h-3.2v3.2h3.2V0ZM28.8 19.2h-3.2v3.2h3.2v-3.2ZM28.8 22.4h-3.2v3.2h3.2v-3.2ZM28.8 28.8h-3.2V32h3.2v-3.2ZM28.8 32h-3.2v3.2h3.2V32ZM28.8 35.2h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M28.8 38.4h-3.2v3.2h3.2v-3.2ZM28.8 44.8h-3.2V48h3.2v-3.2ZM28.8 51.2h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M28.8 54.4h-3.2v3.2h3.2v-3.2ZM28.8 64h-3.2v3.2h3.2V64ZM28.8 67.2h-3.2v3.2h3.2v-3.2ZM28.8 73.6h-3.2v3.2h3.2v-3.2ZM28.8 76.8h-3.2V80h3.2v-3.2ZM32 0h-3.2v3.2H32V0ZM32 6.4h-3.2v3.2H32V6.4ZM32 16h-3.2v3.2H32V16ZM32 22.4h-3.2v3.2H32v-3.2ZM32 25.6h-3.2v3.2H32v-3.2ZM32 32h-3.2v3.2H32V32ZM32 38.4h-3.2v3.2H32v-3.2ZM32 54.4h-3.2v3.2H32v-3.2ZM32 57.6h-3.2v3.2H32v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M32 60.8h-3.2V64H32v-3.2ZM32 76.8h-3.2V80H32v-3.2ZM35.2 0H32v3.2h3.2V0ZM35.2 9.6H32v3.2h3.2V9.6ZM35.2 12.8H32V16h3.2v-3.2ZM35.2 19.2H32v3.2h3.2v-3.2ZM35.2 28.8H32V32h3.2v-3.2ZM35.2 38.4H32v3.2h3.2v-3.2ZM35.2 41.6H32v3.2h3.2v-3.2ZM35.2 48H32v3.2h3.2V48ZM35.2 57.6H32v3.2h3.2v-3.2ZM35.2 64H32v3.2h3.2V64ZM35.2 76.8H32V80h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M38.4 0h-3.2v3.2h3.2V0ZM38.4 3.2h-3.2v3.2h3.2V3.2ZM38.4 6.4h-3.2v3.2h3.2V6.4Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M38.4 9.6h-3.2v3.2h3.2V9.6ZM38.4 12.8h-3.2V16h3.2v-3.2ZM38.4 16h-3.2v3.2h3.2V16ZM38.4 51.2h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M38.4 54.4h-3.2v3.2h3.2v-3.2ZM38.4 60.8h-3.2V64h3.2v-3.2ZM38.4 64h-3.2v3.2h3.2V64ZM38.4 70.4h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M38.4 73.6h-3.2v3.2h3.2v-3.2ZM38.4 76.8h-3.2V80h3.2v-3.2ZM41.6 3.2h-3.2v3.2h3.2V3.2ZM41.6 12.8h-3.2V16h3.2v-3.2ZM41.6 19.2h-3.2v3.2h3.2v-3.2ZM41.6 22.4h-3.2v3.2h3.2v-3.2ZM41.6 25.6h-3.2v3.2h3.2v-3.2ZM41.6 32h-3.2v3.2h3.2V32ZM41.6 41.6h-3.2v3.2h3.2v-3.2ZM41.6 48h-3.2v3.2h3.2V48ZM41.6 51.2h-3.2v3.2h3.2v-3.2ZM41.6 57.6h-3.2v3.2h3.2v-3.2ZM41.6 67.2h-3.2v3.2h3.2v-3.2ZM41.6 73.6h-3.2v3.2h3.2v-3.2ZM41.6 76.8h-3.2V80h3.2v-3.2ZM44.8 0h-3.2v3.2h3.2V0ZM44.8 6.4h-3.2v3.2h3.2V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M44.8 22.4h-3.2v3.2h3.2v-3.2ZM44.8 32h-3.2v3.2h3.2V32ZM44.8 41.6h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path d="M44.8 44.8h-3.2V48h3.2v-3.2ZM44.8 51.2h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path d="M44.8 54.4h-3.2v3.2h3.2v-3.2ZM44.8 57.6h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M44.8 60.8h-3.2V64h3.2v-3.2ZM44.8 64h-3.2v3.2h3.2V64ZM44.8 67.2h-3.2v3.2h3.2v-3.2ZM44.8 70.4h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M44.8 73.6h-3.2v3.2h3.2v-3.2ZM44.8 76.8h-3.2V80h3.2v-3.2ZM48 0h-3.2v3.2H48V0ZM48 16h-3.2v3.2H48V16ZM48 19.2h-3.2v3.2H48v-3.2ZM48 25.6h-3.2v3.2H48v-3.2ZM48 44.8h-3.2V48H48v-3.2ZM48 54.4h-3.2v3.2H48v-3.2ZM48 57.6h-3.2v3.2H48v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M48 60.8h-3.2V64H48v-3.2ZM48 67.2h-3.2v3.2H48v-3.2ZM51.2 6.4H48v3.2h3.2V6.4ZM51.2 12.8H48V16h3.2v-3.2ZM51.2 22.4H48v3.2h3.2v-3.2ZM51.2 25.6H48v3.2h3.2v-3.2ZM51.2 28.8H48V32h3.2v-3.2ZM51.2 32H48v3.2h3.2V32ZM51.2 35.2H48v3.2h3.2v-3.2ZM51.2 41.6H48v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M51.2 44.8H48V48h3.2v-3.2ZM51.2 54.4H48v3.2h3.2v-3.2ZM51.2 60.8H48V64h3.2v-3.2ZM51.2 64H48v3.2h3.2V64ZM54.4 6.4h-3.2v3.2h3.2V6.4ZM54.4 12.8h-3.2V16h3.2v-3.2ZM54.4 19.2h-3.2v3.2h3.2v-3.2ZM54.4 28.8h-3.2V32h3.2v-3.2ZM54.4 32h-3.2v3.2h3.2V32ZM54.4 38.4h-3.2v3.2h3.2v-3.2ZM54.4 48h-3.2v3.2h3.2V48Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M54.4 51.2h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path d="M54.4 54.4h-3.2v3.2h3.2v-3.2ZM54.4 57.6h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M54.4 60.8h-3.2V64h3.2v-3.2ZM54.4 64h-3.2v3.2h3.2V64ZM54.4 67.2h-3.2v3.2h3.2v-3.2ZM54.4 70.4h-3.2v3.2h3.2v-3.2ZM54.4 76.8h-3.2V80h3.2v-3.2ZM57.6 32h-3.2v3.2h3.2V32ZM57.6 41.6h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M57.6 44.8h-3.2V48h3.2v-3.2ZM57.6 51.2h-3.2v3.2h3.2v-3.2ZM57.6 64h-3.2v3.2h3.2V64ZM57.6 70.4h-3.2v3.2h3.2v-3.2ZM57.6 76.8h-3.2V80h3.2v-3.2ZM60.8 0h-3.2v3.2h3.2V0ZM60.8 3.2h-3.2v3.2h3.2V3.2ZM60.8 6.4h-3.2v3.2h3.2V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M60.8 9.6h-3.2v3.2h3.2V9.6ZM60.8 12.8h-3.2V16h3.2v-3.2ZM60.8 16h-3.2v3.2h3.2V16ZM60.8 19.2h-3.2v3.2h3.2v-3.2ZM60.8 25.6h-3.2v3.2h3.2v-3.2ZM60.8 35.2h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M60.8 38.4h-3.2v3.2h3.2v-3.2ZM60.8 44.8h-3.2V48h3.2v-3.2ZM60.8 48h-3.2v3.2h3.2V48ZM60.8 51.2h-3.2v3.2h3.2v-3.2ZM60.8 57.6h-3.2v3.2h3.2v-3.2ZM60.8 64h-3.2v3.2h3.2V64ZM60.8 67.2h-3.2v3.2h3.2v-3.2ZM64 0h-3.2v3.2H64V0ZM64 19.2h-3.2v3.2H64v-3.2ZM64 28.8h-3.2V32H64v-3.2ZM64 38.4h-3.2v3.2H64v-3.2ZM64 48h-3.2v3.2H64V48ZM64 51.2h-3.2v3.2H64v-3.2ZM64 64h-3.2v3.2H64V64ZM64 73.6h-3.2v3.2H64v-3.2ZM67.2 0H64v3.2h3.2V0ZM67.2 6.4H64v3.2h3.2V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M67.2 9.6H64v3.2h3.2V9.6ZM67.2 12.8H64V16h3.2v-3.2ZM67.2 19.2H64v3.2h3.2v-3.2ZM67.2 28.8H64V32h3.2v-3.2ZM67.2 41.6H64v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M67.2 44.8H64V48h3.2v-3.2ZM67.2 51.2H64v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path d="M67.2 54.4H64v3.2h3.2v-3.2ZM67.2 57.6H64v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path d="M67.2 60.8H64V64h3.2v-3.2ZM67.2 64H64v3.2h3.2V64ZM67.2 70.4H64v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path d="M67.2 73.6H64v3.2h3.2v-3.2ZM70.4 0h-3.2v3.2h3.2V0ZM70.4 6.4h-3.2v3.2h3.2V6.4Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M70.4 9.6h-3.2v3.2h3.2V9.6ZM70.4 12.8h-3.2V16h3.2v-3.2ZM70.4 19.2h-3.2v3.2h3.2v-3.2ZM70.4 28.8h-3.2V32h3.2v-3.2ZM70.4 32h-3.2v3.2h3.2V32ZM70.4 35.2h-3.2v3.2h3.2v-3.2ZM70.4 44.8h-3.2V48h3.2v-3.2ZM70.4 48h-3.2v3.2h3.2V48ZM70.4 70.4h-3.2v3.2h3.2v-3.2ZM70.4 76.8h-3.2V80h3.2v-3.2ZM73.6 0h-3.2v3.2h3.2V0Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M73.6 6.4h-3.2v3.2h3.2V6.4Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M73.6 9.6h-3.2v3.2h3.2V9.6ZM73.6 12.8h-3.2V16h3.2v-3.2ZM73.6 19.2h-3.2v3.2h3.2v-3.2ZM73.6 28.8h-3.2V32h3.2v-3.2ZM73.6 35.2h-3.2v3.2h3.2v-3.2ZM73.6 44.8h-3.2V48h3.2v-3.2ZM73.6 48h-3.2v3.2h3.2V48ZM73.6 51.2h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M73.6 54.4h-3.2v3.2h3.2v-3.2ZM73.6 70.4h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M73.6 73.6h-3.2v3.2h3.2v-3.2ZM76.8 0h-3.2v3.2h3.2V0ZM76.8 19.2h-3.2v3.2h3.2v-3.2ZM76.8 28.8h-3.2V32h3.2v-3.2ZM76.8 35.2h-3.2v3.2h3.2v-3.2ZM76.8 41.6h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M76.8 44.8h-3.2V48h3.2v-3.2ZM76.8 51.2h-3.2v3.2h3.2v-3.2Z" fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M76.8 54.4h-3.2v3.2h3.2v-3.2ZM76.8 64h-3.2v3.2h3.2V64ZM76.8 67.2h-3.2v3.2h3.2v-3.2ZM76.8 70.4h-3.2v3.2h3.2v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M76.8 73.6h-3.2v3.2h3.2v-3.2ZM80 0h-3.2v3.2H80V0ZM80 3.2h-3.2v3.2H80V3.2ZM80 6.4h-3.2v3.2H80V6.4Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M80 9.6h-3.2v3.2H80V9.6ZM80 12.8h-3.2V16H80v-3.2ZM80 16h-3.2v3.2H80V16ZM80 19.2h-3.2v3.2H80v-3.2ZM80 25.6h-3.2v3.2H80v-3.2ZM80 32h-3.2v3.2H80V32ZM80 35.2h-3.2v3.2H80v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path
|
|
||||||
d="M80 38.4h-3.2v3.2H80v-3.2ZM80 44.8h-3.2V48H80v-3.2ZM80 48h-3.2v3.2H80V48ZM80 57.6h-3.2v3.2H80v-3.2ZM80 64h-3.2v3.2H80V64ZM80 67.2h-3.2v3.2H80v-3.2ZM80 70.4h-3.2v3.2H80v-3.2Z"
|
|
||||||
fill="#171717" />
|
|
||||||
<path d="M80 73.6h-3.2v3.2H80v-3.2ZM80 76.8h-3.2V80H80v-3.2Z" fill="#171717" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 311 KiB |
@@ -228,4 +228,109 @@
|
|||||||
.bg-stat-gradient {
|
.bg-stat-gradient {
|
||||||
background: linear-gradient(to bottom, rgba(17, 17, 17, 0.5), rgba(50, 48, 49, 0.5));
|
background: linear-gradient(to bottom, rgba(17, 17, 17, 0.5), rgba(50, 48, 49, 0.5));
|
||||||
}
|
}
|
||||||
|
.bg-stat-gradient-full {
|
||||||
|
background: linear-gradient(to bottom, rgba(17, 17, 17, 1), rgba(50, 48, 49, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-new-gradient {
|
||||||
|
background: radial-gradient(circle, rgba(230, 245, 236, 1) 0%, rgba(172, 193, 232, 1) 100%);
|
||||||
|
color: #545853;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-new-gradient:hover {
|
||||||
|
background: radial-gradient(circle, rgba(230, 245, 236, 0.8) 0%, rgba(172, 193, 232, 0.8) 100%);
|
||||||
|
color: #545853;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-new-gradient:active {
|
||||||
|
background: radial-gradient(circle, rgba(230, 245, 236, 0.6) 0%, rgba(172, 193, 232, 0.6) 100%);
|
||||||
|
color: #545853;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-soft {
|
||||||
|
background: #e6f5ec;
|
||||||
|
background: radial-gradient(circle, rgba(230, 245, 236, 1) 0%, rgba(172, 193, 232, 1) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-dark {
|
||||||
|
background: #e6f5ec;
|
||||||
|
background: radial-gradient(circle, rgb(204, 255, 225) 0%, rgb(156, 186, 240) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-neutral {
|
||||||
|
@apply bg-gradient-to-b from-neutral-50 to-neutral-400;
|
||||||
|
/* Recommended text colors for good contrast */
|
||||||
|
color: #1f2937; /* neutral-800 for light text */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alternative text color variants */
|
||||||
|
.bg-gradient-neutral .text-light {
|
||||||
|
color: #374151; /* neutral-700 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-neutral .text-medium {
|
||||||
|
color: #4b5563; /* neutral-600 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-neutral .text-dark {
|
||||||
|
color: #1f2937; /* neutral-800 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text gradient utilities */
|
||||||
|
.text-gradient-neutral {
|
||||||
|
background: linear-gradient(to right, rgb(249, 250, 251), rgb(75, 85, 99));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gradient-neutral-vertical {
|
||||||
|
background: linear-gradient(to bottom, rgb(249, 250, 251), rgb(126, 126, 126));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Variations with different opacity levels */
|
||||||
|
.text-gradient-neutral-light {
|
||||||
|
background: linear-gradient(to right, rgba(249, 250, 251, 0.8), rgba(75, 85, 99, 0.8));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gradient-neutral-dark {
|
||||||
|
background: linear-gradient(to right, rgba(156, 163, 175, 0.8), rgba(31, 41, 55, 1));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reusable animation effects */
|
||||||
|
.animate-fade-in-delay-1 {
|
||||||
|
animation: fadeInUp 0.8s ease-out 0.2s both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in-delay-2 {
|
||||||
|
animation: fadeInUp 0.8s ease-out 0.4s both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in-delay-3 {
|
||||||
|
animation: fadeInUp 0.8s ease-out 0.6s both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in-delay-4 {
|
||||||
|
animation: fadeInUp 0.8s ease-out 0.8s both;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeInUp {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
start.sh
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# HERO Personal Agent Website - Development Server
|
||||||
|
# This script starts the development server with hot reload
|
||||||
|
|
||||||
|
echo "🚀 Starting HERO Personal Agent Website Development Server..."
|
||||||
|
echo "============================================================="
|
||||||
|
|
||||||
|
# Check if node_modules exists
|
||||||
|
if [ ! -d "node_modules" ]; then
|
||||||
|
echo "❌ Dependencies not installed. Please run './install.sh' first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start the development server
|
||||||
|
pnpm run dev -p 3010
|
||||||
|
|
||||||