
3D Extruded Buildings & Urban Footprints
Real-world 3D building extrusions with dynamic sunlight shadows, terrain DEM elevations, and pitch/bearing camera controls.
Pricing collection with eleven interchangeable variants: seat matrix, interactive calculator, enterprise SLA card, feature add-on builder, feature tier slider, grouped matrix, per-plan cards, sticky-header matrix, single plan, tier comparison matrix, and usage calculator slider.
Also available for Vue ->$pnpm dlx shadcn@latest add https://uipkge.dev/r/react/pricing.json$npx shadcn@latest add https://uipkge.dev/r/react/pricing.json$yarn dlx shadcn@latest add https://uipkge.dev/r/react/pricing.json$bunx shadcn@latest add https://uipkge.dev/r/react/pricing.jsonnpx shadcn@latest add @uipkge-react/pricingInstalls to:components/blocks/pricing/Type aliases exported from this item's source. Use these to shape the data you pass in.
RequestTierinterface RequestTier {
label: string
requests: number
cost: number
}StorageTierinterface StorageTier {
label: string
gb: number
cost: number
}SlaGuaranteeinterface SlaGuarantee {
title: string
metric: string
description: string
icon: string
}ComplianceCertinterface ComplianceCert {
id: string
name: string
status: string
badgeVariant?: 'default' | 'outline' | 'secondary'
}PricingPlaninterface PricingPlan {
id: string
name: string
monthlyPrice: number
description: string
includedSeats: number
}PricingAddoninterface PricingAddon {
id: string
name: string
monthlyPrice: number
description: string
category: string
}Planinterface Plan {
id: string
name: string
description: string
monthlyPrice: number
annualPrice: number
highlight: boolean
badge?: string
ctaText: string
ctaVariant: 'default' | 'outline' | 'secondary'
}FeatureComparisonRowinterface FeatureComparisonRow {
category: string
features: {
name: string
tooltip: string
community: boolean | string
pro: boolean | string
enterprise: boolean | string
}[]
}'use client'
import * as React from 'react'
import { ArrowRight, Check, ChevronDown, ChevronUp, ShieldCheck, Users, Zap } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Slider } from '@/components/ui/slider'
import { Switch } from '@/components/ui/switch'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
import { cn } from '@/lib/utils'
type BillingCycle = 'monthly' | 'yearly'
type Currency = 'USD' | 'EUR' | 'GBP'
const currencySymbols: Record<Currency, string> = {
USD: '$',
EUR: '€',
GBP: '£',
}
const currencyRates: Record<Currency, number> = {
USD: 1.0,
EUR: 0.92,
GBP: 0.79,
}
const comparisonMatrix = [
{
category: 'Platform & Compute Core',
features: [
{ name: 'Active Team Members', starter: 'Up to 10', team: 'Unlimited', enterprise: 'Unlimited + Org Units' },
{ name: 'Monthly API Requests', starter: '100,000 / mo', team: '2,500,000 / mo', enterprise: 'Custom Unlimited' },
{ name: 'Workflow Automations', starter: '10 active', team: '100 active', enterprise: 'Unlimited real-time' },
{ name: 'Data Retention History', starter: '30 days', team: '365 days', enterprise: '7 years immutable' },
],
},
{
category: 'Security & Enterprise Governance',
features: [
{
name: 'SOC 2 Type II & ISO 27001',
starter: 'Standard',
team: 'Included',
enterprise: 'Included + Auditor Portal',
},
{ name: 'SAML SSO & SCIM Provisioning', starter: '—', team: 'Google / Okta', enterprise: 'Custom IdP + SCIM v2' },
{
name: 'Role-Based Access (RBAC)',
starter: '3 predefined roles',
team: 'Granular permissions',
enterprise: 'Custom policy engine',
},
{
name: 'Immutable Audit Trail Logs',
starter: '—',
team: '90 days exportable',
enterprise: 'Real-time SIEM streaming',
},
],
},
{
category: 'Support & Success SLAs',
features: [
{
name: 'Support Channel',
starter: 'Community & Email',
team: 'Priority Email + Chat',
enterprise: 'Dedicated Private Slack',
},
{
name: 'First-Response SLA',
starter: '24 business hours',
team: '4 business hours',
enterprise: '< 15 mins (24/7/365)',
},
{ name: 'Uptime SLA Guarantee', starter: '99.9%', team: '99.95%', enterprise: '99.99% financially backed' },
{ name: 'Dedicated Solutions Architect', starter: '—', team: '—', enterprise: 'Assigned Principal Engineer' },
],
},
]
export function Pricing01({ className }: { className?: string }) {
const [billingCycle, setBillingCycle] = React.useState<BillingCycle>('yearly')
const [currency, setCurrency] = React.useState<Currency>('USD')
const [teamSeats, setTeamSeats] = React.useState<number[]>([12])
const [addDedicatedSla, setAddDedicatedSla] = React.useState(false)
const [addAuditVault, setAddAuditVault] = React.useState(false)
const [showComparisonTable, setShowComparisonTable] = React.useState(false)
const rates = currencyRates[currency]
const sym = currencySymbols[currency]
const starterBase = billingCycle === 'yearly' ? 12 : 15
const teamBase = billingCycle === 'yearly' ? 28 : 35
const enterpriseBase = billingCycle === 'yearly' ? 68 : 85
const slaCost = addDedicatedSla ? 99 : 0
const vaultCost = addAuditVault ? 49 : 0
const currentSeats = teamSeats[0] || 1
const starterMonthlyTotal = Math.round((starterBase * currentSeats + (addAuditVault ? 29 : 0)) * rates)
const teamMonthlyTotal = Math.round((teamBase * currentSeats + slaCost + vaultCost) * rates)
const enterpriseMonthlyTotal = Math.round((enterpriseBase * currentSeats + slaCost + vaultCost) * rates)
const annualSavingsTeam = Math.round((35 * currentSeats * 12 - 28 * currentSeats * 12) * rates)
return (
<section data-slot="pricing-01" className={cn('bg-background w-full py-16 sm:py-24', className)}>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="mx-auto max-w-3xl space-y-4 text-center">
<div className="border-primary/20 bg-primary/5 text-primary inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs font-medium shadow-2xs">
<ShieldCheck className="size-3.5" />
<span>Predictable Enterprise Pricing</span>
</div>
<h2 className="text-foreground text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
Scale effortlessly without seat tax surprises
</h2>
<p className="text-muted-foreground text-base sm:text-lg">
Zero setup fees, transparent volume discounts, and instant self-serve provisioning. Switch or cancel plans
anytime.
</p>
{/* Billing Cycle & Currency Switcher Toolbar */}
<div className="mt-8 flex flex-wrap items-center justify-center gap-4 pt-2">
{/* Monthly vs Yearly */}
<div className="border-border bg-card inline-flex rounded-lg border p-1 shadow-2xs">
<ToggleGroup
type="single"
value={billingCycle}
onValueChange={(v) => v && setBillingCycle(v as BillingCycle)}
>
<ToggleGroupItem value="monthly" className="px-3.5 py-1.5 text-xs font-medium">
Monthly
</ToggleGroupItem>
<ToggleGroupItem value="yearly" className="flex items-center gap-1.5 px-3.5 py-1.5 text-xs font-medium">
<span>Annual</span>
<Badge
variant="secondary"
className="bg-primary/10 text-primary border-primary/20 px-1.5 py-0 text-xs"
>
Save 20%
</Badge>
</ToggleGroupItem>
</ToggleGroup>
</div>
{/* Currency Selector */}
<div className="border-border bg-card inline-flex rounded-lg border p-1 shadow-2xs">
<ToggleGroup type="single" value={currency} onValueChange={(v) => v && setCurrency(v as Currency)}>
<ToggleGroupItem value="USD" className="px-2.5 py-1 font-mono text-xs font-medium">
USD ($)
</ToggleGroupItem>
<ToggleGroupItem value="EUR" className="px-2.5 py-1 font-mono text-xs font-medium">
EUR (€)
</ToggleGroupItem>
<ToggleGroupItem value="GBP" className="px-2.5 py-1 font-mono text-xs font-medium">
GBP (£)
</ToggleGroupItem>
</ToggleGroup>
</div>
</div>
{/* Interactive Team Seat Simulator Bar */}
<div className="border-border bg-card/60 mx-auto mt-6 max-w-xl rounded-xl border p-4 shadow-2xs backdrop-blur-xs">
<div className="flex flex-wrap items-center justify-between gap-2 text-xs">
<div className="text-foreground flex items-center gap-2 font-medium">
<Users className="text-primary size-4" />
<span>Simulate Team Size:</span>
</div>
<div className="flex items-center gap-2">
<span className="bg-muted text-foreground rounded px-2 py-0.5 font-mono text-xs font-semibold">
{currentSeats} {currentSeats === 1 ? 'seat' : 'seats'}
</span>
{billingCycle === 'yearly' && annualSavingsTeam > 0 && (
<span className="text-success text-xs font-medium">
(Saves ~{sym}
{annualSavingsTeam.toLocaleString()}/yr on Team plan)
</span>
)}
</div>
</div>
<div className="mt-3">
<Slider
value={teamSeats}
onValueChange={setTeamSeats}
min={1}
max={50}
step={1}
className="cursor-pointer"
/>
</div>
<div className="text-muted-foreground mt-2 flex justify-between font-mono text-xs">
<span>1 seat</span>
<span>25 seats</span>
<span>50+ seats</span>
</div>
</div>
</div>
{/* Plan Cards Grid */}
<div className="mt-12 grid grid-cols-1 gap-8 lg:grid-cols-3 lg:items-stretch">
{/* Tier 1: Starter */}
<Card className="border-border bg-card hover:border-primary/40 relative flex flex-col justify-between shadow-xs transition-colors duration-200 hover:shadow-md">
<div>
<CardHeader className="pb-4">
<div className="flex items-center justify-between">
<Badge variant="outline" className="font-mono text-xs">
Bootstrap & Indie
</Badge>
</div>
<CardTitle className="text-foreground text-xl font-bold tracking-tight">Starter Studio</CardTitle>
<CardDescription className="text-muted-foreground text-xs">
For agile squads and early-stage product teams validating core workflows.
</CardDescription>
<div className="mt-6 space-y-1">
<div className="flex items-baseline gap-1.5">
<span className="text-foreground text-4xl font-bold tracking-tight">
{sym}
{Math.round(starterBase * rates)}
</span>
<span className="text-muted-foreground text-xs font-medium">/ seat / month</span>
</div>
<div className="text-muted-foreground font-mono text-xs">
Est. {sym}
{starterMonthlyTotal.toLocaleString()}/mo for {currentSeats} {currentSeats === 1 ? 'seat' : 'seats'}
</div>
</div>
</CardHeader>
<CardContent className="space-y-4 pt-2">
<Separator />
<div className="space-y-2.5">
<p className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
Included features
</p>
<ul className="text-foreground space-y-2.5 text-xs">
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Up to 10 team seats & unlimited guests</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>100,000 monthly API event calls</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>30-day continuous audit & revision history</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Standard Community & Email support (24h)</span>
</li>
<li className="text-muted-foreground flex items-start gap-2">
<Check className="text-muted-foreground/50 mt-0.5 size-4 shrink-0" />
<span>Community Discord access & quickstarts</span>
</li>
</ul>
</div>
</CardContent>
</div>
<CardFooter className="border-border mt-auto border-t pt-4">
<Button variant="outline" className="h-10 w-full gap-1.5 text-xs font-semibold">
<span>Start Free 14-Day Trial</span>
<ArrowRight className="size-3.5" />
</Button>
</CardFooter>
</Card>
{/* Tier 2: Team Pro (Highlighted Flagship) */}
<Card className="border-primary bg-card ring-primary/20 relative flex flex-col justify-between shadow-lg ring-2 transition-colors duration-200 hover:shadow-xl lg:-translate-y-2">
<div className="absolute -top-3.5 left-1/2 -translate-x-1/2">
<Badge className="bg-primary text-primary-foreground gap-1.5 px-3 py-0.5 text-xs font-semibold shadow-sm">
<Zap className="size-3 fill-current" />
<span>Most Popular Choice</span>
</Badge>
</div>
<div>
<CardHeader className="pt-7 pb-4">
<div className="flex items-center justify-between">
<Badge variant="secondary" className="bg-primary/10 text-primary border-primary/20 font-mono text-xs">
Scale & High-Growth
</Badge>
</div>
<CardTitle className="text-foreground text-2xl font-bold tracking-tight">Team Scale</CardTitle>
<CardDescription className="text-muted-foreground text-xs">
For fast-scaling engineering and product organizations requiring deep automation.
</CardDescription>
<div className="mt-6 space-y-1">
<div className="flex items-baseline gap-1.5">
<span className="text-foreground text-4xl font-bold tracking-tight">
{sym}
{Math.round(teamBase * rates)}
</span>
<span className="text-muted-foreground text-xs font-medium">/ seat / month</span>
</div>
<div className="text-primary font-mono text-xs font-medium">
Est. {sym}
{teamMonthlyTotal.toLocaleString()}/mo for {currentSeats} {currentSeats === 1 ? 'seat' : 'seats'}
</div>
</div>
</CardHeader>
<CardContent className="space-y-4 pt-2">
<Separator />
<div className="space-y-2.5">
<p className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
Everything in Starter, plus
</p>
<ul className="text-foreground space-y-2.5 text-xs">
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span className="font-medium">Unlimited team seats & custom workspace roles</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>2.5M monthly API calls & priority queue</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Google & Okta SAML SSO integration</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>365-day immutable compliance logs</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Priority ticketing with 4h guaranteed SLA</span>
</li>
</ul>
</div>
{/* Addons Selector for Team */}
<div className="border-border bg-muted/30 space-y-2.5 rounded-lg border p-3">
<p className="text-foreground text-xs font-semibold">Optional Power Add-ons</p>
<div className="flex items-center justify-between text-xs">
<label htmlFor="react-sla-addon" className="text-muted-foreground cursor-pointer">
24/7 Dedicated SLA (+{sym}
{Math.round(99 * rates)}/mo)
</label>
<Switch id="react-sla-addon" checked={addDedicatedSla} onCheckedChange={setAddDedicatedSla} />
</div>
<div className="flex items-center justify-between text-xs">
<label htmlFor="react-vault-addon" className="text-muted-foreground cursor-pointer">
SOC 2 Vault Streaming (+{sym}
{Math.round(49 * rates)}/mo)
</label>
<Switch id="react-vault-addon" checked={addAuditVault} onCheckedChange={setAddAuditVault} />
</div>
</div>
</CardContent>
</div>
<CardFooter className="border-border mt-auto border-t pt-4">
<Button className="h-10 w-full gap-1.5 text-xs font-semibold shadow-sm">
<span>Deploy Team Workspace</span>
<ArrowRight className="size-3.5" />
</Button>
</CardFooter>
</Card>
{/* Tier 3: Enterprise Platform */}
<Card className="border-border bg-card hover:border-primary/40 relative flex flex-col justify-between shadow-xs transition-colors duration-200 hover:shadow-md">
<div>
<CardHeader className="pb-4">
<div className="flex items-center justify-between">
<Badge variant="outline" className="font-mono text-xs">
Enterprise & Security
</Badge>
</div>
<CardTitle className="text-foreground text-xl font-bold tracking-tight">Enterprise Suite</CardTitle>
<CardDescription className="text-muted-foreground text-xs">
Dedicated infrastructure, custom security controls, and bespoke compliance SLAs.
</CardDescription>
<div className="mt-6 space-y-1">
<div className="flex items-baseline gap-1.5">
<span className="text-foreground text-4xl font-bold tracking-tight">
{sym}
{Math.round(enterpriseBase * rates)}
</span>
<span className="text-muted-foreground text-xs font-medium">/ seat / month</span>
</div>
<div className="text-muted-foreground font-mono text-xs">
Custom volume licensing available for 100+ seats
</div>
</div>
</CardHeader>
<CardContent className="space-y-4 pt-2">
<Separator />
<div className="space-y-2.5">
<p className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
Everything in Team, plus
</p>
<ul className="text-foreground space-y-2.5 text-xs">
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Custom SCIM v2 user provisioning & directory sync</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Dedicated VPC peering & custom data residency</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>99.99% uptime SLA with financial penalty backing</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Assigned Principal Solutions Engineer & private Slack</span>
</li>
<li className="flex items-start gap-2">
<Check className="text-success mt-0.5 size-4 shrink-0" />
<span>Custom Master Service Agreement (MSA) & DPA</span>
</li>
</ul>
</div>
</CardContent>
</div>
<CardFooter className="border-border mt-auto border-t pt-4">
<Button variant="outline" className="h-10 w-full gap-1.5 text-xs font-semibold">
<ShieldCheck className="text-primary size-3.5" />
<span>Contact Solutions Team</span>
</Button>
</CardFooter>
</Card>
</div>
{/* Collapsible Feature Matrix Trigger */}
<div className="mt-12 text-center">
<Button
variant="ghost"
size="sm"
className="text-foreground hover:bg-muted gap-2 text-xs font-semibold"
onClick={() => setShowComparisonTable(!showComparisonTable)}
>
<span>
{showComparisonTable ? 'Hide Detailed Feature Comparison' : 'Compare All Features & Enterprise Limits'}
</span>
{showComparisonTable ? <ChevronUp className="size-4" /> : <ChevronDown className="size-4" />}
</Button>
</div>
{/* Feature Comparison Matrix Table */}
{showComparisonTable && (
<div className="border-border bg-card mt-8 overflow-hidden rounded-xl border shadow-xs">
<div className="border-border bg-muted/20 flex flex-wrap items-center justify-between gap-4 border-b p-4 sm:p-6">
<div>
<h3 className="text-foreground text-base font-bold">Detailed Specification & Limits</h3>
<p className="text-muted-foreground text-xs">Comprehensive side-by-side breakdown across every tier.</p>
</div>
<Badge variant="outline" className="font-mono text-xs">
All plans include SSL & automated backups
</Badge>
</div>
<div className="overflow-x-auto">
<Table>
<TableHeader>
<TableRow className="bg-muted/40">
<TableHead className="text-foreground w-[34%] text-xs font-semibold">Capabilities</TableHead>
<TableHead className="text-foreground w-[22%] text-xs font-semibold">Starter Studio</TableHead>
<TableHead className="text-primary w-[22%] text-xs font-bold font-semibold">Team Scale</TableHead>
<TableHead className="text-foreground w-[22%] text-xs font-semibold">Enterprise Suite</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{comparisonMatrix.map((group, idx) => (
<React.Fragment key={idx}>
<TableRow className="bg-muted/60 text-muted-foreground text-xs font-semibold">
<TableCell colSpan={4} className="py-2.5 font-mono text-xs tracking-wider uppercase">
{group.category}
</TableCell>
</TableRow>
{group.features.map((feat, fIdx) => (
<TableRow key={fIdx} className="text-xs">
<TableCell className="text-foreground py-3 font-medium">{feat.name}</TableCell>
<TableCell className="text-muted-foreground py-3">{feat.starter}</TableCell>
<TableCell className="text-foreground bg-primary/5 py-3 font-medium">{feat.team}</TableCell>
<TableCell className="text-foreground py-3">{feat.enterprise}</TableCell>
</TableRow>
))}
</React.Fragment>
))}
</TableBody>
</Table>
</div>
</div>
)}
</div>
</section>
)
}
'use client'
import * as React from 'react'
import { ArrowRight, Check, HardDrive, Headphones, KeyRound, ShieldCheck, Users, Zap } from 'lucide-react'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Slider } from '@/components/ui/slider'
import { Switch } from '@/components/ui/switch'
interface RequestTier {
label: string
requests: number
cost: number
}
interface StorageTier {
label: string
gb: number
cost: number
}
const REQUEST_TIERS: RequestTier[] = [
{ label: '10K requests', requests: 10_000, cost: 0 },
{ label: '50K requests', requests: 50_000, cost: 25 },
{ label: '100K requests', requests: 100_000, cost: 60 },
{ label: '250K requests', requests: 250_000, cost: 120 },
{ label: '500K requests', requests: 500_000, cost: 220 },
{ label: '1M requests', requests: 1_000_000, cost: 400 },
{ label: '2.5M requests', requests: 2_500_000, cost: 750 },
{ label: '5M requests', requests: 5_000_000, cost: 1200 },
]
const STORAGE_TIERS: StorageTier[] = [
{ label: '100 GB', gb: 100, cost: 10 },
{ label: '250 GB', gb: 250, cost: 25 },
{ label: '500 GB', gb: 500, cost: 45 },
{ label: '1 TB', gb: 1_000, cost: 80 },
{ label: '2 TB', gb: 2_000, cost: 150 },
{ label: '5 TB', gb: 5_000, cost: 320 },
{ label: '10 TB', gb: 10_000, cost: 580 },
]
const SEAT_PRICE = 15
const SUPPORT_MANAGER_PRICE = 200
const CUSTOM_SLA_PRICE = 500
const SSO_PRICE = 100
const SEAT_MARKS = {
1: '1',
25: '25',
50: '50',
75: '75',
100: '100',
}
const REQUEST_MARKS = {
0: '10K',
2: '100K',
4: '500K',
7: '5M',
}
const STORAGE_MARKS = {
0: '100 GB',
2: '500 GB',
4: '2 TB',
6: '10 TB',
}
export function PricingCalculator({ className }: { className?: string }) {
const [isAnnual, setIsAnnual] = React.useState(true)
const [seats, setSeats] = React.useState(12)
const [requestIndex, setRequestIndex] = React.useState(2)
const [storageIndex, setStorageIndex] = React.useState(2)
const [addonSupport, setAddonSupport] = React.useState(false)
const [addonSla, setAddonSla] = React.useState(false)
const [addonSso, setAddonSso] = React.useState(true)
const currentRequestTier = REQUEST_TIERS[requestIndex] ?? REQUEST_TIERS[0]
const currentStorageTier = STORAGE_TIERS[storageIndex] ?? STORAGE_TIERS[0]
const seatTier = React.useMemo(() => {
if (seats <= 5) return { label: 'Starter Team', variant: 'secondary' as const }
if (seats <= 25) return { label: 'Growth Team', variant: 'outline' as const }
return { label: 'Scale Team', variant: 'default' as const }
}, [seats])
const recommendedPlan = React.useMemo(() => {
if (addonSla || requestIndex >= 6 || storageIndex >= 5 || seats >= 30) {
return { name: 'Enterprise', badge: 'Enterprise Plan', baseFee: 199, variant: 'default' as const }
}
if (seats >= 8 || requestIndex >= 3 || storageIndex >= 3 || addonSupport) {
return { name: 'Growth', badge: 'Growth Plan', baseFee: 79, variant: 'default' as const }
}
return { name: 'Starter', badge: 'Starter Plan', baseFee: 29, variant: 'secondary' as const }
}, [addonSla, requestIndex, storageIndex, seats, addonSupport])
const baseCost = recommendedPlan.baseFee
const seatsCost = seats * SEAT_PRICE
const requestsCost = currentRequestTier.cost
const storageCost = currentStorageTier.cost
const addonsCost =
(addonSupport ? SUPPORT_MANAGER_PRICE : 0) + (addonSla ? CUSTOM_SLA_PRICE : 0) + (addonSso ? SSO_PRICE : 0)
const activeAddonsCount = (addonSupport ? 1 : 0) + (addonSla ? 1 : 0) + (addonSso ? 1 : 0)
const subtotalMonthly = baseCost + seatsCost + requestsCost + storageCost + addonsCost
const discountMultiplier = isAnnual ? 0.8 : 1.0
const totalMonthly = Math.round(subtotalMonthly * discountMultiplier)
const totalAnnual = totalMonthly * 12
const annualSavings = Math.round(subtotalMonthly * 0.2 * 12)
return (
<div
data-slot="pricing-calculator"
className={cn('mx-auto w-full max-w-6xl space-y-10 p-4 sm:p-6 lg:p-8', className)}
>
<div className="flex flex-col items-center gap-4 text-center">
<Badge variant="outline" className="gap-1.5 px-3 py-1 text-xs font-medium tracking-wider uppercase">
<ShieldCheck className="text-primary size-3.5" />
Pricing Calculator
</Badge>
<div className="space-y-2">
<h2 className="text-foreground text-2xl font-bold tracking-tight sm:text-3xl lg:text-4xl">
Interactive Pricing Calculator
</h2>
<p className="text-muted-foreground mx-auto max-w-2xl text-sm sm:text-base">
Calculate your exact monthly or annual investment based on usage.
</p>
</div>
<div className="border-border bg-card mt-2 inline-flex items-center gap-3 rounded-full border px-4 py-2 shadow-xs">
<span
className={cn(
'text-xs font-medium transition-colors',
!isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground',
)}
>
Monthly
</span>
<Switch checked={isAnnual} onCheckedChange={setIsAnnual} />
<span
className={cn(
'text-xs font-medium transition-colors',
isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground',
)}
>
Pay Annually
</span>
<Badge variant="secondary" className="bg-primary/10 text-primary border-primary/20 text-xs font-semibold">
Save 20%
</Badge>
</div>
</div>
<div className="grid grid-cols-1 gap-8 lg:grid-cols-12 lg:items-start">
<div className="space-y-6 lg:col-span-7">
<Card>
<CardHeader>
<CardTitle>Capacity & Scale</CardTitle>
<CardDescription>Configure team seats, API request throughput, and dedicated storage.</CardDescription>
</CardHeader>
<CardContent className="space-y-8">
<div className="space-y-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2.5">
<div className="bg-primary/10 text-primary border-primary/20 flex size-8 shrink-0 items-center justify-center rounded-md border">
<Users className="size-4" />
</div>
<div>
<span className="text-foreground text-sm font-medium">Team Seats</span>
<Badge variant={seatTier.variant} className="ml-2 text-xs font-normal">
{seatTier.label}
</Badge>
</div>
</div>
<div className="text-right">
<span className="text-foreground text-base font-semibold tabular-nums">{seats}</span>
<span className="text-muted-foreground text-xs"> seats (${seats * SEAT_PRICE}/mo)</span>
</div>
</div>
<div className="pb-6">
<Slider
value={[seats]}
min={1}
max={100}
step={1}
marks={SEAT_MARKS}
tooltip={(val) => `${val} seats`}
onValueChange={(val) => setSeats(val[0])}
/>
</div>
<p className="text-muted-foreground text-xs">
Full workspace access, fine-grained permission controls, and audit log tracking for each member.
</p>
</div>
<Separator />
<div className="space-y-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2.5">
<div className="bg-primary/10 text-primary border-primary/20 flex size-8 shrink-0 items-center justify-center rounded-md border">
<Zap className="size-4" />
</div>
<div>
<span className="text-foreground text-sm font-medium">Monthly API Requests</span>
</div>
</div>
<div className="text-right">
<span className="text-foreground text-base font-semibold tabular-nums">
{currentRequestTier.label}
</span>
<span className="text-muted-foreground text-xs">
{' '}
({currentRequestTier.cost === 0 ? 'Included' : `+$${currentRequestTier.cost}/mo`})
</span>
</div>
</div>
<div className="pb-6">
<Slider
value={[requestIndex]}
min={0}
max={REQUEST_TIERS.length - 1}
step={1}
marks={REQUEST_MARKS}
tooltip={(idx) => REQUEST_TIERS[idx]?.label ?? ''}
onValueChange={(val) => setRequestIndex(val[0])}
/>
</div>
<p className="text-muted-foreground text-xs">
Globally distributed edge endpoints, automatic rate limiting, and sub-50ms p99 latency SLA.
</p>
</div>
<Separator />
<div className="space-y-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2.5">
<div className="bg-primary/10 text-primary border-primary/20 flex size-8 shrink-0 items-center justify-center rounded-md border">
<HardDrive className="size-4" />
</div>
<div>
<span className="text-foreground text-sm font-medium">Dedicated Cloud Storage</span>
</div>
</div>
<div className="text-right">
<span className="text-foreground text-base font-semibold tabular-nums">
{currentStorageTier.label}
</span>
<span className="text-muted-foreground text-xs"> (+${currentStorageTier.cost}/mo)</span>
</div>
</div>
<div className="pb-6">
<Slider
value={[storageIndex]}
min={0}
max={STORAGE_TIERS.length - 1}
step={1}
marks={STORAGE_MARKS}
tooltip={(idx) => STORAGE_TIERS[idx]?.label ?? ''}
onValueChange={(val) => setStorageIndex(val[0])}
/>
</div>
<p className="text-muted-foreground text-xs">
Encrypted at rest (AES-256) with multi-region automated replication and daily disaster backups.
</p>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Enterprise Add-ons</CardTitle>
<CardDescription>
Enhance your infrastructure with enterprise compliance, reliability, and support.
</CardDescription>
</CardHeader>
<CardContent className="space-y-3">
<div className="border-border bg-card hover:border-primary/30 flex flex-col justify-between gap-4 rounded-lg border p-4 transition-colors sm:flex-row sm:items-center">
<div className="flex items-start gap-3">
<div className="bg-primary/10 text-primary border-primary/20 mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md border">
<Headphones className="size-4" />
</div>
<div className="space-y-0.5">
<div className="flex items-center gap-2">
<span className="text-foreground text-sm font-medium">Dedicated Support Manager</span>
<Badge variant="outline" className="text-xs font-normal">
+$200/mo
</Badge>
</div>
<p className="text-muted-foreground text-xs">
Direct Slack channel, named technical account manager & 1-hour response SLA.
</p>
</div>
</div>
<div className="flex sm:justify-end">
<Switch checked={addonSupport} onCheckedChange={setAddonSupport} />
</div>
</div>
<div className="border-border bg-card hover:border-primary/30 flex flex-col justify-between gap-4 rounded-lg border p-4 transition-colors sm:flex-row sm:items-center">
<div className="flex items-start gap-3">
<div className="bg-primary/10 text-primary border-primary/20 mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md border">
<ShieldCheck className="size-4" />
</div>
<div className="space-y-0.5">
<div className="flex items-center gap-2">
<span className="text-foreground text-sm font-medium">Custom SLA Guarantee</span>
<Badge variant="outline" className="text-xs font-normal">
+$500/mo
</Badge>
</div>
<p className="text-muted-foreground text-xs">
99.99% uptime guarantee with financial commitments and priority disaster recovery.
</p>
</div>
</div>
<div className="flex sm:justify-end">
<Switch checked={addonSla} onCheckedChange={setAddonSla} />
</div>
</div>
<div className="border-border bg-card hover:border-primary/30 flex flex-col justify-between gap-4 rounded-lg border p-4 transition-colors sm:flex-row sm:items-center">
<div className="flex items-start gap-3">
<div className="bg-primary/10 text-primary border-primary/20 mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md border">
<KeyRound className="size-4" />
</div>
<div className="space-y-0.5">
<div className="flex items-center gap-2">
<span className="text-foreground text-sm font-medium">Single Sign-On (SSO / SAML)</span>
<Badge variant="outline" className="text-xs font-normal">
+$100/mo
</Badge>
</div>
<p className="text-muted-foreground text-xs">
Okta, Azure AD, Google Workspace, and SAML 2.0 enterprise identity integration.
</p>
</div>
</div>
<div className="flex sm:justify-end">
<Switch checked={addonSso} onCheckedChange={setAddonSso} />
</div>
</div>
</CardContent>
</Card>
</div>
<div className="lg:sticky lg:top-8 lg:col-span-5">
<Card className="border-border bg-card shadow-xs">
<CardHeader className="pb-4">
<div className="flex items-center justify-between">
<span className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
Estimated Investment
</span>
<Badge variant={recommendedPlan.variant} className="gap-1 shadow-xs">
{recommendedPlan.name === 'Enterprise' && <ShieldCheck className="size-3" />}
{recommendedPlan.badge}
</Badge>
</div>
<div className="mt-4">
<div className="flex items-baseline gap-1.5">
<span className="text-foreground text-4xl font-bold tracking-tight tabular-nums sm:text-5xl">
${totalMonthly}
</span>
<span className="text-muted-foreground text-sm font-normal"> / month</span>
</div>
{isAnnual ? (
<p className="text-muted-foreground mt-2 text-xs">
Billed annually (${totalAnnual.toLocaleString('en-US')}/yr) ·
<span className="text-success font-semibold">
{' '}
Save ${annualSavings.toLocaleString('en-US')}/yr
</span>
</p>
) : (
<p className="text-muted-foreground mt-2 text-xs">
Billed monthly · Switch to annual to save 20% (${annualSavings.toLocaleString('en-US')}/yr)
</p>
)}
</div>
</CardHeader>
<CardContent className="space-y-4">
<Separator />
<div className="space-y-2.5">
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">Base platform ({recommendedPlan.name})</span>
<span className="font-medium tabular-nums">
${isAnnual ? Math.round(baseCost * 0.8) : baseCost}/mo
</span>
</div>
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">
Team seats ({seats} × ${SEAT_PRICE})
</span>
<span className="font-medium tabular-nums">
${isAnnual ? Math.round(seatsCost * 0.8) : seatsCost}/mo
</span>
</div>
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">API throughput ({currentRequestTier.label})</span>
<span className="font-medium tabular-nums">
{requestsCost === 0
? 'Included'
: `$${isAnnual ? Math.round(requestsCost * 0.8) : requestsCost}/mo`}
</span>
</div>
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">Cloud storage ({currentStorageTier.label})</span>
<span className="font-medium tabular-nums">
${isAnnual ? Math.round(storageCost * 0.8) : storageCost}/mo
</span>
</div>
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">Add-ons ({activeAddonsCount} active)</span>
<span className="font-medium tabular-nums">
{addonsCost === 0 ? '$0/mo' : `$${isAnnual ? Math.round(addonsCost * 0.8) : addonsCost}/mo`}
</span>
</div>
{isAnnual && (
<div className="bg-success/10 text-success flex items-center justify-between rounded-md px-2.5 py-1.5 text-xs font-medium">
<span>Annual discount applied</span>
<span className="font-semibold tabular-nums">20% off</span>
</div>
)}
</div>
<Separator />
<ul className="text-muted-foreground space-y-2 text-xs">
<li className="flex items-center gap-2">
<Check className="text-primary size-3.5 shrink-0" />
<span>14-day fully featured free trial</span>
</li>
<li className="flex items-center gap-2">
<Check className="text-primary size-3.5 shrink-0" />
<span>No credit card required upfront</span>
</li>
<li className="flex items-center gap-2">
<Check className="text-primary size-3.5 shrink-0" />
<span>Zero-downtime migration assistance</span>
</li>
</ul>
</CardContent>
<CardFooter className="flex flex-col gap-2.5 pt-2">
<Button className="w-full gap-2 font-semibold shadow-xs" size="lg">
Start 14-Day Free Trial
<ArrowRight className="size-4" />
</Button>
<Button variant="outline" className="w-full" size="default">
Request Custom Quote
</Button>
</CardFooter>
</Card>
</div>
</div>
</div>
)
}
'use client'
import * as React from 'react'
import { ArrowRight, Building2, Calendar, CheckCircle2, Lock, Server } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
export interface SlaGuarantee {
title: string
metric: string
description: string
icon: string
}
export interface ComplianceCert {
id: string
name: string
status: string
badgeVariant?: 'default' | 'outline' | 'secondary'
}
export interface PricingEnterpriseSlaCardProps {
title?: string
description?: string
guarantees?: SlaGuarantee[]
certifications?: ComplianceCert[]
className?: string
}
const DEFAULT_GUARANTEES: SlaGuarantee[] = [
{
title: 'High-Availability SLA',
metric: '99.999%',
description: 'Financial penalty-backed monthly uptime commitment across multi-region clusters.',
icon: 'ShieldCheck',
},
{
title: 'P1 Incident Response',
metric: '< 15 mins',
description: 'Direct paging to designated Staff Infrastructure Commanders 24/7/365.',
icon: 'Headphones',
},
{
title: 'Global Edge TTFB',
metric: '< 12ms',
description: 'Sub-15ms Time-To-First-Byte guaranteed via Anycast network mesh.',
icon: 'Zap',
},
{
title: 'Custom Legal & DPA',
metric: 'Bespoke',
description: 'Dedicated legal counsel review, redline allowances, and customized BAAs.',
icon: 'Scale',
},
]
const DEFAULT_CERTS: ComplianceCert[] = [
{ id: 'soc2', name: 'SOC 2 Type II Certified', status: 'Continuous Audit' },
{ id: 'hipaa', name: 'HIPAA Compliant BAA', status: 'Available' },
{ id: 'iso27001', name: 'ISO/IEC 27001:2022', status: 'Certified' },
{ id: 'gdpr', name: 'GDPR & CCPA Verified', status: 'Compliant' },
{ id: 'fedramp', name: 'FedRAMP In-Process', status: 'High Baseline' },
]
export function PricingEnterpriseSlaCard({
title = 'Mission-critical infrastructure with contractual legal guarantees.',
description = 'Tailored enterprise licensing, custom security reviews, isolated VPC deployments, and white-glove migration engineering.',
guarantees = DEFAULT_GUARANTEES,
certifications = DEFAULT_CERTS,
className,
}: PricingEnterpriseSlaCardProps) {
const [isMeetingRequested, setIsMeetingRequested] = React.useState(false)
function requestMeeting() {
setIsMeetingRequested(true)
setTimeout(() => {
setIsMeetingRequested(false)
}, 3000)
}
return (
<section
data-slot="pricing-enterprise-sla-card"
className={cn('bg-background relative overflow-hidden py-16 sm:py-24', className)}
>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="mx-auto max-w-3xl space-y-4 text-center">
<a
href="#enterprise-contract"
className="group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors"
>
<Building2 className="text-primary size-3.5" />
<span>Enterprise Custom Contracting</span>
<ArrowRight className="text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5" />
</a>
<h2 className="text-foreground text-3xl font-bold tracking-tight sm:text-4xl">{title}</h2>
<p className="text-muted-foreground text-base sm:text-lg">{description}</p>
</div>
{/* Main Enterprise Showcase Container */}
<div className="border-border bg-card mt-12 overflow-hidden rounded-2xl border shadow-sm">
<div className="divide-border grid grid-cols-1 divide-y lg:grid-cols-12 lg:divide-x lg:divide-y-0">
{/* Left: SLA Guarantees & Contractual Commitments (7 Cols) */}
<div className="space-y-8 p-8 lg:col-span-7">
<div className="space-y-1">
<div className="text-primary text-xs font-bold tracking-wider uppercase">Service Level Agreement</div>
<h3 className="text-foreground text-xl font-bold">Penalty-Backed Contractual Metrics</h3>
<p className="text-muted-foreground text-xs">
Every commitment is codified into your master service agreement with direct financial remedies.
</p>
</div>
{/* Guarantees 2x2 Grid */}
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
{guarantees.map((item, idx) => (
<div key={idx} className="border-border bg-muted/20 space-y-2 rounded-xl border p-4">
<div className="flex items-center justify-between">
<span className="text-foreground text-xs font-bold">{item.title}</span>
<span className="text-primary font-mono text-xs font-bold">{item.metric}</span>
</div>
<p className="text-muted-foreground text-xs leading-relaxed">{item.description}</p>
</div>
))}
</div>
{/* Compliance & Governance Strip */}
<div className="space-y-3 pt-2">
<div className="text-muted-foreground flex items-center gap-2 text-xs font-bold tracking-wider uppercase">
<Lock className="text-primary size-3.5" />
<span>Security & Regulatory Attestations</span>
</div>
<div className="flex flex-wrap gap-2">
{certifications.map((cert) => (
<Badge
key={cert.id}
variant="outline"
className="border-border bg-background text-foreground gap-1.5 px-3 py-1 text-xs font-medium"
>
<CheckCircle2 className="text-success size-3" />
<span>{cert.name}</span>
<span className="text-muted-foreground font-mono text-xs">({cert.status})</span>
</Badge>
))}
</div>
</div>
</div>
{/* Right: Direct Enterprise Solution Consultation Card (5 Cols) */}
<div className="bg-muted/30 flex flex-col justify-between space-y-6 p-8 lg:col-span-5">
<div className="space-y-4">
<div className="border-border flex items-center justify-between border-b pb-3">
<div className="flex items-center gap-2">
<Server className="text-primary size-4" />
<span className="text-foreground text-sm font-semibold">Custom Private Deployment</span>
</div>
<Badge variant="outline" className="border-success/30 bg-success/10 text-success font-mono text-xs">
Tailored
</Badge>
</div>
<div className="space-y-2.5">
<div className="text-foreground text-xs font-bold">Included with Custom Tier:</div>
<ul className="text-muted-foreground space-y-2 text-xs">
<li className="flex items-center gap-2">
<CheckCircle2 className="text-success size-3.5 shrink-0" />
<span>Dedicated AWS / GCP VPC peering or self-hosted air-gap</span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="text-success size-3.5 shrink-0" />
<span>Custom SAML 2.0 / Okta / Azure AD SCIM provisioning</span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="text-success size-3.5 shrink-0" />
<span>Dedicated Solution Architect & design system migration team</span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="text-success size-3.5 shrink-0" />
<span>Invoiced payment via ACH, Wire Transfer, or AWS Marketplace</span>
</li>
</ul>
</div>
</div>
{/* Action Block */}
<div className="border-border space-y-3 border-t pt-4">
<Button className="w-full gap-2 shadow-xs" size="lg" onClick={requestMeeting}>
<Calendar className="size-4" />
<span>
{isMeetingRequested ? 'Direct Routing to Architect...' : 'Book Enterprise Technical Review'}
</span>
</Button>
<div className="text-muted-foreground text-center text-xs">
Average executive response time: <strong>under 20 minutes</strong>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
)
}
'use client'
import * as React from 'react'
import { ArrowRight, Calculator, Check, CreditCard } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { cn } from '@/lib/utils'
export interface PricingPlan {
id: string
name: string
monthlyPrice: number
description: string
includedSeats: number
}
export interface PricingAddon {
id: string
name: string
monthlyPrice: number
description: string
category: string
}
export interface PricingFeatureAddonBuilderProps {
title?: string
description?: string
plans?: PricingPlan[]
addons?: PricingAddon[]
className?: string
}
const DEFAULT_PLANS: PricingPlan[] = [
{
id: 'starter',
name: 'Starter Tier',
monthlyPrice: 29,
description: 'For indie developers and early-stage prototypes needing unbundled speed.',
includedSeats: 2,
},
{
id: 'growth',
name: 'Growth Core',
monthlyPrice: 99,
description: 'For scaling product engineering teams building high-conversion platforms.',
includedSeats: 5,
},
{
id: 'scale',
name: 'Scale Enterprise',
monthlyPrice: 299,
description: 'For mission-critical production clusters requiring sub-10ms global edge delivery.',
includedSeats: 15,
},
]
const DEFAULT_ADDONS: PricingAddon[] = [
{
id: 'dedicated-ip',
name: 'Dedicated Static Edge IP',
monthlyPrice: 49,
description: 'Static IPv4/IPv6 address allocations with zero-reputation penalty.',
category: 'Network',
},
{
id: 'audit-logs',
name: 'Immutable SOC2 Audit Logs',
monthlyPrice: 79,
description: 'Cryptographically signed telemetry logs with 365-day cold storage retention.',
category: 'Security',
},
{
id: 'multi-region',
name: 'Multi-Region Active-Active Mesh',
monthlyPrice: 129,
description: 'Synchronized cross-continental database replicas and automatic DNS failover.',
category: 'Reliability',
},
{
id: 'priority-sla',
name: '1-Hour Enterprise Response SLA',
monthlyPrice: 199,
description: 'Direct Slack / Discord hotline with senior design engineering staff.',
category: 'Support',
},
]
export function PricingFeatureAddonBuilder({
title = 'Build your custom plan with transparent, zero-surprise pricing.',
description = 'Select your base tier, adjust seat allocations, and toggle modular enterprise add-ons with real-time invoice calculations.',
plans = DEFAULT_PLANS,
addons = DEFAULT_ADDONS,
className,
}: PricingFeatureAddonBuilderProps) {
const [selectedPlanId, setSelectedPlanId] = React.useState('growth')
const [selectedAddonIds, setSelectedAddonIds] = React.useState<string[]>(['dedicated-ip', 'audit-logs'])
const [seatCount, setSeatCount] = React.useState(8)
const [isAnnual, setIsAnnual] = React.useState(true)
const selectedPlan = React.useMemo(() => {
return plans.find((p) => p.id === selectedPlanId) || plans[0]
}, [plans, selectedPlanId])
const extraSeats = React.useMemo(() => {
return Math.max(0, seatCount - selectedPlan.includedSeats)
}, [seatCount, selectedPlan])
const extraSeatCost = React.useMemo(() => extraSeats * 15, [extraSeats])
const totalAddonsCost = React.useMemo(() => {
return addons.filter((a) => selectedAddonIds.includes(a.id)).reduce((sum, a) => sum + a.monthlyPrice, 0)
}, [addons, selectedAddonIds])
const monthlySubtotal = React.useMemo(() => {
return selectedPlan.monthlyPrice + extraSeatCost + totalAddonsCost
}, [selectedPlan, extraSeatCost, totalAddonsCost])
const finalMonthlyRate = React.useMemo(() => {
if (isAnnual) {
return Math.round(monthlySubtotal * 0.8)
}
return monthlySubtotal
}, [isAnnual, monthlySubtotal])
const annualSavings = React.useMemo(() => {
return (monthlySubtotal - Math.round(monthlySubtotal * 0.8)) * 12
}, [monthlySubtotal])
function toggleAddon(addonId: string) {
if (selectedAddonIds.includes(addonId)) {
setSelectedAddonIds(selectedAddonIds.filter((id) => id !== addonId))
} else {
setSelectedAddonIds([...selectedAddonIds, addonId])
}
}
return (
<section
data-slot="pricing-feature-addon-builder"
className={cn('bg-background relative overflow-hidden py-16 sm:py-24', className)}
>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="mx-auto max-w-3xl space-y-4 text-center">
<a
href="#pricing-calculator"
className="group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors"
>
<Calculator className="text-primary size-3.5" />
<span>Real-time Add-on Cost Synthesizer</span>
<ArrowRight className="text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5" />
</a>
<h2 className="text-foreground text-3xl font-bold tracking-tight sm:text-4xl">{title}</h2>
<p className="text-muted-foreground text-base sm:text-lg">{description}</p>
{/* Billing Cadence Toggle */}
<div className="flex items-center justify-center gap-3 pt-2">
<span
className={cn(
'text-xs font-medium',
!isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground',
)}
>
Monthly Billing
</span>
<button
type="button"
className={cn(
'focus-visible:ring-ring relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus-visible:ring-2 focus-visible:outline-none',
isAnnual ? 'bg-primary' : 'bg-muted',
)}
onClick={() => setIsAnnual(!isAnnual)}
>
<span
className={cn(
'bg-background pointer-events-none inline-block size-5 transform rounded-full shadow-lg ring-0 transition duration-200 ease-in-out',
isAnnual ? 'translate-x-5' : 'translate-x-0',
)}
/>
</button>
<span
className={cn(
'flex items-center gap-1.5 text-xs font-medium',
isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground',
)}
>
<span>Annual Billing</span>
<Badge variant="outline" className="border-success/30 bg-success/10 text-success text-xs">
Save 20%
</Badge>
</span>
</div>
</div>
{/* Add-on Builder Workbench */}
<div className="mt-12 grid grid-cols-1 gap-6 lg:grid-cols-12">
{/* Left: Plan Selection & Addon Toggles (7 Cols) */}
<div className="space-y-6 lg:col-span-7">
{/* Step 1: Base Tier Cards */}
<div className="space-y-3">
<div className="text-muted-foreground text-xs font-bold tracking-wider uppercase">
Step 1: Choose Base Core Tier
</div>
<div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
{plans.map((plan) => (
<button
key={plan.id}
type="button"
className={cn(
'flex flex-col justify-between rounded-xl border p-4 text-left transition-colors',
selectedPlanId === plan.id
? 'border-primary bg-primary/5 ring-primary/20 shadow-xs ring-1'
: 'border-border bg-card hover:bg-muted/40 text-muted-foreground hover:text-foreground',
)}
onClick={() => setSelectedPlanId(plan.id)}
>
<div>
<div className="text-foreground text-xs font-bold">{plan.name}</div>
<div className="text-foreground mt-1 font-mono text-lg font-bold">
${plan.monthlyPrice}
<span className="text-muted-foreground text-xs font-normal">/mo</span>
</div>
</div>
<div className="text-muted-foreground mt-2 text-xs">
Includes {plan.includedSeats} engineer seats
</div>
</button>
))}
</div>
</div>
{/* Step 2: Seat Allocation Slider */}
<Card className="border-border bg-card/60 shadow-2xs">
<CardContent className="space-y-2.5 p-4">
<div className="flex items-center justify-between text-xs">
<span className="text-foreground font-bold">Engineer Team Seats</span>
<span className="text-foreground font-mono text-sm font-bold">
{seatCount} seats (${extraSeatCost}/mo extra)
</span>
</div>
<input
type="range"
min="2"
max="50"
step="1"
value={seatCount}
onChange={(e) => setSeatCount(parseInt(e.target.value))}
className="accent-primary w-full cursor-pointer"
/>
<div className="text-muted-foreground flex justify-between font-mono text-xs">
<span>2 seats</span>
<span>50 seats</span>
</div>
</CardContent>
</Card>
{/* Step 3: Enterprise Add-ons Checklist */}
<div className="space-y-3">
<div className="text-muted-foreground text-xs font-bold tracking-wider uppercase">
Step 3: Select Modular Capabilities
</div>
<div className="grid grid-cols-1 gap-2.5">
{addons.map((addon) => (
<button
key={addon.id}
type="button"
className={cn(
'flex items-center justify-between rounded-xl border p-3.5 text-left transition-colors',
selectedAddonIds.includes(addon.id)
? 'border-primary/60 bg-primary/5 shadow-2xs'
: 'border-border bg-card hover:bg-muted/30 text-muted-foreground hover:text-foreground',
)}
onClick={() => toggleAddon(addon.id)}
>
<div className="flex min-w-0 items-center gap-3">
<div
className={cn(
'flex size-5 shrink-0 items-center justify-center rounded border transition-colors',
selectedAddonIds.includes(addon.id)
? 'border-primary bg-primary text-primary-foreground'
: 'border-border bg-background',
)}
>
{selectedAddonIds.includes(addon.id) ? <Check className="size-3.5" /> : null}
</div>
<div className="min-w-0 space-y-0.5">
<div className="flex items-center gap-2">
<span className="text-foreground text-xs font-bold">{addon.name}</span>
<Badge variant="outline" className="border-border text-muted-foreground text-xs">
{addon.category}
</Badge>
</div>
<div className="text-muted-foreground truncate text-xs">{addon.description}</div>
</div>
</div>
<div className="text-foreground shrink-0 pl-2 font-mono text-xs font-bold">
+${addon.monthlyPrice}
<span className="text-muted-foreground text-xs font-normal">/mo</span>
</div>
</button>
))}
</div>
</div>
</div>
{/* Right: Real-time Invoice Estimate Card (5 Cols) */}
<div className="lg:col-span-5">
<Card className="border-border bg-card/90 sticky top-8 shadow-md backdrop-blur-xs">
<CardContent className="space-y-6 p-6">
<div className="border-border flex items-center justify-between border-b pb-3">
<div className="flex items-center gap-2">
<CreditCard className="text-primary size-4" />
<span className="text-foreground text-sm font-semibold">Estimated Monthly Invoice</span>
</div>
<Badge variant="outline" className="border-border text-primary font-mono text-xs">
{isAnnual ? 'Annualized' : 'Monthly'}
</Badge>
</div>
{/* Price Breakdown List */}
<div className="space-y-3 text-xs">
<div className="text-muted-foreground flex justify-between">
<span>{selectedPlan.name}</span>
<span className="text-foreground font-mono">${selectedPlan.monthlyPrice}.00</span>
</div>
{extraSeats > 0 ? (
<div className="text-muted-foreground flex justify-between">
<span>Extra Seats ({extraSeats} × $15)</span>
<span className="text-foreground font-mono">${extraSeatCost}.00</span>
</div>
) : null}
{addons
.filter((a) => selectedAddonIds.includes(a.id))
.map((addon) => (
<div key={addon.id} className="text-muted-foreground flex justify-between">
<span className="truncate pr-2">{addon.name}</span>
<span className="text-foreground font-mono">${addon.monthlyPrice}.00</span>
</div>
))}
{isAnnual ? (
<div className="border-border/60 text-success flex justify-between border-t pt-2 font-medium">
<span>Annual Billing Discount (20%)</span>
<span className="font-mono">−${monthlySubtotal - finalMonthlyRate}.00</span>
</div>
) : null}
</div>
{/* Total Sum Band */}
<div className="border-border bg-muted/40 space-y-1 rounded-lg border p-4">
<div className="text-muted-foreground text-xs font-medium">Net Monthly Investment</div>
<div className="flex items-baseline gap-1.5">
<span className="text-foreground font-mono text-3xl font-bold tracking-tight">
${finalMonthlyRate}
</span>
<span className="text-muted-foreground font-mono text-xs">/ month</span>
</div>
{isAnnual ? (
<div className="text-success text-xs font-medium">
Billed annually (${finalMonthlyRate * 12}/yr • Save ${annualSavings}/yr)
</div>
) : null}
</div>
<Button className="w-full gap-2 shadow-xs" size="lg">
<span>Start 14-Day Free Evaluation</span>
<ArrowRight className="size-4" />
</Button>
</CardContent>
</Card>
</div>
</div>
</div>
</section>
)
}
'use client'
import * as React from 'react'
import { ArrowRight, CheckCircle2, Sliders } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { cn } from '@/lib/utils'
export interface PricingFeatureTierSliderProps {
title?: string
description?: string
className?: string
}
const TIERS = [
{
label: '10K MAU',
mauCount: '10,000',
basePriceMonthly: 19,
tierName: 'Starter Hobbyist',
features: [
'10,000 Monthly Users',
'2 Dedicated Edge Locations',
'Community Discord SLA',
'Standard 1-Day Log Retention',
],
},
{
label: '50K MAU',
mauCount: '50,000',
basePriceMonthly: 49,
tierName: 'Pro Creator',
features: [
'50,000 Monthly Users',
'12 Global Anycast Edges',
'Next-Business-Day Support SLA',
'7-Day Immutable Log Retention',
],
},
{
label: '250K MAU',
mauCount: '250,000',
basePriceMonthly: 149,
tierName: 'Growth Scale',
features: [
'250,000 Monthly Users',
'All 36 Global Edge Regions',
'4-Hour Priority Engineering SLA',
'30-Day SOC2 Audit Logs',
],
},
{
label: '1M MAU',
mauCount: '1,000,000',
basePriceMonthly: 399,
tierName: 'Enterprise Core',
features: [
'1,000,000 Monthly Users',
'Dedicated VPC & Multi-Region Mesh',
'15-Minute Critical Incident SLA',
'365-Day Cold Storage Logs',
],
},
{
label: '5M+ MAU',
mauCount: '5,000,000+',
basePriceMonthly: 899,
tierName: 'Hyperscale Cluster',
features: [
'5,000,000+ Monthly Users',
'Custom Bare-Metal Cloud Partitions',
'Dedicated Solutions Architect',
'Custom Security Review & BAA',
],
},
]
export function PricingFeatureTierSlider({
title = 'Predictable usage pricing with dynamic linear scale.',
description = 'Slide to your estimated monthly active users or edge invocations to calculate your exact monthly investment.',
className,
}: PricingFeatureTierSliderProps) {
const [sliderIndex, setSliderIndex] = React.useState(2)
const [isAnnual, setIsAnnual] = React.useState(true)
const currentTier = TIERS[sliderIndex]
const effectivePrice = isAnnual ? Math.round(currentTier.basePriceMonthly * 0.8) : currentTier.basePriceMonthly
const annualSavings = (currentTier.basePriceMonthly - effectivePrice) * 12
return (
<section
data-slot="pricing-feature-tier-slider"
className={cn('bg-background relative overflow-hidden py-16 sm:py-24', className)}
>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="mx-auto max-w-3xl space-y-4 text-center">
<a
href="#scale-pricing"
className="group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors"
>
<Sliders className="text-primary size-3.5" />
<span>Continuous Scale Synthesizer</span>
<ArrowRight className="text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5" />
</a>
<h2 className="text-foreground text-3xl font-bold tracking-tight sm:text-4xl">{title}</h2>
<p className="text-muted-foreground text-base sm:text-lg">{description}</p>
{/* Cadence Switcher */}
<div className="flex items-center justify-center gap-3 pt-2">
<span
className={cn(
'text-xs font-medium',
!isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground',
)}
>
Monthly
</span>
<button
type="button"
className={cn(
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out',
isAnnual ? 'bg-primary' : 'bg-muted',
)}
onClick={() => setIsAnnual(!isAnnual)}
>
<span
className={cn(
'bg-background pointer-events-none inline-block size-5 transform rounded-full shadow-lg ring-0 transition duration-200 ease-in-out',
isAnnual ? 'translate-x-5' : 'translate-x-0',
)}
/>
</button>
<span
className={cn(
'flex items-center gap-1.5 text-xs font-medium',
isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground',
)}
>
<span>Annual Billing</span>
<Badge variant="outline" className="border-success/30 bg-success/10 text-success text-xs">
Save 20%
</Badge>
</span>
</div>
</div>
{/* Pricing Slider Main Card */}
<div className="mx-auto mt-12 max-w-4xl">
<Card className="border-border bg-card overflow-hidden shadow-sm">
<CardContent className="space-y-8 p-8">
{/* Scale Indicator Bar */}
<div className="border-border flex flex-wrap items-center justify-between gap-4 border-b pb-6">
<div className="space-y-1">
<span className="text-muted-foreground text-xs font-bold tracking-wider uppercase">
Calculated Tier Plan
</span>
<h3 className="text-foreground text-2xl font-bold">{currentTier.tierName}</h3>
<div className="text-muted-foreground text-xs">
Engineered for {currentTier.mauCount} active user sessions
</div>
</div>
{/* Price Box */}
<div className="text-right">
<div className="flex items-baseline justify-end gap-1">
<span className="text-foreground font-mono text-4xl font-bold">${effectivePrice}</span>
<span className="text-muted-foreground font-mono text-xs">/ month</span>
</div>
{isAnnual ? (
<div className="text-success font-mono text-xs font-medium">Save ${annualSavings}/yr on annual</div>
) : null}
</div>
</div>
{/* Interactive Stepped Range Slider */}
<div className="space-y-3">
<div className="text-foreground flex items-center justify-between text-xs font-bold">
<span>Monthly Traffic Volume</span>
<span className="text-primary font-mono font-bold">{currentTier.mauCount} Users</span>
</div>
<input
type="range"
min="0"
max="4"
step="1"
value={sliderIndex}
onChange={(e) => setSliderIndex(parseInt(e.target.value))}
className="accent-primary h-2 w-full cursor-pointer"
/>
{/* Slider Step Labels */}
<div className="text-muted-foreground flex justify-between font-mono text-xs">
{TIERS.map((t, idx) => (
<span
key={idx}
className={cn(
'hover:text-foreground cursor-pointer transition-colors',
sliderIndex === idx ? 'text-primary font-bold' : '',
)}
onClick={() => setSliderIndex(idx)}
>
{t.label}
</span>
))}
</div>
</div>
{/* Features Checklist Grid for Current Tier */}
<div className="border-border space-y-3 border-t pt-4">
<span className="text-muted-foreground text-xs font-bold tracking-wider uppercase">
Guaranteed Tier Deliverables
</span>
<div className="grid grid-cols-1 gap-2.5 sm:grid-cols-2">
{currentTier.features.map((feat, fIdx) => (
<div key={fIdx} className="text-foreground flex items-center gap-2 text-xs">
<CheckCircle2 className="text-success size-4 shrink-0" />
<span>{feat}</span>
</div>
))}
</div>
</div>
{/* Action Button */}
<div className="pt-2">
<Button size="lg" className="w-full gap-2 shadow-xs">
<span>Deploy with {currentTier.tierName}</span>
<ArrowRight className="size-4" />
</Button>
</div>
</CardContent>
</Card>
</div>
</div>
</section>
)
}
'use client'
import { useState } from 'react'
import { Check, ChevronDown, Minus } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table'
const plans = ['Team', 'Business', 'Enterprise']
const groups: {
id: string
label: string
summary: string
rows: { feature: string; values: (boolean | string)[] }[]
}[] = [
{
id: 'modelling',
label: 'Modelling',
summary: 'Definitions, versioning, and review',
rows: [
{ feature: 'Certified definitions', values: ['50', '500', 'Unlimited'] },
{ feature: 'Version history', values: ['30 days', 'Unlimited', 'Unlimited'] },
{ feature: 'Required review', values: [false, true, true] },
{ feature: 'Period locking', values: [false, true, true] },
],
},
{
id: 'access',
label: 'Access & identity',
summary: 'Who sees which rows',
rows: [
{ feature: 'SSO (SAML)', values: [true, true, true] },
{ feature: 'SCIM provisioning', values: [false, true, true] },
{ feature: 'Row-level scope', values: [false, true, true] },
{ feature: 'Customer-managed keys', values: [false, false, true] },
],
},
{
id: 'ops',
label: 'Operations',
summary: 'Cost, alerting, and support',
rows: [
{ feature: 'Query budgets', values: [false, true, true] },
{ feature: 'Drift alerting', values: [false, true, true] },
{ feature: 'Audit log export', values: [false, '90 days', 'Unlimited'] },
{ feature: 'Named support engineer', values: [false, false, true] },
],
},
]
export function PricingMatrixGrouped() {
// Opens on the first group only: a fully expanded matrix is the thing readers
// bounce off, and every group is one click from open.
const [open, setOpen] = useState<string[]>([groups[0].id])
const toggle = (id: string) =>
setOpen((current) => (current.includes(id) ? current.filter((entry) => entry !== id) : [...current, id]))
return (
<section data-slot="pricing-matrix-grouped" className="bg-background">
<div className="mx-auto max-w-4xl px-6 py-20 lg:py-28">
<Badge variant="secondary">Compare plans</Badge>
<h2 className="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl">Grouped, so it stays readable</h2>
<Card className="mt-8">
<CardContent className="p-0">
<div className="text-muted-foreground grid grid-cols-[1fr_repeat(3,5rem)] gap-2 px-4 py-3 text-xs font-medium sm:grid-cols-[1fr_repeat(3,7rem)]">
<span>Capability</span>
{plans.map((plan) => (
<span key={plan} className="text-center">
{plan}
</span>
))}
</div>
<Separator />
{groups.map((group) => (
<div key={group.id}>
<button
type="button"
className="hover:bg-muted focus-visible:ring-ring flex w-full items-center gap-3 px-4 py-3 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none"
aria-expanded={open.includes(group.id)}
aria-controls={`group-${group.id}`}
onClick={() => toggle(group.id)}
>
<ChevronDown
className={`text-muted-foreground size-4 shrink-0 transition-transform ${
open.includes(group.id) ? '' : '-rotate-90'
}`}
aria-hidden="true"
/>
<span className="min-w-0">
<span className="block text-sm font-medium">{group.label}</span>
<span className="text-muted-foreground block text-xs">{group.summary}</span>
</span>
<span className="text-muted-foreground ml-auto shrink-0 font-mono text-xs">{group.rows.length}</span>
</button>
{open.includes(group.id) && (
<div id={`group-${group.id}`}>
<Table>
<TableBody>
{group.rows.map((row) => (
<TableRow key={row.feature}>
<TableCell className="pl-11 text-sm">{row.feature}</TableCell>
{row.values.map((value, index) => (
<TableCell key={index} className="w-20 text-center sm:w-28">
{value === true && (
<>
<Check className="text-success mx-auto size-4" aria-hidden="true" />
<span className="sr-only">Included</span>
</>
)}
{value === false && (
<>
<Minus className="text-muted-foreground/50 mx-auto size-4" aria-hidden="true" />
<span className="sr-only">Not included</span>
</>
)}
{typeof value === 'string' && <span className="font-mono text-xs">{value}</span>}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
)}
<Separator />
</div>
))}
</CardContent>
</Card>
<Button className="mt-6">Start on Business</Button>
</div>
</section>
)
}
'use client'
import { Check, Minus } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
const capabilities = [
'Certified metric definitions',
'Connected warehouses',
'Query budget per team',
'Row-level access control',
'SCIM provisioning',
'Audit log export',
'Embedded dashboards',
'Data residency choice',
'Customer-managed keys',
'Named support engineer',
]
const plans = [
{ name: 'Team', price: '$0', cadence: 'while in beta', included: [0, 1], note: 'For one team proving it out.' },
{
name: 'Business',
price: '$1,400',
cadence: 'per month',
included: [0, 1, 2, 3, 4, 5, 6],
note: 'For finance and analytics running together.',
featured: true,
},
{
name: 'Enterprise',
price: 'Custom',
cadence: 'annual',
included: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
note: 'For regulated estates and multi-region.',
},
]
export function PricingMatrixPlanCards() {
return (
<section data-slot="pricing-matrix-plan-cards" className="bg-background">
<div className="mx-auto max-w-6xl px-6 py-20 lg:py-28">
<div className="max-w-2xl">
<Badge variant="secondary">Plans</Badge>
<h2 className="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl">What each plan actually includes</h2>
<p className="text-muted-foreground mt-3 text-lg">
The same list on every card, with what is missing shown rather than omitted.
</p>
</div>
<div className="mt-10 grid gap-4 lg:grid-cols-3">
{plans.map((plan) => (
<Card key={plan.name} className={plan.featured ? 'border-primary' : undefined}>
<CardContent className="flex h-full flex-col p-6">
<div className="flex items-center justify-between gap-3">
<p className="text-sm font-semibold">{plan.name}</p>
{plan.featured && <Badge variant="secondary">Most chosen</Badge>}
</div>
<p className="font-display mt-4 text-3xl font-bold tracking-tight">{plan.price}</p>
<p className="text-muted-foreground mt-1 text-xs">{plan.cadence}</p>
<p className="text-muted-foreground mt-3 text-sm leading-relaxed">{plan.note}</p>
<Separator className="my-5" />
<ul className="space-y-2.5">
{capabilities.map((capability, index) => (
<li
key={capability}
className={`flex items-start gap-2.5 text-sm ${
plan.included.includes(index) ? '' : 'text-muted-foreground/60'
}`}
>
{plan.included.includes(index) ? (
<Check className="text-success mt-0.5 size-4 shrink-0" aria-hidden="true" />
) : (
<Minus className="text-muted-foreground/40 mt-0.5 size-4 shrink-0" aria-hidden="true" />
)}
<span>{capability}</span>
</li>
))}
</ul>
<Button variant={plan.featured ? 'default' : 'outline'} className="mt-auto pt-0 [&]:mt-8">
{plan.name === 'Enterprise' ? 'Talk to us' : `Start on ${plan.name}`}
</Button>
</CardContent>
</Card>
))}
</div>
</div>
</section>
)
}
'use client'
import { Check, Minus } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
const plans = ['Team', 'Business', 'Enterprise']
// Cells are true / false / a string, so a plan can state a limit rather than
// only claiming a feature exists.
const rows: { feature: string; values: (boolean | string)[] }[] = [
{ feature: 'Certified metric definitions', values: ['50', '500', 'Unlimited'] },
{ feature: 'Connected warehouses', values: ['1', '3', 'Unlimited'] },
{ feature: 'Query budget per team', values: [false, true, true] },
{ feature: 'Row-level access control', values: [false, true, true] },
{ feature: 'SCIM provisioning', values: [false, true, true] },
{ feature: 'Audit log export', values: [false, '90 days', 'Unlimited'] },
{ feature: 'Period locking', values: [false, true, true] },
{ feature: 'Embedded dashboards', values: [false, true, true] },
{ feature: 'Data residency choice', values: [false, false, true] },
{ feature: 'Customer-managed keys', values: [false, false, true] },
{ feature: 'Private link', values: [false, false, true] },
{ feature: 'Named support engineer', values: [false, false, true] },
]
export function PricingMatrixStickyHeader() {
return (
<section data-slot="pricing-matrix-sticky-header" className="bg-background">
<div className="mx-auto max-w-4xl px-6 py-20 lg:py-28">
<Badge variant="secondary">Compare plans</Badge>
<h2 className="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl">Every line, no asterisks</h2>
<p className="text-muted-foreground mt-3 text-lg">
Limits differ between plans. Where a plan caps something, the cap is written in the cell.
</p>
<Card className="mt-8">
<CardContent className="p-0">
{/* The header pins with CSS alone. Thirty rows down, a checkmark is
still attributable to a column without scrolling back up. */}
<div className="max-h-[28rem] overflow-auto">
<Table>
<TableHeader className="bg-card sticky top-0 z-10">
<TableRow>
<TableHead className="bg-card">Capability</TableHead>
{plans.map((plan) => (
<TableHead key={plan} className="bg-card text-center">
{plan}
</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{rows.map((row) => (
<TableRow key={row.feature}>
<TableCell className="font-medium">{row.feature}</TableCell>
{row.values.map((value, index) => (
<TableCell key={index} className="text-center">
{value === true && (
<>
<Check className="text-success mx-auto size-4" aria-hidden="true" />
<span className="sr-only">Included</span>
</>
)}
{value === false && (
<>
<Minus className="text-muted-foreground/50 mx-auto size-4" aria-hidden="true" />
<span className="sr-only">Not included</span>
</>
)}
{typeof value === 'string' && <span className="font-mono text-xs">{value}</span>}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
</CardContent>
</Card>
<div className="mt-6 flex flex-wrap gap-3">
<Button>Start on Team</Button>
<Button variant="outline">Talk about Enterprise</Button>
</div>
</div>
</section>
)
}
'use client'
import { ArrowRight, Check, X } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
const included = [
'Unlimited certified metric definitions',
'Unlimited viewers and editors',
'Row-level access from your identity provider',
'Query budgets enforced per team',
'Audit log export, 7-year retention',
'SOC 2 report under NDA',
]
// Naming exclusions is what makes a single plan credible. A list of only
// inclusions invites the reader to assume the gap is hidden somewhere.
const excluded = [
'On-premise deployment behind your firewall',
'Custom SLAs below 99.9%',
'Professional services beyond the five-week rollout',
]
export function PricingSinglePlan() {
return (
<section data-slot="pricing-single-plan" className="bg-background">
<div className="mx-auto max-w-3xl px-6 py-20 lg:py-28">
<div className="text-center">
<Badge variant="secondary">Pricing</Badge>
<h2 className="mt-4 text-3xl font-semibold tracking-tight text-balance sm:text-4xl">One plan, one number</h2>
<p className="text-muted-foreground mt-3 text-lg">
No seat maths and no feature gates. The only thing that scales is query volume.
</p>
</div>
<Card className="mt-10">
<CardContent className="p-8">
<div className="flex flex-wrap items-baseline gap-3">
<span className="font-display text-4xl font-bold tracking-tight">£1,400</span>
<span className="text-muted-foreground">per month, billed annually</span>
</div>
<p className="text-muted-foreground mt-2 text-sm">
Includes 2 million queries a month. Beyond that it is £0.0004 per query, capped by your own budgets.
</p>
<Button size="lg" className="mt-6 w-full sm:w-auto">
Start the 30-day trial
<ArrowRight className="ml-2 size-4" aria-hidden="true" />
</Button>
<Separator className="my-8" />
<p className="text-muted-foreground font-mono text-xs tracking-[0.14em] uppercase">Included</p>
<ul className="mt-3 grid gap-2.5 sm:grid-cols-2">
{included.map((item) => (
<li key={item} className="flex items-start gap-2.5 text-sm">
<Check className="text-success mt-0.5 size-4 shrink-0" aria-hidden="true" />
<span>{item}</span>
</li>
))}
</ul>
<Separator className="my-6" />
<p className="text-muted-foreground font-mono text-xs tracking-[0.14em] uppercase">Not included</p>
<ul className="mt-3 space-y-2.5">
{excluded.map((item) => (
<li key={item} className="flex items-start gap-2.5 text-sm">
<X className="text-muted-foreground/50 mt-0.5 size-4 shrink-0" aria-hidden="true" />
<span className="text-muted-foreground">{item}</span>
</li>
))}
</ul>
<Separator className="my-6" />
<p className="text-muted-foreground text-sm leading-relaxed">
Past roughly 20 million queries a month, or if any of the exclusions above are hard requirements, a
conversation will get you a better answer than this page can.
</p>
<Button variant="outline" className="mt-4">
Talk to us instead
</Button>
</CardContent>
</Card>
</div>
</section>
)
}
'use client'
import * as React from 'react'
import { ArrowRight, Check, Minus, ShieldCheck } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { cn } from '@/lib/utils'
type BillingCycle = 'monthly' | 'annual'
interface Plan {
id: string
name: string
description: string
monthlyPrice: number
annualPrice: number
highlight: boolean
badge?: string
ctaText: string
ctaVariant: 'default' | 'outline' | 'secondary'
}
const plans: Plan[] = [
{
id: 'community',
name: 'Community OSS',
description: 'For indie hackers and developers building open source products.',
monthlyPrice: 0,
annualPrice: 0,
highlight: false,
ctaText: 'Start Building Free',
ctaVariant: 'outline',
},
{
id: 'pro',
name: 'Pro Team',
description: 'For growing startup engineering teams that require high velocity.',
monthlyPrice: 29,
annualPrice: 24,
highlight: true,
badge: 'Most Popular',
ctaText: 'Claim Pro License',
ctaVariant: 'default',
},
{
id: 'enterprise',
name: 'Enterprise Scale',
description: 'Dedicated registry syncing, SSO, SOC2 compliance audits, and SLA.',
monthlyPrice: 119,
annualPrice: 99,
highlight: false,
ctaText: 'Talk to Sales',
ctaVariant: 'outline',
},
]
interface FeatureComparisonRow {
category: string
features: {
name: string
tooltip: string
community: boolean | string
pro: boolean | string
enterprise: boolean | string
}[]
}
const comparisonData: FeatureComparisonRow[] = [
{
category: 'Registry & Core Primitives',
features: [
{
name: 'Full AST Component Source Access',
tooltip: 'Raw SFC and TSX source files copied directly into your repository.',
community: true,
pro: true,
enterprise: true,
},
{
name: 'Dual-Framework Parity (Vue + React)',
tooltip: 'Identical DOM semantics and CVA tokens across both ecosystems.',
community: true,
pro: true,
enterprise: true,
},
{
name: 'Curated Marketing & SaaS Blocks',
tooltip: 'Access to 450+ production-grade unbundled layout blocks.',
community: '100+ Blocks',
pro: 'All 450+ Blocks',
enterprise: 'All Blocks + Custom',
},
{
name: 'Tailwind CSS v4 OKLCH Token System',
tooltip: 'Hardware-calibrated color spaces and spring curves.',
community: true,
pro: true,
enterprise: true,
},
],
},
{
category: 'Enterprise & Security Compliance',
features: [
{
name: 'Private Registry Mirroring',
tooltip: 'Host your organization’s customized internal registry behind a firewall.',
community: false,
pro: '1 Private Repo',
enterprise: 'Unlimited Private Hubs',
},
{
name: 'SOC2 & ISO 27001 Audit Packs',
tooltip: 'Pre-certified security documentation and architecture proofs.',
community: false,
pro: false,
enterprise: true,
},
{
name: 'Guaranteed 99.99% Registry CDN SLA',
tooltip: 'Global multi-region edge distribution uptime guarantee.',
community: false,
pro: '99.9% SLA',
enterprise: '99.99% High Availability',
},
{
name: 'Dedicated Design Engineering Support',
tooltip: 'Direct Slack / Discord channel with core design system maintainers.',
community: false,
pro: 'Priority Email',
enterprise: 'Dedicated Slack Channel',
},
],
},
]
export interface PricingTierComparisonMatrixProps {
className?: string
}
export function PricingTierComparisonMatrix({ className }: PricingTierComparisonMatrixProps) {
const [billing, setBilling] = React.useState<BillingCycle>('annual')
return (
<section
data-slot="pricing-tier-comparison-matrix"
className={cn('bg-background relative overflow-hidden px-4 py-16 sm:px-6 sm:py-24 lg:px-8', className)}
>
<div className="mx-auto max-w-7xl space-y-16">
{/* Header */}
<div className="mx-auto max-w-3xl space-y-4 text-center">
<Badge variant="secondary" className="gap-1.5 px-3 py-1 font-mono text-xs shadow-xs">
<ShieldCheck className="text-primary size-3.5" />
Predictable Pricing
</Badge>
<h2 className="text-foreground text-3xl font-bold tracking-tight sm:text-4xl">
Zero seat taxes. Own your source code forever.
</h2>
<p className="text-muted-foreground text-base">
Choose the tier that fits your engineering team's delivery scale and compliance needs.
</p>
{/* Billing Toggle */}
<div className="flex items-center justify-center gap-3 pt-4">
<span
className={cn(
'font-mono text-xs',
billing === 'monthly' ? 'text-foreground font-bold' : 'text-muted-foreground',
)}
>
Monthly
</span>
<div className="border-border bg-card relative flex items-center rounded-full border p-1">
<button
type="button"
className={cn(
'relative z-10 rounded-full px-3 py-1 font-mono text-xs transition-colors',
billing === 'monthly'
? 'bg-primary text-primary-foreground font-semibold shadow-xs'
: 'text-muted-foreground',
)}
onClick={() => setBilling('monthly')}
>
Monthly
</button>
<button
type="button"
className={cn(
'relative z-10 flex items-center gap-1.5 rounded-full px-3 py-1 font-mono text-xs transition-colors',
billing === 'annual'
? 'bg-primary text-primary-foreground font-semibold shadow-xs'
: 'text-muted-foreground',
)}
onClick={() => setBilling('annual')}
>
<span>Annual</span>
<span className="bg-success rounded-full px-1.5 py-0.5 text-xs font-bold text-white">Save 20%</span>
</button>
</div>
</div>
</div>
{/* Pricing Plan Cards Grid (3 Columns) */}
<div className="grid grid-cols-1 items-stretch gap-6 md:grid-cols-3">
{plans.map((plan) => (
<Card
key={plan.id}
className={cn(
'border-border bg-card relative flex flex-col justify-between space-y-6 rounded-2xl p-6 text-left shadow-xl transition-colors sm:p-8',
plan.highlight
? 'border-primary/80 ring-primary/20 scale-[1.02] shadow-sm ring-2'
: 'hover:border-border/80',
)}
>
{/* Top Badge */}
{plan.badge && (
<div className="absolute -top-3 left-1/2 -translate-x-1/2">
<Badge className="px-3 py-0.5 font-mono text-xs tracking-wider uppercase shadow-md">
{plan.badge}
</Badge>
</div>
)}
<div className="space-y-4">
<div>
<h3 className="text-foreground font-mono text-xl font-bold">{plan.name}</h3>
<p className="text-muted-foreground mt-1 min-h-[36px] text-xs">{plan.description}</p>
</div>
{/* Price display */}
<div className="flex items-baseline gap-1.5 font-mono">
<span className="text-foreground text-4xl font-bold">
${billing === 'annual' ? plan.annualPrice : plan.monthlyPrice}
</span>
<span className="text-muted-foreground text-xs">/ month</span>
</div>
<p className="text-muted-foreground font-mono text-xs">
{billing === 'annual' && plan.annualPrice > 0
? `Billed annually ($${plan.annualPrice * 12}/yr)`
: 'Billed monthly'}
</p>
</div>
<Button variant={plan.ctaVariant} className="h-10 w-full gap-1.5 font-mono text-xs shadow-xs">
<span>{plan.ctaText}</span>
<ArrowRight className="size-3.5" />
</Button>
</Card>
))}
</div>
{/* Deep Feature Comparison Matrix Table */}
<div className="space-y-6">
<div className="text-center">
<h3 className="text-foreground font-mono text-xl font-bold">Detailed Feature Comparison</h3>
<p className="text-muted-foreground mt-1 text-xs">Full granular matrix of capabilities and entitlements.</p>
</div>
<Card className="border-border bg-card overflow-hidden rounded-2xl text-left shadow-sm">
<div className="overflow-x-auto">
<table className="w-full border-collapse text-left text-xs">
<thead>
<tr className="border-border bg-muted/40 text-muted-foreground border-b font-mono">
<th className="w-1/2 p-4 font-semibold">Capability</th>
<th className="p-4 text-center font-semibold">Community</th>
<th className="text-primary p-4 text-center font-bold font-semibold">Pro Team</th>
<th className="p-4 text-center font-semibold">Enterprise</th>
</tr>
</thead>
<tbody>
{comparisonData.map((section, sIdx) => (
<React.Fragment key={sIdx}>
<tr className="bg-muted/20 border-border/80 border-b">
<td
colSpan={4}
className="text-muted-foreground p-3 px-4 font-mono text-xs font-bold tracking-wider uppercase"
>
{section.category}
</td>
</tr>
{section.features.map((row, rIdx) => (
<tr key={rIdx} className="border-border/60 hover:bg-muted/10 border-b transition-colors">
<td className="p-4">
<div className="text-foreground font-medium">{row.name}</div>
<div className="text-muted-foreground mt-0.5 text-xs">{row.tooltip}</div>
</td>
<td className="p-4 text-center font-mono">
{typeof row.community === 'boolean' ? (
row.community ? (
<Check className="text-success mx-auto size-4" />
) : (
<Minus className="text-muted-foreground/40 mx-auto size-4" />
)
) : (
<span className="text-muted-foreground">{row.community}</span>
)}
</td>
<td className="p-4 text-center font-mono font-semibold">
{typeof row.pro === 'boolean' ? (
row.pro ? (
<Check className="text-success mx-auto size-4" />
) : (
<Minus className="text-muted-foreground/40 mx-auto size-4" />
)
) : (
<span className="text-primary">{row.pro}</span>
)}
</td>
<td className="p-4 text-center font-mono">
{typeof row.enterprise === 'boolean' ? (
row.enterprise ? (
<Check className="text-success mx-auto size-4" />
) : (
<Minus className="text-muted-foreground/40 mx-auto size-4" />
)
) : (
<span className="text-foreground font-semibold">{row.enterprise}</span>
)}
</td>
</tr>
))}
</React.Fragment>
))}
</tbody>
</table>
</div>
</Card>
</div>
</div>
</section>
)
}
export default PricingTierComparisonMatrix
'use client'
import * as React from 'react'
import { ArrowRight, Calculator, Globe, Server, Users } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { cn } from '@/lib/utils'
export interface PricingUsageCalculatorSliderProps {
className?: string
}
export function PricingUsageCalculatorSlider({ className }: PricingUsageCalculatorSliderProps) {
const [mau, setMau] = React.useState(100000)
const [qps, setQps] = React.useState(500)
const [edgeReplicas, setEdgeReplicas] = React.useState(3)
const formatNumber = (num: number): string => {
if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M'
if (num >= 1000) return (num / 1000).toFixed(0) + 'k'
return num.toString()
}
const applyPreset = (preset: 'seed' | 'growth' | 'scale') => {
if (preset === 'seed') {
setMau(25000)
setQps(150)
setEdgeReplicas(2)
} else if (preset === 'growth') {
setMau(350000)
setQps(2500)
setEdgeReplicas(5)
} else {
setMau(2500000)
setQps(12000)
setEdgeReplicas(10)
}
}
const traditionalCost = React.useMemo(() => {
const baseSeatFee = 350
const perUserFee = (mau / 1000) * 1.8
const qpsSurcharge = qps * 0.25
return Math.round(baseSeatFee + perUserFee + qpsSurcharge)
}, [mau, qps])
const uipkgeCost = React.useMemo(() => {
const rawBandwidth = (mau / 100000) * 4
const flatProLicense = 24
return Math.round(flatProLicense + rawBandwidth)
}, [mau])
const monthlySavings = Math.max(0, traditionalCost - uipkgeCost)
const annualSavings = monthlySavings * 12
return (
<section
data-slot="pricing-usage-calculator-slider"
className={cn('bg-background relative overflow-hidden px-4 py-16 sm:px-6 sm:py-24 lg:px-8', className)}
>
<div className="mx-auto max-w-6xl space-y-12">
{/* Section Header */}
<div className="mx-auto max-w-3xl space-y-4 text-center">
<Badge variant="secondary" className="gap-1.5 px-3 py-1 font-mono text-xs shadow-xs">
<Calculator className="text-primary size-3.5" />
Interactive Infrastructure ROI Calculator
</Badge>
<h2 className="text-foreground text-3xl font-bold tracking-tight sm:text-4xl">
Calculate your annual savings with unbundled architecture.
</h2>
<p className="text-muted-foreground text-base">
See how eliminating proprietary seat licenses and runtime SaaS wrappers cuts your front-end TCO.
</p>
{/* Presets Bar */}
<div className="flex flex-wrap items-center justify-center gap-2 pt-2">
<Button size="sm" variant="outline" className="font-mono text-xs" onClick={() => applyPreset('seed')}>
Seed Startup (25k MAU)
</Button>
<Button size="sm" variant="outline" className="font-mono text-xs" onClick={() => applyPreset('growth')}>
Growth Scale (350k MAU)
</Button>
<Button size="sm" variant="outline" className="font-mono text-xs" onClick={() => applyPreset('scale')}>
Hypergrowth (2.5M MAU)
</Button>
</div>
</div>
{/* 2-Column Split: Sliders Workbench Left (7 Cols), Savings Scorecard Right (5 Cols) */}
<div className="grid grid-cols-1 items-stretch gap-8 lg:grid-cols-12">
{/* Sliders Controls (7 Cols) */}
<Card className="border-border bg-card/95 flex flex-col justify-between space-y-6 rounded-2xl p-6 text-left shadow-xl sm:p-8 lg:col-span-7">
<div className="space-y-6">
<div className="border-border flex items-center justify-between border-b pb-4">
<h3 className="text-foreground font-mono text-sm font-bold">Traffic & Telemetry Inputs</h3>
<span className="text-muted-foreground font-mono text-xs">Dynamic Projection</span>
</div>
{/* Slider 1: MAU */}
<div className="space-y-2">
<div className="flex items-center justify-between font-mono text-xs">
<span className="text-muted-foreground flex items-center gap-1.5">
<Users className="text-primary size-3.5" /> Monthly Active Users (MAU)
</span>
<span className="text-foreground text-sm font-bold">{formatNumber(mau)} users</span>
</div>
<input
type="range"
min="10000"
max="5000000"
step="25000"
value={mau}
onChange={(e) => setMau(Number(e.target.value))}
className="accent-primary bg-border h-2 w-full cursor-pointer rounded-lg"
/>
</div>
{/* Slider 2: QPS */}
<div className="space-y-2">
<div className="flex items-center justify-between font-mono text-xs">
<span className="text-muted-foreground flex items-center gap-1.5">
<Server className="text-primary size-3.5" /> Peak Query Throughput
</span>
<span className="text-foreground text-sm font-bold">{formatNumber(qps)} QPS</span>
</div>
<input
type="range"
min="100"
max="20000"
step="100"
value={qps}
onChange={(e) => setQps(Number(e.target.value))}
className="accent-primary bg-border h-2 w-full cursor-pointer rounded-lg"
/>
</div>
{/* Slider 3: Global Replicas */}
<div className="space-y-2">
<div className="flex items-center justify-between font-mono text-xs">
<span className="text-muted-foreground flex items-center gap-1.5">
<Globe className="text-primary size-3.5" /> Global Edge POP Replicas
</span>
<span className="text-foreground text-sm font-bold">{edgeReplicas} Edge Regions</span>
</div>
<input
type="range"
min="1"
max="12"
step="1"
value={edgeReplicas}
onChange={(e) => setEdgeReplicas(Number(e.target.value))}
className="accent-primary bg-border h-2 w-full cursor-pointer rounded-lg"
/>
</div>
</div>
<div className="border-border text-muted-foreground flex items-center justify-between border-t pt-4 font-mono text-xs">
<span>Formula: Direct AST + Raw Static Hosting</span>
<span className="text-success font-semibold">✓ Zero Seat Surcharges</span>
</div>
</Card>
{/* ROI Cost & Savings Projection Card (5 Cols) */}
<Card className="border-border bg-card/95 flex flex-col justify-between space-y-6 rounded-2xl p-6 text-left shadow-sm sm:p-8 lg:col-span-5">
<div className="space-y-6">
<Badge variant="outline" className="border-success/20 bg-success/10 text-success font-mono text-xs">
Projected Annual Net Savings
</Badge>
{/* Big Stat Display */}
<div className="space-y-1">
<div className="text-success font-mono text-4xl font-bold tracking-tight sm:text-5xl">
${annualSavings.toLocaleString()}
</div>
<p className="text-muted-foreground font-mono text-xs">
Saved every year (${monthlySavings.toLocaleString()}/month)
</p>
</div>
{/* Comparative Cost Bars */}
<div className="space-y-3 pt-2">
<div className="space-y-1">
<div className="flex items-center justify-between font-mono text-xs">
<span className="text-destructive font-medium">Traditional Monolith Stack:</span>
<span className="text-foreground font-bold">${traditionalCost.toLocaleString()}/mo</span>
</div>
<div className="bg-destructive/20 h-2 overflow-hidden rounded-full">
<div className="bg-destructive h-full w-full" />
</div>
</div>
<div className="space-y-1">
<div className="flex items-center justify-between font-mono text-xs">
<span className="text-success font-semibold">UIPKGE Unbundled Registry:</span>
<span className="text-foreground font-bold">${uipkgeCost.toLocaleString()}/mo</span>
</div>
<div className="bg-success/20 h-2 overflow-hidden rounded-full">
<div
className="bg-success h-full transition-[width] duration-300"
style={{ width: `${Math.max(5, (uipkgeCost / traditionalCost) * 100)}%` }}
/>
</div>
</div>
</div>
</div>
<Button className="mt-4 h-10 w-full gap-1.5 font-mono text-xs shadow-md">
<span>Lock In Pro Savings</span>
<ArrowRight className="size-3.5" />
</Button>
</Card>
</div>
</div>
</section>
)
}
export default PricingUsageCalculatorSlider
Raw manifest:https://uipkge.dev/r/react/pricing.json