Skip to content

Components / Sections

Hero Section

A complete hero as one component with props: an ambient aurora, a headline split and revealed word by word, supporting copy with a rotating word, two actions and a typed command. The parts arrive in a fixed order and timing.

Live demo

Pro section

A whole hero, one component, five beats.

Aurora, split headline, revealed copy, actions and a typed command. Ship faster, lighter, calmer

What Pro is forThe free partsnpx shadcn@latest add @moonarc-pro/hero-section

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 18.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 · widely available

every browser.

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-section
src/pages/index.astro
---
import HeroSection from '@/components/moonarc/pro/HeroSection.astro';
---
<HeroSection
  eyebrow="Astro 5 · 6 · 7"
  headline="A complete hero in one component"
  copy="Ship"
  rotate={['faster', 'lighter', 'calmer']}
  primary={{ href: '/setup/', label: 'Set up' }}
  command="npx astro add moonarc"
/>

Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: aurora, reveal, split-text, 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, split on the server.
eyebrowstringnoneSmall label 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.
auroranumber0.4Aurora strength; 0 removes it.
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 ×0.8 / ×1 / ×1.25 through --ma-density.
align'start' | 'center''start'Text 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-aurora.ma-hero.ma-hero__actions.ma-hero__aside.ma-hero__command.ma-hero__copy.ma-hero__eyebrow.ma-hero__headline.ma-hero__inner.ma-hero__media.ma-hero__primary.ma-hero__secondary.ma-noise

Slots

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

Reduced motion

Inherits every part: fades without travel, static aurora, full text at once.

With ClientRouter

Inherits every part; nothing to wire.

Why it is built this way

Replaces: Hero blocks (Tailwind Plus, shadcnblocks) · Aceternity hero sections. See the migration table.

Ambient gradient field: three soft colour fields drifting at three coprime speeds, a slow hue rotation so the colours themselves move, and a film-grain layer stepped at 12 fps.

every browseralways

Cycles through a list of words in place.

newly · Chrome 85 · Firefox 128 · Safari 16.4always

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

Splits a string into words, characters or lines on the server and reveals them with a capped stagger when they scroll into view.

every browserscroll

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