Web InnoventixFreeCode

Single Highlight Pricing

Original · free

single highlighted plan

byWeb InnoventixReact + Tailwind
pricexsinglehighlightpricing
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-single-highlight.json
pricex-single-highlight.tsx
"use client";

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

type Billing = "monthly" | "annual";

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

const PLANS: Plan[] = [
  {
    id: "starter",
    name: "Starter",
    tagline: "For solo builders finding their footing.",
    monthly: 12,
    annual: 9,
    cta: "Start free",
    featured: false,
    features: [
      "Up to 3 active projects",
      "Basic usage analytics",
      "Community support",
      "1 GB asset storage",
    ],
  },
  {
    id: "pro",
    name: "Pro",
    tagline: "For teams that ship every single week.",
    monthly: 29,
    annual: 23,
    cta: "Start 14-day trial",
    featured: true,
    features: [
      "Unlimited projects",
      "Advanced analytics & reports",
      "Priority support in under 4h",
      "50 GB asset storage",
      "Custom automated workflows",
      "Role-based access controls",
    ],
  },
  {
    id: "scale",
    name: "Scale",
    tagline: "For organizations that need guarantees.",
    monthly: 79,
    annual: 63,
    cta: "Talk to sales",
    featured: false,
    features: [
      "Everything in Pro",
      "SSO & SAML provisioning",
      "Dedicated success manager",
      "Unlimited storage & seats",
      "Audit logs & 99.99% SLA",
    ],
  },
];

function CheckIcon({ className }: { className?: string }) {
  return (
    <svg
      viewBox="0 0 20 20"
      fill="none"
      aria-hidden="true"
      className={className}
    >
      <path
        d="M4.5 10.5l3.2 3.2 7.8-8.4"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

function SparkIcon({ className }: { className?: string }) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      aria-hidden="true"
      className={className}
    >
      <path
        d="M12 2.5l2.1 5.6 5.6 2.1-5.6 2.1L12 18l-2.1-5.7L4.3 10.2l5.6-2.1L12 2.5z"
        fill="currentColor"
      />
    </svg>
  );
}

export default function PricexSingleHighlight() {
  const reduce = useReducedMotion();
  const [billing, setBilling] = useState<Billing>("annual");
  const groupId = useId();

  const headerMotion = reduce
    ? {}
    : {
        initial: { opacity: 0, y: 18 },
        whileInView: { opacity: 1, y: 0 },
        viewport: { once: true, margin: "-80px" },
        transition: { duration: 0.5, ease: [0.22, 1, 0.36, 1] as const },
      };

  return (
    <section className="relative w-full overflow-hidden bg-slate-50 px-6 py-24 text-slate-900 dark:bg-slate-950 dark:text-slate-100 sm:py-28">
      <style>{`
        @keyframes psh-float {
          0%, 100% { transform: translate3d(0, 0, 0); }
          50% { transform: translate3d(0, -22px, 0); }
        }
        @keyframes psh-glow {
          0%, 100% { opacity: 0.55; }
          50% { opacity: 1; }
        }
        @keyframes psh-badge {
          0% { background-position: 0% 50%; }
          100% { background-position: 200% 50%; }
        }
        @media (prefers-reduced-motion: reduce) {
          .psh-anim { animation: none !important; }
        }
      `}</style>

      {/* Decorative background */}
      <div aria-hidden="true" className="pointer-events-none absolute inset-0">
        <div className="psh-anim absolute -left-24 top-8 h-72 w-72 rounded-full bg-indigo-300/40 blur-3xl dark:bg-indigo-600/20" style={{ animation: "psh-float 11s ease-in-out infinite" }} />
        <div className="psh-anim absolute -right-16 bottom-0 h-80 w-80 rounded-full bg-violet-300/40 blur-3xl dark:bg-violet-700/20" style={{ animation: "psh-float 14s ease-in-out infinite reverse" }} />
        <div className="absolute inset-0 bg-[radial-gradient(60%_50%_at_50%_0%,rgba(99,102,241,0.10),transparent_70%)]" />
      </div>

      <div className="relative mx-auto max-w-6xl">
        {/* Header */}
        <motion.div {...headerMotion} className="mx-auto max-w-2xl text-center">
          <span className="inline-flex items-center gap-2 rounded-full border border-indigo-200 bg-white/70 px-3.5 py-1.5 text-xs font-semibold uppercase tracking-wider text-indigo-700 backdrop-blur dark:border-indigo-500/30 dark:bg-white/5 dark:text-indigo-300">
            <span className="h-1.5 w-1.5 rounded-full bg-indigo-500" />
            Pricing
          </span>
          <h2 className="mt-5 text-4xl font-bold tracking-tight sm:text-5xl">
            One plan does the heavy lifting
          </h2>
          <p className="mt-4 text-lg leading-relaxed text-slate-600 dark:text-slate-400">
            Meridian scales from your first side project to a company-wide
            rollout. Most teams land on Pro and never look back.
          </p>
        </motion.div>

        {/* Billing toggle */}
        <div className="mt-9 flex flex-col items-center gap-3">
          <div
            role="group"
            aria-label="Billing period"
            aria-describedby={`${groupId}-hint`}
            className="inline-flex items-center rounded-full border border-slate-200 bg-white p-1 shadow-sm dark:border-white/10 dark:bg-white/5"
          >
            <button
              type="button"
              aria-pressed={billing === "monthly"}
              onClick={() => setBilling("monthly")}
              className={
                "rounded-full px-5 py-2 text-sm font-semibold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-950 " +
                (billing === "monthly"
                  ? "bg-slate-900 text-white dark:bg-white dark:text-slate-900"
                  : "text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-white")
              }
            >
              Monthly
            </button>
            <button
              type="button"
              aria-pressed={billing === "annual"}
              onClick={() => setBilling("annual")}
              className={
                "flex items-center gap-2 rounded-full px-5 py-2 text-sm font-semibold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-950 " +
                (billing === "annual"
                  ? "bg-slate-900 text-white dark:bg-white dark:text-slate-900"
                  : "text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-white")
              }
            >
              Annual
              <span
                className={
                  "rounded-full px-2 py-0.5 text-[11px] font-bold " +
                  (billing === "annual"
                    ? "bg-emerald-400 text-emerald-950"
                    : "bg-emerald-100 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300")
                }
              >
                -20%
              </span>
            </button>
          </div>
          <p
            id={`${groupId}-hint`}
            className="text-sm text-slate-500 dark:text-slate-400"
          >
            {billing === "annual"
              ? "Billed once a year. Two months on the house."
              : "Billed monthly. Cancel whenever you like."}
          </p>
        </div>

        {/* Plans */}
        <div className="mt-14 grid grid-cols-1 items-stretch gap-6 md:grid-cols-3">
          {PLANS.map((plan, i) => {
            const price = billing === "monthly" ? plan.monthly : plan.annual;
            const cardMotion = reduce
              ? {}
              : {
                  initial: { opacity: 0, y: 26 },
                  whileInView: { opacity: 1, y: 0 },
                  viewport: { once: true, margin: "-60px" },
                  transition: {
                    duration: 0.5,
                    delay: i * 0.08,
                    ease: [0.22, 1, 0.36, 1] as const,
                  },
                };

            if (plan.featured) {
              return (
                <motion.div
                  key={plan.id}
                  {...cardMotion}
                  className="relative z-10 flex flex-col rounded-3xl bg-gradient-to-b from-indigo-600 to-violet-700 p-8 shadow-2xl shadow-indigo-500/30 ring-1 ring-white/20 md:-my-4"
                >
                  {/* glow */}
                  <div
                    aria-hidden="true"
                    className="psh-anim pointer-events-none absolute -inset-px -z-10 rounded-3xl bg-gradient-to-b from-indigo-400/50 to-violet-500/50 blur-lg"
                    style={{ animation: "psh-glow 4s ease-in-out infinite" }}
                  />
                  <div className="flex items-center justify-between">
                    <h3 className="text-xl font-bold text-white">{plan.name}</h3>
                    <span
                      className="psh-anim inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-bold text-indigo-950"
                      style={{
                        backgroundImage:
                          "linear-gradient(90deg,#fde68a,#fbbf24,#fde68a)",
                        backgroundSize: "200% 100%",
                        animation: "psh-badge 3s linear infinite",
                      }}
                    >
                      <SparkIcon className="h-3.5 w-3.5" />
                      Most popular
                    </span>
                  </div>
                  <p className="mt-2 text-sm text-indigo-100">{plan.tagline}</p>

                  <div className="mt-6 flex items-end gap-1.5">
                    <span className="text-lg font-semibold text-indigo-200">$</span>
                    <motion.span
                      key={billing}
                      initial={reduce ? false : { opacity: 0, y: 8 }}
                      animate={{ opacity: 1, y: 0 }}
                      transition={{ duration: 0.3 }}
                      className="text-5xl font-extrabold leading-none tracking-tight text-white"
                    >
                      {price}
                    </motion.span>
                    <span className="mb-1 text-sm font-medium text-indigo-200">
                      /mo
                    </span>
                  </div>
                  <p className="mt-1 text-xs text-indigo-200">
                    {billing === "annual"
                      ? `$${price * 12} billed annually per seat`
                      : "billed monthly per seat"}
                  </p>

                  <button
                    type="button"
                    className="mt-7 w-full rounded-xl bg-white px-5 py-3 text-sm font-bold text-indigo-700 shadow-lg transition-transform hover:-translate-y-0.5 hover:bg-indigo-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-indigo-600"
                  >
                    {plan.cta}
                  </button>

                  <ul className="mt-7 space-y-3.5">
                    {plan.features.map((f) => (
                      <li key={f} className="flex items-start gap-3">
                        <span className="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-white/20 text-white">
                          <CheckIcon className="h-3.5 w-3.5" />
                        </span>
                        <span className="text-sm text-indigo-50">{f}</span>
                      </li>
                    ))}
                  </ul>
                </motion.div>
              );
            }

            return (
              <motion.div
                key={plan.id}
                {...cardMotion}
                className="flex flex-col rounded-3xl border border-slate-200 bg-white p-8 shadow-sm transition-colors hover:border-indigo-300 dark:border-white/10 dark:bg-white/[0.03] dark:hover:border-indigo-500/40"
              >
                <h3 className="text-xl font-bold text-slate-900 dark:text-white">
                  {plan.name}
                </h3>
                <p className="mt-2 text-sm text-slate-500 dark:text-slate-400">
                  {plan.tagline}
                </p>

                <div className="mt-6 flex items-end gap-1.5">
                  <span className="text-lg font-semibold text-slate-400">$</span>
                  <motion.span
                    key={billing}
                    initial={reduce ? false : { opacity: 0, y: 8 }}
                    animate={{ opacity: 1, y: 0 }}
                    transition={{ duration: 0.3 }}
                    className="text-5xl font-extrabold leading-none tracking-tight text-slate-900 dark:text-white"
                  >
                    {price}
                  </motion.span>
                  <span className="mb-1 text-sm font-medium text-slate-400">
                    /mo
                  </span>
                </div>
                <p className="mt-1 text-xs text-slate-400 dark:text-slate-500">
                  {billing === "annual"
                    ? `$${price * 12} billed annually per seat`
                    : "billed monthly per seat"}
                </p>

                <button
                  type="button"
                  className="mt-7 w-full rounded-xl border border-slate-300 bg-slate-50 px-5 py-3 text-sm font-bold text-slate-800 transition-colors hover:border-slate-400 hover:bg-slate-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:border-white/15 dark:bg-white/5 dark:text-white dark:hover:bg-white/10 dark:focus-visible:ring-offset-slate-950"
                >
                  {plan.cta}
                </button>

                <ul className="mt-7 space-y-3.5">
                  {plan.features.map((f) => (
                    <li key={f} className="flex items-start gap-3">
                      <span className="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-emerald-600 dark:bg-emerald-500/15 dark:text-emerald-400">
                        <CheckIcon className="h-3.5 w-3.5" />
                      </span>
                      <span className="text-sm text-slate-600 dark:text-slate-300">
                        {f}
                      </span>
                    </li>
                  ))}
                </ul>
              </motion.div>
            );
          })}
        </div>

        {/* Footnote */}
        <p className="mt-10 text-center text-sm text-slate-500 dark:text-slate-400">
          No credit card required to start. Every paid plan includes a 30-day
          money-back guarantee.
        </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

Comparison Table Pricing

Comparison Table Pricing

Original

pricing comparison table

Cards Gradient Pricing

Cards Gradient Pricing

Original

gradient pricing cards

Minimal Pricing

Minimal Pricing

Original

minimal pricing tiers