Alpha: Ships on npm at 7.0.0-alpha.07.0.0-alpha.0

api-product

Say what a Business sells: hero, proof, features, plans and a closing, in the order a buyer reads them.

Theme

7 pages in 4 Businesses name api-product in this build.

Use api-product for the pages that sell: a landing and a pricing page. The hero states the offer and its two actions, proof and features follow in the order a buyer asks, OfferTiles price it, and a closing repeats the one action that matters. Despite the name, it fits any Product or Service, not only an API.

Sections in order

Vanroster /pricing, Harbor tides /pricing

Fields that matter

Section typeFieldTypeBoundsRefused as
herotitlestring ≤641–64hero.title
heroledestring ≤2601–260hero.lede
heroactions0–2 × object≤2hero.actions
feature-griditems2–8 × object2–8feature-grid.items
pricingtiers1–4 × object1–4pricing.tiers
pricingtiers[].features1–10 × string ≤561–10pricing.tiers.features
Every field of hero
FieldTypeReqBoundsRefusal
layout"centered" | "split"yes—
stack560 | 640yes—
kickerobject—
kicker.kind"eyebrow"yes—
kicker.textstring ≤40yes1–40hero.kicker.text
titlestring ≤64yes1–64hero.title
ledestring ≤260yes1–260hero.lede
actions0–2 × objectyes≤2hero.actions
actions[].hrefstring ≤160yes1–160hero.actions.href
actions[].labelstring ≤24yes1–24hero.actions.label
actions[].kind"solid" | "ghost"yes—
actions[].iconicon or mark name (52)—
actions[].externalboolean—
commandobject—
command.commandstring ≤40yes1–40hero.command.command
command.notestring ≤481–48hero.command.note
fine0–4 × string ≤72yes≤4hero.fine
specimenobject—
specimen.panel"none" | "field"—
specimen.blocks1–3 × Section type (nested)yes1–3hero.specimen.blocks
Every field of feature-grid
FieldTypeReqBoundsRefusal
head.eyebrowstring ≤28yes1–28feature-grid.head.eyebrow
head.titlestring ≤721–72feature-grid.head.title
head.ledestring ≤3001–300feature-grid.head.lede
head.maxstring (pattern)—
head.ledeMaxstring (pattern)—
head.balanceboolean—
head.scale"compact" | "large"—
head.tagstring ≤81–8feature-grid.head.tag
head.layout"split"—
asideobject—
aside.commandstring ≤12yes1–12feature-grid.aside.command
aside.notestring ≤40yes1–40feature-grid.aside.note
cellHead"label" | "icon-index" | "icon-label" | "icon" | "none"yes—
denseboolean—
items2–8 × objectyes2–8feature-grid.items
items[].iconicon or mark name (52)—
items[].labelstring ≤241–24feature-grid.items.label
items[].indexstring ≤21–2feature-grid.items.index
items[].titlestring ≤401–40feature-grid.items.title
items[].textstring ≤2001–200feature-grid.items.text
items[].hrefstring ≤1601–160feature-grid.items.href
items[].linkLabelstring ≤241–24feature-grid.items.linkLabel
Every field of pricing
FieldTypeReqBoundsRefusal
head.eyebrowstring ≤28yes1–28pricing.head.eyebrow
head.titlestring ≤721–72pricing.head.title
head.ledestring ≤3001–300pricing.head.lede
head.maxstring (pattern)—
head.ledeMaxstring (pattern)—
head.balanceboolean—
head.scale"compact" | "large"—
head.tagstring ≤81–8pricing.head.tag
head.layout"split"—
layout"ruled" | "cards"yes—
tiers1–4 × objectyes1–4pricing.tiers
tiers[].namestring ≤16yes1–16pricing.tiers.name
tiers[].pricestring ≤16yes1–16pricing.tiers.price
tiers[].notestring ≤241–24pricing.tiers.note
tiers[].descstring ≤801–80pricing.tiers.desc
tiers[].features1–10 × string ≤56yes1–10pricing.tiers.features
tiers[].ctastring ≤40yes1–40pricing.tiers.cta
tiers[].hrefstring ≤160yes1–160pricing.tiers.href
tiers[].featuredboolean—
featuredBadgestring ≤16yes1–16pricing.featuredBadge
notestring ≤1201–120pricing.note

Starter record

Vanrosterpages/vanroster/home.json8.7 KB api-product.json
{
  "$schema": "https://next.mdxui.dev/schema.json",
  "theme": "callboard",
  "frame": "none",
  "template": "api-product",
  "title": "Vanroster: every crew on the right job",
  "description": "Crew scheduling for field-service teams. Vanroster matches each job to a crew with the skills, the van and the shortest drive.",
  "sections": [
    {
      "kind": "nav",
      "shell": {"inset":"bleed","density":"none","surface":"glass","sticky":true},
      "block": {
        "type": "nav",
        "menu": "push",
        "collapse": 880,
        "brand": {"href":"/","text":"Vanroster","mark":"radar"},
        "links": [
          ["/product/dispatch","Dispatch"],
          ["/pricing","Pricing"],
          ["/changelog","Changelog"],
          ["/security","Security"]
        ],
        "cta": {"href":"/contact","label":"Book a walkthrough"}
      }
    },
    {
      "kind": "hero",
      "shell": {"inset":"contained","density":"hero","background":"glow"},
      "block": {
        "type": "hero",
        "layout": "split",
        "stack": 640,
        "title": "Every crew on the right job.",
        "lede": "Vanroster matches each job to a crew with the right skills, the right van and the shortest drive. Move a job on the board, and every crew phone follows.",
        "actions": [
          {"href":"/contact","label":"Book a walkthrough","kind":"solid"},
          {"href":"/pricing","label":"See the plans","kind":"ghost"}
        ],
        "fine": ["14-day trial, no payment details","Office users free on every plan"],
        "specimen": {
          "panel": "field",
          "blocks": [
            {
              "type": "terminal",
              "variant": "plain",
              "title": "Board · Tue 13 Oct · 07:42",
              "lines": [
                "@dim{CREW  VAN   JOB                 WINDOW        DRIVE}",
                "A-1   V-12  Boiler service      08:00-10:00   14 min",
                "A-1   V-12  Heat pump install   10:30-13:00    9 min",
                "@dim{B-2   V-07  Out today: 2 jobs moved}",
                "C-3   V-03  Panel upgrade       08:00-11:00   22 min",
                "C-3   V-03  @acc{Boiler service}  ←B2 11:30-12:30    @pass{6 min}",
                "D-4   V-15  @acc{Gas leak check}  ←B2 13:00-14:00   @pass{11 min}",
                "D-4   V-15  Water heater swap   14:30-16:30   18 min",
                "",
                "@pass{2 customers texted a new window}"
              ]
            }
          ]
        }
      }
    },
    {
      "kind": "band",
      "shell": {"inset":"contained","density":"compact"},
      "block": {
        "type": "stats",
        "items": [
          {"value":"400","label":"Crews on one board, on every plan","icon":"layout-grid"},
          {"value":"12","label":"Skills a job can require, from gas to height","icon":"badge-check"},
          {"value":"30 min","label":"Arrival window texted to each customer","icon":"clock"}
        ]
      }
    },
    {
      "kind": "section",
      "shell": {"inset":"contained","density":"section"},
      "block": {
        "type": "feature-grid",
        "cellHead": "icon",
        "head": {
          "eyebrow": "The board",
          "title": "One board runs the whole day.",
          "lede": "Office staff plan on the board. Crews work from one ordered list on their phones."
        },
        "items": [
          {
            "icon": "map-pin",
            "title": "Drive time, not distance",
            "text": "Jobs are ordered by the drive between them, from road times at the hour of the job."
          },
          {
            "icon": "badge-check",
            "title": "Skills before speed",
            "text": "A gas job reaches only a crew with a gas licence on file and in date."
          },
          {
            "icon": "refresh-cw",
            "title": "Swaps in one drag",
            "text": "Drag a job to another crew. Both crew phones update before the drag ends."
          },
          {
            "icon": "bell",
            "title": "Customers told once",
            "text": "Each customer gets one text with a 30-minute window, and one when the van leaves."
          },
          {
            "icon": "clock",
            "title": "Overtime flagged",
            "text": "A day that keeps a crew past 10 hours turns amber before anyone assigns it."
          },
          {
            "icon": "shield-check",
            "title": "Every change logged",
            "text": "Who moved which job, when and why, kept for up to 7 years."
          }
        ]
      }
    },
    {
      "kind": "section",
      "shell": {"inset":"contained","density":"section","surface":"tint"},
      "block": {
        "type": "feature-split",
        "head": {"eyebrow":"A sick call at 07:40","title":"Re-plan the day in one move."},
        "items": [
          {
            "icon": "x",
            "title": "Mark the crew out",
            "text": "One tap clears the crew and lists every job it held that day."
          },
          {
            "icon": "radar",
            "title": "Accept the re-plan",
            "text": "Each job goes to the nearest crew that holds every skill it needs."
          },
          {
            "icon": "message-square",
            "title": "Tell the customers",
            "text": "Each changed window goes out as one text, with the new time."
          }
        ],
        "specimen": {
          "blocks": [
            {
              "type": "terminal",
              "variant": "plain",
              "title": "Text to the customer · 07:43",
              "lines": [
                "Your boiler service today moved to 11:30-12:30.",
                "Crew C-3 is coming in van V-03.",
                "",
                "@dim{A second text arrives when the van leaves.}",
                "@dim{Reply 1 to keep the time, 2 to pick another day.}"
              ]
            }
          ]
        }
      }
    },
    {
      "kind": "section",
      "shell": {"inset":"contained","density":"section"},
      "block": {
        "type": "compare",
        "head": {"eyebrow":"Against the whiteboard","title":"A board that moves with the day."},
        "cons": {
          "label": "Whiteboard and calls",
          "items": [
            "Jobs assigned from memory",
            "Licences checked by phone",
            "Customers call to ask",
            "Swaps lost by noon"
          ]
        },
        "pros": {
          "label": "Vanroster",
          "items": [
            "Jobs matched to skills",
            "Licences checked on assign",
            "Customers get a window",
            "Every swap on record"
          ]
        }
      }
    },
    {
      "kind": "closing",
      "shell": {"inset":"contained","density":"closing","surface":"plate"},
      "block": {
        "type": "closing",
        "layout": "split",
        "head": {
          "eyebrow": "14-day trial",
          "title": "Plan tomorrow on Vanroster.",
          "lede": "Import crews and jobs from three spreadsheets. The first board is ready the same afternoon."
        },
        "specimen": {
          "blocks": [
            {
              "type": "terminal",
              "variant": "plain",
              "title": "Import · 3 files",
              "lines": [
                "crews.csv    14 crews, 14 vans, 2 depots",
                "skills.csv   38 licences, @acc{3 expire this year}",
                "jobs.csv     212 jobs over the next 10 days",
                "",
                "@pass{Board ready: 212 jobs on 14 crews}"
              ]
            }
          ]
        },
        "actions": [
          {"href":"/contact","label":"Book a walkthrough","kind":"solid"},
          {"href":"/product/dispatch","label":"Tour Dispatch","kind":"ghost"}
        ]
      }
    },
    {
      "kind": "footer",
      "shell": {"inset":"contained","density":"footer"},
      "block": {
        "type": "footer",
        "layout": "areas",
        "brand": {"href":"/","text":"Vanroster","mark":"radar"},
        "blurb": "Crew scheduling for field-service teams: heating, electrical, plumbing, cleaning and grounds.",
        "columns": [
          {
            "title": "Product",
            "links": [["/product/dispatch","Dispatch"],["/pricing","Pricing"],["/changelog","Changelog"]]
          },
          {"title":"Company","links":[["/security","Security"],["/contact","Contact"]]},
          {
            "title": "For agents",
            "links": [["/product/dispatch","The Dispatch API"],["/records.zip","Site records (.zip)"]]
          }
        ],
        "cta": {"href":"/contact","label":"Book a walkthrough","icon":"arrow-right"},
        "note": [
          "Vanroster is a worked example on mdxui.dev, not a customer.",
          "Rendered by @mdxui/site. Forms here do not send."
        ]
      }
    }
  ]
}

Other Templates

Sidework
blog

5 pages · 4 of 6 Businesses

Sidework
post

4 pages · 4 of 6 Businesses

Ledgerhouse
article

24 pages · 6 of 6 Businesses

Ledgerhouse
contact

6 pages · 6 of 6 Businesses

On this page