This commit is contained in:
2025-09-15 16:51:05 +02:00
parent 28fa04afc0
commit bfdd5aae41
37 changed files with 829 additions and 204 deletions

24
components.json Normal file
View File

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

126
package-lock.json generated
View File

@@ -15,8 +15,12 @@
"@types/node": "^20.10.8", "@types/node": "^20.10.8",
"@types/react": "^18.2.55", "@types/react": "^18.2.55",
"@types/react-dom": "^18.2.18", "@types/react-dom": "^18.2.18",
"clsx": "^2.1.0", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cobe": "^0.6.4",
"framer-motion": "^10.15.0", "framer-motion": "^10.15.0",
"lucide-react": "^0.544.0",
"motion": "^12.23.12",
"next": "^14.0.4", "next": "^14.0.4",
"popmotion": "^11.0.5", "popmotion": "^11.0.5",
"react": "^18.2.0", "react": "^18.2.0",
@@ -34,7 +38,8 @@
"eslint-config-next": "^14.0.4", "eslint-config-next": "^14.0.4",
"prettier": "^3.3.2", "prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.11", "prettier-plugin-tailwindcss": "^0.6.11",
"sharp": "0.33.1" "sharp": "0.33.1",
"tw-animate-css": "^1.3.8"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {
@@ -1713,6 +1718,15 @@
"integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@lobehub/fluent-emoji/node_modules/lucide-react": {
"version": "0.469.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.469.0.tgz",
"integrity": "sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==",
"license": "ISC",
"peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@lobehub/icons": { "node_modules/@lobehub/icons": {
"version": "1.97.2", "version": "1.97.2",
"resolved": "https://registry.npmjs.org/@lobehub/icons/-/icons-1.97.2.tgz", "resolved": "https://registry.npmjs.org/@lobehub/icons/-/icons-1.97.2.tgz",
@@ -1731,6 +1745,15 @@
"react-dom": "^18.0.0 || ^19.0.0" "react-dom": "^18.0.0 || ^19.0.0"
} }
}, },
"node_modules/@lobehub/icons/node_modules/lucide-react": {
"version": "0.469.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.469.0.tgz",
"integrity": "sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==",
"license": "ISC",
"peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@lobehub/ui": { "node_modules/@lobehub/ui": {
"version": "1.171.0", "version": "1.171.0",
"resolved": "https://registry.npmjs.org/@lobehub/ui/-/ui-1.171.0.tgz", "resolved": "https://registry.npmjs.org/@lobehub/ui/-/ui-1.171.0.tgz",
@@ -5003,6 +5026,15 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/cobe": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/cobe/-/cobe-0.6.4.tgz",
"integrity": "sha512-huuGFnDoXLy/tsCZYYa/H35BBRs9cxsS0XKJ3BXjRp699cQKuoEVrvKlAQMx0DKXG7+VUv4jsHVrS7yPbkLSkQ==",
"license": "MIT",
"dependencies": {
"phenomenon": "^1.6.0"
}
},
"node_modules/collapse-white-space": { "node_modules/collapse-white-space": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz",
@@ -8959,9 +8991,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/lucide-react": { "node_modules/lucide-react": {
"version": "0.469.0", "version": "0.544.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.469.0.tgz", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.544.0.tgz",
"integrity": "sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==", "integrity": "sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw==",
"license": "ISC", "license": "ISC",
"peerDependencies": { "peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
@@ -10265,6 +10297,32 @@
"pathe": "^2.0.1" "pathe": "^2.0.1"
} }
}, },
"node_modules/motion": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/motion/-/motion-12.23.12.tgz",
"integrity": "sha512-8jCD8uW5GD1csOoqh1WhH1A6j5APHVE15nuBkFeRiMzYBdRwyAHmSP/oXSuW0WJPZRXTFdBoG4hY9TFWNhhwng==",
"license": "MIT",
"dependencies": {
"framer-motion": "^12.23.12",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/motion-dom": { "node_modules/motion-dom": {
"version": "11.18.1", "version": "11.18.1",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
@@ -10280,6 +10338,48 @@
"integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==", "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/motion/node_modules/framer-motion": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.12.tgz",
"integrity": "sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==",
"license": "MIT",
"dependencies": {
"motion-dom": "^12.23.12",
"motion-utils": "^12.23.6",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/motion/node_modules/motion-dom": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.12.tgz",
"integrity": "sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.23.6"
}
},
"node_modules/motion/node_modules/motion-utils": {
"version": "12.23.6",
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz",
"integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
"license": "MIT"
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -10806,6 +10906,12 @@
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/phenomenon": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/phenomenon/-/phenomenon-1.6.0.tgz",
"integrity": "sha512-7h9/fjPD3qNlgggzm88cY58l9sudZ6Ey+UmZsizfhtawO6E3srZQXywaNm2lBwT72TbpHYRPy7ytIHeBUD/G0A==",
"license": "MIT"
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -13491,6 +13597,16 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/tw-animate-css": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.8.tgz",
"integrity": "sha512-Qrk3PZ7l7wUcGYhwZloqfkWCmaXZAoqjkdbIDvzfGshwGtexa/DAs9koXxIkrpEasyevandomzCBAV1Yyop5rw==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/Wombosvideo"
}
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",

View File

@@ -17,8 +17,12 @@
"@types/node": "^20.10.8", "@types/node": "^20.10.8",
"@types/react": "^18.2.55", "@types/react": "^18.2.55",
"@types/react-dom": "^18.2.18", "@types/react-dom": "^18.2.18",
"clsx": "^2.1.0", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cobe": "^0.6.4",
"framer-motion": "^10.15.0", "framer-motion": "^10.15.0",
"lucide-react": "^0.544.0",
"motion": "^12.23.12",
"next": "^14.0.4", "next": "^14.0.4",
"popmotion": "^11.0.5", "popmotion": "^11.0.5",
"react": "^18.2.0", "react": "^18.2.0",
@@ -36,6 +40,7 @@
"eslint-config-next": "^14.0.4", "eslint-config-next": "^14.0.4",
"prettier": "^3.3.2", "prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.11", "prettier-plugin-tailwindcss": "^0.6.11",
"sharp": "0.33.1" "sharp": "0.33.1",
"tw-animate-css": "^1.3.8"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

15
public/images/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 120 KiB

BIN
public/images/m.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

View File

@@ -11,6 +11,7 @@ import { CallTo } from '@/components/CallTo'
import { ScrollDown } from '@/components/ui/ScrollDown' import { ScrollDown } from '@/components/ui/ScrollDown'
import { ScrollUp } from '@/components/ui/ScrollUp' import { ScrollUp } from '@/components/ui/ScrollUp'
import { GridStats } from '@/components/GridStats' import { GridStats } from '@/components/GridStats'
import { WorldMap } from '@/components/WorldMap'
export default function Home() { export default function Home() {
return ( return (
@@ -18,21 +19,19 @@ export default function Home() {
<section id="home-hero"> <section id="home-hero">
<HomeHero /> <HomeHero />
</section> </section>
<section id="home-about">
<HomeAbout />
</section>
<section id="grid-stats">
<GridStats />
</section>
<section id="companies"> <section id="companies">
<Companies /> <Companies />
</section> </section>
<section id="stack-section">
<StackSectionPreview />
</section>
<section id="steps"> <section id="steps">
<Steps /> <Steps />
</section> </section>
<section id="grid-stats">
<GridStats />
</section>
<section id="stack-section">
<StackSectionPreview />
</section>
<section id="clickable-gallery"> <section id="clickable-gallery">
<ClickableGallery /> <ClickableGallery />
</section> </section>
@@ -45,6 +44,7 @@ export default function Home() {
<section id="faqs"> <section id="faqs">
<Faqs /> <Faqs />
</section> </section>
<ScrollDown /> <ScrollDown />
<ScrollUp /> <ScrollUp />
</> </>

View File

@@ -25,7 +25,7 @@ export default function RootLayout({
children: React.ReactNode children: React.ReactNode
}) { }) {
return ( return (
<html lang="en" className={clsx('bg-white antialiased', mulish.variable)}> <html lang="en" className={clsx('antialiased', mulish.variable)}>
<body>{children}</body> <body>{children}</body>
</html> </html>
) )

View File

@@ -0,0 +1,92 @@
"use client";
import React from "react";
import { motion } from "framer-motion";
import { H2, P } from '@/components/Texts';
import Ai21 from '@/components/logos/Ai21';
import Claude from '@/components/logos/Claude';
import BaiduCloud from '@/components/logos/BaiduCloud';
import ByteDance from '@/components/logos/ByteDance';
import DeepSeek from '@/components/logos/DeepSeek';
import DeepMind from '@/components/logos/DeepMind';
import Minimax from '@/components/logos/Minimax';
import Mistral from '@/components/logos/Mistral';
import Moonshot from '@/components/logos/Moonshot';
import AlibabaCloud from '@/components/logos/AlibabaCloud';
import TencentCloud from '@/components/logos/TencentCloud';
import OpenAI from '@/components/logos/OpenAI';
import XAI from '@/components/logos/XAI';
const row1 = [Ai21, Claude, BaiduCloud, ByteDance];
const row2 = [DeepSeek, DeepMind, Minimax, Mistral];
const row3 = [Moonshot, AlibabaCloud];
const row4 = [TencentCloud, OpenAI, XAI];
export function Companies() {
return (
<div id="companies" className="relative flex h-screen 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-6xl p-4 py-12">
{/* Heading */}
<motion.div
className="flex flex-col justify-center max-w-4xl items-center mb-6 mx-auto"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1 }}
>
<H2 className="text-center pb-6">
Deploy the Worlds Leading AI Models
</H2>
<P className="pb-8 text-center" color="custom">
Deploy and scale AI from top global providers on a decentralized, privacy-first infrastructure.
</P>
</motion.div>
{/* Animated Line */}
<motion.div
className="h-[2px] bg-neutral-400 rounded-full mx-auto mb-12"
initial={{ width: 0 }}
animate={{ width: "100%" }}
transition={{ duration: 2, delay: 1 }}
/>
{/* Logos grid */}
<div className="flex flex-col items-center gap-y-10">
{[row1, row2, row3, row4].map((row, rowIndex) => (
<motion.div
key={rowIndex}
className="flex flex-wrap justify-center items-center gap-x-8 sm:gap-x-10"
initial="hidden"
animate="visible"
variants={{
visible: {
transition: {
staggerChildren: 0.15,
delayChildren: 2.8 + rowIndex * 0.5, // Stagger rows
},
},
}}
>
{row.map((Logo, i) => (
<motion.div
key={i}
className="flex justify-center"
variants={{
hidden: { opacity: 0, y: 30 },
visible: { opacity: 1, y: 0 },
}}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<div className="text-[#2F3178]"><Logo /></div>
</motion.div>
))}
</motion.div>
))}
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,90 @@
'use client'
import { useState } from 'react'
import { motion } from 'framer-motion'
import { TypeAnimation } from 'react-type-animation'
import { Dialog, DialogPanel } from '@headlessui/react'
import { Bars3Icon, XMarkIcon, ChevronDoubleDownIcon } from '@heroicons/react/24/outline'
import { H1, PL } from '@/components/Texts'
const navigation = [
{ name: 'Product', href: '#' },
{ name: 'Features', href: '#' },
{ name: 'Marketplace', href: '#' },
{ name: 'Company', href: '#' },
]
export function HomeHero() {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
return (
<div className="relative h-screen -top-15">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2 }}
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] h-[700px] -z-10 rounded-full overflow-hidden"
>
<video
autoPlay
loop
muted
playsInline
className="h-full w-full object-cover"
>
<source src="/videos/mycelium.mp4" type="video/mp4" />
</video>
</motion.div>
<div className="relative isolate px-6 lg:px-8">
<div
aria-hidden="true"
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl lg:-top-80"
>
<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="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#a4caf6] to-[#aaa4fa] opacity-15 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
/>
</div>
<div
aria-hidden="true"
className="absolute inset-x-0 bottom-10 -z-10 transform-gpu overflow-hidden blur-3xl lg:bottom-40"
>
<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="relative bottom-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#93c5fd] to-[#9089fc] opacity-15 sm:left-[calc(50%+30rem)] sm:w-[72.1875rem]"
/>
</div>
<div className="relative -top-15 mx-auto max-w-8xl h-screen flex items-center justify-center">
<div className="text-center max-w-5xl">
<H1>
<TypeAnimation
sequence={[
'Decentralized Autonomous Agentic Cloud.',
1000,
]}
wrapper="span"
speed={50}
repeat={0}
/>
</H1>
</div>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1, delay: 1 }}
>
<PL className="absolute bottom-0 left-0 max-w-xl text-left" color="custom">
Mycelium's advancements in Agentic infrastructure supports private, secure and autonomous Agents that connect, learn and grow with you.
</PL>
</motion.div>
</div>
</div>
</div>
)
}

View File

@@ -10,13 +10,13 @@ const baseStyles = {
const variantStyles = { const variantStyles = {
solid: { solid: {
cyan: 'relative overflow-hidden bg-[#2F3178] text-white before:absolute before:inset-0 active:before:bg-transparent hover:before:bg-white/10 active:bg-[#2F3178] active:text-white/80 before:transition-colors', cyan: 'relative overflow-hidden bg-[#005eff] text-white before:absolute before:inset-0 active:before:bg-transparent hover:before:bg-white/10 active:bg-[#005eff] 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-cyan-900 hover:bg-white/90 active:bg-white/90 active:text-cyan-900/70',
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-200 hover:border-gray-400 active:bg-gray-100 active:text-gray-700/80',
}, },
} }

View File

@@ -3,6 +3,7 @@
import React from "react"; import React from "react";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { H2, P } from '@/components/Texts'; import { H2, P } from '@/components/Texts';
import { InfiniteMovingCards } from "@/components/magicui/infinite-moving-cards";
@@ -15,76 +16,58 @@ import DeepMind from '@/components/logos/DeepMind';
import Minimax from '@/components/logos/Minimax'; import Minimax from '@/components/logos/Minimax';
import Mistral from '@/components/logos/Mistral'; import Mistral from '@/components/logos/Mistral';
import Moonshot from '@/components/logos/Moonshot'; import Moonshot from '@/components/logos/Moonshot';
import AlibabaCloud from '@/components/logos/AlibabaCloud';
import TencentCloud from '@/components/logos/TencentCloud'; import TencentCloud from '@/components/logos/TencentCloud';
import OpenAI from '@/components/logos/OpenAI'; import OpenAI from '@/components/logos/OpenAI';
import XAI from '@/components/logos/XAI'; import XAI from '@/components/logos/XAI';
const row1 = [Ai21, Claude, BaiduCloud, ByteDance]; const logos = [
const row2 = [DeepSeek, DeepMind, Minimax, Mistral]; <Ai21 key="ai21" />,
const row3 = [Moonshot, AlibabaCloud]; <Claude key="claude" />,
const row4 = [TencentCloud, OpenAI, XAI]; <BaiduCloud key="baidu" />,
<ByteDance key="bytedance" />,
<DeepSeek key="deepseek" />,
<DeepMind key="deepmind" />,
<Minimax key="minimax" />,
<Mistral key="mistral" />,
<Moonshot key="moonshot" />,
<TencentCloud key="tencent" />,
<OpenAI key="openai" />,
<XAI key="xai" />,
];
const row1 = logos.slice(0, 6);
const row2 = logos.slice(6);
export function Companies() { export function Companies() {
return ( return (
<div id="companies" className="relative flex h-screen w-full overflow-hidden rounded-md bg-transparent antialiased md:items-center md:justify-center"> <div id="companies" className="relative bg-black flex flex-col items-center justify-center w-full overflow-hidden antialiased py-12 -top-20">
<div className="relative z-10 mx-auto w-full max-w-6xl p-4 py-12"> <div className="relative z-10 mx-auto w-full max-w-6xl p-4">
{/* Heading */} {/* Heading */}
<motion.div <motion.div
className="flex flex-col justify-center max-w-4xl items-center mb-6 mx-auto" className="flex flex-col justify-center max-w-4xl items-center mb-8 mx-auto"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1 }} transition={{ duration: 1 }}
> >
<H2 className="text-center pb-6"> <P className="text-gray-100 text-center">
Deploy the Worlds Leading AI Models Mycelium Cloud allows you to deploy and scale AI agents from top global providers on a decentralized, privacy-first infrastructure.
</H2>
<P className="pb-8 text-center" color="custom">
Deploy and scale AI from top global providers on a decentralized, privacy-first infrastructure. Mycelium Cloud lets you integrate state-of-the-art intelligence into your workflows with full control, sovereignty, and cost efficiency.
</P> </P>
</motion.div> </motion.div>
{/* Animated Line */}
<motion.div
className="h-[2px] bg-neutral-400 rounded-full mx-auto mb-12"
initial={{ width: 0 }}
animate={{ width: "100%" }}
transition={{ duration: 2, delay: 1 }}
/>
{/* Logos grid */} {/* Logos grid */}
<div className="flex flex-col items-center gap-y-10"> <div className="flex flex-col items-center gap-y-4 text-white">
{[row1, row2, row3, row4].map((row, rowIndex) => ( <InfiniteMovingCards
<motion.div items={row1}
key={rowIndex} direction="right"
className="flex flex-wrap justify-center items-center gap-x-8 sm:gap-x-10" speed="slow"
initial="hidden" />
animate="visible" <InfiniteMovingCards
variants={{ className=""
visible: { items={row2}
transition: { direction="left"
staggerChildren: 0.15, speed="slow"
delayChildren: 2.8 + rowIndex * 0.5, // Stagger rows />
},
},
}}
>
{row.map((Logo, i) => (
<motion.div
key={i}
className="flex justify-center"
variants={{
hidden: { opacity: 0, y: 30 },
visible: { opacity: 1, y: 0 },
}}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<div className="text-[#2F3178]"><Logo /></div>
</motion.div>
))}
</motion.div>
))}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -18,51 +18,23 @@ export function HomeHero() {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false) const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
return ( return (
<div className="relative h-screen -top-15"> <div className="relative h-screen -top-20">
<motion.div <div className="absolute inset-0 -z-10">
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2 }}
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] h-[700px] -z-10 rounded-full overflow-hidden"
>
<video <video
autoPlay autoPlay
loop loop
muted muted
playsInline playsInline
className="h-full w-full object-cover" className="absolute inset-0 w-full h-full object-cover"
> >
<source src="/videos/mycelium.mp4" type="video/mp4" /> <source src="/videos/mycelium.mp4" type="video/mp4" />
</video> </video>
</motion.div> <div className="absolute inset-0 bg-black/60" />
<div className="relative isolate px-6 lg:px-8"> </div>
<div <div className="relative px-6 lg:px-8">
aria-hidden="true"
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl lg:-top-80"
>
<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="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#a4caf6] to-[#aaa4fa] opacity-15 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
/>
</div>
<div
aria-hidden="true"
className="absolute inset-x-0 bottom-10 -z-10 transform-gpu overflow-hidden blur-3xl lg:bottom-40"
>
<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="relative bottom-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#93c5fd] to-[#9089fc] opacity-15 sm:left-[calc(50%+30rem)] sm:w-[72.1875rem]"
/>
</div>
<div className="relative -top-15 mx-auto max-w-8xl h-screen flex items-center justify-center"> <div className="relative -top-15 mx-auto max-w-8xl h-screen flex items-center justify-center">
<div className="text-center max-w-5xl"> <div className="text-center max-w-5xl">
<H1> <H1 color="light">
<TypeAnimation <TypeAnimation
sequence={[ sequence={[
'Decentralized Autonomous Agentic Cloud.', 'Decentralized Autonomous Agentic Cloud.',
@@ -79,7 +51,7 @@ export function HomeHero() {
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
transition={{ duration: 1, delay: 1 }} transition={{ duration: 1, delay: 1 }}
> >
<PL className="absolute bottom-0 left-0 max-w-xl text-left" color="custom"> <PL className="absolute bottom-0 left-0 max-w-xl text-left text-gray-100" color="light">
Mycelium's advancements in Agentic infrastructure supports private, secure and autonomous Agents that connect, learn and grow with you. Mycelium's advancements in Agentic infrastructure supports private, secure and autonomous Agents that connect, learn and grow with you.
</PL> </PL>
</motion.div> </motion.div>

File diff suppressed because one or more lines are too long

View File

@@ -21,7 +21,7 @@ export function NavLinks() {
<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-[#2F3178] transition-colors delay-150 hover:text-[#2F3178] hover:delay-0" className="relative -mx-3 -my-2 rounded-lg px-3 py-2 text-sm text-white transition-colors delay-150 hover:text-gray-300 hover:delay-0"
onMouseEnter={() => { onMouseEnter={() => {
if (timeoutRef.current) { if (timeoutRef.current) {
window.clearTimeout(timeoutRef.current) window.clearTimeout(timeoutRef.current)
@@ -37,7 +37,7 @@ export function NavLinks() {
<AnimatePresence> <AnimatePresence>
{hoveredIndex === index && ( {hoveredIndex === index && (
<motion.span <motion.span
className="absolute inset-0 rounded-lg bg-gray-100" className="absolute inset-0 rounded-lg bg-white/10"
layoutId="hoverBackground" layoutId="hoverBackground"
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { duration: 0.15 } }} animate={{ opacity: 1, transition: { duration: 0.15 } }}

View File

@@ -7,6 +7,7 @@ const colorVariants = {
primary: 'text-[#2F3178]', primary: 'text-[#2F3178]',
secondary: 'text-gray-600', secondary: 'text-gray-600',
custom: 'text-[#1c1c49]', custom: 'text-[#1c1c49]',
light: 'text-white',
} as const } as const
type TextOwnProps = { type TextOwnProps = {

View File

@@ -0,0 +1,7 @@
import { Globe } from "@/components/ui/globe"
export function WorldMap() {
return (
<Globe />
)
}

View File

@@ -1,3 +1,3 @@
import { Ai21 } from '@lobehub/icons'; import { Ai21 } from '@lobehub/icons';
export default () => <Ai21.Brand size={40} />; export default () => <Ai21.Brand size={30} />;

View File

@@ -1,3 +1,3 @@
import { AlibabaCloud } from '@lobehub/icons'; import { AlibabaCloud } from '@lobehub/icons';
export default () => <AlibabaCloud.Text size={40} />; export default () => <AlibabaCloud.Text size={30} />;

View File

@@ -1,3 +1,3 @@
import { BaiduCloud } from '@lobehub/icons'; import { BaiduCloud } from '@lobehub/icons';
export default () => <BaiduCloud.Combine size={40} />; export default () => <BaiduCloud.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { ByteDance } from '@lobehub/icons'; import { ByteDance } from '@lobehub/icons';
export default () => <ByteDance.Text size={40} />; export default () => <ByteDance.Text size={30} />;

View File

@@ -1,3 +1,3 @@
import { Claude } from '@lobehub/icons'; import { Claude } from '@lobehub/icons';
export default () => <Claude.Combine size={40} />; export default () => <Claude.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { DeepMind } from '@lobehub/icons'; import { DeepMind } from '@lobehub/icons';
export default () => <DeepMind.Combine size={40} />; export default () => <DeepMind.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { DeepSeek } from '@lobehub/icons'; import { DeepSeek } from '@lobehub/icons';
export default () => <DeepSeek.Combine size={40} />; export default () => <DeepSeek.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { Minimax } from '@lobehub/icons'; import { Minimax } from '@lobehub/icons';
export default () => <Minimax.Combine size={40} />; export default () => <Minimax.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { Mistral } from '@lobehub/icons'; import { Mistral } from '@lobehub/icons';
export default () => <Mistral.Combine size={40} />; export default () => <Mistral.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { Moonshot } from '@lobehub/icons'; import { Moonshot } from '@lobehub/icons';
export default () => <Moonshot.Combine size={40} />; export default () => <Moonshot.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { OpenAI } from '@lobehub/icons'; import { OpenAI } from '@lobehub/icons';
export default () => <OpenAI.Combine size={40} />; export default () => <OpenAI.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { TencentCloud } from '@lobehub/icons'; import { TencentCloud } from '@lobehub/icons';
export default () => <TencentCloud.Combine size={40} />; export default () => <TencentCloud.Combine size={30} />;

View File

@@ -1,3 +1,3 @@
import { XAI } from '@lobehub/icons'; import { XAI } from '@lobehub/icons';
export default () => <XAI.Text size={40} />; export default () => <XAI.Text size={30} />;

View File

@@ -0,0 +1,96 @@
"use client";
import { cn } from "@/lib/utils";
import React, { useEffect, useState } from "react";
export const InfiniteMovingCards = ({
items,
direction = "left",
speed = "fast",
pauseOnHover = true,
className,
}: {
items: React.ReactNode[];
direction?: "left" | "right";
speed?: "fast" | "normal" | "slow";
pauseOnHover?: boolean;
className?: string;
}) => {
const containerRef = React.useRef<HTMLDivElement>(null);
const scrollerRef = React.useRef<HTMLUListElement>(null);
useEffect(() => {
addAnimation();
}, []);
const [start, setStart] = useState(false);
function addAnimation() {
if (containerRef.current && scrollerRef.current) {
const scrollerContent = Array.from(scrollerRef.current.children);
scrollerContent.forEach((item) => {
const duplicatedItem = item.cloneNode(true);
if (scrollerRef.current) {
scrollerRef.current.appendChild(duplicatedItem);
}
});
getDirection();
getSpeed();
setStart(true);
}
}
const getDirection = () => {
if (containerRef.current) {
if (direction === "left") {
containerRef.current.style.setProperty(
"--animation-direction",
"forwards"
);
} else {
containerRef.current.style.setProperty(
"--animation-direction",
"reverse"
);
}
}
};
const getSpeed = () => {
if (containerRef.current) {
if (speed === "fast") {
containerRef.current.style.setProperty("--animation-duration", "20s");
} else if (speed === "normal") {
containerRef.current.style.setProperty("--animation-duration", "40s");
} else {
containerRef.current.style.setProperty("--animation-duration", "80s");
}
}
};
return (
<div
ref={containerRef}
className={cn(
"scroller relative z-20 max-w-7xl overflow-hidden [mask-image:linear-gradient(to_right,transparent,white_20%,white_80%,transparent)]",
className
)}
>
<ul
ref={scrollerRef}
className={cn(
" flex min-w-full shrink-0 gap-4 py-0 w-max flex-nowrap",
start && "animate-scroll ",
pauseOnHover && "hover:[animation-play-state:paused]"
)}
>
{items.map((item, idx) => (
<li
className="w-[160px] max-w-full relative flex-shrink-0 flex items-center justify-center px-8 py-0 md:w-[180px]"
key={idx}
>
{item}
</li>
))}
</ul>
</div>
);
};

View File

@@ -10,12 +10,12 @@ const baseStyles = {
const variantStyles = { const variantStyles = {
solid: { solid: {
primary: 'bg-[#2F3178] text-white hover:bg-[#2F3178]/90 active:bg-[#2F3178]/80', primary: 'bg-[#005eff] text-white hover:bg-[#005eff]/90 active:bg-[#005eff]/80',
white: 'bg-white text-black hover:bg-white/90 active:bg-white/90 active:text-gray-400', white: '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: {
primary: 'border-[#2F3178] text-[#2F3178] hover:border-[#2F3178]/80 hover:text-[#2F3178]/80 active:bg-gray-100 active:text-[#2F3178]/70', primary: 'border-[#005eff] text-[#005eff] hover:border-[#005eff]/80 hover:text-[#005eff]/80 active:bg-gray-100 active:text-[#005eff]/70',
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-400 active:bg-gray-100 active:text-gray-700/80',
}, },
} }

View File

@@ -13,7 +13,7 @@ export function ScrollDown() {
return ( return (
<button <button
onClick={scrollToNext} onClick={scrollToNext}
className="fixed bottom-8 right-8 z-50 flex items-center gap-x-2 text-2xl font-medium text-[#1c1c49] lg:text-3xl animate-blink" className="fixed bottom-8 right-8 z-50 flex items-center gap-x-2 text-2xl font-medium text-white lg:text-3xl animate-blink"
> >
<span>scroll</span> <span>scroll</span>
<ChevronDoubleDownIcon className="h-6 w-6" /> <ChevronDoubleDownIcon className="h-6 w-6" />

128
src/components/ui/globe.tsx Normal file
View File

@@ -0,0 +1,128 @@
"use client";
import createGlobe, { COBEOptions } from "cobe";
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.4,
mapSamples: 16000,
mapBrightness: 1.2,
baseColor: [1, 1, 1],
markerColor: [251 / 255, 100 / 255, 21 / 255],
glowColor: [1, 1, 1],
markers: [
{ location: [14.5995, 120.9842], size: 0.03 },
{ location: [19.076, 72.8777], size: 0.1 },
{ location: [23.8103, 90.4125], size: 0.05 },
{ location: [30.0444, 31.2357], size: 0.07 },
{ location: [39.9042, 116.4074], size: 0.08 },
{ location: [-23.5505, -46.6333], size: 0.1 },
{ location: [19.4326, -99.1332], size: 0.1 },
{ location: [40.7128, -74.006], size: 0.1 },
{ location: [34.6937, 135.5022], size: 0.05 },
{ location: [41.0082, 28.9784], size: 0.06 },
],
};
export function Globe({
className,
config = GLOBE_CONFIG,
}: {
className?: string;
config?: COBEOptions;
}) {
let phi = 0;
let width = 0;
const canvasRef = useRef<HTMLCanvasElement>(null);
const pointerInteracting = useRef<number | null>(null);
const pointerInteractionMovement = useRef(0);
const r = useMotionValue(0);
const rs = useSpring(r, {
mass: 1,
damping: 30,
stiffness: 100,
});
const updatePointerInteraction = (value: number | null) => {
pointerInteracting.current = value;
if (canvasRef.current) {
canvasRef.current.style.cursor = value !== null ? "grabbing" : "grab";
}
};
const updateMovement = (clientX: number) => {
if (pointerInteracting.current !== null) {
const delta = clientX - pointerInteracting.current;
pointerInteractionMovement.current = delta;
r.set(r.get() + delta / MOVEMENT_DAMPING);
}
};
useEffect(() => {
const onResize = () => {
if (canvasRef.current) {
width = canvasRef.current.offsetWidth;
}
};
window.addEventListener("resize", onResize);
onResize();
const globe = createGlobe(canvasRef.current!, {
...config,
width: width * 2,
height: width * 2,
onRender: (state) => {
if (!pointerInteracting.current) phi += 0.005;
state.phi = phi + rs.get();
state.width = width * 2;
state.height = width * 2;
},
});
setTimeout(() => (canvasRef.current!.style.opacity = "1"), 0);
return () => {
globe.destroy();
window.removeEventListener("resize", onResize);
};
}, [rs, config]);
return (
<div
className={cn(
"absolute inset-0 mx-auto aspect-[1/1] w-full max-w-[600px]",
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

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

View File

@@ -1,8 +1,17 @@
@import 'tailwindcss'; @import 'tailwindcss';
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@plugin '@tailwindcss/forms'; @plugin '@tailwindcss/forms';
@theme { @theme {
@keyframes scroll {
to {
transform: translate(calc(-50% - 0.5rem));
}
}
--text-*: initial; --text-*: initial;
--text-xs: 0.75rem; --text-xs: 0.75rem;
--text-xs--line-height: 1rem; --text-xs--line-height: 1rem;
@@ -101,6 +110,10 @@
} }
@layer utilities { @layer utilities {
.animate-scroll {
animation: scroll var(--animation-duration, 40s) var(--animation-direction, forwards) linear infinite;
}
.animate-blink { .animate-blink {
animation: blink 2s infinite; animation: blink 2s infinite;
} }
@@ -112,10 +125,132 @@
@theme inline { @theme inline {
--animate-marquee: marquee var(--marquee-duration) linear infinite; --animate-marquee: marquee var(--marquee-duration) linear infinite;
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--color-foreground: var(--foreground);
--color-background: var(--background);
@keyframes marquee { @keyframes marquee {
100% { 100% {
transform: translateY(-50%); transform: translateY(-50%);
} }
} }
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px)
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.13 0.028 261.692);
--card: oklch(1 0 0);
--card-foreground: oklch(0.13 0.028 261.692);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.13 0.028 261.692);
--primary: oklch(0.21 0.034 264.665);
--primary-foreground: oklch(0.985 0.002 247.839);
--secondary: oklch(0.967 0.003 264.542);
--secondary-foreground: oklch(0.21 0.034 264.665);
--muted: oklch(0.967 0.003 264.542);
--muted-foreground: oklch(0.551 0.027 264.364);
--accent: oklch(0.967 0.003 264.542);
--accent-foreground: oklch(0.21 0.034 264.665);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.928 0.006 264.531);
--input: oklch(0.928 0.006 264.531);
--ring: oklch(0.707 0.022 261.325);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0.002 247.839);
--sidebar-foreground: oklch(0.13 0.028 261.692);
--sidebar-primary: oklch(0.21 0.034 264.665);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-accent: oklch(0.967 0.003 264.542);
--sidebar-accent-foreground: oklch(0.21 0.034 264.665);
--sidebar-border: oklch(0.928 0.006 264.531);
--sidebar-ring: oklch(0.707 0.022 261.325);
}
.dark {
--background: oklch(0.13 0.028 261.692);
--foreground: oklch(0.985 0.002 247.839);
--card: oklch(0.21 0.034 264.665);
--card-foreground: oklch(0.985 0.002 247.839);
--popover: oklch(0.21 0.034 264.665);
--popover-foreground: oklch(0.985 0.002 247.839);
--primary: oklch(0.928 0.006 264.531);
--primary-foreground: oklch(0.21 0.034 264.665);
--secondary: oklch(0.278 0.033 256.848);
--secondary-foreground: oklch(0.985 0.002 247.839);
--muted: oklch(0.278 0.033 256.848);
--muted-foreground: oklch(0.707 0.022 261.325);
--accent: oklch(0.278 0.033 256.848);
--accent-foreground: oklch(0.985 0.002 247.839);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.551 0.027 264.364);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.21 0.034 264.665);
--sidebar-foreground: oklch(0.985 0.002 247.839);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-accent: oklch(0.278 0.033 256.848);
--sidebar-accent-foreground: oklch(0.985 0.002 247.839);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.551 0.027 264.364);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
} }