Visit
Most Thursdays we keep the late afternoon free for visits. You can sit in the chair, see the light, and leave without booking.
Where
Rua da Prata 12, second floor1100-415 Lisbon
Four minutes on foot from Baixa-Chiado. There is a lift to the door and a quiet room to wait in.
When
A visit-us section: a photograph drifting inside its frame on the left, and on the right a serif heading that settles in word by word, an intro, a ruled sheet with the serif address, directions and opening hours, a sliding-marker pill and a text link.
A visit page rather than a booking form: a portrait photograph drifting inside its frame beside the invitation, then address and opening hours side by side under one rule, closed by a pill action and a quieter second link.
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://ui.beste.co/r/booking31?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/booking31?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/booking31.tsx plus the button22 sliding-marker pill and the text1 word stagger it uses.
The installed file exports booking31Demo alongside the block: the exact props behind the preview above. Spread it to get a working visit section in one line.
import { Booking31, booking31Demo } from "@/components/beste/block/booking31";
export default function Page() {
return <Booking31 {...booking31Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Booking31 } from "@/components/beste/block/booking31";
export default function Page() {
return (
<Booking31
eyebrow="Visit"
heading="Come and see the rooms before you decide anything."
description="Most Thursdays we keep the late afternoon free for visits."
address={{
lines: ["Rua da Prata 12, second floor", "1100-415 Lisbon"],
directions: "Four minutes on foot from Baixa-Chiado, with a lift to the door.",
}}
hours={[
{ day: "Monday to Thursday", hours: "9:00 to 21:00" },
{ day: "Friday", hours: "9:00 to 15:00" },
]}
button={{ label: "Plan a visit", href: "/visit", tone: "dark" }}
link={{ label: "Or ask a question first", href: "mailto:hello@beste.co" }}
image={{ src: "/rooms/kitchen.jpg", alt: "A kitchen with oak cabinets and a window onto a garden" }}
labels={{ address: "Where", hours: "When" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Small-caps line above the heading |
heading | string | – | Section heading, rendered as an h2 through Text1 |
description | string | – | Invitation paragraph under the heading |
address | { lines: string[]; directions: string } | – | Address block and the getting-here note |
hours | HourRow[] | [] | Opening-hours rows |
button | ActionButton | – | Pill action at the foot |
link | { label: string; href: string } | – | Quieter second action beside the pill |
image | { src: string; alt: string } | – | Photograph in the left column |
labels | { address?: string; hours?: string } | {} | Small-caps titles over the two columns |
className | string | – | Extra classes for the outer <section> |
type HourRow = {
day: string;
hours: string;
};
type ActionButton = {
label: string;
href: string;
tone?: "primary" | "light" | "dark" | "outline";
};block span and the serif setting wraps exactly where you decided it should.dl with the day and its hours stacked rather than opposed, which is what stops a long value like "Quiet days only" from colliding with a long day label in a narrow column.border-t and split at sm, so on a phone the address and the hours stack in reading order instead of squeezing into two thin columns.-10% to 10% against a 1.2 scale and clears from blur(24px) on decode, with a complete check on mount so a cached image is not left blurred.motion-safe:, so the affordance is dropped for reduced motion while the link still works.image the copy column keeps its grid position, and the action row disappears entirely when neither button nor link is given.booking30
A booking section: a serif heading that settles in word by word over the intro, a ruled contact sheet and a practitioner avatar line, beside a calm request form with name and email fields, pill choices for session type and preferred time, a message box and a sliding-marker pill to send.
booking32
The classic contact section: a serif heading that settles in word by word, an intro and a ruled contact sheet on the left, and a plain form with name, email and message fields and a sliding-marker pill on the right, with no panel around it.
booking33
A booking chooser: a serif heading that settles in word by word and an intro, then a ruled list of session types on the left that swaps, with a soft blur, the muted detail card on the right showing a serif title, a description, a fact row and a sliding-marker pill.
booking25
A confirmation screen with an accent eyebrow, a two-column hairline table of the appointment details, a checked list of what to bring, and a sticky tile floating the live phone view the member also receives.