What a practice does, by group: each group's name and a line about it on one side, its services on the other as rows, each with a line of what it is, how long it takes and what it costs from, and a link to its own page. One group sets its rows alone. The row is the link, its arrow moving a little on hover and focus; nothing else moves. Zero JavaScript.
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 10.4 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/service-index
src/pages/index.astro
---import ServiceIndex from '@/components/moonarc/pro/ServiceIndex.astro';---<ServiceIndex headline="What we do" groups={[ { name: 'Check-ups', text: 'For every patient, twice a year.', services: [ { title: 'Check-up', text: 'An examination and a plan, with X-rays when they are due.', duration: '30 minutes', price: 'From $85', href: '/services/check-up/' }, ] }, ]}/>
Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: reveal.
Props
Prop
Type
Default
Description
headline
string
none
The heading. Slot "headline" wins and may hold an <em>.
The groups and their services; a service with an href is a link to its page.
more
{ href; label }
none
A link under the index.
level
1 | 2 | 3
2
Heading level of the heading; groups are one below and services one below them (one group: the services are one below). 1 under a page's own heading.
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.
What a practice charges, as tables a reader can trust: one a group, each row a service, its price and a note, and where insurance applies a column that says in words whether it is covered, partly or not, with a mark that repeats it in shape.
A service's own page, top to bottom: its name and what it is in a sentence, then the parts a reader looks for before booking (what it is, who it is for, what happens step by step, what to bring, what comes after), each under its own heading; beside them a card that stays in view while the page scrolls (position: sticky, nothing animated) with the facts (how long, from what price, whether insurance covers it), the two actions and a line of small print.
every browserscroll
Sample services
What an imaginary studio does
01Brand identity
A name, a mark and the rules that hold them together, for a company that is new or has outgrown its look.
Deliverables
Logo and mark
Type and colour
Guidelines
02Websites
Sites designed and built by one team, from the first sketch to the code that ships.
Deliverables
Design system
Astro build
Content model
03Product design
Screens for an app or a tool, drawn with the people who will use them and handed over as working components.
Deliverables
Flows
Interface
Components
04Motion
The logo in motion, a product film, the interface itself: motion that says one thing each time.
What a studio or a freelancer does, as numbered rows at display size that open one at a time: each row names a service, and opens to a short text beside the list of deliverables.