Skip to content

Components / Sections

Pricing Table

A feature-by-plan comparison: the highlighted plan's column lit, rows revealed with a 40 ms stagger as the table scrolls into view, and a header row that sticks when you cap the table's height. Semantic table, zero JavaScript of its own.

Live demo

FeatureFree$0Pro$129/yrTeam$349/yr
PrimitivesIncludedIncludedIncluded
SectionsNot included2828
Audit toolsNot includedIncludedIncluded
PeopleAnyone1Up to 10
Client workIncludedIncludedIncluded

Live, from the library itself, at full size: scroll, hover, navigate away and back. The demo is never gated.

Variants · each row writes the attribute the prop writes; the section's own CSS answers

tone
density

Measured

JavaScript of its own

0 B

Uses Reveal and the shared runtime (1.9 kB raw, once per site). With those included: 3.0 kB raw.

CSS 9.9 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.

Browser support

Baseline · widely available

every browser.

Install Pro

The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:

terminal
npx shadcn@latest add @moonarc-pro/pricing-table
src/pages/index.astro
---
import PricingTable from '@/components/moonarc/pro/PricingTable.astro';
---
<PricingTable
  plans={[{ name: 'Starter', price: '$0' }, { name: 'Plus', price: '$120/yr', highlight: true }]}
  rows={[
    { feature: 'Projects', cells: ['3', 'Unlimited'] },
    { feature: 'Priority support', cells: [false, true] },
  ]}
/>

Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: reveal.

Props

PropTypeDefaultDescription
plans{ name, price, highlight? }[]noneColumns.
rows{ feature, cells: (boolean | string)[] }[]noneRows; true renders a check mark and false the word none (noneLabel), each with screen-reader text (includedLabel, excludedLabel); strings render as text.
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The ground: the page surface, a muted band, an always-dark ink panel, or a deep brand panel. Each paints --background, --ma-tone-muted (over --muted, with a --border hairline), --ma-tone-ink or --ma-tone-brand (over --primary) with the matching text. With theme.css, a painted tone also re-declares --card, --border, --input and --ring inside the section, so cards and fields follow the ground. Decoration is strongest on brand.
density'compact' | 'cozy' | 'roomy''cozy'Cell padding ×0.8 / ×1 / ×1.25 through --ma-density.
labelstring'Plans compared'Accessible name of the table, which scrolls sideways when a narrow screen cuts it: the section takes a tab stop, so a keyboard can reach and scroll it.
featureLabelstring'Feature'Screen-reader text of the feature column's header.
includedLabelstring'Included'Screen-reader text of a true cell.
excludedLabelstring'Not included'Screen-reader text of a false cell.
noneLabelstring'none'The word a false cell shows.

Theming and overrides

The section reads the theme contract (shadcn's variable names with the base tokens as fallback), so a pasted theme or one --ma-brand recolours it. Its class names are the override surface and stay stable; a named slot replaces the matching prop with your own markup.

Classes

.ma-pricing-table.ma-pricing-table__copy.ma-pricing-table__eyebrow.ma-pricing-table__head.ma-pricing-table__headline.ma-pricing-table__no.ma-pricing-table__plan.ma-pricing-table__price.ma-pricing-table__sr

Slots

slot="eyebrow"slot="headline"slot="copy"

Reduced motion

Rows fade in without stagger.

With ClientRouter

Inherits Reveal; nothing to wire.

Why it is built this way

Replaces: Comparison tables (Tailwind Plus). See the migration table.

Entrance on scroll that plays once and stays, staggers its children, scrubs with the scroll position when asked, honours reduced motion, and keeps working after every ClientRouter navigation.

every browserscroll

Compares your product with others in an "us versus them" table.

newly · Chrome 85 · Firefox 128 · Safari 16.4scroll

Free

$0/yr

MIT, forever

  • 102 primitives, no account, no token
  • Runtime, GSAP and Lenis adapters
  • Public shadcn registry
  • MCP server
Set up in five minutes

Pro

$129/yr

One person, billed yearly

  • 28 sections and 11 GPU effects, demos never gated
  • Every template, starting with Waitlist
  • audit_motion and measure_budget, locally and in CI
  • compose_section with a total cost
  • New components monthly, dated changelog
  • Email support within 2 working days
Not open yet: see the plan

Team

$349/yr

Up to 10 people, one invoice

  • Everything in Pro, for the whole team
  • One key for the team, locally and in CI
  • Move up from Pro at any time
  • More than 10 people: email us
Talk to us

Shows pricing plans side by side, with an annual/monthly toggle that swaps every price with zero JavaScript (radios and :has), the highlighted plan wearing a travelling border beam, cards revealed with a stagger.

newly · Chrome 105 · Firefox 128 · Safari 16.4scrollclick

Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown