diff --git a/web/NavPanel.tsx b/web/NavPanel.tsx
index a42942e..455e35f 100644
--- a/web/NavPanel.tsx
+++ b/web/NavPanel.tsx
@@ -1,6 +1,6 @@
import { Link, useSearchParams } from 'react-router';
import { Lock } from 'lucide-react';
-import { DEFAULT_SECTION, SECTIONS, isSectionKey, sectionOpen, type SectionKey } from './sections';
+import { DEFAULT_SECTION, LAYOUT_BANDS, SECTIONS, isSectionKey, sectionOpen, type SectionKey } from './sections';
import { useReady } from './useReady';
import { pageParam, usePages } from './usePages';
@@ -145,6 +145,47 @@ export const NavPanel = () => {
Drawn whether or not Pages is the open section. The list of pages IS the site, and hiding it
until you click makes the nav a menu of menus.
*/
+ /*
+ Layout's three bands, as rows under Layout.
+
+ The layout IS a page — a header, the slot a page goes in, and a footer — and those three are the
+ only things on this screen. They were reachable by scrolling and by knowing which tab held what;
+ as rows they are the same shape as the pages under Pages, which is the shape the nav already
+ teaches.
+
+ Fixed rather than fetched: unlike pages, these three are structural. A band cannot be added or
+ removed from the admin, only the code that draws it can, so a list read from the database would
+ be a query that can only ever return the same three rows.
+ */
+ if (section.key === 'layout') {
+ return (
+
+ );
+ }
+
if (section.key !== 'pages' || !pages?.length) return row;
return (
diff --git a/web/sections.ts b/web/sections.ts
index e171cbd..7e30292 100644
--- a/web/sections.ts
+++ b/web/sections.ts
@@ -70,6 +70,27 @@ export type Section = {
pinned?: boolean;
};
+/**
+ * The three bands the layout is made of, in the order they appear on the page.
+ *
+ * The layout IS a page: a header, the slot a page goes in, and a footer. These are the nav rows under
+ * Layout, and the `band` in the query string.
+ *
+ * FIXED, unlike the pages under Pages. A band cannot be added or removed from the admin — only the
+ * code that draws it can — so reading them from the database would be a query that can only ever
+ * return the same three rows in the same order.
+ */
+export const LAYOUT_BANDS = [
+ { key: 'header', label: 'Top Menu' },
+ { key: 'content', label: 'Content' },
+ { key: 'footer', label: 'Footer' },
+] as const;
+
+export type LayoutBand = (typeof LAYOUT_BANDS)[number]['key'];
+
+export const isLayoutBand = (value: string | null): value is LayoutBand =>
+ value !== null && LAYOUT_BANDS.some((band) => band.key === value);
+
export const SECTIONS: Section[] = [
{
/*