HeroCoverpopular
apps/www/src/sections/HeroCover.astro · 71 lines · group Hero
HeroCover — the first screen: a full-width photo under the brand gradient, the title, pitch and buttons centered on top of it. Use for: a landing that opens with a wide, atmospheric photo (a landscape, a workplace, a team) and one short promise. Not for: a product shot that must stay whole (<HeroSplit imageFit="contain">); a page that opens with words alone (<HeroText>). Children: optional markdown between the tags, rendered under the description and above the buttons. No sub-block tags. Picture: LANDSCAPE. It is cropped to fill the section and tinted with the brand colour, so it must not carry text or a logo. Without `image` the section is a plain brand-coloured band. Follow-up: by default the bottom keeps room for a <FeatureCards overlap> row that hangs over the edge. Set overlapNext={false} when the next section is anything else, or the hero ends with an empty band. Buttons: a button appears only when its text is given; primary is the solid brand button, secondary the translucent one.
In the fleet
Used on 3 sites built with this engine.
Samples 2

Weather that pays offin the field, not on a grid cell
A station you install in an hour and forget about for a season. Frost, wind and leaf wetness measured inside the crop, not at the airport twenty kilometres away.
MDX of this sample
<HeroCover
title="Weather that pays off"
highlight="in the field, not on a grid cell"
description="A station you install in an hour and forget about for a season. Frost, wind and leaf wetness measured inside the crop, not at the airport twenty kilometres away."
image="photo-wide-01.jpg"
primaryText="Order a station"
primaryHref="/stations/"
secondaryText="How it works"
secondaryHref="/how-it-works/"
/>
Every field on one screen
One dashboard for one orchard or forty. No buttons you will never press.
MDX of this sample
<HeroCover
title="Every field on one screen"
description="One dashboard for one orchard or forty. No buttons you will never press."
image="photo-wide-02.jpg"
overlapNext={false}
primaryText="Book a demo"
primaryHref="/demo/"
/>Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| title | string | yes | the headline, one line | |
| highlight | string | a second line of the headline, painted with the brand gradient | ||
| description | string | the pitch under the headline, one or two sentences | ||
| image | string | file name in images/, landscape; cropped to fill the section | ||
| overlapNext | boolean | true | keep room at the bottom for a <FeatureCards overlap> row; false when nothing hangs over | |
| primaryText | string | text of the solid brand button; omit to hide the button | ||
| primaryHref | string | '#' | link of the primary button, e.g. "/contacts/" or "#contacts" | |
| secondaryText | string | text of the second, translucent button | ||
| secondaryHref | string | '#' | link of the secondary button |
Source apps/www/src/sections/HeroCover.astro @ gitt.one
---
/**
* HeroCover — the first screen: a full-width photo under the brand gradient,
* the title, pitch and buttons centered on top of it.
*
* Use for: a landing that opens with a wide, atmospheric photo (a landscape, a
* workplace, a team) and one short promise.
* Not for: a product shot that must stay whole (<HeroSplit
* imageFit="contain">); a page that opens with words alone (<HeroText>).
* Children: optional markdown between the tags, rendered under the description
* and above the buttons. No sub-block tags.
* Picture: LANDSCAPE. It is cropped to fill the section and tinted with the
* brand colour, so it must not carry text or a logo. Without `image` the
* section is a plain brand-coloured band.
* Follow-up: by default the bottom keeps room for a <FeatureCards overlap> row
* that hangs over the edge. Set overlapNext={false} when the next section is
* anything else, or the hero ends with an empty band.
* Buttons: a button appears only when its text is given; primary is the solid
* brand button, secondary the translucent one.
*/
import { Image } from 'astro:assets';
import { resolveImage } from '../lib/images';
import Button from './_Button.astro';
interface Props {
/** the headline, one line */
title: string;
/** a second line of the headline, painted with the brand gradient */
highlight?: string;
/** the pitch under the headline, one or two sentences */
description?: string;
/** file name in images/, landscape; cropped to fill the section */
image?: string;
/** keep room at the bottom for a <FeatureCards overlap> row; false when nothing hangs over */
overlapNext?: boolean;
/** text of the solid brand button; omit to hide the button */
primaryText?: string;
/** link of the primary button, e.g. "/contacts/" or "#contacts" */
primaryHref?: string;
/** text of the second, translucent button */
secondaryText?: string;
/** link of the secondary button */
secondaryHref?: string;
}
const { title, highlight, description, image: imageName, overlapNext = true, primaryText, primaryHref = '#', secondaryText, secondaryHref = '#' } = Astro.props;
const image = imageName ? await resolveImage(imageName) : undefined;
---
<section class:list={['relative bg-primary-900', overlapNext && 'pb-32']}>
{image && (
<div class="absolute inset-0">
<Image src={image} alt="" widths={[400, 840, 1280, 1680]} loading="eager" fetchpriority="high" class="h-full w-full object-cover" />
<div class="absolute inset-0 bg-gradient-to-r from-primary-800 to-primary-alt-700 mix-blend-multiply" aria-hidden="true" />
</div>
)}
<div class="relative mx-auto max-w-7xl px-4 py-24 text-center sm:px-6 sm:py-32 lg:px-8">
<h1 class="text-4xl font-extrabold tracking-tight text-white md:text-5xl lg:text-6xl">
{title}
{highlight && <span class="block bg-gradient-to-r from-primary-200 to-primary-alt-300 bg-clip-text text-transparent">{highlight}</span>}
</h1>
{description && <p class="mx-auto mt-6 max-w-3xl text-xl text-primary-100">{description}</p>}
<slot />
{(primaryText || secondaryText) && (
<div class="mt-10 flex flex-wrap justify-center gap-4">
{primaryText && <Button href={primaryHref}>{primaryText}</Button>}
{secondaryText && <Button href={secondaryHref} kind="secondary" onDark>{secondaryText}</Button>}
</div>
)}
</div>
</section>Source links point to engine-astro@7b686388. Samples are demo content: the components are the real ones, the copy and the pictures are made up.