Card over wordmark 01
A page-coloured card with a rounded bottom holding a two-tone heading, a button, three link columns and the copyright, over a giant wordmark on a brand-tinted gradient.
Last updated
---
/**
* Card over wordmark 01: A page-coloured card with a rounded bottom holding a two-tone heading, a button, three link columns and the copyright, over a giant wordmark on a brand-tinted gradient.
*
* @block footers
* @order 54
*/
import { Flower2 } 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 { accentRuns } from '@/components/apogee/sections/_shared/spine.ts'
import { type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {}
const {
brand = 'Pawsley',
heading = 'AI that runs the *clinic front desk*',
primaryAction = { label: 'Get started', href: '#' },
columns = [
{ heading: 'Company', links: [{ label: 'Call us', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Blog', href: '#' }] },
{ heading: 'Social', links: [{ label: 'Photos', href: '#' }, { label: 'Updates', href: '#' }, { label: 'Community', href: '#' }] },
{ heading: 'Legal', links: [{ label: 'Privacy policy', href: '#' }, { label: 'Terms of service', href: '#' }] },
],
copyright = '© 2026 Pawsley, Inc. All rights reserved.\nMade in Portmere.',
} = Astro.props
---
<Section as="footer" spacing="none" container={false} class="overflow-hidden" style="background: linear-gradient(to bottom, color-mix(in oklab, var(--background-primary) 10%, var(--background-page)), color-mix(in oklab, var(--background-primary) 28%, var(--background-page)))">
<div class="rounded-b-[3rem] bg-page px-gutter pb-12 pt-(--spacing-section-lg) shadow-sm">
<div class="mx-auto grid max-w-7xl gap-12 lg:grid-cols-2">
<div class="flex flex-col items-start gap-8">
{heading && <Heading as="h2" size="h1" class="font-normal">{accentRuns(heading).map((r) => (r.accent ? <span class="block italic">{r.text}</span> : r.text))}</Heading>}
{primaryAction && <Button href={primaryAction.href}>{primaryAction.label}</Button>}
</div>
<div class="flex flex-col gap-16">
<div class="grid grid-cols-3 gap-6">
{columns.map((c) => (
<nav aria-label={c.heading}>
<p class="text-neutral-faded">{c.heading}</p>
<ul class="mt-2 flex list-none flex-col gap-1.5 p-0">{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>
</nav>
))}
</div>
<div class="flex flex-col gap-2 font-mono text-sm">
<Flower2 class="size-9" aria-hidden="true" />
{copyright && <p>{copyright.split('\n').map((line, i) => <>{i > 0 && <br />}{line}</>)}</p>}
</div>
</div>
</div>
</div>
<div class="@container px-gutter pt-6">
<p class="whitespace-nowrap text-[29.6cqi] font-medium leading-[0.85] tracking-tight text-(--background-page) [margin-bottom:-0.1em]" aria-hidden="true">{brand}</p>
</div>
</Section>
Show codeHide code
---
/**
* Card over wordmark 01: A page-coloured card with a rounded bottom holding a two-tone heading, a button, three link columns and the copyright, over a giant wordmark on a brand-tinted gradient.
*
* @block footers
* @order 54
*/
import { Flower2 } 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 { accentRuns } from '@/components/apogee/sections/_shared/spine.ts'
import { type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {}
const {
brand = 'Pawsley',
heading = 'AI that runs the *clinic front desk*',
primaryAction = { label: 'Get started', href: '#' },
columns = [
{ heading: 'Company', links: [{ label: 'Call us', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Blog', href: '#' }] },
{ heading: 'Social', links: [{ label: 'Photos', href: '#' }, { label: 'Updates', href: '#' }, { label: 'Community', href: '#' }] },
{ heading: 'Legal', links: [{ label: 'Privacy policy', href: '#' }, { label: 'Terms of service', href: '#' }] },
],
copyright = '© 2026 Pawsley, Inc. All rights reserved.\nMade in Portmere.',
} = Astro.props
---
<Section as="footer" spacing="none" container={false} class="overflow-hidden" style="background: linear-gradient(to bottom, color-mix(in oklab, var(--background-primary) 10%, var(--background-page)), color-mix(in oklab, var(--background-primary) 28%, var(--background-page)))">
<div class="rounded-b-[3rem] bg-page px-gutter pb-12 pt-(--spacing-section-lg) shadow-sm">
<div class="mx-auto grid max-w-7xl gap-12 lg:grid-cols-2">
<div class="flex flex-col items-start gap-8">
{heading && <Heading as="h2" size="h1" class="font-normal">{accentRuns(heading).map((r) => (r.accent ? <span class="block italic">{r.text}</span> : r.text))}</Heading>}
{primaryAction && <Button href={primaryAction.href}>{primaryAction.label}</Button>}
</div>
<div class="flex flex-col gap-16">
<div class="grid grid-cols-3 gap-6">
{columns.map((c) => (
<nav aria-label={c.heading}>
<p class="text-neutral-faded">{c.heading}</p>
<ul class="mt-2 flex list-none flex-col gap-1.5 p-0">{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>
</nav>
))}
</div>
<div class="flex flex-col gap-2 font-mono text-sm">
<Flower2 class="size-9" aria-hidden="true" />
{copyright && <p>{copyright.split('\n').map((line, i) => <>{i > 0 && <br />}{line}</>)}</p>}
</div>
</div>
</div>
</div>
<div class="@container px-gutter pt-6">
<p class="whitespace-nowrap text-[29.6cqi] font-medium leading-[0.85] tracking-tight text-(--background-page) [margin-bottom:-0.1em]" aria-hidden="true">{brand}</p>
</div>
</Section>Add
npx @ava-ui/apogee add footers/card-over-wordmark-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.