Hero Bento
ProThe first screen of one person's work, as a bento.
Kind words from readers, listeners or students, pinned up as notes: each a card in one of the palette's tints with a strip of tape across its top, tilted a little by its words (the same tilt on every build), the quote and who wrote it with where they are. The notes fall into columns that fill top to bottom, so notes of any length hang without gaps. As they scroll in they settle into place, rising from a little lower and more askew on a view timeline; where there is none, or under reduced motion, they hang still. Zero JavaScript.
Readers
The only email I open on the day it arrives.
Issue 140 changed how our team writes error messages.
Short, kind and always something I can try that afternoon.
I bought the field guide for the checklists and read it for the stories.
It reads like a letter from a friend who knows a lot about forms.
I forward it to my students most weeks.
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
CSS 10.0 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.
Browser support
Chrome 115 · not Firefox · Safari 26; needs scroll-timeline, container-units. Elsewhere: the notes hang still at their tilt where there is no view timeline (Firefox); without container units the wall stays one column.
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/notes-wall---
import NotesWall from '@/components/moonarc/pro/NotesWall.astro';
---
<NotesWall
eyebrow="Kind words"
notes={[
{ quote: 'The only email I read the minute it arrives.', who: 'Reader since 2023', where: 'Lisbon' },
{ quote: 'I finished the course in a week and sold my first print the week after.', who: 'A student', where: 'Illustrator' },
{ quote: 'Short, specific and never padded.', who: 'A listener' },
]}
>
<span slot="headline">What readers <em>write back</em></span>
</NotesWall>Without a key the registry answers 401 with an upgrade message.
| Prop | Type | Default | Description |
|---|---|---|---|
notes | { quote: string; who: string; where?: string; block?: 1 | 2 | 3 | 4 | 5 }[] | none | The notes, in order. who is a name, or a role in a sample ("Reader since 2023"); where is where they are or what they do, under the name; block is the note's tint (the first four in turn when unset). The tilt is hashed from the quote. |
eyebrow | string | none | A short line above the heading. Slot "eyebrow" wins. |
headline | string | none | The heading. Slot "headline" wins and may hold an <em>, set in the emphasis face and colour. |
copy | string | none | A line under the heading. |
level | 2 | 3 | 2 | Heading level of the section's heading. |
tone | 'surface' | 'muted' | 'ink' | 'brand' | unset (paints nothing) | The section's ground; the notes keep their blocks on every tone. |
density | 'compact' | 'cozy' | 'roomy' | 'cozy' | Block padding ×0.8 / ×1 / ×1.25 through --ma-density. |
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-notes.ma-notes__copy.ma-notes__eyebrow.ma-notes__head.ma-notes__headline.ma-notes__item.ma-notes__name.ma-notes__note.ma-notes__quote.ma-notes__wall.ma-notes__where.ma-notes__who
slot="eyebrow"slot="headline"
The notes hang still at their tilt, without settling in.
ClientRouterCSS only; nothing to rebind.
Replaces: Testimonial walls (Tailwind Plus, Magic UI) · Embedded review walls (Senja, Testimonial.to). See the migration table.
The first screen of one person's work, as a bento.
Episodes
Episode 48
Episode 47
Episode 46
Episode 45
The issues, episodes, lessons or videos of one person's work, as a list of rows in the order you give them (newest first).
Who it is for, as stickers: a heading and a line beside a cloud of rounded labels in the palette's blocks, each tilted a little its own way, coming in one after another as the cloud enters the screen (Reveal).
Shows two rows of testimonial cards drifting in opposite directions, pausing while hovered so any quote can be read.
Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown