Web InnoventixFreeCode

Aggregate Rating Spotlight

Original · free

A split layout pairing a large aggregate rating score, star row and overlapping avatar stack with two featured review cards.

byWeb InnoventixReact + Tailwind
ratingaggregateavatar-stacksplit
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/testimonial-rating-spotlight.json
testimonial-rating-spotlight.tsx
const stack = [
  { initials: "AO", tint: "from-indigo-500 to-violet-500" },
  { initials: "DR", tint: "from-emerald-500 to-teal-500" },
  { initials: "PN", tint: "from-rose-500 to-orange-500" },
  { initials: "MB", tint: "from-blue-500 to-cyan-500" },
  { initials: "SL", tint: "from-fuchsia-500 to-pink-500" },
];

const featured = [
  {
    quote:
      "Rolling this out felt suspiciously easy. Six weeks in, adoption is north of ninety percent and nobody has asked to go back.",
    name: "Hannah Whitmore",
    role: "Director of Ops, Brightfold",
    initials: "HW",
    tint: "from-indigo-500 to-blue-500",
    rating: 5,
  },
  {
    quote:
      "The little details add up. Keyboard shortcuts, sensible defaults, an audit trail that actually makes sense when you need it most.",
    name: "Owen Fitzgerald",
    role: "Security Lead, Palisade",
    initials: "OF",
    tint: "from-emerald-500 to-teal-500",
    rating: 5,
  },
];

export default function TestimonialRatingSpotlight() {
  return (
    <section className="bg-white px-6 py-16 dark:bg-zinc-950 md:py-24">
      <div className="mx-auto grid max-w-6xl items-center gap-12 lg:grid-cols-5">
        <div className="lg:col-span-2">
          <div className="flex items-baseline gap-2">
            <span className="text-6xl font-bold tracking-tight text-zinc-900 dark:text-white">
              4.9
            </span>
            <span className="text-2xl font-medium text-zinc-400 dark:text-zinc-500">
              / 5
            </span>
          </div>

          <div
            className="mt-3 flex items-center gap-1"
            aria-label="Average rating 4.9 out of 5 stars"
          >
            {[0, 1, 2, 3, 4].map((i) => (
              <svg
                key={i}
                viewBox="0 0 24 24"
                className="h-6 w-6 fill-amber-400"
                aria-hidden="true"
              >
                <path d="M11.48 3.5a.56.56 0 011.04 0l2.12 5.11a.56.56 0 00.48.35l5.52.44c.5.04.7.66.32.99l-4.2 3.6a.56.56 0 00-.19.56l1.29 5.38a.56.56 0 01-.84.61l-4.73-2.88a.56.56 0 00-.58 0l-4.73 2.88a.56.56 0 01-.84-.61l1.29-5.38a.56.56 0 00-.19-.56l-4.2-3.6a.56.56 0 01.32-.99l5.52-.44a.56.56 0 00.48-.35L11.48 3.5z" />
              </svg>
            ))}
          </div>

          <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-400">
            Averaged across more than 2,300 verified reviews from teams of every size.
          </p>

          <div className="mt-6 flex items-center gap-3">
            <div className="flex -space-x-3">
              {stack.map((person) => (
                <span
                  key={person.initials}
                  className={`grid h-11 w-11 place-items-center rounded-full border-2 border-white bg-gradient-to-br ${person.tint} text-xs font-semibold text-white dark:border-zinc-950`}
                  aria-hidden="true"
                >
                  {person.initials}
                </span>
              ))}
              <span className="grid h-11 w-11 place-items-center rounded-full border-2 border-white bg-zinc-100 text-xs font-semibold text-zinc-600 dark:border-zinc-950 dark:bg-zinc-800 dark:text-zinc-300">
                2k+
              </span>
            </div>
            <span className="text-sm text-zinc-500 dark:text-zinc-400">
              teams already on board
            </span>
          </div>
        </div>

        <div className="grid gap-6 lg:col-span-3 sm:grid-cols-2">
          {featured.map((review) => (
            <figure
              key={review.name}
              className="flex flex-col rounded-2xl border border-zinc-200 bg-zinc-50 p-6 shadow-sm dark:border-zinc-800 dark:bg-zinc-900"
            >
              <div
                className="flex items-center gap-0.5"
                aria-label={`Rated ${review.rating} out of 5 stars`}
              >
                {[0, 1, 2, 3, 4].map((i) => (
                  <svg
                    key={i}
                    viewBox="0 0 24 24"
                    className="h-5 w-5 fill-amber-400"
                    aria-hidden="true"
                  >
                    <path d="M11.48 3.5a.56.56 0 011.04 0l2.12 5.11a.56.56 0 00.48.35l5.52.44c.5.04.7.66.32.99l-4.2 3.6a.56.56 0 00-.19.56l1.29 5.38a.56.56 0 01-.84.61l-4.73-2.88a.56.56 0 00-.58 0l-4.73 2.88a.56.56 0 01-.84-.61l1.29-5.38a.56.56 0 00-.19-.56l-4.2-3.6a.56.56 0 01.32-.99l5.52-.44a.56.56 0 00.48-.35L11.48 3.5z" />
                  </svg>
                ))}
              </div>

              <blockquote className="mt-4 flex-1 text-pretty text-zinc-700 dark:text-zinc-300">
                {review.quote}
              </blockquote>

              <figcaption className="mt-6 flex items-center gap-3 border-t border-zinc-200 pt-4 dark:border-zinc-800">
                <span
                  className={`grid h-10 w-10 shrink-0 place-items-center rounded-full bg-gradient-to-br ${review.tint} text-sm font-semibold text-white`}
                  aria-hidden="true"
                >
                  {review.initials}
                </span>
                <span className="min-w-0">
                  <span className="block truncate text-sm font-semibold text-zinc-900 dark:text-white">
                    {review.name}
                  </span>
                  <span className="block truncate text-sm text-zinc-500 dark:text-zinc-400">
                    {review.role}
                  </span>
                </span>
              </figcaption>
            </figure>
          ))}
        </div>
      </div>
    </section>
  );
}

Dependencies

None — React + Tailwind only.

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 →
Three Card Testimonial Grid

Three Card Testimonial Grid

Original

A clean three-column grid of testimonial cards, each with a star rating, quote and an initial avatar with name and role.

Single Featured Quote

Single Featured Quote

Original

A large centred pull quote with a decorative quotation mark, five-star rating and a prominent author avatar for a single standout testimonial.

Logo Wall Marquee

Logo Wall Marquee

Original

A pair of infinitely scrolling, pause-on-hover marquees pairing a customer logo wall with compact quote cards, with reduced-motion support.

Masonry Testimonial Wall

Masonry Testimonial Wall

Original

A CSS-columns masonry wall of testimonial cards in varied lengths, each with a star rating and initial avatar for a natural, organic layout.

Auto-Rotating Quote Carousel

Auto-Rotating Quote Carousel

Original

An auto-advancing testimonial carousel that slides and crossfades between quotes with a live progress bar, pause-on-hover, and dot plus arrow navigation.

Staggered Reveal Testimonial Grid

Staggered Reveal Testimonial Grid

Original

A testimonial grid whose cards spring in with a staggered scroll reveal and light up with an animated gradient border on hover.

Infinite Marquee Testimonial Wall

Infinite Marquee Testimonial Wall

Original

A three-row marquee wall of review cards scrolling in alternating directions that pause on hover, with a shimmering gradient headline and faded edges.

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.