diff --git a/website/public/llms-full.txt b/website/public/llms-full.txt index 326df2442c..7a570e3bc4 100644 --- a/website/public/llms-full.txt +++ b/website/public/llms-full.txt @@ -3682,11 +3682,6 @@ The `setupTest` function automatically calls `vi.useFakeTimers()`, allowing you 4. **Use realistic data**: Test with data that resembles production scenarios. Rivet's testing framework automatically handles server setup and teardown, so you can focus on writing effective tests for your business logic. -## API Reference - -# API Reference - -This is where the technical API docs live. ## Node.js & Bun # Node.js & Bun @@ -6165,6 +6160,8 @@ docker run -d \ Rivet consists of several core components that work together to provide a complete actor orchestration platform. The Rivet Engine is the core of self-hosting and is used for orchestrating actors at scale: + Self-hosting is not required to deploy Rivet applciations in your own cloud. Please see the [deploy documentation](/docs/deploy) if trying to deploy a Rivet application. + ## Core Components - **Your Backend** - Your application server that handles user requests and includes a runner component that executes actor code diff --git a/website/public/llms.txt b/website/public/llms.txt index 213416054c..64d0f30c89 100644 --- a/website/public/llms.txt +++ b/website/public/llms.txt @@ -86,7 +86,6 @@ https://rivet.dev/docs/actors/schedule https://rivet.dev/docs/actors/sharing-and-joining-state https://rivet.dev/docs/actors/state https://rivet.dev/docs/actors/testing -https://rivet.dev/docs/api https://rivet.dev/docs/clients/javascript https://rivet.dev/docs/clients/next-js https://rivet.dev/docs/clients/openapi diff --git a/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/database-sharp-regular-full.svg b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/database-sharp-regular-full.svg new file mode 100644 index 0000000000..af98bd5a33 --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/database-sharp-regular-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/diagram-next-sharp-regular-full.svg b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/diagram-next-sharp-regular-full.svg new file mode 100644 index 0000000000..b9f25f7b42 --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/diagram-next-sharp-regular-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/file-pen-sharp-regular-full.svg b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/file-pen-sharp-regular-full.svg new file mode 100644 index 0000000000..37bb0b4978 --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/file-pen-sharp-regular-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/gears-sharp-light-full.svg b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/gears-sharp-light-full.svg new file mode 100644 index 0000000000..6a74040060 --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/gears-sharp-light-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/globe-sharp-regular-full.svg b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/globe-sharp-regular-full.svg new file mode 100644 index 0000000000..66fabfa19b --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/globe-sharp-regular-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/rotate-sharp-regular-full.svg b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/rotate-sharp-regular-full.svg new file mode 100644 index 0000000000..e2897e066e --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/rotate-sharp-regular-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/sparkles-sharp-regular-full.svg b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/sparkles-sharp-regular-full.svg new file mode 100644 index 0000000000..8cad7b9ad2 --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/images/raw-icon-svgs/sparkles-sharp-regular-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/(v2)/(marketing)/(index)/page.tsx b/website/src/app/(v2)/(marketing)/(index)/page.tsx index fdc8eb5a87..3419b1d7a6 100644 --- a/website/src/app/(v2)/(marketing)/(index)/page.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/page.tsx @@ -1,12 +1,14 @@ import { HeroBackground } from "./components/HeroBackground"; import { HeroSection } from "./sections/HeroSection"; +import { UseCases } from "./sections/UseCases"; +import { PlatformSection } from "./sections/PlatformSection"; import { CodeSnippetsSection } from "./sections/CodeSnippetsSection"; import { FeaturesSection } from "./sections/FeaturesSection"; import { TechSection } from "./sections/TechSection"; +import { DeploymentOptionsSection } from "./sections/DeploymentOptionsSection"; import { StudioSection } from "./sections/StudioSection"; import { CommunitySection } from "./sections/CommunitySection"; import { CTASection } from "./sections/CTASection"; -import { PlatformIcons } from "./components/PlatformIcons"; export default function IndexPage() { return ( @@ -19,18 +21,30 @@ export default function IndexPage() {
-
- +
+ +
+ +
+
- +
+ {/*
+ +
*/} +
+
+ +
+
diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx index 9336fd25ed..7b14c3352d 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx @@ -3,14 +3,14 @@ import CodeSnippets from "../components/code-snippets"; export function CodeSnippetsSection() { return (
- {/*
+

- Reconsider What Your Backend Can Do + See It In Action

- Build powerful applications with Rivet Actors + Real-world examples showing how Rivet Actors simplify complex backends

-
*/} +
diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/DeploymentOptionsSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/DeploymentOptionsSection.tsx new file mode 100644 index 0000000000..be72ca6e6f --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/sections/DeploymentOptionsSection.tsx @@ -0,0 +1,91 @@ +import Link from "next/link"; +import { CopyCommand } from "../components/CopyCommand"; + +interface DeploymentOptionProps { + title: string; + description: string; + children?: React.ReactNode; +} + +function DeploymentOption({ title, description, children }: DeploymentOptionProps) { + return ( +
+

{title}

+

{description}

+ {children} +
+ ); +} + +export function DeploymentOptionsSection() { + return ( +
+
+
+

+ Run It Your Way +

+

+ Deploy Rivet however works best for your team, from local development to production at scale. +

+
+ +
+ + + +
+ + Sign In with Rivet + + + + View Pricing + + +
+
+ + +
+ + View Self-Hosting Docs + + +
+ +
+
+
+
+ +
+

Hybrid Deployment

+

+ Run in Rivet Cloud for production, use self-hosting for on-premises deployments +

+
+
+
+ ); +} diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx index a074198dfa..d783e3de4c 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx @@ -1,4 +1,3 @@ -import { PlatformIcons } from "../components/PlatformIcons"; import { MarketingButton } from "../components/MarketingButton"; import { CopyCommand } from "../components/CopyCommand"; import Link from "next/link"; @@ -7,7 +6,7 @@ import { WithTooltip } from "@rivet-gg/components"; export function HeroSection() { return (
-
+
{/* Main content centered vertically */} @@ -17,11 +16,39 @@ export function HeroSection() {

{/*Lightweight library for building modern backends*/} {/*Library for building stateful applications and distributed systems*/} - Build and scale stateful workloads + {/*Build and scale stateful workloads*/} + State + Compute = Less Complexity

+

+ Rivet Actors merge state and compute in to a primitive that scales effortlessly with less complex infrastructure. + Easily self-hostable and works with your infrastructure. +

+ + {/*

+ Rivet Actors are lightweight processes that unite state and compute.
Scales effortlessly with less complex infrastructure.
+ Easily{" "} + self-hostable{" "} + and works with{" "} + + your infrastructure + + . +

*/} + + {/*

+ Rivet Actors are lightweight processes that merge state and compute{" "}
in to a primitive that scales effortlessly with less complex infrastructure.
+ Easily{" "} + self-hostable{" "} + and works with{" "} + + your infrastructure + + . +

*/} + {/*

Rivet is a library for{" "} long-lived processes{" "} with{" "} @@ -40,7 +67,7 @@ export function HeroSection() {

*/} -

+ {/*

Rivet is an open-source library for{" "} long-lived processes.
@@ -56,7 +83,7 @@ export function HeroSection() { your infrastructure . -

+

*/}
@@ -88,10 +115,6 @@ export function HeroSection() {
-
- - -
diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/IconWithSpotlight.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/IconWithSpotlight.tsx index 6ebc51b11a..9e9145120f 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/IconWithSpotlight.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/IconWithSpotlight.tsx @@ -12,6 +12,21 @@ export function IconWithSpotlight({ iconPath, title }: IconWithSpotlightProps) { return "M144 270L144 341.4L237.8 400L402.3 400L496.1 341.4L496.1 270L416.1 320L224.1 320L144.1 270zM96 240L96 144L224 64L416 64L544 144L544 496L416 576L224 576L96 496L96 240zM496 192L496 170.6L402.2 112L237.7 112L143.9 170.6L143.9 213.4L237.7 272L402.2 272L496 213.4L496 192zM144 469.4L237.8 528L402.3 528L496.1 469.4L496.1 398L416.1 448L224.1 448L144.1 398L144.1 469.4z"; case "/icons/bolt.svg": return "M414.7 48L407.8 54.6L103.8 342.6L60.1 384L247.5 384L193.4 561L183.9 592L225.9 592L232.8 585.4L536.8 297.4L580.5 256L393.1 256L447.2 79L456.7 48L414.7 48zM180.5 336L374.7 152C345.5 247.7 330 298.3 328.3 304L460 304L265.8 488C295 392.4 310.5 341.7 312.2 336L180.4 336z"; + // Use case icons + case "/use-case-icons/sparkles.svg": + return "M480 96L408 128L480 160L512 232L544 160L616 128L544 96L512 24L480 96zM288 384C348.9 356.9 396.9 335.6 432 320C396.9 304.4 348.9 283.1 288 256C260.9 195.1 239.6 147.1 224 112C208.4 147.1 187.1 195.1 160 256C99.1 283.1 51.1 304.4 16 320C51.1 335.6 99.1 356.9 160 384C187.1 444.9 208.4 492.9 224 528C239.6 492.9 260.9 444.9 288 384zM224 409.8C208.5 374.9 199.3 354.1 196.4 347.6C189.9 344.7 169.2 335.5 134.2 320C169.1 304.5 189.9 295.3 196.4 292.4C199.3 285.9 208.5 265.2 224 230.2C239.5 265.1 248.7 285.9 251.6 292.4C258.1 295.3 278.8 304.5 313.8 320C278.9 335.5 258.1 344.7 251.6 347.6C248.7 354.1 239.5 374.8 224 409.8zM480 408L448 480L376 512L448 544L480 616L512 544L584 512L512 480L480 408z"; + case "/use-case-icons/diagram-next.svg": + return "M496 240L144 240L144 144L496 144L496 240zM544 288L544 96L96 96L96 288L296 288L296 374.1C279.6 357.7 266.3 344.4 256 334.1L222.1 368C225.6 371.5 252.6 398.5 303.1 449L320.1 466C323.6 462.5 350.6 435.5 401.1 385L418.1 368L384.2 334.1C373.9 344.4 360.6 357.7 344.2 374.1L344.2 288L544.2 288zM184 352L96 352L96 544L544 544L544 352L456 352L456 400L496 400L496 496L144 496L144 400L184 400L184 352z"; + case "/use-case-icons/gears.svg": + return "M190.3 25.8C190.3 25.8 215.1 32.4 264.5 45.7L276.9 49C276.7 52.6 275.9 71.1 274.5 104.6C276.2 106.2 277.9 107.9 279.5 109.6C313 108.2 331.6 107.4 335.1 107.2L338.4 119.6L355 181.4L358.3 193.8C355.2 195.4 338.7 204 308.9 219.5C308.4 221.8 307.7 224.1 307.1 226.3C325.1 254.6 335.1 270.3 337 273.3L327.9 282.4L282.6 327.7L273.5 336.8C270.5 334.9 254.8 324.9 226.5 306.9C224.2 307.6 222 308.2 219.6 308.7C204.1 338.4 195.5 354.9 193.9 358.1L181.5 354.8L119.7 338.2L107.3 334.9C107.5 331.3 108.3 312.8 109.7 279.3C108 277.7 106.3 276 104.7 274.3C71.2 275.7 52.6 276.5 49.1 276.7C49.1 276.7 42.5 251.9 29.2 202.5L26 190.1L75.4 164.4C75.9 162.1 76.6 159.8 77.2 157.6C59.2 129.3 49.2 113.6 47.3 110.6L101.6 56.3L110.7 47.2C113.7 49.1 129.4 59.1 157.7 77.1C160 76.4 162.2 75.8 164.6 75.3C180.1 45.6 188.7 29.1 190.3 25.9zM206.8 63.4C192.9 90 185.9 103.5 185.7 103.8L177.8 105.1C172.1 106 166.5 107.5 161.2 109.6L153.7 112.4C153.4 112.2 140.5 104 115.2 87.9L88.1 115C104.2 140.4 112.4 153.2 112.6 153.5L109.8 161C108.8 163.7 107.9 166.4 107.2 169.2C106.5 172 105.8 174.8 105.4 177.6L104 185.5C103.7 185.7 90.2 192.7 63.5 206.6L73.4 243.6L119 241.6L124.1 247.8C127.7 252.2 131.8 256.3 136.3 260L142.5 265.1C142.5 265.5 141.8 280.7 140.5 310.7L177.5 320.6C191.4 294 198.4 280.5 198.6 280.2L206.5 278.9C212.2 278 217.8 276.5 223.1 274.4L230.6 271.6C230.9 271.8 243.8 280 269.1 296.1L296.2 269C280.1 243.7 271.9 230.8 271.7 230.5L274.5 223C275.5 220.3 276.4 217.6 277.1 214.8C277.8 212 278.5 209.2 278.9 206.4L280.2 198.5C280.5 198.3 294 191.3 320.7 177.4L310.8 140.4C280.8 141.7 265.6 142.4 265.2 142.4L260.1 136.2C256.5 131.8 252.4 127.7 247.9 124L241.7 118.9C241.7 118.5 242.4 103.3 243.7 73.3L206.7 63.4zM177.7 246.1C147.8 238.1 130.1 207.4 138.1 177.5C146.1 147.6 176.8 129.9 206.7 137.9C236.6 145.9 254.3 176.6 246.3 206.5C238.3 236.4 207.6 254.1 177.7 246.1zM215.4 198.2C218.8 185.4 211.2 172.2 198.4 168.8C185.6 165.4 172.4 173 169 185.8C165.6 198.6 173.2 211.8 186 215.2C198.8 218.6 212 211 215.4 198.2zM363.4 305.1L375.8 301.8L437.6 285.2L450 281.9C451.6 285.1 460.2 301.5 475.7 331.3C478 331.9 480.3 332.5 482.6 333.1C510.9 315.1 526.6 305.1 529.6 303.2L538.7 312.3L584 357.6L593.1 366.7C591.2 369.7 581.2 385.4 563.2 413.7C563.9 415.9 564.5 418.2 565 420.5C594.8 436 611.2 444.6 614.4 446.2L611.1 458.6L594.5 520.4L591.2 532.8C587.6 532.6 569.1 531.8 535.6 530.4C534 532.1 532.3 533.8 530.6 535.4C532 568.9 532.8 587.4 533 591L520.6 594.3L458.8 610.9L446.4 614.2C444.8 611 436.2 594.6 420.7 564.8C418.4 564.3 416.1 563.6 413.8 563C385.5 581 369.8 591 366.8 592.9L357.7 583.8L312.4 538.5L303.3 529.4C305.2 526.4 315.2 510.7 333.2 482.4C332.9 481.3 332.5 480.1 332.2 479C331.9 477.9 331.6 476.7 331.3 475.6C301.5 460.1 285.1 451.5 281.9 449.9L285.2 437.5L301.8 375.7L305.1 363.3C308.7 363.5 327.2 364.3 360.7 365.7C362.3 364 364 362.3 365.7 360.7C364.3 327.2 363.5 308.7 363.3 305.1zM396.5 329.4L398.1 367L398.4 375L392.2 380.1C387.7 383.8 383.7 387.9 380 392.3L374.9 398.5L366.9 398.2L329.3 396.6L319.4 433.6L352.8 451L359.9 454.7L361.2 462.6C361.7 465.4 362.3 468.2 363 471C363.7 473.8 364.6 476.6 365.6 479.2L368.4 486.7L364.1 493.4L343.9 525.2L371 552.3C396.3 536.2 409.2 528 409.5 527.8L417 530.6C422.4 532.6 427.9 534.1 433.6 535.1L441.5 536.4L445.2 543.5L462.6 576.9L499.6 567L498 529.4L497.7 521.4L503.9 516.3C508.4 512.6 512.4 508.5 516.1 504.1L521.2 497.9L529.2 498.2L566.8 499.8L576.7 462.8L543.3 445.4L536.2 441.7L534.9 433.8C534.4 431 533.8 428.2 533.1 425.4C532.4 422.6 531.5 419.8 530.5 417.2L527.7 409.7C527.9 409.4 536.1 396.5 552.2 371.2L525.1 344.1C499.8 360.2 486.9 368.4 486.6 368.6L479.1 365.8C473.7 363.8 468.2 362.3 462.5 361.3L454.6 360L450.9 352.9L433.5 319.5L396.5 329.4zM462.6 502.2C432.7 510.2 402 492.5 394 462.6C386 432.7 403.7 402 433.6 394C463.5 386 494.2 403.7 502.2 433.6C510.2 463.5 492.5 494.2 462.6 502.2zM471.3 441.9C467.9 429.1 454.7 421.5 441.9 424.9C429.1 428.3 421.5 441.5 424.9 454.3C428.3 467.1 441.5 474.7 454.3 471.3C467.1 467.9 474.7 454.7 471.3 441.9z"; + case "/use-case-icons/rotate.svg": + return "M576 107.9L576 40C542.6 73.4 513.4 102.6 488.6 127.4C388.1 39.2 234.9 43 139 139C89 189 64 254.5 64 320L112 320C112 266.7 132.3 213.5 172.9 172.9C250.1 95.7 372.9 91.9 454.6 161.4C430.4 185.6 401.6 214.4 368 248L576 248L576 107.9zM528 200L483.9 200L528 155.9L528 200zM185.4 478.6C209.6 454.4 238.4 425.6 272 392L64 392L64 600C97.4 566.6 126.6 537.4 151.4 512.6C252 600.8 405.1 596.9 501 501C551 451 576 385.5 576 320L528 320C528 373.3 507.7 426.5 467.1 467.1C389.9 544.3 267.1 548.1 185.4 478.6zM112 484.1L112 440L156.1 440L112 484.1z"; + case "/use-case-icons/database.svg": + return "M144 270L144 341.4L237.8 400L402.3 400L496.1 341.4L496.1 270L416.1 320L224.1 320L144.1 270zM96 240L96 144L224 64L416 64L544 144L544 496L416 576L224 576L96 496L96 240zM496 192L496 170.6L402.2 112L237.7 112L143.9 170.6L143.9 213.4L237.7 272L402.2 272L496 213.4L496 192zM144 469.4L237.8 528L402.3 528L496.1 469.4L496.1 398L416.1 448L224.1 448L144.1 398L144.1 469.4z"; + case "/use-case-icons/globe.svg": + return "M192.8 344C197.4 410.4 220.3 472 247.7 515.1C175.6 488.4 122.4 422.9 113.3 344L192.8 344zM240.9 344L399 344C395.1 393.3 379.5 439.8 360.1 475.1C348.9 495.6 337.2 510.7 327.4 520C324.2 523 321.7 525 319.9 526.2C318.1 524.9 315.6 523 312.4 520C302.6 510.7 291 495.6 279.7 475.1C260.3 439.8 244.8 393.3 240.8 344zM399 296L241 296C244.9 246.7 260.5 200.2 279.9 164.9C291.1 144.4 302.8 129.3 312.6 120C315.8 117 318.3 115 320.1 113.8C321.9 115.1 324.4 117 327.6 120C337.4 129.3 349 144.4 360.3 164.9C379.7 200.2 395.2 246.7 399.2 296zM447.1 344L526.6 344C517.5 422.9 464.3 488.4 392.2 515.1C419.5 472 442.5 410.4 447.1 344zM526.6 296L447.1 296C442.5 229.6 419.6 168 392.2 124.9C464.3 151.6 517.5 217.1 526.6 296zM192.8 296L113.3 296C122.4 217.1 175.6 151.6 247.7 124.9C220.4 168 197.4 229.6 192.8 296zM320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576z"; + case "/use-case-icons/file-pen.svg": + return "M240 112L112 112L112 528L284.2 528L276.2 576L64 576L64 64L288 64L448 224L448 331.7L400 379.7L400 272L240 272L240 112zM380.1 224L288 131.9L288 224L380.1 224zM544 303.9L624 383.9L571.2 436.7L491.2 356.7L544 303.9zM336 511.9L468.6 379.3L548.6 459.3L416 591.9L320 607.9L336 511.9z"; default: return ""; } @@ -32,7 +47,7 @@ export function IconWithSpotlight({ iconPath, title }: IconWithSpotlightProps) { + + + ); +} diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/UseCases.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/UseCases.tsx new file mode 100644 index 0000000000..f77201b986 --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/sections/UseCases.tsx @@ -0,0 +1,229 @@ +"use client"; + +import { useRef } from "react"; +import { useCases } from "@/data/use-cases"; +import Link from "next/link"; +import { IconWithSpotlight } from "../sections/IconWithSpotlight"; + +interface UseCaseCardProps { + title: string; + description: React.ReactNode; + href: string; + className?: string; + iconPath: string; + variant?: "default" | "large"; +} + +function UseCaseCard({ + title, + description, + href, + className = "", + iconPath, + variant = "default", +}: UseCaseCardProps) { + const cardRef = useRef(null); + + const handleMouseMove = (e: React.MouseEvent) => { + if (!cardRef.current) return; + const card = cardRef.current; + + // Find the icon container and convert coordinates to icon-relative + const iconContainer = card.querySelector('.icon-spotlight-container') as HTMLElement; + if (!iconContainer) return; + + // Get the icon's position relative to viewport + const iconRect = iconContainer.getBoundingClientRect(); + + // Calculate mouse position relative to the icon (not the card) + const x = ((e.clientX - iconRect.left) / iconRect.width) * 100; + const y = ((e.clientY - iconRect.top) / iconRect.height) * 100; + + // Set CSS custom properties on the icon container + iconContainer.style.setProperty('--mouse-x', `${x}%`); + iconContainer.style.setProperty('--mouse-y', `${y}%`); + }; + + if (variant === "large") { + return ( + +
+ {/* Gradient overlay on hover */} +
+ + {/* Left side: Content + Checkmarks */} +
+
+

+ {title} +

+

+ {description} +

+
+ + {/* Checkmarks */} +
+ {["Cloud & on-prem", "Supports realtime", "Works with AI SDK"].map((item) => ( +
+ + + + {item} +
+ ))} +
+
+ + {/* Right side: Icon */} +
+ +
+
+ + ); + } + + return ( + +
+ {/* Gradient overlay on hover */} +
+ + {/* Content */} +
+

+ {title} +

+

+ {description} +

+
+ + {/* Spotlight icon */} +
+ +
+
+ + ); +} + +export function UseCases() { + // Map the use cases we want to display + const selectedUseCases = [ + useCases.find((uc) => uc.title === "Agent Orchestration & MCP")!, // agent orchestration & mcp + useCases.find((uc) => uc.title === "Workflows")!, // workflows + useCases.find((uc) => uc.title === "Multiplayer Apps")!, // multiplayer apps + useCases.find((uc) => uc.title === "Local-First Sync")!, // local-first sync + useCases.find((uc) => uc.title === "Background Jobs")!, // background jobs + useCases.find((uc) => uc.title === "Per-Tenant Databases")!, // per-tenant databases + useCases.find((uc) => uc.title === "Geo-Distributed Database")!, // geo-distributed database + ]; + + // Map use case titles to icon paths + const getIconPath = (title: string): string => { + const iconMap: { [key: string]: string } = { + "Agent Orchestration & MCP": "/use-case-icons/sparkles.svg", + "Workflows": "/use-case-icons/diagram-next.svg", + "Multiplayer Apps": "/use-case-icons/file-pen.svg", + "Local-First Sync": "/use-case-icons/rotate.svg", + "Background Jobs": "/use-case-icons/gears.svg", + "Per-Tenant Databases": "/use-case-icons/database.svg", + "Geo-Distributed Database": "/use-case-icons/globe.svg", + }; + return iconMap[title] || ""; + }; + + // Get highlighted description + const getHighlightedDescription = (title: string): React.ReactNode => { + const descriptionMap: { [key: string]: React.ReactNode } = { + "Agent Orchestration & MCP": ( + <> + Build AI agents with Model Context Protocol and persistent state + + ), + "Workflows": ( + <> + Durable multi-step workflows with automatic state management + + ), + "Multiplayer Apps": ( + <> + Build realtime multiplayer applications with authoritative state + + ), + "Local-First Sync": ( + <> + Offline-first applications with server synchronization + + ), + "Background Jobs": ( + <> + Scheduled and recurring jobs without external queue infrastructure + + ), + "Per-Tenant Databases": ( + <> + Isolated data stores for each user with zero-latency access + + ), + "Geo-Distributed Database": ( + <> + Store data close to users globally with automatic edge distribution + + ), + }; + return descriptionMap[title] || ""; + }; + + return ( +
+
+
+ {/* First item - takes 6 columns (half width on medium+) */} + + + {/* Remaining items - 3 columns each (quarter width on medium+) */} + {selectedUseCases.slice(1).map((useCase) => ( + + ))} +
+
+
+ ); +} diff --git a/website/src/components/CollapsibleSidebarItem.tsx b/website/src/components/CollapsibleSidebarItem.tsx index 9249e9c0ab..05c9b13bfa 100644 --- a/website/src/components/CollapsibleSidebarItem.tsx +++ b/website/src/components/CollapsibleSidebarItem.tsx @@ -88,7 +88,7 @@ export function CollapsibleSidebarItem({