
A note from the house
My grandparents built the first four rooms with stone from the hill behind us. We added the rest slowly, one winter at a time, and kept the walls thick and the windows small so the house stays cool in August.
There is no lobby and no television. There is a long table under the vine, a hammam under the oldest room and a path down to the water that takes six minutes if you stop to pick figs.
Write to us before you come. We would like to know how you take your coffee.
A text-led hotel hero written as a letter from the owners: a tall photograph rises open and settles from a slight zoom on one side, while a serif headline, letter paragraphs with a drop cap arriving one after another and an italic signature with a hand-drawn underline fill the other, closed by a book pill and a write-to-us link.
A tall photograph wipes open from the top on one side while a serif headline, a letter from the owners with a drop cap, and an italic signature whose underline draws itself in arrive one after another on the other.
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/hotel23?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/hotel23?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/hotel23.tsx plus the button22 sliding-marker pill for the booking button and the text1 word stagger for the headline.
The installed file exports hotel23Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Hotel23, hotel23Demo } from "@/components/beste/block/hotel23";
export default function Page() {
return <Hotel23 {...hotel23Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Hotel23 } from "@/components/beste/block/hotel23";
export default function Page() {
return (
<Hotel23
eyebrow="A note from the house"
heading="Welcome to a house, not a hotel."
letter={[
"My grandparents built the first four rooms with stone from the hill behind us.",
"There is no lobby and no television, just a long table under the vine.",
"Write to us before you come. We would like to know how you take your coffee.",
]}
signature={{ name: "Joanna Newsom", role: "Ostria, second generation" }}
button={{ label: "Book a stay", href: "/book", tone: "dark" }}
link={{ label: "Write to the house", href: "mailto:[email protected]" }}
image={{
src: "https://oud.pics/b/hotel/ostria-reception.webp",
alt: "A limestone reception counter with olive branches and a brass key",
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Small line above the heading |
heading | string | – | Serif <h1>, staggered word by word through Text1 |
letter | string[] | [] | Letter paragraphs; the first one gets a drop cap |
signature | Signature | – | Italic signed name with an underline, plus a role line |
button | ActionButton | – | Primary pill action, dark tone when none is set |
link | TextLink | – | Text link with an arrow next to the button |
image | Image | – | The tall photograph; its column is omitted without it |
className | string | – | Extra classes for the outer <section> |
type Signature = {
name: string;
role: string;
};
type ActionButton = {
label: string;
href: string;
tone?: "primary" | "light" | "dark" | "outline";
};
type TextLink = {
label: string;
href: string;
};
type Image = {
src: string;
alt: string;
};clip-path wipe from the top over 1.6s; inside it the image eases from a 1.32 scale and a 24px blur to 1.16 and sharp, but only once the image has loaded.top-24 next to the letter.first-letter: utilities, so no extra markup is needed in the string.