Web InnoventixFreeCode

Cards Gradient Pricing

Original · free

gradient pricing cards

byWeb InnoventixReact + Tailwind
pricexcardsgradientpricing
Open

Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.

npx shadcn@latest add https://webinnoventix.com/r/pricex-cards-gradient.json
pricex-cards-gradient.tsx
"use client";

import { useState } from "react";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";

type BillingTier = {
  id: string;
  name: string;
  tagline: string;
  monthly: number;
  annual: number;
  cta: string;
  featured: boolean;
  border: string;
  features: string[];
};

const TIERS: BillingTier[] = [
  {
    id: "starter",
    name: "Starter",
    tagline: "For solo builders shipping their first product.",
    monthly: 19,
    annual: 15,
    cta: "Start free trial",
    featured: false,
    border:
      "bg-gradient-to-b from-slate-200 to-slate-200 dark:from-white/12 dark:to-white/5",
    features: [
      "Up to 3 team seats",
      "50k tracked events / month",
      "7 real-time dashboards",
      "Email & community support",
      "30-day data retention",
    ],
  },
  {
    id: "growth",
    name: "Growth",
    tagline: "For growing teams that live inside the data.",
    monthly: 49,
    annual: 39,
    cta: "Start free trial",
    featured: true,
    border:
      "bg-gradient-to-b from-indigo-500 via-violet-500 to-rose-500",
    features: [
      "Up to 15 team seats",
      "1M tracked events / month",
      "Unlimited dashboards & funnels",
      "Priority support, 4-hour SLA",
      "12-month data retention",
      "Custom event pipelines & API",
    ],
  },
  {
    id: "scale",
    name: "Scale",
    tagline: "For orgs that need control, security & scale.",
    monthly: 99,
    annual: 79,
    cta: "Talk to sales",
    featured: false,
    border:
      "bg-gradient-to-b from-slate-200 to-slate-200 dark:from-white/12 dark:to-white/5",
    features: [
      "Unlimited team seats",
      "25M tracked events / month",
      "SSO / SAML & audit logs",
      "Dedicated success manager",
      "Unlimited data retention",
      "SOC 2 report & custom DPA",
    ],
  },
];

function CheckIcon() {
  return (
    <svg
      viewBox="0 0 20 20"
      fill="none"
      aria-hidden="true"
      className="h-3.5 w-3.5"
    >
      <path
        d="M4 10.5 8 14.5 16 5.5"
        stroke="currentColor"
        strokeWidth="2.2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

export default function PricexCardsGradient() {
  const reduce = useReducedMotion();
  const [annual, setAnnual] = useState<boolean>(true);

  const cardMotion = (i: number) => ({
    initial: { opacity: 0, y: reduce ? 0 : 28 },
    whileInView: { opacity: 1, y: 0 },
    viewport: { once: true, margin: "-80px" } as const,
    transition: {
      duration: reduce ? 0 : 0.55,
      delay: reduce ? 0 : i * 0.09,
      ease: "easeOut" as const,
    },
  });

  return (
    <section
      aria-labelledby="pricex-heading"
      className="relative w-full overflow-hidden bg-slate-50 py-24 dark:bg-slate-950 sm:py-32"
    >
      <style>{`
        @keyframes pricex-float-a {0%,100%{transform:translateY(0)}50%{transform:translateY(-22px)}}
        @keyframes pricex-float-b {0%,100%{transform:translateY(0)}50%{transform:translateY(18px)}}
        @keyframes pricex-glow {0%,100%{opacity:.35}50%{opacity:.7}}
        @keyframes pricex-shimmer {0%{background-position:200% 0}100%{background-position:-200% 0}}
        .pricex-blob-a{animation:pricex-float-a 9s ease-in-out infinite}
        .pricex-blob-b{animation:pricex-float-b 11s ease-in-out infinite}
        .pricex-glow-ring{animation:pricex-glow 4.5s ease-in-out infinite}
        .pricex-shimmer{background-size:200% 100%;animation:pricex-shimmer 3.2s linear infinite}
        @media (prefers-reduced-motion: reduce){
          .pricex-blob-a,.pricex-blob-b,.pricex-glow-ring,.pricex-shimmer{animation:none!important}
        }
      `}</style>

      {/* ambient gradient field */}
      <div aria-hidden="true" className="pointer-events-none absolute inset-0">
        <div className="pricex-blob-a absolute -left-24 top-0 h-72 w-72 rounded-full bg-gradient-to-br from-sky-400/25 to-indigo-500/25 blur-3xl" />
        <div className="pricex-blob-b absolute -right-16 bottom-0 h-80 w-80 rounded-full bg-gradient-to-br from-violet-500/25 to-rose-400/20 blur-3xl" />
        <div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-slate-300/60 to-transparent dark:via-white/10" />
      </div>

      <div className="relative mx-auto max-w-6xl px-6 lg:px-8">
        {/* header */}
        <motion.div
          initial={{ opacity: 0, y: reduce ? 0 : 18 }}
          whileInView={{ opacity: 1, y: 0 }}
          viewport={{ once: true, margin: "-80px" }}
          transition={{ duration: reduce ? 0 : 0.5, ease: "easeOut" }}
          className="mx-auto max-w-2xl text-center"
        >
          <span className="inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-medium text-slate-600 shadow-sm dark:border-white/10 dark:bg-white/5 dark:text-slate-300">
            <span className="h-1.5 w-1.5 rounded-full bg-gradient-to-r from-indigo-500 to-violet-500" />
            Simple, transparent pricing
          </span>
          <h2
            id="pricex-heading"
            className="mt-6 text-4xl font-semibold tracking-tight text-slate-900 dark:text-white sm:text-5xl"
          >
            Pricing that scales with your team
          </h2>
          <p className="mx-auto mt-4 max-w-xl text-base leading-7 text-slate-600 dark:text-slate-400">
            Start free for 14 days — no credit card, no lock-in. Every plan
            ships with the full analytics core, and you can switch or cancel
            whenever you like.
          </p>
        </motion.div>

        {/* billing toggle */}
        <div className="mt-10 flex flex-wrap items-center justify-center gap-3">
          <div
            role="group"
            aria-label="Billing period"
            className="inline-flex items-center rounded-full border border-slate-200 bg-white p-1 shadow-sm dark:border-white/10 dark:bg-slate-900"
          >
            {([false, true] as const).map((isAnnual) => {
              const active = isAnnual === annual;
              return (
                <button
                  key={isAnnual ? "annual" : "monthly"}
                  type="button"
                  onClick={() => setAnnual(isAnnual)}
                  aria-pressed={active}
                  className="relative rounded-full px-5 py-2 text-sm font-medium outline-none transition-colors focus-visible:ring-2 focus-visible:ring-indigo-400"
                >
                  {active && (
                    <motion.span
                      layoutId="pricex-toggle-pill"
                      transition={
                        reduce
                          ? { duration: 0 }
                          : { type: "spring", stiffness: 420, damping: 34 }
                      }
                      className="absolute inset-0 rounded-full bg-gradient-to-r from-indigo-500 to-violet-600 shadow"
                    />
                  )}
                  <span
                    className={
                      active
                        ? "relative z-10 text-white"
                        : "relative z-10 text-slate-600 dark:text-slate-300"
                    }
                  >
                    {isAnnual ? "Yearly" : "Monthly"}
                  </span>
                </button>
              );
            })}
          </div>
          <span className="inline-flex items-center gap-1 rounded-full bg-emerald-100 px-3 py-1.5 text-xs font-semibold text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300">
            Save 20% yearly
          </span>
        </div>

        {/* cards */}
        <div className="mt-14 grid gap-6 lg:grid-cols-3 lg:items-stretch">
          {TIERS.map((tier, i) => {
            const price = annual ? tier.annual : tier.monthly;
            const yearly = tier.annual * 12;
            return (
              <motion.div
                key={tier.id}
                {...cardMotion(i)}
                className="relative"
              >
                {tier.featured && (
                  <div
                    aria-hidden="true"
                    className="pricex-glow-ring absolute -inset-1 rounded-[1.9rem] bg-gradient-to-b from-indigo-500/40 via-violet-500/30 to-rose-500/30 blur-xl"
                  />
                )}

                <div
                  className={`relative h-full rounded-3xl p-px transition-transform duration-300 hover:-translate-y-1.5 ${tier.border} ${
                    tier.featured ? "lg:-my-2 lg:scale-[1.04]" : ""
                  }`}
                >
                  <div className="relative flex h-full flex-col overflow-hidden rounded-[1.42rem] bg-white p-7 dark:bg-slate-900 sm:p-8">
                    {tier.featured && (
                      <div
                        aria-hidden="true"
                        className="pointer-events-none absolute inset-x-0 top-0 h-40 bg-gradient-to-b from-indigo-50 to-transparent dark:from-indigo-500/10"
                      />
                    )}

                    <div className="relative flex items-center justify-between">
                      <h3 className="text-lg font-semibold text-slate-900 dark:text-white">
                        {tier.name}
                      </h3>
                      {tier.featured && (
                        <span className="pricex-shimmer rounded-full bg-gradient-to-r from-indigo-500 via-violet-500 to-indigo-500 px-3 py-1 text-xs font-semibold text-white">
                          Most popular
                        </span>
                      )}
                    </div>

                    <p className="relative mt-2 text-sm leading-6 text-slate-500 dark:text-slate-400">
                      {tier.tagline}
                    </p>

                    <div className="relative mt-6 flex items-end gap-1">
                      <span className="mb-2 text-2xl font-semibold text-slate-900 dark:text-white">
                        $
                      </span>
                      <AnimatePresence mode="popLayout" initial={false}>
                        <motion.span
                          key={annual ? "annual" : "monthly"}
                          initial={reduce ? false : { opacity: 0, y: 10 }}
                          animate={{ opacity: 1, y: 0 }}
                          exit={reduce ? { opacity: 0 } : { opacity: 0, y: -10 }}
                          transition={{ duration: reduce ? 0 : 0.25 }}
                          className="text-5xl font-semibold tracking-tight text-slate-900 dark:text-white"
                        >
                          {price}
                        </motion.span>
                      </AnimatePresence>
                      <span className="mb-2 text-sm font-medium text-slate-500 dark:text-slate-400">
                        / mo
                      </span>
                    </div>
                    <p className="relative mt-1.5 text-xs text-slate-500 dark:text-slate-400">
                      {annual
                        ? `Billed $${yearly} once per year`
                        : "Billed monthly, cancel anytime"}
                    </p>

                    <button
                      type="button"
                      className={
                        tier.featured
                          ? "relative mt-7 w-full rounded-xl bg-gradient-to-r from-indigo-500 to-violet-600 px-4 py-3 text-sm font-semibold text-white shadow-lg shadow-indigo-500/25 outline-none transition-colors hover:from-indigo-600 hover:to-violet-700 focus-visible:ring-2 focus-visible:ring-indigo-400 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-900"
                          : "relative mt-7 w-full rounded-xl bg-slate-900 px-4 py-3 text-sm font-semibold text-white outline-none transition-colors hover:bg-slate-800 focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:bg-white dark:text-slate-900 dark:hover:bg-slate-200 dark:focus-visible:ring-offset-slate-900"
                      }
                    >
                      {tier.cta}
                    </button>

                    <div className="relative my-7 h-px bg-gradient-to-r from-transparent via-slate-200 to-transparent dark:via-white/10" />

                    <ul className="relative flex flex-1 flex-col gap-3.5">
                      {tier.features.map((feature) => (
                        <li key={feature} className="flex items-start gap-3">
                          <span
                            className={
                              tier.featured
                                ? "mt-0.5 inline-flex h-5 w-5 flex-none items-center justify-center rounded-full bg-indigo-100 text-indigo-600 dark:bg-indigo-500/20 dark:text-indigo-300"
                                : "mt-0.5 inline-flex h-5 w-5 flex-none items-center justify-center rounded-full bg-emerald-100 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-300"
                            }
                          >
                            <CheckIcon />
                          </span>
                          <span className="text-sm leading-6 text-slate-600 dark:text-slate-300">
                            {feature}
                          </span>
                        </li>
                      ))}
                    </ul>
                  </div>
                </div>
              </motion.div>
            );
          })}
        </div>

        {/* footnote */}
        <p className="mx-auto mt-12 max-w-2xl text-center text-sm text-slate-500 dark:text-slate-400">
          All plans include unlimited projects, GDPR-ready data controls, and a
          99.9% uptime SLA. Prices in USD, taxes may apply.
        </p>
      </div>
    </section>
  );
}

Dependencies

motion

Licence

Built by Web Innoventix. Free for personal and commercial use, no attribution required.

Built by Web Innoventix

Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.

Get a free quote

Similar components

Browse all →
Simple Pricing

Simple Pricing

Original

A three-tier pricing section with a highlighted popular plan.

Single Plan Pricing Card

Single Plan Pricing Card

Original

A focused one-plan pricing card with price, trial badge, feature list, call to action and a money-back trust note, ideal when you sell a single flat-rate product.

Three Tier Pricing With Monthly Annual Toggle

Three Tier Pricing With Monthly Annual Toggle

Original

A three-tier pricing grid with a pure-CSS monthly and annual billing toggle that swaps every price with no JavaScript, using a native checkbox and Tailwind group-has state.

Plan Feature Comparison Table

Plan Feature Comparison Table

Original

A responsive, semantic feature comparison table across three plans with grouped rows, tick and dash indicators and screen-reader labels so visitors can weigh every feature side by side.

Staggered Glow Pricing Tiers

Staggered Glow Pricing Tiers

Original

A three-tier pricing section whose cards reveal in a staggered spring cascade, with a rotating conic-gradient glow on the popular plan and prices that count up smoothly when you toggle monthly and annual billing.

Spotlight Cursor Pricing Cards

Spotlight Cursor Pricing Cards

Original

Pricing cards that light up with a cursor-following radial spotlight, drift over floating background orbs and rise into view with a staggered spring entrance, plus a pulsing glow on the popular plan.

Highlight Follow Pricing Plans

Highlight Follow Pricing Plans

Original

A pricing row where an animated gradient highlight glides via shared layout animation to whichever plan you hover, a three-way billing switch slides its pill, prices recount instantly and a perks marquee scrolls beneath.

Three Tier Pricing

Three Tier Pricing

Original

three-tier pricing cards

Toggle Annual Pricing

Toggle Annual Pricing

Original

pricing with monthly/annual toggle

Single Highlight Pricing

Single Highlight Pricing

Original

single highlighted plan

Comparison Table Pricing

Comparison Table Pricing

Original

pricing comparison table

Minimal Pricing

Minimal Pricing

Original

minimal pricing tiers