Velocity Band Marquee
Original · freeA skewed dual-direction headline marquee of big gradient and outlined words plus a pill ticker, with speed and pause controls and pause on hover over an animated mesh background.
Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.
npx shadcn@latest add https://webinnoventix.com/r/marquee-velocity-band.json"use client";
import { useState } from "react";
import { motion } from "motion/react";
const words = ["Design", "Prototype", "Automate", "Ship", "Scale", "Iterate", "Launch"];
const pills = [
"No code required",
"Realtime sync",
"Dark mode ready",
"Fully responsive",
"Open API",
"Team ready",
"Blazing fast",
];
function Sep() {
return (
<svg viewBox="0 0 24 24" className="mx-6 h-6 w-6 shrink-0 fill-indigo-500/70 sm:h-8 sm:w-8" aria-hidden="true">
<path d="M12 2l2.4 7.1L22 9.5l-6 4.6 2.3 7.4L12 17.4 5.7 21.5 8 14.1l-6-4.6 7.6-.4z" />
</svg>
);
}
function WordTrack({ dir, duration }: { dir: "left" | "right"; duration: number }) {
const doubled = [...words, ...words];
return (
<div className="relative overflow-hidden py-2">
<div
className={`vb-track vb-${dir} items-center`}
style={{ animationDuration: `${duration}s` }}
>
{doubled.map((w, i) => {
const filled = i % 2 === 0;
return (
<span key={`w-${i}`} className="flex shrink-0 items-center" aria-hidden={i >= words.length ? true : undefined}>
<span
className={
filled
? "vb-sheen bg-gradient-to-r from-indigo-400 via-fuchsia-400 to-amber-300 bg-clip-text text-4xl font-black tracking-tight text-transparent sm:text-6xl"
: "cursor-default text-4xl font-black tracking-tight text-transparent transition-all duration-300 [-webkit-text-stroke:1.5px_rgb(212,212,216)] hover:text-white hover:[-webkit-text-stroke:0px_transparent] sm:text-6xl dark:[-webkit-text-stroke:1.5px_rgb(82,82,91)]"
}
>
{w}
</span>
<Sep />
</span>
);
})}
</div>
</div>
);
}
function PillTrack({ dir, duration }: { dir: "left" | "right"; duration: number }) {
const doubled = [...pills, ...pills];
return (
<div className="relative overflow-hidden py-2">
<div
className={`vb-track vb-${dir} items-center gap-3`}
style={{ animationDuration: `${duration}s` }}
>
{doubled.map((p, i) => (
<span
key={`p-${i}`}
aria-hidden={i >= pills.length ? true : undefined}
className="flex shrink-0 items-center gap-2 rounded-full border border-white/15 bg-white/5 px-5 py-2.5 text-sm font-medium text-zinc-200 backdrop-blur transition-colors hover:border-indigo-400/50 hover:bg-indigo-500/10 hover:text-white"
>
<svg viewBox="0 0 24 24" className="h-4 w-4 fill-none stroke-indigo-400" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M20 6L9 17l-5-5" />
</svg>
{p}
</span>
))}
</div>
</div>
);
}
export default function MarqueeVelocityBand() {
const [fast, setFast] = useState(false);
const [paused, setPaused] = useState(false);
const k = fast ? 0.5 : 1;
return (
<section className={`relative overflow-hidden bg-zinc-950 px-6 py-20 md:py-28 ${paused ? "vb-paused" : ""}`}>
<style>{`
@keyframes vb-scroll-left { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes vb-scroll-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
@keyframes vb-sweep { 0% { background-position: 0% 50%; } 100% { background-position: 200% 50%; } }
@keyframes vb-mesh { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(5%,4%) scale(1.2); } }
@keyframes vb-mesh-2 { 0%,100% { transform: translate(0,0) scale(1.15); } 50% { transform: translate(-6%,-5%) scale(0.9); } }
.vb-track { display: flex; width: max-content; animation-timing-function: linear; animation-iteration-count: infinite; will-change: transform; }
.vb-left { animation-name: vb-scroll-left; }
.vb-right { animation-name: vb-scroll-right; }
.vb-band:hover .vb-track { animation-play-state: paused; }
.vb-paused .vb-track { animation-play-state: paused; }
.vb-sheen { background-size: 200% auto; animation: vb-sweep 5s linear infinite; }
.vb-mesh { animation: vb-mesh 16s ease-in-out infinite; }
.vb-mesh-2 { animation: vb-mesh-2 20s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
.vb-track, .vb-sheen, .vb-mesh, .vb-mesh-2 { animation: none; }
}
`}</style>
<div aria-hidden="true" className="pointer-events-none absolute inset-0 overflow-hidden">
<div className="vb-mesh absolute -left-20 top-0 h-96 w-96 rounded-full bg-indigo-600/30 blur-[100px]" />
<div className="vb-mesh-2 absolute -right-20 bottom-0 h-96 w-96 rounded-full bg-fuchsia-600/25 blur-[100px]" />
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,transparent_55%,rgb(9,9,11)_100%)]" />
<div
className="absolute inset-0 opacity-[0.04]"
style={{ backgroundImage: "linear-gradient(rgb(255,255,255) 1px,transparent 1px),linear-gradient(90deg,rgb(255,255,255) 1px,transparent 1px)", backgroundSize: "48px 48px" }}
/>
</div>
<div className="relative mx-auto max-w-3xl text-center">
<motion.span
initial={{ opacity: 0, y: 14 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-80px" }}
transition={{ duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/5 px-4 py-1.5 text-xs font-semibold uppercase tracking-widest text-indigo-300 backdrop-blur"
>
Built for momentum
</motion.span>
<motion.h2
initial={{ opacity: 0, y: 18 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-80px" }}
transition={{ duration: 0.55, delay: 0.08, ease: [0.22, 1, 0.36, 1] }}
className="mt-5 text-balance text-3xl font-bold tracking-tight text-white sm:text-4xl"
>
Everything you need to move fast
</motion.h2>
<motion.div
initial={{ opacity: 0, y: 18 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-80px" }}
transition={{ duration: 0.55, delay: 0.16, ease: [0.22, 1, 0.36, 1] }}
className="mt-6 flex items-center justify-center gap-3"
>
<motion.button
type="button"
onClick={() => setFast((v) => !v)}
aria-pressed={fast}
whileTap={{ scale: 0.94 }}
className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/5 px-4 py-2 text-sm font-semibold text-white backdrop-blur transition-colors hover:border-indigo-400/50 hover:bg-indigo-500/15"
>
<svg viewBox="0 0 24 24" className="h-4 w-4 fill-indigo-300" aria-hidden="true">
<path d="M13 2L4.5 13.5H11l-1 8.5 8.5-11.5H12z" />
</svg>
{fast ? "Warp speed" : "Cruise"}
</motion.button>
<motion.button
type="button"
onClick={() => setPaused((v) => !v)}
aria-pressed={paused}
whileTap={{ scale: 0.94 }}
className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/5 px-4 py-2 text-sm font-semibold text-white backdrop-blur transition-colors hover:border-indigo-400/50 hover:bg-indigo-500/15"
>
{paused ? (
<svg viewBox="0 0 24 24" className="h-4 w-4 fill-indigo-300" aria-hidden="true">
<path d="M8 5v14l11-7z" />
</svg>
) : (
<svg viewBox="0 0 24 24" className="h-4 w-4 fill-indigo-300" aria-hidden="true">
<path d="M7 5h4v14H7zM13 5h4v14h-4z" />
</svg>
)}
{paused ? "Play" : "Pause"}
</motion.button>
</motion.div>
</div>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-60px" }}
transition={{ duration: 0.6, delay: 0.2, ease: [0.22, 1, 0.36, 1] }}
className="relative mt-14"
aria-label="Product capabilities marquee"
>
<div className="vb-band -rotate-2">
<div className="relative w-[106%] -translate-x-[3%] [-webkit-mask-image:linear-gradient(to_right,transparent,black_8%,black_92%,transparent)] [mask-image:linear-gradient(to_right,transparent,black_8%,black_92%,transparent)]">
<WordTrack dir="left" duration={26 * k} />
<div className="my-3 h-px w-full bg-gradient-to-r from-transparent via-white/15 to-transparent" />
<PillTrack dir="right" duration={30 * k} />
</div>
</div>
</motion.div>
</section>
);
}Dependencies
Licence
Built by Web Innoventix. Free for personal and commercial use, no attribution required.
Built by Web Innoventix
Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.
Get a free quoteSimilar components
Browse all →
Glowing Logo Marquee
OriginalA dual-row infinite logo marquee whose rows scroll in opposite directions, pause on hover and lift each logo with a shimmer sweep over an animated gradient glow.

Vertical Testimonial Marquee
OriginalThree vertical testimonial columns scroll at different speeds and opposite directions, pausing on hover with a shine sweep so reviews loop endlessly beside a sticky heading.

Spotlight Hero
OriginalA centred hero with a soft radial spotlight, badge and dual call-to-action.

Split Hero
OriginalA two-column hero pairing a headline and CTAs with a product mock and social proof.

Gradient Spotlight Hero
OriginalA minimal centred hero with a soft gradient-mesh backdrop, announcement pill and dual call-to-action buttons.

App Preview Hero
OriginalA centred hero that pairs headline copy with a realistic product dashboard mock built entirely from markup, complete with browser chrome and a floating notification card.

Waitlist Capture Hero
OriginalA dark, focused hero with an inline email capture form and avatar social proof, ready for pre-launch waitlists.

Image Backdrop Hero
OriginalA cinematic full-bleed hero with a layered image-style backdrop, overlaid left-aligned copy and a trusted-by logos strip.

Gradient Mesh Hero with Staggered Text Reveal
OriginalA full-screen hero pairing a drifting animated gradient-mesh backdrop with a word-by-word staggered blur-in headline and a logo marquee under the fold.

Typewriter Rotating Words Hero
OriginalA hero whose headline cycles through rotating words with a live typewriter caret over an animated grid backdrop, degrading to a gentle word swap when reduced motion is on.

Floating UI Cards Hero with Mouse Parallax
OriginalA hero with glassy floating UI cards that drift continuously and shift on mouse-parallax depth around a staggered centre headline.

Aurora Hero with Shimmer CTA and Logo Marquee
OriginalA dark hero with animated aurora light beams, a shimmering sweep across the primary CTA, and dual-direction logo marquees beneath the fold.

