Animated Text Rotate Hero — shadcn/ui Rotating Headline Component (React + Tailwind + TypeScript + Framer Motion)
A centered marketing hero section that integrates the shadcn/ui animated hero — a headline that swaps a rotating word every two seconds using a framer-motion spring (amazing → new → wonderful → beautiful → smart). The component is embedded inside a branded "Spektr" trade-desk shell (midnight-teal identity, self-hosted fonts, live ticker tape) so you can see it in realistic landing-page context. Fully accessible: ambient motion freezes under prefers-reduced-motion, focus rings are visible, and zero remote assets are fetched at runtime. Generated with Claude Fable 5.
Yes — this folder is a complete shadcn-style project, so the component runs as-is. The pieces that make it a valid shadcn project:
| Requirement | Where it lives |
|---|---|
| shadcn project structure | components.json, src/components/ui/, src/lib/utils.ts |
| Tailwind CSS | tailwind.config.ts, postcss.config.js, src/index.css (tokens) |
| TypeScript | tsconfig.json (with the @/* path alias) |
@ import alias |
vite.config.ts and tsconfig.json (both required) |
# 1. Scaffold a Vite + React + TypeScript app
npm create vite@latest my-app -- --template react-ts
cd my-app
# 2. Add Tailwind (v3) + PostCSS
npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p
# 3. Add the "@" path alias so shadcn imports resolve.
# tsconfig.json -> compilerOptions.baseUrl "." and paths { "@/*": ["./src/*"] }
# vite.config.ts -> resolve.alias { "@": path.resolve(__dirname, "./src") }
# 4. Initialise shadcn/ui and add the only registry dependency this hero needs
npx shadcn@latest init
npx shadcn@latest add buttoncomponents.json pins the defaults the shadcn CLI uses:
So components default to src/components/ui and styles live in
src/index.css. This project already uses /components/ui, but it is worth
keeping even when it is not the framework default, because:
- The CLI writes there.
npx shadcn add <x>drops primitives into theuialias. If the folder is missing or renamed, generated files and the imports inside them (@/components/ui/button) stop lining up. - The copied code imports from it.
animated-hero.tsxanddemo.tsxboth doimport { Button } from "@/components/ui/button". The path has to exist verbatim or the build fails to resolve. - It separates vendor primitives from your app.
ui/holds the shadcn-owned, regenerable building blocks; everything you author by hand (here:Navbar,TradeTicker,Footer, …) sits one level up incomponents/. That boundary keeps re-runs of the CLI from clobbering your own work.
What data / props does the hero take? None — Hero takes no props. The
rotating words live in a local useMemo array and the copy is hard-coded. To
customise, edit the titles array or the headline/paragraph text directly in
src/components/ui/animated-hero.tsx.
State management? Local only. One useState (titleNumber) drives the
index; a useEffect + setTimeout advances it every 2000 ms and is cleaned up
on unmount. No context, store, or provider is required.
Required context providers / hooks? None for the hero. The surrounding demo
adds a tiny client-side theme toggle (ThemeToggle) that flips the .dark
class — that is app chrome, not a dependency of the component.
Required assets (images / icons)? No images. The hero is typography + two
lucide-react icons (MoveRight, PhoneCall). Because nothing in this
component calls for a photograph, no Unsplash stock images are used — adding
any would be decoration the brief does not need. The demo's wordmark and
customer "logos" are likewise built from lucide-react icons, so the project
ships with zero remote assets and runs fully offline.
Responsive behaviour. Mobile-first. The headline scales text-5xl → md:text-7xl, content is centered and width-capped at max-w-2xl, and the CTA
row stays horizontal. The shell's nav links collapse below md while the CTAs
remain. Verified at 1440px and 390px (see screenshots/).
Best place to use it. The above-the-fold section of a landing / marketing
page — exactly how src/App.tsx mounts it: sticky nav + ticker, then <Hero />
over an ambient background, then social proof.
A midnight-teal trade terminal identity (the product streamlines SMB trade), so the chrome speaks that world rather than reaching for a generic dark hero:
- Palette — ink
#05080acanvas, brand cyan#22d3eeaccent (wired to the component's owntext-spektr-cyan-50token), cool foreground. Light and dark are both first-class via shadcn CSS variables. - Type —
Space Groteskdisplay,Interbody,JetBrains Monofor the ticker and eyebrow labels. All three are self-hosted woff2 inpublic/fonts/— no Google Fonts request at runtime. - Signature — a live "trade desk" ticker tape (
TradeTicker) of SMB metrics that encodes the subject instead of decorating it, plus a slow cyan aurora and an engineered dot-grid behind the hero. - Quality floor — visible keyboard focus rings (shadcn
ring), and all ambient + rotation motion is frozen underprefers-reduced-motion.
npm install
npm run dev # http://localhost:5173
npm run build # tsc --noEmit + vite build
npm run preview # serve the production buildnpm run preview & # serve on a port, e.g. 5188
CHROME_BIN=/path/to/chrome VERIFY_URL=http://localhost:5188/ node scripts/verify.mjsscripts/verify.mjs asserts the headline + all five rotating words render, the
word actually advances over time, every CTA is present, the local display font
is applied, the theme toggle flips both ways, and there are no external
requests and no console errors.
| Path | Purpose |
|---|---|
src/components/ui/animated-hero.tsx |
The integrated component (verbatim) |
src/components/ui/demo.tsx |
The provided demo wrapper (verbatim) |
src/components/ui/button.tsx |
shadcn Button dependency (verbatim) |
src/lib/utils.ts |
cn() class-merge helper |
src/App.tsx |
Branded demo host for the hero |
src/components/* |
Shell: navbar, ticker, background, trust strip, footer |
tailwind.config.ts · src/index.css |
shadcn token theme (light + dark) |
components.json |
shadcn CLI config |
Part of the Hero sections collection in the claude-directory — an open-source gallery of AI-generated UI built with Claude Fable 5. Browse the live gallery.

