Zoeken...  ⌘K GitHub

TestimonialsDark Social Proof

Donkere testimonialsgrids met featured eerste kaart in accentkleur.

/testimonials-dark
src/components/social-proof/TestimonialsDark.astro
---
/**
 * TestimonialsDark
 * Donkere grid met testimonials en accent accenten.
 */
interface Props {
  eyebrow?: string;
  headline?: string;
  testimonials: { quote: string; name: string; role: string; avatar?: string; rating?: number }[];
}
const { eyebrow, headline, testimonials } = Astro.props;
---
<section class="tsd">
  <div class="tsd-inner">
    {(eyebrow || headline) && (
      <div class="tsd-header">
        {eyebrow && <span class="tsd-eyebrow">{eyebrow}</span>}
        {headline && <h2 class="tsd-headline">{headline}</h2>}
      </div>
    )}
    <div class="tsd-grid">
      {testimonials.map((t, i) => (
        <div class={`tsd-card${i === 0 ? ' tsd-card--featured' : ''}`}>
          {t.rating && (
            <div class="tsd-stars">
              {Array.from({length: t.rating}).map(() => <span class="tsd-star">★</span>)}
            </div>
          )}
          <p class="tsd-quote">"{t.quote}"</p>
          <footer class="tsd-footer">
            {t.avatar && <img src={t.avatar} alt={t.name} class="tsd-avatar" />}
            <div>
              <cite class="tsd-name">{t.name}</cite>
              <span class="tsd-role">{t.role}</span>
            </div>
          </footer>
        </div>
      ))}
    </div>
  </div>
</section>
<style>
  .tsd { background: #0a0a0a; padding: 5rem 2rem; }
  .tsd-inner { max-width: 1100px; margin: 0 auto; }
  .tsd-header { text-align: center; margin-bottom: 3rem; }
  .tsd-eyebrow { display: block; font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent,#6366f1); margin-bottom: 0.75rem; }
  .tsd-headline { font-size: clamp(1.75rem, 3.5vw, 2.5rem); font-weight: 900; color: #fff; letter-spacing: -0.04em; line-height: 1.15; margin: 0; }
  .tsd-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.25rem; }
  .tsd-card { padding: 2rem; border-radius: 1rem; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.07); display: flex; flex-direction: column; gap: 1.25rem; }
  .tsd-card--featured { background: var(--color-accent,#6366f1); border-color: transparent; }
  .tsd-stars { display: flex; gap: 0.2rem; }
  .tsd-star { color: #f59e0b; font-size: 1rem; }
  .tsd-card--featured .tsd-star { color: #fde68a; }
  .tsd-quote { font-size: 0.9375rem; line-height: 1.65; font-style: italic; margin: 0; flex: 1; color: rgba(255,255,255,0.75); }
  .tsd-card--featured .tsd-quote { color: rgba(255,255,255,0.9); }
  .tsd-footer { display: flex; align-items: center; gap: 0.75rem; }
  .tsd-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; }
  .tsd-name { display: block; font-size: 0.9375rem; font-weight: 700; color: #fff; font-style: normal; }
  .tsd-role { display: block; font-size: 0.8125rem; color: rgba(255,255,255,0.4); }
  .tsd-card--featured .tsd-role { color: rgba(255,255,255,0.65); }
</style>

Props

Prop Type Default Beschrijving
testimonials * { quote: string; name: string; role: string; avatar?: string; rating?: number }[] Testimonials (eerste kaart wordt uitgelicht)
eyebrow string Eyebrow
headline string Sectie headline

* = verplicht