Spiral wordmark 01
A features column at the start and three link columns at the end, social icons and the copyright, then a spiral mark and a giant wordmark across the full width.
Last updated
---
/**
* Spiral wordmark 01: A features column at the start and three link columns at the end, social icons and the copyright, then a spiral mark and a giant wordmark across the full width.
*
* @block footers
* @order 58
*/
import Section from '@/components/apogee/Section/Section.astro'
import Link from '@/components/apogee/Link/Link.astro'
import { socialIcons, type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {}
const {
brand = 'notebrook',
columns = [
{ heading: 'Features', links: [{ label: 'Notepad', href: '#' }, { label: 'Chat', href: '#' }, { label: 'Mobile', href: '#' }] },
{ heading: 'Product', links: [{ label: 'Pricing', href: '#' }, { label: 'Enterprise', href: '#' }, { label: 'Integrations', href: '#' }, { label: 'Notepad or notetaker', href: '#' }, { label: 'For sales', href: '#' }, { label: 'For product teams', href: '#' }, { label: 'Explore more…', href: '#' }] },
{ heading: 'Company', links: [{ label: 'Customers', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Press', href: '#' }, { label: 'Events', href: '#' }, { label: 'Startup programme', href: '#' }, { label: 'Student programme', href: '#' }] },
{ heading: 'Resources', links: [{ label: 'Blog', href: '#' }, { label: 'Security', href: '#' }, { label: 'Transparency', href: '#' }, { label: 'Help centre', href: '#' }, { label: 'Status', href: '#' }, { label: 'Affiliates', href: '#' }, { label: 'Contact us', href: '#' }, { label: 'Terms', href: '#' }, { label: 'Privacy', href: '#' }, { label: 'Licence', href: '#' }] },
],
copyright = '© Notebrook, Inc. 2026',
social = [
{ label: 'Community', href: '#', icon: 'users' },
{ label: 'Updates', href: '#', icon: 'at-sign' },
{ label: 'Videos', href: '#', icon: 'video' },
],
} = Astro.props
---
<Section as="footer" spacing="large">
<div class="grid gap-10 md:grid-cols-[1fr_auto]">
{columns.slice(0, 1).map((c) => (
<nav aria-label={c.heading}>
<p class="text-2xl">{c.heading}</p>
<ul class="mt-4 flex list-none flex-col gap-2 p-0 text-sm">{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>
</nav>
))}
<div class="grid grid-cols-2 gap-10 sm:grid-cols-3">
{columns.slice(1).map((c) => (
<nav aria-label={c.heading}>
<p class="text-2xl">{c.heading}</p>
<ul class="mt-4 flex list-none flex-col gap-2 p-0 text-sm">{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>
</nav>
))}
</div>
</div>
<div class="mt-12 flex items-center justify-between gap-4 text-sm text-neutral-faded">
{social && <ul class="flex list-none gap-4 p-0">{social.map((s) => { const Icon = socialIcons[s.icon]; return <li><Link href={s.href} color="neutral" underline="none" aria-label={s.label} class="text-neutral-faded hover:text-neutral"><Icon class="size-5" aria-hidden="true" /></Link></li> })}</ul>}
{copyright && <p>{copyright}</p>}
</div>
<div class="@container mt-16"><p class="flex items-center gap-[0.15em] whitespace-nowrap text-[16.6cqi] font-black leading-none tracking-tight" aria-hidden="true">
<svg viewBox="-8 -8 116 116" class="h-[1.05em] shrink-0" fill="none" stroke="currentColor" stroke-width="13" stroke-linecap="round"><path d="M88 22A44 44 0 1 0 92 56C90 76 72 86 56 84S28 66 32 52s20-20 30-14 8 18 0 20" /></svg>
{brand}
</p></div>
</Section>
Show codeHide code
---
/**
* Spiral wordmark 01: A features column at the start and three link columns at the end, social icons and the copyright, then a spiral mark and a giant wordmark across the full width.
*
* @block footers
* @order 58
*/
import Section from '@/components/apogee/Section/Section.astro'
import Link from '@/components/apogee/Link/Link.astro'
import { socialIcons, type FooterContent } from '@/components/apogee/sections/_shared/footers.ts'
/** @composable */
interface Props extends FooterContent {}
const {
brand = 'notebrook',
columns = [
{ heading: 'Features', links: [{ label: 'Notepad', href: '#' }, { label: 'Chat', href: '#' }, { label: 'Mobile', href: '#' }] },
{ heading: 'Product', links: [{ label: 'Pricing', href: '#' }, { label: 'Enterprise', href: '#' }, { label: 'Integrations', href: '#' }, { label: 'Notepad or notetaker', href: '#' }, { label: 'For sales', href: '#' }, { label: 'For product teams', href: '#' }, { label: 'Explore more…', href: '#' }] },
{ heading: 'Company', links: [{ label: 'Customers', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Press', href: '#' }, { label: 'Events', href: '#' }, { label: 'Startup programme', href: '#' }, { label: 'Student programme', href: '#' }] },
{ heading: 'Resources', links: [{ label: 'Blog', href: '#' }, { label: 'Security', href: '#' }, { label: 'Transparency', href: '#' }, { label: 'Help centre', href: '#' }, { label: 'Status', href: '#' }, { label: 'Affiliates', href: '#' }, { label: 'Contact us', href: '#' }, { label: 'Terms', href: '#' }, { label: 'Privacy', href: '#' }, { label: 'Licence', href: '#' }] },
],
copyright = '© Notebrook, Inc. 2026',
social = [
{ label: 'Community', href: '#', icon: 'users' },
{ label: 'Updates', href: '#', icon: 'at-sign' },
{ label: 'Videos', href: '#', icon: 'video' },
],
} = Astro.props
---
<Section as="footer" spacing="large">
<div class="grid gap-10 md:grid-cols-[1fr_auto]">
{columns.slice(0, 1).map((c) => (
<nav aria-label={c.heading}>
<p class="text-2xl">{c.heading}</p>
<ul class="mt-4 flex list-none flex-col gap-2 p-0 text-sm">{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>
</nav>
))}
<div class="grid grid-cols-2 gap-10 sm:grid-cols-3">
{columns.slice(1).map((c) => (
<nav aria-label={c.heading}>
<p class="text-2xl">{c.heading}</p>
<ul class="mt-4 flex list-none flex-col gap-2 p-0 text-sm">{c.links.map((l) => <li><Link href={l.href} color="neutral" underline="hover">{l.label}</Link></li>)}</ul>
</nav>
))}
</div>
</div>
<div class="mt-12 flex items-center justify-between gap-4 text-sm text-neutral-faded">
{social && <ul class="flex list-none gap-4 p-0">{social.map((s) => { const Icon = socialIcons[s.icon]; return <li><Link href={s.href} color="neutral" underline="none" aria-label={s.label} class="text-neutral-faded hover:text-neutral"><Icon class="size-5" aria-hidden="true" /></Link></li> })}</ul>}
{copyright && <p>{copyright}</p>}
</div>
<div class="@container mt-16"><p class="flex items-center gap-[0.15em] whitespace-nowrap text-[16.6cqi] font-black leading-none tracking-tight" aria-hidden="true">
<svg viewBox="-8 -8 116 116" class="h-[1.05em] shrink-0" fill="none" stroke="currentColor" stroke-width="13" stroke-linecap="round"><path d="M88 22A44 44 0 1 0 92 56C90 76 72 86 56 84S28 66 32 52s20-20 30-14 8 18 0 20" /></svg>
{brand}
</p></div>
</Section>Add
npx @ava-ui/apogee add footers/spiral-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.