The warehouse homes
The warehouse keeps its double-height volumes and tall arched windows. Every home on the river side gets the long afternoon light across brick, oak and polished concrete.
A split media section for a development: a 4:3 muted looping video on the left that is unveiled top to bottom once it can play and drifts against the scroll, with a round play and pause toggle in its corner, beside a rule eyebrow, a heading, a lead paragraph, three figures on hairline rows and a pill button on the right.
A split media section for a development's sales page: a 4:3 video on the left that plays muted on a loop, is unveiled from the top once the browser can play it and drifts slowly against the scroll, with a round play and pause toggle sitting in its corner. On the right, a rule eyebrow, a heading, a lead paragraph, three figures with their captions on hairline rows and a pill button to the residences.
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/realestate63?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/realestate63?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/realestate63.tsx plus the badge24 rule eyebrow, the button25 quiet pill used for the button, and the shadcn/ui button primitive behind it.
The installed file exports realestate63Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Realestate63, realestate63Demo } from "@/components/beste/block/realestate63";
export default function Page() {
return <Realestate63 {...realestate63Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Realestate63 } from "@/components/beste/block/realestate63";
export default function Page() {
return (
<Realestate63
eyebrow="The warehouse homes"
heading="Rooms built for the light off the river."
description="The warehouse keeps its double-height volumes and tall arched windows."
video={{
src: "https://oud.pics/b/hotel/ostria-video-sea-suite.mp4",
poster: "https://oud.pics/b/realestate/alder-warehouse-living.webp",
label: "A slow pan across a double-height warehouse living room",
}}
facts={[
{ value: "5.4 m", label: "Ceiling height in the warehouse living rooms" },
{ value: "3.1 m", label: "Restored arched windows with slim oak frames" },
]}
button={{ label: "View the warehouse homes", href: "/residences" }}
labels={{ play: "Play video", pause: "Pause video" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Short line above the heading, rendered through badge24. |
heading | string | – | Section heading. |
description | string | – | Lead paragraph under the heading. |
video | { src: string; poster: string; label: string } | – | The clip, its poster frame and the accessible name of the video; without it the text spans the full width. |
facts | Fact[] | [] | Figures with captions, one per hairline row. |
button | { label: string; href: string } | – | Pill button under the facts. |
labels | Labels | {} | Accessible names for the two states of the toggle. |
className | string | – | Extra classes merged onto the section. |
type Fact = { value: string; label: string };
type Labels = { play?: string; pause?: string };autoPlay muted loop playsInline with preload="metadata"; the frame stays a flat bg-muted panel until the canplay event fires (or readyState already allows playback on mount) and the frame has scrolled into view, then opens with a top-to-bottom clip over 1.6 s while the video settles from 1.18 to 1.12 scale.useScroll on the frame itself; with prefers-reduced-motion the drift is zero, the frame renders open and the clip is paused as soon as it can play.play() or pause() on the element and reads the actual state back from the play and pause events, so the icon stays right even when the browser blocks autoplay; its accessible name switches between labels.play and labels.pause.tabular-nums so values of the same length line up; the caption of each fact is kept to one short line at text-sm.