diff --git a/package-lock.json b/package-lock.json index cd1d96d..eeda115 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,10 +20,12 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cobe": "^0.6.5", + "dotted-map": "^2.2.3", "framer-motion": "^10.18.0", "lucide-react": "^0.544.0", "motion": "^12.23.24", "next": "^14.2.33", + "next-themes": "^0.4.6", "popmotion": "^11.0.5", "react": "^18.3.1", "react-countup": "^6.5.3", @@ -4089,6 +4091,40 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@turf/boolean-point-in-polygon": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-6.5.0.tgz", + "integrity": "sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A==", + "license": "MIT", + "dependencies": { + "@turf/helpers": "^6.5.0", + "@turf/invariant": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", + "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", + "license": "MIT", + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/invariant": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", + "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", + "license": "MIT", + "dependencies": { + "@turf/helpers": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", @@ -6889,6 +6925,16 @@ "@types/trusted-types": "^2.0.7" } }, + "node_modules/dotted-map": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/dotted-map/-/dotted-map-2.2.3.tgz", + "integrity": "sha512-8hyOOHHLLVCcCisM3yb9hqp+3bJ7TSMcr1SfrUw8Wxp5UMqih35jIvUyagweCooJbz/EH1nC9GGuPysh7+YlAg==", + "license": "MIT", + "dependencies": { + "@turf/boolean-point-in-polygon": "^6.0.1", + "proj4": "^2.6.1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -10517,6 +10563,12 @@ "uuid": "^11.1.0" } }, + "node_modules/mgrs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz", + "integrity": "sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==", + "license": "MIT" + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -11531,6 +11583,16 @@ } } }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/next/node_modules/@swc/helpers": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", @@ -12218,6 +12280,19 @@ } } }, + "node_modules/proj4": { + "version": "2.19.10", + "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.19.10.tgz", + "integrity": "sha512-uL6/C6kA8+ncJAEDmUeV8PmNJcTlRLDZZa4/87CzRpb8My4p+Ame4LhC4G3H/77z2icVqcu3nNL9h5buSdnY+g==", + "license": "MIT", + "dependencies": { + "mgrs": "1.0.0", + "wkt-parser": "^1.5.1" + }, + "funding": { + "url": "https://github.com/sponsors/ahocevar" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -15508,6 +15583,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wkt-parser": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.5.2.tgz", + "integrity": "sha512-1ZUiV1FTwSiSrgWzV9KXJuOF2BVW91KY/mau04BhnmgOdroRQea7Q0s5TVqwGLm0D2tZwObd/tBYXW49sSxp3Q==", + "license": "MIT" + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index 8f68238..d2dbbb8 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,12 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cobe": "^0.6.5", + "dotted-map": "^2.2.3", "framer-motion": "^10.18.0", "lucide-react": "^0.544.0", "motion": "^12.23.24", "next": "^14.2.33", + "next-themes": "^0.4.6", "popmotion": "^11.0.5", "react": "^18.3.1", "react-countup": "^6.5.3", diff --git a/src/components/ui/card-stack.tsx b/src/components/ui/card-stack.tsx new file mode 100644 index 0000000..33de6cc --- /dev/null +++ b/src/components/ui/card-stack.tsx @@ -0,0 +1,48 @@ +"use client"; +import { motion } from "framer-motion"; + +type Card = { + id: number; + name: string; + description: string; + icon: React.ReactNode; +}; + +export const CardStack = ({ + items, + offset, + scaleFactor, +}: { + items: Card[]; + offset?: number; + scaleFactor?: number; +}) => { + const CARD_OFFSET = offset || 10; + const HORIZONTAL_OFFSET = 336; // Adjusted for 1/8 overlap + const SCALE_FACTOR = scaleFactor || 0.06; + + return ( +
+ {items.map((card, index) => ( + +
+

{card.name}

+

{card.description}

+
+
+ ))} +
+ ); +}; diff --git a/src/components/ui/evervault-card.tsx b/src/components/ui/evervault-card.tsx new file mode 100644 index 0000000..c9ff5b4 --- /dev/null +++ b/src/components/ui/evervault-card.tsx @@ -0,0 +1,106 @@ +"use client"; +import { useMotionValue } from "motion/react"; +import React, { useState, useEffect } from "react"; +import { useMotionTemplate, motion } from "motion/react"; +import { cn } from "@/lib/utils"; + +export const EvervaultCard = ({ + children, + className, +}: { + children?: React.ReactNode; + className?: string; +}) => { + let mouseX = useMotionValue(0); + let mouseY = useMotionValue(0); + + const [randomString, setRandomString] = useState(""); + + useEffect(() => { + let str = generateRandomString(1500); + setRandomString(str); + }, []); + + function onMouseMove({ currentTarget, clientX, clientY }: any) { + let { left, top } = currentTarget.getBoundingClientRect(); + mouseX.set(clientX - left); + mouseY.set(clientY - top); + + const str = generateRandomString(1500); + setRandomString(str); + } + + return ( +
+
+ +
+
+ {children} +
+
+
+
+ ); +}; + +export function CardPattern({ mouseX, mouseY, randomString }: any) { + let maskImage = useMotionTemplate`radial-gradient(250px at ${mouseX}px ${mouseY}px, white, transparent)`; + let style = { maskImage, WebkitMaskImage: maskImage }; + + return ( +
+
+ + +

+ {randomString} +

+
+
+ ); +} + +const characters = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +export const generateRandomString = (length: number) => { + let result = ""; + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * characters.length)); + } + return result; +}; + +export const Icon = ({ className, ...rest }: any) => { + return ( + + + + ); +}; diff --git a/src/components/ui/world-map.tsx b/src/components/ui/world-map.tsx new file mode 100644 index 0000000..ec190ff --- /dev/null +++ b/src/components/ui/world-map.tsx @@ -0,0 +1,170 @@ +"use client"; + +import { useRef } from "react"; +import { motion } from "motion/react"; +import DottedMap from "dotted-map"; + +import { useTheme } from "next-themes"; + +interface MapProps { + dots?: Array<{ + start: { lat: number; lng: number; label?: string }; + end: { lat: number; lng: number; label?: string }; + }>; + lineColor?: string; +} + +export default function WorldMap({ + dots = [], + lineColor = "#06b6d4", +}: MapProps) { + const svgRef = useRef(null); + const map = new DottedMap({ height: 100, grid: "diagonal" }); + + const { theme } = useTheme(); + + const svgMap = map.getSVG({ + radius: 0.22, + color: theme === "dark" ? "#FFFFFF40" : "#00000040", + shape: "circle", + backgroundColor: theme === "dark" ? "black" : "white", + }); + + const projectPoint = (lat: number, lng: number) => { + const x = (lng + 180) * (800 / 360); + const y = (90 - lat) * (400 / 180); + return { x, y }; + }; + + const createCurvedPath = ( + start: { x: number; y: number }, + end: { x: number; y: number } + ) => { + const midX = (start.x + end.x) / 2; + const midY = Math.min(start.y, end.y) - 50; + return `M ${start.x} ${start.y} Q ${midX} ${midY} ${end.x} ${end.y}`; + }; + + return ( +
+ world map + + {dots.map((dot, i) => { + const startPoint = projectPoint(dot.start.lat, dot.start.lng); + const endPoint = projectPoint(dot.end.lat, dot.end.lng); + return ( + + + + ); + })} + + + + + + + + + + + {dots.map((dot, i) => ( + + + + + + + + + + + + + + + + + ))} + +
+ ); +} diff --git a/src/images/cloudlayer.png b/src/images/cloudlayer.png new file mode 100644 index 0000000..b567695 Binary files /dev/null and b/src/images/cloudlayer.png differ diff --git a/src/pages/home/HomeAurora.tsx b/src/pages/home/HomeAurora.tsx index f40186e..37a0d0f 100644 --- a/src/pages/home/HomeAurora.tsx +++ b/src/pages/home/HomeAurora.tsx @@ -16,7 +16,7 @@ export function HomeAurora() { duration: 1, ease: "easeInOut", }} - className="relative mb-20 -top-5 flex flex-col items-center justify-center gap-4 px-4 max-w-5xl" + className="relative mb-20 flex flex-col items-center justify-center gap-4 px-4 max-w-5xl" >

Decentralized Autonomous Agentic Cloud.

diff --git a/src/pages/home/HomeFeatures.tsx b/src/pages/home/HomeFeatures.tsx new file mode 100644 index 0000000..c9ea1b4 --- /dev/null +++ b/src/pages/home/HomeFeatures.tsx @@ -0,0 +1,56 @@ +import { InboxIcon, TrashIcon, UsersIcon } from '@heroicons/react/24/outline' +import { H2, P } from '@/components/Texts' +import { CardStack } from '@/components/ui/card-stack' + +const features = [ + { + name: 'Network Layer', + description: + "A global, end-to-end encrypted overlay that simply doesn't break. Shortest-path routing moves your traffic the fastest way, every time with instant discovery.", + href: '#', + icon: UsersIcon, + }, + { + name: 'Cloud Layer', + description: + 'An autonomous, stateless OS that enforces pre-deterministic deployments you define. Workloads are cryptographically bound to your private key—location and access are yours.', + href: '#', + icon: TrashIcon, + }, + { + name: 'Agent Layer', + description: + 'Your sovereign agent with private memory and permissioned data access—always under your control. Choose from a wide library of open-source LLMs, paired with built-in semantic search and retrieval.', + href: '#', + icon: InboxIcon, + }, +] + +export function HomeFeatures() { + const cards = features.map((feature, index) => ({ + id: index, + name: feature.name, + description: feature.description, + icon: