Skip to content

Components / Sections

Field Hero

A hero with a field of glyphs behind a panel in the brand colour (ink on a page without a theme) whose meta line, headline and actions wipe in one after another. The field is CSS counters on server-drawn noise, with two crossing waves and a cursor trail that decays one character at a time. Zero JavaScript of its own; swish inlines one measured listener.

Live demo

Open source / MIT0.2.0

Motion components for Astro that keep working after every navigation.

What most of them cost: 0 B, nothing, zero

Set up in five minutes

npx astro add moonarc

Available forAstro 5Astro 6Astro 7staticserver

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

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

Browser support

Baseline · newly available

Chrome 125 · Firefox 128 · Safari 17; needs property, css-math, counter-style, has. Elsewhere: the field shows its server-drawn contours without waves; the panel still wipes in.

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/hero-field
src/pages/index.astro
---
import HeroField from '@/components/moonarc/pro/HeroField.astro';
---
<HeroField
  meta={['Open source / MIT', '0.2.0']}
  headline="Motion components for Astro that survive every navigation and ship no runtime."
  copy="What most of them cost:"
  rotate={['0 B', 'nothing', 'zero']}
  primary={{ href: '/setup/', label: 'Set up in five minutes' }}
  command="npx astro add moonarc"
  available={['Astro 5', 'Astro 6', 'Astro 7', 'static', 'server']}
  swish
/>

Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: glyph-field, rotating-text, typewriter.

Props

PropTypeDefaultDescription
level1 | 21Heading level of the headline: 1 on a page's own hero, 2 under another h1 (a demo, or a block further down).
headlinestringnoneHeadline.
metastring[]noneShort tokens above the headline.
copystringnoneSupporting copy.
rotatestring[]noneWords rotated at the end of the copy.
primary{ href, label }nonePrimary action.
secondary{ href, label }noneSecondary action.
commandstringnoneA command typed under the actions.
availablestring[]noneShort tokens under the command, as chips: platforms, versions.
availableLabelstring'Available for'The words before the available chips.
huenumber68Base hue of the field in oklch degrees; the sunset arc turns from there.
swishbooleanfalseTwo-dimensional cursor swish with a tail; inlines GlyphField's one listener, measured.
tone'surface' | 'muted' | 'ink' | 'brand''brand'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'Panel padding ×0.8 / ×1 / ×1.25 through --ma-density.
align'start' | 'center''start'Text alignment inside the panel.

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-hero-field.ma-hero-field__actions.ma-hero-field__aside.ma-hero-field__available.ma-hero-field__chip.ma-hero-field__command.ma-hero-field__copy.ma-hero-field__headline.ma-hero-field__inner.ma-hero-field__media.ma-hero-field__meta.ma-hero-field__panel.ma-hero-field__primary.ma-hero-field__secondary.ma-hero-field__wipe

Slots

slot="eyebrow"slot="headline"slot="copy"slot="actions"slot="aside"slot="media"

Reduced motion

No wipes, no waves, no bloom; cells still light under the cursor, without a tail.

With ClientRouter

CSS-only; nothing to rebind.

Why it is built this way

Replaces: Canvas ASCII hero (motion.dev) · hero sections with WebGL fields. See the migration table.

A field of braille dots that reads as a flowing contour map: two waves cross it, the colour turns along a sunset arc, and the cursor carves a trail that decays one dot at a time.

newly · Chrome 125 · Firefox 128 · Safari 17.2pointeralways

Cycles through a list of words in place.

newly · Chrome 85 · Firefox 128 · Safari 16.4always

Types a string one character at a time in any font, with a caret that stays solid while typing and blinks once idle.

Chrome 116 · not Firefox · Safari 18load

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