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

Open block
Show 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.