Skip to content

Components / Sections

Hero Practice

The first screen of a practice (a dentist, a doctor, a vet, a law or an accounting firm): the headline, a line of what it does, the two things a visitor comes to do (book and call) and a line for the register it is on; beside them the place as one card on a colour block, its front drawn by HomeArt, a line from OpenStatus that says whether it is open now in the place's own time zone, the address, the phone and a few rows a patient or a client asks first. Calm on purpose: the words arrive once and nothing loops.

Live demo

A dental practice in a made-up street

Unhurried dentistry, explained first

Check-ups, hygiene and treatment for adults and children, with the price agreed before any work starts.

Registered with the dental council, practice no. 12345 (a sample)

Harbour Street Dental

Open Monday to Saturday, from 8:00

14 Harbour Street London
New patients
Welcome
Children
Seen free with a parent

Live, from the library itself, at full size: scroll, hover, navigate away and back. The demo is never gated.

Variants · each row writes the attribute the prop writes; the section's own CSS answers

tone
density

Measured

JavaScript of its own

0 B

Uses OpenStatus and the shared runtime (1.9 kB raw, once per site) and Reveal. With those included: 3.9 kB raw.

CSS 16.4 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.

Browser support

Baseline · widely available

every browser. Elsewhere: nothing to fall back from.

Install Pro

The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:

terminal
npx shadcn@latest add @moonarc-pro/hero-practice
src/pages/index.astro
---
import HeroPractice from '@/components/moonarc/pro/HeroPractice.astro';
---
<HeroPractice
  eyebrow="A dental practice in the old town"
  headline="Unhurried dentistry, explained before we start"
  copy="Check-ups, hygiene and treatment for adults and children, with the price agreed before any work."
  primary={{ href: '/book/', label: 'Request an appointment' }}
  secondary={{ href: 'tel:+15550100', label: 'Call 555 0100' }}
  note="Registered with the dental council, practice no. 12345"
  place={{
    name: 'Harbour Street Dental',
    art: { kind: 'shop', seed: 'harbour street' },
    address: ['14 Harbour Street', 'Old Town'],
    phone: { label: '555 0100', href: 'tel:+15550100' },
    timezone: 'Europe/London',
    hours: [{ day: 'mon', label: 'Monday', open: '08:00', close: '18:00' }],
    rows: [{ label: 'New patients', value: 'Welcome' }],
  }}
/>

Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: home-art, open-status, reveal.

Props

PropTypeDefaultDescription
headlinestringnoneThe heading. Slot "headline" wins and may hold an <em>.
eyebrowstringnoneA short line above the heading.
copystringnoneA line under the heading.
primary{ href; label }noneThe first action: book.
secondary{ href; label }noneThe second: a tel: link, say.
notestringnoneA small line under the actions: the register and the number.
place{ name?; art?; address?; phone?; directions?; hours; timezone; openText?; closedText?; todayWord?; tomorrowWord?; fallback?; rows?; block? }noneThe card: its heading, its front drawn (HomeArt kind, seed and time), the address lines, the links, the week OpenStatus reads with its words, a few { label, value } rows and its colour block.
level1 | 21Heading level of the headline; the card's heading is one below.
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The section's ground.
density'compact' | 'cozy' | 'roomy''cozy'Block padding ×0.8 / ×1 / ×1.25 through --ma-density.

Theming and overrides

The section reads the theme contract (shadcn's variable names with the base tokens as fallback), so a pasted theme or one --ma-brand recolours it. Its class names are the override surface and stay stable; a named slot replaces the matching prop with your own markup.

Classes

.ma-hprac.ma-hprac__actions.ma-hprac__address.ma-hprac__art.ma-hprac__body.ma-hprac__card.ma-hprac__copy.ma-hprac__eyebrow.ma-hprac__headline.ma-hprac__inner.ma-hprac__links.ma-hprac__name.ma-hprac__note.ma-hprac__open.ma-hprac__primary.ma-hprac__rows.ma-hprac__secondary

Slots

slot="headline"

Reduced motion

The words and the card arrive at once; the open dot does not pulse.

With ClientRouter

CSS and Reveal.

Why it is built this way

Replaces: Practice landing heroes with a booking button. See the migration table.

Home Art

Backgrounds

A building drawn flat, for a listing that has no photograph yet: a house, a terrace, an apartment block, a villa, a cabin, a tower, an office or a shop, in the colour of the block or tone it sits on, with a shade, a light and the windows mixed from it.

every browserpointer

One line that says whether a place is open now and until when, or when it opens next, read from the week's hours in the place's own time zone, whatever the reader's clock says.

every browserload

What a practice does, by group: each group's name and a line about it on one side, its services on the other as rows, each with a line of what it is, how long it takes and what it costs from, and a link to its own page.

every browserscroll

Where to find a studio, a shop or a counter, as one card in a colour block: a drawn map with a pin, the address with a directions link, the opening hours for the week, the ways to get in touch, and above them a live line that says whether it is open now and until when (or when it opens next), with the time where the place is.

every browserload

Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown