Skip to content

Components / Sections

Notes Wall

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.

Live demo

Readers

Kind words, kept

  • The only email I open on the day it arrives.

    Reader since 2022Product designer
  • Issue 140 changed how our team writes error messages.

    Team leadAgency name
  • Short, kind and always something I can try that afternoon.

    Reader since 2023Front-end developer
  • I bought the field guide for the checklists and read it for the stories.

    MemberStudio name
  • It reads like a letter from a friend who knows a lot about forms.

    Reader since 2021Writer
  • I forward it to my students most weeks.

    TeacherSchool name

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

Measured

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

Limited availability

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.

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/notes-wall
src/pages/index.astro
---
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.

Props

PropTypeDefaultDescription
notes{ quote: string; who: string; where?: string; block?: 1 | 2 | 3 | 4 | 5 }[]noneThe 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.
eyebrowstringnoneA short line above the heading. Slot "eyebrow" wins.
headlinestringnoneThe heading. Slot "headline" wins and may hold an <em>, set in the emphasis face and colour.
copystringnoneA line under the heading.
level2 | 32Heading 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.

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-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

Slots

slot="eyebrow"slot="headline"

Reduced motion

The notes hang still at their tilt, without settling in.

With ClientRouter

CSS only; nothing to rebind.

Why it is built this way

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.

newly · Chrome 105 · Firefox 128 · Safari 17pointerscrollalways

Episodes

The latest conversations

All episodes
  1. 29 September 202652 min

  2. 15 September 202647 min

  3. 1 September 202658 min

  4. 18 August 202644 min

The issues, episodes, lessons or videos of one person's work, as a list of rows in the order you give them (newest first).

every browserhoverclick

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).

every browserscroll

Shows testimonial quotes in a staggered grid.

every browserscrollpointer

Shows two rows of testimonial cards drifting in opposite directions, pausing while hovered so any quote can be read.

every browseralwayshover

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