Tagline columns 01
The logo and a two-tone tagline beside three link columns and a let's-talk column with arrow links and social icons, then the copyright and legal links.
Last updated
---
/**
* Tagline columns 01: The logo and a two-tone tagline beside three link columns and a let's-talk column with arrow links and social icons, then the copyright and legal links.
*
* @block footers
* @order 43
*/
import { ArrowUpRight, Orbit } from '@lucide/astro'
import Section from '@/components/apogee/Section/Section.astro'
import FeaturedIcon from '@/components/apogee/FeaturedIcon/FeaturedIcon.astro'
import Link from '@/components/apogee/Link/Link.astro'
import { accentRuns, type Action } from '@/components/apogee/sections/_shared/spine.ts'
import { socialIcons, type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {
/** The arrow links in the let's-talk column. @category content */
contactLinks?: Action[] | null
}
const {
brand = 'Example',
tagline = 'Good judgement.*Better marketing.*',
columns = [
{ heading: 'Platform', links: [{ label: 'Platform', href: '#' }, { label: 'Use cases', href: '#' }, { label: 'Apps and integrations', href: '#' }] },
{ heading: 'Services', links: [{ label: 'Creative team', href: '#' }, { label: 'Growth team', href: '#' }, { label: 'Custom setup', href: '#' }, { label: 'Pricing', href: '#' }] },
{ heading: 'Company', links: [{ label: 'About', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Become a partner', href: '#' }, { label: 'News', href: '#' }] },
],
copyright = '© 2026 Example',
legal = [{ label: 'Status', href: '#' }, { label: 'Privacy', href: '#' }, { label: 'Terms', href: '#' }],
social = [
{ label: 'Photos', href: '#', icon: 'camera' },
{ label: 'Profile', href: '#', icon: 'at-sign' },
],
contactLinks = [{ label: 'Book a demo', href: '#' }, { label: 'Sign in', href: '#' }],
} = Astro.props
---
<Section as="footer" spacing="medium">
<div class="grid gap-12 lg:grid-cols-[2fr_repeat(4,1fr)]">
<div class="flex flex-col gap-4">
<Link href="/" color="inherit" underline="none" class="inline-flex items-center gap-2 font-semibold"><FeaturedIcon theme="solid" color="primary" size="small"><Orbit /></FeaturedIcon>{brand}</Link>
{tagline && <p class="text-2xl leading-tight tracking-tight">{accentRuns(tagline).map((r) => (r.accent ? <span class="block text-neutral-faded">{r.text}</span> : r.text))}</p>}
</div>
{columns.map((c) => (
<nav aria-label={c.heading}>
<p class="text-sm text-neutral-faded">{c.heading}</p>
<ul class="mt-4 flex list-none flex-col gap-4 p-0">
{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}
</ul>
</nav>
))}
<nav aria-label="Get in touch">
<p class="text-sm text-neutral-faded">Let’s talk</p>
<ul class="mt-4 flex list-none flex-col gap-4 p-0">
{contactLinks && contactLinks.map((l) => <li><Link href={l.href} color="neutral" underline="hover" class="inline-flex items-center gap-1">{l.label}<ArrowUpRight class="size-3.5" aria-hidden="true" /></Link></li>)}
{social && <li class="flex gap-4">
{social.map((s) => { const Icon = socialIcons[s.icon]; return <Link href={s.href} color="neutral" underline="none" aria-label={s.label}><Icon class="size-5" aria-hidden="true" /></Link> })}
</li>}
</ul>
</nav>
</div>
<div class="mt-12 flex flex-col gap-4 border-t border-neutral-faded pt-6 text-sm text-neutral-faded md:flex-row md:justify-between">
<p>{copyright}</p>
{legal && <ul class="flex list-none gap-6 p-0">{legal.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>}
</div>
</Section>
Show codeHide code
---
/**
* Tagline columns 01: The logo and a two-tone tagline beside three link columns and a let's-talk column with arrow links and social icons, then the copyright and legal links.
*
* @block footers
* @order 43
*/
import { ArrowUpRight, Orbit } from '@lucide/astro'
import Section from '@/components/apogee/Section/Section.astro'
import FeaturedIcon from '@/components/apogee/FeaturedIcon/FeaturedIcon.astro'
import Link from '@/components/apogee/Link/Link.astro'
import { accentRuns, type Action } from '@/components/apogee/sections/_shared/spine.ts'
import { socialIcons, type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {
/** The arrow links in the let's-talk column. @category content */
contactLinks?: Action[] | null
}
const {
brand = 'Example',
tagline = 'Good judgement.*Better marketing.*',
columns = [
{ heading: 'Platform', links: [{ label: 'Platform', href: '#' }, { label: 'Use cases', href: '#' }, { label: 'Apps and integrations', href: '#' }] },
{ heading: 'Services', links: [{ label: 'Creative team', href: '#' }, { label: 'Growth team', href: '#' }, { label: 'Custom setup', href: '#' }, { label: 'Pricing', href: '#' }] },
{ heading: 'Company', links: [{ label: 'About', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Become a partner', href: '#' }, { label: 'News', href: '#' }] },
],
copyright = '© 2026 Example',
legal = [{ label: 'Status', href: '#' }, { label: 'Privacy', href: '#' }, { label: 'Terms', href: '#' }],
social = [
{ label: 'Photos', href: '#', icon: 'camera' },
{ label: 'Profile', href: '#', icon: 'at-sign' },
],
contactLinks = [{ label: 'Book a demo', href: '#' }, { label: 'Sign in', href: '#' }],
} = Astro.props
---
<Section as="footer" spacing="medium">
<div class="grid gap-12 lg:grid-cols-[2fr_repeat(4,1fr)]">
<div class="flex flex-col gap-4">
<Link href="/" color="inherit" underline="none" class="inline-flex items-center gap-2 font-semibold"><FeaturedIcon theme="solid" color="primary" size="small"><Orbit /></FeaturedIcon>{brand}</Link>
{tagline && <p class="text-2xl leading-tight tracking-tight">{accentRuns(tagline).map((r) => (r.accent ? <span class="block text-neutral-faded">{r.text}</span> : r.text))}</p>}
</div>
{columns.map((c) => (
<nav aria-label={c.heading}>
<p class="text-sm text-neutral-faded">{c.heading}</p>
<ul class="mt-4 flex list-none flex-col gap-4 p-0">
{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}
</ul>
</nav>
))}
<nav aria-label="Get in touch">
<p class="text-sm text-neutral-faded">Let’s talk</p>
<ul class="mt-4 flex list-none flex-col gap-4 p-0">
{contactLinks && contactLinks.map((l) => <li><Link href={l.href} color="neutral" underline="hover" class="inline-flex items-center gap-1">{l.label}<ArrowUpRight class="size-3.5" aria-hidden="true" /></Link></li>)}
{social && <li class="flex gap-4">
{social.map((s) => { const Icon = socialIcons[s.icon]; return <Link href={s.href} color="neutral" underline="none" aria-label={s.label}><Icon class="size-5" aria-hidden="true" /></Link> })}
</li>}
</ul>
</nav>
</div>
<div class="mt-12 flex flex-col gap-4 border-t border-neutral-faded pt-6 text-sm text-neutral-faded md:flex-row md:justify-between">
<p>{copyright}</p>
{legal && <ul class="flex list-none gap-6 p-0">{legal.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>}
</div>
</Section>Add
npx @ava-ui/apogee add footers/tagline-columns-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.