Skip to content

Components / Sections

Blog Grid

Shows blog posts as cards, with the first post featured across two columns. Cards reveal with a stagger and covers ease larger on hover. Each cover carries a transition name, so with Astro's router a click morphs it into the post's own cover. Give the post page the same name.

Live demo

Release

The logo

The site wears its logo kit: the mark in the header and the footer, and the same drawing on the share cards, the favicons and the home screen icon.

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
columns

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 11.9 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 111 · Firefox 144 · Safari 18; needs view-transitions. Elsewhere: an instant swap into the post.

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/blog-grid
src/pages/index.astro
---
import BlogGrid from '@/components/moonarc/pro/BlogGrid.astro';
---
<BlogGrid posts={posts.map((p) => ({ href: p.url, title: p.title, excerpt: p.excerpt, date: p.date, cover: { src: p.cover, alt: '' } }))} />

<!-- on the post page (import PageTransition from '@/components/moonarc/PageTransition.astro'), the same name morphs the cover: -->
<PageTransition name={`ma-cover-${url}`} preset="morph"><img src={cover} alt="" /></PageTransition>

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

Props

PropTypeDefaultDescription
posts{ href, title, excerpt?, date, cover?, tag? }[]nonePosts in order.
featuredbooleantrueFeature the first post across two columns.
columns2 | 3 | 43Columns on wide screens; the featured post spans two.
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'Gaps ×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-blog.ma-blog__copy.ma-blog__cover.ma-blog__excerpt.ma-blog__eyebrow.ma-blog__head.ma-blog__headline.ma-blog__meta.ma-blog__post.ma-blog__title

Slots

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

Reduced motion

Cards fade in without stagger; no cover scale; instant page swap.

With ClientRouter

The cover morph is the router; everything else is CSS.

Why it is built this way

Replaces: Blog sections (Tailwind Plus) · Blog (shadcnblocks). See the migration table.

page one

Hero.

page two

Hero.

Try the real swap →

Page Transition

Page transitions

Animates a named region between pages: rise, zoom, wipe, scope, fade, slide, or the browser's own shared-element morph.

newly · Chrome 111 · Firefox 144 · Safari 18click

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

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