---
id: seed:archetypes/testimonials
title: Testimonials & social proof sections
source_type: seed_archetype
priority: hot
---

Testimonials work when they sound like a real person and name a specific outcome. Generic five-star praise is noise. Six working archetypes:

---

**Quote grid (default).** Three cards across, each with a quote, attribution, and a 96x96 avatar. Quote should be a single sentence under 25 words.

*Animation & Visual Details:*
- *Entrance*: Cards stagger in from translateY(30px) with fade, 0.1s delay between each
- *Hover*: Card lifts (translateY(-4px)), shadow deepens, radial quote mark fades in behind the text
- *Gradients*: Card has subtle gradient border on hover (left accent color)
- *Radial circles*: Large decorative radial quote mark (") behind each card at 4% opacity, visible on hover
- *Scroll trigger*: IntersectionObserver at 15% threshold
- *JS interaction*: None for base — pure CSS hover + IntersectionObserver entrance

```html
<section data-amb-section="testimonials" class="testimonials-section">
  <div class="container">
    <div class="testimonials-header">
      <h2 class="testimonials-title">{outcome-led: "Teams ship 3x faster"}</h2>
    </div>
    <div class="testimonials-grid">
      <figure class="testimonial-card">
        <div class="testimonial-quote-mark">"</div>
        <blockquote class="testimonial-quote">"{Specific result they got, in their voice}"</blockquote>
        <figcaption class="testimonial-attribution">
          <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="{name}" />
          <div class="testimonial-meta">
            <span class="testimonial-name">{Full name}</span>
            <span class="testimonial-role">{Title}, {Company}</span>
          </div>
        </figcaption>
      </figure>
      <figure class="testimonial-card">
        <div class="testimonial-quote-mark">"</div>
        <blockquote class="testimonial-quote">"{Specific result they got, in their voice}"</blockquote>
        <figcaption class="testimonial-attribution">
          <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="{name}" />
          <div class="testimonial-meta">
            <span class="testimonial-name">{Full name}</span>
            <span class="testimonial-role">{Title}, {Company}</span>
          </div>
        </figcaption>
      </figure>
      <figure class="testimonial-card">
        <div class="testimonial-quote-mark">"</div>
        <blockquote class="testimonial-quote">"{Specific result they got, in their voice}"</blockquote>
        <figcaption class="testimonial-attribution">
          <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="{name}" />
          <div class="testimonial-meta">
            <span class="testimonial-name">{Full name}</span>
            <span class="testimonial-role">{Title}, {Company}</span>
          </div>
        </figcaption>
      </figure>
    </div>
  </div>
</section>
```

```css
:root {
  --testimonial-enter-duration: 0.5s;
  --testimonial-stagger: 0.1s;
}

.testimonials-section {
  padding: clamp(64px, 8vw, 100px) 0;
}

.testimonials-header {
  text-align: center;
  max-width: 560px;
  margin: 0 auto clamp(40px, 5vw, 60px);
}

.testimonials-title {
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  font-weight: 700;
  color: var(--color-text, #1e293b);
}

.testimonials-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

.testimonial-card {
  position: relative;
  background: #fff;
  border-radius: 16px;
  border: 1px solid #f1f5f9;
  padding: 28px;
  margin: 0;
  opacity: 0;
  transform: translateY(24px);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.testimonial-card.is-visible {
  animation: testimonial-enter var(--testimonial-enter-duration) ease-out forwards;
}

.testimonial-card:nth-child(1).is-visible { animation-delay: 0s; }
.testimonial-card:nth-child(2).is-visible { animation-delay: var(--testimonial-stagger); }
.testimonial-card:nth-child(3).is-visible { animation-delay: calc(var(--testimonial-stagger) * 2); }

@keyframes testimonial-enter {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.testimonial-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 32px rgba(0,0,0,0.08);
}

.testimonial-quote-mark {
  position: absolute;
  top: 16px;
  right: 24px;
  font-size: 5rem;
  font-family: Georgia, serif;
  color: var(--color-accent, #6366f1);
  opacity: 0;
  transition: opacity 0.3s ease;
  line-height: 1;
  pointer-events: none;
}

.testimonial-card:hover .testimonial-quote-mark {
  opacity: 0.1;
}

.testimonial-quote {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--color-text, #1e293b);
  margin: 0 0 20px;
}

.testimonial-attribution {
  display: flex;
  align-items: center;
  gap: 12px;
}

.testimonial-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.testimonial-name {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-text, #1e293b);
}

.testimonial-role {
  display: block;
  font-size: 0.8rem;
  color: var(--color-text-muted, #64748b);
}

@media (prefers-reduced-motion: reduce) {
  .testimonial-card {
    opacity: 1;
    transform: none;
  }
}
```

*JS behavior:*
```javascript
const cards = document.querySelectorAll('.testimonial-card');
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.15, rootMargin: '0px 0px -50px 0px' });
cards.forEach(card => observer.observe(card));
```

---

**Featured quote with logo strip.** One oversized testimonial centered, paired with a small row of customer logos below. Use when one quote is dramatically stronger than the others.

*Animation & Visual Details:*
- *Entrance*: Quote fades in with scale 0.98 → 1; logo strip follows at 0.3s delay
- *Hover*: Logo strip auto-scrolls (pause on hover); quote attribution photo has subtle scale (1.03)
- *Gradients*: Large gradient quote mark behind the quote text (accent at 6% opacity)
- *Radial circles*: Radial glow behind the avatar photo
- *Scroll trigger*: IntersectionObserver triggers quote entrance at 20% threshold; logos stagger
- *JS interaction*: Auto-scrolling logo strip with pause on hover

```html
<section data-amb-section="testimonials" class="testimonials-section testimonials-section--featured">
  <div class="container">
    <div class="testimonials-featured">
      <div class="testimonials-featured-quote-wrapper">
        <div class="testimonials-featured-ring"></div>
        <blockquote class="testimonials-featured-quote">
          "{Specific, quantified outcome in the customer's own words. Keep it to one powerful sentence.}"
        </blockquote>
        <figcaption class="testimonials-featured-attribution">
          <img class="testimonials-featured-avatar" src="https://placehold.co/120x120" alt="{name}" />
          <div class="testimonials-featured-meta">
            <span class="testimonials-featured-name">{Full name}</span>
            <span class="testimonials-featured-role">{Title} at {Company}</span>
          </div>
        </figcaption>
      </div>
      <div class="testimonials-logo-strip">
        <div class="testimonials-logo-track-wrapper">
          <div class="testimonials-logo-track">
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Acme" alt="Acme" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Brand" alt="Brand" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Corp" alt="Corp" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Studio" alt="Studio" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=First" alt="First" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Acme" alt="Acme" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Brand" alt="Brand" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Corp" alt="Corp" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=Studio" alt="Studio" />
            <img class="testimonials-logo" src="https://placehold.co/100x32?text=First" alt="First" />
          </div>
        </div>
        <p class="testimonials-logo-label">Trusted by teams at industry-leading companies</p>
      </div>
    </div>
  </div>
</section>
```

```css
.testimonials-section--featured {
  padding: clamp(80px, 10vw, 120px) 0;
  background: var(--color-bg-alt, #f8fafc);
}

.testimonials-featured {
  text-align: center;
  max-width: 720px;
  margin: 0 auto;
}

.testimonials-featured-quote-wrapper {
  position: relative;
  opacity: 0;
  transform: scale(0.98);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.testimonials-featured-quote-wrapper.is-visible {
  opacity: 1;
  transform: scale(1);
}

.testimonials-featured-ring {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 400px;
  height: 300px;
  background: radial-gradient(ellipse, rgba(99,102,241,0.06) 0%, transparent 70%);
  pointer-events: none;
  z-index: 0;
}

.testimonials-featured-quote {
  position: relative;
  z-index: 1;
  font-size: clamp(1.3rem, 2.5vw, 1.75rem);
  line-height: 1.5;
  color: var(--color-text, #1e293b);
  font-style: italic;
  margin: 0 0 32px;
}

.testimonials-featured-attribution {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 16px;
}

.testimonials-featured-avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  object-fit: cover;
  transition: transform 0.2s ease;
}

.testimonials-featured-attribution:hover .testimonials-featured-avatar {
  transform: scale(1.03);
}

.testimonials-featured-name {
  display: block;
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text, #1e293b);
}

.testimonials-featured-role {
  display: block;
  font-size: 0.85rem;
  color: var(--color-text-muted, #64748b);
  margin-top: 2px;
}

.testimonials-logo-strip {
  margin-top: 64px;
}

.testimonials-logo-label {
  font-size: 0.8rem;
  color: var(--color-text-muted, #64748b);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 24px;
}

.testimonials-logo-track-wrapper {
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, black 15%, black 85%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 15%, black 85%, transparent);
}

.testimonials-logo-track {
  display: flex;
  gap: 48px;
  align-items: center;
  animation: logo-scroll 30s linear infinite;
  width: max-content;
  margin: 0 auto;
}

.testimonials-logo-track:hover {
  animation-play-state: paused;
}

.testimonials-logo {
  height: 28px;
  width: auto;
  opacity: 0.4;
  filter: grayscale(100%);
  transition: opacity 0.2s ease, filter 0.2s ease;
  flex-shrink: 0;
}

.testimonials-logo:hover {
  opacity: 0.8;
  filter: grayscale(0%);
}

@keyframes logo-scroll {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .testimonials-logo-track {
    animation: none;
    justify-content: center;
    flex-wrap: wrap;
  }
}
```

*JS behavior:*
```javascript
const featuredWrapper = document.querySelector('.testimonials-featured-quote-wrapper');
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.2 });
if (featuredWrapper) observer.observe(featuredWrapper);

const logoTrack = document.querySelector('.testimonials-logo-track');
const logoObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      logoTrack.style.animationPlayState = 'running';
    } else {
      logoTrack.style.animationPlayState = 'paused';
    }
  });
}, { threshold: 0 });
if (logoTrack) logoObserver.observe(logoTrack);
```

---

**Carousel.** Single card visible at a time, prev/next controls. Only use when you have 6+ quotes and they're all roughly equal in strength. Don't autoplay.

*Animation & Visual Details:*
- *Entrance*: Current card fades in with scale 0.97 → 1; inactive cards hidden off-screen
- *Hover*: Navigation arrows show; dot indicators highlight
- *Gradients*: Gradient fade on the sides of the carousel (indicating more content)
- *Radial circles*: Radial dots in the dot navigation, current dot pulses
- *Scroll trigger*: Not applicable (carousel is interactive)
- *JS interaction*: Full carousel with prev/next, dot navigation, touch/swipe support, pause on hover

```html
<section data-amb-section="testimonials" class="testimonials-section testimonials-section--carousel">
  <div class="container">
    <div class="testimonials-carousel-wrapper">
      <div class="testimonials-carousel-track-wrapper">
        <div class="testimonials-carousel-gradient testimonials-carousel-gradient--left"></div>
        <div class="testimonials-carousel-gradient testimonials-carousel-gradient--right"></div>
        <div class="testimonials-carousel-track">
          <article class="testimonial-card testimonial-card--active">
            <div class="testimonial-quote-mark">"</div>
            <blockquote class="testimonial-quote">"{Specific, quantified result in the customer's voice. One sentence.}"</blockquote>
            <figcaption class="testimonial-attribution">
              <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="Sarah Chen" />
              <div class="testimonial-meta">
                <span class="testimonial-name">Sarah Chen</span>
                <span class="testimonial-role">Head of Engineering, Vercel</span>
              </div>
            </figcaption>
          </article>
          <article class="testimonial-card">
            <div class="testimonial-quote-mark">"</div>
            <blockquote class="testimonial-quote">"{Specific, quantified result in the customer's voice. One sentence.}"</blockquote>
            <figcaption class="testimonial-attribution">
              <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="Marcus Rodriguez" />
              <div class="testimonial-meta">
                <span class="testimonial-name">Marcus Rodriguez</span>
                <span class="testimonial-role">CTO, Linear</span>
              </div>
            </figcaption>
          </article>
          <article class="testimonial-card">
            <div class="testimonial-quote-mark">"</div>
            <blockquote class="testimonial-quote">"{Specific, quantified result in the customer's voice. One sentence.}"</blockquote>
            <figcaption class="testimonial-attribution">
              <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="Priya Patel" />
              <div class="testimonial-meta">
                <span class="testimonial-name">Priya Patel</span>
                <span class="testimonial-role">Design Lead, Stripe</span>
              </div>
            </figcaption>
          </article>
        </div>
      </div>
      <div class="testimonials-carousel-controls">
        <button class="testimonials-carousel-btn testimonials-carousel-btn--prev" aria-label="Previous testimonial">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
        </button>
        <div class="testimonials-carousel-dots"></div>
        <button class="testimonials-carousel-btn testimonials-carousel-btn--next" aria-label="Next testimonial">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
        </button>
      </div>
    </div>
  </div>
</section>
```

```css
.testimonials-section--carousel {
  padding: clamp(64px, 8vw, 100px) 0;
}

.testimonials-carousel-wrapper {
  position: relative;
  max-width: 680px;
  margin: 0 auto;
}

.testimonials-carousel-track-wrapper {
  position: relative;
  overflow: hidden;
}

.testimonials-carousel-gradient {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 80px;
  pointer-events: none;
  z-index: 2;
}

.testimonials-carousel-gradient--left {
  left: 0;
  background: linear-gradient(to right, var(--color-bg, #fff), transparent);
}

.testimonials-carousel-gradient--right {
  right: 0;
  background: linear-gradient(to left, var(--color-bg, #fff), transparent);
}

.testimonials-carousel-track {
  display: flex;
  transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.testimonial-card--active {
  min-width: 100%;
  padding: 40px;
}

.testimonial-card {
  min-width: 100%;
  background: #fff;
  border-radius: 20px;
  border: 1px solid #f1f5f9;
  text-align: center;
  opacity: 0;
  transition: opacity 0.4s ease;
}

.testimonial-card--active {
  opacity: 1;
}

.testimonials-carousel-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  margin-top: 32px;
}

.testimonials-carousel-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid #e2e8f0;
  background: #fff;
  color: var(--color-text, #1e293b);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.testimonials-carousel-btn:hover {
  background: #f8fafc;
  border-color: #cbd5e1;
  transform: scale(1.05);
}

.testimonials-carousel-btn svg {
  width: 18px;
  height: 18px;
}

.testimonials-carousel-dots {
  display: flex;
  gap: 8px;
}

.testimonials-carousel-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #e2e8f0;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}

.testimonials-carousel-dot.is-active {
  background: var(--color-accent, #6366f1);
  transform: scale(1.25);
  animation: dot-pulse 1.5s ease-in-out infinite;
}

@keyframes dot-pulse {
  0%, 100% { transform: scale(1.25); }
  50% { transform: scale(1.4); }
}
```

*JS behavior:*
```javascript
class TestimonialCarousel {
  constructor(container) {
    this.track = container.querySelector('.testimonials-carousel-track');
    this.cards = container.querySelectorAll('.testimonial-card');
    this.prevBtn = container.querySelector('.testimonials-carousel-btn--prev');
    this.nextBtn = container.querySelector('.testimonials-carousel-btn--next');
    this.dotsContainer = container.querySelector('.testimonials-carousel-dots');
    this.current = 0;
    this.autoplayInterval = null;

    this.cards.forEach((_, i) => {
      const dot = document.createElement('button');
      dot.className = 'testimonials-carousel-dot' + (i === 0 ? ' is-active' : '');
      dot.setAttribute('aria-label', `Go to testimonial ${i + 1}`);
      dot.addEventListener('click', () => this.goTo(i));
      this.dotsContainer.appendChild(dot);
    });

    this.dots = this.dotsContainer.querySelectorAll('.testimonials-carousel-dot');
    this.prevBtn.addEventListener('click', () => this.prev());
    this.nextBtn.addEventListener('click', () => this.next());

    // Touch support
    let startX = 0;
    this.track.addEventListener('touchstart', (e) => {
      startX = e.touches[0].clientX;
    }, { passive: true });
    this.track.addEventListener('touchend', (e) => {
      const diff = startX - e.changedTouches[0].clientX;
      if (Math.abs(diff) > 50) {
        diff > 0 ? this.next() : this.prev();
      }
    });

    // Pause on hover
    container.addEventListener('mouseenter', () => this.stopAutoplay());
    container.addEventListener('mouseleave', () => this.startAutoplay());
  }

  goTo(index) {
    this.current = index;
    this.track.style.transform = `translateX(-${index * 100}%)`;
    this.cards.forEach((card, i) => {
      card.classList.toggle('testimonial-card--active', i === index);
    });
    this.dots.forEach((dot, i) => {
      dot.classList.toggle('is-active', i === index);
    });
  }

  next() {
    this.goTo((this.current + 1) % this.cards.length);
  }

  prev() {
    this.goTo((this.current - 1 + this.cards.length) % this.cards.length);
  }

  startAutoplay() {
    this.autoplayInterval = setInterval(() => this.next(), 6000);
  }

  stopAutoplay() {
    clearInterval(this.autoplayInterval);
  }
}

document.querySelectorAll('.testimonials-carousel-wrapper').forEach(container => {
  const carousel = new TestimonialCarousel(container);
  carousel.startAutoplay();
});
```

---

**Logo wall.** Just customer logos, no quotes. Use as a strip directly under the hero for fast credibility, not as a full standalone section.

*Animation & Visual Details:*
- *Entrance*: Logos fade in with stagger (0.05s between each) on scroll-into-view
- *Hover*: Individual logo scales to 1.05, opacity 0.6 → 0.9, grayscale removes
- *Gradients*: None — logos are monochrome by design
- *Radial circles*: Subtle radial gradient behind the logo strip container (optional)
- *Scroll trigger*: IntersectionObserver at 20% threshold
- *JS interaction*: Auto-scroll with pause on hover (optional for longer logo sets)

```html
<section data-amb-section="testimonials" class="testimonials-section testimonials-section--logo-wall">
  <div class="container">
    <p class="testimonials-logo-wall-label">Trusted by teams at</p>
    <div class="testimonials-logo-wall">
      <div class="testimonials-logo-wall-track-wrapper">
        <div class="testimonials-logo-wall-track">
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=Acme" alt="Acme" />
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=Brand" alt="Brand" />
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=Corp" alt="Corp" />
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=Studio" alt="Studio" />
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=First" alt="First" />
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=Second" alt="Second" />
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=Acme" alt="Acme" />
          <img class="testimonials-logo-wall-item" src="https://placehold.co/120x40?text=Brand" alt="Brand" />
        </div>
      </div>
    </div>
  </div>
</section>
```

```css
.testimonials-section--logo-wall {
  padding: clamp(48px, 6vw, 72px) 0;
  background: var(--color-bg-alt, #f8fafc);
}

.testimonials-logo-wall-label {
  text-align: center;
  font-size: 0.8rem;
  color: var(--color-text-muted, #64748b);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 32px;
}

.testimonials-logo-wall-track-wrapper {
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
}

.testimonials-logo-wall-track {
  display: flex;
  gap: 56px;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

.testimonials-logo-wall-item {
  height: 28px;
  width: auto;
  opacity: 0.45;
  filter: grayscale(100%);
  transition: opacity 0.2s ease, filter 0.2s ease, transform 0.2s ease;
}

.testimonials-logo-wall-item:hover {
  opacity: 0.85;
  filter: grayscale(0%);
  transform: scale(1.05);
}
```

---

**Radial quote marks.** Large decorative radial circles behind quote text. Creates visual anchor without card borders.

*Animation & Visual Details:*
- *Entrance*: Quote text fades in with scale 0.98 → 1; radial rings scale from 0.8 → 1 with opacity
- *Hover*: Radial rings pulse gently; attribution photo scales slightly
- *Gradients*: Radial rings use gradient strokes (accent color to transparent); quote text may have subtle gradient
- *Radial circles*: Two or three concentric rings behind the quote, the innermost being the largest
- *Scroll trigger*: IntersectionObserver at 30% threshold (less aggressive for this dramatic style)
- *JS interaction*: Ring pulse animation triggered on viewport entry, runs once

```html
<section data-amb-section="testimonials" class="testimonials-section testimonials-section--radial">
  <div class="container">
    <div class="testimonials-radial-grid">
      <article class="testimonial-radial">
        <div class="testimonial-radial-rings">
          <div class="testimonial-ring testimonial-ring--outer"></div>
          <div class="testimonial-ring testimonial-ring--middle"></div>
          <div class="testimonial-ring testimonial-ring--inner"></div>
        </div>
        <blockquote class="testimonial-radial-quote">"{Specific result in their voice. One powerful sentence.}"</blockquote>
        <div class="testimonial-radial-attribution">
          <img class="testimonial-radial-avatar" src="https://placehold.co/80x80" alt="{name}" />
          <div>
            <span class="testimonial-radial-name">{Full name}</span>
            <span class="testimonial-radial-role">{Title}, {Company}</span>
          </div>
        </div>
      </article>
      <article class="testimonial-radial">
        <div class="testimonial-radial-rings">
          <div class="testimonial-ring testimonial-ring--outer"></div>
          <div class="testimonial-ring testimonial-ring--middle"></div>
          <div class="testimonial-ring testimonial-ring--inner"></div>
        </div>
        <blockquote class="testimonial-radial-quote">"{Specific result in their voice. One powerful sentence.}"</blockquote>
        <div class="testimonial-radial-attribution">
          <img class="testimonial-radial-avatar" src="https://placehold.co/80x80" alt="{name}" />
          <div>
            <span class="testimonial-radial-name">{Full name}</span>
            <span class="testimonial-radial-role">{Title}, {Company}</span>
          </div>
        </div>
      </article>
    </div>
  </div>
</section>
```

```css
.testimonials-section--radial {
  padding: clamp(64px, 8vw, 100px) 0;
}

.testimonials-radial-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 48px;
}

.testimonial-radial {
  position: relative;
  text-align: center;
  padding: 48px 32px;
}

.testimonial-radial-rings {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 0;
}

.testimonial-ring {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 1px solid rgba(99,102,241,0.15);
  opacity: 0;
  animation: ring-reveal 0.6s ease-out forwards;
}

.testimonial-ring--outer {
  width: 300px;
  height: 300px;
  animation-delay: 0.3s;
}

.testimonial-ring--middle {
  width: 220px;
  height: 220px;
  animation-delay: 0.2s;
}

.testimonial-ring--inner {
  width: 140px;
  height: 140px;
  animation-delay: 0.1s;
}

@keyframes ring-reveal {
  to {
    opacity: 1;
  }
}

.testimonial-radial.is-visible .testimonial-ring--outer {
  animation: ring-reveal 0.6s ease-out forwards, ring-pulse-slow 3s ease-in-out 0.9s infinite;
}

@keyframes ring-pulse-slow {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.03); }
}

.testimonial-radial-quote {
  position: relative;
  z-index: 1;
  font-size: 1.15rem;
  line-height: 1.6;
  color: var(--color-text, #1e293b);
  font-style: italic;
  margin: 0 0 24px;
  opacity: 0;
  transform: scale(0.98);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.testimonial-radial.is-visible .testimonial-radial-quote {
  opacity: 1;
  transform: scale(1);
}

.testimonial-radial-attribution {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  opacity: 0;
  transition: opacity 0.5s ease 0.2s;
}

.testimonial-radial.is-visible .testimonial-radial-attribution {
  opacity: 1;
}

.testimonial-radial-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  transition: transform 0.2s ease;
}

.testimonial-radial:hover .testimonial-radial-avatar {
  transform: scale(1.05);
}

.testimonial-radial-name {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-text, #1e293b);
}

.testimonial-radial-role {
  display: block;
  font-size: 0.8rem;
  color: var(--color-text-muted, #64748b);
}

@media (prefers-reduced-motion: reduce) {
  .testimonial-ring {
    animation: none;
    opacity: 0.5;
  }
  .testimonial-radial-quote,
  .testimonial-radial-attribution {
    opacity: 1;
    transform: none;
  }
}
```

*JS behavior:*
```javascript
const radialTestimonials = document.querySelectorAll('.testimonial-radial');
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.3 });
radialTestimonials.forEach(el => observer.observe(el));
```

---

**Animated card testimonials.** Stagger reveal on scroll, hover lift with gradient border glow. Cards have more dramatic hover state than default.

*Animation & Visual Details:*
- *Entrance*: Cards stagger in from translateY(40px) with fade, 0.15s between each
- *Hover*: Card lifts (translateY(-8px)), gradient border glows (0 → 0.6 opacity), shadow intensifies
- *Gradients*: Card border is a gradient (conic-gradient from accent colors) that animates rotation on hover
- *Radial circles*: Radial glow behind the avatar (accent at 10% opacity), intensifies on hover
- *Scroll trigger*: IntersectionObserver at 15% threshold
- *JS interaction*: Gradient border animation toggle on hover

```html
<section data-amb-section="testimonials" class="testimonials-section testimonials-section--animated">
  <div class="container">
    <div class="testimonials-grid">
      <article class="testimonial-card testimonial-card--animated">
        <div class="testimonial-card-border-glow"></div>
        <div class="testimonial-card-content">
          <blockquote class="testimonial-quote">"{Specific, quantified outcome in their voice. One sentence.}"</blockquote>
          <figcaption class="testimonial-attribution">
            <div class="testimonial-avatar-wrapper">
              <div class="testimonial-avatar-glow"></div>
              <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="{name}" />
            </div>
            <div class="testimonial-meta">
              <span class="testimonial-name">{Full name}</span>
              <span class="testimonial-role">{Title}, {Company}</span>
            </div>
          </figcaption>
        </div>
      </article>
      <article class="testimonial-card testimonial-card--animated">
        <div class="testimonial-card-border-glow"></div>
        <div class="testimonial-card-content">
          <blockquote class="testimonial-quote">"{Specific, quantified outcome in their voice. One sentence.}"</blockquote>
          <figcaption class="testimonial-attribution">
            <div class="testimonial-avatar-wrapper">
              <div class="testimonial-avatar-glow"></div>
              <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="{name}" />
            </div>
            <div class="testimonial-meta">
              <span class="testimonial-name">{Full name}</span>
              <span class="testimonial-role">{Title}, {Company}</span>
            </div>
          </figcaption>
        </div>
      </article>
      <article class="testimonial-card testimonial-card--animated">
        <div class="testimonial-card-border-glow"></div>
        <div class="testimonial-card-content">
          <blockquote class="testimonial-quote">"{Specific, quantified outcome in their voice. One sentence.}"</blockquote>
          <figcaption class="testimonial-attribution">
            <div class="testimonial-avatar-wrapper">
              <div class="testimonial-avatar-glow"></div>
              <img class="testimonial-avatar" src="https://placehold.co/96x96" alt="{name}" />
            </div>
            <div class="testimonial-meta">
              <span class="testimonial-name">{Full name}</span>
              <span class="testimonial-role">{Title}, {Company}</span>
            </div>
          </figcaption>
        </div>
      </article>
    </div>
  </div>
</section>
```

```css
.testimonials-section--animated {
  padding: clamp(64px, 8vw, 100px) 0;
}

.testimonial-card--animated {
  position: relative;
  background: #fff;
  border-radius: 20px;
  padding: 2px;
  opacity: 0;
  transform: translateY(32px);
  transition: transform 0.3s ease;
}

.testimonial-card--animated.is-visible {
  animation: testimonial-anim-enter 0.5s ease-out forwards;
}

.testimonial-card--animated:nth-child(1).is-visible { animation-delay: 0s; }
.testimonial-card--animated:nth-child(2).is-visible { animation-delay: 0.15s; }
.testimonial-card--animated:nth-child(3).is-visible { animation-delay: 0.3s; }

@keyframes testimonial-anim-enter {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.testimonial-card--animated::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 22px;
  background: conic-gradient(from 0deg, #6366f1, #a855f7, #ec4899, #f59e0b, #6366f1);
  opacity: 0;
  transition: opacity 0.4s ease;
}

.testimonial-card--animated.is-hovered::before {
  opacity: 0.7;
  animation: border-spin 2s linear infinite;
}

@keyframes border-spin {
  to { background: conic-gradient(from 360deg, #6366f1, #a855f7, #ec4899, #f59e0b, #6366f1); }
}

.testimonial-card-content {
  position: relative;
  z-index: 1;
  background: #fff;
  border-radius: 18px;
  padding: 32px;
  height: 100%;
}

.testimonial-card-border-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80%;
  height: 60%;
  background: radial-gradient(ellipse, rgba(99,102,241,0.08) 0%, transparent 70%);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}

.testimonial-card--animated:hover {
  transform: translateY(-8px);
  box-shadow: 0 20px 48px rgba(0,0,0,0.1);
}

.testimonial-card--animated:hover .testimonial-card-border-glow {
  opacity: 1;
}

.testimonial-avatar-wrapper {
  position: relative;
}

.testimonial-avatar-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 72px;
  height: 72px;
  background: radial-gradient(circle, rgba(99,102,241,0.1) 0%, transparent 70%);
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.testimonial-card--animated:hover .testimonial-avatar-glow {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .testimonial-card--animated {
    opacity: 1;
    transform: none;
  }
  .testimonial-card--animated::before,
  .testimonial-card--animated.is-hovered::before {
    animation: none;
    opacity: 0.5;
  }
}
```

*JS behavior:*
```javascript
const animatedCards = document.querySelectorAll('.testimonial-card--animated');
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.15 });

animatedCards.forEach(card => {
  observer.observe(card);
  card.addEventListener('mouseenter', () => card.classList.add('is-hovered'));
  card.addEventListener('mouseleave', () => card.classList.remove('is-hovered'));
});
```

---

Copy rules: never start a testimonial with "I love..." or "Great product!" — open with the outcome or before/after. Always include the speaker's title AND company, not just one. Avoid "[Customer Name], CEO of [Acme]" — invent specific names and titles when generating.

Layout rules: quote cards should have visible visual weight (border, subtle shadow, or background tint) — pick one. Avatars are always circular (`border-radius: 50%`). If using a logo strip, render logos in monochrome (grayscale or a single brand color) so brand-identity gradients don't fight each other.

CSS custom property summary:
```css
:root {
  --testimonial-enter-duration: 0.5s;
  --testimonial-stagger: 0.1s;
  --color-accent: #6366f1;
  --color-text: #1e293b;
  --color-text-muted: #64748b;
}
```