HeroBento Hero
Bento grid hero: groot donker headline card + kleinere info cards. Modern SaaS/tech stijl.
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