Zoeken...  ⌘K GitHub

HeroBento Hero

Bento grid hero: groot donker headline card + kleinere info cards. Modern SaaS/tech stijl.

/hero-bento
src/components/hero/HeroBento.astro
---
/**
 * HeroBento
 * Bento grid hero: groot headline-card + 3 kleine info-cards.
 * Modern asymmetrisch layout, populair in SaaS/tech.
 */
interface Props {
  eyebrow?: string;
  headline: string;
  sub?: string;
  cta?: { label: string; href: string };
  cards?: { icon?: string; title: string; value?: string; body?: string }[];
  image?: string;
}
const { eyebrow, headline, sub, cta, cards = [], image } = Astro.props;
---
<section class="hbt">
  <div class="hbt-grid">
    <div class="hbt-main">
      {eyebrow && <span class="hbt-eyebrow">{eyebrow}</span>}
      <h1 class="hbt-headline">{headline}</h1>
      {sub && <p class="hbt-sub">{sub}</p>}
      {cta && <a href={cta.href} class="hbt-cta">{cta.label} →</a>}
    </div>
    {image && (
      <div class="hbt-image-card">
        <img src={image} alt="" class="hbt-img" />
      </div>
    )}
    {cards.map((c, i) => (
      <div class={`hbt-card hbt-card--${i}`}>
        {c.icon && <span class="hbt-card-icon">{c.icon}</span>}
        {c.value && <span class="hbt-card-value">{c.value}</span>}
        <span class="hbt-card-title">{c.title}</span>
        {c.body && <span class="hbt-card-body">{c.body}</span>}
      </div>
    ))}
  </div>
</section>
<style>
  .hbt { padding: 3rem 2rem; background: #f1f5f9; }
  .hbt-grid { max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto auto; gap: 1rem; }
  .hbt-main { grid-column: span 2; background: #0f172a; border-radius: 1.25rem; padding: 3rem; color: #fff; display: flex; flex-direction: column; justify-content: flex-end; min-height: 320px; }
  .hbt-eyebrow { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent,#6366f1); margin-bottom: 1rem; }
  .hbt-headline { font-size: clamp(2rem, 3.5vw, 3rem); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; margin: 0 0 1rem; }
  .hbt-sub { font-size: 1rem; color: rgba(255,255,255,0.55); line-height: 1.6; margin: 0 0 2rem; max-width: 400px; }
  .hbt-cta { display: inline-flex; align-items: center; padding: 0.75rem 1.5rem; background: var(--color-accent,#6366f1); color: #fff; border-radius: 0.5rem; font-weight: 600; font-size: 0.9375rem; text-decoration: none; width: fit-content; }
  .hbt-cta:hover { opacity: 0.9; }
  .hbt-image-card { background: #e2e8f0; border-radius: 1.25rem; overflow: hidden; }
  .hbt-img { width: 100%; height: 100%; object-fit: cover; }
  .hbt-card { background: #fff; border-radius: 1.25rem; padding: 1.5rem; display: flex; flex-direction: column; gap: 0.5rem; }
  .hbt-card-icon { font-size: 1.5rem; }
  .hbt-card-value { font-size: 2rem; font-weight: 800; color: #0f172a; letter-spacing: -0.03em; }
  .hbt-card-title { font-size: 0.9375rem; font-weight: 600; color: #334155; }
  .hbt-card-body { font-size: 0.8125rem; color: #94a3b8; line-height: 1.5; }
  @media (max-width: 768px) { .hbt-grid { grid-template-columns: 1fr; } .hbt-main { grid-column: span 1; } }
</style>

Props

Prop Type Default Beschrijving
headline * string H1 tekst
eyebrow string Label boven headline
sub string Ondertitel
cta { label: string; href: string } CTA knop
cards { icon?: string; title: string; value?: string; body?: string }[] Info cards (max 3-4)
image string Optionele afbeelding in grid

* = verplicht