Chapters Rail

Ashgrove Workshop, chairs and tables made by hand

How a chair gets made.

A short story in five parts from our workshop by the river, where six of us make around two hundred pieces a year.

Drafting table covered with sketches and measuring tools

The drawing

Every piece starts full size on paper. We keep drawing until the proportions stop arguing with us, sometimes for weeks.

Close detail of timber meeting concrete at a seam

The timber

We buy whole trees from two mills we know by name, then let the boards rest in the loft for a year before the first cut.

Pale oak chair against a white wall

The joints

No screws and no metal. Mortise, tenon and a little glue, cut by hand so the frame stays tight for decades.

Dark timber chair beside a window

The finish

Three coats of hard wax oil, rubbed in by hand and left to cure between each one. It looks like nothing, which is the point.

Finished interior with furniture catching afternoon light

The room

Then it leaves us. We ask for a photograph a year later, to see where the light falls on it.

Made slowly, for everyday use.

About this block

Chapters RailPRO

A pinned scroll feature section for a furniture workshop built on the scroll-rail component: the heading, intro, an Arrow Pill and an underline link open a long editorial story that travels sideways as the page scrolls. Five chapter spreads follow, each with a large photograph that moves slower than its frame, a faint oversized chapter numeral drifting behind the text, and a short title and paragraph that brighten as the spread reaches the middle. Portrait and landscape spreads alternate with the photograph above or below the text, and a quiet closing line with its own button ends the rail. Reduced motion turns the rail into a plain horizontal scroll.

Feature312: Chapters Rail

A pinned section where an intro panel and a row of numbered chapter spreads travel sideways on the scroll-rail component as the page scrolls, each photograph drifting inside its frame and each chapter's text brightening as it reaches the middle.

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/feature312?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

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

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

Quick start

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

tsx
import { Feature312, feature312Demo } from "@/components/beste/block/feature312";

export default function Page() {
  return <Feature312 {...feature312Demo} />;
}

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

tsx
import { Feature312 } from "@/components/beste/block/feature312";

export default function Page() {
  return (
    <Feature312
      eyebrow="Ashgrove Workshop, chairs and tables made by hand"
      heading="How a chair gets made."
      description="A short story in five parts from our workshop by the river."
      buttons={[
        { label: "Visit the workshop", href: "/visit" },
        { label: "Read the full story", href: "/journal" },
      ]}
      chapters={[
        {
          title: "The drawing",
          text: "Every piece starts full size on paper.",
          image: {
            src: "https://images.unsplash.com/photo-1718981464703-c167144381eb?w=1600&q=80",
            alt: "Drafting table covered with sketches and measuring tools",
          },
          shape: "landscape",
          photo: "top",
        },
        {
          title: "The joints",
          text: "Mortise, tenon and a little glue, cut by hand.",
          image: {
            src: "https://images.unsplash.com/photo-1503602642458-232111445657?w=1600&q=80",
            alt: "Pale oak chair against a white wall",
          },
          shape: "portrait",
          photo: "bottom",
        },
      ]}
      closing="Made slowly, for everyday use."
      closingButton={{ label: "Order a piece", href: "/order" }}
      rail={{ gap: 112, align: "center", smoothing: 0.5 }}
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring–Muted line above the heading in the first panel
headingstring–Section heading, rendered as an h2
descriptionstring–Intro paragraph under the heading
buttonsActionButton[][]The first renders as an Arrow Pill (Button23), the rest as underline links (Button2)
chaptersChapter[][]One spread per chapter, numbered 01, 02 and on in order
closingstring–Large last line on the rail
closingButtonActionButton–Arrow Pill under the closing line
railOmit<ScrollRailProps, "children" | "progress" | "autoplay" | "className">–Forwards the ScrollRail props from the scroll-rail component (gap, align, speed, smoothing, paused)
classNamestring–Extra classes for the outer <section>
ts
type ActionButton = {
  label: string;
  href: string;
};

type Chapter = {
  title: string;
  text: string;
  image: { src: string; alt: string };
  /** Frame proportion of the photograph */
  shape?: "portrait" | "landscape";
  /** Photograph above or below the text */
  photo?: "top" | "bottom";
};

Behavior notes

  • The section is 360svh tall with a sticky stage of 100svh minus 78px (at least 640px); scroll progress between 0.02 and 0.96 is clamped to 0 to 1 and handed to the rail as a live progress value, with autoplay forced off.
  • Each photograph sits in a layer 124% wide tagged data-rail-depth="0.22", so it drifts against the travel inside its clipped frame, and the faint 01 style numeral behind the text drifts faster at 0.4.
  • Chapter titles, paragraphs and the closing block carry data-rail-focus="0.35": they sit at 35% opacity away from the middle and brighten to full as their panel is centered.
  • shape: "landscape" widens a spread to 46rem from md (portrait is 26rem), and photo: "bottom" flips it with flex-col-reverse; on phones every panel is 85vw.
  • The eyebrow, heading, intro and buttons rise in on mount with staggered delays from 0.1s to 0.4s; chapters render as h3.
  • With reduced motion the section drops its pinned height, progress stays at 0, the entrance motion is skipped and the rail becomes a plain horizontal scroll.
  • The closing panel only renders when closing or closingButton is set.

More Feature blocks

View all Feature
PRO

feature318

Collection Rail

PRO

feature314

Selected Work Rail

PRO

feature319

Places Rail

Get Pro access