HeadingCentered heading
Gecentreerde sectiekop met eyebrow + divider en een headline met optioneel cursief accent-woord. Optionele reveal-on-scroll.
src/components/heading/HeadingCentered.astro
---
/**
* HeadingCentered — gecentreerde sectiekop met eyebrow + divider, headline met
* optioneel cursief accent-woord, en sub. Optionele scroll-reveal animatie.
*
* Props:
* - eyebrow?: string
* - headline?: string gebruik <em> voor een cursief accent-woord
* - sub?: string
* - animate?: boolean default false (direct zichtbaar). true = reveal-on-scroll
*/
interface Props {
eyebrow?: string;
headline?: string;
sub?: string;
animate?: boolean;
}
const { eyebrow, headline, sub, animate = false } = Astro.props;
---
<section class:list={['bl-section', 'hcn', { 'hcn--animate': animate }]}>
<div class="bl-inner bl-inner--narrow hcn__inner">
{eyebrow && (
<span class="hcn__eyebrow">
{eyebrow}
<span class="hcn__divider" aria-hidden="true"></span>
</span>
)}
{headline && <h2 class="hcn__headline" set:html={headline} />}
{sub && <p class="hcn__sub">{sub}</p>}
</div>
</section>
<style>
.hcn{text-align:center}
.hcn--animate{opacity:0;transform:translateY(24px);transition:opacity .6s ease,transform .6s ease}
.hcn--animate.hcn--visible{opacity:1;transform:translateY(0)}
.hcn__inner{display:flex;flex-direction:column;gap:1rem;align-items:center}
.hcn__eyebrow{display:flex;flex-direction:column;align-items:center;gap:.75rem;font-size:.75rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--color-accent)}
.hcn__divider{display:block;width:40px;height:3px;background:var(--color-accent);border-radius:2px}
.hcn__headline{margin:0;font-weight:800;letter-spacing:-.02em;color:var(--color-primary);line-height:1.1;font-size:clamp(2.5rem,5vw,4rem)}
.hcn__headline :global(em){font-style:italic;color:var(--color-accent)}
.hcn__sub{margin:0;font-size:1.125rem;line-height:1.7;color:#444;max-width:580px}
</style>
<script>
// WHY: reveal alleen activeren als de auteur animate=true zet; anders blijft
// het blok direct zichtbaar (geen blanco render zonder JS / boven de fold).
document.querySelectorAll('.hcn--animate').forEach((el) => {
const io = new IntersectionObserver((entries, obs) => {
entries.forEach((e) => {
if (e.isIntersecting) { e.target.classList.add('hcn--visible'); obs.unobserve(e.target); }
});
}, { threshold: 0.2 });
io.observe(el);
});
</script>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
eyebrow | string | - | Klein label met divider boven de headline |
headline | string | - | De headline (H2); gebruik <em> voor een cursief accent-woord |
sub | string | - | Ondersteunende ondertitel |
animate | boolean | false | true = reveal-on-scroll; false = direct zichtbaar |
* = verplicht