ComponentsSite blocks

Pricing table

Plan pricing for SaaS subscriptions, agency packages and retainers. Plans are separated by hairline rules, not cards; the highlighted plan gets a 2px accent rule and a label (no glow, no scale). The monthly/yearly switch is a fieldset of hidden radios read by :has() — zero JavaScript. Money goes through Intl per locale and currency, and a tax note is required.

Native radios + :has() blocks/site/pricing-table.tsx, blocks/site/registry-2.ts, styles/blocks.csstheme · material · accent · density · font

Pricing

One booking page, three sizes

Every plan includes the booking page, WhatsApp confirmations and a Google Business Profile sync. Change or cancel any month.

Billing period
  • Solo

    One practitioner, one calendar.

    29 US dollars /mo

    290 US dollars /yr

    Start with Solo
    • 1 calendar
    • Booking page and widget
    • WhatsApp remindersUp to 300 a month
    • Not included: Deposits and prepayment
  • Studio

    Most chosen

    A salon, spa or clinic with a front desk.

    79 US dollars /mo

    790 US dollars /yr

    Start with Studio
    • Up to 8 calendars
    • Deposits and prepayment
    • WhatsApp remindersUp to 2,000 a month
    • Gift cards
  • Group

    Several branches under one brand.

    Custom

    Talk to sales
    • Unlimited branches
    • Central reporting
    • SSO and audit log
    • A named account manager

Prices exclude 20% VAT

Yearly plans are billed once, up front. Cancel within 14 days for a full refund.

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { PricingTable } from "@vamos-ui/react/blocks";

<PricingTable
  title="One booking page, three *sizes*"
  billing="both"
  yearlySaving="2 months free"
  taxNote="Prices exclude 20% VAT"
  plans={[
    { name: "Solo", price: { monthly: { amount: "29", currency: "USD" }, yearly: { amount: "290", currency: "USD" } },
      features: [{ text: "1 calendar" }, { text: "Deposits", included: false }],
      cta: { link: { href: "/signup?plan=solo", label: "Start with Solo" }, style: "secondary" } },
    { name: "Studio", highlight: "Most chosen", … },
  ]}
/>

The schema (`pricingBlock` in blocks/site/registry-2.ts) emits an OfferCatalog with a UnitPriceSpecification per period.

Examples

Rows (agency packages, Turkish)

Each package reads like a line on a quote: name and description, a comma list of inclusions, price and action. ₺ formatting and the “/ay” suffix come from Intl and site2LabelsTr.

Paketler

Web sitesi ve bakım

  1. Tanıtım sitesi

    Tek sayfa, iki dil, rezervasyon ve harita.

    Tasarım, Türkçe ve İngilizce metin, Google İşletme Profili kurulumu

    başlayanbaşlayan ₺45.000 Türk lirası tek sefer

    Teklif al
  2. Kurumsal site

    En çok tercih edilen

    20 sayfaya kadar, blog ve menü yönetimi.

    İçerik yönetimi, Blog, SEO denetimi, Eğitim

    başlayanbaşlayan ₺120.000 Türk lirası tek sefer

    Teklif al
  3. Aylık bakım

    Güncelleme, yedekleme ve küçük değişiklikler.

    Aylık 4 saat değişiklik, Günlük yedek, Uptime takibi

Fiyatlara KDV dahil değildir

Single package (ad retainer)

One plan: large price and action on the start side, a two-column inclusion list, and a “Not included” line.

Ad management

Google Ads, handled

Local retainer

For restaurants, spas and clinics spending $1,000–5,000 a month on Google Ads.

650 US dollars /mo

Book a 20-minute call

Included

  • Search and Performance Max campaigns
  • Call and booking conversion tracking
  • Weekly search-term cleanup
  • Monthly report in plain language
  • Landing page changesUp to 2 hours a month
  • Google Business Profile posts

Not included: Meta and TikTok ads, Creative production

Ad spend is billed by Google, not included

Quote-only plans

No price: `custom` text (“From $4,500”, “Get a quote”) takes its place.

Built to order

Every project starts with a free 30-minute call and a written quote within two working days.

  • Website

    Design, build and launch in 4–8 weeks.

    From $4,500

    Request a quote
    • Up to 20 pages
    • Two languages
    • Booking or contact flows
  • Booking system

    Calendars, deposits and reminders for multi-branch businesses.

    Get a quote

    Request a quote
    • Staff and room calendars
    • iyzico deposits
    • WhatsApp reminders

Quotes exclude VAT

API

PricingTable

PropTypeDefault
variant
Layout. A single plan always renders as single.
"columns" | "rows" | "single""columns"
plans
1–4 plans (see below).
PricingPlan[]—
billing
Which prices exist. both adds the period switch; once shows one-off prices.
"monthly" | "yearly" | "both" | "once""monthly"
defaultPeriod
Selected period with billing=both.
"monthly" | "yearly""monthly"
yearlySaving
Next to “Yearly”: “2 months free” (text, never a strikethrough).
ReactNode—
taxNote
Required by the house rules: “Prices exclude 20% VAT”.
ReactNode—
footnote
Terms under the table.
ReactNode | RichDoc—
eyebrow / title / lead
Section header; title supports one *emphasis*.
ReactNode—
labels
Built-in strings (Monthly, /mo, Not included…). site2LabelsTr for Turkish.
Partial<Site2Labels>—
locale
Intl locale for money.
string"en-US"
theme / anchor / id / className / headingLevel / components / editMode
Shared block props.
BlockBaseProps—

PricingPlan

PropTypeDefault
name / description
Plan name (h3) and one line.
ReactNode—
price
Money is { amount: decimal string, currency: ISO 4217 }. from prefixes “from”.
{ monthly?: Money; yearly?: Money; once?: Money; from?: boolean }—
custom
Shown instead of a price.
ReactNode—
features
Up to 14. Excluded features are muted with a dash and read “Not included”.
{ text; included?; note? }[]—
cta
One primary per block: the highlighted plan keeps it, other primaries become secondary.
{ link: { href, label, newTab? }; style? }—
highlight
Label text for the recommended plan.
ReactNode—