Innovations

Quote Spotlight

Single large featured quote with decorative quotation mark, avatar, and prev/next cycling. Minimal editorial design.

Preview

Source

tsx
"use client";

import { useState } from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { testimonials } from "@/lib/placeholders";

export default function QuoteSpotlight() {
  const [active, setActive] = useState(0);

  const prev = () => setActive((a) => (a - 1 + testimonials.length) % testimonials.length);
  const next = () => setActive((a) => (a + 1) % testimonials.length);

  const t = testimonials[active];

  return (
    <section className="py-20 px-4 sm:px-6 bg-background">
      <div className="max-w-4xl mx-auto">
        <div className="relative flex flex-col items-center text-center">
          {/* Decorative giant quote mark */}
          <div
            className="absolute -top-4 left-1/2 -translate-x-1/2 text-[10rem] sm:text-[14rem] font-serif leading-none select-none pointer-events-none text-primary/8"
            aria-hidden="true"
          >
            &ldquo;
          </div>

          {/* Eyebrow */}
          <span className="relative z-10 inline-block text-xs font-semibold uppercase tracking-widest text-primary bg-primary/10 border border-primary/20 rounded-full px-4 py-1.5 mb-8">
            Featured Review
          </span>

          {/* Quote text */}
          <blockquote className="relative z-10 text-2xl sm:text-3xl lg:text-4xl font-semibold text-foreground leading-snug max-w-3xl mb-10">
            {t.text}
          </blockquote>

          {/* Attribution */}
          <div className="relative z-10 flex flex-col items-center gap-4">
            <img
              src={t.avatar}
              alt={t.name}
              className="w-16 h-16 rounded-full object-cover ring-4 ring-primary/20 shadow-lg"
            />
            <div>
              <p className="text-lg font-bold text-foreground">{t.name}</p>
              <p className="text-sm text-muted-foreground">{t.role}</p>
            </div>
          </div>

          {/* Navigation */}
          <div className="relative z-10 flex items-center gap-6 mt-10">
            <button
              onClick={prev}
              className="w-10 h-10 rounded-full border border-border bg-background hover:bg-muted transition-colors flex items-center justify-center text-muted-foreground hover:text-foreground"
              aria-label="Previous quote"
            >
              <ChevronLeft className="w-5 h-5" />
            </button>

            {/* Indicators */}
            <div className="flex gap-2">
              {testimonials.map((_, i) => (
                <button
                  key={i}
                  onClick={() => setActive(i)}
                  className={`rounded-full transition-all duration-300 ${
                    i === active
                      ? "w-6 h-2 bg-primary"
                      : "w-2 h-2 bg-border hover:bg-muted-foreground"
                  }`}
                  aria-label={`Quote ${i + 1}`}
                />
              ))}
            </div>

            <button
              onClick={next}
              className="w-10 h-10 rounded-full border border-border bg-background hover:bg-muted transition-colors flex items-center justify-center text-muted-foreground hover:text-foreground"
              aria-label="Next quote"
            >
              <ChevronRight className="w-5 h-5" />
            </button>
          </div>
        </div>
      </div>
    </section>
  );
}
Claude Code Instructions

CLI Install

npx innovations add quote-spotlight

Where to use it

Great for homepage hero areas, about pages, or anywhere you want one powerful testimonial to anchor a section. In Astro: import QuoteSpotlight from '../components/innovations/testimonials/quote-spotlight'; <QuoteSpotlight client:load /> In Next.js: import QuoteSpotlight from '@/components/innovations/testimonials/quote-spotlight'; // Place in the hero area, on the about page, or as a break between content sections Users can cycle through all testimonials via the prev/next arrows. Edit testimonials in src/lib/placeholders.ts.