Zoeken...  ⌘K GitHub

ManifestBlock Sections

Genummerde USPs of pijlers. Sober en krachtig.

/manifest-block
src/components/sections/ManifestBlock.astro
---
/**
 * ManifestBlock
 * Genummerde USPs of pijlers. Krachtig en sober.
 *
 * Props:
 * - headline?: string
 * - items: Array<{ number?: string; title: string; body: string }>
 * - columns?: 1 | 2 | 3
 * - numbered?: boolean — toon auto-nummering als number niet opgegeven
 */
interface Props {
  headline?: string;
  items: { number?: string; title: string; body: string }[];
  columns?: 1 | 2 | 3;
  numbered?: boolean;
}

const { headline, items, columns = 3, numbered = true } = Astro.props;
---

<section class={`manifest manifest--cols-${columns}`} data-manifest>
  <div class="manifest__inner">
    {headline && <h2 class="manifest__headline">{headline}</h2>}
    <ol class="manifest__list">
      {items.map((item, i) => (
        <li class="manifest__item">
          <span class="manifest__num">
            {item.number ?? (numbered ? String(i + 1).padStart(2, '0') : null)}
          </span>
          <h3 class="manifest__title">{item.title}</h3>
          <p class="manifest__body">{item.body}</p>
        </li>
      ))}
    </ol>
  </div>
</section>

<style>
  .manifest {
    padding: 5rem 1.5rem;
    background: var(--color-bg);
  }
  .manifest__inner {
    max-width: 1280px;
    margin: 0 auto;
  }
  .manifest__headline {
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: 800;
    letter-spacing: -0.03em;
    margin: 0 0 3rem;
    max-width: 640px;
  }
  .manifest__list {
    list-style: none;
    margin: 0; padding: 0;
    display: grid;
    gap: 2.5rem 3rem;
    grid-template-columns: 1fr;
  }
  @media (min-width: 600px) {
    .manifest--cols-2 .manifest__list,
    .manifest--cols-3 .manifest__list { grid-template-columns: 1fr 1fr; }
  }
  @media (min-width: 960px) {
    .manifest--cols-3 .manifest__list { grid-template-columns: repeat(3, 1fr); }
  }
  .manifest__item {
    border-top: 1px solid color-mix(in srgb, var(--color-text) 15%, transparent);
    padding-top: 1.5rem;
  }
  .manifest__num {
    display: block;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--color-accent);
    margin-bottom: 0.75rem;
  }
  .manifest__title {
    font-size: 1.125rem;
    font-weight: 700;
    margin: 0 0 0.5rem;
    letter-spacing: -0.01em;
  }
  .manifest__body {
    font-size: 0.9375rem;
    color: var(--color-muted);
    line-height: 1.65;
    margin: 0;
  }
</style>

<script>
  if (typeof gsap !== 'undefined' && typeof ScrollTrigger !== 'undefined') {
    gsap.registerPlugin(ScrollTrigger);
    gsap.from('[data-manifest] .manifest__item', {
      y: 24, opacity: 0, duration: 0.6, stagger: 0.08, ease: 'power2.out',
      scrollTrigger: { trigger: '[data-manifest]', start: 'top 80%' }
    });
  }
</script>

Props

Prop Type Default Beschrijving
items * { number?: string; title: string; body: string }[] USP items
headline string Sectie headline
columns 1 | 2 | 3 3 Aantal kolommen
numbered boolean true Auto-nummering tonen

* = verplicht