Seats Calculator

Team pricing

Onepriceperseat.Countyourteam.

Everyone on the plan gets the whole library. Add and remove people whenever the team changes.

Two months free on yearly

Seats

4

$10 per seat, per month

Your total

$480/ year

Your total $480 / year
  • Every section, piece and component
  • Agent access over MCP for each seat
  • Shared themes across projects
  • Version history on every page
  • Priority support

Seats can be added mid-cycle and are charged for the remaining days only.

About this block

Seats CalculatorPRO

A per-seat pricing panel in ink under a centred serif headline that settles in word by word: a monthly or yearly pill switch, a seat count with round plus and minus steppers, the per-seat rate, and a large serif total that blurs to each new value; on the right the included features and a full-width light sliding-marker pill.

Pricing81: Seats Calculator

A per-seat panel in ink: step the team size up or down, switch between monthly and yearly, and watch the total blur to its new figure.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://ui.beste.co/r/pricing81?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://ui.beste.co/r-base/pricing81?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/pricing81.tsx plus the button22 sliding-marker pill and the text1 word stagger it uses.

Quick start

The installed file exports pricing81Demo alongside the block: the exact props behind the preview above. Spread it to get a working pricing section in one line.

tsx
import { Pricing81, pricing81Demo } from "@/components/beste/block/pricing81";

export default function Page() {
  return <Pricing81 {...pricing81Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Pricing81 } from "@/components/beste/block/pricing81";

export default function Page() {
  return (
    <Pricing81
      eyebrow="Team pricing"
      heading="One price per seat. Count your team."
      description="Everyone on the plan gets the whole library."
      labels={{
        monthly: "Monthly",
        yearly: "Yearly",
        seats: "Seats",
        perSeat: "per seat, per month",
        perMonth: "/ month",
        perYear: "/ year",
        total: "Your total",
        saving: "Two months free on yearly",
        fewer: "Fewer seats",
        more: "More seats",
      }}
      pricePerSeat={{ monthly: 12, yearly: 10 }}
      currency="$"
      minSeats={1}
      maxSeats={50}
      defaultSeats={4}
      yearlyDefault
      features={["Every section and component", "Shared themes across projects"]}
      button={{ label: "Start the team plan", href: "/signup" }}
      note="Seats can be added mid-cycle."
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring–Small-caps line above the heading
headingstring–Section heading, through Text1
descriptionstring–Paragraph under the heading
labelsLabels{ monthly: "Monthly", seats: "Seats", total: "Your total", ... }Wording of the switch, the steppers and the figures
pricePerSeat{ monthly: number; yearly: number }{ monthly: 12, yearly: 10 }Monthly rate per seat on each cycle
currencystring"$"Symbol prefixed to every figure
minSeatsnumber1Lower bound of the stepper
maxSeatsnumber50Upper bound of the stepper
defaultSeatsnumber1Seat count on load
yearlyDefaultbooleanfalseOpens on the yearly cycle
featuresstring[][]What the plan includes, listed on the right
button{ label: string; href: string }–Full-width pill under the features
notestring–Small print under the pill
classNamestring–Extra classes for the outer <section>
ts
type Labels = {
  monthly: string;
  yearly: string;
  seats: string;
  perSeat: string;
  perMonth: string;
  perYear: string;
  total: string;
  saving?: string;
  fewer: string;
  more: string;
};

Behavior notes

  • The switch is a radiogroup of two buttons with an ink marker that slides between them through a shared layoutId, so the movement comes from the layout engine rather than a hand-written transform.
  • Prices swap inside an inline-grid where both values share one cell, which lets the number keep its natural width so the unit label always sits right beside it.
  • The saving note collapses its width and margin together rather than unmounting, so the switch drifts back to its resting position instead of jumping when you leave the yearly cycle.
  • This is the one pricing block that takes numbers rather than strings, because it multiplies. The yearly total is the monthly rate times twelve times the seat count, so the saving is expressed in the rate and not in a separate discount.
  • Figures are formatted with toLocaleString("en-US") at render, which is what puts the separator in a four-figure total.
  • The stepper clamps against minSeats and maxSeats on every press rather than disabling the buttons, so holding one down at the boundary does nothing instead of jumping.
  • The whole total is repeated in a visually hidden live region including its unit, since the number alone would be announced without saying what changed.
  • Tick icons use text-current rather than the accent, because an accent-coloured icon disappears against the ink panel.

More Pricing blocks

View all Pricing
PRO

pricing68

Seat Slider Price Calculator

PRO

pricing13

Per-Seat Calculator

PRO

pricing84

Usage Pricing Calculator

Get Pro access