Zoeken...  ⌘K GitHub

ImageShowcase image

Showcase-rij van diensten of producten met afbeelding, tag en beschrijving.

/image-showcase
src/components/image/ImageShowcase.astro
---
interface ShowcaseItem {
  src?: string;
  alt: string;
  title: string;
  description: string;
  tag?: string;
}

interface Props {
  items?: ShowcaseItem[];
  heading?: string;
}

const {
  items = [
    {
      alt: 'Service 1',
      title: 'Brand Identity',
      description: 'Van logo tot volledig merkhandboek — wij bouwen identiteiten die blijven hangen.',
      tag: 'Design',
    },
    {
      alt: 'Service 2',
      title: 'Performance Ads',
      description: 'Data-gedreven campagnes op Google, Meta en LinkedIn met aantoonbaar resultaat.',
      tag: 'Marketing',
    },
    {
      alt: 'Service 3',
      title: 'Web Development',
      description: 'Snelle, converterende websites gebouwd op Astro en moderne technologie.',
      tag: 'Tech',
    },
  ],
  heading = 'Wat we bouwen',
} = Astro.props;
---

<section class="ish">
  {heading && <h2 class="ish__heading">{heading}</h2>}
  <div class="ish__list">
    {items.map((item) => (
      <div class="ish__item">
        <div class="ish__media">
          {item.src ? (
            <img class="ish__img" src={item.src} alt={item.alt} />
          ) : (
            <div class="ish__placeholder" aria-label={item.alt}></div>
          )}
          {item.tag && <span class="ish__tag">{item.tag}</span>}
        </div>
        <h3 class="ish__title">{item.title}</h3>
        <p class="ish__desc">{item.description}</p>
      </div>
    ))}
  </div>
</section>

<style>
  :root {
    --color-accent: #6366f1;
    --color-primary: #0a0a0a;
  }
  .ish { padding: 3rem 0; }
  .ish__heading {
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: 700;
    color: var(--color-primary, #0a0a0a);
    text-align: center;
    margin: 0 0 3rem;
  }
  .ish__list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
  }
  .ish__item { display: flex; flex-direction: column; }
  .ish__media {
    position: relative;
    aspect-ratio: 16/10;
    border-radius: 10px;
    overflow: hidden;
    margin-bottom: 1.25rem;
  }
  .ish__img { width: 100%; height: 100%; object-fit: cover; }
  .ish__placeholder {
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, #e0e4f8 0%, #c8cef0 100%);
  }
  .ish__item:nth-child(2) .ish__placeholder {
    background: linear-gradient(135deg, #f0e8e0 0%, #e8d8c8 100%);
  }
  .ish__item:nth-child(3) .ish__placeholder {
    background: linear-gradient(135deg, #e0f0e0 0%, #c8e8c8 100%);
  }
  .ish__tag {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    background: var(--color-primary, #0a0a0a);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.25rem 0.6rem;
    border-radius: 4px;
  }
  .ish__title {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--color-primary, #0a0a0a);
    margin: 0 0 0.5rem;
  }
  .ish__desc {
    font-size: 0.9rem;
    color: #666;
    line-height: 1.65;
    margin: 0;
  }
  @media (max-width: 768px) {
    .ish__list { grid-template-columns: 1fr; }
  }
</style>

Props

Prop Type Default Beschrijving
items { src?: string; alt: string; title: string; description: string; tag?: string }[] Showcase items
heading string Sectietitel

* = verplicht