Component library
Back to catalog

Flanked masthead header

A centred masthead header: the business name in the middle with the area served beneath it, the number and hours on the left and the booking button on the right as an equal pair, and the pages as one centred row under a double rule. Below 1024px the name stays centred beside a square menu control and the number and booking action become a full-width split call | book strip. Everything renders only when supplied; no script.

headernavigationmastheadcentred logoclick-to-callcall and book striphoursno-script menulocal service

Open preview in a new tab

Use this component

Three ways to get Flanked masthead header into one of your own projects. All pre-filled with this component's name and library page.

Or, for the design alone

Placement prompt

What to do, where it goes and what must not change. Paste it into Claude Code inside the destination project.

Read it first
Add Flanked masthead header from my Astro Component Library to this Astro project.

Library page, for reference only:
https://astro.baysixmedia.com/components/flanked-masthead-header/

Place it in:
[ENTER PAGE, FILE, OR ROUTE]

Position:
[ENTER WHERE IT SHOULD APPEAR]

First read the component source, README, documented props, dependencies, and required assets from the library page. Copy the component and every required companion asset locally into this project. Do not import files from the deployed library at runtime.

Adapt its demo content, links, colors, typography, and images to this project through documented props where possible. Preserve its responsive behavior, accessibility, interaction logic, reduced-motion behavior, and support for multiple instances. Avoid changing unrelated project code.

Test it at desktop, tablet, and mobile widths. Run the project's available check and build commands. Report the files changed and any differences from the library version. Do not commit or deploy.

--- VERIFIED IN THE COMPONENT LIBRARY ---
Enrolled for verification but never run.
No verification run has been recorded.
No checks have passed yet.
This record pre-dates source fingerprinting, so it is not tied to a specific revision.

--- NOT PROVEN ---
- ClientRouter: event-tested only. Handlers respond to dispatched lifecycle events; this has NOT been certified against a real <ClientRouter /> transition.

--- WHAT THIS DOES NOT CERTIFY ---
Verification was performed on the unmodified component, in an isolated fixture, in the
library. It says nothing about this project's CSS, routes, layout or data, and nothing
about the component once you adapt it. A verified component is a good starting point,
not a guarantee about the installation you are about to build.

--- TEST IN THIS PROJECT AFTER INSTALLING OR CUSTOMISING ---
- Horizontal overflow at 1440, 1280, 1024, 834, 390 and 320px.
- Keyboard operation end to end, including visible focus.
- The no-JavaScript render.
- prefers-reduced-motion: reduce.
- Two instances on one page, if this project renders more than one.
- If this project uses <ClientRouter />: teardown and reinitialisation across a real navigation.

Component reference

A fragment for a request you write yourself, e.g. “I want to add [paste] to Section 3 of my homepage.” It names the component, links its page, and fixes what must not change — the design build and its effects — while leaving branding and content open. It does not carry the code.

Read it first
“Flanked masthead header” from my Astro Component Library:
https://astro.baysixmedia.com/components/flanked-masthead-header/

Use the existing library component as the implementation source. Preserve its design structure, layout, proportions, spacing system, responsive behavior, visual effects, animations, transitions, hover states, interactions, and accessibility.

The copy, colors, typography, images, and other content may be adapted to match the destination website. Do not redesign, simplify, or reinterpret the component’s underlying design build or effects.

src/components/library/FlankedMastheadHeader.astro

Installing this one is more than pasting a section

  • installOne required file, plus supporting files worth taking:
    • src/components/FlankedMastheadHeader.astrocomponentrequired
    • src/components/FlankedMastheadHeader.mdreadmesupporting
    Use Copy header kit above to get them all, each one labelled with the path it belongs at.
---
/**
 * FlankedMastheadHeader (candidate, role `navigation`, original)
 *
 * A centred masthead for a business people call or book. The name sits in the middle as a sign would,
 * with the area it serves set small beneath it. The two ways to get in touch flank it as equals: the
 * number (and the hours, one entry per line) on the left, the booking action on the right. Under a
 * double rule, the pages run as one centred row.
 *
 * Below 1024px the masthead keeps the name centred with a square menu control at its right edge, and
 * the two flanks drop into a split strip across the foot of the header: call on the left, book on
 * the right, each half the width of the screen and 56px tall. The number never shrinks into an icon.
 *
 * The pages never wrap: the frontmatter estimates the width the centred row needs and picks the
 * narrowest container width that holds it. Where it does not fit, a centred "Menu" control takes
 * the row's place and opens the same list.
 *
 * Truth rules. Note, hours, phone, links and action each render only when passed. The call link needs
 * a real number (tel: built from its digits). No script: the menu is a native <details> disclosure.
 * In the flow; reserves its own height.
 *
 * Reads, never declares: --fmh-bg, --fmh-text, --fmh-text-muted, --fmh-brand, --fmh-brand-text,
 * --fmh-border, --fmh-family, --fmh-display, --fmh-grid-max, --fmh-grid-gutter.
 */
export interface FlankedMastheadHeaderLink {
	label: string;
	href: string;
}

interface Props {
	brandName?: string;
	brandHref?: string;
	logo?: { src: string; alt: string; width?: number; height?: number } | null;
	items?: readonly FlankedMastheadHeaderLink[];
	currentPath?: string;
	phone?: { number: string; label?: string } | null;
	/** One short line under the name, e.g. the area served. */
	note?: string;
	/** Hours or availability, as supplied: one string or one entry per line. */
	hours?: string | readonly string[];
	cta?: FlankedMastheadHeaderLink | null;
	/** Heading over the hours in the phone menu; "Hours" by default. */
	hoursLabel?: string;
	navLabel?: string;
	menuLabel?: string;
	fontStylesheet?: string;
	class?: string;
	id?: string;
}

const {
	brandName = "",
	brandHref,
	logo = null,
	items = [],
	currentPath,
	phone = null,
	note = "",
	hours,
	cta = null,
	hoursLabel = "Hours",
	navLabel = "Primary",
	menuLabel = "Menu",
	fontStylesheet = "https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,600;12..96,700&family=Instrument+Sans:wght@400;500;600&display=swap",
	class: className,
	id,
} = Astro.props;

const safeHref = (href: string | undefined) => {
	const h = (href ?? "").trim();
	return /^(https?:\/\/|mailto:|tel:|#|\/(?!\/))/i.test(h) ? h : null;
};
const links = items.map((l) => ({ label: (l?.label ?? "").trim(), href: safeHref(l?.href) })).filter((l): l is { label: string; href: string } => Boolean(l.label && l.href));
const action = cta && cta.label?.trim() && safeHref(cta.href) ? { label: cta.label.trim(), href: safeHref(cta.href)! } : null;
const digits = (phone?.number ?? "").replace(/[^\d+]/g, "");
const call = phone && phone.number?.trim() && digits.replace(/\D/g, "").length >= 7 ? { number: phone.number.trim(), label: (phone.label ?? "Call").trim(), href: `tel:${digits}` } : null;
const hourLines = (Array.isArray(hours) ? hours : hours ? [hours] : []).map((h) => String(h).trim()).filter(Boolean);
const noteLine = note.trim();
const name = brandName.trim();
const home = safeHref(brandHref);
const norm = (p: string) => p.replace(/\/+$/, "") || "/";
const isCurrent = (href: string) => (currentPath ? norm(currentPath) === norm(href) : false);
const hasStrip = Boolean(call || action);
const hasFacts = Boolean(noteLine || hourLines.length);

/* The name steps down by length so a long one takes two balanced lines, never three. */
const nameSize = name.length <= 18 ? "l" : name.length <= 28 ? "m" : "s";

/*
 * Both flanks share one width, so the name stays on the true centre line: wide enough for the call
 * line and for the action, capped so the name keeps at least 200px. Hours and a long label wrap
 * inside it; nothing is cut off.
 */
const callW = call ? call.label.length * 7.6 + 10 + call.number.length * 13.4 : 0;
const ctaW = action ? Math.min(action.label.length, 24) * 8.2 + 64 : 0;
const flankW = Math.round(Math.min(260, Math.max(170, callW, ctaW)));

/* One-line budget for the centred page row: about 8px per label character, 36px gaps, 6% margin. */
const rowNeed = (links.reduce((w, l) => w + l.label.length * 8, 0) + Math.max(0, links.length - 1) * 36 + 48) * 1.06;
const STEPS = [1024, 1180, 1280] as const;
const inner = (w: number) => Math.min(w, 1232) - 96;
const inlineAt = links.length ? (STEPS.find((w) => inner(w) >= rowNeed) ?? "never") : 0;
const panelId = `${id ?? "fmh"}-menu`;

const Brand = home ? "a" : "span";
---

{(name || logo?.src || links.length > 0) && (
	<header
		class:list={["fmh", className]}
		id={id}
		data-inline={String(inlineAt)}
		data-links={String(links.length)}
		data-strip={hasStrip ? "" : undefined}
		style={`--fmh-flank: ${flankW}px`}
	>
		{fontStylesheet && <link rel="stylesheet" href={fontStylesheet} />}
		<div class="fmh-mast">
			<div class="fmh-flank fmh-flank--call">
				{call && (
					<a class="fmh-call" href={call.href}>
						<span class="fmh-call-label">{call.label}</span>
						<span class="fmh-call-number">{call.number}</span>
					</a>
				)}
				{hourLines.length > 0 && (
					<p class="fmh-hours">
						{hourLines.map((h) => <span>{h}</span>)}
					</p>
				)}
			</div>

			<div class="fmh-centre">
				<Brand class="fmh-brand" href={home ?? undefined}>
					{logo?.src ? (
						<img class="fmh-logo" src={logo.src} alt={logo.alt || name} width={logo.width} height={logo.height} />
					) : (
						<span class="fmh-wordmark" data-size={nameSize}>{name}</span>
					)}
				</Brand>
				{noteLine && <p class="fmh-dateline">{noteLine}</p>}
			</div>

			<div class="fmh-flank fmh-flank--book">
				{action && (
					<a class="fmh-cta" href={action.href}>
						<span>{action.label}</span>
						<svg aria-hidden="true" viewBox="0 0 16 16" width="16" height="16"><path d="M2.5 8h10M9 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.7" /></svg>
					</a>
				)}
			</div>
		</div>

		{links.length > 0 && (
			<nav class="fmh-row" aria-label={navLabel}>
				<ul role="list">
					{links.map((l) => (
						<li>
							<a href={l.href} aria-current={isCurrent(l.href) ? "page" : undefined}>{l.label}</a>
						</li>
					))}
				</ul>
			</nav>
		)}

		{links.length > 0 && (
			<details class="fmh-menu">
				<summary class="fmh-toggle" aria-controls={panelId}>
					<span class="fmh-toggle-text">{menuLabel}</span>
					<span class="fmh-toggle-icon" aria-hidden="true"><span></span><span></span></span>
				</summary>
				<div class="fmh-panel" id={panelId}>
					<div class="fmh-panel-inner">
						{/* The row and this menu are never displayed together, so one Primary nav is exposed at a time. */}
						<nav aria-label={navLabel}>
							<ul role="list" class="fmh-panel-links">
								{links.map((l) => (
									<li>
										<a href={l.href} aria-current={isCurrent(l.href) ? "page" : undefined}>
											<span>{l.label}</span>
											<svg aria-hidden="true" viewBox="0 0 16 16" width="16" height="16"><path d="M2.5 8h10M9 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.6" /></svg>
										</a>
									</li>
								))}
							</ul>
						</nav>
						{hasFacts && (
							<div class="fmh-panel-facts">
								{hourLines.length > 0 && (
									<p>
										<strong>{hoursLabel}</strong>
										{hourLines.map((h) => <span>{h}</span>)}
									</p>
								)}
								{noteLine && <p class="fmh-panel-note">{noteLine}</p>}
							</div>
						)}
					</div>
				</div>
			</details>
		)}

		{hasStrip && (
			<div class="fmh-strip">
				{call && (
					<a class="fmh-strip-call" href={call.href}>
						<span class="fmh-strip-label">{call.label}</span>
						<span class="fmh-strip-number">{call.number}</span>
					</a>
				)}
				{action && (
					<a class="fmh-strip-book" href={action.href}>
						<span>{action.label}</span>
						<svg aria-hidden="true" viewBox="0 0 16 16" width="16" height="16"><path d="M2.5 8h10M9 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.7" /></svg>
					</a>
				)}
			</div>
		)}
	</header>
)}

<style>
	.fmh {
		--fmh-surface: var(--fmh-bg, #faf7f2);
		--fmh-ink: var(--fmh-text, #1c1a17);
		--fmh-soft: var(--fmh-text-muted, #564f47);
		--fmh-accent: var(--fmh-brand, #a4381c);
		--fmh-accent-ink: var(--fmh-brand-text, #ffffff);
		--fmh-line: var(--fmh-border, #ddd5c9);
		--fmh-font: var(--fmh-family, "Instrument Sans", ui-sans-serif, system-ui, sans-serif);
		--fmh-font-display: var(--fmh-display, "Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif);
		--fmh-max: var(--fmh-grid-max, 1232px);
		--fmh-pad: 20px;
		container-type: inline-size;
		position: relative;
		z-index: 40;
		background: var(--fmh-surface);
		border-bottom: 1px solid var(--fmh-line);
		color: var(--fmh-ink);
		font-family: var(--fmh-font);
	}
	.fmh a {
		-webkit-tap-highlight-color: transparent;
	}

	/* ---------- Masthead (compact: the name centred, the menu square at its right edge) ---------- */
	.fmh-mast {
		box-sizing: border-box;
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		align-items: start;
		max-width: var(--fmh-max);
		margin: 0 auto;
		padding: 14px calc(var(--fmh-pad) + 56px);
	}
	.fmh[data-links="0"] .fmh-mast {
		padding-inline: var(--fmh-pad);
	}
	.fmh-flank {
		display: none;
	}
	.fmh-centre {
		display: flex;
		flex-direction: column;
		align-items: center;
		min-width: 0;
		text-align: center;
	}
	.fmh-brand {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-height: 44px;
		max-width: 100%;
		color: inherit;
		text-decoration: none;
	}
	.fmh-wordmark {
		font-family: var(--fmh-font-display);
		font-size: 23px;
		font-weight: 700;
		letter-spacing: -0.02em;
		line-height: 1.08;
		text-wrap: balance;
		overflow-wrap: anywhere;
	}
	.fmh-wordmark[data-size="m"] {
		font-size: 21px;
	}
	.fmh-wordmark[data-size="s"] {
		font-size: 19px;
	}
	.fmh-logo {
		display: block;
		height: 36px;
		width: auto;
		max-width: 220px;
		object-fit: contain;
	}
	.fmh-dateline {
		display: none;
		margin: 2px 0 0;
		font-size: 14px;
		font-weight: 500;
		line-height: 1.35;
		color: var(--fmh-soft);
		text-wrap: balance;
	}

	/* ---------- Menu control: a square at the masthead's right edge ---------- */
	.fmh-toggle {
		position: absolute;
		top: 14px;
		right: var(--fmh-pad);
		display: inline-flex;
		align-items: center;
		justify-content: center;
		gap: 10px;
		box-sizing: border-box;
		width: 44px;
		height: 44px;
		border: 1px solid var(--fmh-line);
		border-radius: 3px;
		background: var(--fmh-surface);
		color: var(--fmh-ink);
		cursor: pointer;
		list-style: none;
		font-size: 15px;
		font-weight: 600;
		user-select: none;
	}
	.fmh-toggle::-webkit-details-marker {
		display: none;
	}
	.fmh-toggle:hover {
		border-color: var(--fmh-ink);
	}
	.fmh-toggle-text {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
	.fmh-toggle-icon {
		position: relative;
		width: 18px;
		height: 12px;
	}
	.fmh-toggle-icon span {
		position: absolute;
		left: 0;
		right: 0;
		height: 2px;
		background: currentColor;
		transition: transform 180ms ease, top 180ms ease;
	}
	.fmh-toggle-icon span:nth-child(1) { top: 2px; }
	.fmh-toggle-icon span:nth-child(2) { top: 8px; }
	.fmh-menu[open] .fmh-toggle-icon span:nth-child(1) { top: 5px; transform: rotate(45deg); }
	.fmh-menu[open] .fmh-toggle-icon span:nth-child(2) { top: 5px; transform: rotate(-45deg); }
	.fmh-menu[open] .fmh-toggle {
		border-color: var(--fmh-ink);
	}

	.fmh-panel {
		position: absolute;
		left: 0;
		right: 0;
		top: 100%;
		margin-top: 1px;
		background: var(--fmh-surface);
		border-bottom: 1px solid var(--fmh-line);
		box-shadow: 0 24px 40px -28px rgb(28 26 23 / 0.45);
	}
	.fmh-panel-inner {
		box-sizing: border-box;
		max-width: var(--fmh-max);
		margin: 0 auto;
		padding: 4px var(--fmh-pad) 24px;
	}
	.fmh-panel-links {
		margin: 0;
		padding: 0;
		list-style: none;
	}
	.fmh-panel-links a {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		min-height: 56px;
		border-bottom: 1px solid var(--fmh-line);
		color: var(--fmh-ink);
		font-size: 18px;
		font-weight: 500;
		text-decoration: none;
	}
	.fmh-panel-links a svg {
		flex: none;
		color: var(--fmh-soft);
		transition: transform 180ms ease;
	}
	.fmh-panel-links a:hover svg {
		transform: translateX(3px);
		color: var(--fmh-accent);
	}
	.fmh-panel-links a[aria-current="page"] {
		color: var(--fmh-accent);
		box-shadow: inset 3px 0 0 var(--fmh-accent);
		padding-left: 14px;
	}
	.fmh-panel-facts {
		display: grid;
		gap: 16px;
		margin: 20px 0 0;
	}
	.fmh-panel-facts p {
		margin: 0;
		font-size: 15px;
		line-height: 1.5;
		color: var(--fmh-soft);
	}
	.fmh-panel-facts strong {
		display: block;
		margin-bottom: 2px;
		font-size: 14px;
		font-weight: 600;
		color: var(--fmh-ink);
	}
	.fmh-panel-facts span {
		display: block;
	}

	/* ---------- The split strip: call | book, full width under the masthead ---------- */
	.fmh-strip {
		display: flex;
		border-top: 1px solid var(--fmh-line);
	}
	.fmh-strip > a {
		flex: 1 1 0;
		min-width: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		box-sizing: border-box;
		min-height: 58px;
		padding: 8px 10px;
		text-decoration: none;
		text-align: center;
	}
	.fmh-strip-call {
		flex-direction: column;
		gap: 1px;
		color: var(--fmh-ink);
	}
	.fmh-strip-call + .fmh-strip-book {
		border-left: 1px solid var(--fmh-line);
	}
	.fmh-strip-label {
		font-size: 13.5px;
		font-weight: 500;
		line-height: 1.2;
		color: var(--fmh-soft);
	}
	.fmh-strip-number {
		font-family: var(--fmh-font-display);
		font-size: clamp(16.5px, 5.2cqi, 19px);
		font-weight: 700;
		line-height: 1.2;
		letter-spacing: -0.005em;
		font-variant-numeric: lining-nums tabular-nums;
		white-space: nowrap;
	}
	.fmh-strip-call:hover .fmh-strip-number {
		text-decoration: underline;
		text-decoration-thickness: 1.5px;
		text-underline-offset: 3px;
	}
	.fmh-strip-book {
		gap: 8px;
		background: var(--fmh-accent);
		color: var(--fmh-accent-ink);
		font-size: 16px;
		font-weight: 600;
		line-height: 1.25;
	}
	.fmh-strip-book svg {
		flex: none;
		transition: transform 180ms ease;
	}
	.fmh-strip-book:hover {
		background: color-mix(in srgb, var(--fmh-accent) 86%, #000);
	}
	.fmh-strip-book:hover svg {
		transform: translateX(3px);
	}

	/* The page row is a wide-layout element; compact uses the menu. */
	.fmh-row {
		display: none;
	}

	/* ---------- Focus ---------- */
	.fmh-brand:focus-visible,
	.fmh-call:focus-visible,
	.fmh-row a:focus-visible,
	.fmh-panel a:focus-visible,
	.fmh-toggle:focus-visible {
		outline: 2px solid var(--fmh-accent);
		outline-offset: 3px;
		border-radius: 2px;
	}
	.fmh-strip > a:focus-visible {
		outline: 2px solid var(--fmh-ink);
		outline-offset: -4px;
	}
	.fmh-cta:focus-visible {
		outline: 2px solid var(--fmh-ink);
		outline-offset: 3px;
	}

	/* The area line joins the name once the masthead has room for it. */
	@container (min-width: 600px) {
		.fmh-dateline {
			display: block;
		}
		.fmh-panel-note {
			display: none;
		}
		.fmh-mast {
			padding-block: 20px;
		}
		.fmh-toggle {
			top: 20px;
		}
		.fmh-wordmark { font-size: 27px; }
		.fmh-wordmark[data-size="m"] { font-size: 24px; }
		.fmh-wordmark[data-size="s"] { font-size: 22px; }
		.fmh-logo { height: 40px; }
		.fmh-strip-number { font-size: 20px; }
		.fmh-strip-call {
			flex-direction: row;
			gap: 10px;
		}
		.fmh-strip-label {
			font-size: 14px;
		}
		.fmh-panel-links {
			display: grid;
			grid-template-columns: repeat(2, minmax(0, 1fr));
			column-gap: 32px;
		}
		.fmh-panel-facts {
			grid-template-columns: repeat(2, minmax(0, 1fr));
			column-gap: 32px;
		}
	}

	/* ---------- Wide: call | name | book, with the pages under a double rule ---------- */
	@container (min-width: 1024px) {
		.fmh > * {
			--fmh-pad: var(--fmh-grid-gutter, 48px);
		}
		.fmh-mast {
			grid-template-columns: minmax(var(--fmh-flank), 1fr) minmax(0, auto) minmax(var(--fmh-flank), 1fr);
			align-items: start;
			column-gap: 40px;
			padding: 20px var(--fmh-pad) 18px;
		}
		.fmh-brand {
			min-height: 52px;
		}
		.fmh-flank {
			display: flex;
			flex-direction: column;
			gap: 0;
			min-width: 0;
		}
		.fmh-flank--call {
			align-items: flex-start;
		}
		.fmh-flank--book {
			align-items: flex-end;
		}
		.fmh-strip,
		.fmh-panel-facts {
			display: none;
		}
		.fmh-wordmark { font-size: 34px; }
		.fmh-wordmark[data-size="m"] { font-size: 30px; }
		.fmh-wordmark[data-size="s"] { font-size: 27px; }
		.fmh-logo { height: 48px; max-width: 260px; }
		.fmh-dateline {
			margin-top: 0;
			font-size: 15px;
		}

		.fmh-call {
			display: inline-flex;
			align-items: baseline;
			flex-wrap: wrap;
			column-gap: 10px;
			min-height: 52px;
			align-content: center;
			color: var(--fmh-ink);
			text-decoration: none;
		}
		.fmh-call-label {
			font-size: 15px;
			font-weight: 600;
			color: var(--fmh-accent);
		}
		.fmh-call-number {
			font-family: var(--fmh-font-display);
			font-size: 25px;
			font-weight: 700;
			letter-spacing: -0.01em;
			line-height: 1.1;
			font-variant-numeric: lining-nums tabular-nums;
			white-space: nowrap;
			background: linear-gradient(currentColor, currentColor) no-repeat left bottom / 0 2px;
			padding-bottom: 3px;
			transition: background-size 220ms ease;
		}
		.fmh-call:hover .fmh-call-number {
			background-size: 100% 2px;
		}
		.fmh-hours {
			margin: 0;
			font-size: 14.5px;
			line-height: 1.45;
			color: var(--fmh-soft);
		}
		.fmh-hours span:not(:last-child)::after {
			content: ",";
			margin-right: 0.3em;
		}

		.fmh-cta {
			display: inline-flex;
			align-items: center;
			justify-content: center;
			gap: 10px;
			box-sizing: border-box;
			max-width: 100%;
			min-height: 52px;
			padding: 10px 22px 10px 24px;
			border-radius: 2px;
			background: var(--fmh-accent);
			color: var(--fmh-accent-ink);
			font-size: 16px;
			font-weight: 600;
			line-height: 1.25;
			text-align: center;
			text-decoration: none;
			box-shadow: 0 1px 0 rgb(0 0 0 / 0.08), inset 0 -2px 0 rgb(0 0 0 / 0.14);
			transition: background-color 160ms ease;
		}
		.fmh-cta svg {
			flex: none;
			transition: transform 180ms ease;
		}
		.fmh-cta:hover {
			background: color-mix(in srgb, var(--fmh-accent) 86%, #000);
		}
		.fmh-cta:hover svg {
			transform: translateX(3px);
		}

		/* The second tier: the page row, or the centred menu control in its place. */
		.fmh-row,
		.fmh-menu {
			box-sizing: border-box;
			max-width: var(--fmh-max);
			margin: 0 auto;
			padding-inline: var(--fmh-pad);
		}
		.fmh-row ul,
		.fmh-menu > summary {
			border-top: 4px double color-mix(in srgb, var(--fmh-ink) 26%, var(--fmh-surface));
		}
		.fmh-row ul {
			display: flex;
			justify-content: center;
			align-items: center;
			gap: 36px;
			margin: 0;
			padding: 0;
			list-style: none;
		}
		.fmh-row a {
			display: inline-flex;
			align-items: center;
			min-height: 52px;
			color: var(--fmh-ink);
			font-size: 15.5px;
			font-weight: 500;
			text-decoration: none;
			white-space: nowrap;
			background: linear-gradient(currentColor, currentColor) no-repeat center bottom 13px / 0 1.5px;
			transition: background-size 200ms ease;
		}
		.fmh-row a:hover {
			background-size: 100% 1.5px;
		}
		.fmh-row a[aria-current="page"] {
			color: var(--fmh-accent);
			background-image: linear-gradient(var(--fmh-accent), var(--fmh-accent));
			background-size: 100% 2px;
		}
		.fmh-menu > summary.fmh-toggle {
			position: static;
			display: flex;
			width: 100%;
			height: 52px;
			border-width: 4px 0 0;
			border-radius: 0;
			background: transparent;
		}
		.fmh-menu > summary.fmh-toggle:hover {
			color: var(--fmh-accent);
		}
		.fmh-toggle-text {
			position: static;
			width: auto;
			height: auto;
			overflow: visible;
			clip-path: none;
		}
		.fmh-toggle-icon {
			width: 14px;
			height: 10px;
		}
		.fmh-panel-links {
			grid-template-columns: repeat(3, minmax(0, 1fr));
		}
	}

	/* The page row replaces the menu from the width that holds it on one line. */
	@container (min-width: 1024px) {
		.fmh[data-inline="1024"] .fmh-row { display: block; }
		.fmh[data-inline="1024"] .fmh-menu { display: none; }
	}
	@container (min-width: 1180px) {
		.fmh[data-inline="1180"] .fmh-row { display: block; }
		.fmh[data-inline="1180"] .fmh-menu { display: none; }
	}
	@container (min-width: 1280px) {
		.fmh[data-inline="1280"] .fmh-row { display: block; }
		.fmh[data-inline="1280"] .fmh-menu { display: none; }
	}

	@media (prefers-reduced-motion: reduce) {
		.fmh-toggle-icon span,
		.fmh-row a,
		.fmh-call-number,
		.fmh-cta,
		.fmh-cta svg,
		.fmh-strip-book svg,
		.fmh-panel-links a svg {
			transition: none;
		}
		.fmh-cta:hover svg,
		.fmh-strip-book:hover svg,
		.fmh-panel-links a:hover svg {
			transform: none;
		}
	}
	@media (forced-colors: active) {
		.fmh-cta,
		.fmh-strip-book {
			border: 2px solid ButtonText;
		}
		.fmh-panel-links a[aria-current="page"] {
			border-left: 3px solid Highlight;
		}
	}
</style>