Skip to content

Components / Sections

Ticket Tiers

The tickets, as tickets: each tier a card with a perforated line under its head (a notch cut from each side), the name and the price, what it includes, how many are left (a count, and a bar that fills as the card comes into view) and its action. One tier can be featured in a colour block; a sold-out tier is stamped and loses its action; a tier not yet on sale says so. An action that leads to another site's ticket shop says that too. Zero JavaScript.

Live demo

Tickets

Pick your days

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

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

Browser support

Limited availability

Chrome 120 · not Firefox · Safari 26; needs scroll-timeline, mask-image. Elsewhere: the bars stand at their values; without masks the cards keep their corners and lose their notches.

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/ticket-tiers
src/pages/index.astro
---
import TicketTiers from '@/components/moonarc/pro/TicketTiers.astro';
---
<TicketTiers
  eyebrow="Tickets"
  tiers={[
    { name: 'One day', price: '$89', includes: ['Every talk that day', 'Lunch'], left: { sold: 120, total: 300 }, href: 'https://tickets.example/one-day', action: 'Buy one day', external: true },
    { name: 'All three days', price: '$219', includes: ['Every talk and workshop'], left: { sold: 410, total: 500 }, href: 'https://tickets.example/three-days', action: 'Buy three days', external: true, featured: true },
    { name: 'Early bird', price: '$179', includes: ['All three days'], status: 'sold-out' },
  ]}
>
  <span slot="headline">Pick <em>your days</em></span>
</TicketTiers>

Without a key the registry answers 401 with an upgrade message.

Props

PropTypeDefaultDescription
tiers{ name, price, note?, includes, left?: { sold, total, text? }, status?, href?, action?, external?, featured?, block? }[]noneThe tiers, in order. left.text is the count's sentence with {left} and {total}; status is on-sale, sold-out or soon; external marks an action that leads to another site.
eyebrowstringnoneA short line above the heading.
headlinestringnoneThe heading. Slot "headline" wins and may hold an <em>, set in the emphasis face and colour.
copystringnoneA line under the heading.
includesLabelstring'Includes'Accessible name of each tier's list.
soldOutstring'Sold out'The stamp on a sold-out tier.
soonstring'On sale soon'What a tier not yet on sale says in place of its action.
externalLabelstring'(on another site)'The words a screen reader hears after an action that leads to another site.
level1 | 2 | 32Heading level of the section's heading; the tiers' names are one below (1 on a page whose own h1 is above them).
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The section's ground.
density'compact' | 'cozy' | 'roomy''cozy'Block padding ×0.8 / ×1 / ×1.25 through --ma-density.

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-tickets.ma-tickets__action.ma-tickets__body.ma-tickets__copy.ma-tickets__count.ma-tickets__eyebrow.ma-tickets__head.ma-tickets__headline.ma-tickets__includes.ma-tickets__left.ma-tickets__list.ma-tickets__meter.ma-tickets__name.ma-tickets__note.ma-tickets__price.ma-tickets__soon.ma-tickets__stamp.ma-tickets__tier.ma-tickets__top

Slots

slot="eyebrow"slot="headline"

Reduced motion

The bars stand at their values and the cards do not lift on hover.

With ClientRouter

CSS only; nothing to rebind.

Why it is built this way

Replaces: Ticket widgets (event platforms) · Pricing tables for events. See the migration table.

Questions people actually ask

Short answers. The long ones are in the docs.

Is it really zero JS?

For 83 of 125, yes, measured from a build.

Does it survive View Transitions?

Yes, verified on Astro 5, 6 and 7.

Do I need Tailwind?

No.

FAQ

Pro

A heading and lead beside a native accordion: one question open at a time, heights animated by the browser, keyboard and screen reader handled by <details>.

newly · Chrome 131 · Firefox 143 · Safari 18.4scrollclick

The first screen of an event, made like its poster: one colour block with the edition and the place in the mono face, the name huge, the dates, a line, two actions, three facts, a countdown to the doors (core CountdownFlip) and the days as chips, and beside them a composition of nine shapes in the block's drawing colours that pop into place one after another as the page opens and turn a quarter when a pointer rests on them, one of them turning round a quarter at a time once they are in, inside five seconds, then resting.

every browserloadhover

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.

every browserhover

Free

$0/yr

MIT, forever

  • 125 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

  • 108 sections and 11 GPU effects, demos never gated
  • Every template: Waitlist, Launch, Agentic, Studio, Agency, Atelier, Gather, Creator, Endpoint, Homescreen, Estate, Practice, and Stay
  • 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 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.

newly · Chrome 125 · 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