What a writer needs on one page: the app's icon, the fact sheet (a description list a reader can copy from), the files to download with their format and size, the colours with their values, a few words from the people who make it, and who to write to. Every part is plain HTML; the downloads are links with the download attribute, and the colours are written out beside their swatches. The parts arrive in turn. Zero JavaScript.
Live demo
Press
Press kit
An imaginary app's press kit. Everything here may be used in writing about it.
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
Uses Reveal and the shared runtime (1.9 kB raw, once per site). With those included: 3.0 kB raw.
CSS 11.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
Baseline · widely available
every browser. Elsewhere: nothing to fall back from.
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/press-kit
src/pages/index.astro
---import PressKit from '@/components/moonarc/pro/PressKit.astro';---<PressKit headline="Press kit" copy="Everything here may be used in writing about the app." icon={{ src: '/press/icon.svg', alt: 'The app icon' }} facts={[ { term: 'Launched', value: 'March 2025' }, { term: 'Platforms', value: 'iPhone, iPad, Android, Apple Watch' }, { term: 'Price', value: 'Free, or $3.99 a month' }, ]} downloads={[{ label: 'App icon', href: '/press/icon.svg', meta: 'SVG' }]} colors={[{ name: 'Coral', value: '#ff6a4d' }]} quote={{ text: 'We wanted the smallest possible daily habit.', name: 'Ada Park', role: 'Founder' }} contact={{ email: 'press@example.com', note: 'We answer within a working day.' }}/>
Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: reveal.
Props
Prop
Type
Default
Description
facts
{ term: string; value: string }[]
none
The fact sheet, in order.
contact
{ email: string; name?: string; note?: string }
none
Who to write to; the address is a mailto link.
downloads
{ label: string; href: string; meta?: string }[]
none
The files. meta is the format and size as words ("a 180 kB PNG, 1024 px").
colors
{ name: string; value: string }[]
none
The colours, each a swatch with its name and value written out.
quote
{ text: string; name: string; role?: string }
none
A few words from the people who make it.
icon
{ src: string; alt: string }
none
The app's icon, drawn in a rounded square. Slot "icon" wins (an <svg> or an <Image>).
words
{ facts?; downloads?; colors?; contact? }
Fact sheet, Downloads, Colours, Press contact
The parts' headings, in the page's language.
headline
string
none
The heading. Slot "headline" wins.
eyebrow
string
none
A short line above the heading.
copy
string
none
A line under the heading: what the material may be used for.
level
1 | 2 | 3
2
Heading level of the heading: 1 when the kit opens its own page; the parts' headings are one below.
tone
'surface' | 'muted' | 'ink' | 'brand'
unset (paints nothing)
The section's ground.
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.
A heading and lead beside a native accordion: one question open at a time, heights animated by the browser, keyboard and screen reader handled by <details>.