Marquee
TickerInfinite scrolling strip for logos, quotes or tags in any direction.
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.
Zero islands, same motion.
The byte counter is the pitch.
Survived our ClientRouter migration.
Copied the source, owe nothing.
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
JavaScript of its own
0 B
CSS 8.5 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.
Browser support
Chrome 120 · Firefox 53 · Safari 15.4; needs mask-image.
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:
npx shadcn@latest add @moonarc-pro/testimonial-marquee---
import TestimonialMarquee from '@/components/moonarc/pro/TestimonialMarquee.astro';
---
<TestimonialMarquee duration={60} quotes={[
{ quote: 'Zero islands, same motion.', name: 'A. Developer', role: 'Astro' },
{ quote: 'I can see what every component costs.', name: 'B. Builder' },
]} />Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: marquee.
| Prop | Type | Default | Description |
|---|---|---|---|
quotes | { quote, name, role? }[] | none | Split evenly across the rows. |
duration | number | 60 | Seconds per loop; the second row runs 8 s slower. |
rows | 1 | 2 | 2 | One row, or two moving against each other. |
tone | 'surface' | 'muted' | 'ink' | 'brand' | unset (paints nothing) | The ground: the page surface, a muted band, an always-dark ink panel, or a deep brand panel. Each paints --background, --ma-tone-muted (over --muted, with a --border hairline), --ma-tone-ink or --ma-tone-brand (over --primary) with the matching text. With theme.css, a painted tone also re-declares --card, --border, --input and --ring inside the section, so cards and fields follow the ground. Decoration is strongest on brand. |
density | 'compact' | 'cozy' | 'roomy' | 'cozy' | Card padding and the row gap ×0.8 / ×1 / ×1.25 through --ma-density. |
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.
.ma-testimonial-marquee.ma-testimonial-marquee__card.ma-testimonial-marquee__copy.ma-testimonial-marquee__eyebrow.ma-testimonial-marquee__head.ma-testimonial-marquee__headline
slot="eyebrow"slot="headline"slot="copy"
Rows stop and become scrollable strips.
ClientRouterCSS-only; nothing to rebind.
Replaces: Marquee testimonials (Magic UI) · InfiniteMovingCards (Aceternity). See the migration table.
Infinite scrolling strip for logos, quotes or tags in any direction.
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.
Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown