2026-08-09 · 4 min read · prompt-library
The exact prompt that reproduces this interactive 3D hero
A prompt-library entry: one looping reference of an interactive Spline 3D hero, plus the full integration prompt that rebuilds it in any shadcn + Tailwind + TypeScript project. Hand the prompt to any agent harness and you get the same hero.
A landing page has roughly three seconds to earn a second look. Static screenshots earn fewer than they used to. The hero below is the kind of interactive 3D moment that makes a visitor move their cursor: a Spline scene sitting inside a dark card, with a cursor-tracking spotlight sweeping over it. That small piece of motion is what turns a scroll-past into a pause. I want every project I ship to be able to reach for this without starting from zero.
So instead of writing another "here's what I built" post, this is a prompt-library entry. You get the looping reference of the hero exactly as it runs, and then the full, copy-pasteable integration prompt that reproduces it in any project that already runs shadcn, Tailwind CSS, and TypeScript. The point is reproducibility: hand this prompt to any agent harness, or paste it into your own editor, and you should get the same hero asset out the other side.
The reference
This is the hero being reproduced. It is a video capture (not a live Spline scene), so it plays back identically on any device without loading a 3D runtime. Watch the cursor-tracking light and the embedded 3D object on the right.
Reference capture of the interactive 3D hero this prompt reproduces. Looping and muted; the same asset any agent harness given the prompt below will build.
Prompt
The block below is the authoritative copy. It is fenced as one unit so you can copy the entire prompt in a single select-all. The inner code fences are part of the prompt; keep them. It assumes the target project already has shadcn structure, Tailwind CSS, and TypeScript; if it doesn't, the prompt's opening lines tell the agent how to set that up first.
You are given a task to integrate an existing React component in the codebase
The codebase should support:
- shadcn project structure
- Tailwind CSS
- Typescript
If it doesn't, provide instructions on how to setup project via shadcn CLI, install Tailwind or Typescript.
Determine the default path for components and styles.
If default path for components is not /components/ui, provide instructions on why it's important to create this folder
Copy-paste this component to /components/ui folder:
```tsx
splite.tsx
'use client'
import { Suspense, lazy } from 'react'
const Spline = lazy(() => import('@splinetool/react-spline'))
interface SplineSceneProps {
scene: string
className?: string
}
export function SplineScene({ scene, className }: SplineSceneProps) {
return (
<Suspense
fallback={
<div className="w-full h-full flex items-center justify-center">
<span className="loader"></span>
</div>
}
>
<Spline
scene={scene}
className={className}
/>
</Suspense>
)
}
demo.tsx
'use client'
import { SplineScene } from "@/components/ui/splite";
import { Card } from "@/components/ui/card"
import { Spotlight } from "@/components/ui/spotlight"
export function SplineSceneBasic() {
return (
<Card className="w-full h-[500px] bg-black/[0.96] relative overflow-hidden">
<Spotlight
className="-top-40 left-0 md:left-60 md:-top-20"
fill="white"
/>
<div className="flex h-full">
{/* Left content */}
<div className="flex-1 p-8 relative z-10 flex flex-col justify-center">
<h1 className="text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-b from-neutral-50 to-neutral-400">
Interactive 3D
</h1>
<p className="mt-4 text-neutral-300 max-w-lg">
Bring your UI to life with beautiful 3D scenes. Create immersive experiences
that capture attention and enhance your design.
</p>
</div>
{/* Right content */}
<div className="flex-1 relative">
<SplineScene
scene="https://prod.spline.design/kZDDjO5HuC9GJUM2/scene.splinecode"
className="w-full h-full"
/>
</div>
</div>
</Card>
)
}
```
Copy-paste these files for dependencies:
```tsx
ibelick/spotlight
'use client';
import React, { useRef, useState, useCallback, useEffect } from 'react';
import { motion, useSpring, useTransform, SpringOptions } from 'framer-motion';
import { cn } from '@/lib/utils';
type SpotlightProps = {
className?: string;
size?: number;
springOptions?: SpringOptions;
};
export function Spotlight({
className,
size = 200,
springOptions = { bounce: 0 },
}: SpotlightProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [isHovered, setIsHovered] = useState(false);
const [parentElement, setParentElement] = useState<HTMLElement | null>(null);
const mouseX = useSpring(0, springOptions);
const mouseY = useSpring(0, springOptions);
const spotlightLeft = useTransform(mouseX, (x) => `${x - size / 2}px`);
const spotlightTop = useTransform(mouseY, (y) => `${y - size / 2}px`);
useEffect(() => {
if (containerRef.current) {
const parent = containerRef.current.parentElement;
if (parent) {
parent.style.position = 'relative';
parent.style.overflow = 'hidden';
setParentElement(parent);
}
}
}, []);
const handleMouseMove = useCallback(
(event: MouseEvent) => {
if (!parentElement) return;
const { left, top } = parentElement.getBoundingClientRect();
mouseX.set(event.clientX - left);
mouseY.set(event.clientY - top);
},
[mouseX, mouseY, parentElement]
);
useEffect(() => {
if (!parentElement) return;
parentElement.addEventListener('mousemove', handleMouseMove);
parentElement.addEventListener('mouseenter', () => setIsHovered(true));
parentElement.addEventListener('mouseleave', () => setIsHovered(false));
return () => {
parentElement.removeEventListener('mousemove', handleMouseMove);
parentElement.removeEventListener('mouseenter', () => setIsHovered(true));
parentElement.removeEventListener('mouseleave', () =>
setIsHovered(false)
);
};
}, [parentElement, handleMouseMove]);
return (
<motion.div
ref={containerRef}
className={cn(
'pointer-events-none absolute rounded-full bg-[radial-gradient(circle_at_center,var(--tw-gradient-stops),transparent_80%)] blur-xl transition-opacity duration-200',
'from-zinc-50 via-zinc-100 to-zinc-200',
isHovered ? 'opacity-100' : 'opacity-0',
className
)}
style={{
width: size,
height: size,
left: spotlightLeft,
top: spotlightTop,
}}
/>
);
}
```
```tsx
shadcn/card
import * as React from "react"
import { cn } from "@lib/utils"
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className,
)}
{...props}
/>
))
Card.displayName = "Card"
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className,
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
```
Install NPM dependencies:
```bash
@splinetool/runtime, @splinetool/react-spline, framer-motion
```
Sources
- Reference hero capture (MP4) · first-hand · accessed 2026-08-09Looping video capture of the interactive Spline 3D hero this article documents and reproduces. Treated as the authoritative reference; the article does not hotlink it as a live Spline scene.
- Spline — React integration · documentation · accessed 2026-08-09Spline is the 3D tool whose runtime (@splinetool/react-spline, @splinetool/runtime) the documented prompt installs to render the hero scene.
- shadcn/ui — components and CLI · documentation · accessed 2026-08-09The integration prompt assumes a shadcn project structure with a /components/ui folder; shadcn is the source of the Card component referenced in the prompt.
Want this working inside your team?
It starts with one conversation about your workflow.