Zoeken...  ⌘K GitHub

HeroSaas Hero

SaaS-stijl hero met headline, metrics rij en dashboard mockup. Populair voor tech-producten.

/hero-saas
src/components/hero/HeroSaas.astro
---
/**
 * HeroSaas
 * SaaS-stijl hero: headline + metrics row + dashboard mockup (CSS box).
 * Lichte achtergrond, grid card onderaan als product preview.
 */
interface Props {
  eyebrow?: string;
  headline: string;
  sub?: string;
  ctaPrimary?: { label: string; href: string };
  ctaSecondary?: { label: string; href: string };
  metrics?: { value: string; label: string }[];
  dashboardImage?: string;
}
const { eyebrow, headline, sub, ctaPrimary, ctaSecondary, metrics = [], dashboardImage } = Astro.props;
---
<section class="hs">
  <div class="hs-inner">
    <div class="hs-text">
      {eyebrow && <span class="hs-eyebrow">{eyebrow}</span>}
      <h1 class="hs-headline">{headline}</h1>
      {sub && <p class="hs-sub">{sub}</p>}
      <div class="hs-actions">
        {ctaPrimary && <a href={ctaPrimary.href} class="hs-btn hs-btn--primary">{ctaPrimary.label}</a>}
        {ctaSecondary && <a href={ctaSecondary.href} class="hs-btn hs-btn--ghost">{ctaSecondary.label}</a>}
      </div>
      {metrics.length > 0 && (
        <div class="hs-metrics">
          {metrics.map(m => (
            <div class="hs-metric">
              <span class="hs-metric-value">{m.value}</span>
              <span class="hs-metric-label">{m.label}</span>
            </div>
          ))}
        </div>
      )}
    </div>
    <div class="hs-preview">
      {dashboardImage
        ? <img src={dashboardImage} alt="Dashboard preview" class="hs-img" />
        : (
          <div class="hs-mockup">
            <div class="hs-mock-bar"><span/><span/><span/></div>
            <div class="hs-mock-grid">
              <div class="hs-mock-stat"><div class="hs-mock-val">4.2×</div><div class="hs-mock-lbl">ROAS</div></div>
              <div class="hs-mock-stat"><div class="hs-mock-val">€12M</div><div class="hs-mock-lbl">Omzet</div></div>
              <div class="hs-mock-stat"><div class="hs-mock-val">93%</div><div class="hs-mock-lbl">Retentie</div></div>
              <div class="hs-mock-chart"><div class="hs-bar" style="height:40%"/><div class="hs-bar" style="height:65%"/><div class="hs-bar" style="height:50%"/><div class="hs-bar" style="height:80%"/><div class="hs-bar" style="height:70%"/><div class="hs-bar" style="height:90%"/></div>
            </div>
          </div>
        )
      }
    </div>
  </div>
</section>
<style>
  .hs { padding: 5rem 2rem 4rem; background: #f8fafc; }
  .hs-inner { max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: center; }
  .hs-eyebrow { display: inline-block; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent,#6366f1); background: rgba(99,102,241,0.1); padding: 0.25rem 0.75rem; border-radius: 100px; margin-bottom: 1.25rem; }
  .hs-headline { font-size: clamp(2rem, 3.5vw, 3.5rem); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; color: #0f172a; margin: 0 0 1rem; }
  .hs-sub { font-size: 1.0625rem; color: #64748b; line-height: 1.65; margin: 0 0 2rem; }
  .hs-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 2rem; }
  .hs-btn { display: inline-flex; align-items: center; padding: 0.75rem 1.5rem; border-radius: 0.5rem; font-size: 0.9375rem; font-weight: 600; text-decoration: none; transition: all 0.2s; }
  .hs-btn--primary { background: var(--color-accent,#6366f1); color: #fff; }
  .hs-btn--primary:hover { opacity: 0.9; transform: translateY(-1px); }
  .hs-btn--ghost { border: 1.5px solid #e2e8f0; color: #334155; }
  .hs-btn--ghost:hover { border-color: #94a3b8; }
  .hs-metrics { display: flex; gap: 2rem; padding-top: 1.5rem; border-top: 1px solid #e2e8f0; }
  .hs-metric { display: flex; flex-direction: column; gap: 0.2rem; }
  .hs-metric-value { font-size: 1.5rem; font-weight: 800; color: #0f172a; }
  .hs-metric-label { font-size: 0.75rem; color: #94a3b8; }
  .hs-preview { border-radius: 1rem; overflow: hidden; box-shadow: 0 20px 60px rgba(0,0,0,0.1); }
  .hs-img { width: 100%; height: auto; display: block; }
  .hs-mockup { background: #1e293b; padding: 1.25rem; border-radius: 1rem; }
  .hs-mock-bar { display: flex; gap: 0.4rem; margin-bottom: 1rem; }
  .hs-mock-bar span { width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,0.15); }
  .hs-mock-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 0.75rem; }
  .hs-mock-stat { background: rgba(255,255,255,0.06); border-radius: 0.5rem; padding: 1rem; }
  .hs-mock-val { font-size: 1.25rem; font-weight: 800; color: #fff; }
  .hs-mock-lbl { font-size: 0.6875rem; color: rgba(255,255,255,0.4); margin-top: 0.25rem; }
  .hs-mock-chart { grid-column: span 3; background: rgba(255,255,255,0.04); border-radius: 0.5rem; padding: 1rem; display: flex; align-items: flex-end; gap: 0.5rem; height: 80px; }
  .hs-bar { flex: 1; background: var(--color-accent,#6366f1); border-radius: 3px 3px 0 0; opacity: 0.7; }
  @media (max-width: 768px) { .hs-inner { grid-template-columns: 1fr; } .hs-preview { order: -1; } }
</style>

Props

Prop Type Default Beschrijving
headline * string H1 tekst
eyebrow string Label boven headline
sub string Ondertitel
ctaPrimary { label: string; href: string } Primaire CTA
ctaSecondary { label: string; href: string } Secundaire CTA
metrics { value: string; label: string }[] Statistieken onder hero
dashboardImage string Dashboard screenshot URL

* = verplicht