Zoeken...  ⌘K GitHub

CtaGradient CTA

Levendige verloop-CTA met zacht bewegende blobs: eyebrow, kop met accent, sub en twee acties.

/cta-gradient
src/components/cta/CtaGradient.astro
---
/**
 * CtaGradient
 * Levendige verloop-CTA met zacht bewegende blobs: pill-eyebrow, kop met
 * optioneel accent-woord, sub en twee acties. Gecentreerd.
 *
 * Props:
 * - eyebrow?: string
 * - headline: string
 * - accent?: string            normaal-gestijld accent in de kop (na {headline})
 * - sub?: string
 * - primary?: { label: string; href: string }
 * - secondary?: { label: string; href: string }
 * - from?: string              verloop-startkleur
 * - to?: string                verloop-eindkleur
 */
interface Props {
  eyebrow?: string;
  headline: string;
  accent?: string;
  sub?: string;
  primary?: { label: string; href: string };
  secondary?: { label: string; href: string };
  from?: string;
  to?: string;
}
const { eyebrow, headline, accent, sub, primary, secondary, from = '#6366f1', to = '#8b5cf6' } = Astro.props;
---

<section class="bl-section cg" style={`--cg-from:${from};--cg-to:${to};`}>
  <div class="cg__blob cg__blob--1" aria-hidden="true"></div>
  <div class="cg__blob cg__blob--2" aria-hidden="true"></div>
  <div class="cg__noise" aria-hidden="true"></div>
  <div class="bl-inner cg__content">
    {eyebrow && <p class="cg__eyebrow">{eyebrow}</p>}
    <h2 class="cg__headline">{headline}{accent && <em> {accent}</em>}</h2>
    {sub && <p class="cg__sub">{sub}</p>}
    {(primary || secondary) && (
      <div class="cg__actions">
        {primary && <a href={primary.href} class="cg__cta-primary">{primary.label}</a>}
        {secondary && (
          <a href={secondary.href} class="cg__cta-secondary">
            {secondary.label}
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
              <path d="M2 7h10M8 3l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
            </svg>
          </a>
        )}
      </div>
    )}
  </div>
</section>

<style>
.cg{position:relative;overflow:hidden;background:linear-gradient(135deg,var(--cg-from,#6366f1) 0%,var(--cg-to,#8b5cf6) 100%);text-align:center}
.cg__blob{position:absolute;border-radius:50%;filter:blur(80px);opacity:.3;pointer-events:none}
.cg__blob--1{width:60vw;height:60vw;background:#ffffff4d;top:-30%;right:-20%;animation:cg-float-1 20s ease-in-out infinite}
.cg__blob--2{width:40vw;height:40vw;background:#0003;bottom:-20%;left:-15%;animation:cg-float-2 16s ease-in-out infinite}
.cg__noise{position:absolute;inset:0;opacity:.05;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");background-size:256px;pointer-events:none}
.cg__content{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:0}
.cg__eyebrow{display:inline-flex;align-items:center;gap:.5rem;border:1px solid rgba(255,255,255,.3);background:#ffffff1a;padding:.375rem 1rem;border-radius:999px;font-size:.8125rem;font-weight:600;color:#fff;letter-spacing:.04em;margin-bottom:1.75rem}
.cg__headline{font-size:clamp(2.25rem,5vw,4rem);font-weight:900;line-height:1.05;letter-spacing:-.04em;color:#fff;margin-bottom:1.25rem}
.cg__headline em{font-style:normal;opacity:.8}
.cg__sub{font-size:1.125rem;line-height:1.65;color:#ffffffe6;max-width:48ch;margin-bottom:2.5rem}
.cg__actions{display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap;justify-content:center}
.cg__cta-primary{display:inline-flex;align-items:center;background:#fff;color:var(--cg-from,#6366f1);padding:1rem 2.25rem;border-radius:var(--radius,.5rem);font-weight:800;font-size:1rem;text-decoration:none;box-shadow:0 4px 24px #00000026;transition:transform .2s,box-shadow .2s}
.cg__cta-primary:hover{transform:translateY(-3px);box-shadow:0 8px 32px #0003}
.cg__cta-secondary{display:inline-flex;align-items:center;gap:.5rem;font-size:1rem;font-weight:600;color:#fff;text-decoration:none;transition:gap .2s}
.cg__cta-secondary:hover{gap:.75rem}
@keyframes cg-float-1{0%,100%{transform:translate(0,0)}50%{transform:translate(-4%,4%)}}
@keyframes cg-float-2{0%,100%{transform:translate(0,0)}50%{transform:translate(5%,-3%)}}
@media (prefers-reduced-motion:reduce){.cg__blob--1,.cg__blob--2{animation:none}}
@media (max-width:640px){
  .cg__actions{flex-direction:column;width:100%}
  .cg__cta-primary{width:100%;justify-content:center}
}
</style>

Props

Prop Type Default Beschrijving
eyebrow string - Pill-label boven de kop
headline * string - H2-kop
accent string - Accent-woord (komt na de kop)
sub string - Ondertitel
primary { label: string; href: string } - Primaire knop
secondary { label: string; href: string } - Secundaire link
from string #6366f1 Verloop-startkleur
to string #8b5cf6 Verloop-eindkleur

* = verplicht