# Multi-column footer

> A site footer with a brand block, contact details and two to five headed link columns, each hung from one shared rule, over a small-print row with copyright and legal links.

- ID: `cmp_footer_multi_column_01`
- Slug: `footer-multi-column-01`
- Version: `1.0.0` (current)
- Status: published
- Published: 2026-09-30
- Updated: 2026-09-30
- Available versions: `1.0.0`
- Kind: section
- Primary category: `footers`
- Detail page: https://pagesugar.com/components/footer-multi-column-01
- Preview: https://pagesugar.com/preview/footer-multi-column-01

## Variants

| Variant | Label | Default | Artifact digest |
| --- | --- | --- | --- |
| `neutral` | Neutral | yes | `sha256-84650244f5c9b55ac40060c5b6d81794db89c97fb9ce14eab5033723139c4f44` |
| `dark` | Dark band | no | `sha256-1d042baf73b9433c82c8594956111e24d2dbca74c1b728c32a3964f602c31839` |
| `brand-tint` | Brand tint | no | `sha256-6a365f24a65a83a15b263bdb94377dfd6b5683958dea5b5d1704ffa1e0b617e9` |

## Runtime and compatibility

- Runtime: svelte
- Svelte: 5
- SvelteKit required: no (portable Svelte component)
- Tailwind CSS: 4
- SSR: supported
- Requires client-side JavaScript: no
- Integration level: presentational
- Appearance modes: light
- Suggested directory: `src/lib/components/footer-multi-column-01`

## Dependencies

No third-party runtime packages.

## Services

No external services required.

## Usage

Presentational only: every heading, link, contact line and small-print string is rendered as supplied. It does not include a newsletter form, supply social profiles, check that links resolve or work out the copyright year; pass the complete copyright text. No runtime packages beyond Svelte and Tailwind CSS.

Required props: `brand`, `columns`, `copyright`

```svelte
<script lang="ts">
	import FooterMultiColumn, {
		type FooterColumn
	} from '$lib/components/footer-multi-column-01/FooterMultiColumn.svelte';

	const columns: FooterColumn[] = [
		{
			heading: 'Product',
			links: [
				{ label: 'Features', href: '/features' },
				{ label: 'Pricing', href: '/pricing' }
			]
		},
		{
			heading: 'Company',
			links: [
				{ label: 'About', href: '/about' },
				{ label: 'Status', href: 'https://status.example.com', external: true }
			]
		}
	];
</script>

<FooterMultiColumn
	brand={{ name: 'Example Co', href: '/', tagline: 'What you do, in one plain sentence.' }}
	{columns}
	contact={{ email: 'hello@example.com', phone: '+44 20 7946 0000' }}
	legalLinks={[{ label: 'Privacy', href: '/privacy' }, { label: 'Terms', href: '/terms' }]}
	copyright="© 2026 Example Co Ltd."
	mobileBehaviour="disclosure"
/>
```

Limitations:

- Holds five columns a row at lg; a sixth column wraps to a second row.
- Columns with no links are skipped. With an empty columns array the navigation is omitted and the brand, contact and small print still render.
- In disclosure mode the links are rendered twice, once as disclosures below 640 px and once as headed lists from 640 px; CSS hides one copy, so assistive technology meets them once, but the markup is larger.
- Light appearance by default. The dark and brand-tint palettes retone it through its variables; no dark mode is declared or selected automatically.

## Usage guide

### Filling it in

Copy `FooterMultiColumn.svelte` into `src/lib/components/footer-multi-column-01/`. The types `FooterBrand`, `FooterColumn`, `FooterLink` and `FooterContact` are exported from its module script.

- `brand` is `{ name, href?, tagline? }`. Pass your mark through the `logo` snippet; it renders inside the brand link, before the name, so keep it `aria-hidden`.
- `columns` is the link groups in display order. Two to five read best. A link with `external: true` opens a new tab, shows an arrow and reads `newTabLabel` to screen readers; nothing else opens a new tab.
- `contact` renders in an `<address>`: address lines first, then the email and phone as `mailto:` and `tel:` links. Leave it out and no address renders.
- `copyright` is the whole string, year included. The component never computes the year, so the server and the browser always render the same text.
- `social` is your own snippet, rendered under the contact details. Give its list a name such as "Follow us".

### Layout

| Width       | `brandPlacement="start"` (default)               | `brandPlacement="top"`                                                       |
| ----------- | ------------------------------------------------ | ---------------------------------------------------------------------------- |
| under 1024  | Brand above, columns two to a row                | Brand above, columns two to a row                                            |
| 1024 and up | Brand on the start third, columns share the rest | Brand across the width, contact on the end third, columns share the full row |

Every group, the brand block included, hangs from one rule, so columns of different lengths still start on the same line. With `mobileBehaviour="disclosure"`, below 640 px each column folds into a native `<details>` with the heading as its summary; from 640 px the plain headed lists show instead.

### Retoning

| Variable                          | Default             | Draws                                          |
| --------------------------------- | ------------------- | ---------------------------------------------- |
| `--footer-multi-column-ink`       | `#18181b`           | Brand name, headings, link hover               |
| `--footer-multi-column-muted`     | `#52525b`           | Tagline, links, contact, small print           |
| `--footer-multi-column-rule`      | the ink value       | The rule each group hangs from                 |
| `--footer-multi-column-hairline`  | `rgb(0 0 0 / 0.08)` | Top edge, small-print divider, disclosure rows |
| `--footer-multi-column-accent`    | `#18181b`           | Focus ring, selection fill                     |
| `--footer-multi-column-on-accent` | `#ffffff`           | Selected text                                  |
| `--footer-multi-column-surface`   | `#ffffff`           | Background                                     |

A dark band:

```svelte
<div
	style="
		--footer-multi-column-surface: #09090b;
		--footer-multi-column-ink: #fafafa;
		--footer-multi-column-muted: #a1a1aa;
		--footer-multi-column-rule: #fafafa;
		--footer-multi-column-hairline: rgb(255 255 255 / 0.1);
		--footer-multi-column-accent: #fafafa;
		--footer-multi-column-on-accent: #18181b;
	"
>
	<FooterMultiColumn {brand} {columns} {copyright} />
</div>
```

## Props

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `brand` | `FooterBrand` | yes |  | { name, href?, tagline? }. The name links to href when given; the tagline sits under it at a readable measure. |
| `columns` | `FooterColumn[]` | yes |  | Link groups in display order, each { heading, links: { label, href, external? }\[\] }. Two to five read best; groups with no links are skipped. |
| `copyright` | `string` | yes |  | Complete copyright text for the small-print row, including the year. |
| `logo` | `Snippet` | no |  | Mark rendered before the brand name, inside its link. Keep it decorative (aria-hidden) since the name follows. |
| `contact` | `FooterContact` | no |  | { email?, phone?, phoneHref?, addressLines? } rendered in an address element with mailto: and tel: links. The tel: link dials the leading + and the digits before any extension unless phoneHref is given. Blank fields are skipped; with none left, no address renders. |
| `legalLinks` | `FooterLink[]` | no | `[]` | Policy links in the small-print row, after the copyright. |
| `social` | `Snippet` | no |  | Your own social links group, rendered under the contact details. |
| `headingLevel` | 2 \| 3 \| 4 | no | `2` | Heading level for the column headings. |
| `mobileBehaviour` | 'stack' \| 'disclosure' | no | `'stack'` | Below 640 px, stack the columns two to a row, or fold each into a native details/summary disclosure. |
| `brandPlacement` | 'start' \| 'top' | no | `'start'` | Brand block on the start third beside the columns at lg, or across the width above them with the contact on the end third. |
| `navLabel` | `string` | no | `'Footer'` | Accessible name of the navigation landmark holding the columns. |
| `legalLabel` | `string` | no | `'Legal'` | Accessible name of the legal links list. |
| `newTabLabel` | `string` | no | `'(opens in new tab)'` | Visually hidden text after each external link's label; translate it with the rest of the page. |

## Customization

Change content through props, retone the footer through seven --footer-multi-column-\* variables (accent, on-accent, ink, muted, rule, hairline, surface), and edit Tailwind classes in the source for spacing or column counts.

- Text: --footer-multi-column-ink sets the brand name, column headings and link hover; --footer-multi-column-muted sets the tagline, links, contact and small print. Keep muted at 4.5:1 against the surface.
- Rules: --footer-multi-column-rule draws the line every group hangs from (ink by default); --footer-multi-column-hairline draws the footer's top edge, the small-print divider and the disclosure dividers.
- Accent: --footer-multi-column-accent is the focus ring and the text-selection fill, with --footer-multi-column-on-accent as the selected text. Keep the accent at 3:1 against the surface and on-accent at 4.5:1 against the accent.
- Surface: --footer-multi-column-surface is the footer background.
- Dark band: surface #09090b, ink #fafafa, muted #a1a1aa, rule #fafafa, hairline #ffffff1a, accent #fafafa, on-accent #18181b. usage.md has the snippet.
- Brand tint: surface #eff6ff, rule #1e3a8a, hairline #1e3a8a1f, accent #1d4ed8, on-accent #ffffff; ink and muted stay zinc.
- Columns: the besideCols and topCols maps at the top of the script decide the lg column count; below lg two columns share a row.
- Headings: set headingLevel so the column headings fit your page outline.
- Copyright: pass the full string, including the year; the component does not compute it, so server and client renders always agree.

| Token | Public CSS variable |
| --- | --- |
| `accent` | `--footer-multi-column-accent` |
| `onAccent` | `--footer-multi-column-on-accent` |
| `ink` | `--footer-multi-column-ink` |
| `muted` | `--footer-multi-column-muted` |
| `rule` | `--footer-multi-column-rule` |
| `hairline` | `--footer-multi-column-hairline` |
| `surface` | `--footer-multi-column-surface` |

## Accessibility

- The root is a footer element; the link columns sit in a nav landmark named by navLabel ("Footer"), so it is distinct from the header's navigation.
- Column headings are real headings at headingLevel, and each list is labelled by its heading through aria-labelledby.
- In disclosure mode below 640 px each group is a native details/summary that opens with Enter or Space and works without JavaScript. A visually hidden heading at headingLevel sits before each disclosure and labels its list, so the heading outline is the same at every width.
- Contact details render in an address element with mailto: and tel: links; nothing renders when contact is omitted or empty.
- Only links with external: true open a new tab. They carry rel="noopener noreferrer", a decorative arrow kept on the line with the label's last word, and visually hidden newTabLabel text.
- Links are muted at rest (#52525b, 7.7:1 on white) and turn ink on hover; focus shows a two-pixel accent outline offset by two pixels on :focus-visible only.
- On a coarse pointer every link row is at least 44 px tall; disclosure summaries are 48 px.
- The layout uses logical properties and mirrors under dir="rtl"; the external-link arrow flips and the brand name's tracking resets.
- IDs come from $props.id(), so two footers on one page stay unique.

Known limitations:

- Contrast ratios are computed for the shipped palettes; re-check any retoned token (4.5:1 for text, 3:1 for the focus ring).
- The social snippet is yours: give it an accessible name and text or labelled icons.

## License

- Declared source: MIT
- Default license approval is pending. See https://pagesugar.com/docs/license.

## Source

- Palette: Neutral (`neutral`)
- Entry: `FooterMultiColumn.svelte`
- Suggested directory: `src/lib/components/footer-multi-column-01`
- Files: 1
- Artifact digest: `sha256-84650244f5c9b55ac40060c5b6d81794db89c97fb9ce14eab5033723139c4f44`

Paths below are relative to the suggested directory. Copy the files as they are;
they import nothing from this site.

#### `FooterMultiColumn.svelte`

Role: entry · 12341 bytes · SHA-256 `b328b50a052f8b3a49964d0a8c68d669df7efc7a7d3bd984ffb0299c071a6298`

```svelte
<script lang="ts" module>
	export interface FooterLink {
		label: string;
		href: string;
		/** Opens in a new tab and says so, visibly and to assistive technology. */
		external?: boolean;
	}

	export interface FooterColumn {
		heading: string;
		links: FooterLink[];
	}

	export interface FooterBrand {
		/** Organisation name, set beside the logo. */
		name: string;
		/** Where the name links, usually the home page. Omitted, the name is plain text. */
		href?: string;
		/** One or two sentences under the name. */
		tagline?: string;
	}

	export interface FooterContact {
		email?: string;
		/** Shown as written. The tel: link keeps the leading + and the digits before any extension. */
		phone?: string;
		/** The tel: destination, when the displayed number cannot be dialled as written. */
		phoneHref?: string;
		addressLines?: string[];
	}
</script>

<script lang="ts">
	import type { Snippet } from 'svelte';

	interface Props {
		brand: FooterBrand;
		columns: FooterColumn[];
		copyright: string;
		logo?: Snippet;
		contact?: FooterContact;
		legalLinks?: FooterLink[];
		social?: Snippet;
		headingLevel?: 2 | 3 | 4;
		mobileBehaviour?: 'stack' | 'disclosure';
		brandPlacement?: 'start' | 'top';
		navLabel?: string;
		legalLabel?: string;
		newTabLabel?: string;
	}

	let {
		brand,
		columns,
		copyright,
		logo,
		contact,
		legalLinks = [],
		social,
		headingLevel = 2,
		mobileBehaviour = 'stack',
		brandPlacement = 'start',
		navLabel = 'Footer',
		legalLabel = 'Legal',
		newTabLabel = '(opens in new tab)'
	}: Props = $props();

	const uid = $props.id();
	const headingTag = $derived(`h${headingLevel}`);

	const groups = $derived(columns.filter((column) => column.links.length > 0));
	const addressLines = $derived((contact?.addressLines ?? []).filter((line) => line.trim()));
	const email = $derived(contact?.email?.trim() ?? '');
	const phone = $derived(contact?.phone?.trim() ?? '');
	const hasContact = $derived(Boolean(email || phone || addressLines.length));
	/* With no groups to sit beside, the brand spans the width and its contact moves to the end. */
	const beside = $derived(brandPlacement === 'start' && groups.length > 0);
	const disclosure = $derived(mobileBehaviour === 'disclosure');

	/*
	 * Complete static classes for each group count, so every track at lg holds a group. Above the
	 * columns, the brand's grid repeats their tracks and its contact takes the last one, so the
	 * contact starts on the same line as the last column below it.
	 */
	const lgCols: Record<number, string> = {
		1: 'lg:grid-cols-1',
		2: 'lg:grid-cols-2',
		3: 'lg:grid-cols-3',
		4: 'lg:grid-cols-4'
	};
	const topTracks: Record<number, [string, string]> = {
		2: ['lg:grid-cols-2', 'lg:col-span-1'],
		3: ['lg:grid-cols-3', 'lg:col-span-2'],
		4: ['lg:grid-cols-4', 'lg:col-span-3']
	};
	const columnsClass = $derived(lgCols[groups.length] ?? 'lg:grid-cols-5');
	const [topGrid, topSpan] = $derived(
		topTracks[groups.length] ??
			(groups.length > 4
				? ['lg:grid-cols-5', 'lg:col-span-4']
				: ['lg:grid-cols-3', 'lg:col-span-2'])
	);
	/* Below lg the groups pair up; an odd last group takes the whole row and splits its list in two. */
	const isWide = (index: number) => groups.length % 2 === 1 && index === groups.length - 1;

	/* Dial what precedes an extension ("ext. 12", "x12", ";", ","), keeping only + and digits. */
	const telHref = (value: string) => {
		const number = value.split(/[a-z;,]/i)[0].trim();
		return `tel:${number.startsWith('+') ? '+' : ''}${number.replace(/\D/g, '')}`;
	};

	/*
	 * The arrow travels with the label's last word, so a wrapped label never leaves it alone on a
	 * line. A last word too long to hold together is left free to break.
	 */
	const splitLabel = (label: string) => {
		const text = label.trim();
		const at = text.lastIndexOf(' ') + 1;
		return { head: text.slice(0, at), tail: text.slice(at) };
	};

	/* One link style for every list: muted at rest, ink on hover, a 44 px row on a coarse pointer. */
	const linkClass =
		'footer-multi-column__link inline-flex max-w-full min-h-11 min-w-11 items-center rounded-sm text-[var(--_muted)] transition-colors duration-150 ease-[cubic-bezier(.2,0,0,1)] hover:text-[var(--_ink)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--_accent)] pointer-fine:min-h-0 pointer-fine:min-w-0';
</script>

{#snippet anchor(link: FooterLink)}
	<a
		href={link.href}
		class={linkClass}
		target={link.external ? '_blank' : undefined}
		rel={link.external ? 'noopener noreferrer' : undefined}
	>
		<span class="min-w-0 [overflow-wrap:anywhere]">
			{#if link.external}
				{@const { head, tail } = splitLabel(link.label)}
				{head}<span class={tail.length <= 24 ? 'whitespace-nowrap' : undefined}
					>{tail}<svg
						class="ms-0.5 inline size-3.5 align-[-0.125em] rtl:-scale-x-100"
						viewBox="0 0 16 16"
						fill="none"
						stroke="currentColor"
						stroke-width="1.75"
						stroke-linecap="round"
						stroke-linejoin="round"
						aria-hidden="true"><path d="M4.5 11.5l7-7M6 4.5h5.5V10" /></svg
					></span
				><span class="sr-only">&nbsp;{newTabLabel}</span>
			{:else}
				{link.label}
			{/if}
		</span>
	</a>
{/snippet}

{#snippet list(column: FooterColumn, labelId: string, wide = false)}
	<ul
		role="list"
		aria-labelledby={labelId}
		class={[
			'grid text-sm leading-5 pointer-fine:gap-y-3',
			wide && 'grid-cols-2 gap-x-8 lg:grid-cols-1'
		]}
	>
		{#each column.links as link, index (index)}
			<li class="min-w-0">{@render anchor(link)}</li>
		{/each}
	</ul>
{/snippet}

<footer
	class="footer-multi-column border-t border-[var(--_hairline)] bg-[var(--_surface)] px-4 pt-16 pb-8 text-start sm:px-6 sm:pt-24 lg:px-8 lg:pt-32"
>
	<div class="mx-auto max-w-6xl">
		<div class={['grid gap-x-8 gap-y-12', beside && 'lg:grid-cols-3']}>
			<!-- The brand hangs from the same rule as the columns, so every group starts on one line. -->
			<div
				class={[
					'min-w-0 border-t border-[var(--_rule)] pt-4',
					!beside && ['lg:grid lg:gap-x-8', topGrid]
				]}
			>
				<div class={['min-w-0', !beside && topSpan]}>
					{#if brand.href}
						<a
							href={brand.href}
							class="footer-multi-column__tracked inline-flex min-h-11 max-w-full items-center gap-2 rounded-sm text-lg leading-[1.3] font-semibold tracking-[-0.015em] text-[var(--_ink)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--_accent)] pointer-fine:min-h-0"
						>
							{#if logo}{@render logo()}{/if}
							<span class="min-w-0 [overflow-wrap:anywhere]">{brand.name}</span>
						</a>
					{:else}
						<p
							class="footer-multi-column__tracked flex items-center gap-2 text-lg leading-[1.3] font-semibold tracking-[-0.015em] text-[var(--_ink)]"
						>
							{#if logo}{@render logo()}{/if}
							<span class="min-w-0 [overflow-wrap:anywhere]">{brand.name}</span>
						</p>
					{/if}
					{#if brand.tagline}
						<p
							class="mt-4 max-w-sm text-base leading-6 text-pretty [overflow-wrap:anywhere] text-[var(--_muted)]"
						>
							{brand.tagline}
						</p>
					{/if}
				</div>
				{#if hasContact || social}
					<div class={['min-w-0', beside ? 'mt-8' : 'mt-8 lg:mt-0']}>
						{#if hasContact}
							<address class="grid text-sm leading-5 text-[var(--_muted)] not-italic">
								{#if addressLines.length}
									<span class="block pb-3">
										{#each addressLines as line, index (index)}
											<span class="block [overflow-wrap:anywhere]">{line}</span>
										{/each}
									</span>
								{/if}
								{#if email}
									<span class="block min-w-0">
										<a href="mailto:{email}" class={linkClass}>
											<span dir="ltr" class="min-w-0 [overflow-wrap:anywhere]">{email}</span>
										</a>
									</span>
								{/if}
								{#if phone}
									<span class="block min-w-0 pointer-fine:pt-3">
										<a
											href={contact?.phoneHref?.trim() || telHref(phone)}
											class={[linkClass, 'tabular-nums']}
										>
											<span dir="ltr" class="min-w-0 [overflow-wrap:anywhere]">{phone}</span>
										</a>
									</span>
								{/if}
							</address>
						{/if}
						{#if social}
							<div class={hasContact ? 'mt-8' : undefined}>{@render social()}</div>
						{/if}
					</div>
				{/if}
			</div>

			{#if groups.length}
				<nav aria-label={navLabel} class={['min-w-0', beside && 'lg:col-span-2']}>
					<div
						class={[
							'grid-cols-2 items-start gap-x-8 gap-y-12',
							columnsClass,
							disclosure ? 'hidden sm:grid' : 'grid'
						]}
					>
						{#each groups as column, index (index)}
							<div
								class={[
									'min-w-0 border-t border-[var(--_rule)] pt-4',
									isWide(index) && 'col-span-2 lg:col-span-1'
								]}
							>
								<svelte:element
									this={headingTag}
									id="{uid}-heading-{index}"
									class="text-sm leading-5 font-semibold text-balance [overflow-wrap:anywhere] text-[var(--_ink)]"
								>
									{column.heading}
								</svelte:element>
								<div class="mt-4 pointer-coarse:mt-0">
									{@render list(column, `${uid}-heading-${index}`, isWide(index))}
								</div>
							</div>
						{/each}
					</div>

					{#if disclosure}
						<!-- Below sm each group folds into a native disclosure, so it opens without JavaScript. -->
						<div class="border-t border-[var(--_rule)] sm:hidden">
							{#each groups as column, index (index)}
								<!-- A real heading for each group, read before its disclosure; the summary shows the same text. -->
								<svelte:element this={headingTag} id="{uid}-fold-{index}" class="sr-only">
									{column.heading}
								</svelte:element>
								<details class="group border-b border-[var(--_hairline)] last:border-b-0">
									<summary
										class="flex min-h-12 cursor-pointer list-none items-center justify-between gap-4 rounded-sm text-sm leading-5 font-semibold text-[var(--_ink)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--_accent)] [&::-webkit-details-marker]:hidden"
									>
										<span class="min-w-0 [overflow-wrap:anywhere]">{column.heading}</span>
										<svg
											class="size-4 shrink-0 text-[var(--_muted)] transition-transform duration-200 ease-[cubic-bezier(.2,0,0,1)] group-open:rotate-180 motion-reduce:transition-none"
											viewBox="0 0 16 16"
											fill="none"
											stroke="currentColor"
											stroke-width="1.75"
											stroke-linecap="round"
											stroke-linejoin="round"
											aria-hidden="true"
										>
											<path d="M4 6l4 4 4-4" />
										</svg>
									</summary>
									<div class="pb-3">
										{@render list(column, `${uid}-fold-${index}`)}
									</div>
								</details>
							{/each}
						</div>
					{/if}
				</nav>
			{/if}
		</div>

		<div
			class="mt-12 flex flex-col gap-3 border-t border-[var(--_hairline)] pt-8 text-[0.8125rem] leading-5 text-[var(--_muted)] sm:flex-row sm:items-start sm:justify-between sm:gap-8"
		>
			<p class="max-w-[30em] min-w-0 text-pretty [overflow-wrap:anywhere] tabular-nums">
				{copyright}
			</p>
			{#if legalLinks.length}
				<ul
					role="list"
					aria-label={legalLabel}
					class="flex flex-wrap gap-x-8 sm:justify-end pointer-fine:gap-y-3"
				>
					{#each legalLinks as link, index (index)}
						<li class="min-w-0">{@render anchor(link)}</li>
					{/each}
				</ul>
			{/if}
		</div>
	</div>
</footer>

<style>
	/* Public tokens: set --footer-multi-column-* on this footer or any ancestor to retone it. */
	.footer-multi-column {
		--_accent: var(--footer-multi-column-accent, #18181b);
		--_on-accent: var(--footer-multi-column-on-accent, #ffffff);
		--_ink: var(--footer-multi-column-ink, #18181b);
		--_muted: var(--footer-multi-column-muted, #52525b);
		--_rule: var(--footer-multi-column-rule, #18181b);
		--_hairline: var(--footer-multi-column-hairline, rgb(0 0 0 / 0.08));
		--_surface: var(--footer-multi-column-surface, #ffffff);
	}

	/* Selected text takes the accent pair, so a copied address or email reads in the brand's colours. */
	.footer-multi-column ::selection {
		background-color: var(--_accent);
		color: var(--_on-accent);
	}

	/* Arabic and Hebrew are never letter-spaced; tracked text resets under right-to-left. */
	.footer-multi-column__tracked:dir(rtl) {
		letter-spacing: 0;
	}
</style>
```

## Artifacts

### Neutral (`neutral`) (default)

- Artifact digest: `sha256-84650244f5c9b55ac40060c5b6d81794db89c97fb9ce14eab5033723139c4f44`
- Entry: `FooterMultiColumn.svelte`
- Receipt: https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/neutral/sha256-84650244f5c9b55ac40060c5b6d81794db89c97fb9ce14eab5033723139c4f44/manifest.json
- Bundle: https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/neutral/sha256-84650244f5c9b55ac40060c5b6d81794db89c97fb9ce14eab5033723139c4f44/bundle.zip (7402 bytes, sha256 `5ae1086d0997000b6a51092885c6d2c2b0ea752b228daf9707b21348e7af0765`)

Files:

- `FooterMultiColumn.svelte` (entry, 12341 bytes): https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/neutral/sha256-84650244f5c9b55ac40060c5b6d81794db89c97fb9ce14eab5033723139c4f44/source/FooterMultiColumn.svelte

### Dark band (`dark`)

- Artifact digest: `sha256-1d042baf73b9433c82c8594956111e24d2dbca74c1b728c32a3964f602c31839`
- Entry: `FooterMultiColumn.svelte`
- Receipt: https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/dark/sha256-1d042baf73b9433c82c8594956111e24d2dbca74c1b728c32a3964f602c31839/manifest.json
- Bundle: https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/dark/sha256-1d042baf73b9433c82c8594956111e24d2dbca74c1b728c32a3964f602c31839/bundle.zip (7392 bytes, sha256 `4616ab1834f46a40a155344feafcdb251cd503f32af909f5cab72eca209fd429`)

Files:

- `FooterMultiColumn.svelte` (entry, 12333 bytes): https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/dark/sha256-1d042baf73b9433c82c8594956111e24d2dbca74c1b728c32a3964f602c31839/source/FooterMultiColumn.svelte

### Brand tint (`brand-tint`)

- Artifact digest: `sha256-6a365f24a65a83a15b263bdb94377dfd6b5683958dea5b5d1704ffa1e0b617e9`
- Entry: `FooterMultiColumn.svelte`
- Receipt: https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/brand-tint/sha256-6a365f24a65a83a15b263bdb94377dfd6b5683958dea5b5d1704ffa1e0b617e9/manifest.json
- Bundle: https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/brand-tint/sha256-6a365f24a65a83a15b263bdb94377dfd6b5683958dea5b5d1704ffa1e0b617e9/bundle.zip (7403 bytes, sha256 `ae54e964c0903503f9c6e455bde7962489308df73bfd5c5ed9b46fe92c1c729d`)

Files:

- `FooterMultiColumn.svelte` (entry, 12333 bytes): https://pagesugar.com/artifacts/cmp_footer_multi_column_01/1.0.0/brand-tint/sha256-6a365f24a65a83a15b263bdb94377dfd6b5683958dea5b5d1704ffa1e0b617e9/source/FooterMultiColumn.svelte
