Places Rail

Ferro Coffee House, five rooms in five cities

Pull up a chair in any of them.

The same beans, the same slow bar and the same long tables, from a sunny corner in Lisbon to a lamp-lit room in Melbourne.

A sunlit street in Lisbon

Lisbon

Príncipe Real

Rua da Escola Politécnica 58 1250-102 Lisbon

Open every day from 7:30 am to 6 pm.

Get directions
A calm coffee bar interior with a long counter

Copenhagen

Vesterbro

Istedgade 88 1650 Copenhagen

Weekdays from 7 am, weekends from 8 am, until 5 pm.

Get directions
A warm dining room with long tables in Brooklyn

Brooklyn

Williamsburg

212 Wythe Avenue Brooklyn, NY 11249

Open every day from 7 am to 7 pm, later on Fridays.

Get directions
A city street at dusk with car lights and lit towers

Tokyo

Jingumae

2-14-7 Jingumae Shibuya, Tokyo 150-0001

Open every day from 8 am to 8 pm.

Get directions
An intimate room with warm amber lighting

Melbourne

Fitzroy

301 Smith Street Fitzroy VIC 3065

Weekdays from 7 am to 4 pm, weekends until 5 pm.

Get directions

Next, Mexico City, in the spring.

About this block

Places RailPRO

A pinned scroll feature section for a coffee house with rooms in several cities, built on the scroll-rail component: the heading, intro, an Arrow Pill and an underline link open a travel guide that moves sideways as the page scrolls. Each location is a tall photo card with the picture moving slower than its frame, and a soft shade at the foot holding the city name, the neighborhood, a two-line address, the opening hours and a Get directions link. The city names also run as a giant faint row behind the cards, drifting at their own slower pace for depth, and a quiet closing line ends the rail. Reduced motion turns the rail into a plain horizontal scroll.

Feature319: Places Rail

A pinned scroll section where an intro panel and one tall photo card per location travel sideways on a ScrollRail as the page scrolls, each photo drifting slower than its card, while the city names drift as a giant faint row behind them.

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.

Upgrade Now

Installation

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

bash
npx shadcn add "https://ui.beste.co/r/feature319?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://ui.beste.co/r-base/feature319?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/feature319.tsx plus the scroll-rail component and the button23 and button2 buttons it uses.

Quick start

The installed file exports feature319Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.

tsx
import { Feature319, feature319Demo } from "@/components/beste/block/feature319";

export default function Page() {
  return <Feature319 {...feature319Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Feature319 } from "@/components/beste/block/feature319";

export default function Page() {
  return (
    <Feature319
      eyebrow="Ferro Coffee House, five rooms in five cities"
      heading="Pull up a chair in any of them."
      description="The same beans, the same slow bar and the same long tables."
      buttons={[
        { label: "Find the nearest room", href: "/locations" },
        { label: "Our coffee", href: "https://beste.co" },
      ]}
      places={[
        {
          city: "Lisbon",
          neighborhood: "Príncipe Real",
          address: "Rua da Escola Politécnica 58\n1250-102 Lisbon",
          hours: "Open every day from 7:30 am to 6 pm.",
          image: {
            src: "https://images.unsplash.com/photo-1753236404576-b4c1a4b5f0dc?w=1400&q=80",
            alt: "A sunlit street in Lisbon",
          },
          directions: { label: "Get directions", href: "https://beste.co" },
        },
        {
          city: "Brooklyn",
          neighborhood: "Williamsburg",
          address: "212 Wythe Avenue\nBrooklyn, NY 11249",
          image: {
            src: "https://images.unsplash.com/photo-1559339352-11d035aa65de?w=1400&q=80",
            alt: "A warm dining room with long tables in Brooklyn",
          },
        },
      ]}
      closing="Next, Mexico City, in the spring."
      rail={{ gap: 40, smoothing: 0.5 }}
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring–Small line above the heading on the intro panel
headingstring–Section heading, rendered as an h2
descriptionstring–Intro paragraph under the heading
buttonsActionButton[][]The first renders as a primary arrow pill (Button23), the rest as muted underline links (Button2)
placesPlace[][]One tall card per location, in travel order
closingstring–Quiet last line at the end of the rail
backdropbooleantrueShows the city names as a giant faint row drifting behind the cards
railOmit<ScrollRailProps, "children" | "progress" | "autoplay" | "align" | "className">–Forwards ScrollRail props (gap, smoothing, speed, paused); progress, autoplay and alignment are set by the block
classNamestring–Extra classes for the outer <section>
ts
type ActionButton = {
  label: string;
  href: string;
};

type Place = {
  city: string;
  neighborhood?: string;
  address?: string; // "\n" breaks it onto two lines
  hours?: string;
  image: { src: string; alt: string };
  directions?: ActionButton;
};

Behavior notes

  • The section is 320svh tall with a sticky stage of 100svh minus 78px (at least 640px). Rail progress maps page scroll from 2% to 96% of the section onto 0 to 1, clamped.
  • The backdrop row is driven by the same progress but moves from 0% to -46% at its own pace, so it reads as a layer far behind the cards. It is aria-hidden and only renders when backdrop is on and there is at least 1 place.
  • Each photo sits in a layer 120% wide marked data-rail-depth="0.2", so it drifts inside the card. The caption block uses data-rail-focus="0.55" and the closing line 0.35, so both dim away from the middle of the viewport.
  • The intro panel is the first rail item, so the heading travels off with the cards. Eyebrow, heading, text and buttons rise in once when 40% in view.
  • City names are h3. The address keeps its line breaks through whitespace-pre-line, and a dark gradient at the card foot keeps the white text readable on any photo. Everything outside the photo cards uses theme tokens (bg-background, text-foreground, text-muted-foreground), so the section follows the site theme.
  • With reduced motion the section drops its tall height, the backdrop stops drifting, the rise-ins are skipped and the rail becomes a plain horizontal scroll.

More Feature blocks

View all Feature
PRO

feature312

Chapters Rail

PRO

feature318

Collection Rail

PRO

feature314

Selected Work Rail

Get Pro access