Skip to content

Components / Sections

Listing Hero

The first screen of an estate agency: the headline, a line, two actions and a few figures on one side, and on the other the homes on the market now, one large and two small, each its building drawn by HomeArt with the price and the street on a card over it, every one a link to its page. The large one is drawn at dusk with its windows lit. A home can carry a view-transition-name so its card grows into its page. Zero JavaScript.

Live demo

Estate agents in a made-up city

Homes you can picture

Homes to buy across four neighbourhoods, each measured and drawn up by its agent. Sample prices.

homes for sale
7
to sell, on average
23 days

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 Reveal and the shared runtime (1.9 kB raw, once per site). With those included: 3.0 kB raw.

CSS 17.7 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-listing
src/pages/index.astro
---
import HeroListing from '@/components/moonarc/pro/HeroListing.astro';
---
<HeroListing
  eyebrow="Estate agents in the city since 2009"
  copy="Homes to buy across six neighbourhoods, each one visited and measured by us."
  primary={{ href: '/homes/', label: 'See every home' }}
  secondary={{ href: '/contact/', label: 'Value my home' }}
  facts={[{ value: '86', label: 'homes for sale' }, { value: '23 days', label: 'to sell, on average' }]}
  homes={[
    { href: '/homes/12-linden-row/', price: '$845,000', title: '12 Linden Row', meta: '4 beds · 2 baths', art: { kind: 'house', seed: '12 Linden Row', block: 2 } },
    { href: '/homes/4-quay-street/', price: '$520,000', title: '4 Quay Street', art: { kind: 'apartment', seed: '4 Quay Street', block: 3 } },
  ]}
>
  <span slot="headline">A home you can <em>picture</em></span>
</HeroListing>

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

Props

PropTypeDefaultDescription
homes{ href; price; title; meta?; art; transition? }[]noneOne to three homes: the first large, the others small. art is HomeArt's kind, seed, time and block; transition is a view-transition-name for the picture.
headlinestringnoneThe headline, split by word. Slot "headline" wins and may hold an <em>.
eyebrowstringnoneA short line above the headline.
copystringnoneA paragraph under the headline.
primary{ href: string; label: string }noneThe main action.
secondary{ href: string; label: string }noneThe second action.
facts{ value: string; label: string }[]noneA few figures under the actions.
labelstring'Homes on the market'What the homes are, read before them.
level1 | 21Heading level of the headline.
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The hero'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-hlist.ma-hlist__actions.ma-hlist__art.ma-hlist__card.ma-hlist__copy.ma-hlist__eyebrow.ma-hlist__facts.ma-hlist__headline.ma-hlist__home.ma-hlist__homes.ma-hlist__inner.ma-hlist__link.ma-hlist__meta.ma-hlist__price.ma-hlist__primary.ma-hlist__secondary.ma-hlist__title

Slots

slot="headline"

Reduced motion

The headline and the homes are there at once.

With ClientRouter

CSS and Reveal.

Why it is built this way

Replaces: Real estate template heroes with a search bar over a photograph. 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

Firing 08 is on the shelf

Clay for the table, thrown slowly

Cups, bowls and vases thrown by hand and fired a few dozen at a time.

Fired
Every six weeks
Batch
About 120 pieces
Made by
Two pairs of hands
  • Tall vase32 cm · StonewarePrice: $86

  • Morning cup300 ml · Two glazesPrice: $24

  • Breakfast bowl16 cm · Speckled clayPrice: $32

Show a piece

The first screen of a maker's site: the heading, a line, two actions and three facts on one side; on the other, the products themselves, each drawn on its plate (ProductArt) with its name, a spec line in the mono face and its price.

newly · Chrome 105 · Firefox 121 · Safari 15.4loadclick

The Boathouse

Southbank, on the river path

$1,150,000 Guide price (a sample)

Bedrooms
4
Bathrooms
3
Floor area
204 m²
Built
2019

Book a viewing

The top of a home's own page: its pictures on one side, each a building drawn by HomeArt under a Lens that magnifies it at the pointer, with a row of thumbnails that picks one (radios and :has(), so the arrow keys move along them); on the other side the price, the title, the address, the facts and two actions.

newly · Chrome 105 · Firefox 121 · Safari 15.4clickpointer

Homes for sale

Pick a kind and the least bedrooms: the cards filter with no script. Sample homes and prices.

Kind
Bedrooms

6 homes6 homes5 homes3 homes2 homes3 homes3 homes3 homes3 homes2 homes3 homes3 homes2 homes0 homes0 homes

No home matches. Try fewer bedrooms or another kind.No home matches. Try fewer bedrooms or another kind.

Homes as cards (the building drawn by HomeArt, the price, the address, the beds, the baths and the area) with filters that work with no script: a group of radios for the kind of home and one for the least bedrooms, and :has() rules written for the list at build hide every card that does not match.

newly · Chrome 105 · Firefox 121 · Safari 15.4clickscroll

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