Grid Pattern
BackgroundsA hairline grid behind content, faded toward the edges, optionally drifting one cell at a time.
A split hero: a tall headline revealed line by line on the left, a live panel sliding in from the right, on a slowly drifting grid. Copy and actions follow in two beats; the primary action is magnetic. Everything inside is free-tier; the composition is what is sold.
Editorial
102 primitives, 67 of them at zero bytes.
Motion components for Astro that keep working after every navigation.
move your cursor · <FluidField curl={24}>
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
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 14.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
every browser.
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:
npx shadcn@latest add @moonarc-pro/hero-editorial---
import HeroEditorial from '@/components/moonarc/pro/HeroEditorial.astro';
---
<HeroEditorial
eyebrow="Now in beta"
headline={"Field notes for small studios,\nwritten every week."}
copy="Short essays on pricing, hiring and the work itself."
primary={{ href: '/subscribe/', label: 'Subscribe' }}
secondary={{ href: '/archive/', label: 'The archive' }}
image={{ src: '/hero.png', alt: 'A desk with a notebook' }}
/>Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: grid-pattern, split-text, reveal, magnetic.
| Prop | Type | Default | Description |
|---|---|---|---|
level | 1 | 2 | 1 | Heading level of the headline: 1 on a page's own hero, 2 under another h1 (a demo, or a block further down). |
headline | string | none | Headline; \n breaks lines, each revealed in turn. |
eyebrow | string | none | Small label above the headline. |
copy | string | none | Supporting copy. |
primary | { href, label } | none | Primary action, magnetic. |
secondary | { href, label } | none | Secondary action. |
image | { src, alt } | none | Panel image; or slot anything into the panel. |
media | 'right' | 'left' | 'none' | 'right' | Side of the panel; none drops it and the text takes the width. |
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; center reads best with media="none". |
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.
.ma-hero-editorial.ma-hero-editorial__actions.ma-hero-editorial__copy.ma-hero-editorial__eyebrow.ma-hero-editorial__headline.ma-hero-editorial__inner.ma-hero-editorial__panel.ma-hero-editorial__primary.ma-hero-editorial__secondary.ma-hero-editorial__text
slot="eyebrow"slot="headline"slot="copy"slot="actions"slot="media"
Inherits every part: lines fade without travel, the panel fades in place, the grid holds still, the magnet is off.
ClientRouterInherits every part; nothing to wire.
Replaces: Hero blocks with image (Tailwind Plus) · Aceternity hero sections. See the migration table.
A hairline grid behind content, faded toward the edges, optionally drifting one cell at a time.
A button or icon is pulled toward the cursor while it is nearby and springs back when it leaves.
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.
Splits a string into words, characters or lines on the server and reveals them with a capped stagger when they scroll into view.
Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown