From 041aba9a4166598b1895665d859083e3260adea5 Mon Sep 17 00:00:00 2001 From: Nicholas Kissel Date: Fri, 12 Jun 2026 01:16:55 -0700 Subject: [PATCH 01/25] [SLOP(claude-fable-5)] style(website): align marketing heading weights with cookbook and compare pages --- website/CLAUDE.md | 5 ++++ website/src/components/BlogArticle.astro | 4 ++-- website/src/components/faq/FaqSection.tsx | 2 +- .../marketing/cloud/PerformanceSection.tsx | 2 +- .../marketing/components/AnimatedCTATitle.tsx | 2 +- .../marketing/pricing/PricingPageClient.tsx | 24 +++++++++---------- .../marketing/sales/SalesPageClient.tsx | 2 +- .../src/components/marketing/sales/form.tsx | 2 +- .../marketing/sections/AgentOSSection.tsx | 2 +- .../marketing/sections/BenchmarksSection.tsx | 2 +- .../marketing/sections/BuiltInFeatures.tsx | 2 +- .../marketing/sections/CodeWalkthrough.tsx | 6 ++--- .../sections/DynamicActorsSection.tsx | 2 +- .../marketing/sections/HeroSection.tsx | 2 +- .../marketing/sections/HostingSection.tsx | 8 +++---- .../sections/IntegrationsSection.tsx | 2 +- .../sections/ObservabilitySection.tsx | 4 ++-- .../marketing/sections/OnPremSection.tsx | 4 ++-- .../marketing/sections/ProblemSection.tsx | 2 +- .../sections/ProductSplitSection.tsx | 2 +- .../marketing/sections/RedesignedHero.tsx | 2 +- .../marketing/solutions/AgentOSPage.tsx | 22 ++++++++--------- .../solutions/AgentOSPricingPage.tsx | 4 ++-- .../solutions/AgentOSUseCasesPage.tsx | 4 ++-- .../marketing/solutions/RegistryPage.tsx | 2 +- .../marketing/solutions/TimelinePage.tsx | 6 ++--- .../components/marketing/solutions/page.tsx | 22 ++++++++--------- .../marketing/startups/StartupsPage.tsx | 12 +++++----- .../TalkToAnEngineerPageClient.tsx | 2 +- .../marketing/talk-to-an-engineer/form.tsx | 2 +- website/src/pages/actors.astro | 2 +- website/src/pages/blog/index.astro | 4 ++-- website/src/pages/oss-friends.astro | 4 ++-- 33 files changed, 87 insertions(+), 82 deletions(-) diff --git a/website/CLAUDE.md b/website/CLAUDE.md index 3997a5f1b0..c82adfa48b 100644 --- a/website/CLAUDE.md +++ b/website/CLAUDE.md @@ -61,3 +61,8 @@ Import from `@rivet-gg/icons`. The full Font Awesome Pro library is available. C - Do not split related multi-file examples into separate non-workspace code blocks. - If any code block fails type checking, the build fails. + +## Typography + +- Marketing headings and card titles use `font-medium` (h1 heroes, section h2s, h3/h4 card titles, FAQ headings, price figures). Do not introduce `font-normal` headings. +- `font-normal` remains correct only for deliberate de-emphasis: table `th` de-bolding (UsagePricingModal), quiet `dt` labels (MobilePricingTabs), and input-like UI (TypesenseSearch). diff --git a/website/src/components/BlogArticle.astro b/website/src/components/BlogArticle.astro index 5cb2456e3c..cd56ef7659 100644 --- a/website/src/components/BlogArticle.astro +++ b/website/src/components/BlogArticle.astro @@ -61,7 +61,7 @@ const otherArticles = allPosts -

+

{title}

{description && ( @@ -116,7 +116,7 @@ const otherArticles = allPosts {formatTimestamp(article.published)} -

+

{article.title}

diff --git a/website/src/components/faq/FaqSection.tsx b/website/src/components/faq/FaqSection.tsx index 5a0d500b35..bcd7105da5 100644 --- a/website/src/components/faq/FaqSection.tsx +++ b/website/src/components/faq/FaqSection.tsx @@ -99,7 +99,7 @@ export function FaqSection({

{title}

diff --git a/website/src/components/marketing/cloud/PerformanceSection.tsx b/website/src/components/marketing/cloud/PerformanceSection.tsx index 1c9332b690..ef9fec960e 100644 --- a/website/src/components/marketing/cloud/PerformanceSection.tsx +++ b/website/src/components/marketing/cloud/PerformanceSection.tsx @@ -61,7 +61,7 @@ export const PerformanceSection = () => { />
-

+

{stat.title}

diff --git a/website/src/components/marketing/components/AnimatedCTATitle.tsx b/website/src/components/marketing/components/AnimatedCTATitle.tsx index 9d4f05b687..996b8838bb 100644 --- a/website/src/components/marketing/components/AnimatedCTATitle.tsx +++ b/website/src/components/marketing/components/AnimatedCTATitle.tsx @@ -9,7 +9,7 @@ export function AnimatedCTATitle() { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='text-2xl font-normal tracking-tight text-white md:text-4xl' + className='text-2xl font-medium tracking-tight text-white md:text-4xl' > Infrastructure for
the agentic era. diff --git a/website/src/components/marketing/pricing/PricingPageClient.tsx b/website/src/components/marketing/pricing/PricingPageClient.tsx index e2c596e217..6249cc451c 100644 --- a/website/src/components/marketing/pricing/PricingPageClient.tsx +++ b/website/src/components/marketing/pricing/PricingPageClient.tsx @@ -27,7 +27,7 @@ const Hero = () => (

-

+

Rivet Cloud

@@ -245,7 +245,7 @@ const CloudFeatures = () => {
-

Platform Features

+

Platform Features

Everything you need to run stateful workloads in production.

@@ -254,7 +254,7 @@ const CloudFeatures = () => {
-

{f.title}

+

{f.title}

{f.desc}

))} @@ -271,7 +271,7 @@ const SelfHostingComparison = () => {
-

Compare Deployment Models

+

Compare Deployment Models

Rivet is open source. Run it yourself for total control, or use Rivet Cloud for a hands-off experience.

@@ -282,7 +282,7 @@ const SelfHostingComparison = () => {
Rivet -

Rivet Cloud

+

Rivet Cloud

Managed cloud solution for personal projects to enterprise. @@ -318,7 +318,7 @@ const SelfHostingComparison = () => {

-

Open Source

+

Open Source

Maximum control for air-gapped environments or specific compliance requirements. @@ -384,7 +384,7 @@ const ComparisonTable = () => { return (

-

Compare Plans

+

Compare Plans

@@ -547,7 +547,7 @@ const Pricing = () => {
-

+

{isCloud ? "Simple, predictable pricing" : "Run it where your data lives"}

@@ -595,12 +595,12 @@ const Pricing = () => { }`} >

-

{plan.name}

+

{plan.name}

{plan.prefix && {plan.prefix}}
- {plan.price} + {plan.price} {plan.period && {plan.period}}
@@ -666,14 +666,14 @@ const Pricing = () => { <> {/* Usage Pricing Section */}
-

Usage Pricing

+

Usage Pricing

Metered costs for scaling beyond plan limits.

{usagePricing.map((item, i) => (
{item.resource}
-
{item.price}
+
{item.price}
{item.unit}
))} diff --git a/website/src/components/marketing/sales/SalesPageClient.tsx b/website/src/components/marketing/sales/SalesPageClient.tsx index 850cafacad..77136eaecb 100644 --- a/website/src/components/marketing/sales/SalesPageClient.tsx +++ b/website/src/components/marketing/sales/SalesPageClient.tsx @@ -5,7 +5,7 @@ export default function SalesPageClient() {
-

+

Contact Sales

diff --git a/website/src/components/marketing/sales/form.tsx b/website/src/components/marketing/sales/form.tsx index d2b9eac6d1..e4440f5557 100644 --- a/website/src/components/marketing/sales/form.tsx +++ b/website/src/components/marketing/sales/form.tsx @@ -47,7 +47,7 @@ export function SalesForm() { if (isSubmitted) { return (

-

+

Thank you for your interest!

diff --git a/website/src/components/marketing/sections/AgentOSSection.tsx b/website/src/components/marketing/sections/AgentOSSection.tsx index 134955d192..9e34717ce7 100644 --- a/website/src/components/marketing/sections/AgentOSSection.tsx +++ b/website/src/components/marketing/sections/AgentOSSection.tsx @@ -71,7 +71,7 @@ export const AgentOSSection = () => ( whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.05 }} - className='mb-4 text-2xl font-normal tracking-tight text-white md:text-4xl' + className='mb-4 text-2xl font-medium tracking-tight text-white md:text-4xl' > Need more than primitives? Try agentOS. diff --git a/website/src/components/marketing/sections/BenchmarksSection.tsx b/website/src/components/marketing/sections/BenchmarksSection.tsx index 8f0b574b0a..a99cf38054 100644 --- a/website/src/components/marketing/sections/BenchmarksSection.tsx +++ b/website/src/components/marketing/sections/BenchmarksSection.tsx @@ -246,7 +246,7 @@ export const BenchmarksSection = () => { transition={{ duration: 0.5 }} className='mb-10' > -

+

How Actors Compare

diff --git a/website/src/components/marketing/sections/BuiltInFeatures.tsx b/website/src/components/marketing/sections/BuiltInFeatures.tsx index d6e97b2b22..57e668f0b8 100644 --- a/website/src/components/marketing/sections/BuiltInFeatures.tsx +++ b/website/src/components/marketing/sections/BuiltInFeatures.tsx @@ -99,7 +99,7 @@ export const BuiltInFeatures = () => { transition={{ duration: 0.5 }} className='mb-10' > -

+

A lightweight primitive with powerful capabilities.

diff --git a/website/src/components/marketing/sections/CodeWalkthrough.tsx b/website/src/components/marketing/sections/CodeWalkthrough.tsx index 71ec8c8261..6ee20726f5 100644 --- a/website/src/components/marketing/sections/CodeWalkthrough.tsx +++ b/website/src/components/marketing/sections/CodeWalkthrough.tsx @@ -112,7 +112,7 @@ export const CodeWalkthrough = () => { transition={{ duration: 0.5 }} className='mb-12 lg:hidden' > -

+

How Actors work.

@@ -131,7 +131,7 @@ export const CodeWalkthrough = () => { transition={{ duration: 0.5 }} className='mb-8' > -

+

How Actors work.

@@ -193,7 +193,7 @@ export const CodeWalkthrough = () => { {String(idx + 1).padStart(2, '0')}/{String(steps.length).padStart(2, '0')}

diff --git a/website/src/components/marketing/sections/DynamicActorsSection.tsx b/website/src/components/marketing/sections/DynamicActorsSection.tsx index c63cc29df7..0e4a6c13ec 100644 --- a/website/src/components/marketing/sections/DynamicActorsSection.tsx +++ b/website/src/components/marketing/sections/DynamicActorsSection.tsx @@ -32,7 +32,7 @@ export const DynamicActorsSection = () => { viewport={{ once: true }} transition={{ duration: 0.5 }} > -

+

Securely Run AI-Generated Code

diff --git a/website/src/components/marketing/sections/HeroSection.tsx b/website/src/components/marketing/sections/HeroSection.tsx index 425bb41b25..1cdfb731a6 100644 --- a/website/src/components/marketing/sections/HeroSection.tsx +++ b/website/src/components/marketing/sections/HeroSection.tsx @@ -11,7 +11,7 @@ export function HeroSection() {

{/* Title */} -

+

The Primitive for Real-Time and Agent Applications

diff --git a/website/src/components/marketing/sections/HostingSection.tsx b/website/src/components/marketing/sections/HostingSection.tsx index 3aeaa38c02..02cc0a2376 100644 --- a/website/src/components/marketing/sections/HostingSection.tsx +++ b/website/src/components/marketing/sections/HostingSection.tsx @@ -13,7 +13,7 @@ export const HostingSection = () => ( whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mb-2 text-2xl font-normal tracking-tight text-white md:text-4xl' + className='mb-2 text-2xl font-medium tracking-tight text-white md:text-4xl' > Start local. Scale to millions. @@ -40,7 +40,7 @@ export const HostingSection = () => (
-

Just a Library

+

Just a Library

Install a package and run locally. No servers, no infrastructure. Actors run in your process during development.

@@ -65,7 +65,7 @@ export const HostingSection = () => (
-

Self-Host

+

Self-Host

Single Rust binary or Docker container. Works with Postgres, file system, or FoundationDB (enterprise). Full dashboard included.

@@ -90,7 +90,7 @@ export const HostingSection = () => (
Rivet
-

Rivet Cloud

+

Rivet Cloud

Fully managed Actors and agentOS. Global edge network. Connects to your existing cloud — Vercel, Railway, AWS, wherever you already deploy.

diff --git a/website/src/components/marketing/sections/IntegrationsSection.tsx b/website/src/components/marketing/sections/IntegrationsSection.tsx index a3e81726c3..5f99d3cdab 100644 --- a/website/src/components/marketing/sections/IntegrationsSection.tsx +++ b/website/src/components/marketing/sections/IntegrationsSection.tsx @@ -26,7 +26,7 @@ export const IntegrationsSection = () => ( transition={{ duration: 0.5 }} className='max-w-xl' > -

Runs where you do.

+

Runs where you do.

Serverless, containers, or your own servers — Rivet Actors work with your existing infrastructure, frameworks, and tools.

diff --git a/website/src/components/marketing/sections/ObservabilitySection.tsx b/website/src/components/marketing/sections/ObservabilitySection.tsx index 3fdb26db69..a65bb11605 100644 --- a/website/src/components/marketing/sections/ObservabilitySection.tsx +++ b/website/src/components/marketing/sections/ObservabilitySection.tsx @@ -102,7 +102,7 @@ export const ObservabilitySection = () => { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mb-2 text-2xl font-normal tracking-tight text-white md:text-4xl' + className='mb-2 text-2xl font-medium tracking-tight text-white md:text-4xl' > Built-In Observability @@ -127,7 +127,7 @@ export const ObservabilitySection = () => { className='border-t border-white/10 py-6 pr-8' >
{feat.icon}
-

{feat.title}

+

{feat.title}

{feat.description}

))} diff --git a/website/src/components/marketing/sections/OnPremSection.tsx b/website/src/components/marketing/sections/OnPremSection.tsx index c539a4b41f..4d22a208f6 100644 --- a/website/src/components/marketing/sections/OnPremSection.tsx +++ b/website/src/components/marketing/sections/OnPremSection.tsx @@ -30,7 +30,7 @@ export const OnPremSection = () => ( whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.05 }} - className='mb-4 text-2xl font-normal tracking-tight text-white md:text-4xl' + className='mb-4 text-2xl font-medium tracking-tight text-white md:text-4xl' > Run it where your data lives. @@ -60,7 +60,7 @@ export const OnPremSection = () => (
-

{point.title}

+

{point.title}

{point.body}

); diff --git a/website/src/components/marketing/sections/ProblemSection.tsx b/website/src/components/marketing/sections/ProblemSection.tsx index bb7690f6f8..a480b975df 100644 --- a/website/src/components/marketing/sections/ProblemSection.tsx +++ b/website/src/components/marketing/sections/ProblemSection.tsx @@ -370,7 +370,7 @@ export const ProblemSection = () => { transition={{ duration: 0.5 }} className='mb-12' > -

+

Actors in action.

diff --git a/website/src/components/marketing/sections/ProductSplitSection.tsx b/website/src/components/marketing/sections/ProductSplitSection.tsx index 3c951a74fc..302c52d4ec 100644 --- a/website/src/components/marketing/sections/ProductSplitSection.tsx +++ b/website/src/components/marketing/sections/ProductSplitSection.tsx @@ -124,7 +124,7 @@ const ProductCard = ({ icon, title, tagline, docsHref, detailsHref, features, de >

{icon} -

{title}

+

{title}

diff --git a/website/src/components/marketing/sections/RedesignedHero.tsx b/website/src/components/marketing/sections/RedesignedHero.tsx index 3d3838b03e..330db7827e 100644 --- a/website/src/components/marketing/sections/RedesignedHero.tsx +++ b/website/src/components/marketing/sections/RedesignedHero.tsx @@ -270,7 +270,7 @@ export const RedesignedHero = ({ latestChangelogTitle, thinkingImages }: Redesig initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} - className='mb-4 text-4xl font-normal leading-[1.1] tracking-tight text-white md:text-6xl' + className='mb-4 text-4xl font-medium leading-[1.1] tracking-tight text-white md:text-6xl' > Infrastructure for
the agentic era. diff --git a/website/src/components/marketing/solutions/AgentOSPage.tsx b/website/src/components/marketing/solutions/AgentOSPage.tsx index cbe1349a4e..79d2a92ba1 100644 --- a/website/src/components/marketing/solutions/AgentOSPage.tsx +++ b/website/src/components/marketing/solutions/AgentOSPage.tsx @@ -962,7 +962,7 @@ const FeatureCard = ({

-

+

{title}

{description}

@@ -980,7 +980,7 @@ const FeatureCard = ({ )} {metric && (
- + {metric.value} {metric.label} @@ -1153,7 +1153,7 @@ const StackingFeatureCards = () => { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mx-auto max-w-4xl text-center text-3xl font-normal tracking-tight text-zinc-900 md:text-5xl' + className='mx-auto max-w-4xl text-center text-3xl font-medium tracking-tight text-zinc-900 md:text-5xl' > Meet your agent's new operating system. @@ -1185,7 +1185,7 @@ const StackingFeatureCards = () => { -

+

{feature.title}

@@ -1212,7 +1212,7 @@ const StackingFeatureCards = () => {

{feature.metrics.map((m) => (
- + {m.value} {m.label} @@ -1346,7 +1346,7 @@ const ThemedFeatureSections = () => ( transition={{ duration: 0.6 }} className='mb-10' > -

+

{section.title}

@@ -1382,7 +1382,7 @@ const RegistryCallout = () => ( >

-

+

agentOS Registry

@@ -1717,7 +1717,7 @@ function BenchmarkSection() { transition={{ duration: 0.5 }} >

-

+

Performance benchmarks

@@ -1775,7 +1775,7 @@ const TechnologyAndBenchmarks = () => ( transition={{ duration: 0.5 }} className='mb-16' > -

+

A new operating system architecture.

@@ -1905,7 +1905,7 @@ const SisterProducts = () => { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.05 }} - className='mb-4 text-3xl font-normal tracking-tight text-zinc-900 md:text-4xl' + className='mb-4 text-3xl font-medium tracking-tight text-zinc-900 md:text-4xl' > Pairs with agentOS. @@ -1981,7 +1981,7 @@ const FromUnixToAgents = () => ( transition={{ duration: 0.5, delay: 0.1 }} className='flex-1' > -

+

From humans to agents

diff --git a/website/src/components/marketing/solutions/AgentOSPricingPage.tsx b/website/src/components/marketing/solutions/AgentOSPricingPage.tsx index 0af32d9711..9fec7f8a9d 100644 --- a/website/src/components/marketing/solutions/AgentOSPricingPage.tsx +++ b/website/src/components/marketing/solutions/AgentOSPricingPage.tsx @@ -177,7 +177,7 @@ const CTASection = () => ( className="border-t border-zinc-200 px-6 py-24" >

-

+

Ready to get started?

@@ -215,7 +215,7 @@ export default function AgentOSPricingPage() { animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} > -

+

Free and open source.

diff --git a/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx b/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx index 361d4d7e6a..9d914b30d3 100644 --- a/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx +++ b/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx @@ -177,7 +177,7 @@ export default function AgentOSUseCasesPage() { initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.05 }} - className='mb-6 text-4xl font-normal leading-[1.1] tracking-tight text-zinc-900 md:text-6xl' + className='mb-6 text-4xl font-medium leading-[1.1] tracking-tight text-zinc-900 md:text-6xl' > Who is agentOS for? @@ -211,7 +211,7 @@ export default function AgentOSUseCasesPage() { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mb-4 text-2xl font-normal tracking-tight text-zinc-900 md:text-4xl' + className='mb-4 text-2xl font-medium tracking-tight text-zinc-900 md:text-4xl' > Ready to build? diff --git a/website/src/components/marketing/solutions/RegistryPage.tsx b/website/src/components/marketing/solutions/RegistryPage.tsx index ce4bf4fd64..bb3153c208 100644 --- a/website/src/components/marketing/solutions/RegistryPage.tsx +++ b/website/src/components/marketing/solutions/RegistryPage.tsx @@ -110,7 +110,7 @@ const Hero = () => ( transition={{ duration: 0.5 }} className='text-center' > -

+

agentOS Registry

diff --git a/website/src/components/marketing/solutions/TimelinePage.tsx b/website/src/components/marketing/solutions/TimelinePage.tsx index 34d3e41bff..b27a31c503 100644 --- a/website/src/components/marketing/solutions/TimelinePage.tsx +++ b/website/src/components/marketing/solutions/TimelinePage.tsx @@ -33,7 +33,7 @@ const Era = ({ year, title, lead, body, children, future, delay = 0 }: EraProps)

{title}

@@ -70,7 +70,7 @@ export default function TimelinePage() { initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} - className='mb-4 text-4xl font-normal leading-[1.1] tracking-tight text-zinc-900 md:text-6xl' + className='mb-4 text-4xl font-medium leading-[1.1] tracking-tight text-zinc-900 md:text-6xl' > From Unix to Agents @@ -257,7 +257,7 @@ export default function TimelinePage() { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mb-4 text-2xl font-normal tracking-tight text-zinc-900 md:text-4xl' + className='mb-4 text-2xl font-medium tracking-tight text-zinc-900 md:text-4xl' > The shift is happening now. diff --git a/website/src/components/marketing/solutions/page.tsx b/website/src/components/marketing/solutions/page.tsx index 6996744019..3032056e03 100644 --- a/website/src/components/marketing/solutions/page.tsx +++ b/website/src/components/marketing/solutions/page.tsx @@ -117,7 +117,7 @@ const FeatureItem = ({ title, description, icon: Icon }: { title: string; descri
-

{title}

+

{title}

{description}

); @@ -134,7 +134,7 @@ const Hero = () => ( initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} - className="mb-6 text-4xl font-normal leading-[1.1] tracking-tight text-white md:text-6xl" + className="mb-6 text-4xl font-medium leading-[1.1] tracking-tight text-white md:text-6xl" > Build AI Agents @@ -207,7 +207,7 @@ const MemoryArchitecture = () => {
-

+

Why Actors for Agents?

@@ -278,7 +278,7 @@ const MemoryArchitecture = () => {

-

Zero-Latency Context

+

Zero-Latency Context

Conversation history and embedding vectors stay in the Actor's heap. No database queries required to "rehydrate" the agent state for each message.

@@ -293,7 +293,7 @@ const MemoryArchitecture = () => {
-

Long-Running "Thought" Loops

+

Long-Running "Thought" Loops

Agents often need to chain multiple tool calls (CoT). Actors can run for minutes or hours, maintaining their state throughout the entire reasoning chain without timeouts.

@@ -308,7 +308,7 @@ const MemoryArchitecture = () => {
-

Multi-User Collaboration

+

Multi-User Collaboration

Since the Actor is a live process, multiple users can connect to the same Agent instance simultaneously via WebSockets to collaborate or monitor execution.

@@ -359,7 +359,7 @@ const AgentCapabilities = () => {
-

Built for the Agentic Future

+

Built for the Agentic Future

The infrastructure primitives you need to move beyond simple chatbots.

@@ -380,7 +380,7 @@ const UseCases = () => (
-

+

Customer Support Swarms

@@ -458,7 +458,7 @@ export const manager = actor({

-

+

Orchestrate Agent Swarms

@@ -487,7 +487,7 @@ export const manager = actor({ const Ecosystem = () => (

-

+

Works with your stack

@@ -518,7 +518,7 @@ export default function AgentsPage() { {/* CTA Section */}
-

+

Stop building generic bots.

diff --git a/website/src/components/marketing/startups/StartupsPage.tsx b/website/src/components/marketing/startups/StartupsPage.tsx index 61d04821cc..7f26734939 100644 --- a/website/src/components/marketing/startups/StartupsPage.tsx +++ b/website/src/components/marketing/startups/StartupsPage.tsx @@ -190,7 +190,7 @@ function CollapsibleSection({ title, children, defaultOpen = false }: Collapsibl onClick={() => setIsOpen(!isOpen)} className="flex h-28 w-full items-center justify-between text-left" > -

+

{title}

-

+

Built for Demo Day and Beyond

@@ -310,7 +310,7 @@ export default function StartupsPage({ foundersImage, speedrunImage }: StartupsP

-

+

50% off Rivet Cloud for 12 months

@@ -339,7 +339,7 @@ export default function StartupsPage({ foundersImage, speedrunImage }: StartupsP

{benefits.map((benefit, idx) => (
-

{benefit.title}

+

{benefit.title}

{benefit.description}

))} @@ -368,7 +368,7 @@ export default function StartupsPage({ foundersImage, speedrunImage }: StartupsP
{step.number}
-

{step.title}

+

{step.title}

{step.description}

))} @@ -378,7 +378,7 @@ export default function StartupsPage({ foundersImage, speedrunImage }: StartupsP {/* CTA */}
-

+

Ready to build?

diff --git a/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx b/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx index d1c4872294..ce306f6091 100644 --- a/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx +++ b/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx @@ -5,7 +5,7 @@ export default function TalkToAnEngineerPageClient() {
-

+

Talk to an Engineer

diff --git a/website/src/components/marketing/talk-to-an-engineer/form.tsx b/website/src/components/marketing/talk-to-an-engineer/form.tsx index 47b30bf9a8..2ed58b7408 100644 --- a/website/src/components/marketing/talk-to-an-engineer/form.tsx +++ b/website/src/components/marketing/talk-to-an-engineer/form.tsx @@ -50,7 +50,7 @@ export function TalkToAnEngineerForm() { if (isSubmitted) { return (

-

+

Thank you for your interest!

diff --git a/website/src/pages/actors.astro b/website/src/pages/actors.astro index 1609c479ae..b618619cd9 100644 --- a/website/src/pages/actors.astro +++ b/website/src/pages/actors.astro @@ -24,7 +24,7 @@ import { actorsFaqs } from '@/data/faqs/actors';

-

+

The primitive for
stateful workloads.

diff --git a/website/src/pages/blog/index.astro b/website/src/pages/blog/index.astro index 37f3963c61..ebdaf729c7 100644 --- a/website/src/pages/blog/index.astro +++ b/website/src/pages/blog/index.astro @@ -55,7 +55,7 @@ for (const entry of changelogPosts) {

-

Blog

+

Blog

-

+

{article.title}

diff --git a/website/src/pages/oss-friends.astro b/website/src/pages/oss-friends.astro index af002a7d32..6266d7764d 100644 --- a/website/src/pages/oss-friends.astro +++ b/website/src/pages/oss-friends.astro @@ -21,7 +21,7 @@ try {

-

+

Open Source Friends

@@ -41,7 +41,7 @@ try { rel="noopener noreferrer" class="group flex flex-col rounded-lg border border-white/10 p-6 transition-colors hover:border-white/20" > -

+

{friend.name}

From 69a2420e23febbb29d90dfc6bbb09d5e92bf5b26 Mon Sep 17 00:00:00 2001 From: Nicholas Kissel Date: Fri, 12 Jun 2026 01:34:02 -0700 Subject: [PATCH 02/25] [SLOP(claude-opus-4-8)] feat(website): swap observability inspector screenshot for light/dark variants with animated toggle --- .../sections/ObservabilitySection.tsx | 86 +++++++++++-------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/website/src/components/marketing/sections/ObservabilitySection.tsx b/website/src/components/marketing/sections/ObservabilitySection.tsx index a65bb11605..fdec2e35b0 100644 --- a/website/src/components/marketing/sections/ObservabilitySection.tsx +++ b/website/src/components/marketing/sections/ObservabilitySection.tsx @@ -4,24 +4,26 @@ import { Database, GitBranch, Activity, Terminal, ArrowRight, Sun, Moon } from ' import { motion } from 'framer-motion'; import { useState } from 'react'; +const inspectorAspect = 2438 / 1613; + const inspectorImages = { - dark: { - src: 'https://assets.rivet.dev/repo/website/src/components/marketing/images/screenshots/rivet-actor-inspector-dark.png', - width: 2446, - height: 1658, - }, light: { src: 'https://assets.rivet.dev/repo/website/src/components/marketing/images/screenshots/rivet-actor-inspector-light.png', - width: 2446, - height: 1658, + icon: Sun, + label: 'Show inspector in light mode', + }, + dark: { + src: 'https://assets.rivet.dev/repo/website/src/components/marketing/images/screenshots/rivet-actor-inspector-dark.png', + icon: Moon, + label: 'Show inspector in dark mode', }, } as const; type InspectorTheme = keyof typeof inspectorImages; +const inspectorThemes = Object.keys(inspectorImages) as InspectorTheme[]; export const ObservabilitySection = () => { const [theme, setTheme] = useState('dark'); - const inspector = inspectorImages[theme]; const features = [ { @@ -60,37 +62,49 @@ export const ObservabilitySection = () => { className='relative' >

-
- {`Rivet +
+ {inspectorThemes.map((t) => ( + + ))}
{/* Light/dark mode toggle */} -
- - +
+ {inspectorThemes.map((t) => { + const Icon = inspectorImages[t].icon; + const active = theme === t; + return ( + + ); + })}
From f544debcaac9273b1a8a4bac6c42912ffd01f831 Mon Sep 17 00:00:00 2001 From: Nicholas Kissel Date: Fri, 12 Jun 2026 10:22:59 -0700 Subject: [PATCH 03/25] [SLOP(claude-fable-5)] fix(website): lead marketing copy with agents and run-anywhere positioning --- .../marketing/pricing/PricingPageClient.tsx | 40 ++++---- .../marketing/registry/RegistryPageClient.tsx | 4 +- .../marketing/sections/BuiltInFeatures.tsx | 6 +- .../marketing/sections/OnPremSection.tsx | 12 ++- .../sections/ProductSplitSection.tsx | 30 +++++- .../marketing/sections/RedesignedHero.tsx | 4 +- .../marketing/solutions/AgentOSPage.tsx | 32 +++--- .../components/marketing/solutions/page.tsx | 97 +++++++++++++++++-- website/src/data/bench.ts | 4 + .../compare/cloudflare-durable-objects.tsx | 4 +- website/src/pages/actors.astro | 10 +- website/src/pages/agent-os/use-cases.astro | 2 +- website/src/pages/agent.astro | 5 +- 13 files changed, 188 insertions(+), 62 deletions(-) diff --git a/website/src/components/marketing/pricing/PricingPageClient.tsx b/website/src/components/marketing/pricing/PricingPageClient.tsx index 6249cc451c..59de0318a2 100644 --- a/website/src/components/marketing/pricing/PricingPageClient.tsx +++ b/website/src/components/marketing/pricing/PricingPageClient.tsx @@ -27,12 +27,12 @@ const Hero = () => (
-

+

Rivet Cloud

- Rivet sits between your clients and your infrastructure. We manage the persistent connections, global routing, and actor state orchestrating your logic wherever it runs. + The managed way to run Rivet. We operate the persistent connections, global routing, and actor state so you don't — and because Rivet is open source, the same runtime runs in your own infrastructure when you need it to.

@@ -245,7 +245,7 @@ const CloudFeatures = () => {
-

Platform Features

+

Platform Features

Everything you need to run stateful workloads in production.

@@ -271,15 +271,15 @@ const SelfHostingComparison = () => {
-

Compare Deployment Models

+

Compare Deployment Models

- Rivet is open source. Run it yourself for total control, or use Rivet Cloud for a hands-off experience. + Rivet is open source. Use Rivet Cloud for managed infrastructure, or self-host in your VPC, your customers' environments, or air-gapped networks.

@@ -547,7 +550,7 @@ const Pricing = () => {
-

+

{isCloud ? "Simple, predictable pricing" : "Run it where your data lives"}

@@ -588,9 +591,9 @@ const Pricing = () => { {plans.map((plan, idx) => (

@@ -600,11 +603,13 @@ const Pricing = () => {
{plan.prefix && {plan.prefix}}
- {plan.price} + {plan.price} {plan.period && {plan.period}}
+
+ {plan.desc &&

{plan.desc}

}
@@ -666,7 +671,7 @@ const Pricing = () => { <> {/* Usage Pricing Section */}
-

Usage Pricing

+

Usage Pricing

Metered costs for scaling beyond plan limits.

@@ -696,6 +701,7 @@ export default function PricingPageClient() {
+
); diff --git a/website/src/components/marketing/registry/RegistryPageClient.tsx b/website/src/components/marketing/registry/RegistryPageClient.tsx index 38c2fae330..79cfd8f4f6 100644 --- a/website/src/components/marketing/registry/RegistryPageClient.tsx +++ b/website/src/components/marketing/registry/RegistryPageClient.tsx @@ -22,7 +22,7 @@ const CATEGORY_ORDER: { type: string; label: string; description: string }[] = [ type: "file-system", label: "File Systems", description: - "Mount these file systems as the root or at any sub-path inside the VM.", + "Mount these file systems as the root or at any sub-path inside the agent's environment.", }, { type: "sandbox-extension", @@ -34,7 +34,7 @@ const CATEGORY_ORDER: { type: string; label: string; description: string }[] = [ type: "software", label: "Software", description: - "WASM command packages that run inside the VM. Install individually or use meta-packages.", + "Wasm command packages that run inside the agent's environment. Install individually or use meta-packages.", }, ]; diff --git a/website/src/components/marketing/sections/BuiltInFeatures.tsx b/website/src/components/marketing/sections/BuiltInFeatures.tsx index 57e668f0b8..9670e5b5ad 100644 --- a/website/src/components/marketing/sections/BuiltInFeatures.tsx +++ b/website/src/components/marketing/sections/BuiltInFeatures.tsx @@ -52,8 +52,8 @@ const features = [ }, { icon: Layers, - title: 'Scales infinitely, scales to zero', - description: 'Supports bursty workloads and is cost-efficient.', + title: 'Scales to zero, bursts to thousands', + description: 'Sleeps at near-zero cost when idle, fans out when traffic spikes.', href: '/docs/actors/design-patterns', }, { @@ -99,7 +99,7 @@ export const BuiltInFeatures = () => { transition={{ duration: 0.5 }} className='mb-10' > -

+

A lightweight primitive with powerful capabilities.

diff --git a/website/src/components/marketing/sections/OnPremSection.tsx b/website/src/components/marketing/sections/OnPremSection.tsx index 4d22a208f6..bc61668293 100644 --- a/website/src/components/marketing/sections/OnPremSection.tsx +++ b/website/src/components/marketing/sections/OnPremSection.tsx @@ -22,7 +22,7 @@ const points = [ ]; export const OnPremSection = () => ( -

+
( whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.05 }} - className='mb-4 text-2xl font-medium tracking-tight text-white md:text-4xl' + className='mb-4 text-3xl font-medium tracking-[-0.015em] text-white md:text-4xl' > Run it where your data lives. @@ -41,7 +41,13 @@ export const OnPremSection = () => ( transition={{ duration: 0.5, delay: 0.1 }} className='text-base leading-relaxed text-zinc-500 md:text-lg' > - A single binary you control. Deploy Rivet inside your VPC, your customer’s VPC, or fully air-gapped. Use the compliance you already have instead of waiting on someone else’s. + A single binary you control. Deploy Rivet inside your VPC, your customer’s VPC, or fully air-gapped. Use the compliance you already have instead of waiting on someone else’s.{' '} + + Runs where Cloudflare Durable Objects can’t reach. +
diff --git a/website/src/components/marketing/sections/ProductSplitSection.tsx b/website/src/components/marketing/sections/ProductSplitSection.tsx index 302c52d4ec..c338d207ef 100644 --- a/website/src/components/marketing/sections/ProductSplitSection.tsx +++ b/website/src/components/marketing/sections/ProductSplitSection.tsx @@ -17,8 +17,8 @@ const actorFeatures = [ }, { icon: Layers, - title: 'Scales infinitely, scales to zero', - description: 'Supports bursty workloads and is cost-efficient.', + title: 'Scales to zero, bursts to thousands', + description: 'Sleeps at near-zero cost when idle, fans out when traffic spikes.', }, { icon: Globe, @@ -45,8 +45,8 @@ const agentOSFeatures = [ }, { icon: Layers, - title: '32x cheaper than sandboxes', - description: 'V8 isolates + WASM instead of full VMs.', + title: 'An order of magnitude cheaper', + description: 'V8 isolates + Wasm instead of full VM sandboxes.', }, { icon: Code, @@ -167,6 +167,26 @@ const ProductCard = ({ icon, title, tagline, docsHref, detailsHref, features, de export const ProductSplitSection = () => (
+
+ + One runtime, two products. + + + Rivet Actors give agents and realtime apps durable, stateful compute. agentOS gives agents a portable OS to run in. Use them alone or together. + +
} @@ -180,7 +200,7 @@ export const ProductSplitSection = () => ( } title='agentOS' - tagline='A lightweight open-source operating system for any type of agent. Built on WASM & V8.' + tagline='A portable, lightweight in-process OS for agents. Open source, built on Wasm + V8.' docsHref='/docs/agent-os' detailsHref='/agent-os' features={agentOSFeatures} diff --git a/website/src/components/marketing/sections/RedesignedHero.tsx b/website/src/components/marketing/sections/RedesignedHero.tsx index 330db7827e..664746be98 100644 --- a/website/src/components/marketing/sections/RedesignedHero.tsx +++ b/website/src/components/marketing/sections/RedesignedHero.tsx @@ -270,7 +270,7 @@ export const RedesignedHero = ({ latestChangelogTitle, thinkingImages }: Redesig initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} - className='mb-4 text-4xl font-medium leading-[1.1] tracking-tight text-white md:text-6xl' + className='mb-4 text-4xl font-medium leading-[1.06] tracking-[-0.015em] text-white md:text-6xl' > Infrastructure for
the agentic era. @@ -282,7 +282,7 @@ export const RedesignedHero = ({ latestChangelogTitle, thinkingImages }: Redesig transition={{ duration: 0.5, delay: 0.05 }} className='mb-6 text-lg text-zinc-400 md:text-xl' > - Actors are the primitive for AI agents, real-time apps,
and durable workflows. They burst when traffic spikes,
sleep when idle, run for hours, and hold state across regions. + Actors are the primitive for AI agents — and the realtime
apps and workflows around them. They burst when traffic spikes, sleep
when idle, and run anywhere: Rivet Cloud, your VPC, or fully air-gapped. { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mx-auto max-w-4xl text-center text-3xl font-medium tracking-tight text-zinc-900 md:text-5xl' + className='mx-auto max-w-4xl text-center text-3xl font-medium tracking-[-0.015em] text-zinc-900 md:text-5xl' > Meet your agent's new operating system. @@ -1185,7 +1185,7 @@ const StackingFeatureCards = () => { -

+

{feature.title}

@@ -1285,7 +1285,7 @@ const FeatureCardCarousel = ({ section }: { section: ThemedSection }) => {

-

+

{feature.title}

@@ -1346,7 +1346,7 @@ const ThemedFeatureSections = () => ( transition={{ duration: 0.6 }} className='mb-10' > -

+

{section.title}

@@ -1382,7 +1382,7 @@ const RegistryCallout = () => ( >

-

+

agentOS Registry

@@ -1415,7 +1415,7 @@ const BENCH_ACCENT = '#18181b'; const BENCH_ACCENT_LIGHT = '#3f3f46'; // Benchmark data (computed from raw inputs in bench.ts) -import { benchColdStart, benchWorkloads, SANDBOX_COLDSTART_PROVIDER, SANDBOX_COST_PROVIDER, type WorkloadKey } from '@/data/bench'; +import { benchColdStart, benchWorkloads, BENCHMARK_DATE, SANDBOX_COLDSTART_PROVIDER, SANDBOX_COST_PROVIDER, type WorkloadKey } from '@/data/bench'; function BenchInfoTooltip({ children }: { children: React.ReactNode }) { return ( @@ -1454,9 +1454,9 @@ function BenchColdStartChart() { What's measured: Time from requesting an execution to first code running.

- Why the gap: agentOS boots a lightweight VM inside the host process. No network hop, no disk image. Sandboxes must boot an entire environment, allocate memory, and establish a network connection before code can run. + Why the gap: agentOS runs agents in-process — V8 isolates and Wasm inside your host. No VM to boot, no network hop, no disk image. Sandboxes must boot an entire environment, allocate memory, and establish a network connection before code can run.

- Sandbox baseline: {SANDBOX_COLDSTART_PROVIDER}, the fastest mainstream sandbox provider as of March 30, 2026. + Sandbox baseline: {SANDBOX_COLDSTART_PROVIDER}, the fastest mainstream sandbox provider as of {BENCHMARK_DATE}.

agentOS: Median of 10,000 runs (100 iterations x 100 samples) on Intel i7-12700KF.
@@ -1546,9 +1546,9 @@ function BenchMemoryBar({ workload }: { workload: WorkloadKey }) { What's measured: Memory footprint added per concurrent execution.

- Why the gap: Lightweight VMs share the host process. Each additional execution only adds its own heap and stack. Sandboxes allocate a dedicated environment with a minimum memory reservation, even if the code inside uses far less. + Why the gap: In-process isolates share the host's memory. Each additional execution only adds its own heap and stack. Sandboxes allocate a dedicated environment with a minimum memory reservation, even if the code inside uses far less.

- Sandbox baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of March 30, 2026. Default sandbox: 1 vCPU + 1 GiB RAM. + Sandbox baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of {BENCHMARK_DATE}. Default sandbox: 1 vCPU + 1 GiB RAM.

agentOS: {workload === 'agent' ? `${benchWorkloads.agent.memory.agentOS} for a full Pi coding agent session with MCP servers and file system mounts.` : `${benchWorkloads.shell.memory.agentOS} for the minimal shell workload under sustained load.`}
@@ -1631,7 +1631,7 @@ function BenchCostChart({ workload }: { workload: WorkloadKey }) {

Why it's cheaper: Each execution uses {benchWorkloads[workload].memory.agentOS} instead of a {benchWorkloads[workload].memory.sandbox} sandbox minimum. And you run on your own hardware, which is significantly cheaper than per-second sandbox billing.

- Sandbox baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of March 30, 2026. Default sandbox: 1 vCPU + 1 GiB RAM at $0.0504/vCPU-h + $0.0162/GiB-h. + Sandbox baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of {BENCHMARK_DATE}. Default sandbox: 1 vCPU + 1 GiB RAM at $0.0504/vCPU-h + $0.0162/GiB-h.

agentOS: {benchWorkloads[workload].memory.agentOS} baseline per execution, assuming 70% utilization (industry-standard HPA scaling threshold). Select a hardware tier above to compare. @@ -1717,7 +1717,7 @@ function BenchmarkSection() { transition={{ duration: 0.5 }} >

-

+

Performance benchmarks

@@ -1751,7 +1751,7 @@ function BenchmarkSection() {

- Measured on Intel i7-12700KF. Cold start baseline: {SANDBOX_COLDSTART_PROVIDER}, the fastest mainstream sandbox provider as of March 30, 2026. Cost baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of March 30, 2026 (1 vCPU + 1 GiB default). Cost assumes 70% utilization on self-hosted hardware vs. per-second sandbox billing.{' '} + Measured on Intel i7-12700KF. Cold start baseline: {SANDBOX_COLDSTART_PROVIDER}, the fastest mainstream sandbox provider as of {BENCHMARK_DATE}. Cost baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of {BENCHMARK_DATE} (1 vCPU + 1 GiB default). Cost assumes 70% utilization on self-hosted hardware vs. per-second sandbox billing.{' '} ( transition={{ duration: 0.5 }} className='mb-16' > -

+

A new operating system architecture.

@@ -1905,7 +1905,7 @@ const SisterProducts = () => { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.05 }} - className='mb-4 text-3xl font-medium tracking-tight text-zinc-900 md:text-4xl' + className='mb-4 text-3xl font-medium tracking-[-0.015em] text-zinc-900 md:text-4xl' > Pairs with agentOS. @@ -1981,7 +1981,7 @@ const FromUnixToAgents = () => ( transition={{ duration: 0.5, delay: 0.1 }} className='flex-1' > -

+

From humans to agents

diff --git a/website/src/components/marketing/solutions/page.tsx b/website/src/components/marketing/solutions/page.tsx index 3032056e03..f49b9abbd7 100644 --- a/website/src/components/marketing/solutions/page.tsx +++ b/website/src/components/marketing/solutions/page.tsx @@ -1,5 +1,9 @@ "use client"; +// Page lane: /agent is the use-case page for agent builders. It frames Rivet Actors +// through the agent lens and owns the deploy-anywhere story. The primitive itself and +// the realtime, multiplayer, and collaborative use cases live at /actors. + import { useState, useEffect } from "react"; import { Terminal, @@ -28,6 +32,9 @@ import { Brain, Sparkles, Network, + Lock, + Building2, + ShieldCheck, } from "lucide-react"; import { motion } from "framer-motion"; @@ -134,7 +141,7 @@ const Hero = () => ( initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} - className="mb-6 text-4xl font-medium leading-[1.1] tracking-tight text-white md:text-6xl" + className="mb-6 text-4xl font-medium leading-[1.06] tracking-[-0.015em] text-white md:text-6xl" > Build AI Agents @@ -145,7 +152,7 @@ const Hero = () => ( transition={{ duration: 0.5, delay: 0.1 }} className="mb-8 max-w-lg text-base leading-relaxed text-zinc-500" > - LLMs are stateless. Agents shouldn't be. Rivet Actors provide the persistent memory, tool execution environment, and long-running context your agents need to thrive. + LLMs are stateless. Agents shouldn't be. Rivet Actors give each agent persistent memory, a tool execution environment, and long-running context — on Rivet Cloud, your Kubernetes cluster, or fully air-gapped. ( View Documentation + + Agents are one thing Rivet Actors do.{" "} + + See the primitive + +

{
-

+

Why Actors for Agents?

@@ -359,7 +377,7 @@ const AgentCapabilities = () => {

-

Built for the Agentic Future

+

Built for the Agentic Future

The infrastructure primitives you need to move beyond simple chatbots.

@@ -380,7 +398,7 @@ const UseCases = () => (
-

+

Customer Support Swarms

@@ -458,7 +476,7 @@ export const manager = actor({

-

+

Orchestrate Agent Swarms

@@ -484,10 +502,72 @@ export const manager = actor({ ); }; +const deployAnywherePoints = [ + { + icon: Lock, + title: "Air-gapped and on-prem", + body: "Run the same Rivet that powers our cloud entirely inside your perimeter. No outbound calls, no telemetry leaving your boundary.", + }, + { + icon: Building2, + title: "Embed in your customers", + body: "Ship Rivet inside your customer's VPC, regulated environment, or on-prem hardware. They keep their data, you keep your product.", + }, + { + icon: ShieldCheck, + title: "Your compliance posture, intact", + body: "FedRAMP, HIPAA, regulated industries, sovereign clouds. Deploying inside the boundary your existing controls already cover keeps the audit story simple.", + }, +]; + +const DeployAnywhere = () => ( +

+
+
+

+ Runs where managed platforms can't. +

+

+ Durable Objects only run on Cloudflare. Rivet is open source: deploy agents inside your VPC, your customers' environments, or air-gapped networks on the same open-source runtime. +

+
+
+ {deployAnywherePoints.map((point) => { + const Icon = point.icon; + return ( +
+
+ +
+

{point.title}

+

{point.body}

+
+ ); + })} +
+ +
+
+); + const Ecosystem = () => (
-

+

Works with your stack

@@ -513,12 +593,13 @@ export default function AgentsPage() { + {/* CTA Section */}
-

+

Stop building generic bots.

diff --git a/website/src/data/bench.ts b/website/src/data/bench.ts index 107294d6d9..553cb6e69e 100644 --- a/website/src/data/bench.ts +++ b/website/src/data/bench.ts @@ -24,6 +24,10 @@ export const MEMORY_SHELL_MB = 22; // memory-sleep.json (23160422 / 1024 // ── Sandbox baselines (external benchmarks) ── +// Date the external sandbox baselines were last verified. Interpolated wherever +// marketing copy cites the baselines so a refresh only touches this constant. +export const BENCHMARK_DATE = 'March 30, 2026'; + // Coldstart baseline: E2B (used for cold start comparison only) export const SANDBOX_COLDSTART_PROVIDER = 'E2B'; export const SANDBOX_COLDSTART_MS = { p50: 440, p95: 950, p99: 3150 }; diff --git a/website/src/data/compare/cloudflare-durable-objects.tsx b/website/src/data/compare/cloudflare-durable-objects.tsx index bf94fd9cec..5dc971886d 100644 --- a/website/src/data/compare/cloudflare-durable-objects.tsx +++ b/website/src/data/compare/cloudflare-durable-objects.tsx @@ -10,7 +10,7 @@ export const cloudflareDurableObjects: CompareEntry = { description: 'Compare Rivet Actors and Cloudflare Durable Objects: open-source stateful actors on your own infrastructure versus stateful compute tied to Cloudflare.', heroSubtitle: - 'Cloudflare Durable Objects provide stateful serverless computing with vendor lock-in. Rivet Actors give you the same capabilities as an open-source library that works with your existing infrastructure and technology stack.', + 'Cloudflare Durable Objects provide stateful serverless computing with vendor lock-in. Rivet Actors give you the same capabilities as an open-source library that works with your existing infrastructure and technology stack. If your workloads must run on-prem, in a customer VPC, or air-gapped, Durable Objects are not an option. Rivet is built for exactly that.', rivetSummary: 'Rivet Actors bring the actor model to your existing infrastructure as an open-source library. Build stateful, distributed applications with your preferred technology stack, deployed on your own infrastructure.', competitorSummary: @@ -248,7 +248,7 @@ export const cloudflareDurableObjects: CompareEntry = { feature: 'Built-in scheduling', rivet: { status: 'yes', - text: 'Powerful built-in scheduling system', + text: 'Built-in scheduling with durable timers and cron', }, competitor: { status: 'partial', diff --git a/website/src/pages/actors.astro b/website/src/pages/actors.astro index b618619cd9..affd9bab1d 100644 --- a/website/src/pages/actors.astro +++ b/website/src/pages/actors.astro @@ -1,4 +1,7 @@ --- +// Page lane: /actors is the canonical home of the Actor primitive and of the +// realtime, multiplayer, and collaborative use cases. Keep non-agent workloads +// first-class here. The agent-builder story lives at /agent. import MarketingLayout from '@/layouts/MarketingLayout.astro'; import { BuiltInFeatures } from '@/components/marketing/sections/BuiltInFeatures'; import { ProblemSection } from '@/components/marketing/sections/ProblemSection'; @@ -24,11 +27,11 @@ import { actorsFaqs } from '@/data/faqs/actors';

-

+

The primitive for
stateful workloads.

- One Actor per agent, per session, per user. State, storage, and networking included. + One Actor per agent, per session, per user. The same primitive powers realtime apps, multiplayer, and collaborative state.

+

+ Building AI agents? Start at Rivet for Agents +

diff --git a/website/src/pages/agent-os/use-cases.astro b/website/src/pages/agent-os/use-cases.astro index ef757dc044..4169a49a91 100644 --- a/website/src/pages/agent-os/use-cases.astro +++ b/website/src/pages/agent-os/use-cases.astro @@ -5,7 +5,7 @@ import AgentOSUseCasesPage from '@/components/marketing/solutions/AgentOSUseCase diff --git a/website/src/pages/agent.astro b/website/src/pages/agent.astro index 8bf55575da..180c777604 100644 --- a/website/src/pages/agent.astro +++ b/website/src/pages/agent.astro @@ -1,11 +1,14 @@ --- +// Page lane: /agent is the use-case page for agent builders and owns the +// deploy-anywhere story. The Actor primitive and the realtime, multiplayer, and +// collaborative use cases live at /actors. import MarketingLayout from '@/layouts/MarketingLayout.astro'; import AgentPageClient from '@/components/marketing/solutions/page'; --- From 7d578f0d4509e62f54bb1b3229a82466631c0ad4 Mon Sep 17 00:00:00 2001 From: Nicholas Kissel Date: Fri, 12 Jun 2026 10:23:13 -0700 Subject: [PATCH 04/25] [SLOP(claude-fable-5)] style(website): unify marketing typography and card system on compare-page primitives --- website/CLAUDE.md | 6 ++++ website/src/components/faq/FaqSection.tsx | 2 +- .../marketing/components/AnimatedCTATitle.tsx | 2 +- .../marketing/sales/SalesPageClient.tsx | 2 +- .../marketing/sections/BenchmarksSection.tsx | 2 +- .../marketing/sections/HostingSection.tsx | 2 +- .../sections/IntegrationsSection.tsx | 4 +-- .../sections/ObservabilitySection.tsx | 2 +- .../marketing/sections/ProblemSection.tsx | 2 +- .../solutions/AgentOSPricingPage.tsx | 8 ++--- .../solutions/AgentOSUseCasesPage.tsx | 4 +-- .../marketing/solutions/RegistryPage.tsx | 2 +- .../src/components/marketing/typography.tsx | 29 +++++++++++++++++++ website/src/pages/oss-friends.astro | 4 +-- 14 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 website/src/components/marketing/typography.tsx diff --git a/website/CLAUDE.md b/website/CLAUDE.md index c82adfa48b..87672f1409 100644 --- a/website/CLAUDE.md +++ b/website/CLAUDE.md @@ -66,3 +66,9 @@ Import from `@rivet-gg/icons`. The full Font Awesome Pro library is available. C - Marketing headings and card titles use `font-medium` (h1 heroes, section h2s, h3/h4 card titles, FAQ headings, price figures). Do not introduce `font-normal` headings. - `font-normal` remains correct only for deliberate de-emphasis: table `th` de-bolding (UsagePricingModal), quiet `dt` labels (MobilePricingTabs), and input-like UI (TypesenseSearch). +- Hero h1s and section h2s use the class constants in `src/components/marketing/typography.tsx` (`tracking-[-0.015em]`, h1 `leading-[1.06]`). Do not hand-write `tracking-tight` on headings at `text-2xl` or larger; `tracking-tight` stays acceptable on `text-base` and smaller card titles. + +## Theme + +- Marketing pages are dark (black background) by default. Sanctioned light surfaces: agentOS product pages (`/agent-os/*`) as a deliberate product sub-brand, and the Learn section's classical editorial treatment. No other page may introduce a light theme. +- No drop shadows on marketing cards or imagery; depth comes from `border-white/10..25` and `bg-white/[0.03]` opacity layering. Shadows stay acceptable on functional overlays (dropdowns, tooltips, modals). diff --git a/website/src/components/faq/FaqSection.tsx b/website/src/components/faq/FaqSection.tsx index bcd7105da5..0889884ce5 100644 --- a/website/src/components/faq/FaqSection.tsx +++ b/website/src/components/faq/FaqSection.tsx @@ -99,7 +99,7 @@ export function FaqSection({

{title}

diff --git a/website/src/components/marketing/components/AnimatedCTATitle.tsx b/website/src/components/marketing/components/AnimatedCTATitle.tsx index 996b8838bb..55f4b1e6d0 100644 --- a/website/src/components/marketing/components/AnimatedCTATitle.tsx +++ b/website/src/components/marketing/components/AnimatedCTATitle.tsx @@ -9,7 +9,7 @@ export function AnimatedCTATitle() { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='text-2xl font-medium tracking-tight text-white md:text-4xl' + className='text-3xl font-medium tracking-[-0.015em] text-white md:text-4xl' > Infrastructure for
the agentic era. diff --git a/website/src/components/marketing/sales/SalesPageClient.tsx b/website/src/components/marketing/sales/SalesPageClient.tsx index 77136eaecb..54734a0ddc 100644 --- a/website/src/components/marketing/sales/SalesPageClient.tsx +++ b/website/src/components/marketing/sales/SalesPageClient.tsx @@ -5,7 +5,7 @@ export default function SalesPageClient() {
-

+

Contact Sales

diff --git a/website/src/components/marketing/sections/BenchmarksSection.tsx b/website/src/components/marketing/sections/BenchmarksSection.tsx index a99cf38054..04332b2e76 100644 --- a/website/src/components/marketing/sections/BenchmarksSection.tsx +++ b/website/src/components/marketing/sections/BenchmarksSection.tsx @@ -246,7 +246,7 @@ export const BenchmarksSection = () => { transition={{ duration: 0.5 }} className='mb-10' > -

+

How Actors Compare

diff --git a/website/src/components/marketing/sections/HostingSection.tsx b/website/src/components/marketing/sections/HostingSection.tsx index 02cc0a2376..43a1309e32 100644 --- a/website/src/components/marketing/sections/HostingSection.tsx +++ b/website/src/components/marketing/sections/HostingSection.tsx @@ -13,7 +13,7 @@ export const HostingSection = () => ( whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mb-2 text-2xl font-medium tracking-tight text-white md:text-4xl' + className='mb-2 text-3xl font-medium tracking-[-0.015em] text-white md:text-4xl' > Start local. Scale to millions. diff --git a/website/src/components/marketing/sections/IntegrationsSection.tsx b/website/src/components/marketing/sections/IntegrationsSection.tsx index 5f99d3cdab..9e75554d37 100644 --- a/website/src/components/marketing/sections/IntegrationsSection.tsx +++ b/website/src/components/marketing/sections/IntegrationsSection.tsx @@ -16,7 +16,7 @@ const frameworks = [ ]; export const IntegrationsSection = () => ( -

+
( transition={{ duration: 0.5 }} className='max-w-xl' > -

Runs where you do.

+

Runs where you do.

Serverless, containers, or your own servers — Rivet Actors work with your existing infrastructure, frameworks, and tools.

diff --git a/website/src/components/marketing/sections/ObservabilitySection.tsx b/website/src/components/marketing/sections/ObservabilitySection.tsx index fdec2e35b0..c53c905285 100644 --- a/website/src/components/marketing/sections/ObservabilitySection.tsx +++ b/website/src/components/marketing/sections/ObservabilitySection.tsx @@ -116,7 +116,7 @@ export const ObservabilitySection = () => { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mb-2 text-2xl font-medium tracking-tight text-white md:text-4xl' + className='mb-2 text-3xl font-medium tracking-[-0.015em] text-white md:text-4xl' > Built-In Observability diff --git a/website/src/components/marketing/sections/ProblemSection.tsx b/website/src/components/marketing/sections/ProblemSection.tsx index a480b975df..8f22c2fcf9 100644 --- a/website/src/components/marketing/sections/ProblemSection.tsx +++ b/website/src/components/marketing/sections/ProblemSection.tsx @@ -370,7 +370,7 @@ export const ProblemSection = () => { transition={{ duration: 0.5 }} className='mb-12' > -

+

Actors in action.

diff --git a/website/src/components/marketing/solutions/AgentOSPricingPage.tsx b/website/src/components/marketing/solutions/AgentOSPricingPage.tsx index 9fec7f8a9d..ba74a55cee 100644 --- a/website/src/components/marketing/solutions/AgentOSPricingPage.tsx +++ b/website/src/components/marketing/solutions/AgentOSPricingPage.tsx @@ -105,7 +105,7 @@ const PricingCard = ({ tier, index, showCloudNotice = false }: { tier: typeof pr }`}>

-

{tier.name}

+

{tier.name}

{tier.description}

@@ -113,7 +113,7 @@ const PricingCard = ({ tier, index, showCloudNotice = false }: { tier: typeof pr
- {tier.price} + {tier.price}

{tier.priceSuffix} @@ -177,7 +177,7 @@ const CTASection = () => ( className="border-t border-zinc-200 px-6 py-24" >

-

+

Ready to get started?

@@ -215,7 +215,7 @@ export default function AgentOSPricingPage() { animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} > -

+

Free and open source.

diff --git a/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx b/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx index 9d914b30d3..3e51eba34d 100644 --- a/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx +++ b/website/src/components/marketing/solutions/AgentOSUseCasesPage.tsx @@ -177,7 +177,7 @@ export default function AgentOSUseCasesPage() { initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.05 }} - className='mb-6 text-4xl font-medium leading-[1.1] tracking-tight text-zinc-900 md:text-6xl' + className='mb-6 text-4xl font-medium leading-[1.06] tracking-[-0.015em] text-zinc-900 md:text-6xl' > Who is agentOS for? @@ -211,7 +211,7 @@ export default function AgentOSUseCasesPage() { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5 }} - className='mb-4 text-2xl font-medium tracking-tight text-zinc-900 md:text-4xl' + className='mb-4 text-3xl font-medium tracking-[-0.015em] text-zinc-900 md:text-4xl' > Ready to build? diff --git a/website/src/components/marketing/solutions/RegistryPage.tsx b/website/src/components/marketing/solutions/RegistryPage.tsx index bb3153c208..56436e68bc 100644 --- a/website/src/components/marketing/solutions/RegistryPage.tsx +++ b/website/src/components/marketing/solutions/RegistryPage.tsx @@ -110,7 +110,7 @@ const Hero = () => ( transition={{ duration: 0.5 }} className='text-center' > -

+

agentOS Registry

diff --git a/website/src/components/marketing/typography.tsx b/website/src/components/marketing/typography.tsx new file mode 100644 index 0000000000..f983dd91be --- /dev/null +++ b/website/src/components/marketing/typography.tsx @@ -0,0 +1,29 @@ +import type { ReactNode } from 'react'; + +// Canonical marketing typography. These class strings are the single source of +// truth for heading treatment on marketing surfaces. Use them (or SectionHeading) +// instead of hand-writing tracking and weight classes on new pages. + +// Hero H1 on dark marketing pages. +export const HERO_H1_CLASS = + 'text-4xl font-medium leading-[1.06] tracking-[-0.015em] text-white md:text-6xl'; + +// Section H2 on dark marketing pages. +export const SECTION_H2_CLASS = + 'text-3xl font-medium tracking-[-0.015em] text-white md:text-4xl'; + +// Muted subtitle that sits under a hero or section heading. +export const SUBTITLE_CLASS = 'mt-4 text-base leading-relaxed text-zinc-500'; + +interface SectionHeadingProps { + title: ReactNode; + subtitle?: ReactNode; + className?: string; +} + +export const SectionHeading = ({ title, subtitle, className }: SectionHeadingProps) => ( +

+

{title}

+ {subtitle ?

{subtitle}

: null} +
+); diff --git a/website/src/pages/oss-friends.astro b/website/src/pages/oss-friends.astro index 6266d7764d..418f71f245 100644 --- a/website/src/pages/oss-friends.astro +++ b/website/src/pages/oss-friends.astro @@ -21,7 +21,7 @@ try {
-

+

Open Source Friends

@@ -39,7 +39,7 @@ try { href={friend.href} target="_blank" rel="noopener noreferrer" - class="group flex flex-col rounded-lg border border-white/10 p-6 transition-colors hover:border-white/20" + class="group flex flex-col rounded-xl border border-white/10 p-6 transition-colors hover:border-white/20" >

{friend.name} From 41c21537db9c3c11f6062939bbe34f6a652b7b52 Mon Sep 17 00:00:00 2001 From: Nicholas Kissel Date: Fri, 12 Jun 2026 10:23:22 -0700 Subject: [PATCH 05/25] [SLOP(claude-fable-5)] style(website): remove dated decoration and align blog and timeline with dark design language --- website/src/components/BlogArticle.astro | 7 +- .../src/components/marketing/NotFoundPage.tsx | 2 +- .../marketing/solutions/GetStartedPage.tsx | 170 ++---------------- .../marketing/solutions/TimelinePage.tsx | 52 +++--- .../marketing/startups/StartupsPage.tsx | 65 +------ .../TalkToAnEngineerPageClient.tsx | 2 +- website/src/pages/blog/index.astro | 12 +- website/src/pages/support.astro | 10 +- 8 files changed, 63 insertions(+), 257 deletions(-) diff --git a/website/src/components/BlogArticle.astro b/website/src/components/BlogArticle.astro index cd56ef7659..55504001c3 100644 --- a/website/src/components/BlogArticle.astro +++ b/website/src/components/BlogArticle.astro @@ -61,7 +61,7 @@ const otherArticles = allPosts -

+

{title}

{description && ( @@ -111,7 +111,7 @@ const otherArticles = allPosts /> )}
- {article.category.name} + {article.category.name} @@ -152,6 +152,7 @@ const otherArticles = allPosts .blog-article .blog-prose h2 { font-size: 1.75rem; + font-weight: 500; line-height: 1.2; letter-spacing: -0.02em; margin-top: 2.75rem; @@ -161,6 +162,7 @@ const otherArticles = allPosts .blog-article .blog-prose h3 { font-size: 1.3rem; + font-weight: 500; line-height: 1.3; letter-spacing: -0.015em; margin-top: 2.25rem; @@ -170,6 +172,7 @@ const otherArticles = allPosts .blog-article .blog-prose h4 { font-size: 1.075rem; + font-weight: 500; margin-top: 2rem; margin-bottom: 0.5rem; color: #fff; diff --git a/website/src/components/marketing/NotFoundPage.tsx b/website/src/components/marketing/NotFoundPage.tsx index e98a5fb5a8..16a5494ef1 100644 --- a/website/src/components/marketing/NotFoundPage.tsx +++ b/website/src/components/marketing/NotFoundPage.tsx @@ -108,7 +108,7 @@ export const NotFoundPage = ({ thinkingImage }: NotFoundPageProps) => { transition={{ duration: 0.6 }} className="relative w-[280px] h-[350px] sm:w-[320px] sm:h-[400px]" > -
+
Classical artwork depicting contemplation { - const canvasRef = useRef(null); - const gridRef = useRef([]); - const animationRef = useRef(); - - const CELL_SIZE = 16; - const UPDATE_INTERVAL = 150; - - const initGrid = useCallback((cols: number, rows: number) => { - const grid: boolean[][] = []; - for (let i = 0; i < rows; i++) { - grid[i] = []; - for (let j = 0; j < cols; j++) { - // Sparse random initialization - grid[i][j] = Math.random() < 0.15; - } - } - return grid; - }, []); - - const countNeighbors = useCallback((grid: boolean[][], x: number, y: number, rows: number, cols: number) => { - let count = 0; - for (let i = -1; i <= 1; i++) { - for (let j = -1; j <= 1; j++) { - if (i === 0 && j === 0) continue; - const ni = (y + i + rows) % rows; - const nj = (x + j + cols) % cols; - if (grid[ni][nj]) count++; - } - } - return count; - }, []); - - const nextGeneration = useCallback((grid: boolean[][], rows: number, cols: number) => { - const newGrid: boolean[][] = []; - for (let i = 0; i < rows; i++) { - newGrid[i] = []; - for (let j = 0; j < cols; j++) { - const neighbors = countNeighbors(grid, j, i, rows, cols); - if (grid[i][j]) { - newGrid[i][j] = neighbors === 2 || neighbors === 3; - } else { - newGrid[i][j] = neighbors === 3; - } - } - } - return newGrid; - }, [countNeighbors]); - - useEffect(() => { - const canvas = canvasRef.current; - if (!canvas) return; - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const resize = () => { - canvas.width = canvas.offsetWidth; - canvas.height = canvas.offsetHeight; - const cols = Math.ceil(canvas.width / CELL_SIZE); - const rows = Math.ceil(canvas.height / CELL_SIZE); - gridRef.current = initGrid(cols, rows); - }; - - resize(); - window.addEventListener('resize', resize); - - let lastUpdate = 0; - - const draw = (timestamp: number) => { - if (!ctx || !canvas) return; - - if (timestamp - lastUpdate > UPDATE_INTERVAL) { - const cols = Math.ceil(canvas.width / CELL_SIZE); - const rows = Math.ceil(canvas.height / CELL_SIZE); - - // Occasionally add new cells to keep it alive - if (Math.random() < 0.02) { - const rx = Math.floor(Math.random() * cols); - const ry = Math.floor(Math.random() * rows); - for (let i = -1; i <= 1; i++) { - for (let j = -1; j <= 1; j++) { - const ni = (ry + i + rows) % rows; - const nj = (rx + j + cols) % cols; - if (gridRef.current[ni] && Math.random() < 0.5) { - gridRef.current[ni][nj] = true; - } - } - } - } - - gridRef.current = nextGeneration(gridRef.current, rows, cols); - lastUpdate = timestamp; - } - - ctx.clearRect(0, 0, canvas.width, canvas.height); - - const cols = Math.ceil(canvas.width / CELL_SIZE); - const rows = Math.ceil(canvas.height / CELL_SIZE); - - for (let i = 0; i < rows; i++) { - for (let j = 0; j < cols; j++) { - if (gridRef.current[i]?.[j]) { - ctx.fillStyle = 'rgba(228, 228, 231, 0.6)'; // zinc-200 with transparency - ctx.fillRect( - j * CELL_SIZE + 1, - i * CELL_SIZE + 1, - CELL_SIZE - 2, - CELL_SIZE - 2 - ); - } - } - } - - animationRef.current = requestAnimationFrame(draw); - }; - - animationRef.current = requestAnimationFrame(draw); - - return () => { - window.removeEventListener('resize', resize); - if (animationRef.current) { - cancelAnimationFrame(animationRef.current); - } - }; - }, [initGrid, nextGeneration]); - - return ( - - ); -}; - const CopyCommand = ({ command }: { command: string }) => { const [copied, setCopied] = useState(false); @@ -151,12 +14,12 @@ const CopyCommand = ({ command }: { command: string }) => { }; return ( -
- $ - {command} +
+ $ + {command} @@ -166,13 +29,9 @@ const CopyCommand = ({ command }: { command: string }) => { export default function GetStartedPage() { return ( -
- {/* Game of Life Background */} -
- -
+
{/* Hero */} -
+
-
- agentOS - -
+ agentOS
Quickstart Guide diff --git a/website/src/components/marketing/solutions/TimelinePage.tsx b/website/src/components/marketing/solutions/TimelinePage.tsx index b27a31c503..1c1a85e44d 100644 --- a/website/src/components/marketing/solutions/TimelinePage.tsx +++ b/website/src/components/marketing/solutions/TimelinePage.tsx @@ -23,17 +23,17 @@ const Era = ({ year, title, lead, body, children, future, delay = 0 }: EraProps) >
{year}

{title}

@@ -51,7 +51,7 @@ const Era = ({ year, title, lead, body, children, future, delay = 0 }: EraProps) ); const PrincipleChip = ({ label, text }: { label: string; text: string }) => ( -
+
{label} @@ -61,7 +61,7 @@ const PrincipleChip = ({ label, text }: { label: string; text: string }) => ( export default function TimelinePage() { return ( -
+
{/* Hero */}
@@ -70,7 +70,7 @@ export default function TimelinePage() { initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} - className='mb-4 text-4xl font-medium leading-[1.1] tracking-tight text-zinc-900 md:text-6xl' + className='mb-4 text-4xl font-medium leading-[1.06] tracking-[-0.015em] text-white md:text-6xl' > From Unix to Agents @@ -86,7 +86,7 @@ export default function TimelinePage() {
{/* Timeline */} -
+
-
+
Ken Thompson and Dennis Ritchie, creators of Unix, 1973 -

+

Ken Thompson and Dennis Ritchie, 1973.{' '} @@ -136,18 +136,18 @@ export default function TimelinePage() { body='This openness sparked an explosion of innovation. The kernel became the backbone of servers, phones, cars, and spacecraft. Open source became the default way to build software.' delay={0.1} > -

+
The first web server at CERN -

+

The first web server at CERN. Photo by Coolcaesar,{' '} @@ -164,18 +164,18 @@ export default function TimelinePage() { body='But the fundamental model stayed the same: humans writing code, humans operating systems, humans in the loop at every step. The cloud made computing elastic, but it was still computing for humans.' delay={0.2} > -

+
Server racks at NERSC -

+

Server racks at NERSC. Photo by Derrick Coetzee,{' '} @@ -202,18 +202,18 @@ export default function TimelinePage() { body='But agents have different needs than humans. They need persistent memory that survives crashes. They need secure execution environments they can't escape. They need real-time communication with other agents and systems.' future > -

{/* CTA */} -
+
The shift is happening now. @@ -277,7 +277,7 @@ export default function TimelinePage() { viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.2 }} href='/agent-os' - className='selection-dark inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md bg-zinc-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-zinc-700' + className='selection-dark inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md bg-white px-4 py-2 text-sm font-medium text-black transition-colors hover:bg-zinc-200' > Explore agentOS diff --git a/website/src/components/marketing/startups/StartupsPage.tsx b/website/src/components/marketing/startups/StartupsPage.tsx index 7f26734939..24d2a38bd8 100644 --- a/website/src/components/marketing/startups/StartupsPage.tsx +++ b/website/src/components/marketing/startups/StartupsPage.tsx @@ -118,62 +118,6 @@ const StartupImageCycler = ({ images }: { images: { src: string; alt: string; mo ); }; -// Demo day dates - update these when new dates are announced -const YC_DEMO_DAY = new Date('2026-03-24T00:00:00-07:00'); -const A16Z_DEMO_DAY = new Date('2026-04-14T00:00:00-07:00'); - -function getTimeRemaining(targetDate: Date) { - const now = new Date(); - const diff = targetDate.getTime() - now.getTime(); - - if (diff <= 0) return null; - - const totalHours = Math.floor(diff / (1000 * 60 * 60)); - const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); - const seconds = Math.floor((diff % (1000 * 60)) / 1000); - - return { totalHours, minutes, seconds }; -} - -function DemoCountdown() { - const [ycCountdown, setYcCountdown] = useState(getTimeRemaining(YC_DEMO_DAY)); - const [a16zCountdown, setA16zCountdown] = useState(getTimeRemaining(A16Z_DEMO_DAY)); - - useEffect(() => { - const interval = setInterval(() => { - setYcCountdown(getTimeRemaining(YC_DEMO_DAY)); - setA16zCountdown(getTimeRemaining(A16Z_DEMO_DAY)); - }, 1000); - - return () => clearInterval(interval); - }, []); - - const formatCountdown = (countdown: { totalHours: number; minutes: number; seconds: number } | null) => { - if (!countdown) return 'Passed'; - const h = String(countdown.totalHours).padStart(2, '0'); - const m = String(countdown.minutes).padStart(2, '0'); - const s = String(countdown.seconds).padStart(2, '0'); - return `${h}:${m}:${s}`; - }; - - return ( -
- {ycCountdown && ( -
- YC Demo Day - {formatCountdown(ycCountdown)} -
- )} - {a16zCountdown && ( -
- a16z Demo Day - {formatCountdown(a16zCountdown)} -
- )} -
- ); -} - interface CollapsibleSectionProps { title: string; children: React.ReactNode; @@ -190,7 +134,7 @@ function CollapsibleSection({ title, children, defaultOpen = false }: Collapsibl onClick={() => setIsOpen(!isOpen)} className="flex h-28 w-full items-center justify-between text-left" > -

+

{title}

-

+

Built for Demo Day and Beyond

@@ -304,9 +248,6 @@ export default function StartupsPage({ foundersImage, speedrunImage }: StartupsP {/* Bottom section */}

-
- -
@@ -378,7 +319,7 @@ export default function StartupsPage({ foundersImage, speedrunImage }: StartupsP {/* CTA */}
-

+

Ready to build?

diff --git a/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx b/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx index ce306f6091..fdad3d0130 100644 --- a/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx +++ b/website/src/components/marketing/talk-to-an-engineer/TalkToAnEngineerPageClient.tsx @@ -5,7 +5,7 @@ export default function TalkToAnEngineerPageClient() {
-

+

Talk to an Engineer

diff --git a/website/src/pages/blog/index.astro b/website/src/pages/blog/index.astro index ebdaf729c7..499b27b817 100644 --- a/website/src/pages/blog/index.astro +++ b/website/src/pages/blog/index.astro @@ -1,6 +1,7 @@ --- import { getCollection } from 'astro:content'; import BlogLayout from '@/layouts/BlogLayout.astro'; +import { CATEGORIES } from '@/lib/article'; import { formatTimestamp } from '@/lib/formatDate'; import { getPostImage } from '@/lib/postImage'; import { Icon, faRss } from '@rivet-gg/icons'; @@ -55,7 +56,7 @@ for (const entry of changelogPosts) {

-

Blog

+

Blog

-
+
{blogPosts.map((article) => ( -
+
{article.image && (
@@ -125,6 +126,11 @@ for (const entry of changelogPosts) {
)}
+ {CATEGORIES[article.data.category] && ( + + {CATEGORIES[article.data.category].name} + + )} diff --git a/website/src/pages/support.astro b/website/src/pages/support.astro index 31874d0513..d778b4b056 100644 --- a/website/src/pages/support.astro +++ b/website/src/pages/support.astro @@ -11,10 +11,10 @@ import { Icon, faBook, faComments, faEnvelope } from "@rivet-gg/icons";
-

+

Support

-

+

Get help with Rivet, from troubleshooting to feature requests.

@@ -26,7 +26,7 @@ import { Icon, faBook, faComments, faEnvelope } from "@rivet-gg/icons";
Date: Fri, 12 Jun 2026 10:23:32 -0700 Subject: [PATCH 06/25] [SLOP(claude-fable-5)] feat(website): enterprise page, self-hosted compare entry, and on-prem cookbook guide --- website/src/components/Footer.jsx | 1 + website/src/components/v2/Header.tsx | 38 ++- .../src/content/cookbook/vpc-air-gapped.mdx | 132 ++++++++ website/src/data/compare/index.ts | 3 +- website/src/data/compare/self-hosted.tsx | 305 ++++++++++++++++++ website/src/data/cookbook/covers.ts | 9 + website/src/pages/enterprise.astro | 186 +++++++++++ 7 files changed, 658 insertions(+), 16 deletions(-) create mode 100644 website/src/content/cookbook/vpc-air-gapped.mdx create mode 100644 website/src/data/compare/self-hosted.tsx create mode 100644 website/src/pages/enterprise.astro diff --git a/website/src/components/Footer.jsx b/website/src/components/Footer.jsx index 4b9509b6b8..a52b992a21 100644 --- a/website/src/components/Footer.jsx +++ b/website/src/components/Footer.jsx @@ -25,6 +25,7 @@ const footer = { { name: "Sandbox Agent SDK", href: "https://sandboxagent.dev" }, { name: "Secure Exec SDK", href: "https://secureexec.dev" }, { name: "Cloud Pricing", href: "/cloud#pricing" }, + { name: "Enterprise", href: "/enterprise" }, { name: "Talk to an engineer", href: "/talk-to-an-engineer" }, { name: "Sales", href: "/sales" }, ], diff --git a/website/src/components/v2/Header.tsx b/website/src/components/v2/Header.tsx index 56dca16763..5ae90cbfd2 100644 --- a/website/src/components/v2/Header.tsx +++ b/website/src/components/v2/Header.tsx @@ -47,14 +47,16 @@ function TextNavItem({ ariaCurrent, }: TextNavItemProps) { return ( -
+
- + {children} @@ -132,10 +134,7 @@ function ProductsDropdown({ return (
@@ -145,9 +144,9 @@ function ProductsDropdown({ - ); - })} + + ); + })} +
-
+ {/* Text content below */}
- - Built-In Observability - + +

Built-In Observability

+ Debugging and monitoring for actors and agents, from local development to production at scale. @@ -138,11 +148,11 @@ export const ObservabilitySection = () => { whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: idx * 0.1 }} - className='border-t border-white/10 py-6 pr-8' + className='border-t border-ink/10 py-6 pr-8' > -
{feat.icon}
-

{feat.title}

-

{feat.description}

+
{feat.icon}
+

{feat.title}

+

{feat.description}

))}
diff --git a/website/src/components/marketing/sections/OnPremSection.tsx b/website/src/components/marketing/sections/OnPremSection.tsx index 2e30b080a5..4d87620102 100644 --- a/website/src/components/marketing/sections/OnPremSection.tsx +++ b/website/src/components/marketing/sections/OnPremSection.tsx @@ -1,7 +1,10 @@ 'use client'; import { motion } from 'framer-motion'; -import { ArrowRight, Ban, Check } from 'lucide-react'; +import { ArrowRight, Check } from 'lucide-react'; +import { SECTION_H2_CLASS, SUBTITLE_CLASS } from '../typography'; +import { Eyebrow } from '../editorial/Eyebrow'; +import { PerimeterDiagram } from '../editorial/PerimeterDiagram'; const points = [ 'Air-gapped and on-prem: no outbound calls, no telemetry leaving your boundary', @@ -9,55 +12,26 @@ const points = [ 'FedRAMP, HIPAA, sovereign clouds: stay inside the boundary your controls already cover', ]; -const diagramNodes = [ - { title: 'Your backend', detail: 'Actors run in your Node.js or Bun process' }, - { title: 'Rivet Engine', detail: 'Single binary for orchestration and routing' }, - { title: 'Your storage', detail: 'File system, Postgres, or FoundationDB' }, -]; - -const PerimeterDiagram = () => ( -
- - Your perimeter - -
- {diagramNodes.map((node, idx) => ( -
- {idx > 0 &&
} -
-
{node.title}
-
{node.detail}
-
-
- ))} -
-
- - No outbound connections. No telemetry. -
-
-); - export const OnPremSection = () => ( -
+
- - Run it where your data lives. - + +

Run it where your data lives.

+ A single binary you control. Deploy Rivet inside your VPC, your customer’s VPC, or fully air-gapped, with the compliance you already have. @@ -69,9 +43,9 @@ export const OnPremSection = () => ( className='mt-8 space-y-4' > {points.map((point) => ( -
  • - - +
  • + + {point}
  • @@ -86,14 +60,14 @@ export const OnPremSection = () => ( >
    Talk to an engineer Rivet for Enterprise diff --git a/website/src/components/marketing/sections/ProductSplitSection.tsx b/website/src/components/marketing/sections/ProductSplitSection.tsx index bfb8272195..c3c372897e 100644 --- a/website/src/components/marketing/sections/ProductSplitSection.tsx +++ b/website/src/components/marketing/sections/ProductSplitSection.tsx @@ -2,6 +2,8 @@ import { Database, Globe, Infinity, Layers, Wifi, GitBranch, ListOrdered, Clock, Shield, FolderOpen, Code, ArrowRight } from 'lucide-react'; import { motion } from 'framer-motion'; +import { SECTION_H2_CLASS, SUBTITLE_CLASS } from '../typography'; +import { Eyebrow } from '../editorial/Eyebrow'; import agentosLogoUrl from '@/images/products/agentos-logo.svg'; const actorFeatures = [ @@ -120,27 +122,27 @@ const ProductCard = ({ icon, title, tagline, docsHref, detailsHref, features, de whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay }} - className='flex flex-col rounded-xl border border-white/10 bg-white/[0.03] p-6 md:p-8' + className='flex flex-col border border-ink/10 bg-white/55 p-6 md:p-8' >
    {icon} -

    {title}

    +

    {title}

    -

    +

    {tagline}

    Documentation Details @@ -153,10 +155,10 @@ const ProductCard = ({ icon, title, tagline, docsHref, detailsHref, features, de return (
    - - {feature.title} + + {feature.title}
    -

    {feature.description}

    +

    {feature.description}

    ); })} @@ -165,31 +167,31 @@ const ProductCard = ({ icon, title, tagline, docsHref, detailsHref, features, de ); export const ProductSplitSection = () => ( -
    +
    - - Two products, one platform. - + +

    Two products, one platform.

    + Rivet Actors give agents and realtime apps durable, stateful compute in your existing Node.js or Bun backend. agentOS gives agents a portable OS to run in. Use them alone or together.
    } + icon={} title='Actors' tagline='The primitive for stateful workloads.' docsHref='/docs' diff --git a/website/src/components/marketing/sections/RedesignedCTA.tsx b/website/src/components/marketing/sections/RedesignedCTA.tsx index 384226dd1f..66df46410e 100644 --- a/website/src/components/marketing/sections/RedesignedCTA.tsx +++ b/website/src/components/marketing/sections/RedesignedCTA.tsx @@ -2,10 +2,41 @@ import { motion } from 'framer-motion'; import { AnimatedCTATitle } from '../components/AnimatedCTATitle'; +import { Spirograph } from '../art/Spirograph'; + +// Warm oil-paint texture behind the closing band. Ships with the site so the +// colophon never depends on external assets; the veil keeps text readable +// even if the image fails to load. +const OIL_TEXTURE_SRC = '/images/textures/oil-olive-landscape.jpg'; export const RedesignedCTA = () => ( -
    -
    +
    + {/* Oil-paint backdrop under a darkening veil */} +