# Pricing Horizontal Rows — Tailwind Pricing Section

> An editorial price list: each plan is a full-width row with a serif name, and an inverted fill wipes up from the bottom edge on hover.

- Category: [Pricing](https://pixelpapa.com/components/pricing.md)
- Tags: pricing, rows, editorial, serif, hover
- Dependencies: lucide-react, motion (plus React and Tailwind CSS v4)
- Last updated: 2026-11-13
- Live preview: https://pixelpapa.com/components/pricing/pricing-horizontal-rows

## Install

```bash
npx shadcn@latest add "https://pixelpapa.com/r/pricing-horizontal-rows.json"
```

The file is written to `components/pixelpapa/pricing-horizontal-rows.tsx`. To install manually, run `npm install lucide-react motion` and copy the source below into your project. It imports `cn` from `@/lib/utils`, which every shadcn project has.

## Source

```tsx
"use client";

import { ArrowUpRight } from "lucide-react";
import { motion } from "motion/react";

type Plan = { name: string; price: string; unit: string; blurb: string; features: string[] };

const defaultPlans: Plan[] = [
  {
    name: "Reader",
    price: "$0",
    unit: "always",
    blurb: "Publish a newsletter and keep every subscriber you earn.",
    features: ["Up to 1,000 subscribers", "Web archive", "Basic open stats"],
  },
  {
    name: "Writer",
    price: "$15",
    unit: "per month",
    blurb: "Paid subscriptions, your own domain and none of our branding.",
    features: ["Up to 10,000 subscribers", "Paid tiers, 0% platform fee", "Custom domain", "Scheduling"],
  },
  {
    name: "Masthead",
    price: "$49",
    unit: "per month",
    blurb: "A small publication with several bylines and an editor in charge.",
    features: ["Up to 50,000 subscribers", "5 author seats", "Editorial review flow", "Sponsorship slots"],
  },
  {
    name: "Press",
    price: "Let's talk",
    unit: "annual",
    blurb: "For newsrooms moving an existing audience without losing a single address.",
    features: ["Unlimited subscribers", "Assisted migration", "Dedicated sending IPs", "SSO"],
  },
];

export default function PricingHorizontalRows({ plans = defaultPlans }: { plans?: Plan[] }) {
  return (
    <section className="bg-background px-6 py-24">
      <div className="mx-auto max-w-6xl">
        <div className="flex flex-wrap items-end justify-between gap-6 pb-10">
          <h2 className="max-w-xl font-serif text-5xl leading-[1.05] tracking-tight text-foreground sm:text-6xl">
            A price list, <span className="italic">not a puzzle.</span>
          </h2>
          <p className="max-w-xs text-sm text-muted-foreground">
            Inkpost plans are billed monthly and include unlimited sends. Prices in USD, tax where it applies.
          </p>
        </div>

        <ul className="border-t border-foreground">
          {plans.map((plan, i) => (
            <motion.li
              key={plan.name}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.6, delay: 0.1 + i * 0.08, ease: [0.22, 1, 0.36, 1] }}
              className="border-b border-border"
            >
              <a
                href="#"
                aria-label={`${plan.name}, ${plan.price} ${plan.unit}`}
                className="group relative grid items-center gap-x-8 gap-y-4 overflow-hidden px-2 py-8 outline-none sm:px-6 md:grid-cols-[3rem_14rem_1fr_auto]"
              >
                <span
                  aria-hidden
                  className="absolute inset-0 origin-bottom scale-y-0 bg-foreground transition-transform duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:scale-y-100 group-focus-visible:scale-y-100 motion-reduce:transition-none"
                />
                <span className="relative font-mono text-xs text-muted-foreground transition-colors duration-300 group-hover:text-background/60 group-focus-visible:text-background/60 max-md:hidden">
                  0{i + 1}
                </span>
                <h3 className="relative font-serif text-4xl tracking-tight text-foreground transition-colors duration-300 group-hover:text-background group-focus-visible:text-background sm:text-5xl">
                  {plan.name}
                </h3>
                <div className="relative">
                  <p className="max-w-md text-foreground transition-colors duration-300 group-hover:text-background group-focus-visible:text-background">
                    {plan.blurb}
                  </p>
                  <ul className="mt-3 flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted-foreground transition-colors duration-300 group-hover:text-background/70 group-focus-visible:text-background/70">
                    {plan.features.map((f, n) => (
                      <li key={f} className="flex items-center gap-4">
                        {n > 0 && <span aria-hidden className="size-1 rounded-full bg-current opacity-50" />}
                        {f}
                      </li>
                    ))}
                  </ul>
                </div>
                <div className="relative flex items-center gap-5 md:justify-end">
                  <p className="text-right max-md:text-left">
                    <span className="block text-3xl font-semibold tracking-tight text-foreground transition-colors duration-300 group-hover:text-background group-focus-visible:text-background">
                      {plan.price}
                    </span>
                    <span className="text-xs text-muted-foreground transition-colors duration-300 group-hover:text-background/60 group-focus-visible:text-background/60">
                      {plan.unit}
                    </span>
                  </p>
                  <span className="flex size-11 items-center justify-center rounded-full border border-border text-foreground transition-all duration-300 group-hover:rotate-45 group-hover:border-background group-hover:bg-background group-focus-visible:rotate-45 group-focus-visible:bg-background max-md:ml-auto">
                    <ArrowUpRight className="size-5" />
                  </span>
                </div>
              </a>
            </motion.li>
          ))}
        </ul>
      </div>
    </section>
  );
}
```

## AI prompt

```text
Add the "Pricing Horizontal Rows" component from PixelPapa UI to this project.

What it is: An editorial price list: each plan is a full-width row with a serif name, and an inverted fill wipes up from the bottom edge on hover.
Category: Pricing. Depends on: lucide-react, motion.

1. Install it with the shadcn CLI:
   npx shadcn@latest add "https://pixelpapa.com/r/pricing-horizontal-rows.json"
   (If the CLI is unavailable, fetch that URL, write files[0].content to components/pixelpapa/pricing-horizontal-rows.tsx and install the listed dependencies.)
2. Import it from "@/components/pixelpapa/pricing-horizontal-rows" and place it where I describe below.
3. Keep its animation timings and accessibility attributes. Replace the demo copy and data with content that fits my product, and use my existing theme tokens (bg-background, text-foreground, bg-primary, border-border) rather than hard-coded colours.

Where to use it: <describe the page and position here>
```

## More pricing

- [Pricing Addon Builder](https://pixelpapa.com/components/pricing/pricing-addon-builder.md) (Pro): Build a plan by switching add-ons on and off; each one slides onto a receipt and the running total rolls to its new value.
- [Pricing Comparison Matrix](https://pixelpapa.com/components/pricing/pricing-comparison-matrix.md) (Pro): A feature-by-feature plan table with a sticky plan header, grouped rows, a column that highlights on hover and checkmarks that draw themselves in.
- [Pricing Credits Packs](https://pixelpapa.com/components/pricing/pricing-credits-packs.md): Pay-as-you-go credit packs as radio cards with growing coin stacks, a best-value corner ribbon and a selection ring that glides to the chosen pack.
- [Pricing Currency Switcher](https://pixelpapa.com/components/pricing/pricing-currency-switcher.md) (Pro): Three plans in one divided panel with a hand-built currency menu; choosing a currency counts every price to its localised amount.
- [Pricing Enterprise Contact](https://pixelpapa.com/components/pricing/pricing-enterprise-contact.md) (Pro): Two self-serve plans beside an inverted enterprise card with a named contact and a short form that morphs into a confirmation.
- [Pricing Single Plan Spotlight](https://pixelpapa.com/components/pricing/pricing-single-plan-spotlight.md): One plan presented large inside a slowly rotating gradient border, with a staggered included list, crossed-out extras and a money-back guarantee.
