import { type CatalogTier, catalogTiers, formatPlanPrice, formatTierPrice, type Plan, plans, } from '@shared/pricing'; import { IconArrowRight as ArrowRight, IconCheck as Check, IconX as X } from '@tabler/icons-react'; import { Link } from 'react-router'; import { Nav } from '@/components/Nav'; import { SEO } from '@/components/SEO'; import FooterSection from '@/components/sections/footer'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; interface PricingCardProps { name: string; description: string | null; price: string; /** Feature rows. Catalog tiers are all included; demo plans mark exclusions. */ features: { text: string; included: boolean }[]; ctaLabel: string; popular?: boolean; } function PricingCard({ name, description, price, features, ctaLabel, popular = false, }: PricingCardProps) { return (
{popular && (
Most popular
)}

{name}

{description &&

{description}

}
{price}
); } /** Cap the column count at the number of cards so 1–2 tiers don't stretch oddly. */ const gridColsByCount: Record = { 1: 'sm:max-w-md sm:mx-auto', 2: 'sm:grid-cols-2 sm:max-w-3xl sm:mx-auto', 3: 'sm:grid-cols-2 lg:grid-cols-3', 4: 'sm:grid-cols-2 lg:grid-cols-4', }; export default function Pricing() { const useCatalog = catalogTiers.length > 0; const count = useCatalog ? catalogTiers.length : plans.length; const gridCols = gridColsByCount[Math.min(count, 4)] ?? 'sm:grid-cols-2 lg:grid-cols-4'; return (
); }