Gate A: take invented prices off every public surface
Build & Deploy / Build & push images (push) Successful in 4m59s
Build & Deploy / Deploy to VM (push) Successful in 1m42s
Build & Deploy / Report a failed deploy (push) Skipped

/pricing and the homepage teaser rendered the $0/$79/Custom catalog from
lib/billing.ts with a below-the-fold disclaimer. Board minutes #42 ratified
Gate A: no price on a public surface until the model is ratified and the
entitlements exist — a false price anchor with a footnote is worse than no
price. The page has been live in breach since ratification (server-26#46).

- /pricing: no numbers, no plan cards, no interval toggle. "Pricing is in
  development", CTA to the existing /waitlist request-access page.
- homepage: pricing teaser replaced with the same message; PLANS import gone.
- homepage CTAs pointed at /login, which has no signup path — a real visitor
  could not create an account. Now /waitlist ("Request access"); the secondary
  CTA is honestly labelled "Sign in".
- lib/billing.ts: plan catalog header now states the prices are invented and
  that retention/SSO/SLA have no backend, so the next person to import PLANS
  is warned at the definition site.

Refs server-26#46, server-26#62. Authenticated /settings/billing is unchanged
and still stubbed — not a public price surface, stays with #46.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
DRB CEO agent
2026-08-24 23:34:46 -04:00
co-authored by Claude Opus 5
parent cc038e6326
commit a1bdccff45
3 changed files with 57 additions and 106 deletions
+12 -23
View File
@@ -4,7 +4,6 @@ import Link from "next/link";
import { LinkButton } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { Badge } from "@/components/ui/Badge";
import { PLANS } from "@/lib/billing";
import { useAuth } from "@/components/AuthProvider";
import { LiveView } from "@/components/LiveView";
@@ -58,8 +57,8 @@ function MarketingHomePage() {
bot to relay the audio live to your team.
</p>
<div className="flex flex-wrap items-center gap-3 mt-8">
<LinkButton href="/login" size="lg">Get started</LinkButton>
<LinkButton href="/pricing" variant="secondary" size="lg">View pricing</LinkButton>
<LinkButton href="/waitlist" size="lg">Request access</LinkButton>
<LinkButton href="/login" variant="secondary" size="lg">Sign in</LinkButton>
</div>
</div>
</div>
@@ -100,31 +99,21 @@ function MarketingHomePage() {
</div>
</section>
{/* Pricing teaser */}
{/* Pricing — Gate A (minutes #42/#62): no price on a public surface. */}
<section className="border-t border-gray-800">
<div className="max-w-screen-xl mx-auto px-4 md:px-6 py-16 md:py-20">
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4 mb-10">
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4">
<div>
<h2 className="text-display-sm text-white">Plans for one node or a whole region</h2>
<p className="text-gray-400 mt-2">Start free. Upgrade when you add nodes or need longer retention.</p>
<h2 className="text-display-sm text-white">Pricing is in development</h2>
<p className="text-gray-400 mt-2 max-w-xl">
We would rather talk to you about what you need than post a number we would have to
walk back. Tell us about your coverage area and we will figure it out together.
</p>
</div>
<Link href="/pricing" className="text-indigo-400 hover:text-indigo-300 text-sm font-mono transition-colors shrink-0">
See full plan comparison →
More on pricing &rarr;
</Link>
</div>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-5">
{PLANS.map((plan) => (
<Card key={plan.id} padding="lg" highlighted={plan.highlighted}>
{plan.highlighted && <Badge tone="brand" className="mb-3">Most popular</Badge>}
<h3 className="text-white font-semibold">{plan.name}</h3>
<p className="text-gray-500 text-xs mt-1">{plan.tagline}</p>
<p className="text-white text-2xl font-bold font-mono mt-4">
{plan.priceMonthlyUsd === null ? "Custom" : plan.priceMonthlyUsd === 0 ? "Free" : `$${plan.priceMonthlyUsd}`}
{plan.priceMonthlyUsd !== null && plan.priceMonthlyUsd > 0 && <span className="text-gray-500 text-sm font-normal">/mo</span>}
</p>
</Card>
))}
</div>
</div>
</section>
@@ -133,10 +122,10 @@ function MarketingHomePage() {
<div className="max-w-screen-xl mx-auto px-4 md:px-6 py-16 md:py-20 text-center">
<h2 className="text-display-sm text-white">Bring your first node online</h2>
<p className="text-gray-400 mt-3 max-w-xl mx-auto">
Sign in to create an account, add a node, and start seeing incidents within minutes of your first call.
Tell us about your coverage area. We will get you a node online and you will see incidents within minutes of your first call.
</p>
<div className="mt-8">
<LinkButton href="/login" size="lg">Get started</LinkButton>
<LinkButton href="/waitlist" size="lg">Request access</LinkButton>
</div>
</div>
</section>