Figures Rail

Wildacre Cooperative, impact report 2025

A year of better soil, in six numbers.

38 family farms and one shared way of working the land. Here is what changed between one harvest and the next.

94%

of our fields covered all winter

Cover crops of rye, clover and vetch keep the soil alive through the cold months. Five years ago it was barely half.

38

family farms in the cooperative

We started with 11 neighbors sharing one seed drill. This year 7 more farms joined after a season of trials.

Hens foraging across leaf-covered grass on an autumn morning
Hens follow the cattle on Brook Farm

+2.1%

soil organic carbon since 2019

Measured every spring at the same 400 points across member land. Slow, steady and hard to fake.

1.2M

hedgerow plants in the ground

Hawthorn, hazel and blackthorn, planted by hand every winter. We promised 1.5 million by 2030.

Sunrise over a misty valley with lone pines on a grassy slope
Early May on the upper pastures

61%

less synthetic fertilizer than in 2019

2019
2025

Legumes, compost and grazing do most of the work now. Yields held steady on 34 of our 38 farms.

212

bird species counted on member land

FarmlandHedgerowWoodlandWetland

Volunteers walk the same routes each May. Skylarks and lapwings are back on fields where no one had heard them in years.

Every method and every number is in the full report.

About this block

Figures RailPRO

A pinned scroll feature section for an impact report built on the scroll-rail component: the heading, intro, an Arrow Pill and an underline link open a row of figures that travels sideways as the page scrolls. Each figure panel pairs a large number and a one-line label with its own small chart drawn in the text color, a filling bar, a field of dots, a sparkline, a ring, a two-year comparison or a stacked share with a legend, which draws itself when the panel reaches the middle and resets when it moves back. A short context paragraph brightens as the panel arrives, photographs with inner parallax break up the rhythm, and a closing line with its own button ends the rail. Reduced motion turns the rail into a plain horizontal scroll with every chart drawn.

Feature316: Figures Rail

A pinned section where an intro panel, large figures with small self-drawing charts and captioned photographs travel sideways on the scroll-rail component as the page scrolls; each chart draws when its panel reaches the middle band and resets when it moves back.

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

Base UI flavor

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

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

Quick start

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

tsx
import { Feature316, feature316Demo } from "@/components/beste/block/feature316";

export default function Page() {
  return <Feature316 {...feature316Demo} />;
}

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

tsx
import { Feature316 } from "@/components/beste/block/feature316";

export default function Page() {
  return (
    <Feature316
      eyebrow="Wildacre Cooperative, impact report 2025"
      heading="A year of better soil, in six numbers."
      buttons={[
        { label: "Download the report", href: "/report" },
        { label: "Meet the farms", href: "/farms" },
      ]}
      entries={[
        {
          type: "figure",
          value: "94%",
          label: "of our fields covered all winter",
          text: "Cover crops keep the soil alive through the cold months.",
          visual: { kind: "bar", value: 0.94 },
        },
        {
          type: "photo",
          src: "https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?w=1200&q=80",
          alt: "Sunrise over a misty valley with lone pines on a grassy slope",
          caption: "Early May on the upper pastures",
        },
        {
          type: "figure",
          value: "+2.1%",
          label: "soil organic carbon since 2019",
          text: "Measured every spring at the same 400 points.",
          visual: { kind: "line", points: [3.1, 3.3, 3.2, 3.7, 4.2, 4.6, 5.2] },
        },
      ]}
      closing="Every method and every number is in the full report."
      closingButton={{ label: "Read the full report", href: "/report" }}
      rail={{ gap: 96, 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)
entriesRailEntry[][]Figure panels and photographs along the rail, 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 Part = {
  label: string;
  /** Share of the whole, 0 to 1 */
  value: number;
};

type FigureVisual =
  | { kind: "bar"; value: number }
  | { kind: "dots"; filled: number; total: number }
  | { kind: "line"; points: number[] }
  | { kind: "ring"; value: number }
  | { kind: "compare"; items: Part[] }
  | { kind: "stack"; items: Part[] };

type RailEntry =
  | { type: "figure"; value: string; label: string; text: string; visual: FigureVisual }
  | { type: "photo"; src: string; alt: string; caption?: string };

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 fed to the rail as a live progress value with autoplay off.
  • Each figure panel watches itself with an IntersectionObserver whose root is inset 32% on both sides: the chart draws once the panel enters that middle band and resets only when the panel leaves back to the right, so charts already passed stay drawn.
  • Charts are drawn in the text color: bar and compare scale their fills from the left, dots lays out a 20-column grid and pops the first filled dots in with a 25ms stagger, line normalizes points to its own min and max and wipes in with a clip-path, ring fills a stroke dash, and stack sizes each part by its share of the total with a legend below.
  • Figure context paragraphs carry data-rail-focus="0.4" and brighten as their panel is centered; photographs sit in a layer 128% wide with data-rail-depth="0.2", so they drift inside their frames.
  • With reduced motion the section loses its pinned height, progress stays at 0, every chart is drawn from the start with transitions disabled, and the rail becomes a plain horizontal scroll.
  • The intro rises in on mount with staggered delays from 0.1s to 0.4s; the closing panel only renders when closing or closingButton is set.

More Feature blocks

View all Feature
PRO

feature314

Selected Work Rail

PRO

feature318

Collection Rail

PRO

feature312

Chapters Rail

Get Pro access