No.490 · Sections· New
Murmur Rows
Testimonials as two quiet rows of quotes drifting in opposite directions, with edges that blur out like a shallow depth of field. Point at a row and it stops, with that quote brought forward; a pause button stops everything.
The prompt
Written for the variant you picked above: Illustrated
Build a testimonial section where quotes drift sideways in rows. Props: quotes [{id, text, name, role, avatar, tint}], rows (1–3, default 2), speed (px/s; default 24, 18 in narrow containers; 0 holds still), look and label. Deal the quotes into rows round-robin. Each row is a measured loop: render one sequence of quotes with a trailing gap, measure its width, repeat it enough times to cover the row plus a spare, and move the track by translate3d at a constant pixel speed, wrapping by the exact measured period, so the seam never shows. Rows alternate direction — the first moves left, the next right — and start out of step. Re-measure on resize and font load, keeping each row's progress proportional. Clamp long frames so a backgrounded tab doesn't jump, and stop the animation frame entirely when the section is offscreen or the page is hidden. A quote is a fixed 440px column: the text at 1.32rem, weight 500, line height 1.42, clamped to six lines; then, 44px below, a 54px round portrait beside the name and role (1.12rem, the role muted). Quotes sit 120px apart and rows 76px apart on a black ground, with text at about 92% white. Both edges carry a progressive blur 15% of the width wide: three stacked layers with backdrop blur at 1, 3 and 6px, each masked by a gradient that starts further from the edge than the last, so letters soften gradually as they leave, then a final gradient into the ground colour. Pointing at a row stops that row only and dims its other quotes to 45%, leaving the one under the pointer at full strength. A small pill button in the bottom-right corner ('Pause testimonials' / 'Play testimonials', with an icon and aria-pressed) stops and restarts all rows. Assistive tech reads one plain list of the quotes as figure, blockquote and figcaption; the moving rows are hidden from it. With reduced motion, or fewer than three quotes, there are no rows: the quotes wrap in a static grid with no blur. Below 640px quotes narrow to 300px, text drops to 1.08rem and portraits to 44px. Selected variant — Illustrated (illustrated): Give every quote a portrait: a small monoline bust (a white figure with ink hair and features on a near-black disc with a fine ring), each person with their own hair and collar. Black ground, white text. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Point at a row to stop it and bring one quote forward; move away and it carries on. The pause button stops and restarts every row. Motion: Rows move at 24px/s (18px/s on small screens) in opposite directions, with no easing or jumps; dimming takes 240ms. Animation stops offscreen and in hidden tabs. Reduced motion shows a static grid. Accessibility: A labelled region with a single list of quotes for assistive tech, while the moving copies are hidden. The pause button is a real toggle with a label that says what it will do, so the motion can always be stopped (WCAG 2.2.2). Reduced motion removes the movement entirely. Responsive behavior: Rows always fill the width and repeat to cover it. Below 640px quotes and type step down; the blur edges scale with the width. Touch: Touch doesn't hover, so rows keep moving; the pause button stops them. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.
Notes
- Interaction
- Point at a row to stop it and bring one quote forward; move away and it carries on. The pause button stops and restarts every row.
- Motion
- Rows move at 24px/s (18px/s on small screens) in opposite directions, with no easing or jumps; dimming takes 240ms. Animation stops offscreen and in hidden tabs. Reduced motion shows a static grid.
- Accessibility
- A labelled region with a single list of quotes for assistive tech, while the moving copies are hidden. The pause button is a real toggle with a label that says what it will do, so the motion can always be stopped (WCAG 2.2.2). Reduced motion removes the movement entirely.
- Responsive
- Rows always fill the width and repeat to cover it. Below 640px quotes and type step down; the blur edges scale with the width.
- On touch
- Touch doesn't hover, so rows keep moving; the pause button stops them.