Menu

Change language

GitHub repo

Pricing — Per-Plan Comparison

blockmarketing

Plan-first comparison that renders each plan as its own card of included and excluded capabilities, the layout a wide matrix should degrade to on a phone.

Installation

$npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/pricing-matrix-plan-cards.json
Manifest:https://uipkge.dev/r/svelte/pricing-matrix-plan-cards.jsonInstalls to:src/lib/components/blocks/pricing-matrix-plan-cards/

Variants

Loading interactive previews…

Files installed (1)

  • src/lib/components/blocks/pricing-matrix-plan-cards/PricingMatrixPlanCards.svelte3.6 kB
    <script lang="ts">
      import { Check, Minus } from '@lucide/svelte'
      import { Badge } from '$lib/components/ui/badge'
      import { Button } from '$lib/components/ui/button'
      import { Card, CardContent } from '$lib/components/ui/card'
      import { Separator } from '$lib/components/ui/separator'
      import { cn } from '$lib/utils'
    
      // One capability list, three plans referencing it by index — a capability can
      // never appear on one card and silently vanish from another.
      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.',
        },
      ]
    </script>
    
    <section data-slot="pricing-matrix-plan-cards" class="bg-background">
      <div class="mx-auto max-w-6xl px-6 py-20 lg:py-28">
        <div class="max-w-2xl">
          <Badge variant="secondary">Plans</Badge>
          <h2 class="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl">What each plan actually includes</h2>
          <p class="text-muted-foreground mt-3 text-lg">
            The same list on every card, with what is missing shown rather than omitted.
          </p>
        </div>
    
        <div class="mt-10 grid gap-4 lg:grid-cols-3">
          {#each plans as plan (plan.name)}
            <Card class={cn('featured' in plan && plan.featured && 'border-primary')}>
              <CardContent class="flex h-full flex-col p-6">
                <div class="flex items-center justify-between gap-3">
                  <p class="text-sm font-semibold">{plan.name}</p>
                  {#if 'featured' in plan && plan.featured}
                    <Badge variant="secondary">Most chosen</Badge>
                  {/if}
                </div>
    
                <p class="font-display mt-4 text-3xl font-bold tracking-tight">{plan.price}</p>
                <p class="text-muted-foreground mt-1 text-xs">{plan.cadence}</p>
                <p class="text-muted-foreground mt-3 text-sm leading-relaxed">{plan.note}</p>
    
                <Separator class="my-5" />
    
                <ul class="space-y-2.5">
                  {#each capabilities as capability, index (capability)}
                    <li
                      class={cn(
                        'flex items-start gap-2.5 text-sm',
                        plan.included.includes(index) ? '' : 'text-muted-foreground/60',
                      )}
                    >
                      {#if plan.included.includes(index)}
                        <Check class="text-success mt-0.5 size-4 shrink-0" aria-hidden="true" />
                      {:else}
                        <Minus class="text-muted-foreground/40 mt-0.5 size-4 shrink-0" aria-hidden="true" />
                      {/if}
                      <span>{capability}</span>
                    </li>
                  {/each}
                </ul>
    
                <Button
                  variant={'featured' in plan && plan.featured ? 'default' : 'outline'}
                  class="mt-auto pt-0 [&]:mt-8"
                >
                  {plan.name === 'Enterprise' ? 'Talk to us' : `Start on ${plan.name}`}
                </Button>
              </CardContent>
            </Card>
          {/each}
        </div>
      </div>
    </section>
    

Raw manifest:https://uipkge.dev/r/svelte/pricing-matrix-plan-cards.json