# Moonarc
> Zero-runtime, ClientRouter-safe animation and motion components for Astro: 102 primitives (67 of them load no JavaScript) and, in Pro, 28 sections and 11 GPU effects. Every component states its JavaScript cost, measured from a real build, and its browser support. Primitives are MIT.
Install: `npx astro add moonarc`. Import per component: `import Reveal from '@moonarc/core/Reveal'`. Full setup, per package manager and project type, with fixes: https://moonarc.dev/setup.md
Runtime for your own scripts: `import { onMount, onPage } from '@moonarc/core/runtime'`. It binds now and after every navigation, never double-binds, and cleans up on astro:before-swap. Do not listen to astro:page-load directly: it does not fire without , and with one it can be lost for a whole page view when a navigation is interrupted after its swap.
Shared runtime cost: 1.9 kB raw, 1.0 kB gzip, once per site. Each byte figure in this file says raw (as built, before compression) or gzip.
Motion presets: set data-ma-preset="snap|ui|gentle|lively|ambient" on (or any subtree); every component resolves its curve, duration, travel and stagger from it.
## Components
- [Accordion](https://moonarc.dev/components/accordion.md): Native items whose height animates open and closed, with an optional one-at-a-time rule the browser enforces. Zero JavaScript: ::details-content is a grid whose row interpolates from 0fr to 1fr, so height-to-auto costs nothing to measure. Cost: 0 B JS. Support: newly (Chrome 131 · Firefox 143 · Safari 18.4). Intents: accordion, faq accordion, animate details summary, collapsible sections, height auto transition.
- [Animated Beam](https://moonarc.dev/components/animated-beam.md): Sends packets of light along curves between nodes. The layout is a preset (satellites around a hub, a row, or a fan into one), computed on the server in percent, so the SVG paths and the slotted nodes share coordinates and nothing is measured. Each beam is one dash, sized as a fraction of its path's on-screen length (computed in CSS from the box's container units), whose offset runs from start to past the end, with a fainter tail behind it. Zero JS. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 118 · Safari 16). Intents: animated beam between elements, integration diagram animated lines, connecting beams hub and spokes, data flow lines animation, animated connection lines svg.
- [Animated Icons](https://moonarc.dev/components/animated-icons.md): Six line icons that morph into a second state: menu to close, plus to close, copy to check, play to pause, sun to moon, and a check that draws itself. Each stroke is its own path moved by translate, rotate, scale, opacity and dash offset, so every pair works in every engine; play/pause also morphs with d: path() where the property exists. The state is a prop or comes from the button around it (aria-pressed, aria-expanded, data-state="done", data-on). Zero JavaScript. Cost: 0 B JS. Support: limited (Chrome 52 · Firefox 97 · not Safari). Intents: animated hamburger icon, menu to x icon animation, play pause morph icon, copy to check icon, sun moon icon animation, animated icons css.
- [Animated List](https://moonarc.dev/components/animated-list.md): Shows notifications arriving one at a time: the new one drops in at the top, the older ones are pushed down, and the oldest slides out. Zero JavaScript: in interval mode one registered number runs over the period on every item and the item's time slot decides where it is. Every change is a transition on the preset curve, and no keyframe knows how many items there are. In live mode the host prepends items (newest first) and they grow in through @starting-style while the oldest leaves. Cost: 0 B JS. Support: newly (Chrome 125 · Firefox 129 · Safari 17.5). Intents: animated notification list, notifications one by one, activity feed animation, list items slide in stack, animated list astro, chat messages arriving in sequence.
- [Animated Select](https://moonarc.dev/components/animated-select.md): A native select with an animated picker. Where the engine has appearance: base-select, the picker takes the tokens, the options arrive one after another through @starting-style with a delay from sibling-index(), the list leaves on allow-discrete and the checkmark is drawn. Elsewhere it is the native select with the same border and chevron, no animation. No imitated listbox: the keyboard, type-to-select, the value and the accessibility tree are the browser's. Zero JavaScript. Cost: 0 B JS. Support: limited (Chrome 138 · not Firefox · Safari 27). Intents: animated select, custom select css, styled dropdown native, select with animated options, customizable select, dropdown with stagger.
- [Arrow Button](https://moonarc.dev/components/arrow-button.md): A button whose arrow slides out on hover as a new one slides in. Two copies of the icon sit in one clipped cell, one translating out while the other comes in on the preset's spring. direction rotates the cell so up, down and left travel the way they point. Hover is read from the containing link or button too; focus draws the same. Zero JavaScript. Cost: 0 B JS. Support: widely (every browser). Intents: arrow button hover, button arrow slides out, cta arrow animation, link arrow animation, arrow that moves on hover.
- [Aurora Background](https://moonarc.dev/components/aurora.md): Ambient gradient field: three soft colour fields drifting at three coprime speeds, a slow hue rotation so the colours themselves move, and a film-grain layer stepped at 12 fps. No WebGL, no canvas, no blur filter: every layer is a transform on the compositor. Cost: 0 B JS. Support: widely (every browser). Intents: aurora background, gradient background animation, animated gradient blobs, ambient hero background astro, aurora without webgl.
- [Avatar Stack](https://moonarc.dev/components/avatar-stack.md): A row of overlapping avatars with a count chip such as "+2 398". Lazy images or initials, overlapped by a negative margin with a ring in the surface colour. Hover the row and it spreads; hover one and it rises and its name appears above it in a CSS tooltip. Avatars are not tab stops unless they carry an href; the names live in the alt text and the chip has its own screen-reader line. The count is formatted with Intl at build. Zero JavaScript. Cost: 0 B JS. Support: widely (every browser). Intents: avatar stack, avatar group, overlapping avatars, avatar circles hover, joined by avatars, social proof avatars.
- [Bar Grow](https://moonarc.dev/components/bar-grow.md): A bar chart whose bars grow from the baseline one after another when it scrolls into view; hovering a bar shows its value. Rendered on the server from the data: each bar is a flex child scaled from 0 to 1 on a per-index delay. Composes Reveal; no script of its own. The accessible name summarises the series. Cost: 0 B JS of its own · uses Reveal + runtime. Support: widely (every browser). Intents: animated bar chart, bars grow on scroll, css bar chart animation, stagger bars chart, tiny bar chart astro.
- [Border Beam](https://moonarc.dev/components/border-beam.md): A beam of light travels around the edge of a card. A conic gradient behind two composited masks leaves only the ring; the start angle animates as a registered custom property. Pure CSS, inherits the parent radius. Cost: 0 B JS. Support: newly (Chrome 120 · Firefox 128 · Safari 16.4). Intents: border beam, animated border, glowing card border, light around card edge, moving border gradient.
- [Browser Frame](https://moonarc.dev/components/browser-frame.md): A browser window around a screenshot or any content: the three lights, an address bar with a lock, optional tabs with one active. Static, zero JavaScript. The chrome scales with the frame's own width through container query units, and every colour is a theme token, so theme="dark" or "light" pins one look and "auto" follows the page. Cost: 0 B JS. Support: widely (Chrome 105 · Firefox 110 · Safari 16). Intents: browser window mockup, browser frame component, safari frame screenshot, mac window mockup, device frame astro.
- [Bubble Text](https://moonarc.dev/components/bubble-text.md): Swells the letter under the cursor to the heaviest weight and lifts it; its neighbours follow at half and a quarter, and everything settles when the pointer leaves. Letters split on the server, neighbours found with :has(). Pure CSS on a variable font. Cost: 0 B JS. Support: widely (Chrome 105 · Firefox 121 · Safari 15.4). Intents: bubble text hover, text weight hover effect, letters swell under cursor, variable font hover, hover text bulge.
- [Card Stack](https://moonarc.dev/components/card-stack.md): Cards stick to the top as you scroll and each one shrinks and dims as the next slides over it, as on Apple product pages. Zero JavaScript: sticky positioning plus each card's scale bound to the next card's view timeline. Up to eight cards. Cost: 0 B JS. Support: limited (Chrome 116 · not Firefox · Safari 26). Intents: card stack scroll, sticky stacking cards, stacked cards on scroll, apple style card stack, scroll stack astro.
- [Carousel](https://moonarc.dev/components/carousel.md): A scroll-snap strip with previous/next buttons and dot markers that the browser generates and keeps in sync. Zero JavaScript. Touch, momentum, keyboard and snapping are native everywhere; the buttons and dots appear where ::scroll-button() and ::scroll-marker exist. Cost: 0 B JS. Support: limited (Chrome 135 · not Firefox · not Safari). Intents: carousel, slider, scroll snap carousel, image carousel astro, carousel without javascript, testimonial slider.
- [Check Draw](https://moonarc.dev/components/check-draw.md): A checkbox whose tick is drawn. A label wraps a native input with appearance: none and an SVG beside it: the box fills on the fast token, then the tick (a path with pathLength 1) runs its dash offset from 1 to 0 on the preset curve. The indeterminate state draws a bar instead. The value submits, required and disabled work, the keyboard is the browser's. Zero JavaScript. Cost: 0 B JS. Support: widely (every browser). Intents: animated checkbox, checkbox with drawn check, checkmark animation, custom checkbox css, indeterminate checkbox, checkbox tick draws itself.
- [Circular Text](https://moonarc.dev/components/circular-text.md): A ring of text turning slowly around an icon, a logo, or nothing. SVG text on a circle, justified to the full circumference so the loop has no seam, spun by one compositor rotation. Pure CSS; the centre is the slot. Cost: 0 B JS. Support: widely (every browser). Intents: circular text, text on a circle, rotating badge text, spinning text ring, text around icon.
- [Code Tabs](https://moonarc.dev/components/code-tabs.md): A code block with tabs (for example npm, pnpm, bun) and a copy button per panel. Highlighted at build by Astro's own (Shiki) with light and dark themes as CSS variables, so it follows the page theme with no script. The tabs are radio inputs and :has(), so arrow keys and selection are native and the indicator slides on the preset. The only script is CopyButton's, shared; long lines scroll inside the panel. Cost: 0 B JS of its own · uses CopyButton + runtime. Support: widely (Chrome 117 · Firefox 129 · Safari 17.5). Intents: code block with tabs, npm pnpm yarn tabs, install command tabs, code tabs with copy button, shiki code tabs astro.
- [Command Palette](https://moonarc.dev/components/command-palette.md): A ⌘K command palette: a native modal dialog with an input and a ranked list of links. ↑ ↓ move, ↵ follows the link through the ClientRouter, Escape closes and focus returns to where it was; results are re-rendered and each arrives through @starting-style on the stagger token. Items come from the server, from a JSON URL fetched once on the first open, or both. Without JavaScript the invoker still opens the dialog and the server-rendered items are plain links. Cost: 3.0 kB raw JS · 1.4 kB gzip · + runtime. Support: newly (Chrome 135 · Firefox 144 · Safari 26.2). Intents: command palette, cmd k search, keyboard search dialog, spotlight search astro, site search modal, command menu.
- [Confetti](https://moonarc.dev/components/confetti.md): Fires a burst of paper confetti on load, on a click or on an ma:confetti event. One fixed canvas exists only while pieces are falling. Gravity, drag, launch speed and spread are custom properties declared per preset in the stylesheet: the script reads them and carries no constant. Also callable as confetti() from your own handler. Never fires under reduced motion. Cost: 2.4 kB raw JS · 1.3 kB gzip · + runtime + canvas. Support: widely (every browser). Intents: confetti on click, celebration animation, confetti burst success, party popper button, confetti astro without canvas-confetti, confetti after form submit, trigger confetti from javascript event.
- [Copy Button](https://moonarc.dev/components/copy-button.md): A button that copies text to the clipboard: the icon turns into a check, the label says "Copied", and both come back after the ambient duration. The clipboard write is the only script; it sets one attribute, data-state, and writes the outcome into a visually hidden status node rendered after the button, so a screen reader hears it; the icon (AnimatedIcons) and the label faces are CSS. When the clipboard refuses, the button says and announces "Copy failed". Cost: 837 B raw JS · 489 B gzip · + runtime. Support: widely (Chrome 66 · Firefox 63 · Safari 13.1). Intents: copy to clipboard button, copy button with check icon, copy code button, clipboard button astro, copied feedback.
- [Count Up](https://moonarc.dev/components/count-up.md): Counts a number up from zero to its value when it scrolls into view, with thousands separators, decimals, prefix and suffix. No script of its own: Reveal supplies the trigger, and the digits are CSS counters driven by a custom property transitioning from 0 to the target. The server HTML already shows the final number. Cost: 0 B JS of its own · uses Reveal + runtime. Support: newly (Chrome 91 · Firefox 128 · Safari 17). Intents: count up, animated number, number counter on scroll, statistics counter, countup astro.
- [Countdown Flip](https://moonarc.dev/components/countdown-flip.md): A flip clock counting down to a date: days, hours, minutes, seconds, each a card whose top half folds down over the hinge when the number changes. The only script is one timer a second, set to the moment the next second begins, that writes the digits and stops while the tab is hidden; the flip is CSS. The server renders the time left at build for readers without JavaScript, or the done state when the target has already passed. Cost: 1.1 kB raw JS · 649 B gzip · + runtime. Support: widely (Chrome 55 · Firefox 54 · Safari 13.1). Intents: countdown flip clock, flip clock countdown, launch countdown timer, countdown to date animation, flip counter css.
- [Counter Preloader](https://moonarc.dev/components/counter-preloader.md): A preloader that counts from 0 to 100 and then lifts like a curtain, on a fixed layer that never blocks the page: pointer-events none from the first frame, aria-hidden, the page rendered and usable beneath. The number is one registered integer printed through counter-set; the layer then translates off and ends hidden. It runs about two seconds, set by the tokens. once skips it for the rest of the session, on a reload and after every ClientRouter swap. Under reduced motion, or without @property, it never shows. Zero JavaScript. Cost: 0 B JS. Support: newly (Chrome 85 · Firefox 128 · Safari 17.2). Intents: preloader counter, page loader 0 to 100, loading screen counter, intro curtain, site preloader css, studio loading number.
- [Cursor](https://moonarc.dev/components/cursor.md): A custom pointer that trails the real one: a dot, a ring that grows over links and buttons, or a label ("View") any element can ask for with data-cursor-label. One fixed element; the script writes the position and a state, CSS transitions the lag, the growth and the pill on the preset curve. Not installed on touch or under reduced motion. Cost: 1021 B raw JS · 574 B gzip · + runtime. Support: widely (every browser). Intents: custom cursor, cursor follower, cursor that says view over images, mouse follower ring, blend mode cursor, custom mouse pointer astro.
- [Cursor Grid](https://moonarc.dev/components/cursor-grid.md): A field of cells that light up under the cursor and fade where it has been, with a slow idle sweep when nothing is touched. Zero JavaScript: every cell is an element whose own hover state decays on a transition, so the trail is the browser doing the work. Fills its positioned parent. Cost: 0 B JS. Support: widely (Chrome 105 · Firefox 121 · Safari 15.4). Intents: cursor grid, interactive grid background, hover grid cells, pointer reactive background, hero background reacts to mouse.
- [Curtain](https://moonarc.dev/components/curtain.md): A full-viewport wipe between pages: the next page opens through an iris from where you clicked, or through blinds, a shutter, doors, pixels, staggered columns, a diagonal, or a title panel that carries the next page's name. It animates the browser's own root view-transition snapshots with clip-path and mask, on Astro's router; back plays the shape in reverse. The only script is the click point. Cost: 479 B raw JS · 266 B gzip. Support: newly (Chrome 120 · Firefox 144 · Safari 18). Intents: page curtain transition, iris page transition, full screen wipe between pages, view transition root clip-path, blinds page transition, pixel page transition astro.
- [Dialog](https://moonarc.dev/components/dialog.md): A native modal that scales in over a blurred backdrop and scales out again, closes on Escape, the close button or a backdrop click, and traps focus, all handled by the browser. Zero JavaScript: the trigger uses the invoker command attribute; the exit is transition-behavior: allow-discrete. Cost: 0 B JS. Support: newly (Chrome 135 · Firefox 144 · Safari 26.2). Intents: modal dialog, animated modal, dialog open close animation, native dialog astro, modal without javascript.
- [Dock](https://moonarc.dev/components/dock.md): A macOS-style dock: the tile under the pointer swells, its neighbours swell less, and the row pushes apart to make room. Zero JavaScript: :has() sets one size number on the hovered tile and the four around it, and the tiles transition their size on the preset curve. Keyboard focus magnifies the same way; touch gets a plain row of links. Cost: 0 B JS. Support: widely (Chrome 105 · Firefox 121 · Safari 15.4). Intents: macos dock, dock navigation, magnifying icons on hover, dock menu astro, floating dock bottom of page, icon bar that grows under the cursor.
- [Dot Pattern](https://moonarc.dev/components/dot-pattern.md): A field of dots behind content, faded toward the edges, with an optional slow pulse. One tiled radial gradient and a mask; pure CSS. Fills its positioned parent. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 53 · Safari 15.4). Intents: dot pattern background, dotted background, dot grid, polka dot background css.
- [Dotted Map](https://moonarc.dev/components/dotted-map.md): A world map drawn as a grid of dots, with markers that pulse. The land is a 1° bitmask from Natural Earth, drawn on the server as one : each run of land cells in a row is a segment, and a dash pattern of zero-length dashes with round caps turns it into dots: a few hundred segments, not five thousand circles. Markers ping on a delay from the stagger token and carry a title. Zero JS. Cost: 0 B JS. Support: widely (every browser). Intents: dotted world map, world map with markers, dot map svg, map with pulsing locations, regions map astro.
- [Drawer](https://moonarc.dev/components/drawer.md): A bottom sheet that slides up over a scrim and can be dragged closed: it follows the finger, and on release springs back or leaves depending on distance and velocity, interruptible mid-flight. A native does the top layer, focus and Escape; the script is only the gesture. Cost: 933 B raw JS · 500 B gzip · + runtime. Support: newly (Chrome 135 · Firefox 144 · Safari 26.2). Intents: bottom sheet, drawer, draggable sheet, swipe to dismiss, mobile drawer astro, vaul alternative.
- [Dynamic Island](https://moonarc.dev/components/dynamic-island.md): A black pill that changes shape with its state. auto → auto never animates, so every state declares its width, height and radius in rem; the active one is data-state on the element, set by your script, and a small style block rendered per instance maps each name to its lengths and shows the matching child. The shape transitions on the preset spring; the old content blurs out on the fast token and the new one arrives after it. Zero JavaScript. Cost: 0 B JS. Support: widely (every browser). Intents: dynamic island, morphing pill notification, island state animation, pill that changes shape, live activity pill, expanding notification pill.
- [File Tree](https://moonarc.dev/components/file-tree.md): A project tree whose folders open with an animated height, a turning chevron and a folder glyph that tips open; rows can be lit up to say "this is the file you change". Zero JavaScript: folders are native and the height is ::details-content laid out as a grid row from 0fr to 1fr, the Accordion technique nested as deep as the tree goes. Cost: 0 B JS. Support: newly (Chrome 131 · Firefox 143 · Safari 18.4). Intents: file tree, project structure tree, animated folder tree, directory tree astro, docs file explorer, nested details accordion.
- [Filter Grid](https://moonarc.dev/components/filter-grid.md): Filter buttons over a grid of cards: the cards that stay slide to their new places, the ones that go fade out, the ones that return fade in. The motion is a same-document view transition, so the browser measures and moves them. The script toggles aria-pressed and hidden; each card is a transition group only for the duration through view-transition-name: match-element. Without JavaScript every card shows; under reduced motion they change places at once. Cost: 987 B raw JS · 535 B gzip · + runtime + morph. Support: newly (Chrome 137 · Firefox 144 · Safari 18.4). Intents: filterable grid, filter cards with animation, isotope style filter, portfolio filter astro, animated grid reflow, tag filter gallery.
- [Footer Reveal](https://moonarc.dev/components/footer-reveal.md): The page content slides up to reveal a footer that is already in place underneath. No timeline and no script: the footer is position: sticky at the bottom of the scrollport with a fixed height, and the content in front carries a higher z-index and its own background, so the only motion is the scroll itself. On a page shorter than the viewport the footer simply sits below the content. Cost: 0 B JS. Support: widely (every browser). Intents: footer reveal on scroll, sticky footer reveal, footer behind content, parallax footer, content slides over footer.
- [Glitch Text](https://moonarc.dev/components/glitch-text.md): Splits text into two coloured copies and jumps a few slices sideways for a fraction of a second, every few seconds; the rest of the time the text is clean. Two pseudo-element copies clipped to slices on step-end keyframes, so nothing tweens. Pure CSS, and completely still under reduced motion. Cost: 0 B JS. Support: widely (Chrome 55 · Firefox 54 · Safari 13.1). Intents: glitch text, rgb split text, glitch effect css, cyberpunk text animation, distorted text effect.
- [Globe](https://moonarc.dev/components/globe.md): A turning globe of dots that you can drag. The land is the same 1° bitmask DottedMap draws from, sent as a downsampled mask in a JSON block and decoded on the client into rows of dots spread evenly by latitude; each frame projects them orthographically, front side only, depth as alpha, in three batched fills. Markers pulse on the ambient token. Drag has inertia; touch-action keeps the page scrolling. An SVG globe stands in without JavaScript. Cost: 2.8 kB raw JS · 1.4 kB gzip · + runtime + canvas. Support: widely (every browser). Intents: 3d globe, rotating globe with markers, cobe alternative, dotted globe canvas, interactive globe astro, draggable globe.
- [Glyph Field](https://moonarc.dev/components/glyph-field.md): A field of braille dots that reads as a flowing contour map: two waves cross it, the colour turns along a sunset arc, and the cursor carves a trail that decays one dot at a time. No canvas and no frame loop: every cell is an element whose glyph is a CSS counter on a registered integer, the contours are noise computed on the server, and the waves are one stepping animation per row. ASCII and block sets are one prop away. Fills its positioned parent. Cost: 0 B JS. Support: newly (Chrome 125 · Firefox 128 · Safari 17.2). Intents: braille dot field, dot matrix background, ascii hero background, glyph field, ascii art background reacts to cursor, motion.dev style ascii hero, character field animation, terminal texture background, contour map background.
- [Gradient Text](https://moonarc.dev/components/gradient-text.md): A gradient fill drifting slowly through the text with no seam at the loop point. Only the background position moves. Pure CSS; works on any inline or block text. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 49 · Safari 14). Intents: gradient text, animated gradient text, rainbow text, color shifting headline.
- [Grid Pattern](https://moonarc.dev/components/grid-pattern.md): A hairline grid behind content, faded toward the edges, optionally drifting one cell at a time. Two repeating gradients and a mask; pure CSS. Fills its positioned parent. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 53 · Safari 15.4). Intents: grid background, grid pattern background, blueprint grid, faded grid lines background.
- [Highlight Marker](https://moonarc.dev/components/highlight-marker.md): A highlighter sweeps across the phrases you marked, one after another, when the sentence scrolls into view. Each phrase is a real whose background grows from the left; wrapped lines are painted as separate strokes. Composes Reveal; no script of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Support: widely (every browser). Intents: highlight text on scroll, marker highlight animation, highlighter sweep text, animated text highlight, mark animation css.
- [Horizontal Scroll](https://moonarc.dev/components/horizontal-scroll.md): A strip of items slides sideways while the page scrolls down and the section stays pinned. Zero JavaScript: a sticky viewport and a translate bound to the section's view timeline. Where scroll timelines are missing it is a normal horizontally scrollable strip. Cost: 0 B JS. Support: limited (Chrome 115 · not Firefox · Safari 26). Intents: horizontal scroll section, scroll sideways on vertical scroll, pinned horizontal scroll, horizontal scrolling gallery astro.
- [Hover Image Links](https://moonarc.dev/components/hover-image-links.md): A list of project links: hovering one floats its image beside the pointer, leaning the way the pointer moves, while the other links step back. One floating box per list with every image server-rendered in it; the script writes two lengths, a lean and an index, and CSS gives the follow its lag on the fast token. Keyboard focus and reduced motion show the image at a fixed spot; touch gets the list. Cost: 597 B raw JS · 359 B gzip · + runtime. Support: widely (Chrome 105 · Firefox 121 · Safari 15.4). Intents: hover image links, project list hover image follows cursor, link list with floating image, portfolio index hover preview, blog list hover cover, image reveal on link hover astro.
- [Hover Video](https://moonarc.dev/components/hover-video.md): A poster card that plays a muted clip while the pointer or focus is on it and rewinds when it leaves. The card is a link, the video decoration behind it with preload="none", so nothing loads until a hover; coarse pointers get a play/pause button, reduced motion never autoplays. The script is play(), pause() and a rewind. Cost: 684 B raw JS · 364 B gzip · + runtime. Support: widely (every browser). Intents: play video on hover, hover to play preview, video card hover, muted autoplay on hover astro, portfolio video thumbnails, work grid video preview.
- [Image Compare](https://moonarc.dev/components/image-compare.md): Compares a before and an after image with a line you drag between them. A native range input lies over the box, invisible, so dragging, clicking to jump, the arrow keys, touch and the screen reader are the browser's; the script writes its value to one custom property and the after image is clipped to it. Held, it follows with no lag; stepped, it glides on the fast token. Cost: 205 B raw JS · 177 B gzip · + runtime. Support: newly (Chrome 124 · Firefox 121 · Safari 16.5). Intents: before after slider, image comparison slider, compare two images drag, before after image astro, juxtapose images, split image reveal.
- [Image Trail](https://moonarc.dev/components/image-trail.md): Small images pop up along the pointer's path and fade behind it. The images are a server-rendered pool of lazy elements; every `threshold` px the script positions the next one and restarts its keyframes, so nothing is created on move. The pop and the fade are CSS on the preset curve, the lifetime a duration token. On touch and under reduced motion the first image simply rests in the centre, under the slotted content. Cost: 872 B raw JS · 504 B gzip · + runtime. Support: widely (Chrome 105 · Firefox 110 · Safari 16). Intents: image trail on cursor, images follow mouse, photo trail hover effect, cursor image trail astro, hover image reveal along mouse path.
- [Lightbox](https://moonarc.dev/components/lightbox.md): A thumbnail gallery whose images open full size: the image grows out of its own thumbnail on a same-document view transition and returns to it on close, and ← → move through the set. Built on Dialog morph: the dialog is native (Escape, the backdrop where closedby is supported, the close button, the focus trap), the growth is lib/morph, the caption and the count are a polite live region, and without JavaScript each thumbnail is a link to the full file. Cost: 972 B raw JS · 501 B gzip · + Dialog morph + runtime + morph. Support: newly (Chrome 111 · Firefox 144 · Safari 18). Intents: lightbox, image gallery lightbox, image zoom on click, photo grows from thumbnail, gallery modal astro, shared element transition image.
- [Link Preview](https://moonarc.dev/components/link-preview.md): A link that shows a small card (image, title, one line, domain) after a moment on hover or focus, above everything, flipping when there is no room. The card is a manual popover anchored to the link; the script only shows and hides it, the wait is a CSS transition-delay on a duration token, and everything on the card is a prop at build time, so nothing is fetched. Touch gets the link alone. Cost: 671 B raw JS · 405 B gzip · + runtime. Support: newly (Chrome 125 · Firefox 147 · Safari 26). Intents: link preview on hover, hover card link, link hover card with image, link preview astro, hovercard, preview tooltip for links.
- [Liquid Glass](https://moonarc.dev/components/liquid-glass.md): A glass pane that blurs and tints whatever is behind it. Every engine: backdrop blur and saturation, a specular rim, a tint from the tokens, a sheen that crosses on hover. The refraction at the rim is an SVG displacement map on its own backdrop-filter layer, built on the server from strength and edge and stretched to the box by the filter, so it works at any size with no measuring. Chromium bends the backdrop; Firefox and WebKit paint nothing on that layer and show the same glass without the bend. Zero JavaScript. Cost: 0 B JS. Support: limited (Chrome 76 · not Firefox · not Safari). Intents: liquid glass, glassmorphism css, frosted glass panel, glass card with refraction, apple liquid glass effect, backdrop blur card.
- [Magnetic](https://moonarc.dev/components/magnetic.md): A button or icon is pulled toward the cursor while it is nearby and springs back when it leaves. An invisible field around the child lets clicks through to its neighbours; one pointermove listener on the document measures the pointer against it, and the pull is CSS translate on the active preset's spring. No pull under reduced motion, read on every move. Cost: 619 B raw JS · 391 B gzip · + runtime. Support: widely (every browser). Intents: magnetic button, button follows cursor, magnetic hover effect, cursor attraction button.
- [Marquee](https://moonarc.dev/components/marquee.md): Infinite scrolling strip for logos, quotes or tags in any direction. The content is rendered twice (or repeat times) and the track moves by exactly one copy, so there is never a seam; a copy narrower than the strip stretches to fill it, so a short list never leaves a blank band. Pauses on hover; becomes a static scrollable strip under reduced motion. Pure CSS. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 53 · Safari 15.4). Intents: logo marquee, infinite scroll strip, logo loop, ticker, scrolling logos astro.
- [Meteors](https://moonarc.dev/components/meteors.md): Streaks falling diagonally across a twinkling sky. Each meteor is one element with a bright head, rotated to its angle and sent along its own axis; start, delay, length and pace come from a seeded generator on the server, so the same seed always draws the same sky. Stars are two tiled gradient layers blinking in alternation. Zero JS; fills its positioned parent. Cost: 0 B JS. Support: widely (Chrome 105 · Firefox 110 · Safari 16). Intents: meteor shower background, falling stars animation, shooting stars css, meteors effect hero, starry night background.
- [Noise](https://moonarc.dev/components/noise.md): Film grain over a gradient or image, blended and flickering at 12 fps. One SVG turbulence tile as a background whose translate steps; pure CSS, no canvas. Fills its positioned parent. Cost: 0 B JS. Support: widely (every browser). Intents: noise overlay, film grain effect, grain texture css, noisy background.
- [Number Flow](https://moonarc.dev/components/number-flow.md): A number whose digits roll to the new value when it changes. Each column slides to its digit on the preset spring, thousands separators stay put, and leading columns collapse when the number gets shorter. The value is one custom property your code writes; every column derives its digit from it with round() and mod(). No script of its own. Cost: 0 B JS. Support: newly (Chrome 125 · Firefox 118 · Safari 15.4). Intents: number flow, rolling digits, odometer number animation, animated counter on change, slot machine digits css, number transition.
- [Orb](https://moonarc.dev/components/orb.md): A sphere of light that breathes and slowly turns its colour. Three radial gradients on one element, soft at their edges so no blur filter is ever painted; the breath is a scale on the compositor and the colour shift is one registered number scaled to a drift angle every gradient adds to its hue. A conic highlight turns around the rim. Zero JS; centred in its positioned parent. Cost: 0 B JS. Support: newly (Chrome 85 · Firefox 128 · Safari 16.4). Intents: glowing orb background, breathing orb, ai orb animation, gradient sphere hero, siri orb css.
- [Orbiting Circles](https://moonarc.dev/components/orbiting-circles.md): The children orbit the centre of their parent and stay upright. One transform animation per item (rotate, translate out, rotate back) from its start angle to a full turn, on the compositor, no wrapper. Start angles come from :nth-child, the count from :has(). Two instances at two radii are two rings; `reverse` sends one the other way. Zero JS. Cost: 0 B JS. Support: widely (Chrome 105 · Firefox 121 · Safari 15.4). Intents: orbiting icons, icons rotating around logo, orbit animation css, planets orbit integration logos, circular orbit icons astro.
- [OTP Input](https://moonarc.dev/components/otp-input.md): A one-time code in cells, from one native input. Paste, SMS autofill, screen readers and Backspace only work in the single-input pattern, so the cells are drawn under the field and a monospace font with a computed letter-spacing puts each glyph in the middle of its cell. Full and valid, the check draws itself; :user-invalid tints the cells only after the reader has been there. Zero JavaScript. Cost: 0 B JS. Support: widely (Chrome 119 · Firefox 121 · Safari 16.5). Intents: otp input, one time code input, verification code boxes, pin input, sms code input, 6 digit code input css.
- [Page Transition](https://moonarc.dev/components/page-transition.md): Animates a named region between pages: rise, zoom, wipe, scope, fade, slide, or the browser's own shared-element morph. Zero JavaScript of its own: Astro's drives view transitions, and the presets are keyframes on the active motion preset's curve. Cost: 0 B JS. Support: newly (Chrome 111 · Firefox 144 · Safari 18). Intents: page transition, view transitions astro, animate between pages, shared element transition, transition:name preset, route transition.
- [Parallax](https://moonarc.dev/components/parallax.md): An element drifts at its own speed as it crosses the viewport, exactly in step with the scroll. Zero JavaScript: a translate bound to the element's own view timeline. Stack a few with different speeds for depth. Cost: 0 B JS. Support: limited (Chrome 115 · not Firefox · Safari 26). Intents: parallax, parallax scroll effect, background moves slower than foreground, scroll-driven parallax astro, parallax without javascript.
- [Particles](https://moonarc.dev/components/particles.md): A field of drifting dots that part around the cursor, on a canvas that draws only while on screen in a visible tab. The count follows the area (capped), every constant is a custom property declared per preset, the colours are the theme's and are re-read when it changes. Without JavaScript a still dot pattern in CSS stands in; under reduced motion one frame is drawn. Cost: 1.6 kB raw JS · 960 B gzip · + runtime + canvas. Support: widely (every browser). Intents: particles background, floating dots interactive, particles.js alternative, dots avoid cursor, constellation background canvas.
- [Persist Player](https://moonarc.dev/components/persist-player.md): An audio player that keeps playing while you navigate: the same element is carried into the next page by Astro's router, so position, volume and playback never restart. Native controls, zero JavaScript of its own. Put it in the layout; every page gets the one that is already playing. Cost: 0 B JS. Support: widely (every browser). Intents: persistent audio player astro, music keeps playing between pages, transition:persist audio, site-wide player view transitions, audio survives navigation.
- [Phone Frame](https://moonarc.dev/components/phone-frame.md): A generic phone frame around a screenshot or any content, with three cut-outs (island, notch, punch), a home bar, and no logo, buttons or brand. The chrome scales with the frame's width through container query units and shares BrowserFrame's tokens; scroll drifts content taller than the screen up and back on a translate keyframe, paused under the pointer. Zero JavaScript. Cost: 0 B JS. Support: widely (Chrome 105 · Firefox 110 · Safari 16). Intents: phone mockup, iphone frame css, device frame screenshot, mobile mockup scrolling, app screenshot frame, phone frame no brand.
- [Pill Nav](https://moonarc.dev/components/pill-nav.md): A floating pill of links whose active pill glides to the page you chose. Zero JavaScript: the server marks the current link, the pill carries a view-transition-name, and under ClientRouter the browser slides it across the swap; a faint pill follows hover and focus through anchor positioning. Cost: 0 B JS. Support: newly (Chrome 125 · Firefox 147 · Safari 26). Intents: pill navigation, floating nav pill, sliding active indicator nav, nav with animated indicator, navbar pill astro, tab bar that slides between pages.
- [Popover](https://moonarc.dev/components/popover.md): A popover that opens beside its trigger, flips when there is no room, closes on outside click or Escape, and animates in and out. Zero JavaScript: the popover attribute, anchor positioning and @starting-style do all of it. Cost: 0 B JS. Support: newly (Chrome 125 · Firefox 147 · Safari 26). Intents: popover, tooltip popover, anchored popup, dropdown without javascript, popover api astro.
- [Price Switch](https://moonarc.dev/components/price-switch.md): A monthly / yearly toggle whose prices roll to the other amount instead of swapping. The thumb slides, the period label changes places, and a "save" badge appears on the yearly option. Two native radios, :has() and NumberFlow. Zero JavaScript; both prices are in the HTML as text for assistive tech. Cost: 0 B JS. Support: newly (Chrome 125 · Firefox 129 · Safari 17.5). Intents: pricing toggle monthly yearly, price switch animation, billing period toggle, animated pricing switch, pricing table toggle astro.
- [Progress](https://moonarc.dev/components/progress.md): A bar that fills to its value when it scrolls into view, with the number counting up beside it, or a ring with the number in the middle. No script of its own: Reveal is the trigger and CountUp the number; the fill is one translate transition, the ring one dash offset. The server HTML already shows the final state. Cost: 0 B JS of its own · uses Reveal + runtime. Support: newly (Chrome 91 · Firefox 128 · Safari 17). Intents: progress bar, animated progress bar on scroll, skill bar, percentage bar animation.
- [Progressive Blur](https://moonarc.dev/components/progressive-blur.md): An edge that blurs what scrolls under it, more the closer it gets: a few bands, each with a backdrop blur twice the last and a mask that keeps it to its own slice, so the blur ramps instead of stepping. Nothing animates: the content moving beneath is the motion. Without backdrop-filter the edge fades to a colour. Zero JS. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 103 · Safari 18). Intents: progressive blur edge, gradient blur bottom of list, blurred fade scroll edge, apple style progressive blur, backdrop blur gradient css.
- [Prompt Input](https://moonarc.dev/components/prompt-input.md): The AI prompt box: a form with a textarea that grows with its content through field-sizing, a model select, an attachment button that is a real file input, and a send button that dims until something is typed and spins while the form carries data-pending. Zero JavaScript by default; submitOnEnter adds a measured script: Enter sends, Shift+Enter breaks the line, and an IME composition is never interrupted. Cost: 0 B JS. Support: newly (Chrome 123 · Firefox 152 · Safari 26.2). Intents: ai prompt input, chat input box, growing textarea, textarea autosize css, prompt box with model picker, chatgpt style input.
- [Reading TOC](https://moonarc.dev/components/reading-toc.md): A table of contents that lights up as you read. The list is server-rendered from items (Astro's own headings shape works), the links are plain anchors, and one passive scroll listener sets aria-current on the link of the last heading above the reading line, which is the only thing the script does. The indicator is CSS from that attribute. Works inside a scrolling box as well as on the page, follows jumps from its own links, and is dropped before every navigation. Cost: 899 B raw JS · 547 B gzip · + runtime. Support: widely (every browser). Intents: table of contents highlight on scroll, active heading toc, scrollspy, on this page navigation, reading progress toc.
- [Retro Grid](https://moonarc.dev/components/retro-grid.md): A perspective grid floor sliding toward the viewer. Two repeating gradients on one plane rotated in 3D; the motion is a translate of exactly one cell on the compositor, so the loop has no visible seam and never repaints. A mask fades the horizon. Zero JS; fills its positioned parent. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 53 · Safari 15.4). Intents: retro grid background, synthwave grid, perspective grid floor, moving grid background hero, tron grid css.
- [Ripple](https://moonarc.dev/components/ripple.md): Rings expand from a point and fade, one after another, like a pulse. Each ring is an element scaling and fading on its own delay; pure CSS, compositor only. Fills its positioned parent. Cost: 0 B JS. Support: widely (every browser). Intents: ripple effect, pulsing rings, radar pulse background, concentric circles animation.
- [Rotating Text](https://moonarc.dev/components/rotating-text.md): Cycles through a list of words in place. Each word rises in, holds, and leaves upward, and the box is sized to the widest word so the surrounding text never shifts. Pure CSS. Cost: 0 B JS. Support: newly (Chrome 85 · Firefox 128 · Safari 16.4). Intents: rotating words, word cycle animation, flip words, animated headline words, text loop astro.
- [Scroll Expand](https://moonarc.dev/components/scroll-expand.md): An image that starts narrow and rounded and opens to the full width as it scrolls into view. The layout never changes: the element is full width from the start and a clip-path inset with its rounding shrinks it, animated on the element's own view() timeline; the content inside scales up a touch for depth. Without scroll timelines it is simply full width. Zero JavaScript. Cost: 0 B JS. Support: limited (Chrome 115 · not Firefox · Safari 26). Intents: image expands on scroll, scroll zoom image full width, container scroll expand, scroll expand media, hero image grows on scroll.
- [Scroll Progress](https://moonarc.dev/components/scroll-progress.md): A hairline along the top of the viewport that fills as the page is read. Zero JavaScript: its scale is bound to the document's scroll timeline, so nothing listens to scroll and it is never a frame behind. Cost: 0 B JS. Support: limited (Chrome 115 · not Firefox · Safari 26). Intents: scroll progress bar, reading progress indicator, page scroll indicator, progress bar on scroll astro.
- [Scroll Reveal](https://moonarc.dev/components/reveal.md): Entrance on scroll that plays once and stays, staggers its children, scrubs with the scroll position when asked, honours reduced motion, and keeps working after every ClientRouter navigation. Server HTML stays readable without JavaScript. Cost: 1.3 kB raw JS · 718 B gzip · + runtime. Support: widely (every browser). Intents: scroll reveal, fade in on scroll, animate on scroll, AOS alternative, stagger children on scroll, scroll-linked reveal, view transitions safe reveal.
- [Scroll Scrub](https://moonarc.dev/components/scroll-scrub.md): Bind translate, scale, rotate and opacity to the scroll position: the element goes from the start values you give to neutral across a range of its own passage through the viewport, exactly in step. Zero JavaScript. Cost: 0 B JS. Support: limited (Chrome 115 · not Firefox · Safari 26). Intents: scroll linked animation, scrub animation with scroll, animate on scroll position, scroll-driven transform, scrolltrigger scrub alternative.
- [Shimmer Button](https://moonarc.dev/components/shimmer-button.md): A highlight sweeps across the body of a button on a loop; hover lifts it on the preset's hover travel and adds a ring, and focus draws the same. One pseudo-element gradient whose position animates: no layout, though every frame repaints the button's own box. Renders a or an . Zero JavaScript. Cost: 0 B JS. Support: widely (every browser). Intents: shimmer button, shiny button, animated cta button, button with light sweep, glowing button astro.
- [Shiny Text](https://moonarc.dev/components/shiny-text.md): A highlight sweeps across the text every few seconds. The text keeps its own colour; the shine is a gradient clipped to a repeated copy on top, and only its position animates. Pure CSS. Cost: 0 B JS. Support: widely (Chrome 120 · Firefox 49 · Safari 14). Intents: shiny text, shimmer text, text highlight sweep, glossy text animation, shine effect on text.
- [Skeleton](https://moonarc.dev/components/skeleton.md): Placeholder lines, optionally with an avatar, shimmering while content loads. The shimmer is a gradient texture whose position moves; pure CSS. Marks itself busy for assistive tech. Cost: 0 B JS. Support: widely (every browser). Intents: skeleton loader, loading placeholder, shimmer loading, content placeholder animation.
- [Sparkline](https://moonarc.dev/components/sparkline.md): A small line chart that draws itself from left to right when it scrolls into view; the last point lands and pulses. The SVG is rendered on the server from the data, the line is uncovered by a clip that sweeps from its left edge to its right, and the accessible name summarises the series. Composes Reveal; no script of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Support: widely (Chrome 55 · Firefox 54 · Safari 13.1). Intents: sparkline, animated line chart, svg line draw on scroll, tiny chart astro, trend line animation.
- [Spinner](https://moonarc.dev/components/spinner.md): An indeterminate arc whose length breathes while it rotates, so it looks like it is working rather than spinning a fixed wedge. One SVG circle, pure CSS; announces itself as a status. Cost: 0 B JS. Support: widely (every browser). Intents: loading spinner, css spinner, indeterminate loader, spinner astro.
- [Split Flap](https://moonarc.dev/components/split-flap.md): A departures board: every character spins through the alphabet and locks, one cell after another, when the board scrolls into view. Each glyph is a CSS counter on a registered integer that transitions from blank to the letter, and a flap turns once per step. Composes Reveal; no script of its own. The server HTML already reads the final text. Cost: 0 B JS of its own · uses Reveal + runtime. Support: newly (Chrome 91 · Firefox 128 · Safari 17.2). Intents: split flap text, departures board animation, airport board text, flip board letters, solari board css.
- [Split Text](https://moonarc.dev/components/split-text.md): Splits a string into words, characters or lines on the server and reveals them with a capped stagger when they scroll into view. One string to screen readers, zero script of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Support: widely (every browser). Intents: split text animation, animate words on scroll, staggered text reveal, character reveal, text animation astro.
- [Spotlight](https://moonarc.dev/components/spotlight.md): A soft radial light follows the cursor over a card and fades in only while hovered. One pointermove listener writes two custom properties; the light itself is a CSS gradient. Bound through the shared runtime, so it survives navigation. Cost: 340 B raw JS · 250 B gzip · + runtime. Support: widely (Chrome 120 · Firefox 53 · Safari 15.4). Intents: spotlight card, cursor light effect, hover glow follows mouse, radial gradient follows cursor, spotlight hover astro.
- [Stagger Menu](https://moonarc.dev/components/stagger-menu.md): A burger that opens a full-screen menu (or a top sheet, or a side panel) whose items arrive one after another and leave in reverse. No script: a native modal dialog opened by the invoker command (focus trap, Escape, backdrop click and the focus returning to the burger are the browser's), and each item is a @starting-style transition delayed by its index on the stagger token. A link to a place on the same page carries a one-line onclick that closes the menu. Cost: 0 B JS. Support: newly (Chrome 135 · Firefox 144 · Safari 26.2). Intents: fullscreen menu, staggered menu items, burger menu overlay, hamburger menu animation astro, menu items animate in one by one, mobile nav overlay.
- [Stateful Button](https://moonarc.dev/components/stateful-button.md): One submit button with four faces (idle, pending with a spinner, done with a check that draws itself, error) and a width that follows the label. The state is data-state on the button, set by the prop, by your script, or inherited from a form that carries data-pending. The faces are clipped to a bound derived from the label, so nothing is measured, and only the face that shows is in the accessibility tree. Zero JavaScript of its own. Cost: 0 B JS. Support: widely (every browser). Intents: loading button, submit button with spinner, button success state, stateful button, button that shows sending and done.
- [Sticky Banner](https://moonarc.dev/components/sticky-banner.md): An announcement ribbon that sticks to the top of the page and folds away when dismissed, the content below sliding up on the preset curve. Zero JavaScript: a non-modal dialog closed by a form with method="dialog", a grid row that :has() collapses, and an exit through allow-discrete. remember inlines 286 B raw that keep it closed across pages. Cost: 0 B JS. Support: newly (Chrome 117 · Firefox 129 · Safari 17.4). Intents: announcement banner, sticky top banner dismissible, promo bar, cookie bar without javascript, site notice ribbon, banner that remembers dismissal.
- [Sticky Reveal](https://moonarc.dev/components/sticky-reveal.md): Steps on the left scroll by; one visual on the right stays put and changes with them. Each step names its own view timeline, the visuals are stacked in a sticky cell, and each visual's opacity and travel are bound to its step through timeline-scope. Without scroll timelines, or in a narrow container, the steps and visuals interleave in one column so every step still meets its own visual. Zero JavaScript. Cost: 0 B JS. Support: limited (Chrome 116 · not Firefox · Safari 26). Intents: sticky scroll reveal, scroll steps with sticky image, features scroll with changing image, sticky scroll section, scrollytelling astro.
- [Stroke Draw](https://moonarc.dev/components/stroke-draw.md): A headline's outline draws itself glyph by glyph when it scrolls into view, then the fill comes in. SVG text with one stroked per character, a dash longer than any outline offset to zero on a per-index delay. Composes Reveal; no script of its own. The server HTML holds the finished text. Cost: 0 B JS of its own · uses Reveal + runtime. Support: widely (every browser). Intents: text stroke animation, draw text outline svg, handwritten headline animation, svg text stroke dashoffset, outline text draw on scroll.
- [Switch](https://moonarc.dev/components/switch.md): A toggle that springs. It is a native checkbox with role="switch" and appearance: none (the input is the track, its ::before the thumb), so the value submits, required and disabled work, Space flips it, and the thumb travels on the preset curve with a bounce under the snap and lively presets. Zero JavaScript. Cost: 0 B JS. Support: widely (every browser). Intents: toggle switch, animated switch, checkbox as switch, ios style toggle, switch with spring, settings toggle.
- [Tabs](https://moonarc.dev/components/tabs.md): Tabs with an indicator that slides to the selected one and panels that fade in. Zero JavaScript: the tabs are radio inputs, so keyboard and selection are native, and :has() turns the checked index into the indicator's position. Cost: 0 B JS. Support: widely (Chrome 117 · Firefox 129 · Safari 17.5). Intents: tabs, animated tab indicator, sliding underline tabs, tabs without javascript, segmented control.
- [Text Roll](https://moonarc.dev/components/text-roll.md): A label rolls upward into a copy of itself on hover, letter by letter from the left, and rolls back when the pointer leaves. Two copies in one clipped cell, one translate per character on a per-index delay. Pure CSS; works from the link or button around it. Cost: 0 B JS. Support: widely (every browser). Intents: text roll hover, rolling link text, hover text flip up, letter roll animation, text roll motion primitives.
- [Text Scramble](https://moonarc.dev/components/text-scramble.md): Random characters resolve into the real text from left to right when it scrolls into view, on load, or on hover. The server HTML is the final string; a small requestAnimationFrame loop does the rest and never runs under reduced motion. Cost: 921 B raw JS · 530 B gzip · + runtime. Support: widely (every browser). Intents: text scramble, decrypt text effect, hacker text animation, scramble letters into words, decode text on scroll.
- [Theme Toggle](https://moonarc.dev/components/theme-toggle.md): Cycles system → light → dark, and the page changes theme through a circle that grows from the click, on a same-document view transition. ThemeScript in stores the choice, applies it before paint and after every swap and exposes the API; ThemeToggle's own script only advances the choice and wraps the change (its storageKey prop is ThemeScript's). Without view transitions, or under reduced motion, the theme switches at once. Without ThemeScript, which includes a page without JavaScript, the toggle is hidden. The icon is AnimatedIcons (sun to moon). Cost: 1.0 kB raw JS · 613 B gzip · + runtime. Support: newly (Chrome 111 · Firefox 144 · Safari 18). Intents: dark mode toggle, theme toggle with animation, theme switch circle transition, view transition dark mode, light dark system toggle astro.
- [Tilt](https://moonarc.dev/components/tilt.md): A card leans toward the cursor in 3D, lifts slightly, catches a glare, and settles back on the active preset's spring when the cursor leaves. The pointer writes two custom properties; everything visible is CSS. Never binds under reduced motion. Cost: 588 B raw JS · 346 B gzip · + runtime. Support: widely (every browser). Intents: tilt card, 3d hover card, card tilts on mouse move, parallax tilt effect, vanilla-tilt astro.
- [Toast](https://moonarc.dev/components/toast.md): Notifications that slide in, stack behind each other, push up as new ones arrive, and expand into a list on hover. Raise one from anywhere with toast() or a DOM event; timers pause while the stack is hovered or focused and while the tab is hidden, and the region is a polite live region. The stack geometry is CSS reading one custom property per toast. Cost: 1.0 kB raw JS · 605 B gzip · + runtime. Support: newly (Chrome 117 · Firefox 129 · Safari 17.5). Intents: toast notification, sonner alternative, stacked toasts, notification stack, toast astro.
- [Tracing Beam](https://moonarc.dev/components/tracing-beam.md): A line beside an article fills as it is read, with a dot at its head. One registered percentage animates on the article's own view() timeline, and both the fill's height and the head's position read that value. Without scroll timelines the line is full and still. Correct for an article shorter than the viewport too. Zero JavaScript. Cost: 0 B JS. Support: limited (Chrome 115 · not Firefox · Safari 26). Intents: tracing beam, article progress line, scroll progress beside content, vertical reading progress, beam follows scroll.
- [Typewriter](https://moonarc.dev/components/typewriter.md): Types a string one character at a time in any font, with a caret that stays solid while typing and blinks once idle. Pure CSS: every character is a span whose display animates on its own delay. Cost: 0 B JS. Support: limited (Chrome 116 · not Firefox · Safari 18). Intents: typewriter effect, typing animation, type text one character at a time, terminal typing effect astro.
- [Underline Hover](https://moonarc.dev/components/underline-hover.md): A link underline that enters from the left on hover and leaves to the right, so the exit continues the entrance instead of rewinding it. One background gradient, no pseudo-element, wraps across lines. Pure CSS; triggered by the link around it. Cost: 0 B JS. Support: widely (every browser). Intents: underline hover animation, link underline slide in, animated underline css, underline left to right hover, nav link underline effect.
- [Vanish Input](https://moonarc.dev/components/vanish-input.md): Placeholders that take turns, and text that blurs away on submit. A native input in your form: the first suggestion is the placeholder attribute, the rest cycle in an aria-hidden overlay driven by one registered number, so their entrances are transitions on the preset curve. A small script listens for submit on the document and, only when your handler prevented the default, splits the value into characters that rise and blur out on the stagger token. Cost: 604 B raw JS · 375 B gzip · + runtime. Support: newly (Chrome 125 · Firefox 128 · Safari 16.4). Intents: placeholders and vanish effect, input with rotating placeholder, text vanishes on submit, animated placeholder input, search input hints cycle, waitlist input animation.
- [Video Dialog](https://moonarc.dev/components/video-dialog.md): A poster with a breathing play button that opens the video in a dialog: a file with native controls, or an embed. The dialog is Dialog (native, invoker-opened, optionally morphing out of the poster); the script does what a closed dialog will not: play on open, pause on close, and for an embed set the iframe src on open and blank it on close so nothing loads or keeps playing behind a closed dialog. Cost: 604 B raw JS · 374 B gzip · + runtime. Support: newly (Chrome 135 · Firefox 144 · Safari 26.2). Intents: video modal, play video in dialog, hero video popup, youtube embed modal astro, video lightbox, poster with play button opens video.
- [Weight Wave](https://moonarc.dev/components/weight-wave.md): A wave of boldness rolls through the letters of a line, each character animating its font weight on its own delay. Pure CSS. Continuous with a variable font; steps between available weights otherwise. Cost: 0 B JS. Support: widely (Chrome 62 · Firefox 62 · Safari 11). Intents: variable font animation, font weight wave, text weight animation, animate font-weight, wavy bold text.
## Pro (demo public, source gated)
- [404](https://moonarc.dev/components/not-found-section.md): A 404 page: the code scrambles into place from random digits, rings spread slowly behind it, and the headline, copy and one link home arrive in three beats. Cost: 0 B JS of its own · uses TextScramble + runtime + Reveal. Install: `npx shadcn@latest add @moonarc-pro/not-found-section` with a license key (https://moonarc.dev/account/).
- [Blog Grid](https://moonarc.dev/components/blog-grid.md): Shows blog posts as cards, with the first post featured across two columns. Cards reveal with a stagger and covers ease larger on hover. Each cover carries a transition name, so with Astro's router a click morphs it into the post's own cover. Give the post page the same name. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/blog-grid` with a license key (https://moonarc.dev/account/).
- [Call to Action](https://moonarc.dev/components/cta-section.md): A closing call to action: a deep brand panel with an aurora and film grain behind it, a headline that catches a shine, a magnetic primary action, a secondary one, and a typed command. Scales in as it is reached. Cost: 0 B JS of its own · uses Magnetic + runtime + Reveal. Install: `npx shadcn@latest add @moonarc-pro/cta-section` with a license key (https://moonarc.dev/account/).
- [Changelog](https://moonarc.dev/components/changelog-section.md): Lists dated releases in a hairline list. Each entry reveals as it is reached, and the newest version catches a shine. Every entry carries its date, so readers can check how often you ship. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/changelog-section` with a license key (https://moonarc.dev/account/).
- [Comparison Table](https://moonarc.dev/components/compare-table.md): Compares your product with others in an "us versus them" table. The first column is highlighted, rows reveal with a stagger, and a thin bar under each numeric cell shows a byte count or a score at a glance. A semantic table with zero JavaScript of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/compare-table` with a license key (https://moonarc.dev/account/).
- [Dither](https://moonarc.dev/components/dither.md): Draws slow noise waves on the GPU, ordered-dithered into pixel cells of one colour on the page's ground, for the look of a 1-bit screen. The pointer lifts the field around it. The drawing buffer is one pixel per cell, scaled up pixelated by CSS, so the shader touches a ninth of the pixels at the default cell. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript a still dot grid stands in. Fills its positioned parent. Cost: 1.2 kB raw JS · 776 B gzip · + runtime + shader + canvas + gl, 10.8 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/dither` with a license key (https://moonarc.dev/account/).
- [Docs Shell](https://moonarc.dev/components/docs-shell.md): A documentation layout: a sticky sidebar with the current page marked, a reading-progress hairline bound to the scroll, the header and content revealed in two beats, and previous/next links. Content is the default slot. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/docs-shell` with a license key (https://moonarc.dev/account/).
- [Editorial Hero](https://moonarc.dev/components/hero-editorial.md): A split hero: a tall headline revealed line by line on the left, a live panel sliding in from the right, on a slowly drifting grid. Copy and actions follow in two beats; the primary action is magnetic. Everything inside is free-tier; the composition is what is sold. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/hero-editorial` with a license key (https://moonarc.dev/account/).
- [FAQ](https://moonarc.dev/components/faq-section.md): 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 . Zero JavaScript of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/faq-section` with a license key (https://moonarc.dev/account/).
- [Feature Atlas](https://moonarc.dev/components/feature-atlas.md): Lays out features as a bento grid: one slab split by 1 px hairlines, with the page ground showing through the gaps. Each cell has a stage slot for a live demo, an index, a title (a link when `href` is set), a blurb and one readout line. Cells reveal with a stagger, and two can be accent-filled. The Moonarc home page's atlas uses the same pattern. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/feature-atlas` with a license key (https://moonarc.dev/account/).
- [Feature Rows](https://moonarc.dev/components/feature-rows.md): Shows features in alternating rows of copy and a visual. The copy reveals from its side, and the visual rises and sharpens exactly in step with the scroll. One slot per row for a live demo, a screenshot or a video. Zero JavaScript of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/feature-rows` with a license key (https://moonarc.dev/account/).
- [Field Hero](https://moonarc.dev/components/hero-field.md): A hero with a field of glyphs behind a panel in the brand colour (ink on a page without a theme) whose meta line, headline and actions wipe in one after another. The field is CSS counters on server-drawn noise, with two crossing waves and a cursor trail that decays one character at a time. Zero JavaScript of its own; swish inlines one measured listener. Cost: 0 B JS. Install: `npx shadcn@latest add @moonarc-pro/hero-field` with a license key (https://moonarc.dev/account/).
- [Flow Particles](https://moonarc.dev/components/flow-particles.md): Moves thousands of particles along an invisible current, leaving fading trails. Positions live in a float texture that a GPU pass moves along curl noise, which is divergence-free, so the particles swirl instead of bunching. Each frame they are drawn as points into a trail texture that fades, shown in two tones on the page's ground. The pointer drags the current with it. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or a colour-renderable float texture, or without JavaScript, a still wisp of lines stands in. Fills its positioned parent. Cost: 2.9 kB raw JS · 1.6 kB gzip · + runtime + canvas + gl, 11.4 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/flow-particles` with a license key (https://moonarc.dev/account/).
- [Fluid Field](https://moonarc.dev/components/fluid-field.md): Draws smoke that follows the cursor. It is a real fluid simulation on the GPU (advection, vorticity confinement and a pressure solve in WebGL2), drawn in two tones: the ground and one colour. The dye is one channel coloured at display time, so a theme change never resets the smoke; `dots` lights a halftone grid instead of a wash. A slow emitter wanders around the focus while the pointer is still and on touch. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript a still glow stands in. Fills its positioned parent. Cost: 1.9 kB raw JS · 1.1 kB gzip · + runtime + canvas + gl + fluid, 12.8 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/fluid-field` with a license key (https://moonarc.dev/account/).
- [Footer](https://moonarc.dev/components/footer-section.md): A site footer: brand and blurb, link columns revealed with a stagger, a legal row, and a dot field fading up from the bottom edge. Pure CSS. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/footer-section` with a license key (https://moonarc.dev/account/).
- [Gooey](https://moonarc.dev/components/gooey.md): Draws a cluster of liquid drops that merge and pull apart: metaballs on the GPU with a compact kernel, cut with an edge exactly one pixel soft. Seven drops orbit a focus at their own pace; an eighth follows the pointer on a spring and the others lean toward it, so the cluster stretches after the cursor, necks form between drops, and it gathers again when the pointer leaves. Two tones: the body, and a core only where drops overlap. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript two still drops stand in. Fills its positioned parent. Cost: 1.1 kB raw JS · 752 B gzip · + runtime + shader + canvas + gl, 10.6 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/gooey` with a license key (https://moonarc.dev/account/).
- [Hero Section](https://moonarc.dev/components/hero-section.md): A complete hero as one component with props: an ambient aurora, a headline split and revealed word by word, supporting copy with a rotating word, two actions and a typed command. The parts arrive in a fixed order and timing. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/hero-section` with a license key (https://moonarc.dev/account/).
- [Hyperspeed](https://moonarc.dev/components/hyperspeed.md): Draws a jump to light speed: streaks of light rush out of a vanishing point, longer and brighter toward the edge, in one colour with a hot head in a second tone. Three layers of angular sectors on the GPU, each streak at its own pace; the vanishing point leans toward the pointer, and holding the pointer down on the host (or Space or Enter while the host itself has focus) punches the drive: streaks stretch and the rush speeds up, easing back on release. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript a still starburst stands in. Fills its positioned parent. Cost: 1.5 kB raw JS · 928 B gzip · + runtime + shader + canvas + gl, 11.1 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/hyperspeed` with a license key (https://moonarc.dev/account/).
- [Ink Reveal](https://moonarc.dev/components/ink-reveal.md): Covers content with a layer that the cursor washes away like ink in water, showing what is underneath. The content is ordinary HTML in the slot, in the page for readers, search and keyboard users from the start. The cover is a canvas above it, drawn by the GPU: a fluid simulation whose dye is the hole, with a ragged, moving edge and a soft grain. The ink fades back at `fade` per second (0 keeps what was revealed). A small swirl opens at the centre on the first frame to say there is something underneath. Focus inside, reduced motion, a touch device without hover, no WebGL2 or no JavaScript all show the content with no cover. Cost: 1.6 kB raw JS · 1.0 kB gzip · + runtime + canvas + gl + fluid, 12.5 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/ink-reveal` with a license key (https://moonarc.dev/account/).
- [Integration Grid](https://moonarc.dev/components/integration-grid.md): A grid of integrations, tools or partners: cards with an icon, a name and a line, each lit by a spotlight that follows the cursor and lifting on hover, revealed with a tight stagger. Cost: 0 B JS of its own · uses Spotlight + runtime + Reveal. Install: `npx shadcn@latest add @moonarc-pro/integration-grid` with a license key (https://moonarc.dev/account/).
- [Liquid Chrome](https://moonarc.dev/components/liquid-chrome.md): Draws a pool of liquid metal. Coordinates are folded through six octaves of sine warps on the GPU and read through a chrome ramp (a deep body, a sharp bright horizon, a soft sky), tinted by one colour with a highlight tone. Opaque, like metal. The pointer sends ripples across the surface. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript a still brushed-metal gradient stands in. Fills its positioned parent. Cost: 744 B raw JS · 508 B gzip · + runtime + shader + canvas + gl, 10.3 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/liquid-chrome` with a license key (https://moonarc.dev/account/).
- [Liquid Image](https://moonarc.dev/components/liquid-image.md): Makes an image turn liquid under the cursor and settle back. A velocity field on the GPU (WebGL2 stable fluids, no dye) displaces where the picture is sampled, with a touch of chromatic split along the flow. The picture is a real , which keeps alt, lazy loading, srcset and the LCP candidate, and is what shows without JavaScript or WebGL. The canvas above it takes over only while the fluid moves and hands back once it has settled. object-fit: cover and the image's object-position are matched in the shader. A cross-origin image without CORS, or one larger than the GPU takes as a texture (8192 px a side on many devices), stays a plain image. Every constant is a custom property re-read when the element's style changes. Cost: 2.3 kB raw JS · 1.3 kB gzip · + runtime + canvas + gl + fluid, 13.1 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/liquid-image` with a license key (https://moonarc.dev/account/).
- [Logo Wall](https://moonarc.dev/components/logo-wall.md): A "trusted by" section: a heading, a strip of greyscale logos drifting past that colour up on hover, and optionally the same logos as a hairline grid revealed with a stagger. Pure CSS. Cost: 0 B JS. Install: `npx shadcn@latest add @moonarc-pro/logo-wall` with a license key (https://moonarc.dev/account/).
- [Mega Menu](https://moonarc.dev/components/mega-menu.md): A menu bar whose panels open as popovers anchored under their triggers, columns revealing with a stagger, closing on Escape or outside click. Zero JavaScript of its own: the popover attribute and anchor positioning do the menu; Reveal does the columns. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/mega-menu` with a license key (https://moonarc.dev/account/).
- [Newsletter](https://moonarc.dev/components/newsletter-section.md): An email signup section built on a real form: native validation, an invalid state that only shows after the user has typed, a submit button whose label swaps for a spinner when the form carries data-pending, a status line for your handler, and a dot field behind. It takes a list service's form as it is (field name, hidden fields, a honeypot, form attributes) and only posts. Zero JavaScript of its own; wire the fetch yourself or let the form post. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/newsletter-section` with a license key (https://moonarc.dev/account/).
- [Plasma](https://moonarc.dev/components/plasma.md): Draws glowing ribbons of light drifting through each other: four sine fields interfere on the GPU, the sum folds into soft bands, and each band glows in a colour sliding between two tones with a hot core at its peak. The ground between the ribbons is the page, so it reads on either theme: neon on dark, pastel on light. The pointer draws the plasma toward it. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript a still two-tone glow stands in. Fills its positioned parent. Cost: 723 B raw JS · 487 B gzip · + runtime + shader + canvas + gl, 10.2 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/plasma` with a license key (https://moonarc.dev/account/).
- [Pricing Cards](https://moonarc.dev/components/pricing-cards.md): Shows pricing plans side by side, with an annual/monthly toggle that swaps every price with zero JavaScript (radios and :has), the highlighted plan wearing a travelling border beam, cards revealed with a stagger. Plans with no monthly price render without the toggle. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/pricing-cards` with a license key (https://moonarc.dev/account/).
- [Pricing Table](https://moonarc.dev/components/pricing-table.md): A feature-by-plan comparison: the highlighted plan's column lit, rows revealed with a 40 ms stagger as the table scrolls into view, and a header row that sticks when you cap the table's height. Semantic table, zero JavaScript of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/pricing-table` with a license key (https://moonarc.dev/account/).
- [Silk](https://moonarc.dev/components/silk.md): Draws a sheet of fabric drifting in slow folds, lit from one side: a warped height field on the GPU, normals from finite differences, a diffuse body in the colour and a narrow sheen in a second tone. The troughs keep a trace of the colour and let the page's ground through, so it reads on either theme. The pointer presses a soft dent into the cloth. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript a still diagonal sheen stands in. Fills its positioned parent. Cost: 1.1 kB raw JS · 683 B gzip · + runtime + shader + canvas + gl, 10.6 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/silk` with a license key (https://moonarc.dev/account/).
- [Stats Row](https://moonarc.dev/components/stats-row.md): Shows big numbers that count up when scrolled into view, 120 ms apart, with labels and an optional bar under each, in a hairline row. No script of its own: CountUp and Progress do the counting. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/stats-row` with a license key (https://moonarc.dev/account/).
- [Steps / Timeline](https://moonarc.dev/components/steps-section.md): A vertical timeline: the line draws itself down the page in step with the scroll, each step revealing from the line's side as it is reached, markers numbered or dated. Zero JavaScript of its own; where scroll timelines are missing the line is simply drawn. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/steps-section` with a license key (https://moonarc.dev/account/).
- [Sticky Nav Bar](https://moonarc.dev/components/nav-bar.md): A sticky navigation bar that condenses over the first 120 px of scroll: the row tightens and a hairline appears, bound to the document's scroll timeline. Zero JavaScript; where scroll timelines are missing it is a plain sticky bar with the hairline. Cost: 0 B JS. Install: `npx shadcn@latest add @moonarc-pro/nav-bar` with a license key (https://moonarc.dev/account/).
- [Team Grid](https://moonarc.dev/components/team-grid.md): Shows team members in a hairline grid: portraits that tilt toward the cursor with a glare, initials when there is no photo, names and roles revealed with a stagger. Cost: 0 B JS of its own · uses Tilt + runtime + Reveal. Install: `npx shadcn@latest add @moonarc-pro/team-grid` with a license key (https://moonarc.dev/account/).
- [Terminal Hero](https://moonarc.dev/components/hero-terminal.md): A hero for developer tools: split headline on the left, a terminal window on the right that types the install command and prints its output line by line, on a pulsing dot field. Zero JavaScript of its own. Cost: 0 B JS of its own · uses Reveal + runtime. Install: `npx shadcn@latest add @moonarc-pro/hero-terminal` with a license key (https://moonarc.dev/account/).
- [Testimonial Cards](https://moonarc.dev/components/testimonial-cards.md): Shows testimonial quotes in a staggered grid. Each card tilts gently toward the cursor, and the featured quote spans two columns with its words revealed one by one. Attribution with avatar and role. Cost: 0 B JS of its own · uses Tilt + runtime + Reveal. Install: `npx shadcn@latest add @moonarc-pro/testimonial-cards` with a license key (https://moonarc.dev/account/).
- [Testimonial Marquee](https://moonarc.dev/components/testimonial-marquee.md): Shows two rows of testimonial cards drifting in opposite directions, pausing while hovered so any quote can be read. Pure CSS; under reduced motion the rows become scrollable strips. Cost: 0 B JS. Install: `npx shadcn@latest add @moonarc-pro/testimonial-marquee` with a license key (https://moonarc.dev/account/).
- [Thank You](https://moonarc.dev/components/thank-you.md): A thanks page for after a signup: a headline, the reader's place in line rolling up, a referral link with a copy button, and one burst of confetti. The values come from the server or from the record the form lib leaves for this page, never from the URL. Without any values, the page still reads as complete. Cost: 981 B raw JS · 608 B gzip · + CopyButton + runtime + Confetti + canvas. Install: `npx shadcn@latest add @moonarc-pro/thank-you` with a license key (https://moonarc.dev/account/).
- [Waitlist Hero](https://moonarc.dev/components/hero-waitlist.md): A pre-launch hero with a waitlist form: a flip countdown over a retro grid floor, an email field whose text blurs away on submit, a status line that says what happened, and the people already waiting. It is a real form first (method="post" to your action, labelled, validated), so it sends with JavaScript off. One small script binds it with the core form lib for the fetch, the pending lock, the spoken status and the thanks-page record. The email never goes in the URL: any method but post fails the build. Cost: 43 B raw JS · 63 B gzip · + CountdownFlip + runtime + VanishInput + form. Install: `npx shadcn@latest add @moonarc-pro/hero-waitlist` with a license key (https://moonarc.dev/account/).
- [Wave Field](https://moonarc.dev/components/wave-field.md): Draws a water surface in halftone. It runs the wave equation on the GPU (a height field and its previous step), so a drop spreads into rings that cross, interfere and settle, and the edges absorb them. The cursor drops ripples along its path, a wake of rings behind it; while it rests, a light rain falls around the focus. The steepness of the surface sizes a dot per cell, in two tones on the page's ground; `dots` 0 draws a smooth surface. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or a colour-renderable float texture, or without JavaScript, still rings stand in. Fills its positioned parent. Cost: 2.3 kB raw JS · 1.3 kB gzip · + runtime + canvas + gl, 10.8 kB raw in all. Install: `npx shadcn@latest add @moonarc-pro/wave-field` with a license key (https://moonarc.dev/account/).
## Docs
Index: https://moonarc.dev/docs/
### Start here
- [Installation](https://moonarc.dev/docs/installation.md): One command, or a manual install when you want to own every line.
- [The integration](https://moonarc.dev/docs/integration.md): What `moonarc()` does to your project, and how to turn each part off.
- [Runtime](https://moonarc.dev/docs/runtime.md): The lifecycle substrate every scripted component sits on, and the API you can use for your own scripts.
### Style
- [Motion tokens and presets](https://moonarc.dev/docs/motion-tokens.md): Five sampled springs, one attribute to switch the whole page, and the durations, travel and stagger every component resolves from, as CSS custom properties and an opt-in Tailwind v4 layer.
- [Theming](https://moonarc.dev/docs/theming.md): The Pro sections read shadcn's variable names with the base tokens as fallback. Paste a shadcn or tweakcn theme, set one --ma-brand (and optionally a neutral and an accent), or write the tokens yourself. The tone, density, align, columns and media props set the variants, and a painted tone re-declares the card, border, field and focus colours inside the section.
### Checks
- [Performance](https://moonarc.dev/docs/performance.md): How every cost on this site is measured, and how to run the same check on your own build.
- [Accessibility](https://moonarc.dev/docs/accessibility.md): The reduced-motion policy every component follows, and the details screen readers care about.
- [Browser support](https://moonarc.dev/docs/browser-support.md): What each component needs from the browser, which engines have it, and what the others show instead, stated per component.
### Patterns
- [View transitions](https://moonarc.dev/docs/view-transitions.md): How every component survives ClientRouter navigation, and how to keep GSAP and Lenis working too.
- [Forms that send](https://moonarc.dev/docs/forms.md): One function turns a plain posting form into a fetch with a pending state, spoken status, a thanks-page record and the value back after a failure. The form still posts with JavaScript off.
### Moving over
- [Migrating from React Bits and friends](https://moonarc.dev/docs/migrating-from-react-bits.md): Maps each React Bits, Aceternity, Magic UI, shadcn and Framer Motion component to its Moonarc equivalent and the byte delta.
## Guides
- [An AOS alternative for Astro](https://moonarc.dev/resources/guides/aos-alternative-for-astro.md): AOS keeps animated elements invisible until its script runs, shows elements without animating them after a ClientRouter navigation, and has had no release since October 2018. Reveal does the same job without those problems.
- [GSAP ScrollTrigger with Astro View Transitions](https://moonarc.dev/resources/guides/gsap-scrolltrigger-astro-view-transitions.md): Why ScrollTrigger stops working after a ClientRouter navigation, and the adapter that sets it up on every page and cleans up before the next one.
- [Lenis smooth scroll with Astro's ClientRouter](https://moonarc.dev/resources/guides/lenis-smooth-scroll-astro-clientrouter.md): A navigation made while Lenis is still easing scrolls the next page to the old page's target. lenisPage stops the animation and resyncs Lenis after every ClientRouter swap.
## Registry and agents
- shadcn registry index: https://moonarc.dev/r/registry.json (items at /r/.json)
- MCP server: `npx -y @moonarc/mcp`. Free tools: search_motion(intent, max_js_bytes?, tier?, limit?), get_component(name), get_install_command(names, method?) and get_usage(). With a Pro key also: audit_motion(paths, format?), measure_budget(dist, ceiling?, base?, format?) and compose_section(intent). max_js_bytes counts raw bytes. Setup: https://moonarc.dev/mcp/
- Pro registry index: https://moonarc.dev/r/pro/registry.json (public; items at /r/pro/.json need a license key; @moonarc-pro namespace)
## Compare
- [Animation libraries for Astro, measured](https://moonarc.dev/compare.md): The same scroll reveal built with 6 animation libraries in 9 setups on Astro 7.3.2, measured on 2026-09-28 in Chromium, Firefox and WebKit. Without `ClientRouter`, 8 of the 9 setups animate; astro-reveal (default mode) does not, for a reason its card gives. With `ClientRouter`, 2 setups animate on every page: Moonarc (1.2 kB gzip of JavaScript) and Motion for React in a React island (108.2 kB gzip of JavaScript). The other 7 setups lose the reveal on one page or more; each card gives the cause, and the fix where one was measured. Raw results: https://moonarc.dev/compare.json
## Pricing and license
- [Pricing](https://moonarc.dev/pricing/): the plans and what each covers
- [License](https://moonarc.dev/license/): the free MIT primitives and the Pro license
- [Refunds](https://moonarc.dev/refund/)
## About
- [About Moonarc](https://moonarc.dev/about.md): Who builds Moonarc, why it exists, how it is tested and paid for, and what keeps working if it stops.