FooterColumn
ImplementedFooter column with title + optional accent underline + vertical link list. Column sizing is owned by the parent Footer organism.
patterns/molecules/footercolumn.htmlOne labelled navigation column for footer contexts: a semantic <nav aria-label> with a heading, an optional ADR-031 decorative accent underline, and a list of anchor links. All strings are caller-owned, so the molecule is bilingual-safe by construction. Column sizing is owned by the parent Footer organism's CSS grid.
FooterColumn
Navigation molecule (Footer family)
Renders title + links as a nav landmark with an overline heading. The heading element defaults to <h2> and is overridable via headingAs for embedded document outlines — the visual scale stays pinned to the overline treatment regardless of level.
This component supports light and dark mode.
Usage
import { FooterColumn } from '@epasslive/design-system'
// Default heading level (<h2>) — as composed by the Footer organism.
<FooterColumn
title="Browse"
accent="teal" // events identity (ADR-031)
links={[
{ label: 'Events', href: '/events' },
{ label: 'Venues', href: '/venues' },
]}
/>
// Embedded context — demote the heading so it nests under an existing h2
// instead of injecting a sibling h2 into the page outline.
<FooterColumn
title="Help"
accent="indigo" // support identity (ADR-031)
headingAs={3}
links={[{ label: 'FAQ', href: '/faq' }]}
/>Heading levels
- Default is
<h2>— correct for a standalone footer landmark. The [slug] docs outline is H1 (page) → H2 (sections), so this demo's second column usesheadingAs={3}. - The visual scale never follows the level: the overline treatment (
text-ep-sm uppercase tracking-wider) is kept at every level, mirroring the Heading atom's decoupledas/sizecontract. - Pick the level from the surrounding document outline, not from the desired visual size.
Accessibility
- Semantic
<nav aria-label>per column — each of several columns on a page is an independently labelled landmark; the label falls back to the visible title. role="list"on the<ul>restores list semantics under Tailwind preflight.- Every anchor carries
min-h-[var(--ep-tap-min)](44px, WCAG 2.5.5) and afocus-visiblering (ring-ep-teal+ring-offset-ep-bg). - The accent underline is
aria-hidden— decorative only (ADR-031 §4.3); the heading carries the semantics.
i18n contract
The molecule contributes zero strings: title, links[].label/href, and ariaLabel are all consumer props. The storefront consumer (SiteFooter) pulls every string from useTranslations("Footer"). Note: the heading carries truncate — very long FR titles can visually clip in narrow columns (screen readers still read the full text).
Composition
- Composes the AccentUnderline atom for the decorative accent (ADR-031 identity mapping: events=teal, support=indigo, company=amber, newsletter=pink).
- Composed by the Footer organism — one FooterColumn per navigation column. Column sizing and the responsive grid are owned by the organism, not this molecule.
- Links are currently raw
<a>anchors with the DS focus/tap recipe. Consolidation onto the TextLink atom (external href handling:rel="noopener noreferrer", new-tab announcement) is planned behind an ADR — until then, prefer internal hrefs or addrelat the consumer. - Boundary: NavGroup is deprecated (superseded by the sidebar) — FooterColumn is the live molecule for labelled link columns in footer/nav contexts.
Props
title*stringHeading rendered above the link list. Also used as the nav label when ariaLabel is omitted.
links*ReadonlyArray<{ label: string; href: string }>Links rendered in the column. Every string is caller-owned (i18n contract).
ariaLabelstringAccessible name for the inner <nav>. Falls back to the visible title.
accent'teal' | 'indigo' | 'amber' | 'pink'Decorative AccentUnderline beneath the heading. Must attach to a stable identity per ADR-031 §3 (events=teal, support=indigo, company=amber, newsletter=pink) — never index % 4 cycling.
headingAs1 | 2 | 3 | 4 | 5 | 62Semantic heading level for the column title. Default 2 renders <h2>; pass 3 when embedding the column under an existing h2 section. Visual scale is decoupled — the overline treatment is kept at every level (Heading atom as/size contract).
idstringOptional id for the inner nav. Auto-generated when omitted.
classNamestringExtra utility classes appended to the nav.
Props
ariaLabelstringvisible titleAccessible name for the inner <nav>; falls back to the visible title.
titlestring—Heading rendered above the link list (also the nav label fallback).
linksReadonlyArray<{ label: string; href: string }>—Link list — strings are caller-owned (bilingual-safe by construction).
accent'teal' | 'indigo' | 'amber' | 'pink'—Decorative AccentUnderline below the heading — identity-stable per ADR-031 (events=teal, support=indigo, company=amber, newsletter=pink).
headingAsHeadingLevel2 (<h2>)Semantic heading level for the title; visual scale stays pinned to the overline treatment regardless of level (use h3 in embedded contexts).
idstringautoOptional id for the inner nav; auto-generated when omitted.
classNamestring—Extra utility classes appended to the nav.
<FooterColumn />Accessibility
ARIA
1 ruleType
1 ruleUsage
Import
Example 1
Example 2
Anti-patterns
— Do not cycle accents by index — accents are identity-stable per column (ADR-031)
— Do not hardcode column strings — pull labels from your i18n Footer namespace