## Odometer Pricing (S—478)

Three pricing tiers whose prices roll digit by digit, like an odometer, when you switch between monthly and yearly.

- URL: https://sundaeui.dev/components/odometer-pricing
- Category: Page sections · Art direction: Refined
- Access: Sundae Pro (authenticated install)
- Stack: React 18+, TypeScript, plain CSS; dependencies: none
- Install: `npx shadcn@latest add https://sundaeui.dev/r/odometer-pricing.json`
- Tags: saas, pricing, section, animated, toggle, react, odometer, landing-page

Switch billing and every price changes the way a mechanical counter does: each digit rolls through its column to the new value, the ones place first and the tens a beat later, while digits that are no longer needed fold away. The billing note underneath crossfades to show the yearly total.
The switch has a sliding thumb on a soft spring. The featured tier is set in reverse, with its own badge. Cards rise in on first view, and each tier’s checkmarks draw themselves in sequence.
Prices are plain numbers in props; the currency symbol is configurable. Light and dark (.dark), one CSS file, no animation library. Screen readers get the full price as text, and reduced motion swaps values instantly.

### Usage

```tsx
import { OdometerPricing } from '@/components/sundae/odometer-pricing'

<OdometerPricing
  title="Simple pricing that grows with you."
  plans={[
    { name: 'Starter', description: '…', monthly: 12, yearly: 9, features: ['3 sources'], cta: { label: 'Start free', href: '/signup' } },
    { name: 'Team', description: '…', monthly: 49, yearly: 39, features: ['Unlimited sources'], cta: { label: 'Start trial', href: '/signup?plan=team' }, featured: true, badge: 'Most teams' },
  ]}
/>
```

### Props

- `title` (`string`, required): Section heading.
- `plans` (`PricingPlan[]`, required): name, description, monthly, yearly (per month), features, cta, featured?, badge?
- `intro` (`string`): Supporting paragraph.
- `currency` (`string`, default `'$'`): Symbol shown before prices.
- `yearlyNote` (`string`, default `'Save 20%'`): Label beside Yearly.
- `defaultBilling` (`'monthly' | 'yearly'`, default `'yearly'`): Initial billing period.

### Accessibility

- The billing switch is a radiogroup of two radio buttons.
- The rolling digits are aria-hidden; each price is also given as text, and the billing note is a polite live region.
- Each tier is an article labelled by its name.
