2 Commits

11 changed files with 1192 additions and 57 deletions

View File

@@ -0,0 +1,139 @@
import React from "react";
import { useId } from "react";
export default function FeaturesSectionDemo() {
return (
<div className="py-20 lg:py-40">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-10 md:gap-2 max-w-7xl mx-auto">
{grid.map((feature) => (
<div
key={feature.title}
className="relative bg-gradient-to-b dark:from-neutral-900 from-neutral-100 dark:to-neutral-950 to-white p-6 rounded-3xl overflow-hidden"
>
<Grid size={20} />
<p className="text-base font-bold text-neutral-800 dark:text-white relative z-20">
{feature.title}
</p>
<p className="text-neutral-600 dark:text-neutral-400 mt-4 text-base font-normal relative z-20">
{feature.description}
</p>
</div>
))}
</div>
</div>
);
}
const grid = [
{
title: "HIPAA and SOC2 Compliant",
description:
"Our applications are HIPAA and SOC2 compliant, your data is safe with us, always.",
},
{
title: "Automated Social Media Posting",
description:
"Schedule and automate your social media posts across multiple platforms to save time and maintain a consistent online presence.",
},
{
title: "Advanced Analytics",
description:
"Gain insights into your social media performance with detailed analytics and reporting tools to measure engagement and ROI.",
},
{
title: "Content Calendar",
description:
"Plan and organize your social media content with an intuitive calendar view, ensuring you never miss a post.",
},
{
title: "Audience Targeting",
description:
"Reach the right audience with advanced targeting options, including demographics, interests, and behaviors.",
},
{
title: "Social Listening",
description:
"Monitor social media conversations and trends to stay informed about what your audience is saying and respond in real-time.",
},
{
title: "Customizable Templates",
description:
"Create stunning social media posts with our customizable templates, designed to fit your brand's unique style and voice.",
},
{
title: "Collaboration Tools",
description:
"Work seamlessly with your team using our collaboration tools, allowing you to assign tasks, share drafts, and provide feedback in real-time.",
},
];
export const Grid = ({
pattern,
size,
}: {
pattern?: number[][];
size?: number;
}) => {
const p = pattern ?? [
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
];
return (
<div className="pointer-events-none absolute left-1/2 top-0 -ml-20 -mt-2 h-full w-full [mask-image:linear-gradient(white,transparent)]">
<div className="absolute inset-0 bg-gradient-to-r [mask-image:radial-gradient(farthest-side_at_top,white,transparent)] dark:from-zinc-900/30 from-zinc-100/30 to-zinc-300/30 dark:to-zinc-900/30 opacity-100">
<GridPattern
width={size ?? 20}
height={size ?? 20}
x="-12"
y="4"
squares={p}
className="absolute inset-0 h-full w-full mix-blend-overlay dark:fill-white/10 dark:stroke-white/10 stroke-black/10 fill-black/10"
/>
</div>
</div>
);
};
export function GridPattern({ width, height, x, y, squares, ...props }: any) {
const patternId = useId();
return (
<svg aria-hidden="true" {...props}>
<defs>
<pattern
id={patternId}
width={width}
height={height}
patternUnits="userSpaceOnUse"
x={x}
y={y}
>
<path d={`M.5 ${height}V.5H${width}`} fill="none" />
</pattern>
</defs>
<rect
width="100%"
height="100%"
strokeWidth={0}
fill={`url(#${patternId})`}
/>
{squares && (
<svg x={x} y={y} className="overflow-visible">
{squares.map(([x, y]: any) => (
<rect
strokeWidth="0"
key={`${x}-${y}`}
width={width + 1}
height={height + 1}
x={x * width}
y={y * height}
/>
))}
</svg>
)}
</svg>
);
}

View File

@@ -0,0 +1,109 @@
import { cn } from "@/lib/utils";
import {
IconAdjustmentsBolt,
IconCloud,
IconCurrencyDollar,
IconEaseInOut,
IconHeart,
IconHelp,
IconRouteAltLeft,
IconTerminal2,
} from "@tabler/icons-react";
export default function FeaturesSectionDemo() {
const features = [
{
title: "Built for developers",
description:
"Built for engineers, developers, dreamers, thinkers and doers.",
icon: <IconTerminal2 />,
},
{
title: "Ease of use",
description:
"It's as easy as using an Apple, and as expensive as buying one.",
icon: <IconEaseInOut />,
},
{
title: "Pricing like no other",
description:
"Our prices are best in the market. No cap, no lock, no credit card required.",
icon: <IconCurrencyDollar />,
},
{
title: "100% Uptime guarantee",
description: "We just cannot be taken down by anyone.",
icon: <IconCloud />,
},
{
title: "Multi-tenant Architecture",
description: "You can simply share passwords instead of buying new seats",
icon: <IconRouteAltLeft />,
},
{
title: "24/7 Customer Support",
description:
"We are available a 100% of the time. Atleast our AI Agents are.",
icon: <IconHelp />,
},
{
title: "Money back guarantee",
description:
"If you donot like EveryAI, we will convince you to like us.",
icon: <IconAdjustmentsBolt />,
},
{
title: "And everything else",
description: "I just ran out of copy ideas. Accept my sincere apologies",
icon: <IconHeart />,
},
];
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 relative z-10 py-10 max-w-7xl mx-auto">
{features.map((feature, index) => (
<Feature key={feature.title} {...feature} index={index} />
))}
</div>
);
}
const Feature = ({
title,
description,
icon,
index,
}: {
title: string;
description: string;
icon: React.ReactNode;
index: number;
}) => {
return (
<div
className={cn(
"flex flex-col lg:border-r py-10 relative group/feature dark:border-neutral-800",
(index === 0 || index === 4) && "lg:border-l dark:border-neutral-800",
index < 4 && "lg:border-b dark:border-neutral-800"
)}
>
{index < 4 && (
<div className="opacity-0 group-hover/feature:opacity-100 transition duration-200 absolute inset-0 h-full w-full bg-gradient-to-t from-neutral-100 dark:from-neutral-800 to-transparent pointer-events-none" />
)}
{index >= 4 && (
<div className="opacity-0 group-hover/feature:opacity-100 transition duration-200 absolute inset-0 h-full w-full bg-gradient-to-b from-neutral-100 dark:from-neutral-800 to-transparent pointer-events-none" />
)}
<div className="mb-4 relative z-10 px-10 text-neutral-600 dark:text-neutral-400">
{icon}
</div>
<div className="text-lg font-bold mb-2 relative z-10 px-10">
<div className="absolute left-0 inset-y-0 h-6 group-hover/feature:h-8 w-1 rounded-tr-full rounded-br-full bg-neutral-300 dark:bg-neutral-700 group-hover/feature:bg-blue-500 transition-all duration-200 origin-center" />
<span className="group-hover/feature:translate-x-2 transition duration-200 inline-block text-neutral-800 dark:text-neutral-100">
{title}
</span>
</div>
<p className="text-sm text-neutral-600 dark:text-neutral-300 max-w-xs relative z-10 px-10">
{description}
</p>
</div>
);
};

View File

@@ -0,0 +1,281 @@
import React from "react";
import { cn } from "@/lib/utils";
import createGlobe from "cobe";
import { useEffect, useRef } from "react";
import { motion } from "motion/react";
import { IconBrandYoutubeFilled } from "@tabler/icons-react";
export default function FeaturesSectionDemo() {
const features = [
{
title: "Track issues effectively",
description:
"Track and manage your project issues with ease using our intuitive interface.",
skeleton: <SkeletonOne />,
className:
"col-span-1 lg:col-span-4 border-b lg:border-r dark:border-neutral-800",
},
{
title: "Capture pictures with AI",
description:
"Capture stunning photos effortlessly using our advanced AI technology.",
skeleton: <SkeletonTwo />,
className: "border-b col-span-1 lg:col-span-2 dark:border-neutral-800",
},
{
title: "Watch our AI on YouTube",
description:
"Whether its you or Tyler Durden, you can get to know about our product on YouTube",
skeleton: <SkeletonThree />,
className:
"col-span-1 lg:col-span-3 lg:border-r dark:border-neutral-800",
},
{
title: "Deploy in seconds",
description:
"With our blazing fast, state of the art, cutting edge, we are so back cloud servies (read AWS) - you can deploy your model in seconds.",
skeleton: <SkeletonFour />,
className: "col-span-1 lg:col-span-3 border-b lg:border-none",
},
];
return (
<div className="relative z-20 py-10 lg:py-40 max-w-7xl mx-auto">
<div className="px-8">
<h4 className="text-3xl lg:text-5xl lg:leading-tight max-w-5xl mx-auto text-center tracking-tight font-medium text-black dark:text-white">
Packed with thousands of features
</h4>
<p className="text-sm lg:text-base max-w-2xl my-4 mx-auto text-neutral-500 text-center font-normal dark:text-neutral-300">
From Image generation to video generation, Everything AI has APIs for
literally everything. It can even create this website copy for you.
</p>
</div>
<div className="relative ">
<div className="grid grid-cols-1 lg:grid-cols-6 mt-12 xl:border rounded-md dark:border-neutral-800">
{features.map((feature) => (
<FeatureCard key={feature.title} className={feature.className}>
<FeatureTitle>{feature.title}</FeatureTitle>
<FeatureDescription>{feature.description}</FeatureDescription>
<div className=" h-full w-full">{feature.skeleton}</div>
</FeatureCard>
))}
</div>
</div>
</div>
);
}
const FeatureCard = ({
children,
className,
}: {
children?: React.ReactNode;
className?: string;
}) => {
return (
<div className={cn(`p-4 sm:p-8 relative overflow-hidden`, className)}>
{children}
</div>
);
};
const FeatureTitle = ({ children }: { children?: React.ReactNode }) => {
return (
<p className=" max-w-5xl mx-auto text-left tracking-tight text-black dark:text-white text-xl md:text-2xl md:leading-snug">
{children}
</p>
);
};
const FeatureDescription = ({ children }: { children?: React.ReactNode }) => {
return (
<p
className={cn(
"text-sm md:text-base max-w-4xl text-left mx-auto",
"text-neutral-500 text-center font-normal dark:text-neutral-300",
"text-left max-w-sm mx-0 md:text-sm my-2"
)}
>
{children}
</p>
);
};
export const SkeletonOne = () => {
return (
<div className="relative flex py-8 px-2 gap-10 h-full">
<div className="w-full p-5 mx-auto bg-white dark:bg-neutral-900 shadow-2xl group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 ">
{/* TODO */}
<img
src="/linear.webp"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-left-top rounded-sm"
/>
</div>
</div>
<div className="absolute bottom-0 z-40 inset-x-0 h-60 bg-gradient-to-t from-white dark:from-black via-white dark:via-black to-transparent w-full pointer-events-none" />
<div className="absolute top-0 z-40 inset-x-0 h-60 bg-gradient-to-b from-white dark:from-black via-transparent to-transparent w-full pointer-events-none" />
</div>
);
};
export const SkeletonThree = () => {
return (
<a
href="https://www.youtube.com/watch?v=RPa3_AD1_Vs"
target="__blank"
className="relative flex gap-10 h-full group/image"
>
<div className="w-full mx-auto bg-transparent dark:bg-transparent group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 relative">
{/* TODO */}
<IconBrandYoutubeFilled className="h-20 w-20 absolute z-10 inset-0 text-red-500 m-auto " />
<img
src="https://assets.aceternity.com/fireship.jpg"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-center rounded-sm blur-none group-hover/image:blur-md transition-all duration-200"
/>
</div>
</div>
</a>
);
};
export const SkeletonTwo = () => {
const images = [
"https://images.unsplash.com/photo-1517322048670-4fba75cbbb62?q=80&w=3000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1573790387438-4da905039392?q=80&w=3425&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1555400038-63f5ba517a47?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1554931670-4ebfabf6e7a9?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1546484475-7f7bd55792da?q=80&w=2581&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
];
const imageVariants = {
whileHover: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
whileTap: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
};
return (
<div className="relative flex flex-col items-start p-8 gap-10 h-full overflow-hidden">
{/* TODO */}
<div className="flex flex-row -ml-20">
{images.map((image, idx) => (
<motion.div
variants={imageVariants}
key={"images-first" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="flex flex-row">
{images.map((image, idx) => (
<motion.div
key={"images-second" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
variants={imageVariants}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="absolute left-0 z-[100] inset-y-0 w-20 bg-gradient-to-r from-white dark:from-black to-transparent h-full pointer-events-none" />
<div className="absolute right-0 z-[100] inset-y-0 w-20 bg-gradient-to-l from-white dark:from-black to-transparent h-full pointer-events-none" />
</div>
);
};
export const SkeletonFour = () => {
return (
<div className="h-60 md:h-60 flex flex-col items-center relative bg-transparent dark:bg-transparent mt-10">
<Globe className="absolute -right-10 md:-right-10 -bottom-80 md:-bottom-72" />
</div>
);
};
export const Globe = ({ className }: { className?: string }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
let phi = 0;
if (!canvasRef.current) return;
const globe = createGlobe(canvasRef.current, {
devicePixelRatio: 2,
width: 600 * 2,
height: 600 * 2,
phi: 0,
theta: 0,
dark: 1,
diffuse: 1.2,
mapSamples: 16000,
mapBrightness: 6,
baseColor: [0.3, 0.3, 0.3],
markerColor: [0.1, 0.8, 1],
glowColor: [1, 1, 1],
markers: [
// longitude latitude
{ location: [37.7595, -122.4367], size: 0.03 },
{ location: [40.7128, -74.006], size: 0.1 },
],
onRender: (state) => {
// Called on every animation frame.
// `state` will be an empty object, return updated params.
state.phi = phi;
phi += 0.01;
},
});
return () => {
globe.destroy();
};
}, []);
return (
<canvas
ref={canvasRef}
style={{ width: 600, height: 600, maxWidth: "100%", aspectRatio: 1 }}
className={className}
/>
);
};

View File

@@ -6,7 +6,7 @@ import { SectionHeader } from '@/components/Texts'
interface CountUpNumberProps { interface CountUpNumberProps {
end: number end: number
className?: string className?: string
color?: 'light' | 'primary' | 'secondary' color?: 'light' | 'primary' | 'secondary' | 'white'
} }
export function CountUpNumber({ end, className, color }: CountUpNumberProps) { export function CountUpNumber({ end, className, color }: CountUpNumberProps) {

View File

@@ -1,47 +1,159 @@
import { useEffect, useRef } from 'react' "use client";
import createGlobe from 'cobe'
export function Globe({ className }: { className?: string }) { import createGlobe, { type COBEOptions } from "cobe";
const canvasRef = useRef<HTMLCanvasElement>(null) import { useMotionValue, useSpring } from "motion/react";
import { useEffect, useRef } from "react";
import { cn } from "@/lib/utils";
const MOVEMENT_DAMPING = 1400;
const GLOBE_CONFIG: COBEOptions = {
width: 800,
height: 800,
onRender: () => {},
devicePixelRatio: 2,
phi: 0,
theta: 0.3,
dark: 0,
diffuse: 0.25, // softer shading for premium look
mapSamples: 16000,
mapBrightness: 1.1,
baseColor: [0.8, 0.8, 0.8], // sleek dark gray globe
markerColor: [0.02, 0.71, 0.83], // cyan-500
glowColor: [0.8, 0.8, 0.85], // grey
markers: [
// --- Core Global Markers ---
{ location: [14.5995, 120.9842], size: 0.03 }, // Manila
{ location: [19.076, 72.8777], size: 0.1 }, // Mumbai
{ location: [23.8103, 90.4125], size: 0.05 }, // Dhaka
{ location: [30.0444, 31.2357], size: 0.07 }, // Cairo
{ location: [39.9042, 116.4074], size: 0.08 }, // Beijing
{ location: [-23.5505, -46.6333], size: 0.1 }, // São Paulo
{ location: [19.4326, -99.1332], size: 0.1 }, // Mexico City
{ location: [40.7128, -74.006], size: 0.1 }, // New York
{ location: [34.6937, 135.5022], size: 0.05 }, // Osaka
{ location: [41.0082, 28.9784], size: 0.06 }, // Istanbul
{ location: [48.8566, 2.3522], size: 0.08 }, // Paris
{ location: [51.5072, -0.1276], size: 0.08 }, // London
{ location: [52.52, 13.405], size: 0.07 }, // Berlin
{ location: [35.6895, 139.6917], size: 0.06 }, // Tokyo
{ location: [-33.8688, 151.2093], size: 0.06 }, // Sydney
{ location: [-1.2921, 36.8219], size: 0.05 }, // Nairobi
{ location: [-34.6037, -58.3816], size: 0.07 }, // Buenos Aires
{ location: [37.7749, -122.4194], size: 0.08 }, // San Francisco
{ location: [1.3521, 103.8198], size: 0.06 }, // Singapore
{ location: [28.6139, 77.2090], size: 0.08 }, // New Delhi
{ location: [13.7563, 100.5018], size: 0.06 }, // Bangkok
{ location: [59.9343, 30.3351], size: 0.05 }, // St. Petersburg
{ location: [33.6844, 73.0479], size: 0.05 }, // Islamabad
{ location: [25.276987, 55.296249], size: 0.07 }, // Dubai
{ location: [60.1699, 24.9384], size: 0.05 }, // Helsinki
{ location: [43.6532, -79.3832], size: 0.07 }, // Toronto
{ location: [6.5244, 3.3792], size: 0.08 }, // Lagos
{ location: [50.1109, 8.6821], size: 0.06 }, // Frankfurt
// --- 12 New US + European Cities ---
{ location: [34.0522, -118.2437], size: 0.08 }, // Los Angeles
{ location: [41.8781, -87.6298], size: 0.07 }, // Chicago
{ location: [29.7604, -95.3698], size: 0.07 }, // Houston
{ location: [25.7617, -80.1918], size: 0.07 }, // Miami
{ location: [45.5017, -73.5673], size: 0.06 }, // Montreal
{ location: [47.6062, -122.3321], size: 0.06 }, // Seattle
{ location: [40.4406, -79.9959], size: 0.05 }, // Pittsburgh
{ location: [41.3851, 2.1734], size: 0.06 }, // Barcelona
{ location: [45.4642, 9.19], size: 0.06 }, // Milan
{ location: [52.3676, 4.9041], size: 0.06 }, // Amsterdam
{ location: [38.7169, -9.139], size: 0.05 }, // Lisbon
{ location: [59.3293, 18.0686], size: 0.05 }, // Stockholmx
],
};
export function Globe({
className,
config = GLOBE_CONFIG,
}: {
className?: string;
config?: COBEOptions;
}) {
let phi = 0;
let width = 0;
const canvasRef = useRef<HTMLCanvasElement>(null);
const pointerInteracting = useRef<number | null>(null);
const r = useMotionValue(0);
const rs = useSpring(r, {
mass: 1,
damping: 35, // slightly smoother motion
stiffness: 100,
});
const updatePointerInteraction = (value: number | null) => {
pointerInteracting.current = value;
if (canvasRef.current) {
canvasRef.current.style.cursor = value !== null ? "grabbing" : "grab";
}
};
const updateMovement = (clientX: number) => {
if (pointerInteracting.current !== null) {
const delta = clientX - pointerInteracting.current;
r.set(r.get() + delta / MOVEMENT_DAMPING);
}
};
useEffect(() => { useEffect(() => {
let phi = 0 const onResize = () => {
if (canvasRef.current) width = canvasRef.current.offsetWidth;
};
if (!canvasRef.current) return window.addEventListener("resize", onResize);
onResize();
const globe = createGlobe(canvasRef.current, { const globe = createGlobe(canvasRef.current!, {
devicePixelRatio: 2, ...config,
width: 600 * 2, width: width * 2,
height: 600 * 2, height: width * 2,
phi: 0,
theta: 0,
dark: 0,
diffuse: 1.2,
mapSamples: 16000,
mapBrightness: 6,
baseColor: [0.3, 0.3, 0.3],
markerColor: [0.1, 0.8, 1],
glowColor: [1, 1, 1],
markers: [
{ location: [37.7595, -122.4367], size: 0.03 },
{ location: [40.7128, -74.006], size: 0.1 },
],
onRender: (state) => { onRender: (state) => {
state.phi = phi if (!pointerInteracting.current) phi += 0.004; // slightly slower rotation for elegance
phi += 0.01 state.phi = phi + rs.get();
state.width = width * 2;
state.height = width * 2;
}, },
}) });
setTimeout(() => (canvasRef.current!.style.opacity = "1"), 0);
return () => { return () => {
globe.destroy() globe.destroy();
} window.removeEventListener("resize", onResize);
}, []) };
}, [rs, config]);
return ( return (
<canvas <div
ref={canvasRef} className={cn(
className={className} // Radial gradient background that fades to pure black at edges
style={{ width: '100%', height: '100%', maxWidth: '100%', aspectRatio: 1 }} "absolute inset-0 mx-auto aspect-[1/1] w-full max-w-[600px] rounded-full",
/> className,
) )}
>
<canvas
className={cn(
"size-full opacity-0 transition-opacity duration-500 [contain:layout_paint_size]",
)}
ref={canvasRef}
onPointerDown={(e) => {
pointerInteracting.current = e.clientX;
updatePointerInteraction(e.clientX);
}}
onPointerUp={() => updatePointerInteraction(null)}
onPointerOut={() => updatePointerInteraction(null)}
onMouseMove={(e) => updateMovement(e.clientX)}
onTouchMove={(e) =>
e.touches[0] && updateMovement(e.touches[0].clientX)
}
/>
</div>
);
} }

View File

@@ -0,0 +1,40 @@
import { CircleBackground } from '../../components/CircleBackground'
import { Container } from '../../components/Container'
import { Button } from '../../components/Button'
export function CallToAction() {
return (
<section
id="get-started"
className="relative overflow-hidden bg-gray-900 py-32"
>
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<CircleBackground color="#06b6d4" className="animate-spin-slower" />
</div>
<Container className="relative">
<div className="mx-auto max-w-2xl text-center">
<h2 className="text-3xl lg:text-4xl font-medium tracking-tight text-white sm:text-4xl">
Build the Future, Today
</h2>
<p className="mt-6 text-lg text-gray-300">
Ready to reclaim your digital freedom? Start building on a cloud thats autonomous, efficient, and truly yours. Explore the documentation or join our community to get started.
</p>
<div className="mt-10 flex flex-wrap justify-center gap-x-6 gap-y-4">
<Button to="/cloud" variant="solid" color="white">
Start Building
</Button>
<Button
to="https://threefold.info/mycelium_network/docs/"
as="a"
target="_blank"
variant="outline"
color="white"
>
Read Docs
</Button>
</div>
</div>
</Container>
</section>
)
}

View File

@@ -0,0 +1,284 @@
import React from "react";
import { cn } from "@/lib/utils";
import createGlobe from "cobe";
import { useEffect, useRef } from "react";
import { motion } from "motion/react";
import { IconBrandYoutubeFilled } from "@tabler/icons-react";
import { LockClosedIcon, CogIcon, BoltIcon, CurrencyDollarIcon } from '@heroicons/react/24/solid'
import { H2, P } from '@/components/Texts'
export function HomeBenefits() {
const features = [
{
title: "Sovereign",
description:
"Own your infrastructure and your data. Mycelium Cloud eliminates dependency on centralized providers, giving you full digital sovereignty.",
icon: <LockClosedIcon className="h-6 w-6 text-cyan-500" />,
className:
"col-span-1 lg:col-span-4 border-b lg:border-r dark:border-neutral-800",
},
{
title: "Autonomous",
description:
"The cloud that runs itself. From deployment to scaling, Mycelium Cloud automates everything — so your systems stay fast, resilient, and adaptive.",
icon: <CogIcon className="h-6 w-6 text-cyan-500" />,
className: "border-b col-span-1 lg:col-span-2 dark:border-neutral-800",
},
{
title: "Energy Efficient",
description:
"Built on distributed nodes designed for minimal energy use, Mycelium Cloud redefines sustainability without compromising performance.",
icon: <BoltIcon className="h-6 w-6 text-cyan-500" />,
className:
"col-span-1 lg:col-span-3 lg:border-r dark:border-neutral-800",
},
{
title: "Cost Efficient",
description:
"No middlemen. No inflated bills. Just pure compute power at a fraction of traditional cloud costs — optimized, transparent, and fair.",
icon: <CurrencyDollarIcon className="h-6 w-6 text-cyan-500" />,
className: "col-span-1 lg:col-span-3 border-b lg:border-none",
},
];
return (
<div className="relative z-20 py-10 lg:py-40 max-w-7xl mx-auto">
<div className="px-8">
<H2 className="text-3xl lg:text-5xl lg:leading-tight max-w-5xl mx-auto text-center tracking-tight font-medium text-black dark:text-white">
Why It Changes Everything
</H2>
<P className="text-sm lg:text-base max-w-2xl my-4 mx-auto text-neutral-500 text-center font-normal dark:text-neutral-300">
Mycelium Cloud isnt just another cloud its a new foundation for digital independence. A self-governing, AI-powered infrastructure that gives you control, efficiency, and trust without compromise.
</P>
</div>
<div className="relative ">
<div className="grid grid-cols-1 lg:grid-cols-6 mt-12 xl:border rounded-md dark:border-neutral-800">
{features.map((feature) => (
<FeatureCard key={feature.title} className={feature.className}>
<FeatureTitle icon={feature.icon}>{feature.title}</FeatureTitle>
<FeatureDescription>{feature.description}</FeatureDescription>
</FeatureCard>
))}
</div>
</div>
</div>
);
}
const FeatureCard = ({
children,
className,
}: {
children?: React.ReactNode;
className?: string;
}) => {
return (
<div className={cn(`p-4 sm:p-8 relative overflow-hidden`, className)}>
{children}
</div>
);
};
const FeatureTitle = ({ children, icon }: { children?: React.ReactNode, icon?: React.ReactNode }) => {
return (
<div className="flex items-center gap-2">
{icon}
<p className="max-w-5xl text-left tracking-tight text-black dark:text-white text-xl md:text-2xl md:leading-snug">
{children}
</p>
</div>
);
};
const FeatureDescription = ({ children }: { children?: React.ReactNode }) => {
return (
<p
className={cn(
"text-sm md:text-base max-w-4xl text-left mx-auto",
"text-neutral-500 text-center font-normal dark:text-neutral-300",
"text-left max-w-sm mx-0 md:text-sm my-2"
)}
>
{children}
</p>
);
};
export const SkeletonOne = () => {
return (
<div className="relative flex py-8 px-2 gap-10 h-full">
<div className="w-full p-5 mx-auto bg-white dark:bg-neutral-900 shadow-2xl group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 ">
{/* TODO */}
<img
src="/linear.webp"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-left-top rounded-sm"
/>
</div>
</div>
<div className="absolute bottom-0 z-40 inset-x-0 h-60 bg-gradient-to-t from-white dark:from-black via-white dark:via-black to-transparent w-full pointer-events-none" />
<div className="absolute top-0 z-40 inset-x-0 h-60 bg-gradient-to-b from-white dark:from-black via-transparent to-transparent w-full pointer-events-none" />
</div>
);
};
export const SkeletonThree = () => {
return (
<a
href="https://www.youtube.com/watch?v=RPa3_AD1_Vs"
target="__blank"
className="relative flex gap-10 h-full group/image"
>
<div className="w-full mx-auto bg-transparent dark:bg-transparent group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 relative">
{/* TODO */}
<IconBrandYoutubeFilled className="h-20 w-20 absolute z-10 inset-0 text-red-500 m-auto " />
<img
src="https://assets.aceternity.com/fireship.jpg"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-center rounded-sm blur-none group-hover/image:blur-md transition-all duration-200"
/>
</div>
</div>
</a>
);
};
export const SkeletonTwo = () => {
const images = [
"https://images.unsplash.com/photo-1517322048670-4fba75cbbb62?q=80&w=3000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1573790387438-4da905039392?q=80&w=3425&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1555400038-63f5ba517a47?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1554931670-4ebfabf6e7a9?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1546484475-7f7bd55792da?q=80&w=2581&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
];
const imageVariants = {
whileHover: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
whileTap: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
};
return (
<div className="relative flex flex-col items-start p-8 gap-10 h-full overflow-hidden">
{/* TODO */}
<div className="flex flex-row -ml-20">
{images.map((image, idx) => (
<motion.div
variants={imageVariants}
key={"images-first" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="flex flex-row">
{images.map((image, idx) => (
<motion.div
key={"images-second" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
variants={imageVariants}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="absolute left-0 z-[100] inset-y-0 w-20 bg-gradient-to-r from-white dark:from-black to-transparent h-full pointer-events-none" />
<div className="absolute right-0 z-[100] inset-y-0 w-20 bg-gradient-to-l from-white dark:from-black to-transparent h-full pointer-events-none" />
</div>
);
};
export const SkeletonFour = () => {
return (
<div className="h-60 md:h-60 flex flex-col items-center relative bg-transparent dark:bg-transparent mt-10">
<Globe className="absolute -right-10 md:-right-10 -bottom-80 md:-bottom-72" />
</div>
);
};
export const Globe = ({ className }: { className?: string }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
let phi = 0;
if (!canvasRef.current) return;
const globe = createGlobe(canvasRef.current, {
devicePixelRatio: 2,
width: 600 * 2,
height: 600 * 2,
phi: 0,
theta: 0,
dark: 1,
diffuse: 1.2,
mapSamples: 16000,
mapBrightness: 6,
baseColor: [0.3, 0.3, 0.3],
markerColor: [0.1, 0.8, 1],
glowColor: [1, 1, 1],
markers: [
// longitude latitude
{ location: [37.7595, -122.4367], size: 0.03 },
{ location: [40.7128, -74.006], size: 0.1 },
],
onRender: (state) => {
// Called on every animation frame.
// `state` will be an empty object, return updated params.
state.phi = phi;
phi += 0.01;
},
});
return () => {
globe.destroy();
};
}, []);
return (
<canvas
ref={canvasRef}
style={{ width: 600, height: 600, maxWidth: "100%", aspectRatio: 1 }}
className={className}
/>
);
};

View File

@@ -32,24 +32,11 @@ export function HomeFeatures() {
return ( return (
<div className=""> <div className="">
<div className="relative bg-transparent py-24 overflow-hidden"> <div className="relative bg-transparent pb-24 Pt-0 overflow-hidden">
{/* --- Soft background gradients --- */}
<div
aria-hidden="true"
className="absolute inset-x-0 -top-16 -z-10 flex transform-gpu justify-center overflow-hidden blur-3xl"
>
<div
style={{
clipPath:
'polygon(73.6% 51.7%, 91.7% 11.8%, 100% 46.4%, 97.4% 82.2%, 92.5% 84.9%, 75.7% 64%, 55.3% 47.5%, 46.5% 49.4%, 45% 62.9%, 50.3% 87.2%, 21.3% 64.1%, 0.1% 100%, 5.4% 51.1%, 21.4% 63.9%, 58.9% 0.2%, 73.6% 51.7%)',
}}
className="aspect-1318/752 w-329.5 flex-none bg-linear-to-r from-[#9fd6fc] to-[#c6c4fa] opacity-40"
/>
</div>
<div className="mx-auto max-w-7xl px-6 lg:px-8"> <div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:mx-0"> <div className="mx-auto max-w-2xl lg:mx-0">
<H2 className=""> <H2 className="">
The Building Blocks of <span className="font-medium text-7xl italic">Decentralized Future</span> The Building Blocks of <span className="font-medium text-7xl">Decentralized Future</span>
</H2> </H2>
<P className="mt-6 "> <P className="mt-6 ">
From compute and networking to intelligent automation, these components work together to empower users, developers, and organizations to build freely, without intermediaries. From compute and networking to intelligent automation, these components work together to empower users, developers, and organizations to build freely, without intermediaries.
@@ -65,7 +52,6 @@ export function HomeFeatures() {
<h3 className="mt-6 text-xl font-semibold text-black">{feature.name}</h3> <h3 className="mt-6 text-xl font-semibold text-black">{feature.name}</h3>
<p className="mt-4 text-base text-gray-800">{feature.description}</p> <p className="mt-4 text-base text-gray-800">{feature.description}</p>
<a href={feature.href} className="mt-6 text-base font-semibold text-black">Learn more <span aria-hidden="true"> &rarr;</span></a> <a href={feature.href} className="mt-6 text-base font-semibold text-black">Learn more <span aria-hidden="true"> &rarr;</span></a>
<div className="absolute -bottom-10 -right-10 h-50 w-50 -z-10" style={{ background: 'radial-gradient(circle, rgba(173, 239, 255, 0.6) 0%, rgba(115, 207, 255, 0.4) 100%)', filter: 'blur(80px)' }}></div>
</div> </div>
))} ))}
</div> </div>

View File

@@ -0,0 +1,60 @@
import { GlobeAltIcon, ServerStackIcon, CpuChipIcon } from '@heroicons/react/24/solid'
import { H2, P } from '@/components/Texts'
const features = [
{
name: 'Mycelium Network',
description:
"A global, end-to-end encrypted overlay that simply doesn't break.",
href: '/network',
icon: GlobeAltIcon,
},
{
name: 'Mycelium Cloud',
description:
'An autonomous, stateless OS that enforces pre-deterministic deployments you define.',
href: '/cloud',
icon: ServerStackIcon,
},
{
name: 'Mycelium Agents',
description:
'Your sovereign agent with private memory and permissioned data access—always under your control.',
href: '/agents',
icon: CpuChipIcon,
},
]
export function HomeFeaturesDark() {
return (
<div className="">
<div className="relative bg-black py-24 overflow-hidden">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:mx-0">
<H2 className="text-white">
The Building Blocks of Decentralized Future
</H2>
<P className="mt-6 text-gray-300">
From compute and networking to intelligent automation, these components work together to empower users, developers, and organizations to build freely, without intermediaries.
</P>
</div>
<div className="mx-auto mt-16 max-w-2xl lg:max-w-7xl">
<div className="grid grid-cols-1 gap-x-12 gap-y-12 lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="relative flex flex-col p-8 rounded-3xl border border-gray-700 bg-gray-900/50 backdrop-blur-lg overflow-hidden shadow-2xl hover:shadow-cyan-500/40 hover:border-cyan-500 hover:scale-105 transform transition-all duration-300">
<div className="w-20 h-20 bg-gray-800/80 rounded-full flex items-center justify-center">
<feature.icon className="h-12 w-12 text-cyan-500" />
</div>
<h3 className="mt-6 text-xl font-semibold text-white">{feature.name}</h3>
<p className="mt-4 text-base text-gray-300">{feature.description}</p>
<a href={feature.href} className="mt-6 text-base font-semibold text-white">Learn more <span aria-hidden="true"> &rarr;</span></a>
</div>
))}
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,117 @@
'use client'
import { Globe } from "@/components/ui/Globe"
import { motion } from "framer-motion"
import { H2, P, CT, CP, SectionHeader, Eyebrow } from "@/components/Texts"
import { CountUpNumber } from '@/components/CountUpNumber'
export function WorldMap() {
return (
<div className="relative min-h-screen w-full overflow-hidden top-0 flex py-12 flex-col">
{/* Background video */}
<video
autoPlay
loop
muted
playsInline
className="absolute inset-0 w-full h-full object-cover"
>
<source src="/videos/benefits.mp4" type="video/mp4" />
</video>
{/* Dark overlay */}
<div className="absolute inset-0 bg-black/10" />
{/* Content */}
<div className="relative z-10 flex flex-col h-full px-8 md:px-16 py-12">
{/* Title + Subtitle */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className="max-w-xl"
>
<Eyebrow color="accent">Network</Eyebrow>
<SectionHeader color="light">Mycelium Network is Live.</SectionHeader>
<P className=" mt-4 text-base leading-relaxed" color="light">
Mycelium Cloud's advancement technology enables anyone to deploy
their own Internet infrastructure, anywhere.
</P>
</motion.div>
{/* Bottom Layout: Globe + Cards */}
<div className="mt-8 flex flex-1 flex-col lg:flex-row items-center lg:items-stretch gap-x-10">
{/* Globe Left Column */}
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5, delay: 0.2 }}
className="flex-1 flex items-center justify-center"
>
<div className="relative w-[450px] h-[450px] md:w-[600px] md:h-[600px]">
<Globe className="absolute inset-0 w-full h-full left-0 lg:-left-24" />
</div>
</motion.div>
{/* Cards Right Column */}
<div className="relative flex-1 lg:h-auto h-[700px] flex flex-col lg:block items-center gap-y-4 mt-8 lg:mt-0">
<motion.div
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.4 }}
className="lg:absolute lg:top-12 lg:-left-12 w-80 rounded-2xl border border-gray-300 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 bg-white/5 backdrop-blur-md"
>
<div><CT color="light" className="uppercase tracking-wide">CORES</CT></div>
<div><CountUpNumber end={54958} className="mt-2 text-3xl font-bold text-white" /></div>
<CP color="light" className="mt-2 text-sm">
Total Central Processing Unit Cores available on the grid.
</CP>
</motion.div>
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.5 }}
className="lg:absolute lg:-top-10 lg:right-0 w-80 rounded-2xl border border-gray-300 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 bg-white/5 backdrop-blur-md"
>
<div><CT color="light" className="uppercase tracking-wide">NODES</CT></div>
<div><CountUpNumber end={1493} className="mt-4 text-3xl font-bold text-white" /></div>
<CP color="light" className="mt-2 text-sm">
Total number of nodes on the grid.
</CP>
</motion.div>
<motion.div
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.6 }}
className="lg:absolute lg:bottom-28 lg:-left-12 w-80 rounded-2xl border border-gray-300 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 bg-white/5 backdrop-blur-md"
>
<div><CT color="light" className="uppercase tracking-wide">SSD CAPACITY</CT></div>
<div><CountUpNumber end={5388956} className="mt-2 text-3xl font-bold text-white" /></div>
<CP color="light" className="mt-2 text-sm">
Total GB amount of storage (SSD, HDD, & RAM) on the grid.
</CP>
</motion.div>
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.7 }}
className="lg:absolute lg:top-47 lg:right-0 w-80 rounded-2xl border border-gray-300 p-8 transition-all duration-300 ease-in-out hover:scale-105 hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20 bg-white/5 backdrop-blur-md"
>
<div><CT color="light" className="uppercase tracking-wide">COUNTRIES</CT></div>
<div><CountUpNumber end={44} className="mt-2 text-3xl font-bold text-white" /></div>
<CP color="light" className="mt-2 text-sm">
Total number of countries with active nodes.
</CP>
</motion.div>
</div>
</div>
</div>
{/* Radial fade overlay */}
<div className="pointer-events-none absolute inset-0 h-full bg-[radial-gradient(circle_at_50%_200%,rgba(0,0,0,0.2),rgba(255,255,255,0))]" />
</div>
)
}

View File

@@ -1,10 +1,13 @@
import { AnimatedSection } from '../../components/AnimatedSection' import { AnimatedSection } from '../../components/AnimatedSection'
import { HomeAurora } from './HomeAurora' import { HomeAurora } from './HomeAurora'
import { HomeMapSection } from './HomeMap'
import { HomeFeatures } from './HomeFeatures' import { HomeFeatures } from './HomeFeatures'
import { HomeFeaturesDark } from './HomeFeaturesDark'
import { HomeCloud } from './HomeCloud' import { HomeCloud } from './HomeCloud'
import { HomeAgent } from './HomeAgent' import { HomeAgent } from './HomeAgent'
import { StackSectionLight } from './StackSection' import { StackSectionLight } from './StackSection'
import { WorldMap } from './HomeGlobe'
import { HomeBenefits } from './HomeBenefits'
import { CallToAction } from './CallToAction'
export default function HomePage() { export default function HomePage() {
@@ -14,22 +17,26 @@ export default function HomePage() {
<HomeAurora /> <HomeAurora />
</AnimatedSection> </AnimatedSection>
<AnimatedSection id="next-section">
<WorldMap />
</AnimatedSection>
<AnimatedSection> <AnimatedSection>
<StackSectionLight /> <StackSectionLight />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<HomeFeatures /> <HomeFeaturesDark />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<HomeCloud /> <HomeBenefits />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<HomeAgent /> <CallToAction />
</AnimatedSection> </AnimatedSection>
</div> </div>
) )
} }