# Pricing 3

> pricing

A shadcn/ui block from the [@cnippet-blocks](https://blocks.cnippet.dev/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/cnippet-blocks/pricing-3).

- Page, with a live preview: https://shadcn.exchange/r/cnippet-blocks/pricing-3
- Screenshot: https://shadcn.exchange/shot/cnippet-blocks/pricing-3/light.png
- Registry item: https://blocks.cnippet.dev/r/pricing-3.json
- Categories: pricing
- Listed: 2026-11-01, source last changed 2026-11-01

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/cnippet-blocks/pricing-3.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`
- Registry items: `@cnippet/button`, `@cnippet/utils`

## Files

### `registry/default/sections/pricing-3.tsx`

```tsx
"use client";

import { Check } from "lucide-react";
import * as React from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

// Decorative rainbow stripe
function RainbowStripe({ className }: { className?: string }) {
  return (
    <svg className={cn("h-16 w-12", className)} viewBox="0 0 60 80">
      <path d="M10 0 L50 80" fill="none" stroke="#e53935" strokeWidth="8" />
      <path d="M18 0 L58 80" fill="none" stroke="#fdd835" strokeWidth="8" />
      <path d="M26 0 L66 80" fill="none" stroke="#43a047" strokeWidth="8" />
      <path d="M34 0 L74 80" fill="none" stroke="#1e88e5" strokeWidth="8" />
    </svg>
  );
}

const plans = [
  {
    featured: false,
    featureGroups: [
      {
        items: [
          "1 free guided meditation monthly",
          "Seasonal wellness tips via email",
          "Community forum access",
        ],
        title: "Features:",
      },
      {
        items: ["Access to 3 yoga classes (pre-recorded)"],
        title: "Classes:",
      },
    ],
    id: "gentle",
    isPrice: false,
    name: "Gentle Start",
    price: "Free-forever",
    subtitle: "Begin with Curiosity",
    tagColor: "text-[#2a7d5f]",
  },
  {
    featured: true,
    featureGroups: [
      {
        items: [
          "2 live sessions weekly",
          "10% off retreats & workshops",
          "Exclusive member community",
          "Free downloadable guides",
          "SSO & enhanced security",
        ],
        title: "Features:",
      },
      {
        items: ["Unlimited on-demand classes"],
        title: "Classes:",
      },
    ],
    id: "mindful",
    name: "Mindful Flow",
    period: "/mo (billed annually)",
    price: 19,
    spotsLeft: 8,
    subtitle: "Begin with Curiosity",
    tagColor: "text-[#c9463d]",
  },
  {
    featured: false,
    featureGroups: [
      {
        items: [
          "Unlimited 1:1 virtual check-ins",
          "25% off wellness products",
          "Gift a membership at 50% off",
          "Custom wellness plans",
          "VIP sessions + global summit access",
          "2 guest passes/month",
        ],
        title: "Features:",
      },
      {
        items: [
          "Access to 3 yoga classes (pre-recorded)",
          "Advanced & offline class access",
        ],
        title: "Classes:",
      },
    ],
    id: "unlimited",
    name: "Unlimited Serenity",
    period: "/mo (billed annually)",
    price: 29,
    subtitle: "Deepen Your Journey",
    tagColor: "text-[#c9463d]",
  },
];

export function Pricing3() {
  const [billing, setBilling] = React.useState<"monthly" | "yearly">("monthly");

  return (
    <section className="w-full bg-[#f7f5ef] py-16 md:py-24">
      <div className="mx-auto w-full max-w-6xl px-6">
        {/* Header */}
        <div className="mb-10 text-center">
          <span className="mb-4 block text-gray-600 text-sm dark:text-gray-400">
            Pricing Tiers
          </span>
          <h2 className="mb-2 font-serif text-4xl text-gray-900 leading-tight md:text-5xl dark:text-gray-100">
            Nurture Your Practice,
          </h2>
          <div className="relative inline-block">
            <span className="font-serif text-4xl text-[#c9463d] italic md:text-5xl">
              Your Budget
            </span>
            {/* Underline decoration */}
            <svg
              className="absolute -bottom-2 left-0 h-3 w-full"
              fill="none"
              viewBox="0 0 200 12"
            >
              <path
                d="M2 8 Q50 2 100 8 Q150 14 198 6"
                fill="none"
                stroke="#c9463d"
                strokeLinecap="round"
                strokeWidth="2"
              />
            </svg>
          </div>
        </div>

        {/* Billing Toggle */}
        <div className="mb-12 flex justify-center">
          <div className="inline-flex rounded-full border border-neutral-300 bg-white p-1">
            <button
              className={cn(
                "rounded-full px-6 py-2 font-medium text-sm transition-colors",
                billing === "monthly"
                  ? "bg-white text-gray-900 shadow-sm dark:text-gray-100"
                  : "text-gray-600 dark:text-gray-400",
              )}
              onClick={() => setBilling("monthly")}
            >
              Monthly
            </button>
            <button
              className={cn(
                "flex items-center gap-2 rounded-full px-6 py-2 font-medium text-sm transition-colors",
                billing === "yearly"
                  ? "bg-white text-gray-900 shadow-sm dark:text-gray-100"
                  : "text-gray-600 dark:text-gray-400",
              )}
              onClick={() => setBilling("yearly")}
            >
              Yearly <span className="text-[#c9463d]">15% OFF</span>
            </button>
          </div>
        </div>

        {/* Pricing Cards */}
        <div className="grid grid-cols-1 gap-6 md:grid-cols-3">
          {plans.map((plan) => (
            <div
              className={cn(
                "relative flex flex-col rounded-2xl p-6",
                plan.featured
                  ? "border-2 border-[#3d5a45] bg-[#3d5a45] text-white"
                  : "border border-gray-200 bg-white dark:border-neutral-700 dark:bg-background",
              )}
              key={plan.id}
            >
              {/* Rainbow decoration for featured */}
              {plan.featured && (
                <RainbowStripe className="absolute top-4 right-4 opacity-80" />
              )}

              {/* Plan Name */}
              <span className={cn("mb-2 font-medium text-sm", plan.tagColor)}>
                {plan.name}
              </span>

              {/* Price */}
              <div className="mb-4">
                {plan.isPrice === false ? (
                  <span className="font-semibold font-serif text-3xl">
                    {plan.price}
                  </span>
                ) : (
                  <div className="flex items-baseline gap-1">
                    <span className="font-normal text-3xl">
                      $
                      {billing === "yearly"
                        ? Math.round((plan.price as number) * 0.85)
                        : plan.price}
                    </span>
                    <span
                      className={cn(
                        "text-sm",
                        plan.featured
                          ? "text-white/70"
                          : "text-gray-600 dark:text-gray-400",
                      )}
                    >
                      {plan.period}
                    </span>
                  </div>
                )}
              </div>

              {/* Subtitle & Features Card */}
              <div
                className={cn(
                  "flex-1 rounded-xl p-4",
                  plan.featured
                    ? "bg-white text-gray-900 dark:text-gray-100"
                    : "bg-transparent",
                )}
              >
                <p className="mb-4 font-semibold text-gray-900 dark:text-gray-100">
                  {plan.subtitle}
                </p>

                {plan.featureGroups.map((group) => (
                  <div className="mb-4" key={group.title}>
                    <p className="mb-2 text-gray-600 text-sm dark:text-gray-400">
                      {group.title}
                    </p>
                    <ul className="space-y-2">
                      {group.items.map((item, index) => {
                        const k = `feature_icon${index}`;
                        return (
                          <li
                            className="flex items-start gap-2 text-gray-700 text-sm dark:text-gray-300"
                            key={k}
                          >
                            <Check className="mt-0.5 h-4 w-4 shrink-0 text-[#2a7d5f]" />
                            {item}
                          </li>
                        );
                      })}
                    </ul>
                  </div>
                ))}
              </div>

              {/* CTA Button */}
              <Button
                className={cn(
                  "mt-4 h-11 w-full rounded-xl",
                  plan.featured
                    ? "bg-[#3d5a45] text-white hover:bg-[#2d4535]"
                    : "border-neutral-300 text-[#2a7d5f] hover:bg-gray-50 dark:bg-neutral-900",
                )}
                variant={plan.featured ? "default" : "outline"}
              >
                Start today
              </Button>

              {/* Spots left */}
              {plan.spotsLeft && (
                <p className="mt-3 text-center text-neutral-400 text-xs">
                  *{plan.spotsLeft} spots for member left
                </p>
              )}
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

export default Pricing3;
```
