Starter
One channel, kept alive
4.5 ma month
- 12 posts
- Captions and hashtags
- A monthly report
Fixed packages with what they cost: each card names a package and who it suits, gives the price and what it is counted in (or "Price on request", for a business that quotes), lists what is included with a tick in a colour block, can carry a bonus line on that block, and ends in an action that asks about that package. The cards lift a hover step under the pointer. The action is a link: a contact page, a mailto, a chat. Zero JavaScript.
Sample packages
One channel, kept alive
4.5 ma month
Two channels and ads
8 ma month
Ads budget apart
First month: a free shoot
For groups and launches
Price on request
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
JavaScript of its own
0 B
CSS 11.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
every browser.
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:
npx shadcn@latest add @moonarc-pro/package-cards---
import PackageCards from '@/components/moonarc/pro/PackageCards.astro';
---
<PackageCards
headline="Monthly packages"
packages={[
{ name: 'Starter', tagline: 'One channel, kept alive', price: '4.5 m', unit: 'a month', includes: ['12 posts', 'Captions', 'A monthly report'], href: '/contact/?package=starter' },
{ name: 'Growth', tagline: 'Two channels and ads', price: '8 m', unit: 'a month', includes: ['20 posts', '8 short videos', 'Ads set-up'], bonus: 'First month: a free shoot', href: '/contact/?package=growth' },
{ name: 'Custom', tagline: 'For groups and launches', includes: ['Everything above', 'A team on call'], href: '/contact/?package=custom' },
]}
/>Without a key the registry answers 401 with an upgrade message.
| Prop | Type | Default | Description |
|---|---|---|---|
packages | { name, tagline?, price?, unit?, note?, includes, bonus?, href, action?, external? }[] | none | The packages, in order. A package without a price shows the section's onRequest line; note sits under the price; action replaces "Ask about <name>"; external opens the link in a new tab. |
eyebrow | string | none | A short line above the heading. |
headline | string | none | The heading. Slot "headline" wins and may hold an <em>. |
copy | string | none | A line under the heading. Slot "copy" wins. |
block | 1 | 2 | 3 | 4 | 5 | 1 | The colour block the ticks and the bonus line paint. |
onRequest | string | 'Price on request' | What a package without a price says instead. |
ask | string | 'Ask about' | The action's first words, followed by the package's name. |
includesLabel | string | 'Included' | Accessible name of each card's list. |
level | 2 | 3 | 2 | Heading level of the section's heading; the packages' names are one below. |
tone | 'surface' | 'muted' | 'ink' | 'brand' | unset (paints nothing) | The section's ground; on ink and brand the cards follow the tone's card colour. |
density | 'compact' | 'cozy' | 'roomy' | 'cozy' | Block padding ×0.8 / ×1 / ×1.25 through --ma-density. |
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.
.ma-packages.ma-packages__action.ma-packages__amount.ma-packages__bonus.ma-packages__card.ma-packages__copy.ma-packages__eyebrow.ma-packages__foot.ma-packages__grid.ma-packages__head.ma-packages__headline.ma-packages__item.ma-packages__list.ma-packages__name.ma-packages__note.ma-packages__price.ma-packages__tagline.ma-packages__tick.ma-packages__top.ma-packages__unit
slot="eyebrow"slot="headline"slot="copy"
The cards do not lift and the action fills at once.
ClientRouterCSS only; nothing to rebind.
Replaces: Pricing cards (Tailwind Plus) · Package cards (Framer agency templates). See the migration table.
What is on offer, as colour blocks: each card paints one of the palette's blocks and carries a drawing in its corner (Motif), an index, a name, a line, chips for what it includes and a foot with a price and a round arrow.
$0/yr
MIT, forever
$129/yr
One person, billed yearly
$349/yr
Up to 10 people, one invoice
Shows pricing plans side by side, with an annual/monthly toggle that rolls every price digit by digit to the other period with zero JavaScript (radios, :has and NumberFlow), the highlighted plan wearing a travelling border beam, cards revealed with a stagger.
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.
Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown