Nine metres of air above the floor means anything under forty millimetres disappears. We measured before we drew.
Every sign lines up with a structural rib, so the system looks intentional from any angle instead of merely tidy from one.
Gloss threw the window straight back at the reader, so everything switched to a matte lacquer at the sample stage.
Two blank slots per panel, sized for names nobody has signed yet, which is the only part of the brief that will age.
A single tall photograph pinned with position sticky, captioned without a rule, while a column of eyebrow-led notes scrolls past it, each note after the first opening on its own hairline.
One photograph holds its position while a numbered set of notes scrolls past it. Each note opens on its own eyebrow and rule, and the outline CTA closes the column rather than the section.
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/feature250?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/feature250?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/feature250.tsx plus the badge7 eyebrow and button12 pill button it uses.
The installed file exports feature250Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.
import { Feature250, feature250Demo } from "@/components/beste/block/feature250";
export default function Page() {
return <Feature250 {...feature250Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Feature250 } from "@/components/beste/block/feature250";
export default function Page() {
return (
<Feature250
badge={{ label: "One building, four notes" }}
heading="Read down the page, the picture stays where it is."
image={{
src: "/case/ceiling.jpg",
alt: "Vaulted ceiling with repeating ribs",
caption: "Atrium ceiling, before the signage went up",
}}
notes={[
{
index: "Note one",
title: "The ceiling decided the type size",
description: "Nine metres of air means anything under forty millimetres disappears.",
},
{
index: "Note two",
title: "The ribs decided the spacing",
description: "Every sign lines up with a structural rib.",
},
]}
button={{ label: "Read the full case", href: "/work/atrium" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow label rendered as a Badge7 |
heading | string | – | Section heading above the two columns |
image | StickyImage | – | The photograph that sticks, plus its caption |
notes | FeatureNote[] | [] | Notes in the scrolling column, each with its own eyebrow |
button | ActionButton | – | Outline Button12 at the end of the notes column |
className | string | – | Extra classes for the outer <section> |
type StickyImage = {
src: string;
alt: string;
caption: string;
};
type FeatureNote = {
index: string;
title: string;
description: string;
};
type ActionButton = {
label: string;
href: string;
};md:sticky md:top-24 md:self-start; self-start is the part that matters, because a stretched grid item cannot stick at all.md. On a phone the photograph is simply the first thing in the column, so the section reads as picture then notes.border-t pt-6, which keeps the column from opening on a stray rule directly under the heading.Badge7, so the sequence uses the same eyebrow treatment as the section itself instead of inventing a second label style.aspect-[4/5], tall enough that the sticky frame still fills its side of the grid while four notes scroll past it.feature276
A scroll-led feature: a serif heading settling in word by word beside a pill action, then numbered chapters that scroll past a pinned photograph, each one swapping the image with a soft blur and brightening its own title as it reaches the centre of the viewport.
feature303
The heading, intro and pill stay pinned in a sticky column while linked photo cards scroll past in pairs beside them, each photograph drifting inside its frame under a serif title, a meta line and an arrow that lifts on hover.
feature227
Sticky left intro paired with a stacked, numbered list of feature blocks, each with a title, description, and small image.