Image banner 01
A photo banner with a heading and button, three link columns, then a framed bottom bar with the copyright, a centred mark and a social link. Always dark.
Last updated
---
/**
* Image banner 01: A photo banner with a heading and button, three link columns, then a framed bottom bar with the copyright, a centred mark and a social link. Always dark.
*
* @block footers
* @order 41
*/
import { Orbit } from '@lucide/astro'
import Section from '@/components/apogee/Section/Section.astro'
import Heading from '@/components/apogee/Heading/Heading.astro'
import Button from '@/components/apogee/Button/Button.astro'
import Link from '@/components/apogee/Link/Link.astro'
import { plain, srcUrl, type Action, type Media } from '@/components/apogee/sections/_shared/spine.ts'
import { type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {
/** The banner photo behind the heading. @category content */
media?: Media | null
/** The text link at the end of the bottom bar. @category content */
socialLink?: Action | null
}
const {
brand = 'Northwave',
heading = 'Bring AI into the core of your operations',
primaryAction = { label: 'Request a demo', href: '#' },
columns = [
{ heading: 'Platform', links: [{ label: 'Consolidate', href: '#' }, { label: 'Build', href: '#' }, { label: 'Control', href: '#' }, { label: 'Scale', href: '#' }, { label: 'Integrations', href: '#' }, { label: 'Security', href: '#' }] },
{ heading: 'Solutions', links: [{ label: 'Aerospace and defence', href: '#' }, { label: 'Chemicals', href: '#' }, { label: 'Energy and commodities', href: '#' }, { label: 'Engineering', href: '#' }, { label: 'Shipping', href: '#' }, { label: 'Telecoms', href: '#' }] },
{ heading: 'Company', links: [{ label: 'About', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Terms of service', href: '#' }, { label: 'Cookie policy', href: '#' }] },
],
copyright = '© 2026 Northwave',
media = { src: 'https://picsum.photos/id/1018/1800/700', alt: '' },
socialLink = { label: 'Social', href: '#' },
} = Astro.props
---
<Section as="footer" spacing="small" containerWidth="full" theme="dark">
<div class="relative isolate flex min-h-80 flex-col justify-between gap-10 overflow-hidden rounded-md p-8 md:min-h-96 md:p-10">
{media && <img src={srcUrl(media.src)} alt={media.alt} loading="lazy" class="absolute inset-0 -z-10 size-full object-cover" />}
<div class="absolute inset-0 -z-10 bg-[linear-gradient(to_right,color-mix(in_oklab,var(--background-page)_80%,transparent),transparent_70%)]" aria-hidden="true"></div>
{heading && <Heading as="h2" size="h1" class="max-w-xl font-normal text-balance">{plain(heading)}</Heading>}
{primaryAction && <Button href={primaryAction.href} size="large" color="neutral" variant="outline" class="self-start rounded-none!">{primaryAction.label}</Button>}
</div>
<div class="grid grid-cols-2 gap-10 px-2 py-16 md:grid-cols-4 md:px-8 md:py-24">
{columns.map((c) => (
<nav aria-label={c.heading}>
<p class="font-mono text-xs uppercase tracking-widest text-neutral-faded">{c.heading}</p>
<ul class="mt-6 flex list-none flex-col gap-3 p-0">
{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}
</ul>
</nav>
))}
</div>
<!-- Bottom bar framed by a top line with short end ticks. -->
<div class="relative grid grid-cols-[1fr_auto_1fr] items-center gap-4 border-y border-neutral-faded px-4 py-6 font-mono text-xs uppercase tracking-widest text-neutral-faded md:px-8">
<span class="absolute -top-3 start-0 h-3 border-s border-neutral-faded" aria-hidden="true"></span>
<span class="absolute -top-3 end-0 h-3 border-e border-neutral-faded" aria-hidden="true"></span>
<p>{copyright}</p>
<Link href="/" color="inherit" underline="none" aria-label={`${brand} home`}><Orbit class="size-6 text-neutral" aria-hidden="true" /></Link>
{socialLink && <Link href={socialLink.href} color="inherit" underline="hover" class="justify-self-end">{socialLink.label}</Link>}
</div>
</Section>
Show codeHide code
---
/**
* Image banner 01: A photo banner with a heading and button, three link columns, then a framed bottom bar with the copyright, a centred mark and a social link. Always dark.
*
* @block footers
* @order 41
*/
import { Orbit } from '@lucide/astro'
import Section from '@/components/apogee/Section/Section.astro'
import Heading from '@/components/apogee/Heading/Heading.astro'
import Button from '@/components/apogee/Button/Button.astro'
import Link from '@/components/apogee/Link/Link.astro'
import { plain, srcUrl, type Action, type Media } from '@/components/apogee/sections/_shared/spine.ts'
import { type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {
/** The banner photo behind the heading. @category content */
media?: Media | null
/** The text link at the end of the bottom bar. @category content */
socialLink?: Action | null
}
const {
brand = 'Northwave',
heading = 'Bring AI into the core of your operations',
primaryAction = { label: 'Request a demo', href: '#' },
columns = [
{ heading: 'Platform', links: [{ label: 'Consolidate', href: '#' }, { label: 'Build', href: '#' }, { label: 'Control', href: '#' }, { label: 'Scale', href: '#' }, { label: 'Integrations', href: '#' }, { label: 'Security', href: '#' }] },
{ heading: 'Solutions', links: [{ label: 'Aerospace and defence', href: '#' }, { label: 'Chemicals', href: '#' }, { label: 'Energy and commodities', href: '#' }, { label: 'Engineering', href: '#' }, { label: 'Shipping', href: '#' }, { label: 'Telecoms', href: '#' }] },
{ heading: 'Company', links: [{ label: 'About', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Terms of service', href: '#' }, { label: 'Cookie policy', href: '#' }] },
],
copyright = '© 2026 Northwave',
media = { src: 'https://picsum.photos/id/1018/1800/700', alt: '' },
socialLink = { label: 'Social', href: '#' },
} = Astro.props
---
<Section as="footer" spacing="small" containerWidth="full" theme="dark">
<div class="relative isolate flex min-h-80 flex-col justify-between gap-10 overflow-hidden rounded-md p-8 md:min-h-96 md:p-10">
{media && <img src={srcUrl(media.src)} alt={media.alt} loading="lazy" class="absolute inset-0 -z-10 size-full object-cover" />}
<div class="absolute inset-0 -z-10 bg-[linear-gradient(to_right,color-mix(in_oklab,var(--background-page)_80%,transparent),transparent_70%)]" aria-hidden="true"></div>
{heading && <Heading as="h2" size="h1" class="max-w-xl font-normal text-balance">{plain(heading)}</Heading>}
{primaryAction && <Button href={primaryAction.href} size="large" color="neutral" variant="outline" class="self-start rounded-none!">{primaryAction.label}</Button>}
</div>
<div class="grid grid-cols-2 gap-10 px-2 py-16 md:grid-cols-4 md:px-8 md:py-24">
{columns.map((c) => (
<nav aria-label={c.heading}>
<p class="font-mono text-xs uppercase tracking-widest text-neutral-faded">{c.heading}</p>
<ul class="mt-6 flex list-none flex-col gap-3 p-0">
{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}
</ul>
</nav>
))}
</div>
<!-- Bottom bar framed by a top line with short end ticks. -->
<div class="relative grid grid-cols-[1fr_auto_1fr] items-center gap-4 border-y border-neutral-faded px-4 py-6 font-mono text-xs uppercase tracking-widest text-neutral-faded md:px-8">
<span class="absolute -top-3 start-0 h-3 border-s border-neutral-faded" aria-hidden="true"></span>
<span class="absolute -top-3 end-0 h-3 border-e border-neutral-faded" aria-hidden="true"></span>
<p>{copyright}</p>
<Link href="/" color="inherit" underline="none" aria-label={`${brand} home`}><Orbit class="size-6 text-neutral" aria-hidden="true" /></Link>
{socialLink && <Link href={socialLink.href} color="inherit" underline="hover" class="justify-self-end">{socialLink.label}</Link>}
</div>
</Section>Add
npx @ava-ui/apogee add footers/image-banner-01
Every piece of copy is a prop, with the sample copy as its default. Pass yours, or null to hide a part; see copy is props.