Web InnoventixFreeCode

Typewriter Rotating Words Hero

Original · free

A 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.

byWeb InnoventixReact + Tailwind
typewriter herorotating words animationanimated heroframer motion typewriterhero text animationhero section
Open

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
ahero-rotating-words-typewriter.tsx
"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

motion

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 quote

Similar components

Browse all →
Spotlight Hero

Spotlight Hero

Original

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

Split Hero

Split Hero

Original

A two-column hero pairing a headline and CTAs with a product mock and social proof.

Gradient Spotlight Hero

Gradient Spotlight Hero

Original

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

App Preview Hero

App Preview Hero

Original

A 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

Waitlist Capture Hero

Original

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

Image Backdrop Hero

Image Backdrop Hero

Original

A 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

Gradient Mesh Hero with Staggered Text Reveal

Original

A 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

Floating UI Cards Hero with Mouse Parallax

Original

A 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

Aurora Hero with Shimmer CTA and Logo Marquee

Original

A 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

Gradient Conversion Hero

MIT

Centered, 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

Split Showcase Hero

MIT

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

Aurora Gradient Hero

Aurora Gradient Hero

MIT

Animated 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.