Marginalia
Margin notes for prose — inline marks get a hand-drawn pen underline that draws in on view; hover, focus or click reveals each note in a gutter rail aligned to its line, collision-stacked and joined to the word by a hairline leader that draws out to it. Notes take any content (images, charts), fold into inline expanding blocks on narrow containers, and preview once in a ghost reading pass. Marks are real buttons with aria-expanded/aria-controls and Escape to close.
The preview is live. The source is Pro.
One purchase, lifetime access: every pro component's source, CLI install with your own registry token, and all future drops.
Installation
CLI
npx shadcn@latest add @crucible/marginaliaManual — install dependencies, then copy the source
npm install motionProps
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | The prose. Each direct child is treated as one block (paragraph, list, quote…) — on narrow containers a mark's note expands inline directly beneath the block that contains it. Place <Mark> elements anywhere inside those blocks. | |
| rail | "right" | "left" | "right" | Which page gutter the notes stack in on wide containers. |
| accentColor | string | "#a5b4fc" | Ink color for underlines, leader lines and note numerals. |
| railWidth | number | 224 | Width of the note rail in px on wide containers. |
| gutter | number | 40 | Gap between the prose column and the rail in px. |
| breakpoint | number | 640 | Container width (px) below which the rail collapses and notes open as inline expanding blocks beneath their paragraph instead. |
| ghost | boolean | true | On first view, preview each note in reading order once (a ghost reading pass), then settle closed. Cancelled by any real interaction; skipped under reduced motion and on narrow containers. |
| className | string | Classes merged onto the root element. | |
| ref | React.Ref<MarginaliaHandle> | Imperative handle — see {@link MarginaliaHandle}. |
Honors prefers-reduced-motion with a designed static fallback, and passes className through.