diff --git a/apps/blog/src/app/(blog)/layout.tsx b/apps/blog/src/app/(blog)/layout.tsx
index b63622a04c..54ce2154d2 100644
--- a/apps/blog/src/app/(blog)/layout.tsx
+++ b/apps/blog/src/app/(blog)/layout.tsx
@@ -34,12 +34,6 @@ export function baseOptions() {
desc: "Make your database global",
url: "https://www.prisma.io/accelerate",
},
- // {
- // icon: "fa-regular fa-plug",
- // text: "Management API",
- // desc: "Offer Postgres to your users",
- // url: "https://www.prisma.io/management-api",
- // },
],
},
{
@@ -56,14 +50,14 @@ export function baseOptions() {
icon: "fa-regular fa-message-code",
},
{
- text: "Get started",
- url: "https://www.prisma.io/docs",
- icon: "fa-regular fa-book-open",
+ text: "Prisma Partners",
+ url: "/partners",
+ icon: "fa-regular fa-lightbulb",
},
{
text: "Tutorials",
url: "https://www.prisma.io/docs/guides",
- icon: "fa-regular fa-clapperboard-play"
+ icon: "fa-regular fa-clapperboard-play",
},
{
text: "Examples",
@@ -95,8 +89,8 @@ export function baseOptions() {
],
},
{
- url: "/partners",
- text: "Partners",
+ url: "/docs",
+ text: "Docs",
},
{
url: "https://www.prisma.io/blog",
@@ -109,7 +103,10 @@ export function baseOptions() {
export default function Layout({ children }: { children: React.ReactNode }) {
return (
-
+
{children}
diff --git a/apps/site/package.json b/apps/site/package.json
index f89768ff49..c9d6de8357 100644
--- a/apps/site/package.json
+++ b/apps/site/package.json
@@ -13,17 +13,21 @@
},
"dependencies": {
"@base-ui/react": "catalog:",
- "@prisma/eclipse": "workspace:^",
"@prisma-docs/ui": "workspace:*",
+ "@prisma/eclipse": "workspace:^",
+ "@react-three/fiber": "^9.5.0",
"cors": "^2.8.6",
+ "html-react-parser": "^5.2.17",
"lucide-react": "catalog:",
"next": "catalog:",
"npm-to-yarn": "catalog:",
+ "posthog-js": "catalog:",
"react": "catalog:",
"react-dom": "catalog:",
"react-tweet": "catalog:",
- "posthog-js": "catalog:",
"remark-directive": "catalog:",
+ "tailwind-merge": "catalog:",
+ "three": "^0.183.2",
"zod": "catalog:"
},
"devDependencies": {
@@ -32,11 +36,12 @@
"@types/node": "catalog:",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
+ "@types/three": "^0.183.1",
+ "babel-plugin-react-compiler": "catalog:",
"next-validate-link": "catalog:",
"postcss": "catalog:",
"tailwindcss": "catalog:",
"tsx": "catalog:",
- "typescript": "catalog:",
- "babel-plugin-react-compiler": "catalog:"
+ "typescript": "catalog:"
}
}
diff --git a/apps/site/public/icons/companies/OpenAi.svg b/apps/site/public/icons/companies/OpenAi.svg
new file mode 100644
index 0000000000..745f69f03e
--- /dev/null
+++ b/apps/site/public/icons/companies/OpenAi.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/apps/site/public/icons/companies/agvolution.svg b/apps/site/public/icons/companies/agvolution.svg
new file mode 100644
index 0000000000..3c72c04318
--- /dev/null
+++ b/apps/site/public/icons/companies/agvolution.svg
@@ -0,0 +1 @@
+
diff --git a/apps/site/public/icons/companies/amplify.svg b/apps/site/public/icons/companies/amplify.svg
new file mode 100644
index 0000000000..263397e9a4
--- /dev/null
+++ b/apps/site/public/icons/companies/amplify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/anstack.svg b/apps/site/public/icons/companies/anstack.svg
new file mode 100644
index 0000000000..667fed7137
--- /dev/null
+++ b/apps/site/public/icons/companies/anstack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/apideck.svg b/apps/site/public/icons/companies/apideck.svg
new file mode 100644
index 0000000000..894b564a0e
--- /dev/null
+++ b/apps/site/public/icons/companies/apideck.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/apollo.svg b/apps/site/public/icons/companies/apollo.svg
new file mode 100644
index 0000000000..688bbb543d
--- /dev/null
+++ b/apps/site/public/icons/companies/apollo.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/avenue.svg b/apps/site/public/icons/companies/avenue.svg
new file mode 100644
index 0000000000..ab40ee7bf7
--- /dev/null
+++ b/apps/site/public/icons/companies/avenue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/aws-white.svg b/apps/site/public/icons/companies/aws-white.svg
new file mode 100644
index 0000000000..6ed2d8600f
--- /dev/null
+++ b/apps/site/public/icons/companies/aws-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/aws.svg b/apps/site/public/icons/companies/aws.svg
new file mode 100644
index 0000000000..238645df20
--- /dev/null
+++ b/apps/site/public/icons/companies/aws.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/azure.svg b/apps/site/public/icons/companies/azure.svg
new file mode 100644
index 0000000000..c10fa4e3d0
--- /dev/null
+++ b/apps/site/public/icons/companies/azure.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/cal.svg b/apps/site/public/icons/companies/cal.svg
new file mode 100644
index 0000000000..5f9e051284
--- /dev/null
+++ b/apps/site/public/icons/companies/cal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/cargon.svg b/apps/site/public/icons/companies/cargon.svg
new file mode 100644
index 0000000000..94da283173
--- /dev/null
+++ b/apps/site/public/icons/companies/cargon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/caribou.png b/apps/site/public/icons/companies/caribou.png
new file mode 100644
index 0000000000..1fa0482fcd
Binary files /dev/null and b/apps/site/public/icons/companies/caribou.png differ
diff --git a/apps/site/public/icons/companies/cloudfare-white.svg b/apps/site/public/icons/companies/cloudfare-white.svg
new file mode 100644
index 0000000000..6932411f60
--- /dev/null
+++ b/apps/site/public/icons/companies/cloudfare-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/cloudflare.svg b/apps/site/public/icons/companies/cloudflare.svg
new file mode 100644
index 0000000000..65d861aef7
--- /dev/null
+++ b/apps/site/public/icons/companies/cloudflare.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/cockroachdb-white.svg b/apps/site/public/icons/companies/cockroachdb-white.svg
new file mode 100644
index 0000000000..13d7da3f0e
--- /dev/null
+++ b/apps/site/public/icons/companies/cockroachdb-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/cockroachdb.svg b/apps/site/public/icons/companies/cockroachdb.svg
new file mode 100644
index 0000000000..fd6dbb7184
--- /dev/null
+++ b/apps/site/public/icons/companies/cockroachdb.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/coinrotator.png b/apps/site/public/icons/companies/coinrotator.png
new file mode 100644
index 0000000000..88d3bae356
Binary files /dev/null and b/apps/site/public/icons/companies/coinrotator.png differ
diff --git a/apps/site/public/icons/companies/debrie-advisory-white.svg b/apps/site/public/icons/companies/debrie-advisory-white.svg
new file mode 100644
index 0000000000..78dfe460d7
--- /dev/null
+++ b/apps/site/public/icons/companies/debrie-advisory-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/deno-darkmode.svg b/apps/site/public/icons/companies/deno-darkmode.svg
new file mode 100644
index 0000000000..82da8c6e04
--- /dev/null
+++ b/apps/site/public/icons/companies/deno-darkmode.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/digitalspeed.png b/apps/site/public/icons/companies/digitalspeed.png
new file mode 100644
index 0000000000..b8c819cdb3
Binary files /dev/null and b/apps/site/public/icons/companies/digitalspeed.png differ
diff --git a/apps/site/public/icons/companies/dooboolab.png b/apps/site/public/icons/companies/dooboolab.png
new file mode 100644
index 0000000000..53e497bb74
Binary files /dev/null and b/apps/site/public/icons/companies/dooboolab.png differ
diff --git a/apps/site/public/icons/companies/dotworld.png b/apps/site/public/icons/companies/dotworld.png
new file mode 100644
index 0000000000..6f2c65eabb
Binary files /dev/null and b/apps/site/public/icons/companies/dotworld.png differ
diff --git a/apps/site/public/icons/companies/ecstatic.svg b/apps/site/public/icons/companies/ecstatic.svg
new file mode 100644
index 0000000000..fa8d54a770
--- /dev/null
+++ b/apps/site/public/icons/companies/ecstatic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/elsevier.svg b/apps/site/public/icons/companies/elsevier.svg
new file mode 100644
index 0000000000..50c231254f
--- /dev/null
+++ b/apps/site/public/icons/companies/elsevier.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/escape.png b/apps/site/public/icons/companies/escape.png
new file mode 100644
index 0000000000..5d441f31af
Binary files /dev/null and b/apps/site/public/icons/companies/escape.png differ
diff --git a/apps/site/public/icons/companies/everfund.svg b/apps/site/public/icons/companies/everfund.svg
new file mode 100644
index 0000000000..256eb32d84
--- /dev/null
+++ b/apps/site/public/icons/companies/everfund.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/everify.svg b/apps/site/public/icons/companies/everify.svg
new file mode 100644
index 0000000000..69f0ef964e
--- /dev/null
+++ b/apps/site/public/icons/companies/everify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/expand.png b/apps/site/public/icons/companies/expand.png
new file mode 100644
index 0000000000..9749b86a09
Binary files /dev/null and b/apps/site/public/icons/companies/expand.png differ
diff --git a/apps/site/public/icons/companies/fathom.png b/apps/site/public/icons/companies/fathom.png
new file mode 100644
index 0000000000..b74292bdf7
Binary files /dev/null and b/apps/site/public/icons/companies/fathom.png differ
diff --git a/apps/site/public/icons/companies/feather.svg b/apps/site/public/icons/companies/feather.svg
new file mode 100644
index 0000000000..deba2869de
--- /dev/null
+++ b/apps/site/public/icons/companies/feather.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/fig.svg b/apps/site/public/icons/companies/fig.svg
new file mode 100644
index 0000000000..994af00257
--- /dev/null
+++ b/apps/site/public/icons/companies/fig.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/flux.svg b/apps/site/public/icons/companies/flux.svg
new file mode 100644
index 0000000000..4536d2dd8a
--- /dev/null
+++ b/apps/site/public/icons/companies/flux.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/flycode.png b/apps/site/public/icons/companies/flycode.png
new file mode 100644
index 0000000000..a9513a1839
Binary files /dev/null and b/apps/site/public/icons/companies/flycode.png differ
diff --git a/apps/site/public/icons/companies/fridayfinance.svg b/apps/site/public/icons/companies/fridayfinance.svg
new file mode 100644
index 0000000000..7c963e9e9d
--- /dev/null
+++ b/apps/site/public/icons/companies/fridayfinance.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/gamma.svg b/apps/site/public/icons/companies/gamma.svg
new file mode 100644
index 0000000000..eb01bb892e
--- /dev/null
+++ b/apps/site/public/icons/companies/gamma.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/garages-near-me.svg b/apps/site/public/icons/companies/garages-near-me.svg
new file mode 100644
index 0000000000..2265d0784b
--- /dev/null
+++ b/apps/site/public/icons/companies/garages-near-me.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/gatsby.svg b/apps/site/public/icons/companies/gatsby.svg
new file mode 100644
index 0000000000..659db3a91a
--- /dev/null
+++ b/apps/site/public/icons/companies/gatsby.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/github-light.svg b/apps/site/public/icons/companies/github-light.svg
new file mode 100644
index 0000000000..d5e6491854
--- /dev/null
+++ b/apps/site/public/icons/companies/github-light.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/github.svg b/apps/site/public/icons/companies/github.svg
new file mode 100644
index 0000000000..9d410383fe
--- /dev/null
+++ b/apps/site/public/icons/companies/github.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/apps/site/public/icons/companies/goodsouls.svg b/apps/site/public/icons/companies/goodsouls.svg
new file mode 100644
index 0000000000..6b81a2c859
--- /dev/null
+++ b/apps/site/public/icons/companies/goodsouls.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/googlecloud.svg b/apps/site/public/icons/companies/googlecloud.svg
new file mode 100644
index 0000000000..210a384528
--- /dev/null
+++ b/apps/site/public/icons/companies/googlecloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/grover.svg b/apps/site/public/icons/companies/grover.svg
new file mode 100644
index 0000000000..3134fe25f3
--- /dev/null
+++ b/apps/site/public/icons/companies/grover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/ihi.svg b/apps/site/public/icons/companies/ihi.svg
new file mode 100644
index 0000000000..ce84482714
--- /dev/null
+++ b/apps/site/public/icons/companies/ihi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/insta.svg b/apps/site/public/icons/companies/insta.svg
new file mode 100644
index 0000000000..43c362b863
--- /dev/null
+++ b/apps/site/public/icons/companies/insta.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/instatus.svg b/apps/site/public/icons/companies/instatus.svg
new file mode 100644
index 0000000000..d2de70cf88
--- /dev/null
+++ b/apps/site/public/icons/companies/instatus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/invisible.svg b/apps/site/public/icons/companies/invisible.svg
new file mode 100644
index 0000000000..cc59927212
--- /dev/null
+++ b/apps/site/public/icons/companies/invisible.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/jelly.svg b/apps/site/public/icons/companies/jelly.svg
new file mode 100644
index 0000000000..ed7e4a1100
--- /dev/null
+++ b/apps/site/public/icons/companies/jelly.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/kleinerperkins.png b/apps/site/public/icons/companies/kleinerperkins.png
new file mode 100644
index 0000000000..b85e582fa1
Binary files /dev/null and b/apps/site/public/icons/companies/kleinerperkins.png differ
diff --git a/apps/site/public/icons/companies/krisenchat.png b/apps/site/public/icons/companies/krisenchat.png
new file mode 100644
index 0000000000..d378e669d9
Binary files /dev/null and b/apps/site/public/icons/companies/krisenchat.png differ
diff --git a/apps/site/public/icons/companies/lovable.svg b/apps/site/public/icons/companies/lovable.svg
new file mode 100644
index 0000000000..6a6ad1a39e
--- /dev/null
+++ b/apps/site/public/icons/companies/lovable.svg
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/memberstack.svg b/apps/site/public/icons/companies/memberstack.svg
new file mode 100644
index 0000000000..c674258363
--- /dev/null
+++ b/apps/site/public/icons/companies/memberstack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/mongodb-white.svg b/apps/site/public/icons/companies/mongodb-white.svg
new file mode 100644
index 0000000000..7fea28554f
--- /dev/null
+++ b/apps/site/public/icons/companies/mongodb-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/motionbox.svg b/apps/site/public/icons/companies/motionbox.svg
new file mode 100644
index 0000000000..872dca332d
--- /dev/null
+++ b/apps/site/public/icons/companies/motionbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/nachonacho.svg b/apps/site/public/icons/companies/nachonacho.svg
new file mode 100644
index 0000000000..7e977eb81c
--- /dev/null
+++ b/apps/site/public/icons/companies/nachonacho.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/neon.svg b/apps/site/public/icons/companies/neon.svg
new file mode 100644
index 0000000000..1f15c5a149
--- /dev/null
+++ b/apps/site/public/icons/companies/neon.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/nestjs.svg b/apps/site/public/icons/companies/nestjs.svg
new file mode 100644
index 0000000000..ce3245a30b
--- /dev/null
+++ b/apps/site/public/icons/companies/nestjs.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/netlify-logo.svg b/apps/site/public/icons/companies/netlify-logo.svg
new file mode 100644
index 0000000000..ccb830dcbd
--- /dev/null
+++ b/apps/site/public/icons/companies/netlify-logo.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/netlify-white.svg b/apps/site/public/icons/companies/netlify-white.svg
new file mode 100644
index 0000000000..63ef5b2fb3
--- /dev/null
+++ b/apps/site/public/icons/companies/netlify-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/netlify.svg b/apps/site/public/icons/companies/netlify.svg
new file mode 100644
index 0000000000..bfe0355611
--- /dev/null
+++ b/apps/site/public/icons/companies/netlify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/nextjs.svg b/apps/site/public/icons/companies/nextjs.svg
new file mode 100644
index 0000000000..cf7f77fb1c
--- /dev/null
+++ b/apps/site/public/icons/companies/nextjs.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/nuna.svg b/apps/site/public/icons/companies/nuna.svg
new file mode 100644
index 0000000000..0ba8a5f61b
--- /dev/null
+++ b/apps/site/public/icons/companies/nuna.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/openai-light.svg b/apps/site/public/icons/companies/openai-light.svg
new file mode 100644
index 0000000000..ba36fc2aa7
--- /dev/null
+++ b/apps/site/public/icons/companies/openai-light.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/outrider.svg b/apps/site/public/icons/companies/outrider.svg
new file mode 100644
index 0000000000..1a5464479c
--- /dev/null
+++ b/apps/site/public/icons/companies/outrider.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/oxio.svg b/apps/site/public/icons/companies/oxio.svg
new file mode 100644
index 0000000000..b87d9b0383
--- /dev/null
+++ b/apps/site/public/icons/companies/oxio.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/pabio.svg b/apps/site/public/icons/companies/pabio.svg
new file mode 100644
index 0000000000..75f1b041b6
--- /dev/null
+++ b/apps/site/public/icons/companies/pabio.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/panther.svg b/apps/site/public/icons/companies/panther.svg
new file mode 100644
index 0000000000..145ac6f9c3
--- /dev/null
+++ b/apps/site/public/icons/companies/panther.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/planetscale-light.svg b/apps/site/public/icons/companies/planetscale-light.svg
new file mode 100644
index 0000000000..e4b0536df3
--- /dev/null
+++ b/apps/site/public/icons/companies/planetscale-light.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/planetscale-white.svg b/apps/site/public/icons/companies/planetscale-white.svg
new file mode 100644
index 0000000000..5584a8c6ac
--- /dev/null
+++ b/apps/site/public/icons/companies/planetscale-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/planetscale.svg b/apps/site/public/icons/companies/planetscale.svg
new file mode 100644
index 0000000000..76aaa1e4ee
--- /dev/null
+++ b/apps/site/public/icons/companies/planetscale.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/apps/site/public/icons/companies/pmt.svg b/apps/site/public/icons/companies/pmt.svg
new file mode 100644
index 0000000000..a11bd02f3d
--- /dev/null
+++ b/apps/site/public/icons/companies/pmt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/poppy.svg b/apps/site/public/icons/companies/poppy.svg
new file mode 100644
index 0000000000..81d7347f7f
--- /dev/null
+++ b/apps/site/public/icons/companies/poppy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/postgres.svg b/apps/site/public/icons/companies/postgres.svg
new file mode 100644
index 0000000000..a83d647c31
--- /dev/null
+++ b/apps/site/public/icons/companies/postgres.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/prevalentware.png b/apps/site/public/icons/companies/prevalentware.png
new file mode 100644
index 0000000000..6d6ab0b994
Binary files /dev/null and b/apps/site/public/icons/companies/prevalentware.png differ
diff --git a/apps/site/public/icons/companies/primcloud.png b/apps/site/public/icons/companies/primcloud.png
new file mode 100644
index 0000000000..501cfda3d1
Binary files /dev/null and b/apps/site/public/icons/companies/primcloud.png differ
diff --git a/apps/site/public/icons/companies/prosperity.png b/apps/site/public/icons/companies/prosperity.png
new file mode 100644
index 0000000000..c4d63e04fd
Binary files /dev/null and b/apps/site/public/icons/companies/prosperity.png differ
diff --git a/apps/site/public/icons/companies/questmate.png b/apps/site/public/icons/companies/questmate.png
new file mode 100644
index 0000000000..74551a06e5
Binary files /dev/null and b/apps/site/public/icons/companies/questmate.png differ
diff --git a/apps/site/public/icons/companies/railway-light.svg b/apps/site/public/icons/companies/railway-light.svg
new file mode 100644
index 0000000000..6ba32d849b
--- /dev/null
+++ b/apps/site/public/icons/companies/railway-light.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/railway.svg b/apps/site/public/icons/companies/railway.svg
new file mode 100644
index 0000000000..2a7a513a56
--- /dev/null
+++ b/apps/site/public/icons/companies/railway.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/rapha.svg b/apps/site/public/icons/companies/rapha.svg
new file mode 100644
index 0000000000..f97a013d9e
--- /dev/null
+++ b/apps/site/public/icons/companies/rapha.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/react.svg b/apps/site/public/icons/companies/react.svg
new file mode 100644
index 0000000000..76cf7a40a8
--- /dev/null
+++ b/apps/site/public/icons/companies/react.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/remix-light.svg b/apps/site/public/icons/companies/remix-light.svg
new file mode 100644
index 0000000000..f0643d873f
--- /dev/null
+++ b/apps/site/public/icons/companies/remix-light.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/remix.svg b/apps/site/public/icons/companies/remix.svg
new file mode 100644
index 0000000000..25faf57061
--- /dev/null
+++ b/apps/site/public/icons/companies/remix.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/replit.svg b/apps/site/public/icons/companies/replit.svg
new file mode 100644
index 0000000000..deb66b5fae
--- /dev/null
+++ b/apps/site/public/icons/companies/replit.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/revere.png b/apps/site/public/icons/companies/revere.png
new file mode 100644
index 0000000000..e7297e2d9f
Binary files /dev/null and b/apps/site/public/icons/companies/revere.png differ
diff --git a/apps/site/public/icons/companies/sequin.svg b/apps/site/public/icons/companies/sequin.svg
new file mode 100644
index 0000000000..868464c09e
--- /dev/null
+++ b/apps/site/public/icons/companies/sequin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/simpler.png b/apps/site/public/icons/companies/simpler.png
new file mode 100644
index 0000000000..2e389304bf
Binary files /dev/null and b/apps/site/public/icons/companies/simpler.png differ
diff --git a/apps/site/public/icons/companies/southpole.svg b/apps/site/public/icons/companies/southpole.svg
new file mode 100644
index 0000000000..59659d8524
--- /dev/null
+++ b/apps/site/public/icons/companies/southpole.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/sqlite.svg b/apps/site/public/icons/companies/sqlite.svg
new file mode 100644
index 0000000000..59073339da
--- /dev/null
+++ b/apps/site/public/icons/companies/sqlite.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/sqlserver.svg b/apps/site/public/icons/companies/sqlserver.svg
new file mode 100644
index 0000000000..da58ca5b24
--- /dev/null
+++ b/apps/site/public/icons/companies/sqlserver.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/stellate.svg b/apps/site/public/icons/companies/stellate.svg
new file mode 100644
index 0000000000..8d2d68d940
--- /dev/null
+++ b/apps/site/public/icons/companies/stellate.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/stonegiantstudio.svg b/apps/site/public/icons/companies/stonegiantstudio.svg
new file mode 100644
index 0000000000..21dd5ea2b3
--- /dev/null
+++ b/apps/site/public/icons/companies/stonegiantstudio.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/sunhat.svg b/apps/site/public/icons/companies/sunhat.svg
new file mode 100644
index 0000000000..6f4004fb2d
--- /dev/null
+++ b/apps/site/public/icons/companies/sunhat.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/supabase.svg b/apps/site/public/icons/companies/supabase.svg
new file mode 100644
index 0000000000..4a2bb01f78
--- /dev/null
+++ b/apps/site/public/icons/companies/supabase.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/superblog.svg b/apps/site/public/icons/companies/superblog.svg
new file mode 100644
index 0000000000..644fcd35ca
--- /dev/null
+++ b/apps/site/public/icons/companies/superblog.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/systemone.png b/apps/site/public/icons/companies/systemone.png
new file mode 100644
index 0000000000..195e7a5501
Binary files /dev/null and b/apps/site/public/icons/companies/systemone.png differ
diff --git a/apps/site/public/icons/companies/tabya.png b/apps/site/public/icons/companies/tabya.png
new file mode 100644
index 0000000000..84a1e67b25
Binary files /dev/null and b/apps/site/public/icons/companies/tabya.png differ
diff --git a/apps/site/public/icons/companies/tanstack.svg b/apps/site/public/icons/companies/tanstack.svg
new file mode 100644
index 0000000000..a530641199
--- /dev/null
+++ b/apps/site/public/icons/companies/tanstack.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/timenavi.svg b/apps/site/public/icons/companies/timenavi.svg
new file mode 100644
index 0000000000..82b88228b8
--- /dev/null
+++ b/apps/site/public/icons/companies/timenavi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/travis.svg b/apps/site/public/icons/companies/travis.svg
new file mode 100644
index 0000000000..fe9666f61b
--- /dev/null
+++ b/apps/site/public/icons/companies/travis.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/trunk.png b/apps/site/public/icons/companies/trunk.png
new file mode 100644
index 0000000000..a284f2cdc0
Binary files /dev/null and b/apps/site/public/icons/companies/trunk.png differ
diff --git a/apps/site/public/icons/companies/tryg.svg b/apps/site/public/icons/companies/tryg.svg
new file mode 100644
index 0000000000..a9b36772f2
--- /dev/null
+++ b/apps/site/public/icons/companies/tryg.svg
@@ -0,0 +1 @@
+
diff --git a/apps/site/public/icons/companies/turso.svg b/apps/site/public/icons/companies/turso.svg
new file mode 100644
index 0000000000..a8634abfb0
--- /dev/null
+++ b/apps/site/public/icons/companies/turso.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/companies/twiga.svg b/apps/site/public/icons/companies/twiga.svg
new file mode 100644
index 0000000000..a2395f0b6d
--- /dev/null
+++ b/apps/site/public/icons/companies/twiga.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/vercel-white.svg b/apps/site/public/icons/companies/vercel-white.svg
new file mode 100644
index 0000000000..109a19246e
--- /dev/null
+++ b/apps/site/public/icons/companies/vercel-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/vercel.svg b/apps/site/public/icons/companies/vercel.svg
new file mode 100644
index 0000000000..7d116d8d3c
--- /dev/null
+++ b/apps/site/public/icons/companies/vercel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/wasp.png b/apps/site/public/icons/companies/wasp.png
new file mode 100644
index 0000000000..a46bdfb73a
Binary files /dev/null and b/apps/site/public/icons/companies/wasp.png differ
diff --git a/apps/site/public/icons/companies/wefindflats.svg b/apps/site/public/icons/companies/wefindflats.svg
new file mode 100644
index 0000000000..b4bedc5c55
--- /dev/null
+++ b/apps/site/public/icons/companies/wefindflats.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/companies/wingfield.png b/apps/site/public/icons/companies/wingfield.png
new file mode 100644
index 0000000000..815d6a043a
Binary files /dev/null and b/apps/site/public/icons/companies/wingfield.png differ
diff --git a/apps/site/public/icons/companies/woofmeets.svg b/apps/site/public/icons/companies/woofmeets.svg
new file mode 100644
index 0000000000..429cb93e2e
--- /dev/null
+++ b/apps/site/public/icons/companies/woofmeets.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/angular.svg b/apps/site/public/icons/technologies/angular.svg
new file mode 100644
index 0000000000..4f127ef969
--- /dev/null
+++ b/apps/site/public/icons/technologies/angular.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/apollo.svg b/apps/site/public/icons/technologies/apollo.svg
new file mode 100644
index 0000000000..e3f2251793
--- /dev/null
+++ b/apps/site/public/icons/technologies/apollo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/appsync.svg b/apps/site/public/icons/technologies/appsync.svg
new file mode 100644
index 0000000000..c616a34fcd
--- /dev/null
+++ b/apps/site/public/icons/technologies/appsync.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/astro-dark.svg b/apps/site/public/icons/technologies/astro-dark.svg
new file mode 100644
index 0000000000..52b76d5509
--- /dev/null
+++ b/apps/site/public/icons/technologies/astro-dark.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/technologies/astro.svg b/apps/site/public/icons/technologies/astro.svg
new file mode 100644
index 0000000000..e52118199d
--- /dev/null
+++ b/apps/site/public/icons/technologies/astro.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/apps/site/public/icons/technologies/aurora.svg b/apps/site/public/icons/technologies/aurora.svg
new file mode 100644
index 0000000000..18ada6593c
--- /dev/null
+++ b/apps/site/public/icons/technologies/aurora.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/authjs.png b/apps/site/public/icons/technologies/authjs.png
new file mode 100644
index 0000000000..a1d000cda2
Binary files /dev/null and b/apps/site/public/icons/technologies/authjs.png differ
diff --git a/apps/site/public/icons/technologies/aws.svg b/apps/site/public/icons/technologies/aws.svg
new file mode 100644
index 0000000000..35e92a10c6
--- /dev/null
+++ b/apps/site/public/icons/technologies/aws.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/azure.svg b/apps/site/public/icons/technologies/azure.svg
new file mode 100644
index 0000000000..20426bf884
--- /dev/null
+++ b/apps/site/public/icons/technologies/azure.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/betterauth.png b/apps/site/public/icons/technologies/betterauth.png
new file mode 100644
index 0000000000..2daf864cf0
Binary files /dev/null and b/apps/site/public/icons/technologies/betterauth.png differ
diff --git a/apps/site/public/icons/technologies/bun.svg b/apps/site/public/icons/technologies/bun.svg
new file mode 100644
index 0000000000..7e6ec5bfc9
--- /dev/null
+++ b/apps/site/public/icons/technologies/bun.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/technologies/chakraui.svg b/apps/site/public/icons/technologies/chakraui.svg
new file mode 100644
index 0000000000..ddb5804cc1
--- /dev/null
+++ b/apps/site/public/icons/technologies/chakraui.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/clerk.jpeg b/apps/site/public/icons/technologies/clerk.jpeg
new file mode 100644
index 0000000000..8d6c953894
Binary files /dev/null and b/apps/site/public/icons/technologies/clerk.jpeg differ
diff --git a/apps/site/public/icons/technologies/client/mongodb.svg b/apps/site/public/icons/technologies/client/mongodb.svg
new file mode 100644
index 0000000000..0f1e4ce51f
--- /dev/null
+++ b/apps/site/public/icons/technologies/client/mongodb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/client/msserver.svg b/apps/site/public/icons/technologies/client/msserver.svg
new file mode 100644
index 0000000000..4a8b378523
--- /dev/null
+++ b/apps/site/public/icons/technologies/client/msserver.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/client/mysql.svg b/apps/site/public/icons/technologies/client/mysql.svg
new file mode 100644
index 0000000000..11d26f0a31
--- /dev/null
+++ b/apps/site/public/icons/technologies/client/mysql.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/client/postgres.svg b/apps/site/public/icons/technologies/client/postgres.svg
new file mode 100644
index 0000000000..7fecf163f6
--- /dev/null
+++ b/apps/site/public/icons/technologies/client/postgres.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/client/sqlite.svg b/apps/site/public/icons/technologies/client/sqlite.svg
new file mode 100644
index 0000000000..b6c2f82890
--- /dev/null
+++ b/apps/site/public/icons/technologies/client/sqlite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/cloudflare-d1.svg b/apps/site/public/icons/technologies/cloudflare-d1.svg
new file mode 100644
index 0000000000..de4b576f37
--- /dev/null
+++ b/apps/site/public/icons/technologies/cloudflare-d1.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/apps/site/public/icons/technologies/cloudflare-icon-only.svg b/apps/site/public/icons/technologies/cloudflare-icon-only.svg
new file mode 100644
index 0000000000..a8cbf3bc36
--- /dev/null
+++ b/apps/site/public/icons/technologies/cloudflare-icon-only.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/technologies/cloudflare.svg b/apps/site/public/icons/technologies/cloudflare.svg
new file mode 100644
index 0000000000..6debd115bb
--- /dev/null
+++ b/apps/site/public/icons/technologies/cloudflare.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/cockroach-full.svg b/apps/site/public/icons/technologies/cockroach-full.svg
new file mode 100644
index 0000000000..5462f6c52c
--- /dev/null
+++ b/apps/site/public/icons/technologies/cockroach-full.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/cockroach.svg b/apps/site/public/icons/technologies/cockroach.svg
new file mode 100644
index 0000000000..1d0da130a7
--- /dev/null
+++ b/apps/site/public/icons/technologies/cockroach.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/cognito.svg b/apps/site/public/icons/technologies/cognito.svg
new file mode 100644
index 0000000000..ee3a99bf76
--- /dev/null
+++ b/apps/site/public/icons/technologies/cognito.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/crunchbase.svg b/apps/site/public/icons/technologies/crunchbase.svg
new file mode 100644
index 0000000000..8691f3a560
--- /dev/null
+++ b/apps/site/public/icons/technologies/crunchbase.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/dart.svg b/apps/site/public/icons/technologies/dart.svg
new file mode 100644
index 0000000000..d8a76289ff
--- /dev/null
+++ b/apps/site/public/icons/technologies/dart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/datadog.svg b/apps/site/public/icons/technologies/datadog.svg
new file mode 100644
index 0000000000..b45614c826
--- /dev/null
+++ b/apps/site/public/icons/technologies/datadog.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/apps/site/public/icons/technologies/datadog_light.svg b/apps/site/public/icons/technologies/datadog_light.svg
new file mode 100644
index 0000000000..7c7320afed
--- /dev/null
+++ b/apps/site/public/icons/technologies/datadog_light.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/apps/site/public/icons/technologies/deno-deploy.svg b/apps/site/public/icons/technologies/deno-deploy.svg
new file mode 100644
index 0000000000..fbd0939a9b
--- /dev/null
+++ b/apps/site/public/icons/technologies/deno-deploy.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/apps/site/public/icons/technologies/digital-ocean.svg b/apps/site/public/icons/technologies/digital-ocean.svg
new file mode 100644
index 0000000000..616e9ec51e
--- /dev/null
+++ b/apps/site/public/icons/technologies/digital-ocean.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/docker-blue.svg b/apps/site/public/icons/technologies/docker-blue.svg
new file mode 100644
index 0000000000..90b0352f61
--- /dev/null
+++ b/apps/site/public/icons/technologies/docker-blue.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/docker.svg b/apps/site/public/icons/technologies/docker.svg
new file mode 100644
index 0000000000..16098870a5
--- /dev/null
+++ b/apps/site/public/icons/technologies/docker.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/elderjs.svg b/apps/site/public/icons/technologies/elderjs.svg
new file mode 100644
index 0000000000..95827dc802
--- /dev/null
+++ b/apps/site/public/icons/technologies/elderjs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/elixir.svg b/apps/site/public/icons/technologies/elixir.svg
new file mode 100644
index 0000000000..50f366abe5
--- /dev/null
+++ b/apps/site/public/icons/technologies/elixir.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/expo.svg b/apps/site/public/icons/technologies/expo.svg
new file mode 100644
index 0000000000..cf7e178c22
--- /dev/null
+++ b/apps/site/public/icons/technologies/expo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/express.svg b/apps/site/public/icons/technologies/express.svg
new file mode 100644
index 0000000000..a20e9a3d22
--- /dev/null
+++ b/apps/site/public/icons/technologies/express.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/fastify.svg b/apps/site/public/icons/technologies/fastify.svg
new file mode 100644
index 0000000000..e67bc90aec
--- /dev/null
+++ b/apps/site/public/icons/technologies/fastify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/gcp.svg b/apps/site/public/icons/technologies/gcp.svg
new file mode 100644
index 0000000000..16c5e0b473
--- /dev/null
+++ b/apps/site/public/icons/technologies/gcp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/genericdb.svg b/apps/site/public/icons/technologies/genericdb.svg
new file mode 100644
index 0000000000..0e6d1fb5d8
--- /dev/null
+++ b/apps/site/public/icons/technologies/genericdb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/github-dark.svg b/apps/site/public/icons/technologies/github-dark.svg
new file mode 100644
index 0000000000..d5e6491854
--- /dev/null
+++ b/apps/site/public/icons/technologies/github-dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/go.svg b/apps/site/public/icons/technologies/go.svg
new file mode 100644
index 0000000000..6239558454
--- /dev/null
+++ b/apps/site/public/icons/technologies/go.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/graphql.svg b/apps/site/public/icons/technologies/graphql.svg
new file mode 100644
index 0000000000..46f9e7a14e
--- /dev/null
+++ b/apps/site/public/icons/technologies/graphql.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/hapi.svg b/apps/site/public/icons/technologies/hapi.svg
new file mode 100644
index 0000000000..027886d838
--- /dev/null
+++ b/apps/site/public/icons/technologies/hapi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/haskell.svg b/apps/site/public/icons/technologies/haskell.svg
new file mode 100644
index 0000000000..8024a5d168
--- /dev/null
+++ b/apps/site/public/icons/technologies/haskell.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/helm.svg b/apps/site/public/icons/technologies/helm.svg
new file mode 100644
index 0000000000..279d3a39ed
--- /dev/null
+++ b/apps/site/public/icons/technologies/helm.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/heroku.svg b/apps/site/public/icons/technologies/heroku.svg
new file mode 100644
index 0000000000..7ad0e2cd42
--- /dev/null
+++ b/apps/site/public/icons/technologies/heroku.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/apollo.svg b/apps/site/public/icons/technologies/home-page/apollo.svg
new file mode 100644
index 0000000000..a333db3b48
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/apollo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/express.svg b/apps/site/public/icons/technologies/home-page/express.svg
new file mode 100644
index 0000000000..bce6404a30
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/express.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/github.svg b/apps/site/public/icons/technologies/home-page/github.svg
new file mode 100644
index 0000000000..4df97bd1e6
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/graphql.svg b/apps/site/public/icons/technologies/home-page/graphql.svg
new file mode 100644
index 0000000000..0e45ff5e21
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/graphql.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/hapi.svg b/apps/site/public/icons/technologies/home-page/hapi.svg
new file mode 100644
index 0000000000..50c1935e55
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/hapi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/nest.svg b/apps/site/public/icons/technologies/home-page/nest.svg
new file mode 100644
index 0000000000..b46928a1d9
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/nest.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/nextjs.svg b/apps/site/public/icons/technologies/home-page/nextjs.svg
new file mode 100644
index 0000000000..0b3a06ed85
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/nextjs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/subtract.svg b/apps/site/public/icons/technologies/home-page/subtract.svg
new file mode 100644
index 0000000000..0fb255eea2
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/subtract.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/home-page/union.svg b/apps/site/public/icons/technologies/home-page/union.svg
new file mode 100644
index 0000000000..080d3aa306
--- /dev/null
+++ b/apps/site/public/icons/technologies/home-page/union.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/hono.svg b/apps/site/public/icons/technologies/hono.svg
new file mode 100644
index 0000000000..eadbd3e119
--- /dev/null
+++ b/apps/site/public/icons/technologies/hono.svg
@@ -0,0 +1,7 @@
+
+
+ Hono Streamline Icon: https://streamlinehq.com
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/jamstack.svg b/apps/site/public/icons/technologies/jamstack.svg
new file mode 100644
index 0000000000..e66ae08a41
--- /dev/null
+++ b/apps/site/public/icons/technologies/jamstack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/js.svg b/apps/site/public/icons/technologies/js.svg
new file mode 100644
index 0000000000..dd87f59891
--- /dev/null
+++ b/apps/site/public/icons/technologies/js.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/kafka.svg b/apps/site/public/icons/technologies/kafka.svg
new file mode 100644
index 0000000000..c8e81f3fc6
--- /dev/null
+++ b/apps/site/public/icons/technologies/kafka.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/kubernetes.svg b/apps/site/public/icons/technologies/kubernetes.svg
new file mode 100644
index 0000000000..4045603a1d
--- /dev/null
+++ b/apps/site/public/icons/technologies/kubernetes.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/mariadb.png b/apps/site/public/icons/technologies/mariadb.png
new file mode 100644
index 0000000000..fb112daedc
Binary files /dev/null and b/apps/site/public/icons/technologies/mariadb.png differ
diff --git a/apps/site/public/icons/technologies/mongo-gray.svg b/apps/site/public/icons/technologies/mongo-gray.svg
new file mode 100644
index 0000000000..166589ebdf
--- /dev/null
+++ b/apps/site/public/icons/technologies/mongo-gray.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/mongo.svg b/apps/site/public/icons/technologies/mongo.svg
new file mode 100644
index 0000000000..f83134a1e8
--- /dev/null
+++ b/apps/site/public/icons/technologies/mongo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/mongodb.svg b/apps/site/public/icons/technologies/mongodb.svg
new file mode 100644
index 0000000000..3c0ea8bb4b
--- /dev/null
+++ b/apps/site/public/icons/technologies/mongodb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/mysql-gray.svg b/apps/site/public/icons/technologies/mysql-gray.svg
new file mode 100644
index 0000000000..c5de9dc24d
--- /dev/null
+++ b/apps/site/public/icons/technologies/mysql-gray.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/mysql.svg b/apps/site/public/icons/technologies/mysql.svg
new file mode 100644
index 0000000000..d76a7d87e5
--- /dev/null
+++ b/apps/site/public/icons/technologies/mysql.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/nest.svg b/apps/site/public/icons/technologies/nest.svg
new file mode 100644
index 0000000000..44f3e70213
--- /dev/null
+++ b/apps/site/public/icons/technologies/nest.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/nestjs.svg b/apps/site/public/icons/technologies/nestjs.svg
new file mode 100644
index 0000000000..1c2149258d
--- /dev/null
+++ b/apps/site/public/icons/technologies/nestjs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/netlify.svg b/apps/site/public/icons/technologies/netlify.svg
new file mode 100644
index 0000000000..513aca1688
--- /dev/null
+++ b/apps/site/public/icons/technologies/netlify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/next.svg b/apps/site/public/icons/technologies/next.svg
new file mode 100644
index 0000000000..646304c7ed
--- /dev/null
+++ b/apps/site/public/icons/technologies/next.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/nextjs copy.svg b/apps/site/public/icons/technologies/nextjs copy.svg
new file mode 100644
index 0000000000..cf7f77fb1c
--- /dev/null
+++ b/apps/site/public/icons/technologies/nextjs copy.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/nextjs-new.svg b/apps/site/public/icons/technologies/nextjs-new.svg
new file mode 100644
index 0000000000..b029dbd1bd
--- /dev/null
+++ b/apps/site/public/icons/technologies/nextjs-new.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/nextjs.svg b/apps/site/public/icons/technologies/nextjs.svg
new file mode 100644
index 0000000000..646304c7ed
--- /dev/null
+++ b/apps/site/public/icons/technologies/nextjs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/nexus.svg b/apps/site/public/icons/technologies/nexus.svg
new file mode 100644
index 0000000000..f6354654de
--- /dev/null
+++ b/apps/site/public/icons/technologies/nexus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/node.svg b/apps/site/public/icons/technologies/node.svg
new file mode 100644
index 0000000000..66945bbb7b
--- /dev/null
+++ b/apps/site/public/icons/technologies/node.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/nuxt.svg b/apps/site/public/icons/technologies/nuxt.svg
new file mode 100644
index 0000000000..c1854ba717
--- /dev/null
+++ b/apps/site/public/icons/technologies/nuxt.svg
@@ -0,0 +1,6 @@
+
+
+ Nuxt Icon Streamline Icon: https://streamlinehq.com
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/open-api.svg b/apps/site/public/icons/technologies/open-api.svg
new file mode 100644
index 0000000000..084e9e1269
--- /dev/null
+++ b/apps/site/public/icons/technologies/open-api.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/planetscale.svg b/apps/site/public/icons/technologies/planetscale.svg
new file mode 100644
index 0000000000..5025d378c2
--- /dev/null
+++ b/apps/site/public/icons/technologies/planetscale.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/pnpm.svg b/apps/site/public/icons/technologies/pnpm.svg
new file mode 100644
index 0000000000..70db803a46
--- /dev/null
+++ b/apps/site/public/icons/technologies/pnpm.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/postgres.svg b/apps/site/public/icons/technologies/postgres.svg
new file mode 100644
index 0000000000..ff40e30e7f
--- /dev/null
+++ b/apps/site/public/icons/technologies/postgres.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/postgresql.svg b/apps/site/public/icons/technologies/postgresql.svg
new file mode 100644
index 0000000000..ff40e30e7f
--- /dev/null
+++ b/apps/site/public/icons/technologies/postgresql.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/prisma-postgres.svg b/apps/site/public/icons/technologies/prisma-postgres.svg
new file mode 100644
index 0000000000..0313f6a862
--- /dev/null
+++ b/apps/site/public/icons/technologies/prisma-postgres.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/prisma-white.svg b/apps/site/public/icons/technologies/prisma-white.svg
new file mode 100644
index 0000000000..afd929e7ec
--- /dev/null
+++ b/apps/site/public/icons/technologies/prisma-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/prisma.svg b/apps/site/public/icons/technologies/prisma.svg
new file mode 100644
index 0000000000..e250c0f520
--- /dev/null
+++ b/apps/site/public/icons/technologies/prisma.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/python.svg b/apps/site/public/icons/technologies/python.svg
new file mode 100644
index 0000000000..4aa29519c0
--- /dev/null
+++ b/apps/site/public/icons/technologies/python.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/railway-dark.svg b/apps/site/public/icons/technologies/railway-dark.svg
new file mode 100644
index 0000000000..6ba32d849b
--- /dev/null
+++ b/apps/site/public/icons/technologies/railway-dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/react-query.svg b/apps/site/public/icons/technologies/react-query.svg
new file mode 100644
index 0000000000..9c3439cedf
--- /dev/null
+++ b/apps/site/public/icons/technologies/react-query.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/react.svg b/apps/site/public/icons/technologies/react.svg
new file mode 100644
index 0000000000..237fe6b560
--- /dev/null
+++ b/apps/site/public/icons/technologies/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/redis.svg b/apps/site/public/icons/technologies/redis.svg
new file mode 100644
index 0000000000..392e91b927
--- /dev/null
+++ b/apps/site/public/icons/technologies/redis.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/redwoodjs.svg b/apps/site/public/icons/technologies/redwoodjs.svg
new file mode 100644
index 0000000000..3b23f8b2c8
--- /dev/null
+++ b/apps/site/public/icons/technologies/redwoodjs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/relay.svg b/apps/site/public/icons/technologies/relay.svg
new file mode 100644
index 0000000000..f13a4773e0
--- /dev/null
+++ b/apps/site/public/icons/technologies/relay.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/remix.svg b/apps/site/public/icons/technologies/remix.svg
new file mode 100644
index 0000000000..8e5c737e1b
--- /dev/null
+++ b/apps/site/public/icons/technologies/remix.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/rr7.svg b/apps/site/public/icons/technologies/rr7.svg
new file mode 100644
index 0000000000..73e2b73d32
--- /dev/null
+++ b/apps/site/public/icons/technologies/rr7.svg
@@ -0,0 +1,7 @@
+
+
+ React Router Streamline Icon: https://streamlinehq.com
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/rust.svg b/apps/site/public/icons/technologies/rust.svg
new file mode 100644
index 0000000000..c37be51ca9
--- /dev/null
+++ b/apps/site/public/icons/technologies/rust.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/shopify.svg b/apps/site/public/icons/technologies/shopify.svg
new file mode 100644
index 0000000000..e35deb8cc8
--- /dev/null
+++ b/apps/site/public/icons/technologies/shopify.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/solid-start.svg b/apps/site/public/icons/technologies/solid-start.svg
new file mode 100644
index 0000000000..7a8d22a8c1
--- /dev/null
+++ b/apps/site/public/icons/technologies/solid-start.svg
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/technologies/sqlite.svg b/apps/site/public/icons/technologies/sqlite.svg
new file mode 100644
index 0000000000..992616b0a5
--- /dev/null
+++ b/apps/site/public/icons/technologies/sqlite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/sqlserver.svg b/apps/site/public/icons/technologies/sqlserver.svg
new file mode 100644
index 0000000000..daae76c748
--- /dev/null
+++ b/apps/site/public/icons/technologies/sqlserver.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/svelte.svg b/apps/site/public/icons/technologies/svelte.svg
new file mode 100644
index 0000000000..c50e1c1063
--- /dev/null
+++ b/apps/site/public/icons/technologies/svelte.svg
@@ -0,0 +1,7 @@
+
+
+ Svelte Icon Streamline Icon: https://streamlinehq.com
+
+
+
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/swagger.svg b/apps/site/public/icons/technologies/swagger.svg
new file mode 100644
index 0000000000..88b8e87723
--- /dev/null
+++ b/apps/site/public/icons/technologies/swagger.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/tailwind.svg b/apps/site/public/icons/technologies/tailwind.svg
new file mode 100644
index 0000000000..28a991dc65
--- /dev/null
+++ b/apps/site/public/icons/technologies/tailwind.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/tanstack.svg b/apps/site/public/icons/technologies/tanstack.svg
new file mode 100644
index 0000000000..a530641199
--- /dev/null
+++ b/apps/site/public/icons/technologies/tanstack.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/technologies/trpc.svg b/apps/site/public/icons/technologies/trpc.svg
new file mode 100644
index 0000000000..d5eef07715
--- /dev/null
+++ b/apps/site/public/icons/technologies/trpc.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/ts-framed.svg b/apps/site/public/icons/technologies/ts-framed.svg
new file mode 100644
index 0000000000..159bf20291
--- /dev/null
+++ b/apps/site/public/icons/technologies/ts-framed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/ts.svg b/apps/site/public/icons/technologies/ts.svg
new file mode 100644
index 0000000000..89bc2cc237
--- /dev/null
+++ b/apps/site/public/icons/technologies/ts.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/turborepo-icon-only.svg b/apps/site/public/icons/technologies/turborepo-icon-only.svg
new file mode 100644
index 0000000000..7bd3c7baff
--- /dev/null
+++ b/apps/site/public/icons/technologies/turborepo-icon-only.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/icons/technologies/turborepo.svg b/apps/site/public/icons/technologies/turborepo.svg
new file mode 100644
index 0000000000..8671fba07c
--- /dev/null
+++ b/apps/site/public/icons/technologies/turborepo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/typegraphql.svg b/apps/site/public/icons/technologies/typegraphql.svg
new file mode 100644
index 0000000000..183654964c
--- /dev/null
+++ b/apps/site/public/icons/technologies/typegraphql.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/vercel-icon-dark.svg b/apps/site/public/icons/technologies/vercel-icon-dark.svg
new file mode 100644
index 0000000000..4e3b0e9335
--- /dev/null
+++ b/apps/site/public/icons/technologies/vercel-icon-dark.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/apps/site/public/icons/technologies/vercel.svg b/apps/site/public/icons/technologies/vercel.svg
new file mode 100644
index 0000000000..42740db776
--- /dev/null
+++ b/apps/site/public/icons/technologies/vercel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/vscode.svg b/apps/site/public/icons/technologies/vscode.svg
new file mode 100644
index 0000000000..97ca79854d
--- /dev/null
+++ b/apps/site/public/icons/technologies/vscode.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/icons/technologies/vue.svg b/apps/site/public/icons/technologies/vue.svg
new file mode 100644
index 0000000000..5965b3796f
--- /dev/null
+++ b/apps/site/public/icons/technologies/vue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/site/public/illustrations/homepage/collaborative.svg b/apps/site/public/illustrations/homepage/collaborative.svg
new file mode 100644
index 0000000000..bda169bc17
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/collaborative.svg
@@ -0,0 +1,368 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/collaborative_light.svg b/apps/site/public/illustrations/homepage/collaborative_light.svg
new file mode 100644
index 0000000000..b1394df84f
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/collaborative_light.svg
@@ -0,0 +1,368 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/data.svg b/apps/site/public/illustrations/homepage/data.svg
new file mode 100644
index 0000000000..6307485800
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/data.svg
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/data_light.svg b/apps/site/public/illustrations/homepage/data_light.svg
new file mode 100644
index 0000000000..8f782c456a
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/data_light.svg
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/footer_grid.svg b/apps/site/public/illustrations/homepage/footer_grid.svg
new file mode 100644
index 0000000000..f75fc3c650
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/footer_grid.svg
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/ide.svg b/apps/site/public/illustrations/homepage/ide.svg
new file mode 100644
index 0000000000..e39d309d46
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/ide.svg
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/ide_light.svg b/apps/site/public/illustrations/homepage/ide_light.svg
new file mode 100644
index 0000000000..ffa5f590fc
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/ide_light.svg
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/mcp.svg b/apps/site/public/illustrations/homepage/mcp.svg
new file mode 100644
index 0000000000..ba79f759ba
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/mcp.svg
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/mcp_light.svg b/apps/site/public/illustrations/homepage/mcp_light.svg
new file mode 100644
index 0000000000..34b7fd21e2
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/mcp_light.svg
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/real_ppg.svg b/apps/site/public/illustrations/homepage/real_ppg.svg
new file mode 100644
index 0000000000..3461c2a1aa
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/real_ppg.svg
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/real_ppg_light.svg b/apps/site/public/illustrations/homepage/real_ppg_light.svg
new file mode 100644
index 0000000000..05b89ccc19
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/real_ppg_light.svg
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/real_ppg_mobile.svg b/apps/site/public/illustrations/homepage/real_ppg_mobile.svg
new file mode 100644
index 0000000000..971d8521d9
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/real_ppg_mobile.svg
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/real_ppg_mobile_light.svg b/apps/site/public/illustrations/homepage/real_ppg_mobile_light.svg
new file mode 100644
index 0000000000..b51240b87c
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/real_ppg_mobile_light.svg
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/typesafe.svg b/apps/site/public/illustrations/homepage/typesafe.svg
new file mode 100644
index 0000000000..cc8dc64b93
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/typesafe.svg
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/illustrations/homepage/typesafe_light.svg b/apps/site/public/illustrations/homepage/typesafe_light.svg
new file mode 100644
index 0000000000..de704ac181
--- /dev/null
+++ b/apps/site/public/illustrations/homepage/typesafe_light.svg
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/site/public/photos/people/chris-lis.jpg b/apps/site/public/photos/people/chris-lis.jpg
new file mode 100644
index 0000000000..5279c9afaa
Binary files /dev/null and b/apps/site/public/photos/people/chris-lis.jpg differ
diff --git a/apps/site/public/photos/people/cody-bontecou.jpg b/apps/site/public/photos/people/cody-bontecou.jpg
new file mode 100644
index 0000000000..47c9ce5797
Binary files /dev/null and b/apps/site/public/photos/people/cody-bontecou.jpg differ
diff --git a/apps/site/public/photos/people/daniel-cranney.jpeg b/apps/site/public/photos/people/daniel-cranney.jpeg
new file mode 100644
index 0000000000..66618e73dc
Binary files /dev/null and b/apps/site/public/photos/people/daniel-cranney.jpeg differ
diff --git a/apps/site/public/photos/people/dries-augustyns.jpg b/apps/site/public/photos/people/dries-augustyns.jpg
new file mode 100644
index 0000000000..a78e221654
Binary files /dev/null and b/apps/site/public/photos/people/dries-augustyns.jpg differ
diff --git a/apps/site/public/photos/people/elie-steinbock.png b/apps/site/public/photos/people/elie-steinbock.png
new file mode 100644
index 0000000000..3849bae0df
Binary files /dev/null and b/apps/site/public/photos/people/elie-steinbock.png differ
diff --git a/apps/site/public/photos/people/harshal-patil.png b/apps/site/public/photos/people/harshal-patil.png
new file mode 100644
index 0000000000..1889348436
Binary files /dev/null and b/apps/site/public/photos/people/harshal-patil.png differ
diff --git a/apps/site/public/photos/people/harshdeep-singh-hura.jpg b/apps/site/public/photos/people/harshdeep-singh-hura.jpg
new file mode 100644
index 0000000000..be0f916745
Binary files /dev/null and b/apps/site/public/photos/people/harshdeep-singh-hura.jpg differ
diff --git a/apps/site/public/photos/people/ian-hunter.jpeg b/apps/site/public/photos/people/ian-hunter.jpeg
new file mode 100644
index 0000000000..918506cb0a
Binary files /dev/null and b/apps/site/public/photos/people/ian-hunter.jpeg differ
diff --git a/apps/site/public/photos/people/jake-colling.jpeg b/apps/site/public/photos/people/jake-colling.jpeg
new file mode 100644
index 0000000000..eaa6de03fd
Binary files /dev/null and b/apps/site/public/photos/people/jake-colling.jpeg differ
diff --git a/apps/site/public/photos/people/jim-hendriks.webp b/apps/site/public/photos/people/jim-hendriks.webp
new file mode 100644
index 0000000000..8570e32e0c
Binary files /dev/null and b/apps/site/public/photos/people/jim-hendriks.webp differ
diff --git a/apps/site/public/photos/people/jonathan-wilke.jpeg b/apps/site/public/photos/people/jonathan-wilke.jpeg
new file mode 100644
index 0000000000..a55fd49eef
Binary files /dev/null and b/apps/site/public/photos/people/jonathan-wilke.jpeg differ
diff --git a/apps/site/public/photos/people/joonatan.jpeg b/apps/site/public/photos/people/joonatan.jpeg
new file mode 100644
index 0000000000..d027b208b4
Binary files /dev/null and b/apps/site/public/photos/people/joonatan.jpeg differ
diff --git a/apps/site/public/photos/people/martin-adams.jpeg b/apps/site/public/photos/people/martin-adams.jpeg
new file mode 100644
index 0000000000..6362382e8b
Binary files /dev/null and b/apps/site/public/photos/people/martin-adams.jpeg differ
diff --git a/apps/site/public/photos/people/matti-nannt.jpeg b/apps/site/public/photos/people/matti-nannt.jpeg
new file mode 100644
index 0000000000..189e799b3b
Binary files /dev/null and b/apps/site/public/photos/people/matti-nannt.jpeg differ
diff --git a/apps/site/public/photos/people/nevo-david.jpg b/apps/site/public/photos/people/nevo-david.jpg
new file mode 100644
index 0000000000..daa3a294f0
Binary files /dev/null and b/apps/site/public/photos/people/nevo-david.jpg differ
diff --git a/apps/site/public/photos/people/nicolas-torres.png b/apps/site/public/photos/people/nicolas-torres.png
new file mode 100644
index 0000000000..a214e6760a
Binary files /dev/null and b/apps/site/public/photos/people/nicolas-torres.png differ
diff --git a/apps/site/public/photos/people/niko-guerra.png b/apps/site/public/photos/people/niko-guerra.png
new file mode 100644
index 0000000000..97fb4df4f3
Binary files /dev/null and b/apps/site/public/photos/people/niko-guerra.png differ
diff --git a/apps/site/public/photos/people/ricardo-almeida.jpeg b/apps/site/public/photos/people/ricardo-almeida.jpeg
new file mode 100644
index 0000000000..4c4797d319
Binary files /dev/null and b/apps/site/public/photos/people/ricardo-almeida.jpeg differ
diff --git a/apps/site/public/photos/people/shuhrat-saipov.jpg b/apps/site/public/photos/people/shuhrat-saipov.jpg
new file mode 100644
index 0000000000..29ad02754c
Binary files /dev/null and b/apps/site/public/photos/people/shuhrat-saipov.jpg differ
diff --git a/apps/site/public/photos/people/steven-tey.jpeg b/apps/site/public/photos/people/steven-tey.jpeg
new file mode 100644
index 0000000000..d34cade825
Binary files /dev/null and b/apps/site/public/photos/people/steven-tey.jpeg differ
diff --git a/apps/site/public/photos/people/tom.png b/apps/site/public/photos/people/tom.png
new file mode 100644
index 0000000000..c936e558f7
Binary files /dev/null and b/apps/site/public/photos/people/tom.png differ
diff --git a/apps/site/public/photos/people/yuval-hazaz.jpeg b/apps/site/public/photos/people/yuval-hazaz.jpeg
new file mode 100644
index 0000000000..28c6dd30a2
Binary files /dev/null and b/apps/site/public/photos/people/yuval-hazaz.jpeg differ
diff --git a/apps/site/public/photos/people/zai-chi.jpeg b/apps/site/public/photos/people/zai-chi.jpeg
new file mode 100644
index 0000000000..5456781af2
Binary files /dev/null and b/apps/site/public/photos/people/zai-chi.jpeg differ
diff --git a/apps/site/src/app/(index)/page.tsx b/apps/site/src/app/(index)/page.tsx
index 428125b655..fb7167dac7 100644
--- a/apps/site/src/app/(index)/page.tsx
+++ b/apps/site/src/app/(index)/page.tsx
@@ -1,6 +1,64 @@
+import Antigravity from "../../components/homepage/antigravity";
import type { Metadata } from "next";
-import { SITE_HOME_DESCRIPTION, SITE_HOME_TITLE } from "../../lib/blog-metadata";
+import {
+ SITE_HOME_DESCRIPTION,
+ SITE_HOME_TITLE,
+} from "../../lib/blog-metadata";
+import { Button } from "@prisma/eclipse";
+import { CopyCode } from "@/components/homepage/copy-btn";
+import LogoParade from "@prisma-docs/ui/components/logo-parade";
+import React from "react";
+import { Bento } from "@/components/homepage/bento";
+import { CardSection } from "@/components/homepage/card-section/card-section";
+const MemorizedLogoParade = React.memo(LogoParade);
+import review from "../../data/homepage.json";
+import Testimonials from "../../components/homepage/testimonials";
+const twoCol = [
+ {
+ content: (
+ <>
+
+ Postgres that fits your stack.
+
+
+ Works with your existing stack, wherever you deploy.Your choice of
+ ORM, frameworks, and tools, they all just connect.
+
+ >
+ ),
+ imageUrl: null,
+ imageAlt: null,
+ mobileImageUrl: null,
+ mobileImageAlt: null,
+ logos: null,
+ useDefaultLogos: true,
+ visualPosition: "right" as const,
+ visualType: "logoGrid" as const,
+ },
+ {
+ content: (
+ <>
+
+ Real Postgres. Better experience.
+
+
+ The PostgreSQL millions know and trust in production, ready in seconds
+ with zero configuration. Automatic backups, observability and
+ compliance.
+
+ >
+ ),
+ imageUrl: "/illustrations/homepage/real_ppg",
+ imageAlt: "Real Postgres",
+ mobileImageUrl: "/illustrations/homepage/real_ppg_mobile",
+ mobileImageAlt: "Real PPG mobile",
+ logos: null,
+ useDefaultLogos: false,
+ visualPosition: "left" as const,
+ visualType: "image" as const,
+ },
+];
export const metadata: Metadata = {
title: SITE_HOME_TITLE,
description: SITE_HOME_DESCRIPTION,
@@ -8,14 +66,183 @@ export const metadata: Metadata = {
export default function SiteHome() {
return (
-
-
- Prisma Site
-
-
- This app is the primary host zone. Content sections are served by their
- own zones via routing rules.
-
+
+
+
+
+
+ Postgres,
+ perfectly managed.
+
+
+ Real Postgres with the developer experience and infrastructure to
+ ship faster.
+
+
+
+ Create database
+
+
+
+ $
+
+ npx prisma init --db
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Build anything.
+
+ Deploy instantly.
+
+
+
+ Give your users instant production-ready Postgres, create
+ databases, add a built-in data browser, and personalize it.
+
+
+ Explore Pricing
+
+
+
+
+
+
+ {review?.testimonials?.length > 0 && (
+
+ )}
+
+
+
+
+
+ Ready to try Prisma?
+
+
+ Deploy a Postgres database instantly.
+
+
+
+
+ Create your first Database
+
+
+
+ Explore Pricing
+
+
+
+
+ Free to get started, no credit card needed.
+
+
+
+
);
}
diff --git a/apps/site/src/app/global.css b/apps/site/src/app/global.css
index f0100f4a23..799fd38d4c 100644
--- a/apps/site/src/app/global.css
+++ b/apps/site/src/app/global.css
@@ -1,89 +1,194 @@
@import "tailwindcss";
@import "@prisma/eclipse/styles/globals.css";
@import "@prisma-docs/ui/styles";
+@source inline("paused");
+@source inline("running");
+@source inline("md:hover:paused");
+@source inline("hover:paused");
+
+@theme {
+ --animate-slide-down: slideDown 130s linear infinite;
+ --animate-slide-down-2: slideDown2 130s linear infinite;
+ --animate-slide-up: slideUp 100s linear infinite;
+ --animate-slide-up-2: slideUp2 100s linear infinite;
+}
:root {
--color-fd-primary: var(--color-stroke-ppg);
}
-.bg-blog {
- background-color: var(--color-background-default);
+body {
+ background: var(--color-background-default);
}
-.bg-blog::after {
- content: "";
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 5000px;
- background: linear-gradient(
- 0deg,
- var(--color-background-default) 95%,
- var(--color-background-ppg) 100%
- );
- z-index: -1;
+@keyframes slideDown {
+ from {
+ transform: translateY(0%);
+ }
+ to {
+ transform: translateY(50%);
+ }
}
-.landing-h1 {
- color: var(--color-foreground-neutral);
- font-variant-numeric: lining-nums tabular-nums slashed-zero;
- font-variation-settings: "wdth" 125;
- /* title/3xl */
- font-family: var(--font-sans-display);
- font-size: 60px;
- font-style: normal;
- font-weight: 900;
- line-height: 120%; /* 120% */
+@keyframes slideDown2 {
+ from {
+ transform: translateY(-50%);
+ }
+ to {
+ transform: translateY(0%);
+ }
}
-.newsletter-bg {
- background: linear-gradient(
- 59deg,
- color-mix(in srgb, var(--color-foreground-ppg) 30%, transparent) 6.53%,
- var(--color-background-default) 74.71%
- )
+@keyframes slideUp {
+ from {
+ transform: translateY(0%);
+ }
+ to {
+ transform: translateY(-50%);
+ }
+}
+
+@keyframes slideUp2 {
+ from {
+ transform: translateY(50%);
+ }
+ to {
+ transform: translateY(0%);
+ }
}
@keyframes glitch-1 {
0% {
- clip-path: inset(20% 0 60% 0);
+ clip-path: inset(20% 0 60% 0);
}
20% {
- clip-path: inset(10% 0 85% 0);
+ clip-path: inset(10% 0 85% 0);
}
40% {
- clip-path: inset(40% 0 40% 0);
+ clip-path: inset(40% 0 40% 0);
}
60% {
- clip-path: inset(80% 0 5% 0);
+ clip-path: inset(80% 0 5% 0);
}
80% {
- clip-path: inset(50% 0 30% 0);
+ clip-path: inset(50% 0 30% 0);
}
100% {
- clip-path: inset(25% 0 55% 0);
+ clip-path: inset(25% 0 55% 0);
}
- }
+}
@keyframes glitch-2 {
0% {
- clip-path: inset(80% 0 5% 0);
+ clip-path: inset(80% 0 5% 0);
}
20% {
- clip-path: inset(50% 0 30% 0);
+ clip-path: inset(50% 0 30% 0);
}
40% {
- clip-path: inset(20% 0 60% 0);
+ clip-path: inset(20% 0 60% 0);
}
60% {
- clip-path: inset(10% 0 85% 0);
+ clip-path: inset(10% 0 85% 0);
}
80% {
- clip-path: inset(40% 0 40% 0);
+ clip-path: inset(40% 0 40% 0);
}
100% {
- clip-path: inset(75% 0 15% 0);
+ clip-path: inset(75% 0 15% 0);
}
}
+.box {
+ display: flex;
+ height: 300px;
+ cursor: pointer;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 16px;
+ z-index: 10;
+ border-radius: 9px;
+ border: 1px solid var(--color-stroke-neutral);
+ opacity: 0;
+ overflow: hidden;
+ position: relative;
+ transform: scale(0.9) translateY(20px);
+ border-radius: rounded-square-high;
+ border: 1px solid stroke-neutral;
+ background: linear-gradient(
+ 180deg,
+ var(--color-background-default) 0%,
+ var(--color-background-ppg) 262.5%
+ );
+ transition: background 0.3s ease;
+}
+
+.box-visible {
+ opacity: 1;
+ transform: scale(1) translateY(0);
+ transition:
+ opacity 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
+ transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
+ border-color 0.3s ease,
+ box-shadow 0.3s ease,
+ background 0.3s ease;
+}
+
+.box::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ border-radius: 8px;
+ padding: 1px;
+ background: var(--color-stroke-neutral);
+ -webkit-mask:
+ linear-gradient(#fff 0 0) content-box,
+ linear-gradient(#fff 0 0);
+ mask-composite: exclude;
+ pointer-events: none;
+ transition: background 0.3s ease;
+ zindex: 1;
+}
+
+/* Dark mode hover effect */
+.box:hover::before {
+ background: conic-gradient(
+ from var(--angle, 0deg) at 50% 50%,
+ var(--color-teal-400) 0deg,
+ rgba(22, 163, 148, 0.3) 30deg,
+ rgba(22, 29, 43, 0.8) 90deg,
+ rgba(22, 29, 43, 0.8) 270deg,
+ rgba(22, 163, 148, 0.3) 330deg,
+ var(--color-teal-400) 360deg
+ );
+}
+
+/* Light mode hover effect */
+[data-theme="light"] .box:hover::before {
+ background: conic-gradient(
+ from var(--angle, 0deg) at 50% 50%,
+ var(--color-teal-400) 0deg,
+ rgba(22, 163, 148, 0.3) 30deg,
+ rgba(229, 231, 235, 0.8) 90deg,
+ rgba(229, 231, 235, 0.8) 270deg,
+ rgba(22, 163, 148, 0.3) 330deg,
+ var(--color-teal-400) 360deg
+ );
+}
+
+.box:hover {
+ transform: translateY(-1px) scale(1.005);
+}
+
+.box:hover img {
+ mask-image: none;
+}
+
+/* Animation play state utilities */
+.paused {
+ animation-play-state: paused;
+}
+
+.running {
+ animation-play-state: running;
+}
diff --git a/apps/site/src/app/layout.tsx b/apps/site/src/app/layout.tsx
index 3fac2aaf3e..055a16cd81 100644
--- a/apps/site/src/app/layout.tsx
+++ b/apps/site/src/app/layout.tsx
@@ -8,6 +8,7 @@ import { SITE_HOME_DESCRIPTION, SITE_HOME_TITLE } from "@/lib/blog-metadata";
import { WebNavigation } from "@prisma-docs/ui/components/web-navigation";
import { Footer } from "@prisma-docs/ui/components/footer";
import { ThemeProvider } from "@prisma-docs/ui/components/theme-provider";
+import { FontAwesomeScript as WebFA } from "@prisma/eclipse";
const inter = Inter({
subsets: ["latin"],
@@ -69,9 +70,9 @@ function baseOptions() {
icon: "fa-regular fa-message-code",
},
{
- text: "Get started",
- url: "https://www.prisma.io/docs",
- icon: "fa-regular fa-book-open",
+ text: "Prisma Partners",
+ url: "/partners",
+ icon: "fa-regular fa-lightbulb",
},
{
text: "Tutorials",
@@ -108,8 +109,8 @@ function baseOptions() {
],
},
{
- url: "/partners",
- text: "Partners",
+ url: "/docs",
+ text: "Docs",
},
{
url: "https://www.prisma.io/blog",
@@ -121,16 +122,9 @@ function baseOptions() {
export default function Layout({ children }: { children: React.ReactNode }) {
return (
-
+
-
+
diff --git a/apps/site/src/components/homepage/antigravity.tsx b/apps/site/src/components/homepage/antigravity.tsx
new file mode 100644
index 0000000000..f9dab2bdb7
--- /dev/null
+++ b/apps/site/src/components/homepage/antigravity.tsx
@@ -0,0 +1,190 @@
+"use client";
+/* eslint-disable react/no-unknown-property */
+import { Canvas, useFrame, useThree } from "@react-three/fiber";
+import { useMemo, useRef } from "react";
+import * as THREE from "three";
+
+const AntigravityInner = ({
+ count = 300,
+ magnetRadius = 10,
+ ringRadius = 10,
+ waveSpeed = 0.4,
+ waveAmplitude = 1,
+ particleSize = 2,
+ lerpSpeed = 0.1,
+ color = "#FF9FFC",
+ autoAnimate = false,
+ particleVariance = 1,
+ rotationSpeed = 0,
+ depthFactor = 1,
+ pulseSpeed = 3,
+ particleShape = "capsule",
+ fieldStrength = 10,
+}) => {
+ const meshRef = useRef(null);
+ const { viewport } = useThree();
+ const dummy = useMemo(() => new THREE.Object3D(), []);
+
+ const lastMousePos = useRef({ x: 0, y: 0 });
+ const lastMouseMoveTime = useRef(0);
+ const virtualMouse = useRef({ x: 0, y: 0 });
+
+ const particles = useMemo(() => {
+ const temp = [];
+ const width = viewport.width || 100;
+ const height = viewport.height || 100;
+
+ for (let i = 0; i < count; i++) {
+ const t = Math.random() * 100;
+ const factor = 20 + Math.random() * 100;
+ const speed = 0.01 + Math.random() / 200;
+ const xFactor = -50 + Math.random() * 100;
+ const yFactor = -50 + Math.random() * 100;
+ const zFactor = -50 + Math.random() * 100;
+
+ const x = (Math.random() - 0.5) * width;
+ const y = (Math.random() - 0.5) * height;
+ const z = (Math.random() - 0.5) * 20;
+
+ const randomRadiusOffset = (Math.random() - 0.5) * 2;
+
+ temp.push({
+ t,
+ factor,
+ speed,
+ xFactor,
+ yFactor,
+ zFactor,
+ mx: x,
+ my: y,
+ mz: z,
+ cx: x,
+ cy: y,
+ cz: z,
+ vx: 0,
+ vy: 0,
+ vz: 0,
+ randomRadiusOffset,
+ });
+ }
+ return temp;
+ }, [count, viewport.width, viewport.height]);
+
+ useFrame((state) => {
+ const mesh = meshRef.current;
+ if (!mesh) return;
+
+ const { viewport: v, pointer: m } = state;
+
+ const mouseDist = Math.sqrt(
+ Math.pow(m.x - lastMousePos.current.x, 2) +
+ Math.pow(m.y - lastMousePos.current.y, 2),
+ );
+
+ if (mouseDist > 0.001) {
+ lastMouseMoveTime.current = Date.now();
+ lastMousePos.current = { x: m.x, y: m.y };
+ }
+
+ let destX = (m.x * v.width) / 2;
+ let destY = (m.y * v.height) / 2;
+
+ if (autoAnimate && Date.now() - lastMouseMoveTime.current > 2000) {
+ const time = state.clock.getElapsedTime();
+ destX = Math.sin(time * 0.5) * (v.width / 4);
+ destY = Math.cos(time * 0.5 * 2) * (v.height / 4);
+ }
+
+ const smoothFactor = 0.05;
+ virtualMouse.current.x += (destX - virtualMouse.current.x) * smoothFactor;
+ virtualMouse.current.y += (destY - virtualMouse.current.y) * smoothFactor;
+
+ const targetX = virtualMouse.current.x;
+ const targetY = virtualMouse.current.y;
+
+ const globalRotation = state.clock.getElapsedTime() * rotationSpeed;
+
+ particles.forEach((particle, i) => {
+ let { t, speed, mx, my, mz, cz, randomRadiusOffset } = particle;
+
+ t = particle.t += speed / 2;
+
+ const projectionFactor = 1 - cz / 50;
+ const projectedTargetX = targetX * projectionFactor;
+ const projectedTargetY = targetY * projectionFactor;
+
+ const dx = mx - projectedTargetX;
+ const dy = my - projectedTargetY;
+ const dist = Math.sqrt(dx * dx + dy * dy);
+
+ let targetPos = { x: mx, y: my, z: mz * depthFactor };
+
+ if (dist < magnetRadius) {
+ const angle = Math.atan2(dy, dx) + globalRotation;
+
+ const wave = Math.sin(t * waveSpeed + angle) * (0.5 * waveAmplitude);
+ const deviation = randomRadiusOffset * (5 / (fieldStrength + 0.1));
+
+ const currentRingRadius = ringRadius + wave + deviation;
+
+ targetPos.x = projectedTargetX + currentRingRadius * Math.cos(angle);
+ targetPos.y = projectedTargetY + currentRingRadius * Math.sin(angle);
+ targetPos.z =
+ mz * depthFactor + Math.sin(t) * (1 * waveAmplitude * depthFactor);
+ }
+
+ particle.cx += (targetPos.x - particle.cx) * lerpSpeed;
+ particle.cy += (targetPos.y - particle.cy) * lerpSpeed;
+ particle.cz += (targetPos.z - particle.cz) * lerpSpeed;
+
+ dummy.position.set(particle.cx, particle.cy, particle.cz);
+
+ dummy.lookAt(projectedTargetX, projectedTargetY, particle.cz);
+ dummy.rotateX(Math.PI / 2);
+
+ const currentDistToMouse = Math.sqrt(
+ Math.pow(particle.cx - projectedTargetX, 2) +
+ Math.pow(particle.cy - projectedTargetY, 2),
+ );
+
+ const distFromRing = Math.abs(currentDistToMouse - ringRadius);
+ let scaleFactor = 1 - distFromRing / 10;
+
+ scaleFactor = Math.max(0, Math.min(1, scaleFactor));
+
+ const finalScale =
+ scaleFactor *
+ (0.8 + Math.sin(t * pulseSpeed) * 0.2 * particleVariance) *
+ particleSize;
+ dummy.scale.set(finalScale, finalScale, finalScale);
+
+ dummy.updateMatrix();
+
+ mesh.setMatrixAt(i, dummy.matrix);
+ });
+
+ mesh.instanceMatrix.needsUpdate = true;
+ });
+
+ return (
+
+ {particleShape === "capsule" && (
+
+ )}
+ {particleShape === "sphere" && }
+ {particleShape === "box" && }
+ {particleShape === "tetrahedron" && }
+
+
+ );
+};
+
+const Antigravity = (props: any) => {
+ return (
+
+
+
+ );
+};
+
+export default Antigravity;
diff --git a/apps/site/src/components/homepage/bento.tsx b/apps/site/src/components/homepage/bento.tsx
new file mode 100644
index 0000000000..cfec2277a2
--- /dev/null
+++ b/apps/site/src/components/homepage/bento.tsx
@@ -0,0 +1,262 @@
+"use client";
+
+import { useCallback, useEffect, useRef, useState } from "react";
+import Link from "next/link";
+import { Action } from "@prisma/eclipse";
+import { cn } from "@prisma-docs/ui/lib/cn";
+import { useTheme } from "@prisma-docs/ui/components/theme-provider";
+
+interface CardData {
+ id: string;
+ title: string;
+ subtitle: string;
+ image: string;
+ link: string;
+ icon: string;
+ row: "top" | "center";
+}
+
+interface BentoBox {
+ title: string;
+ subtitle: string;
+ imageUrl: string;
+ icon: string;
+ imageAlt: string | null;
+ link: string;
+}
+
+interface BentoProps {
+ bentoSection: {
+ boxes: BentoBox[];
+ };
+}
+
+const HeroContent = ({ className = "" }: { className?: string }) => (
+
+
+ Your database, right in your workflow
+
+
+);
+
+const useResponsiveLayout = () => {
+ const [isDesktop, setIsDesktop] = useState(true);
+ const handleResize = () => setIsDesktop(window.innerWidth > 1024);
+
+ useEffect(() => {
+ handleResize();
+ window.addEventListener("resize", handleResize);
+ return () => window.removeEventListener("resize", handleResize);
+ }, []);
+
+ return { isDesktop };
+};
+
+const useCardAnimation = () => {
+ const [visibleBoxes, setVisibleBoxes] = useState>(new Set());
+ const [heroVisible, setHeroVisible] = useState(false);
+
+ const startAnimations = useCallback(() => {
+ setHeroVisible(true);
+
+ const rippleOrder = [
+ { ids: ["1"] as const, delay: 100 },
+ { ids: ["2"] as const, delay: 200 },
+ { ids: ["3"] as const, delay: 300 },
+ { ids: ["4"] as const, delay: 400 },
+ { ids: ["5"] as const, delay: 500 },
+ ] as const;
+
+ rippleOrder.forEach(({ ids, delay }) => {
+ setTimeout(() => {
+ setVisibleBoxes((prev) => {
+ const next = new Set(prev);
+ ids.forEach((id) => next.add(id));
+ return next;
+ });
+ }, delay);
+ });
+ }, []);
+
+ return { visibleBoxes, heroVisible, startAnimations };
+};
+
+export const Bento = ({ bentoSection }: BentoProps) => {
+ const containerRef = useRef(null);
+ const { isDesktop } = useResponsiveLayout();
+ const { visibleBoxes, heroVisible, startAnimations } = useCardAnimation();
+
+ // Transform Sanity data to internal CardData format
+ const CARDS: CardData[] = bentoSection.boxes.map((box, index) => ({
+ id: (index + 1).toString(),
+ title: box.title,
+ subtitle: box.subtitle,
+ image: box.imageUrl,
+ icon: box.icon,
+ link: box.link,
+ row: index < 3 ? "top" : "center",
+ }));
+
+ useEffect(() => {
+ const observer = new IntersectionObserver(
+ ([entry]) => entry.isIntersecting && startAnimations(),
+ { threshold: 0.1 },
+ );
+
+ const currentRef = containerRef.current;
+ if (currentRef) observer.observe(currentRef);
+
+ return () => {
+ if (currentRef) observer.unobserve(currentRef);
+ observer.disconnect();
+ };
+ }, [startAnimations]);
+
+ const centerCards = CARDS.filter((card) => card.row === "center");
+ const [firstCenterCard, secondCenterCard] = centerCards;
+ return (
+
+ {/* Desktop Layout (961+): Original 3-row layout with text in middle */}
+
+ {isDesktop ? (
+ <>
+
+ {CARDS.filter((card) => card.row === "top").map((card) => (
+
+ ))}
+
+
+
+ {firstCenterCard && (
+
+ )}
+
+ {secondCenterCard && (
+
+ )}
+
+ >
+ ) : (
+
+ {CARDS.map((card) => (
+
+ ))}
+
+ )}
+
+ );
+};
+
+interface CardProps {
+ card: CardData;
+ isVisible: boolean;
+}
+
+const Card = ({ card, isVisible }: CardProps) => {
+ const cardRef = useRef(null);
+ const isCenterCard = ["4", "5"].includes(card.id);
+ const { resolvedTheme } = useTheme();
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ const handleMouseMove = useCallback(
+ (e: React.MouseEvent) => {
+ if (!cardRef.current) return;
+
+ const rect = cardRef.current.getBoundingClientRect();
+ const centerX = rect.left + rect.width / 2;
+ const centerY = rect.top + rect.height / 2;
+ const mouseX = e.clientX;
+ const mouseY = e.clientY;
+
+ const angle = Math.atan2(mouseY - centerY, mouseX - centerX);
+
+ const degrees = ((angle * 180) / Math.PI + 90 + 360) % 360;
+
+ cardRef.current.style.setProperty("--angle", `${degrees}deg`);
+ },
+ [],
+ );
+
+ const handleMouseLeave = useCallback(() => {
+ if (cardRef.current) {
+ cardRef.current.style.setProperty("--angle", "0deg");
+ }
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+ {card.title}
+
+
+ {card.subtitle}
+
+
+
+ {card.image && (
+ // eslint-disable-next-line @next/next/no-img-element
+
+ )}
+
+ );
+};
diff --git a/apps/site/src/components/homepage/card-section/card-section.tsx b/apps/site/src/components/homepage/card-section/card-section.tsx
new file mode 100644
index 0000000000..3537d0b6f8
--- /dev/null
+++ b/apps/site/src/components/homepage/card-section/card-section.tsx
@@ -0,0 +1,94 @@
+"use client";
+
+import { LogoGrid } from "./logo-grid";
+import { ReactNode, useEffect, useState } from "react";
+import { cn } from "../../../lib/cn";
+import { useTheme } from "@prisma-docs/ui/components/theme-provider";
+
+interface TwoColumnItem {
+ content: ReactNode;
+ imageUrl: string | null;
+ imageAlt: string | null;
+ mobileImageUrl: string | null;
+ mobileImageAlt: string | null;
+ logos: any[] | null;
+ useDefaultLogos: boolean;
+ visualPosition: "left" | "right";
+ visualType: "logoGrid" | "image";
+}
+
+interface CardSectionProps {
+ cardSection: TwoColumnItem[];
+}
+
+export const CardSection = ({ cardSection }: CardSectionProps) => {
+ const { resolvedTheme } = useTheme();
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ return (
+
+ {cardSection.map((item, index) => (
+
+
+
+ {item.content}
+
+
+ {item.visualType === "logoGrid" && item.useDefaultLogos && (
+
+ )}
+ {item.visualType === "image" && item.imageUrl && (
+ <>
+
+ {item.mobileImageUrl && (
+
+ )}
+ >
+ )}
+
+
+
+ ))}
+
+ );
+};
diff --git a/apps/site/src/components/homepage/card-section/default-logos.json b/apps/site/src/components/homepage/card-section/default-logos.json
new file mode 100644
index 0000000000..bca88aae4f
--- /dev/null
+++ b/apps/site/src/components/homepage/card-section/default-logos.json
@@ -0,0 +1,113 @@
+[
+ {
+ "link": "/docs/guides/cloudflare-d1",
+ "imageUrl": "/icons/technologies/cloudflare-d1.svg",
+ "alt": "Cloudflare D1"
+ },
+ {
+ "link": "/docs/orm/prisma-client/deployment/edge/deploy-to-cloudflare",
+ "imageUrl": "/icons/technologies/cloudflare-icon-only.svg",
+ "alt": "Cloudflare"
+ },
+ {
+ "link": "/docs/guides/astro",
+ "imageUrl": "/icons/technologies/astro-dark.svg",
+ "mobileImageUrl": "/icons/technologies/astro.svg",
+ "alt": "Astro"
+ },
+ {
+ "link": "/docs/guides/betterauth-nextjs",
+ "imageUrl": "/icons/technologies/betterauth.png",
+ "alt": "BetterAuth"
+ },
+ {
+ "link": "/docs/guides/bun",
+ "imageUrl": "/icons/technologies/bun.svg",
+ "alt": "Bun"
+ },
+ {
+ "link": "/docs/guides/clerk-nextjs",
+ "imageUrl": "/icons/technologies/clerk.jpeg",
+ "alt": "Clerk"
+ },
+ {
+ "link": "/docs/guides/data-dog",
+ "imageUrl": "/icons/technologies/datadog_light.svg",
+ "mobileImageUrl": "/icons/technologies/datadog.svg",
+ "alt": "Datadog"
+ },
+ {
+ "link": "/docs/guides/docker",
+ "imageUrl": "/icons/technologies/docker-blue.svg",
+ "alt": "Docker"
+ },
+ {
+ "link": "/docs/guides/deno-integration",
+ "imageUrl": "/icons/companies/deno-darkmode.svg",
+ "mobileImageUrl": "/icons/technologies/deno-deploy.svg",
+ "alt": "Deno"
+ },
+ {
+ "link": "/docs/guides/vercel-app-deployment",
+ "imageUrl": "/icons/technologies/vercel-icon-dark.svg",
+ "mobileImageUrl": "/icons/technologies/vercel.svg",
+ "alt": "Vercel"
+ },
+ {
+ "link": "/docs/guides/nextjs",
+ "imageUrl": "/icons/technologies/nextjs.svg",
+ "alt": "Next.js"
+ },
+ {
+ "link": "/docs/guides/hono",
+ "imageUrl": "/icons/technologies/hono.svg",
+ "alt": "Hono"
+ },
+ {
+ "link": "/docs/guides/github-actions",
+ "imageUrl": "/icons/technologies/github-dark.svg",
+ "mobileImageUrl": "/icons/companies/github.svg",
+ "alt": "GitHub"
+ },
+ {
+ "link": "/docs/orm/prisma-client/deployment/traditional/deploy-to-railway",
+ "imageUrl": "/icons/technologies/railway-dark.svg",
+ "mobileImageUrl": "/icons/companies/railway.svg",
+ "alt": "Railway"
+ },
+ {
+ "link": "/docs/guides/react-router-7",
+ "imageUrl": "/icons/technologies/rr7.svg",
+ "alt": "React Router"
+ },
+ {
+ "link": "/docs/guides/solid-start",
+ "imageUrl": "/icons/technologies/solid-start.svg",
+ "alt": "Solid Start"
+ },
+ {
+ "link": "/docs/guides/sveltekit",
+ "imageUrl": "/icons/technologies/svelte.svg",
+ "alt": "SvelteKit"
+ },
+ {
+ "link": "/docs/guides/tanstack-start",
+ "imageUrl": "/icons/technologies/tanstack.svg",
+ "alt": "TanStack"
+ },
+ {
+ "link": "/docs/guides/turborepo",
+ "imageUrl": "/icons/technologies/turborepo-icon-only.svg",
+ "alt": "Turborepo"
+ },
+ {
+ "link": "/docs/guides/nuxt",
+ "imageUrl": "/icons/technologies/nuxt.svg",
+ "alt": "Nuxt"
+ },
+ {
+ "link": "/docs/guides/shopify",
+ "imageUrl": "/icons/technologies/shopify.svg",
+ "alt": "Shopify"
+ }
+]
diff --git a/apps/site/src/components/homepage/card-section/logo-grid.tsx b/apps/site/src/components/homepage/card-section/logo-grid.tsx
new file mode 100644
index 0000000000..f511840b1a
--- /dev/null
+++ b/apps/site/src/components/homepage/card-section/logo-grid.tsx
@@ -0,0 +1,421 @@
+"use client";
+
+import Image from "next/image";
+import { useState, useRef, useEffect, useCallback, memo } from "react";
+import defaultLogosData from "./default-logos.json";
+import { cn } from "../../../lib/cn";
+import { useTheme } from "@prisma-docs/ui/components/theme-provider";
+
+// Inline keyframe animations
+const AnimationStyles = () => (
+
+);
+
+// Inline LogoBar component
+const LogoBar = ({
+ logos,
+ direction = "right",
+ pauseOnHover = false,
+ duplicateCount = 3,
+}: {
+ logos: Logo[];
+ direction?: "left" | "right";
+ pauseOnHover?: boolean;
+ duplicateCount?: number;
+}) => {
+ const duplicatedLogos = Array.from(
+ { length: duplicateCount },
+ () => logos,
+ ).flat();
+
+ return (
+
+
+ {duplicatedLogos.map((logo, index) => (
+
+
+
+ ))}
+
+
+ );
+};
+
+// ============================================================================
+// TYPES
+// ============================================================================
+
+interface Logo {
+ imageUrl: string;
+ mobileImageUrl?: string;
+ link: string;
+ alt: string;
+}
+
+interface LogoGridProps {
+ logos?: Logo[];
+ type?: "spotlight" | "track";
+}
+
+// ============================================================================
+// CONFIGURATION
+// ============================================================================
+
+const SPOTLIGHT_RADIUS = 200; // Distance in pixels for spotlight effect
+const SPOTLIGHT_POWER = 1.5; // Easing power for spotlight fade
+const MOBILE_BREAKPOINT = 874;
+const TABLET_BREAKPOINT = 1024;
+
+// ============================================================================
+// UTILITY HOOKS
+// ============================================================================
+
+const useResponsive = () => {
+ const [isMobile, setIsMobile] = useState(false);
+ const [isTablet, setIsTablet] = useState(false);
+
+ useEffect(() => {
+ const updateResponsive = () => {
+ const width = window.innerWidth;
+ setIsMobile(width <= MOBILE_BREAKPOINT);
+ setIsTablet(width <= TABLET_BREAKPOINT && width > MOBILE_BREAKPOINT);
+ };
+
+ updateResponsive();
+ window.addEventListener("resize", updateResponsive);
+ return () => window.removeEventListener("resize", updateResponsive);
+ }, []);
+
+ return { isMobile, isTablet };
+};
+
+// ============================================================================
+// LOGO IMAGE COMPONENT
+// ============================================================================
+
+const LogoImage = memo(({ logo, size }: { logo: Logo; size: number }) => {
+ const { resolvedTheme } = useTheme();
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ const imageUrl =
+ mounted && resolvedTheme === "light" && logo.mobileImageUrl
+ ? logo.mobileImageUrl
+ : logo.imageUrl;
+
+ const isSvg = imageUrl.endsWith(".svg");
+ const ImageComponent = isSvg ? Image : "img";
+
+ return (
+
+ );
+});
+
+LogoImage.displayName = "LogoImage";
+
+// ============================================================================
+// SPOTLIGHT MODE COMPONENT
+// ============================================================================
+
+const SpotlightMode = memo(
+ ({
+ logos,
+ isMobile,
+ isTablet,
+ }: {
+ logos: Logo[];
+ isMobile: boolean;
+ isTablet: boolean;
+ }) => {
+ const [gradientPosition, setGradientPosition] = useState({ x: 50, y: 50 });
+ const [isTransitioning, setIsTransitioning] = useState(false);
+ const [logoOpacities, setLogoOpacities] = useState([]);
+ const [isHovering, setIsHovering] = useState(false);
+
+ const wrapperRef = useRef(null);
+ const logoRefs = useRef<(HTMLAnchorElement | null)[]>([]);
+ const rafRef = useRef(undefined);
+ const timeoutRef = useRef(undefined);
+
+ // Calculate logo opacities based on mouse position
+ const calculateLogoOpacities = useCallback(
+ (mouseX: number, mouseY: number) => {
+ return logoRefs.current.map((logoRef) => {
+ if (!logoRef) return 0.2;
+
+ const logoRect = logoRef.getBoundingClientRect();
+ const dx = mouseX - (logoRect.left + logoRect.width / 2);
+ const dy = mouseY - (logoRect.top + logoRect.height / 2);
+ const distance = Math.sqrt(dx * dx + dy * dy);
+ const normalized = Math.min(distance / SPOTLIGHT_RADIUS, 1);
+ const eased = Math.pow(normalized, SPOTLIGHT_POWER);
+
+ return Math.max(0.2, 1 - eased * 0.8);
+ });
+ },
+ [],
+ );
+
+ // Initialize default logo opacities (centered)
+ useEffect(() => {
+ if (
+ !wrapperRef.current ||
+ isHovering ||
+ logoRefs.current.length === 0 ||
+ isMobile ||
+ isTablet
+ ) {
+ return;
+ }
+
+ const rect = wrapperRef.current.getBoundingClientRect();
+ setLogoOpacities(
+ calculateLogoOpacities(
+ rect.left + rect.width / 2,
+ rect.top + rect.height / 2,
+ ),
+ );
+ }, [isHovering, isMobile, isTablet, calculateLogoOpacities]);
+
+ // Mouse enter handler
+ const handleMouseEnter = useCallback(() => {
+ if (isMobile || isTablet) return;
+ setIsTransitioning(true);
+ setIsHovering(true);
+ }, [isMobile, isTablet]);
+
+ // Mouse move handler with RAF optimization
+ const handleMouseMove = useCallback(
+ (e: React.MouseEvent) => {
+ if (!wrapperRef.current || isMobile || isTablet) return;
+
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
+
+ rafRef.current = requestAnimationFrame(() => {
+ if (!wrapperRef.current) return;
+
+ const rect = wrapperRef.current.getBoundingClientRect();
+ setGradientPosition({
+ x: ((e.clientX - rect.left) / rect.width) * 100,
+ y: ((e.clientY - rect.top) / rect.height) * 100,
+ });
+ setLogoOpacities(calculateLogoOpacities(e.clientX, e.clientY));
+
+ if (isTransitioning) {
+ setTimeout(() => setIsTransitioning(false), 50);
+ }
+ });
+
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
+ },
+ [isMobile, isTablet, isTransitioning, calculateLogoOpacities],
+ );
+
+ // Mouse leave handler
+ const handleMouseLeave = useCallback(() => {
+ if (isMobile) return;
+ setIsTransitioning(true);
+ setIsHovering(false);
+ timeoutRef.current = setTimeout(() => {
+ setGradientPosition({ x: 50, y: 50 });
+ }, 100);
+ }, [isMobile]);
+
+ // Cleanup
+ useEffect(() => {
+ return () => {
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
+ };
+ }, []);
+
+ const logoSize = isMobile ? 50 : 75;
+
+ return (
+
+ {/* Gradient background - desktop/tablet only or static on mobile */}
+ {!isMobile && !isTablet && (
+
+ )}
+ {(isMobile || isTablet) && (
+
+ )}
+
+ {/* Logo grid */}
+
+ {logos.map((logo, index) => {
+ const opacity =
+ isMobile || isTablet ? 1 : (logoOpacities[index] ?? 0.2);
+ const brightness =
+ isMobile || isTablet ? 1 : 0.7 + (opacity - 0.2) * 0.375;
+ const grayscale =
+ isMobile || isTablet ? 0 : 0.3 * (1 - (opacity - 0.2) / 0.8);
+
+ // nth-child translations for mobile
+ const getMobileTransform = () => {
+ if (!isMobile) return "";
+ const pos = index + 1;
+ if (pos >= 21) return "hidden";
+ if (pos >= 1 && pos <= 6) return "-translate-x-[20px]";
+ if (pos >= 7 && pos <= 12) return "translate-x-[20px]";
+ if (pos >= 13 && pos <= 18) return "-translate-x-[20px]";
+ if (pos >= 19 && pos <= 21) return "translate-x-[190%]";
+ return "";
+ };
+
+ // nth-child margin for desktop
+ const getDesktopMargin = () => {
+ if (isMobile) return "";
+ const pos = index + 1;
+ if (pos >= 8 && pos <= 14) return "md:-ml-[20px]";
+ return "";
+ };
+
+ return (
+
{
+ logoRefs.current[index] = el;
+ }}
+ href={logo.link}
+ className={cn(
+ "w-full aspect-square rounded-xl z-[1] bg-background-default border border-white/10 flex items-center justify-center p-4 md:p-3 transition-[opacity_0.2s_ease,filter_0.2s_ease,transform_0.2s_ease,background_0.2s_ease,border-color_0.2s_ease] cursor-pointer will-change-[opacity,filter] hover:border-[#16A394] hover:-translate-y-0.5 active:translate-y-0 lg:opacity-100 lg:filter-none",
+ getMobileTransform(),
+ getDesktopMargin(),
+ index === 18 ? "md:ml-[calc(50%-1.grid-column-start:3]" : "",
+ )}
+ target="_blank"
+ rel="noopener noreferrer"
+ style={
+ isMobile || isTablet
+ ? undefined
+ : {
+ opacity,
+ filter: `grayscale(${grayscale}) brightness(${brightness})`,
+ }
+ }
+ >
+
+
+ );
+ })}
+
+
+ );
+ },
+);
+
+SpotlightMode.displayName = "SpotlightMode";
+
+// ============================================================================
+// TRACK MODE COMPONENT
+// ============================================================================
+
+const TrackMode = memo(({ logos }: { logos: Logo[] }) => {
+ // Split logos into 3 even groups
+ const logosPerBar = Math.ceil(logos.length / 3);
+ const logosBar1 = logos.slice(0, logosPerBar);
+ const logosBar2 = logos.slice(logosPerBar, logosPerBar * 2);
+ const logosBar3 = logos.slice(logosPerBar * 2);
+
+ return (
+
+ );
+});
+
+TrackMode.displayName = "TrackMode";
+
+// ============================================================================
+// MAIN COMPONENT
+// ============================================================================
+
+export const LogoGrid = ({
+ logos: propLogos,
+ type = "spotlight",
+}: LogoGridProps) => {
+ const { isMobile, isTablet } = useResponsive();
+ const logos =
+ propLogos && propLogos.length > 0 ? propLogos : defaultLogosData;
+
+ return (
+ <>
+
+ {type === "track" ? (
+
+ ) : (
+
+ )}
+ >
+ );
+};
diff --git a/apps/site/src/components/homepage/copy-btn.tsx b/apps/site/src/components/homepage/copy-btn.tsx
new file mode 100644
index 0000000000..9218f769bf
--- /dev/null
+++ b/apps/site/src/components/homepage/copy-btn.tsx
@@ -0,0 +1,44 @@
+"use client";
+import {
+ Button,
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@prisma/eclipse";
+import { useState } from "react";
+
+export const CopyCode = ({
+ children,
+ text,
+}: {
+ children: React.ReactNode;
+ text: string;
+}) => {
+ const [tooltip, setTooltip] = useState(undefined);
+ const copyText = async () => {
+ navigator.clipboard.writeText(text);
+ setTooltip("copied!");
+ setTimeout(() => {
+ setTooltip(undefined);
+ }, 2000);
+ };
+ return (
+
+
+
+ copyText()}
+ onMouseEnter={() => setTooltip("Copy")}
+ className="font-sans-display! font-normal! text-base! font-mono!"
+ >
+ {children}
+
+
+ {tooltip}
+
+
+ );
+};
diff --git a/apps/site/src/components/homepage/testimonials/MIGRATION.md b/apps/site/src/components/homepage/testimonials/MIGRATION.md
new file mode 100644
index 0000000000..c4c70fb4b4
--- /dev/null
+++ b/apps/site/src/components/homepage/testimonials/MIGRATION.md
@@ -0,0 +1,134 @@
+# Testimonials Migration: Vanilla Extract → Tailwind CSS
+
+## Summary
+
+This document outlines the migration of the testimonials component from Vanilla Extract CSS to Tailwind CSS.
+
+## Files Changed
+
+1. **tailwind.config.ts** - Added animation keyframes and utilities
+2. **index.tsx** - Converted component to use Tailwind classes
+3. **testimonial-item.tsx** - Converted component to use Tailwind classes
+4. **index.css.ts** - ❌ Can be deleted (no longer needed)
+
+## Key Changes
+
+### 1. Tailwind Config Updates
+
+Added custom animations:
+- `slideDown` / `slideDown2` - For downward scrolling testimonials
+- `slideUp` / `slideUp2` - For upward scrolling testimonials
+- `fadein` - Fade-in animation
+
+Added custom utilities:
+- `.paused` - For pausing animations on hover
+- `.running` - For running animations
+
+### 2. Component Class Conversions
+
+#### testimonialRoot
+**Before:** Vanilla Extract style object
+**After:**
+```tsx
+cn(
+ "grid max-w-full gap-[30px] relative",
+ "before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-[30%]...",
+ "after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-[30%]..."
+)
+```
+
+#### Responsive Display Classes
+- **mobile**: `grid md:hidden`
+- **tablet**: `hidden md:grid lg:hidden grid-cols-2`
+- **desktop**: `hidden lg:grid grid-cols-3`
+
+#### brandWheel
+**Before:** Complex Vanilla Extract style
+**After:** `relative flex flex-row items-center overflow-hidden w-full min-h-[680px] h-[100px] max-w-[1200px] mx-auto hover:![animation-duration:0s]`
+
+#### rollingList
+**Before:** Separate style with animation
+**After:**
+```tsx
+cn(
+ "absolute flex-shrink-0 w-full min-w-full flex flex-col justify-around mx-auto",
+ reverse ? "animate-slide-up md:hover:paused" : "animate-slide-down md:hover:paused"
+)
+```
+
+#### testimonialItemRoot
+**Before:** Vanilla Extract style object
+**After:** `text-foreground-neutral p-6 my-3 font-[family-name:var(--barlow)] font-normal text-lg bg-surface-primary border border-border-primary rounded-[10px] leading-[25.2px]`
+
+### 3. Nth-child Selectors
+
+Converted global styles to Tailwind arbitrary variants:
+
+**Before:**
+```ts
+globalStyle(`${testimonialRoot} > div:nth-child(3)`, {
+ display: 'none',
+ '@media': { '(min-width: 940px)': { display: 'flex' } }
+})
+```
+
+**After:**
+```tsx
+"[&>*:nth-child(3)]:flex [&>*]:flex-1"
+```
+
+### 4. Pseudo-elements
+
+**Before:**
+```ts
+"::before": {
+ content: " / ",
+ color: vars.colors.text.disabled,
+}
+```
+
+**After:**
+```tsx
+"before:content-['_/_'] before:text-foreground-neutral-disabled"
+```
+
+## Animation Timing
+
+- Original: 100s base, 130s for slide down
+- Kept the same durations in Tailwind config
+- Hover pause behavior maintained with `md:hover:paused` utility
+
+## Color Token Mapping
+
+| Vanilla Extract | Tailwind |
+|----------------|----------|
+| `vars.colors.text.secondary` | `text-foreground-neutral-weak` |
+| `vars.colors.text.terciary` | `text-foreground-neutral-weak` |
+| `vars.colors.text.disabled` | `text-foreground-neutral-disabled` |
+| `vars.colors.surface.primary` | `bg-surface-primary` |
+| `vars.colors.border.primary` | `border-border-primary` |
+| `vars.colors.surface.brand.darker` | `text-surface-brand-darker` |
+
+## Breaking Changes
+
+None - the component API remains the same:
+- `list` prop still accepts `TestimonialItemType[]`
+- `noShadow` prop still removes gradients
+- `mask` prop still applies mask styles
+
+## Testing Checklist
+
+- [ ] Mobile view (< 768px) - single column
+- [ ] Tablet view (768px - 940px) - two columns
+- [ ] Desktop view (> 940px) - three columns
+- [ ] Hover pause animation works on desktop
+- [ ] Gradient overlays appear/disappear with `noShadow` prop
+- [ ] Animations scroll smoothly
+- [ ] Both regular and "startups" variant of testimonial items render correctly
+
+## Next Steps
+
+1. Delete `web/apps/site/src/components/homepage/testimonials/index.css.ts`
+2. Test the component thoroughly
+3. Verify no build errors
+4. Check that animations perform smoothly
\ No newline at end of file
diff --git a/apps/site/src/components/homepage/testimonials/index.tsx b/apps/site/src/components/homepage/testimonials/index.tsx
new file mode 100644
index 0000000000..7c72fb182d
--- /dev/null
+++ b/apps/site/src/components/homepage/testimonials/index.tsx
@@ -0,0 +1,128 @@
+"use client";
+
+import { cn } from "@/lib/cn";
+import { memo } from "react";
+import { TestimonialItem, TestimonialItemType } from "./testimonial-item";
+
+type TestimonialsType = {
+ list: Array;
+ noShadow?: boolean;
+ mask?: string;
+};
+
+type TestimonialColProps = {
+ list: TestimonialItemType[];
+ reverse?: boolean;
+};
+
+const MemoizedTestimonialItem = memo(TestimonialItem);
+
+const getColumnSlices = (list: TestimonialItemType[]) => {
+ const third = Math.ceil(list.length / 3);
+ return [
+ list.slice(0, third),
+ list.slice(third, third * 2),
+ list.slice(third * 2),
+ ];
+};
+
+const TestimonialCol = ({ list, reverse }: TestimonialColProps) => (
+
+
+ {list.map((testimonial: TestimonialItemType, idx) => (
+
+ ))}
+ {list.map((testimonial: TestimonialItemType, idx) => (
+
+ ))}
+
+
+ {list.map((testimonial: TestimonialItemType, idx) => (
+
+ ))}
+ {list.map((testimonial: TestimonialItemType, idx) => (
+
+ ))}
+
+
+);
+
+const getTabletSlices = (list: TestimonialItemType[]) => {
+ const half = Math.ceil(list.length / 2);
+ return [list.slice(0, half), list.slice(half)];
+};
+
+const Testimonials = ({ list, noShadow, mask }: TestimonialsType) => {
+ const [col1, col2, col3] = getColumnSlices(list);
+ const [tabletCol1, tabletCol2] = getTabletSlices(list);
+
+ const gridClasses = cn(
+ "grid max-w-full gap-4 relative",
+ !noShadow &&
+ "before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-[30%] before:pointer-events-none before:z-[1] before:bg-gradient-to-b before:from-[#0B0C17] before:to-[rgba(11,12,23,0)]",
+ !noShadow &&
+ "after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-[30%] after:pointer-events-none after:z-[1] after:bg-gradient-to-t after:from-[#1A202B] after:to-[rgba(26,32,43,0)]",
+ );
+
+ return (
+
+ {/* Mobile */}
+
+
+
+
+ {/* Tablet */}
+
*:nth-child(2)]:flex [&>*]:flex-1",
+ )}
+ >
+
+
+
+
+ {/* Desktop */}
+
*:nth-child(2)]:flex [&>*:nth-child(3)]:flex [&>*]:flex-1",
+ )}
+ >
+
+
+
+
+
+ );
+};
+
+export default Testimonials;
diff --git a/apps/site/src/components/homepage/testimonials/testimonial-item.tsx b/apps/site/src/components/homepage/testimonials/testimonial-item.tsx
new file mode 100644
index 0000000000..552fbe6ddc
--- /dev/null
+++ b/apps/site/src/components/homepage/testimonials/testimonial-item.tsx
@@ -0,0 +1,87 @@
+import { cn } from "@/lib/cn";
+import Image from "next/image";
+import parse from "html-react-parser";
+import { Avatar, Separator } from "@prisma/eclipse";
+
+export type TestimonialItemType = {
+ text: string | React.ReactNode;
+ author: string;
+ title: string;
+ company: string;
+ imageUrl?: string;
+ startups?: boolean;
+ imageAlt?: string;
+ key?: string | number;
+};
+
+export const TestimonialItem = ({
+ text,
+ author,
+ title,
+ company,
+ imageUrl,
+ imageAlt,
+ startups,
+ ...rest
+}: TestimonialItemType) => (
+
+
+ {typeof text === "string" ? parse(text) : text}
+
+
+
+
+
+ {startups ? company : author}
+
+
+
+ {startups ? author : title}
+
+
+ {startups ? (
+
+ {title}
+
+ ) : (
+ company && (
+
+ {company}
+
+ )
+ )}
+
+
+
+
+);
diff --git a/apps/site/src/data/homepage.json b/apps/site/src/data/homepage.json
new file mode 100644
index 0000000000..41221c8a44
--- /dev/null
+++ b/apps/site/src/data/homepage.json
@@ -0,0 +1,173 @@
+{
+ "title": "TRUSTED BY MORE THAN 500k MONTHLY ACTIVE DEVELOPERS GLOBALLY",
+ "testimonials": [
+ {
+ "company": "Amplication",
+ "author": "Yuval Hazaz",
+ "text": "We adopted Prisma conventions as our standard and it saves lots of time having from reinventing things ourselves.",
+ "title": "CEO",
+ "imageUrl": "/photos/people/yuval-hazaz.jpeg"
+ },
+ {
+ "author": "Matti Nannt",
+ "company": "Formbricks",
+ "title": "Co-founder",
+ "text": "Thanks to Prisma, we can seamlessly scale our applications, without concerns about data layer performance. ",
+ "imageUrl": "/photos/people/matti-nannt.jpeg"
+ },
+ {
+ "company": "Dub.co",
+ "author": "Steven Tey",
+ "title": "Founder",
+ "text": "Underrated: Prisma 🐐 Entire SaaS businesses have been built on top of the Prisma ecosystem— including OSS ones like Dub.co. Have been loving the recent performance improvements as well 🔥",
+ "imageUrl": "/photos/people/steven-tey.jpeg"
+ },
+ {
+ "author": "Niko Guerra",
+ "title": "Senior Backend Engineering Manager",
+ "company": "Lush",
+ "text": "With Prisma, we migrated a core production system from MySQL to SQL Server with zero downtime, simply by swapping a few references and updating our schema. I can't imagine building systems without it; it's instrumental to major projects at Lush. ",
+ "imageUrl": "/photos/people/niko-guerra.png"
+ },
+ {
+ "company": "Rapha",
+ "title": "Head of Mobile",
+ "author": "Tom Hutchinson",
+ "text": "Prisma helps us unify data access from multiple enterprise systems into a single API. It means we can move very quickly whilst staying flexible.",
+ "imageUrl": "/photos/people/tom.png"
+ },
+ {
+ "company": "Fluidwave",
+ "author": "Martin Adams",
+ "title": "Founder",
+ "text": "Prisma Postgres has really good DX. It's easy, simple, straightforward. I don't spend time on deployment. It just works.",
+ "imageUrl": "/photos/people/martin-adams.jpeg"
+ },
+ {
+ "company": "Grover",
+ "author": "Ricardo Almeida",
+ "title": "Software Engineer",
+ "text": "Prisma has a low learning curve. Productivity becomes higher because it gets combined with end-to-end type-safety using TypeScript.",
+ "imageUrl": "/photos/people/ricardo-almeida.jpeg"
+ },
+ {
+ "company": "Juniqe",
+ "author": "Jonathan Wilke",
+ "title": "Frontend Dev",
+ "text": "I have been using Prisma since day one, and it has become my number one choice for ORM. It's the default in @supastarter , and even though things like Drizzle might be more lightweight, the DX of Prisma is just unbeaten .",
+ "imageUrl": "/photos/people/jonathan-wilke.jpeg"
+ },
+ {
+ "company": "Backbase",
+ "author": "Nicolás Torres",
+ "title": "Fullstack Engineer",
+ "text": "It's the kind of DX that lets me get stuff done in between my daughter's naps.",
+ "imageUrl": "/photos/people/nicolas-torres.png"
+ },
+ {
+ "company": "@kinngh",
+ "author": "Harshdeep Singh Hura",
+ "title": "Shopify App Developer and Consultant",
+ "text": "Prisma Accelerate handled 670,000+ webhooks from Shopify when the orders webhook from 2022/23 was fired, which cost us about $11. Not bad for accidentally being DDoS'd to a Heroku Postgres instance with zero downtime, and all the entries made it through.",
+ "imageUrl": "/photos/people/harshdeep-singh-hura.jpeg"
+ },
+ {
+ "company": "Plunk",
+ "author": "Dries Augustyns",
+ "title": "Founder",
+ "text": "Prisma spares me the hassle of keeping my database in sync, allowing me to develop my product with complete confidence.",
+ "imageUrl": "/photos/people/dries-augustyns.jpg"
+ },
+ {
+ "company": "WeAreDevelopers",
+ "author": "Daniel Cranney",
+ "title": "Developer Advocate",
+ "text": "I like how the Prisma docs made it easy to jump straight into using it without needing to do a huge amount of reading, and I instantly felt the benefits.",
+ "imageUrl": "/photos/people/daniel-cranney.jpeg"
+ },
+ {
+ "company": "Jake Colling",
+ "author": "",
+ "title": "Experimenting with LLM powered apps",
+ "text": "Huge fan of Prisma! The Schema file is great for Cursor. You literally never have to write a CRUD operation again.",
+ "imageUrl": "/photos/people/jake-colling.jpeg"
+ },
+ {
+ "company": "Stockle App",
+ "author": "Joonatan",
+ "title": "Building",
+ "text": "I've been building the backend on @stockleapp , with Prisma since the beginning, and I've got to say, it has worked like a charm",
+ "imageUrl": "/photos/people/joonatan.jpeg"
+ },
+ {
+ "company": "OpenSeas",
+ "author": "Ian Hunter",
+ "title": "Pushing electrons",
+ "text": "I keep switching from Prisma to whatever the latest flavor is, but always end up coming back to Prisma.",
+ "imageUrl": "/photos/people/ian-hunter.jpeg"
+ },
+ {
+ "company": "Solin",
+ "author": "Blake Carroll",
+ "title": "CTO",
+ "text": "Accelerate is a perfect fit for landing pages. We take advantage of caching to speed up queries and reduce latency, making them lightning-fast. This means we have a faster landing page, leading to better conversion.",
+ "imageUrl": "/photos/people/blake-carroll.jpeg"
+ },
+ {
+ "company": "Inbox Zero",
+ "author": "Elie Steinbock",
+ "title": "Founder",
+ "text": "I love how Prisma makes my life as a developer so easy. The TypeScript autocompletion is the best I've used, having tried many different ORMs. The migrations are a breeze. And I love how easy it is to get a full view of your database from the Prisma schema file. It's all in one place in readable format.",
+ "imageUrl": "/photos/people/elie-steinbock.png"
+ },
+ {
+ "company": "Stack Auth",
+ "author": "Zai Shi",
+ "title": "Co-founder",
+ "text": "I love the Prisma typing system! Stack Auth relies heavily on it.",
+ "imageUrl": "/photos/people/zai-shi.jpeg"
+ },
+ {
+ "company": "i18nlocale",
+ "author": "Cody Bontecou",
+ "title": "Founder",
+ "text": "Prisma enabled me to easily manage authentication as well as users' paid status. Prisma Accelerate was a huge boost to my productivity, cutting latency issues I was encountering with Vercel SQL.",
+ "imageUrl": "/photos/people/cody-bontecou.jpg"
+ },
+ {
+ "company": "Postiz",
+ "author": "Nevo David",
+ "title": "Founder",
+ "text": "What I love most about Postiz is Prisma. It lets me switch between SQL databases effortlessly. I've used other ORMs before such as Eloquent (Laravel), but nothing matches Prisma's typing and features!",
+ "imageUrl": "/photos/people/nevo-david.jpg"
+ },
+ {
+ "company": "Meister",
+ "author": "Harshal Patil",
+ "title": "Staff Engineer",
+ "text": "Prisma's typesafe SQL is a great feature. It fills a great abstraction gap that existed prior to this. Earlier, I would have to fall back straight to pgtyped.",
+ "imageUrl": "/photos/people/harshal-patil.png"
+ },
+ {
+ "company": "ChrisCourses",
+ "author": "Chris Lis",
+ "title": "Dev Educator",
+ "text": "Imagine never typing out a migration again. Yeah, that's basically what Prisma does for you. Has saved me literal hours of time, and can for you too.",
+ "imageUrl": "/photos/people/chris-lis.jpg"
+ },
+ {
+ "company": "ReUI",
+ "author": "Shuhrat Saipov",
+ "title": "Co-founder",
+ "text": "Prisma has been instrumental in building ReUI, by providing a fully abstracted database layer. It accelerated our development speed several times over, letting us focus on business logic with a beautiful API and top-notch transaction support.",
+ "imageUrl": "/photos/people/shuhrat-saipov.jpg"
+ },
+ {
+ "company": "myBeat",
+ "author": "Jim Hendriks",
+ "title": "Tech Lead",
+ "text": "For myBeat, we migrated our legacy codebase to Prisma very easily using Prisma ORM's introspection feature as we were moving from CakePHP to Node.js.",
+ "imageUrl": "/photos/people/jim-hendriks.webp"
+ }
+ ]
+}
diff --git a/apps/site/src/lib/cn.ts b/apps/site/src/lib/cn.ts
new file mode 100644
index 0000000000..8e473dac8a
--- /dev/null
+++ b/apps/site/src/lib/cn.ts
@@ -0,0 +1 @@
+export { twMerge as cn } from "tailwind-merge";
diff --git a/apps/site/tailwind.config.ts b/apps/site/tailwind.config.ts
new file mode 100644
index 0000000000..4db90ac23f
--- /dev/null
+++ b/apps/site/tailwind.config.ts
@@ -0,0 +1,82 @@
+import type { Config } from "tailwindcss";
+
+const config: Config = {
+ content: [
+ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
+ "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
+ "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
+ ],
+ theme: {
+ extend: {
+ fontVariationSettings: {
+ normal: "'wght' 400",
+ medium: "'wght' 500",
+ semibold: "'wght' 600",
+ bold: "'wght' 700",
+ extrabold: "'wght' 800",
+ black: "'wght' 900",
+ wide: "'wdth' 125",
+ narrow: "'wdth' 75",
+ "bold-wide": "'wght' 700, 'wdth' 125",
+ "black-wide": "'wght' 900, 'wdth' 125",
+ },
+ keyframes: {
+ slideDown: {
+ from: { transform: "translateY(0%)" },
+ to: { transform: "translateY(100%)" },
+ },
+ slideDown2: {
+ from: { transform: "translateY(-100%)" },
+ to: { transform: "translateY(0%)" },
+ },
+ slideUp: {
+ from: { transform: "translateY(0%)" },
+ to: { transform: "translateY(-100%)" },
+ },
+ slideUp2: {
+ from: { transform: "translateY(100%)" },
+ to: { transform: "translateY(0%)" },
+ },
+ fadein: {
+ "0%": { opacity: "0" },
+ "100%": { opacity: "1" },
+ },
+ },
+ animation: {
+ "slide-down": "slideDown 130s linear infinite",
+ "slide-down-2": "slideDown2 130s linear infinite",
+ "slide-up": "slideUp 100s linear infinite",
+ "slide-up-2": "slideUp2 100s linear infinite",
+ "fade-in":
+ "fadein 0.5s cubic-bezier(0.455, 0.03, 0.515, 0.955) forwards",
+ },
+ },
+ },
+ plugins: [
+ function ({ addUtilities, theme }: any) {
+ const fontVariationSettings = theme("fontVariationSettings");
+ const utilities = Object.entries(fontVariationSettings).reduce(
+ (acc, [key, value]) => ({
+ ...acc,
+ [`.font-variation-${key}`]: {
+ "font-variation-settings": value,
+ },
+ }),
+ {},
+ );
+ addUtilities(utilities);
+
+ // Add animation-play-state utilities
+ addUtilities({
+ ".paused": {
+ "animation-play-state": "paused",
+ },
+ ".running": {
+ "animation-play-state": "running",
+ },
+ });
+ },
+ ],
+};
+
+export default config;
diff --git a/packages/eclipse/src/components/button.tsx b/packages/eclipse/src/components/button.tsx
index 061f56253c..256477d76d 100644
--- a/packages/eclipse/src/components/button.tsx
+++ b/packages/eclipse/src/components/button.tsx
@@ -5,29 +5,36 @@ import { cn } from "../lib/cn";
const buttonVariants = cva(
"flex flex-row justify-center items-center rounded-square transition-all duration-50 cursor-pointer disabled:bg-background-neutral-weak! disabled:border-none! disabled:text-foreground-neutral-weaker! disabled:cursor-not-allowed disabled:shadow-none",
{
- variants: {
- variant: {
- ppg: "bg-background-ppg-reverse text-foreground-ppg-reverse hover:bg-background-ppg-reverse-strong shadow-box-low",
- orm: "bg-background-orm-reverse text-foreground-orm-reverse hover:bg-background-orm-reverse-strong shadow-box-low",
- "default-stronger": "bg-background-neutral text-foreground-neutral hover:bg-background-neutral-strong",
- default: "bg-background-default hover:bg-background-neutral border border-stroke-neutral hover:border-stroke-neutral-strong text-foreground-neutral shadow-box-low",
- "default-weaker": "bg-transparent hover:bg-background-neutral text-foreground-neutral",
- error: "bg-background-error-reverse text-foreground-error-reverse hover:bg-background-error-reverse-strong shadow-box-low",
- success: "bg-background-success-reverse text-foreground-success-reverse hover:bg-background-success-reverse-strong shadow-box-low",
- link: "text-foreground-neutral underline-offset-4 hover:underline focus-visible:ring-foreground-neutral",
+ variants: {
+ variant: {
+ ppg: "bg-background-ppg-reverse text-foreground-ppg-reverse hover:bg-background-ppg-reverse-strong shadow-box-low",
+ orm: "bg-background-orm-reverse text-foreground-orm-reverse hover:bg-background-orm-reverse-strong shadow-box-low",
+ "default-stronger":
+ "bg-background-neutral text-foreground-neutral hover:bg-background-neutral-strong border border-stroke-neutral-strong",
+ default:
+ "bg-background-default hover:bg-background-neutral border border-stroke-neutral hover:border-stroke-neutral-strong text-foreground-neutral shadow-box-low",
+ "default-weaker":
+ "bg-transparent hover:bg-background-neutral text-foreground-neutral",
+ error:
+ "bg-background-error-reverse text-foreground-error-reverse hover:bg-background-error-reverse-strong shadow-box-low",
+ success:
+ "bg-background-success-reverse text-foreground-success-reverse hover:bg-background-success-reverse-strong shadow-box-low",
+ link: "text-foreground-neutral underline-offset-4 hover:underline focus-visible:ring-foreground-neutral",
+ },
+ size: {
+ lg: "px-2 h-element-lg type-text-sm-strong",
+ xl: "px-3 h-element-xl type-text-sm-strong",
+ "2xl": "px-3 h-element-2xl type-text-sm-strong",
+ "3xl": "px-4 h-element-3xl type-text-sm-strong",
+ "4xl": "px-4 h-element-4xl type-heading-md",
+ },
},
- size: {
- lg: "px-2 h-element-lg type-text-sm-strong",
- xl: "px-3 h-element-xl type-text-sm-strong",
- "2xl": "px-3 h-element-2xl type-text-sm-strong",
- "4xl": "px-4 h-element-4xl type-heading-md",
+ defaultVariants: {
+ variant: "default",
+ size: "lg",
},
},
- defaultVariants: {
- variant: "default",
- size: "lg",
- },
-});
+);
type ButtonBaseProps = VariantProps;
@@ -47,27 +54,27 @@ const Button = React.forwardRef<
HTMLButtonElement | HTMLAnchorElement,
ButtonProps
>(({ className, variant, size, href, ...props }, ref) => {
- const classNames = cn(buttonVariants({ variant, size, className }));
-
- if (href) {
- return (
- }
- href={href}
- {...(props as React.AnchorHTMLAttributes)}
- />
- );
- }
+ const classNames = cn(buttonVariants({ variant, size, className }));
+ if (href) {
return (
- }
- {...(props as React.ButtonHTMLAttributes)}
+ ref={ref as React.Ref}
+ href={href}
+ {...(props as React.AnchorHTMLAttributes)}
/>
);
- });
+ }
+
+ return (
+ }
+ {...(props as React.ButtonHTMLAttributes)}
+ />
+ );
+});
Button.displayName = "Button";
diff --git a/packages/ui/src/components/logo-parade.tsx b/packages/ui/src/components/logo-parade.tsx
new file mode 100644
index 0000000000..4b0d5ce382
--- /dev/null
+++ b/packages/ui/src/components/logo-parade.tsx
@@ -0,0 +1,248 @@
+import clsx from "clsx";
+
+const LogoParadeItem = ({
+ logo,
+ clickable = true,
+ className,
+ homepage,
+ noFilter,
+ noLinks,
+}: any) => {
+ const LogoParadeWrapper = ({ href, children }: any) => {
+ const wrapperClass = clsx(
+ "inline-flex self-center p-0 animate-[fadein_0.5s_cubic-bezier(0.455,0.03,0.515,0.955)_forwards]",
+ !clickable && "cursor-default pointer-events-none",
+ );
+
+ return !Boolean(noLinks) && Boolean(href) && clickable ? (
+
+ {children}
+
+ ) : (
+ {children}
+ );
+ };
+ return (
+
+
+
+
+
+ );
+};
+
+const logoParade = [
+ {
+ name: "Gatsby",
+ imageUrl: `/icons/companies/gatsby.svg`,
+ url: "https://www.gatsbyjs.com",
+ width: 107,
+ height: 29,
+ },
+ {
+ name: "Rapha",
+ imageUrl: `/icons/companies/rapha.svg`,
+ url: "https://www.rapha.cc/",
+ width: 85,
+ height: 39,
+ },
+ {
+ name: "Poppy",
+ imageUrl: `/icons/companies/poppy.svg`,
+ url: "https://poppy.be/",
+ width: 110,
+ height: 40,
+ },
+ {
+ name: "Twiga",
+ imageUrl: `/icons/companies/twiga.svg`,
+ url: "https://twiga.com/",
+ width: 55,
+ height: 61,
+ },
+ {
+ name: "Panther",
+ imageUrl: `/icons/companies/panther.svg`,
+ url: " https://www.panther.co/",
+ width: 122,
+ height: 28,
+ },
+ {
+ name: "Grover",
+ imageUrl: `/icons/companies/grover.svg`,
+ url: "https://www.grover.com/",
+ width: 97,
+ height: 26,
+ },
+ {
+ name: "Invisible",
+ imageUrl: `/icons/companies/invisible.svg`,
+ url: "https://inv.tech/",
+ width: 182,
+ height: 36,
+ },
+ {
+ name: "Elsevier",
+ imageUrl: `/icons/companies/elsevier.svg`,
+ url: "https://www.elsevier.com/",
+ width: 177,
+ height: 48,
+ },
+ {
+ name: "Tryg",
+ imageUrl: `/icons/companies/tryg.svg`,
+ url: "https://www.tryg.com/",
+ width: 105,
+ height: 45,
+ },
+ {
+ name: "IHI",
+ imageUrl: `/icons/companies/ihi.svg`,
+ url: "https://www.ihiterrasun.com/",
+ width: 225,
+ height: 55,
+ },
+ {
+ name: "Insta",
+ imageUrl: `/icons/companies/insta.svg`,
+ url: "",
+ width: 225,
+ height: 55,
+ },
+ {
+ name: "Outrider",
+ imageUrl: `/icons/companies/outrider.svg`,
+ url: "https://outrider.org/",
+ width: 225,
+ height: 55,
+ },
+ {
+ name: "Oxio",
+ imageUrl: `/icons/companies/oxio.svg`,
+ url: "https://oxio.com/",
+ width: 225,
+ height: 55,
+ },
+ {
+ name: "Southpole",
+ imageUrl: `/icons/companies/southpole.svg`,
+ url: "https://www.southpole.com/",
+ width: 173,
+ height: 32,
+ },
+];
+
+const LogoParade = ({
+ logos,
+ noFade = false,
+ homepage = false,
+ reverseAnim = false,
+ noFilter = false,
+ noRandom = false,
+ customSpeed = undefined,
+ noLinks = true,
+ clickable = true,
+}: any) => {
+ const tmpLogos = logos ? logos : logoParade;
+ const finalLogos = noRandom
+ ? tmpLogos
+ : tmpLogos.sort(() => Math.random() - 0.5);
+
+ const animationSpeed = customSpeed || "135s";
+
+ return (
+
+ {finalLogos.length >= 6 ? (
+
+
5 && !noFade && "mx-auto",
+ )}
+ style={{
+ animationDuration: animationSpeed,
+ }}
+ >
+ {finalLogos.map((logo: any, index: number) => (
+
+ ))}
+
+
5 && !noFade && "mx-auto",
+ )}
+ style={{
+ animationDuration: animationSpeed,
+ }}
+ >
+ {finalLogos.map((logo: any, index: number) => (
+
+ ))}
+
+
+ ) : (
+
+ {finalLogos.map((logo: any, index: number) => (
+
+ ))}
+
+ )}
+
+ );
+};
+
+export default LogoParade;
diff --git a/packages/ui/src/components/navigation-menu.tsx b/packages/ui/src/components/navigation-menu.tsx
index ebee9395d6..8d02b1e2b3 100644
--- a/packages/ui/src/components/navigation-menu.tsx
+++ b/packages/ui/src/components/navigation-menu.tsx
@@ -66,9 +66,9 @@ function NavigationWrapper({
return (
-
-
+
+
+
@@ -245,8 +254,16 @@ function Socials({
className="p-0 hover:bg-revert cursor-pointer"
href="https://pris.ly/discord"
>
-
Discord
-
+
+ Discord
+
+
)}
@@ -296,7 +313,9 @@ function MenuNavigationItem({
{link.text}
- {link.external && }
+ {link.external && (
+
+ )}
{link.desc ? (
{link.desc}
diff --git a/packages/ui/src/components/theme-toggle.tsx b/packages/ui/src/components/theme-toggle.tsx
index c4896be5fd..5f08feedb9 100644
--- a/packages/ui/src/components/theme-toggle.tsx
+++ b/packages/ui/src/components/theme-toggle.tsx
@@ -10,7 +10,7 @@ const itemVariants = cva(
{
variants: {
active: {
- true: "bg-fd-accent text-fd-accent-foreground",
+ true: "bg-foreground-ppg-reverse-weak/50 text-fd-accent-foreground",
false: "text-fd-muted-foreground",
},
},
diff --git a/packages/ui/src/components/web-navigation.tsx b/packages/ui/src/components/web-navigation.tsx
index 940da72cc5..eff70f009a 100644
--- a/packages/ui/src/components/web-navigation.tsx
+++ b/packages/ui/src/components/web-navigation.tsx
@@ -113,7 +113,11 @@ export function WebNavigation({ links, utm }: WebNavigationProps) {
-
+
Get started
diff --git a/packages/ui/src/styles/globals.css b/packages/ui/src/styles/globals.css
index 8c48df7f22..fa31e08b5b 100644
--- a/packages/ui/src/styles/globals.css
+++ b/packages/ui/src/styles/globals.css
@@ -134,3 +134,48 @@
"wdth" 125;
}
+/* Logo Parade Animations */
+@keyframes slidelogo {
+ from {
+ transform: translateX(0%);
+ }
+ to {
+ transform: translateX(100%);
+ }
+}
+
+@keyframes slidelogo2 {
+ from {
+ transform: translateX(-100%);
+ }
+ to {
+ transform: translateX(0%);
+ }
+}
+
+@keyframes slidelogoreverse {
+ from {
+ transform: translateX(0%);
+ }
+ to {
+ transform: translateX(-100%);
+ }
+}
+
+@keyframes slidelogo2reverse {
+ from {
+ transform: translateX(100%);
+ }
+ to {
+ transform: translateX(0%);
+ }
+}
+
+@keyframes fadein {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f11ecc6306..b24cda31ba 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -588,9 +588,15 @@ importers:
'@prisma/eclipse':
specifier: workspace:^
version: link:../../packages/eclipse
+ '@react-three/fiber':
+ specifier: ^9.5.0
+ version: 9.5.0(@types/react@19.2.14)(immer@11.1.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(three@0.183.2)
cors:
specifier: ^2.8.6
version: 2.8.6
+ html-react-parser:
+ specifier: ^5.2.17
+ version: 5.2.17(@types/react@19.2.14)(react@19.2.4)
lucide-react:
specifier: 'catalog:'
version: 0.575.0(react@19.2.4)
@@ -615,6 +621,12 @@ importers:
remark-directive:
specifier: 'catalog:'
version: 4.0.0
+ tailwind-merge:
+ specifier: 'catalog:'
+ version: 3.5.0
+ three:
+ specifier: ^0.183.2
+ version: 0.183.2
zod:
specifier: 'catalog:'
version: 4.3.6
@@ -634,6 +646,9 @@ importers:
'@types/react-dom':
specifier: 'catalog:'
version: 19.2.3(@types/react@19.2.14)
+ '@types/three':
+ specifier: ^0.183.1
+ version: 0.183.1
babel-plugin-react-compiler:
specifier: 'catalog:'
version: 1.0.0
@@ -1166,6 +1181,9 @@ packages:
resolution: {integrity: sha512-ZaaBr0pTvNxmyUbIn+nVPXPr383VqJzfUDMWicgTjJIeo2+T2hOq2kNpgpvTIrWtZrsZnSP8oXms1+sKTjcvkw==}
engines: {node: '>=20'}
+ '@dimforge/rapier3d-compat@0.12.0':
+ resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==}
+
'@emnapi/core@1.8.1':
resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==}
@@ -2930,6 +2948,31 @@ packages:
'@radix-ui/rect@1.1.1':
resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
+ '@react-three/fiber@9.5.0':
+ resolution: {integrity: sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA==}
+ peerDependencies:
+ expo: '>=43.0'
+ expo-asset: '>=8.4'
+ expo-file-system: '>=11.0'
+ expo-gl: '>=11.0'
+ react: '>=19 <19.3'
+ react-dom: '>=19 <19.3'
+ react-native: '>=0.78'
+ three: '>=0.156'
+ peerDependenciesMeta:
+ expo:
+ optional: true
+ expo-asset:
+ optional: true
+ expo-file-system:
+ optional: true
+ expo-gl:
+ optional: true
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+
'@reduxjs/toolkit@2.11.2':
resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==}
peerDependencies:
@@ -3592,6 +3635,9 @@ packages:
peerDependencies:
react: ^18 || ^19
+ '@tweenjs/tween.js@23.1.3':
+ resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==}
+
'@tybys/wasm-util@0.10.1':
resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
@@ -3675,12 +3721,23 @@ packages:
peerDependencies:
'@types/react': ^19.2.0
+ '@types/react-reconciler@0.28.9':
+ resolution: {integrity: sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==}
+ peerDependencies:
+ '@types/react': '*'
+
'@types/react@19.2.14':
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
+ '@types/stats.js@0.17.4':
+ resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==}
+
'@types/tedious@4.0.14':
resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==}
+ '@types/three@0.183.1':
+ resolution: {integrity: sha512-f2Pu5Hrepfgavttdye3PsH5RWyY/AvdZQwIVhrc4uNtvF7nOWJacQKcoVJn0S4f0yYbmAE6AR+ve7xDcuYtMGw==}
+
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
@@ -3693,6 +3750,9 @@ packages:
'@types/use-sync-external-store@0.0.6':
resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
+ '@types/webxr@0.5.24':
+ resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==}
+
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
@@ -3741,6 +3801,9 @@ packages:
'@webassemblyjs/wast-printer@1.14.1':
resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==}
+ '@webgpu/types@0.1.69':
+ resolution: {integrity: sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==}
+
'@xtuc/ieee754@1.2.0':
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
@@ -3827,6 +3890,9 @@ packages:
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
engines: {node: 18 || 20 || >=22}
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
baseline-browser-mapping@2.10.0:
resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==}
engines: {node: '>=6.0.0'}
@@ -3851,6 +3917,9 @@ packages:
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+ buffer@6.0.3:
+ resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
+
cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
@@ -4089,10 +4158,23 @@ packages:
dexie@4.3.0:
resolution: {integrity: sha512-5EeoQpJvMKHe6zWt/FSIIuRa3CWlZeIl6zKXt+Lz7BU6RoRRLgX9dZEynRfXrkLcldKYCBiz7xekTEylnie1Ug==}
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
+ domelementtype@2.3.0:
+ resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
dompurify@3.3.2:
resolution: {integrity: sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==}
engines: {node: '>=20'}
+ domutils@3.2.2:
+ resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
+
dotenv@16.6.1:
resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
engines: {node: '>=12'}
@@ -4117,10 +4199,18 @@ packages:
resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==}
engines: {node: '>=10.13.0'}
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'}
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
env-paths@4.0.0:
resolution: {integrity: sha512-pxP8eL2SwwaTRi/KHYwLYXinDs7gL3jxFcBYmEdYfZmZXbaVDvdppd0XBU8qVz03rDfKZMXg1omHCbsJjZrMsw==}
engines: {node: '>=20'}
@@ -4258,6 +4348,9 @@ packages:
fflate@0.4.8:
resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==}
+ fflate@0.8.2:
+ resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
+
fill-range@7.1.1:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
@@ -4484,16 +4577,34 @@ packages:
hookable@6.0.1:
resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==}
+ html-dom-parser@5.1.8:
+ resolution: {integrity: sha512-MCIUng//mF2qTtGHXJWr6OLfHWmg3Pm8ezpfiltF83tizPWY17JxT4dRLE8lykJ5bChJELoY3onQKPbufJHxYA==}
+
+ html-react-parser@5.2.17:
+ resolution: {integrity: sha512-m+K/7Moq1jodAB4VL0RXSOmtwLUYoAsikZhwd+hGQe5Vtw2dbWfpFd60poxojMU0Tsh9w59mN1QLEcoHz0Dx9w==}
+ peerDependencies:
+ '@types/react': 0.14 || 15 || 16 || 17 || 18 || 19
+ react: 0.14 || 15 || 16 || 17 || 18 || 19
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
html-url-attributes@3.0.1:
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
html-void-elements@3.0.0:
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+ htmlparser2@10.1.0:
+ resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==}
+
https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
+ ieee754@1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+
image-size@2.0.2:
resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==}
engines: {node: '>=16.x'}
@@ -4572,6 +4683,11 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ its-fine@2.0.0:
+ resolution: {integrity: sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==}
+ peerDependencies:
+ react: ^19.0.0
+
jest-worker@27.5.1:
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
engines: {node: '>= 10.13.0'}
@@ -4822,6 +4938,9 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
+ meshoptimizer@1.0.1:
+ resolution: {integrity: sha512-Vix+QlA1YYT3FwmBBZ+49cE5y/b+pRrcXKqGpS5ouh33d3lSp2PoTpCw19E0cKDFWalembrHnIaZetf27a+W2g==}
+
micromark-core-commonmark@2.0.3:
resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
@@ -5241,6 +5360,9 @@ packages:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-property@2.0.2:
+ resolution: {integrity: sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==}
+
react-redux@9.2.0:
resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==}
peerDependencies:
@@ -5289,6 +5411,15 @@ packages:
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
+ react-use-measure@2.1.7:
+ resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==}
+ peerDependencies:
+ react: '>=16.13'
+ react-dom: '>=16.13'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+
react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
@@ -5553,6 +5684,11 @@ packages:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
engines: {node: '>=10'}
+ suspend-react@0.1.3:
+ resolution: {integrity: sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==}
+ peerDependencies:
+ react: '>=17.0'
+
swr@2.4.1:
resolution: {integrity: sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA==}
peerDependencies:
@@ -5592,6 +5728,9 @@ packages:
engines: {node: '>=10'}
hasBin: true
+ three@0.183.2:
+ resolution: {integrity: sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==}
+
tiny-invariant@1.3.3:
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
@@ -5891,6 +6030,24 @@ packages:
zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
+ zustand@5.0.12:
+ resolution: {integrity: sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==}
+ engines: {node: '>=12.20.0'}
+ peerDependencies:
+ '@types/react': '>=18.0.0'
+ immer: '>=9.0.6'
+ react: '>=18.0.0'
+ use-sync-external-store: '>=1.2.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ immer:
+ optional: true
+ react:
+ optional: true
+ use-sync-external-store:
+ optional: true
+
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@@ -6311,6 +6468,8 @@ snapshots:
'@cspell/url@9.7.0': {}
+ '@dimforge/rapier3d-compat@0.12.0': {}
+
'@emnapi/core@1.8.1':
dependencies:
'@emnapi/wasi-threads': 1.1.0
@@ -7799,6 +7958,26 @@ snapshots:
'@radix-ui/rect@1.1.1': {}
+ '@react-three/fiber@9.5.0(@types/react@19.2.14)(immer@11.1.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(three@0.183.2)':
+ dependencies:
+ '@babel/runtime': 7.28.6
+ '@types/webxr': 0.5.24
+ base64-js: 1.5.1
+ buffer: 6.0.3
+ its-fine: 2.0.0(@types/react@19.2.14)(react@19.2.4)
+ react: 19.2.4
+ react-use-measure: 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ scheduler: 0.27.0
+ suspend-react: 0.1.3(react@19.2.4)
+ three: 0.183.2
+ use-sync-external-store: 1.6.0(react@19.2.4)
+ zustand: 5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
+ optionalDependencies:
+ react-dom: 19.2.4(react@19.2.4)
+ transitivePeerDependencies:
+ - '@types/react'
+ - immer
+
'@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1))(react@19.2.4)':
dependencies:
'@standard-schema/spec': 1.1.0
@@ -8362,6 +8541,8 @@ snapshots:
'@tanstack/query-core': 5.90.20
react: 19.2.4
+ '@tweenjs/tween.js@23.1.3': {}
+
'@tybys/wasm-util@0.10.1':
dependencies:
tslib: 2.8.1
@@ -8453,14 +8634,30 @@ snapshots:
dependencies:
'@types/react': 19.2.14
+ '@types/react-reconciler@0.28.9(@types/react@19.2.14)':
+ dependencies:
+ '@types/react': 19.2.14
+
'@types/react@19.2.14':
dependencies:
csstype: 3.2.3
+ '@types/stats.js@0.17.4': {}
+
'@types/tedious@4.0.14':
dependencies:
'@types/node': 25.3.5
+ '@types/three@0.183.1':
+ dependencies:
+ '@dimforge/rapier3d-compat': 0.12.0
+ '@tweenjs/tween.js': 23.1.3
+ '@types/stats.js': 0.17.4
+ '@types/webxr': 0.5.24
+ '@webgpu/types': 0.1.69
+ fflate: 0.8.2
+ meshoptimizer: 1.0.1
+
'@types/trusted-types@2.0.7':
optional: true
@@ -8470,6 +8667,8 @@ snapshots:
'@types/use-sync-external-store@0.0.6': {}
+ '@types/webxr@0.5.24': {}
+
'@ungap/structured-clone@1.3.0': {}
'@webassemblyjs/ast@1.14.1':
@@ -8548,6 +8747,8 @@ snapshots:
'@webassemblyjs/ast': 1.14.1
'@xtuc/long': 4.2.2
+ '@webgpu/types@0.1.69': {}
+
'@xtuc/ieee754@1.2.0': {}
'@xtuc/long@4.2.2': {}
@@ -8620,6 +8821,8 @@ snapshots:
balanced-match@4.0.4: {}
+ base64-js@1.5.1: {}
+
baseline-browser-mapping@2.10.0: {}
birpc@4.0.0: {}
@@ -8642,6 +8845,11 @@ snapshots:
buffer-from@1.1.2: {}
+ buffer@6.0.3:
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+
cac@6.7.14: {}
callsites@3.1.0: {}
@@ -8887,10 +9095,28 @@ snapshots:
dexie@4.3.0: {}
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
+ domelementtype@2.3.0: {}
+
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
dompurify@3.3.2:
optionalDependencies:
'@types/trusted-types': 2.0.7
+ domutils@3.2.2:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
dotenv@16.6.1: {}
dts-resolver@2.1.3(oxc-resolver@11.19.1):
@@ -8906,8 +9132,12 @@ snapshots:
graceful-fs: 4.2.11
tapable: 2.3.0
+ entities@4.5.0: {}
+
entities@6.0.1: {}
+ entities@7.0.1: {}
+
env-paths@4.0.0:
dependencies:
is-safe-filename: 0.1.1
@@ -9068,6 +9298,8 @@ snapshots:
fflate@0.4.8: {}
+ fflate@0.8.2: {}
+
fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
@@ -9361,10 +9593,32 @@ snapshots:
hookable@6.0.1: {}
+ html-dom-parser@5.1.8:
+ dependencies:
+ domhandler: 5.0.3
+ htmlparser2: 10.1.0
+
+ html-react-parser@5.2.17(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ domhandler: 5.0.3
+ html-dom-parser: 5.1.8
+ react: 19.2.4
+ react-property: 2.0.2
+ style-to-js: 1.1.21
+ optionalDependencies:
+ '@types/react': 19.2.14
+
html-url-attributes@3.0.1: {}
html-void-elements@3.0.0: {}
+ htmlparser2@10.1.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ entities: 7.0.1
+
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
@@ -9372,6 +9626,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ ieee754@1.2.1: {}
+
image-size@2.0.2: {}
immer@10.2.0: {}
@@ -9431,6 +9687,13 @@ snapshots:
isexe@2.0.0: {}
+ its-fine@2.0.0(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ '@types/react-reconciler': 0.28.9(@types/react@19.2.14)
+ react: 19.2.4
+ transitivePeerDependencies:
+ - '@types/react'
+
jest-worker@27.5.1:
dependencies:
'@types/node': 25.3.5
@@ -9743,6 +10006,8 @@ snapshots:
merge2@1.4.1: {}
+ meshoptimizer@1.0.1: {}
+
micromark-core-commonmark@2.0.3:
dependencies:
decode-named-character-reference: 1.3.0
@@ -10395,6 +10660,8 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
+ react-property@2.0.2: {}
+
react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1):
dependencies:
'@types/use-sync-external-store': 0.0.6
@@ -10439,6 +10706,12 @@ snapshots:
react-dom: 19.2.4(react@19.2.4)
swr: 2.4.1(react@19.2.4)
+ react-use-measure@2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+ optionalDependencies:
+ react-dom: 19.2.4(react@19.2.4)
+
react@19.2.4: {}
readdirp@5.0.0: {}
@@ -10853,6 +11126,10 @@ snapshots:
dependencies:
has-flag: 4.0.0
+ suspend-react@0.1.3(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+
swr@2.4.1(react@19.2.4):
dependencies:
dequal: 2.0.3
@@ -10882,6 +11159,8 @@ snapshots:
commander: 2.20.3
source-map-support: 0.5.21
+ three@0.183.2: {}
+
tiny-invariant@1.3.3: {}
tinyexec@1.0.2: {}
@@ -11187,4 +11466,11 @@ snapshots:
zod@4.3.6: {}
+ zustand@5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)):
+ optionalDependencies:
+ '@types/react': 19.2.14
+ immer: 11.1.4
+ react: 19.2.4
+ use-sync-external-store: 1.6.0(react@19.2.4)
+
zwitch@2.0.4: {}