Typewriter Rotating Words Hero
Original · freeA 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.
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/ahero-rotating-words-typewriter.json"use client";
import { useEffect, useState } from "react";
import { motion, useReducedMotion, type Variants } from "motion/react";
const WORDS = ["designers", "founders", "engineers", "marketers", "makers"];
export default function AheroRotatingWordsTypewriter() {
const reduce = useReducedMotion();
const [index, setIndex] = useState(0);
const [text, setText] = useState("");
const [deleting, setDeleting] = useState(false);
// Typewriter path (motion allowed).
useEffect(() => {
if (reduce) return;
const current = WORDS[index % WORDS.length];
let timeout: ReturnType<typeof setTimeout>;
if (!deleting && text === current) {
timeout = setTimeout(() => setDeleting(true), 1500);
} else if (deleting && text === "") {
setDeleting(false);
setIndex((i) => (i + 1) % WORDS.length);
} else {
timeout = setTimeout(
() => setText((t) => (deleting ? current.slice(0, t.length - 1) : current.slice(0, t.length + 1))),
deleting ? 45 : 95,
);
}
return () => clearTimeout(timeout);
}, [text, deleting, index, reduce]);
// Reduced-motion path: simple word swap on a slow interval.
useEffect(() => {
if (!reduce) return;
setText(WORDS[index % WORDS.length]);
const id = setInterval(() => setIndex((i) => (i + 1) % WORDS.length), 2600);
return () => clearInterval(id);
}, [reduce, index]);
const container: Variants = {
hidden: {},
show: { transition: { staggerChildren: 0.12, delayChildren: 0.1 } },
};
const item: Variants = reduce
? { hidden: { opacity: 0 }, show: { opacity: 1, transition: { duration: 0.5 } } }
: { hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0, transition: { duration: 0.6, ease: "easeOut" } } };
return (
<section className="relative isolate flex min-h-screen items-center overflow-hidden bg-white px-6 py-24 dark:bg-zinc-950">
<style>{`
@keyframes ahrw-grid { from { background-position: 0 0; } to { background-position: 48px 48px; } }
@keyframes ahrw-blink { 0%, 45% { opacity: 1; } 50%, 95% { opacity: 0; } 100% { opacity: 1; } }
@keyframes ahrw-glow { 0%, 100% { opacity: 0.5; transform: translate(-50%, 0) scale(1); } 50% { opacity: 0.85; transform: translate(-50%, 0) scale(1.12); } }
.ahrw-grid { animation: ahrw-grid 6s linear infinite; }
.ahrw-caret { animation: ahrw-blink 1.1s step-end infinite; }
.ahrw-glow { animation: ahrw-glow 8s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
.ahrw-grid, .ahrw-caret, .ahrw-glow { animation: none; }
.ahrw-caret { opacity: 1; }
}
`}</style>
<div aria-hidden="true" className="pointer-events-none absolute inset-0 -z-10">
<div className="ahrw-grid absolute inset-0 bg-[linear-gradient(to_right,rgba(24,24,27,0.06)_1px,transparent_1px),linear-gradient(to_bottom,rgba(24,24,27,0.06)_1px,transparent_1px)] bg-[size:48px_48px] [mask-image:radial-gradient(ellipse_at_center,black_20%,transparent_75%)] dark:bg-[linear-gradient(to_right,rgba(255,255,255,0.06)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,0.06)_1px,transparent_1px)]" />
<div className="ahrw-glow absolute left-1/2 top-[18%] h-72 w-[42rem] max-w-[90vw] rounded-full bg-gradient-to-r from-violet-400 via-indigo-400 to-sky-400 opacity-50 blur-[110px] dark:from-violet-600 dark:via-indigo-600 dark:to-sky-600" />
</div>
<motion.div
variants={container}
initial="hidden"
animate="show"
className="mx-auto w-full max-w-4xl text-center"
>
<motion.span
variants={item}
className="inline-flex items-center gap-2 rounded-full border border-zinc-200 bg-zinc-50 px-4 py-1.5 text-sm font-medium text-zinc-600 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-300"
>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className="h-4 w-4 text-indigo-500">
<path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1" />
</svg>
The workspace that adapts to you
</motion.span>
<motion.h1
variants={item}
className="mt-8 text-4xl font-bold tracking-tight text-zinc-900 dark:text-white sm:text-6xl"
>
A better toolkit
<span className="mt-2 block">
<span className="text-zinc-400 dark:text-zinc-500">for </span>
<span className="bg-gradient-to-r from-violet-600 via-indigo-600 to-sky-500 bg-clip-text text-transparent dark:from-violet-400 dark:via-indigo-400 dark:to-sky-400">
{text || " "}
</span>
<span
aria-hidden="true"
className="ahrw-caret ml-0.5 inline-block h-[0.9em] w-[3px] translate-y-[0.1em] rounded-full bg-indigo-500 align-middle dark:bg-indigo-400"
/>
</span>
</motion.h1>
<motion.p
variants={item}
className="mx-auto mt-6 max-w-xl text-lg leading-relaxed text-zinc-600 dark:text-zinc-400"
>
One flexible surface that moulds to how your team actually works. Draft, plan and launch without wrestling ten disconnected tools.
</motion.p>
<motion.div variants={item} className="mt-10 flex flex-col items-center justify-center gap-3 sm:flex-row">
<motion.a
href="#"
whileHover={reduce ? undefined : { scale: 1.03 }}
whileTap={reduce ? undefined : { scale: 0.97 }}
className="inline-flex w-full items-center justify-center gap-2 rounded-xl bg-indigo-600 px-6 py-3 text-sm font-semibold text-white shadow-lg shadow-indigo-600/25 transition-colors hover:bg-indigo-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-zinc-950 sm:w-auto"
>
Get started
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className="h-4 w-4">
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
</motion.a>
<motion.a
href="#"
whileHover={reduce ? undefined : { scale: 1.03 }}
whileTap={reduce ? undefined : { scale: 0.97 }}
className="inline-flex w-full items-center justify-center gap-2 rounded-xl border border-zinc-200 bg-white px-6 py-3 text-sm font-semibold text-zinc-700 transition-colors hover:bg-zinc-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-200 dark:hover:bg-zinc-800 dark:focus-visible:ring-offset-zinc-950 sm:w-auto"
>
Book a demo
</motion.a>
</motion.div>
<motion.p variants={item} className="mt-6 text-sm text-zinc-500 dark:text-zinc-500">
Free for 14 days. No card required.
</motion.p>
</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 →
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.

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.

Gradient Conversion Hero
MITCentered, full-screen marketing hero with a colour-accent headline word, supporting copy, and dual primary/secondary CTA buttons. Dark-mode ready and dependency-free.

Split Showcase Hero
MITTwo-column hero on a dark background — headline, paragraph, and two buttons beside a gradient media panel. Responsive column stack on mobile.

Aurora Gradient Hero
MITAnimated hero with a shimmering animated-gradient badge and an aurora gradient-text headline over an ambient radial glow. Self-contained CSS animations, dependency-free, respects prefers-reduced-motion.

