Finishes
Every home comes in one of two palettes put together by Agnes Obel Interiors. Pick one and the five finishes that change are listed beside the kitchen it makes.
Palettes
What changes
Palettes are chosen at reservation and cannot be mixed. Samples of every finish are at the sales suite.

A finishes picker for a development: two palettes listed as rows of five round swatches with a name and a mood line, the chosen one carrying a primary bar; picking a palette cross-fades the 4:3 kitchen photograph beside it and swaps the list of what changes (floor, cabinets, worktop, tiles, ironmongery) under hairlines, with a note about choosing at reservation.
A finishes picker for a development's sales page. Two palettes are listed as rows, each with a name, a mood line and five round swatches, the chosen one carrying a primary bar on its left edge. Picking a palette cross-fades the 4:3 kitchen photograph beside the list and swaps the list of what changes (floor, cabinets, worktop, tiles, ironmongery) under hairlines, and a note explains that palettes are chosen whole at reservation.
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/realestate35?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/realestate35?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/realestate35.tsx plus the badge24 eyebrow; it uses no shadcn/ui primitives.
The installed file exports realestate35Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Realestate35, realestate35Demo } from "@/components/beste/block/realestate35";
export default function Page() {
return <Realestate35 {...realestate35Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Realestate35 } from "@/components/beste/block/realestate35";
export default function Page() {
return (
<Realestate35
eyebrow="Finishes"
heading="Two palettes, chosen whole"
description="Pick one and the finishes that change are listed beside the kitchen it makes."
palettes={[
{
name: "Light oak",
title: "Pale, warm, morning light",
swatches: [
{ hex: "#D9C3A0", name: "European oak" },
{ hex: "#E8E4DC", name: "Limestone" },
{ hex: "#8B8F86", name: "Brushed steel" },
],
image: { src: "https://oud.pics/b/realestate/alder-courtyard-kitchen.webp", alt: "An open kitchen with pale oak cabinets and a limestone island" },
changes: [
{ label: "Floor", value: "Wide European oak boards, matt oiled" },
{ label: "Worktop", value: "Honed limestone, 30 mm" },
{ label: "Ironmongery", value: "Brushed stainless steel" },
],
},
{
name: "Dark stone",
title: "Deep, quiet, evening light",
swatches: [
{ hex: "#5A4636", name: "Smoked oak" },
{ hex: "#3E3F3B", name: "Basalt" },
{ hex: "#4A3B2E", name: "Bronze" },
],
image: { src: "https://oud.pics/b/realestate/alder-dining-dusk.webp", alt: "A long oak dining table at dusk with the river lights beyond" },
changes: [
{ label: "Floor", value: "Smoked oak boards, matt oiled" },
{ label: "Worktop", value: "Honed basalt, 30 mm" },
{ label: "Ironmongery", value: "Unlacquered bronze" },
],
},
]}
palette={0}
labels={{ palettes: "Palettes", changes: "What changes" }}
note="Palettes are chosen at reservation and cannot be mixed."
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Short line above the heading, drawn with a rule in front of it. |
heading | string | – | Section heading. |
description | string | – | Intro paragraph beside the heading. |
palettes | Palette[] | [] | The palettes offered; two is the intended count, more are listed as further rows. |
palette | number | – | Index of the palette selected on load; the first when omitted. |
labels | Labels | {} | Captions over the palette list and over the list of changes. |
note | string | – | Short note under the list of changes. |
className | string | – | Extra classes merged onto the section. |
type Swatch = { hex: string; name: string };
type Palette = {
name: string;
title: string;
swatches: Swatch[];
image: { src: string; alt: string };
changes: { label: string; value: string }[];
};
type Labels = {
palettes?: string;
changes?: string;
};hex of each finish through an inline style; the swatch name is read out to screen readers and shown as a tooltip. Swatches scale in from 0.6 after their row rises.aria-pressed.load event and on scrolling into view, then opens from the top over 1.6 s while the image settles from a slight zoom. A later pick mounts the new image over the old one and cross-fades them over about 0.8 s; a small parallax moves the frame's image from -6% to 6% against the scroll.prefers-reduced-motion the photograph shows at once, the parallax is held still and lists swap without the rise.