From de19cf9bae7492c79e124ddac5726797209f2452 Mon Sep 17 00:00:00 2001 From: Molecule AI Marketing Lead Date: Fri, 24 Apr 2026 03:11:43 +0000 Subject: [PATCH] fix(canvas): apply flat-rate pricing copy for Phase 34 launch (Issue #1833) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename "Starter" → "Team", update tagline + pricing page hero copy to lead with flat-rate per-org positioning — deliberate wedge against Cursor/Windsurf per-seat pricing ($40/seat vs $29/org). PMM decision: Issue #1833. Approved by Marketing Lead 2026-04-24. Co-Authored-By: Claude Sonnet 4.6 --- canvas/src/app/pricing/page.tsx | 14 +++++++++----- .../components/__tests__/PricingTable.test.tsx | 10 +++++----- canvas/src/lib/billing.ts | 18 ++++++++++++------ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/canvas/src/app/pricing/page.tsx b/canvas/src/app/pricing/page.tsx index 061a7e60..a7327793 100644 --- a/canvas/src/app/pricing/page.tsx +++ b/canvas/src/app/pricing/page.tsx @@ -14,7 +14,7 @@ import { PricingTable } from "@/components/PricingTable"; export const metadata = { title: "Pricing — Molecule AI", description: - "Free while you tinker, paid tiers for shipping production multi-agent organizations. Transparent usage-based overage pricing on Pro.", + "Flat-rate team and org pricing — no per-seat fees. Free to start, $29/month for teams, $99/month for production orgs. Full runtime stack included on every paid tier.", }; export default function PricingPage() { @@ -25,9 +25,12 @@ export default function PricingPage() { Pricing

- Free while you tinker. Pay when you ship real agents to production. - Every tier includes the full runtime stack — you upgrade for scale, - support, and dedicated infrastructure. + One flat price per org — not per seat. Every paid tier includes the + full runtime stack. You upgrade for scale, support, and dedicated + infrastructure. +

+

+ 5-person team? You pay $29/month — not $200. No seat math, ever.

@@ -53,7 +56,8 @@ export default function PricingPage() { .

- Prices shown in USD. Enterprise / self-hosted licensing available — contact us. + Prices shown in USD. Flat-rate per org — no per-seat fees on any paid tier. + Enterprise / self-hosted licensing available — contact us.

diff --git a/canvas/src/components/__tests__/PricingTable.test.tsx b/canvas/src/components/__tests__/PricingTable.test.tsx index af5faec0..919dc788 100644 --- a/canvas/src/components/__tests__/PricingTable.test.tsx +++ b/canvas/src/components/__tests__/PricingTable.test.tsx @@ -50,14 +50,14 @@ describe("PricingTable", () => { it("renders all three plans with their CTAs", () => { render(); expect(screen.getByRole("heading", { name: "Free" })).toBeTruthy(); - expect(screen.getByRole("heading", { name: "Starter" })).toBeTruthy(); - expect(screen.getByRole("heading", { name: "Pro" })).toBeTruthy(); + expect(screen.getByRole("heading", { name: "Team" })).toBeTruthy(); + expect(screen.getByRole("heading", { name: "Growth" })).toBeTruthy(); expect(screen.getByRole("button", { name: "Get started" })).toBeTruthy(); - expect(screen.getByRole("button", { name: "Upgrade to Starter" })).toBeTruthy(); - expect(screen.getByRole("button", { name: "Upgrade to Pro" })).toBeTruthy(); + expect(screen.getByRole("button", { name: "Upgrade to Team" })).toBeTruthy(); + expect(screen.getByRole("button", { name: "Upgrade to Growth" })).toBeTruthy(); }); - it("shows the 'Most popular' badge only on the starter card", () => { + it("shows the 'Most popular' badge only on the Team card", () => { render(); const badges = screen.getAllByText("Most popular"); expect(badges.length).toBe(1); diff --git a/canvas/src/lib/billing.ts b/canvas/src/lib/billing.ts index c9260e61..b258a56a 100644 --- a/canvas/src/lib/billing.ts +++ b/canvas/src/lib/billing.ts @@ -32,6 +32,10 @@ export interface Plan { // plans is the canonical order shown on the pricing page: free → starter // → pro. Change the order here + the rendered columns follow. Keeping // this as a module-level const so tests can assert against a known list. +// +// Flat-rate positioning (Issue #1833): "starter" and "pro" are flat-rate +// per-org, not per-seat. This is a deliberate wedge against Cursor/Windsurf +// ($40/seat) — at 5 engineers the Team tier is 28% cheaper. export const plans: Plan[] = [ { id: "free", @@ -48,8 +52,8 @@ export const plans: Plan[] = [ }, { id: "starter", - name: "Starter", - tagline: "For small teams shipping real agents", + name: "Team", + tagline: "Flat-rate for teams — one price, no per-seat fees", price: "$29/month", features: [ "10 workspaces", @@ -57,14 +61,15 @@ export const plans: Plan[] = [ "Private Upstash Redis namespace", "Email support (48h)", "5M LLM tokens / month included", + "No per-seat pricing", ], - ctaLabel: "Upgrade to Starter", + ctaLabel: "Upgrade to Team", highlighted: true, }, { id: "pro", - name: "Pro", - tagline: "For production multi-agent orgs", + name: "Growth", + tagline: "Flat-rate for production multi-agent orgs", price: "$99/month", features: [ "Unlimited workspaces", @@ -72,9 +77,10 @@ export const plans: Plan[] = [ "Cross-workspace A2A audit log", "Priority support (24h)", "25M LLM tokens / month included", + "No per-seat pricing", "Usage-based overage billing", ], - ctaLabel: "Upgrade to Pro", + ctaLabel: "Upgrade to Growth", }, ];