Blocks / Marketing

Pricing section

Four plans with a monthly or yearly toggle, a line of small print and a pricing FAQ in an accordion.

Width

Pricing

Priced per kitchen, not per person on the pass.

Everyone on the line gets their own login. You pay for the kitchens you run, and the free plan stays free.

Billing period
Save up to 18%

Pantry

For a small cafe finding out what it actually uses in a week.

£0 per monthFree for one kitchen, for as long as you like
Start counting
  • Included, Kitchens1
  • Included, Stock itemsUp to 150
  • Included, Counts from sales and deliveries
  • Not included, Supplier ordering
  • Not included, Waste reports
  • Not included, Transfers between sites
  • Not included, Roles and API
  • Not included, Single sign-on and a named contact

Kitchen

Most kitchens

For one busy kitchen that orders every day. Free for the first 30 days.

£39 per monthBilled monthly
Start a free trial
  • Included, Kitchens1
  • Included, Stock itemsUnlimited
  • Included, Counts from sales and deliveries
  • Included, Supplier ordering
  • Included, Waste reports
  • Not included, Transfers between sites
  • Not included, Roles and API
  • Not included, Single sign-on and a named contact

Group

For a restaurant with a bakery, or a few cafes sharing one walk-in.

£119 per monthBilled monthly
Start a group
  • Included, KitchensUp to 5
  • Included, Stock itemsUnlimited
  • Included, Counts from sales and deliveries
  • Included, Supplier ordering
  • Included, Waste reports
  • Included, Transfers between sites
  • Included, Roles and API
  • Not included, Single sign-on and a named contact

Enterprise

For groups past five sites who need single sign-on and one person to call.

CustomPriced by site, from six
Talk to us
  • Included, Kitchens6 or more
  • Included, Stock itemsUnlimited
  • Included, Counts from sales and deliveries
  • Included, Supplier ordering
  • Included, Waste reports
  • Included, Transfers between sites
  • Included, Roles and API
  • Included, Single sign-on and a named contact
  • Prices exclude VAT, which is shown at checkout.
  • Cancel from settings. We keep your data for 90 days.
  • Change plan any day, charged by the day.

Questions before you pay

Something else on your mind? Write to Priya and the team at hello@larder.example. A person answers, usually before lunch service.

What counts as a kitchen?
One place where stock is counted and food is cooked or baked. A restaurant with a bakery round the corner is two kitchens, because the flour lives in different rooms.
What happens when Pantry hits 150 stock items?
Nothing breaks. Larder keeps counting what you have, and asks you to archive slow lines or move to Kitchen before you add the 151st.
Do I need the scanner and printer to start?
No. You can check deliveries in by tapping lines on a phone. The shelf kit only makes it quicker on a Thursday with six drops before ten.
Can I pay yearly and still leave?
Yes. Cancel from settings and we refund the months you have not started, less any discount you used.
Do you charge for staff logins?
Never. Chefs, porters and front of house all get their own login on every plan, so counts are signed by the person who did them.

Install

Writes the block to components/blocks/pricing-section.tsx and its .css, and every part it uses to components/equip/, with the parts those are built from.

npx https://equip.studio311.app/equip.tgz add block:pricing-section

Built from 6 parts

Notes

  • Yearly prices are the yearly total; PricingTable divides by 12 for the headline figure and prints the total under it.
  • Every plan button has a fragment href, so the block stays a server component; pass onPlanSelect instead and add "use client".
  • The FAQ items share one name, so the browser keeps only one answer open at a time.
  • Plans list the same features in the same order, which keeps rows level across the cards.

Source

components/blocks/pricing-section.tsx168 lines
import { Accordion, AccordionItem } from "@/components/equip/accordion";
import { Heading } from "@/components/equip/heading";
import { Icon } from "@/components/equip/icon";
import { Link } from "@/components/equip/link";
import { PricingTable } from "@/components/equip/pricing-table";
import { Text } from "@/components/equip/text";
import "./pricing-section.css";

/*
 * Plans, the questions people ask before paying, and the small print said plainly.
 * Every CTA has a fragment href, so nothing here passes a function and the block stays on the server.
 */
export default function PricingSection() {
  return (
    <section className="blk-pricing-section" aria-labelledby="pricing-section-title">
      <div className="blk-pricing-section-inner">
        <header className="blk-pricing-section-head">
          <Text size="s" weight="strong" tone="quiet">
            Pricing
          </Text>
          <Heading level={2} id="pricing-section-title" className="blk-pricing-section-title">
            Priced per kitchen, not per person on the pass.
          </Heading>
          <Text size="l" tone="quiet" className="blk-pricing-section-lede">
            Everyone on the line gets their own login. You pay for the kitchens you run, and the free plan stays free.
          </Text>
        </header>

        <PricingTable
          currency="GBP"
          locale="en-GB"
          defaultBilling="monthly"
          yearlyNote="Save up to 18%"
          headingLevel={3}
          plans={[
            {
              id: "pantry",
              name: "Pantry",
              description: "For a small cafe finding out what it actually uses in a week.",
              price: { monthly: 0, yearly: 0 },
              priceNote: "Free for one kitchen, for as long as you like",
              features: [
                { label: "Kitchens", included: "1" },
                { label: "Stock items", included: "Up to 150" },
                { label: "Counts from sales and deliveries", included: true },
                { label: "Supplier ordering", included: false },
                { label: "Waste reports", included: false },
                { label: "Transfers between sites", included: false },
                { label: "Roles and API", included: false },
                { label: "Single sign-on and a named contact", included: false },
              ],
              cta: { label: "Start counting", href: "#start-pantry" },
            },
            {
              id: "kitchen",
              name: "Kitchen",
              description: "For one busy kitchen that orders every day. Free for the first 30 days.",
              price: { monthly: 39, yearly: 384 },
              features: [
                { label: "Kitchens", included: "1" },
                { label: "Stock items", included: "Unlimited" },
                { label: "Counts from sales and deliveries", included: true },
                { label: "Supplier ordering", included: true },
                { label: "Waste reports", included: true },
                { label: "Transfers between sites", included: false },
                { label: "Roles and API", included: false },
                { label: "Single sign-on and a named contact", included: false },
              ],
              cta: { label: "Start a free trial", href: "#start-kitchen" },
              highlighted: true,
              highlightLabel: "Most kitchens",
            },
            {
              id: "group",
              name: "Group",
              description: "For a restaurant with a bakery, or a few cafes sharing one walk-in.",
              price: { monthly: 119, yearly: 1188 },
              features: [
                { label: "Kitchens", included: "Up to 5" },
                { label: "Stock items", included: "Unlimited" },
                { label: "Counts from sales and deliveries", included: true },
                { label: "Supplier ordering", included: true },
                { label: "Waste reports", included: true },
                { label: "Transfers between sites", included: true },
                { label: "Roles and API", included: true },
                { label: "Single sign-on and a named contact", included: false },
              ],
              cta: { label: "Start a group", href: "#start-group" },
            },
            {
              id: "enterprise",
              name: "Enterprise",
              description: "For groups past five sites who need single sign-on and one person to call.",
              price: null,
              priceNote: "Priced by site, from six",
              features: [
                { label: "Kitchens", included: "6 or more" },
                { label: "Stock items", included: "Unlimited" },
                { label: "Counts from sales and deliveries", included: true },
                { label: "Supplier ordering", included: true },
                { label: "Waste reports", included: true },
                { label: "Transfers between sites", included: true },
                { label: "Roles and API", included: true },
                { label: "Single sign-on and a named contact", included: true },
              ],
              cta: { label: "Talk to us", href: "#contact-sales" },
            },
          ]}
        />

        <ul className="blk-pricing-section-assure" aria-label="The small print">
          <li className="blk-pricing-section-assure-item">
            <Icon name="receipt" className="blk-pricing-section-assure-icon" />
            <Text as="span" size="s" tone="quiet">
              Prices exclude VAT, which is shown at checkout.
            </Text>
          </li>
          <li className="blk-pricing-section-assure-item">
            <Icon name="archive" className="blk-pricing-section-assure-icon" />
            <Text as="span" size="s" tone="quiet">
              Cancel from settings. We keep your data for 90 days.
            </Text>
          </li>
          <li className="blk-pricing-section-assure-item">
            <Icon name="refresh" className="blk-pricing-section-assure-icon" />
            <Text as="span" size="s" tone="quiet">
              Change plan any day, charged by the day.
            </Text>
          </li>
        </ul>

        <div className="blk-pricing-section-faq">
          <div className="blk-pricing-section-faq-head">
            <Heading level={3} size="l" id="pricing-section-faq-title">
              Questions before you pay
            </Heading>
            <Text tone="quiet">
              Something else on your mind? Write to Priya and the team at{" "}
              <Link href="#contact-sales">hello@larder.example</Link>
              . A person answers, usually before lunch service.
            </Text>
          </div>
          <Accordion className="blk-pricing-section-accordion">
            <AccordionItem name="pricing-section-faq" summary="What counts as a kitchen?" open>
              One place where stock is counted and food is cooked or baked. A restaurant with a bakery round the corner
              is two kitchens, because the flour lives in different rooms.
            </AccordionItem>
            <AccordionItem name="pricing-section-faq" summary="What happens when Pantry hits 150 stock items?">
              Nothing breaks. Larder keeps counting what you have, and asks you to archive slow lines or move to Kitchen
              before you add the 151st.
            </AccordionItem>
            <AccordionItem name="pricing-section-faq" summary="Do I need the scanner and printer to start?">
              No. You can check deliveries in by tapping lines on a phone. The shelf kit only makes it quicker on a
              Thursday with six drops before ten.
            </AccordionItem>
            <AccordionItem name="pricing-section-faq" summary="Can I pay yearly and still leave?">
              Yes. Cancel from settings and we refund the months you have not started, less any discount you used.
            </AccordionItem>
            <AccordionItem name="pricing-section-faq" summary="Do you charge for staff logins?">
              Never. Chefs, porters and front of house all get their own login on every plan, so counts are signed by
              the person who did them.
            </AccordionItem>
          </Accordion>
        </div>
      </div>
    </section>
  );
}
components/blocks/pricing-section.css113 lines
@layer blocks {
  .blk-pricing-section {
    container: blk-pricing-section / inline-size;
    background: var(--eq-bg);
    color: var(--eq-ink);
  }

  .blk-pricing-section-inner {
    display: grid;
    gap: calc(var(--eq-space-6) * 1.25);
    max-width: 76rem;
    margin-inline: auto;
    padding: calc(var(--eq-space-6) * 1.5) var(--eq-space-4);
  }

  .blk-pricing-section-head {
    display: grid;
    justify-items: center;
    gap: var(--eq-space-3);
    max-width: 40rem;
    margin-inline: auto;
    text-align: center;
  }

  .blk-pricing-section-head > * {
    margin: 0;
  }

  .blk-pricing-section-title {
    font-size: clamp(1.75rem, 5.5cqi, 3rem);
    line-height: 1.06;
    letter-spacing: -0.025em;
    text-wrap: balance;
  }

  .blk-pricing-section-lede {
    max-width: 34rem;
    text-wrap: pretty;
  }

  /* The small print, set like the foot of a till receipt: a torn dashed edge and short lines. */
  .blk-pricing-section-assure {
    display: grid;
    gap: var(--eq-space-3);
    margin: 0;
    margin-top: calc(var(--eq-space-6) * -0.5);
    padding: var(--eq-space-4) 0 0;
    list-style: none;
    border-top: 1px dashed var(--eq-line-strong);
  }

  .blk-pricing-section-assure-item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    gap: var(--eq-space-2);
    margin: 0;
  }

  .blk-pricing-section-assure-item > p,
  .blk-pricing-section-assure-item > span {
    margin: 0;
  }

  .blk-pricing-section-assure-icon {
    margin-top: 1px;
    color: var(--eq-ink-3);
  }

  .blk-pricing-section-faq {
    display: grid;
    gap: var(--eq-space-5);
    padding-top: calc(var(--eq-space-6) * 1.25);
    border-top: 1px solid var(--eq-line);
  }

  .blk-pricing-section-faq-head {
    display: grid;
    align-content: start;
    gap: var(--eq-space-3);
    max-width: 26rem;
  }

  .blk-pricing-section-faq-head > * {
    margin: 0;
  }

  .blk-pricing-section-accordion {
    min-width: 0;
  }

  @container blk-pricing-section (width >= 40rem) {
    .blk-pricing-section-inner {
      padding-inline: var(--eq-space-6);
    }

    .blk-pricing-section-assure {
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: var(--eq-space-5);
    }
  }

  @container blk-pricing-section (width >= 56rem) {
    .blk-pricing-section-inner {
      padding-block: calc(var(--eq-space-6) * 2.5);
    }

    .blk-pricing-section-faq {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
      gap: calc(var(--eq-space-6) * 1.5);
    }
  }
}

EqUIp is in beta: free for non-commercial use, no warranty, and things can change. Terms

Nothing picked yet. Press A on a part, or use the plus on the board, and the install command builds here.

Loading the index.

Loading the index