Sales progress
Updated after every reservation. Sold homes have exchanged, reserved homes are within their 28 days to exchange, and everything else can be viewed this week.





Figures correct as of 15 October 2026. Phase 2, the courtyard wing, launches on 14 March 2027.
Ask about a homeSales progress for a development as a grid of photo cards, one per home type: a 4:3 photograph that unveils once loaded with an availability pill on it, the type and title, a three-part bar for sold, reserved and available homes and the counts beside coloured dots. A dark summary card closes the grid with the total counting up, three status figures, a note and a button.
Sales progress for a development as a grid of photo cards, one per home type: a 4:3 photograph that unveils once loaded with an availability pill on it, the type and title, a three-part bar for sold, reserved and available homes and the counts beside coloured dots. A dark summary card closes the grid with the total counting up, three status figures, a note and a button.
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.
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
npx shadcn add "https://beste.dev/r/realestate69?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/realestate69?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/realestate69.tsx plus the badge24 rule eyebrow, the button25 quiet pill used in the summary card, and the shadcn/ui button primitive it builds on.
The installed file exports realestate69Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Realestate69, realestate69Demo } from "@/components/beste/block/realestate69";
export default function Page() {
return <Realestate69 {...realestate69Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Realestate69 } from "@/components/beste/block/realestate69";
export default function Page() {
return (
<Realestate69
eyebrow="Sales progress"
heading="Where the 24 homes stand today"
description="Updated after every reservation."
rows={[
{ name: "Type A", title: "Two bedroom", sold: 2, reserved: 1, available: 5, image: { src: "https://oud.pics/b/realestate/alder-warehouse-living.webp", alt: "A double-height living room" } },
{ name: "Type E", title: "Penthouse", sold: 1, reserved: 0, available: 1, image: { src: "https://oud.pics/b/realestate/alder-roof-terrace.webp", alt: "A roof terrace over the river" } },
]}
locale="en-US"
labels={{ sold: "sold", reserved: "reserved", available: "available", homes: "Homes in phase 1", soldOut: "All sold" }}
note="Figures correct as of 15 October 2026."
button={{ label: "Ask about a home", href: "/contact" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Short line above the heading, rendered through badge24. |
heading | string | – | Section heading. |
description | string | – | Intro paragraph beside the heading. |
rows | Row[] | [] | One card per home type, in order. |
locale | string | – | Locale for the counted figures, en-US when omitted. |
labels | Labels | {} | Status words, the summary caption and the sold out pill text. |
note | string | – | Short note inside the summary card. |
button | { label: string; href: string } | – | Button at the foot of the summary card. |
className | string | – | Extra classes merged onto the section. |
type Row = {
name: string;
title: string;
sold: number;
reserved: number;
available: number;
image: { src: string; alt: string };
};
type Labels = {
sold?: string;
reserved?: string;
available?: string;
homes?: string;
soldOut?: string;
};sm, lg). With five home types the dark summary card fills the sixth cell, so the grid closes evenly on desktop.labels.soldOut when nothing is left. The bar under the title splits the type into sold (foreground), reserved (primary) and available (a faint foreground) by share; segments grow from the left one after another, and empty statuses are left out of the bar but still listed, dimmed, in the counts.Intl.NumberFormat.prefers-reduced-motion the photos, bars and figures render in their final state.