Skip to content

Components / Sections

Steps / Timeline

A vertical timeline: the line draws itself down the page in step with the scroll, each step revealing from the line's side as it is reached, markers numbered or dated. Zero JavaScript of its own; where scroll timelines are missing the line is simply drawn.

Live demo

scroll inside

How it ships

  1. Install

    npx astro add moonarc

  2. Import

    One component at a time.

  3. Measure

    The budget test prints every byte.

  4. Ship

    Verified on Astro 5, 6 and 7.

Live, from the library itself, at full size: scroll, hover, navigate away and back. The demo is never gated.

Variants · each row writes the attribute the prop writes; the section's own CSS answers

tone
density
align

Measured

JavaScript of its own

0 B

Uses Reveal and the shared runtime (1.9 kB raw, once per site). With those included: 3.0 kB raw.

CSS 10.1 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.

Browser support

Limited availability

Chrome 115 · not Firefox · Safari 26; needs scroll-timeline. Elsewhere: the line is fully drawn; steps still reveal (Firefox).

Install Pro

The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:

terminal
npx shadcn@latest add @moonarc-pro/steps-section
src/pages/index.astro
---
import StepsSection from '@/components/moonarc/pro/StepsSection.astro';
---
<StepsSection headline="How it ships" steps={[
  { title: 'Install', body: 'npx astro add moonarc' },
  { title: 'Import', body: 'One component at a time.' },
  { title: 'Measure', body: 'The budget test prints every byte.' },
]} />

Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: reveal.

Props

PropTypeDefaultDescription
steps{ title, body, label? }[]noneSteps in order; label replaces the number (a date, a version) and, unlike the number, is read by screen readers.
headlinestringnoneSection heading.
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The ground: the page surface, a muted band, an always-dark ink panel, or a deep brand panel. Each paints --background, --ma-tone-muted (over --muted, with a --border hairline), --ma-tone-ink or --ma-tone-brand (over --primary) with the matching text. With theme.css, a painted tone also re-declares --card, --border, --input and --ring inside the section, so cards and fields follow the ground. Decoration is strongest on brand.
density'compact' | 'cozy' | 'roomy''cozy'Block padding and the gap between steps ×0.8 / ×1 / ×1.25 through --ma-density.
align'start' | 'center''start'Heading alignment.

Theming and overrides

The section reads the theme contract (shadcn's variable names with the base tokens as fallback), so a pasted theme or one --ma-brand recolours it. Its class names are the override surface and stay stable; a named slot replaces the matching prop with your own markup.

Classes

.ma-steps.ma-steps__aside.ma-steps__body.ma-steps__copy.ma-steps__eyebrow.ma-steps__head.ma-steps__headline.ma-steps__line.ma-steps__list.ma-steps__marker.ma-steps__step.ma-steps__title.ma-steps__track

Slots

slot="eyebrow"slot="headline"slot="copy"slot="aside"

Reduced motion

Steps fade in place; the line is drawn.

With ClientRouter

Inherits Reveal; nothing to rebind.

Why it is built this way

Replaces: Timeline (Aceternity) · Steps sections (Tailwind Plus). See the migration table.

Entrance on scroll that plays once and stays, staggers its children, scrubs with the scroll position when asked, honours reduced motion, and keeps working after every ClientRouter navigation.

every browserscroll

Bind translate, scale, rotate and opacity to the scroll position: the element goes from the start values you give to neutral across a range of its own passage through the viewport, exactly in step.

Chrome 115 · not Firefox · Safari 26scroll

Lists dated releases in a hairline list.

every browserscroll

Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown