Skip to content

Components / Sections

Dot Process

How the work runs, in a few steps across the page: each step a round number in a colour block, a title and a line. On a wide screen the steps stand in one row and a hairline runs behind the numbers, drawn across as the row comes into view on a scroll-driven timeline; on a phone each step is a card of its own. The steps come in one after another (Reveal). Zero JavaScript of its own.

Live demo

Sample process

From brief to report

  1. Brief

    A call about the month: what is new, what sells, what to say.

  2. Plan

    A calendar of posts and a shot list, to approve.

  3. Shoot

    One day on site; the edit is back within two.

  4. Post and report

    Posting, replies, and the numbers at the end of the month.

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

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 13.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 hairline is drawn whole from the start.

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/dot-process
src/pages/index.astro
---
import DotProcess from '@/components/moonarc/pro/DotProcess.astro';
---
<DotProcess
  eyebrow="How a month runs"
  headline="From brief to report"
  steps={[
    { title: 'Brief', body: 'A call about the month: what is new, what sells, what to say.' },
    { title: 'Plan', body: 'A calendar of posts and the shoot list, for you to approve.' },
    { title: 'Shoot', body: 'One day on site; the edit is back within two.' },
    { title: 'Post and report', body: 'Posting, replies and the numbers at the end of the month.' },
  ]}
/>

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

Props

PropTypeDefaultDescription
steps{ title: string; body: string; label?: string }[]noneThe steps, in order. label replaces the number in the dot and is read (a week, a day); a plain number is hidden from a screen reader, since the list says the order.
eyebrowstringnoneA short line above the heading.
headlinestringnoneThe heading. Slot "headline" wins and may hold an <em>.
blocks(1 | 2 | 3 | 4 | 5)[][1, 2, 3, 5]The blocks the dots take in turn.
level2 | 32Heading level of the section's heading; the steps' titles are one below.
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The section's ground; the dots keep their blocks.
density'compact' | 'cozy' | 'roomy''cozy'Block padding ×0.8 / ×1 / ×1.25 through --ma-density.

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-dotsteps.ma-dotsteps__body.ma-dotsteps__dot.ma-dotsteps__eyebrow.ma-dotsteps__head.ma-dotsteps__headline.ma-dotsteps__list.ma-dotsteps__step.ma-dotsteps__title

Slots

slot="eyebrow"slot="headline"

Reduced motion

The steps are in place and the hairline is drawn whole.

With ClientRouter

Inherits Reveal; the hairline is CSS (a view timeline). Nothing of its own to rebind.

Why it is built this way

Replaces: Process sections (Framer agency templates). 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

A line beside an article fills as it is read, with a dot at its head.

Chrome 115 · not Firefox · Safari 26scroll

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.

Chrome 115 · not Firefox · Safari 26scroll

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