diff --git a/CLAUDE.md b/CLAUDE.md
index deac08e..17f288f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -247,6 +247,17 @@ Presentational config separate from `config.yml`. Controls accent colour, dark/l
Keys in both blocks: `info`, `warning`, `success`, `error`.
+**Nav section toggle icons** (top-level keys, not inside `light:`/`dark:`):
+
+| Key | Default | Purpose |
+|---|---|---|
+| `nav-section-expand-icon` | `arrow_right` | icon shown when section is collapsed |
+| `nav-section-collapse-icon` | `arrow_drop_down` | icon shown when section is expanded |
+
+Available icon names: `arrow_right`, `arrow_drop_down`, `keyboard_arrow_right`, `keyboard_arrow_down`, `keyboard_double_arrow_right`, `keyboard_double_arrow_down`, `expand_content`, `collapse_content`, `add`, `minimize`.
+
+These only apply to nav sections with `pagesvisibility: hidden` (collapsible sections).
+
### Icon system
All UI icons served as local SVGs from `app/assets/icons/`. No Google Fonts or external icon font. Icon names are normalised (lowercase, spaces → hyphens).
diff --git a/app/assets/icons/add.svg b/app/assets/icons/add.svg
new file mode 100644
index 0000000..44deff6
--- /dev/null
+++ b/app/assets/icons/add.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/icons/collapse_content.svg b/app/assets/icons/collapse_content.svg
new file mode 100644
index 0000000..12f1411
--- /dev/null
+++ b/app/assets/icons/collapse_content.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/icons/expand_content.svg b/app/assets/icons/expand_content.svg
new file mode 100644
index 0000000..2b183c4
--- /dev/null
+++ b/app/assets/icons/expand_content.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/icons/keyboard_arrow_down.svg b/app/assets/icons/keyboard_arrow_down.svg
new file mode 100644
index 0000000..38b217c
--- /dev/null
+++ b/app/assets/icons/keyboard_arrow_down.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/icons/keyboard_arrow_right.svg b/app/assets/icons/keyboard_arrow_right.svg
new file mode 100644
index 0000000..9aaa66b
--- /dev/null
+++ b/app/assets/icons/keyboard_arrow_right.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/icons/keyboard_double_arrow_down.svg b/app/assets/icons/keyboard_double_arrow_down.svg
new file mode 100644
index 0000000..ca22ca0
--- /dev/null
+++ b/app/assets/icons/keyboard_double_arrow_down.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/icons/keyboard_double_arrow_right.svg b/app/assets/icons/keyboard_double_arrow_right.svg
new file mode 100644
index 0000000..580e6eb
--- /dev/null
+++ b/app/assets/icons/keyboard_double_arrow_right.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/icons/minimize.svg b/app/assets/icons/minimize.svg
new file mode 100644
index 0000000..c6365a7
--- /dev/null
+++ b/app/assets/icons/minimize.svg
@@ -0,0 +1 @@
+
diff --git a/app/index.html b/app/index.html
index b0a722b..9cba457 100644
--- a/app/index.html
+++ b/app/index.html
@@ -959,7 +959,7 @@ body {
let loadedFonts = new Set(); // track which font files have been loaded
// ─── Icons ────────────────────────────────────────────────
- const STANDARD_ICONS = ['dark_mode','light_mode','menu','search','arrow_right','arrow_drop_down','mobile_arrow_down','language','info','warning','error','success','exclamation','dangerous','report','history','text_compare'];
+ const STANDARD_ICONS = ['dark_mode','light_mode','menu','search','arrow_right','arrow_drop_down','mobile_arrow_down','language','info','warning','error','success','exclamation','dangerous','report','history','text_compare','keyboard_arrow_right','keyboard_arrow_down','keyboard_double_arrow_right','keyboard_double_arrow_down','expand_content','collapse_content','add','minimize'];
const iconCache = {};
function normaliseIconName(name) {
@@ -2427,8 +2427,10 @@ function fmtDatetime(dtStr) {
if (isHidden) {
const expanded = sectionExpanded(section.code);
+ const expandIcon = themeConfig['nav-section-expand-icon'] || 'arrow_right';
+ const collapseIcon = themeConfig['nav-section-collapse-icon'] || 'arrow_drop_down';
heading.innerHTML = '';
- heading.appendChild(iconEl(expanded ? 'arrow_drop_down' : 'arrow_right', 'toggle-icon'));
+ heading.appendChild(iconEl(expanded ? collapseIcon : expandIcon, 'toggle-icon'));
heading.appendChild(el('span', { textContent: name }));
heading.addEventListener('click', () => {
toggleSection(section.code);
diff --git a/app/theme.yml b/app/theme.yml
index 2fe1838..d5ce962 100644
--- a/app/theme.yml
+++ b/app/theme.yml
@@ -81,6 +81,17 @@ font-heading: "bunny:Noto Sans:700"
font-size: 1.0 # unitless multiplier (1.0 = 16px base)
line-height: 1.7 # unitless multiplier
+# ──────────────────────────────────
+# Nav section toggle icons
+# Used on sections with pagesvisibility: hidden (collapsible sections).
+# expand-icon shown when section is collapsed; collapse-icon when expanded.
+# Options: arrow_right/arrow_drop_down (default) | keyboard_arrow_right/keyboard_arrow_down
+# keyboard_double_arrow_right/keyboard_double_arrow_down
+# expand_content/collapse_content | add/minimize
+# ──────────────────────────────────
+# nav-section-expand-icon: arrow_right
+# nav-section-collapse-icon: arrow_drop_down
+
# ──────────────────────────────────
# Layout
# ──────────────────────────────────
diff --git a/docs/claude-design.md b/docs/claude-design.md
index bd07f1a..e507570 100644
--- a/docs/claude-design.md
+++ b/docs/claude-design.md
@@ -92,6 +92,14 @@ font-heading: "bunny:IBM Plex Sans:700"
font-size: 1.0 # unitless multiplier (1.0 = 16px base)
line-height: 1.7 # unitless multiplier
+# ──────────────────────────────────
+# Nav section toggle icons
+# expand-icon: shown when section is collapsed
+# collapse-icon: shown when section is expanded
+# ──────────────────────────────────
+nav-section-expand-icon: arrow_right # default
+nav-section-collapse-icon: arrow_drop_down # default
+
# ──────────────────────────────────
# Layout
# ──────────────────────────────────
@@ -101,6 +109,38 @@ nav-width: 20em
---
+## Nav section toggle icons
+
+Sections with `pagesvisibility: hidden` in `nav.yml` are collapsible. The
+expand and collapse icons are set independently at the top level of `theme.yml`
+(not inside `light:` or `dark:` — they are not per-mode).
+
+| Key | Default | Shown when |
+|---|---|---|
+| `nav-section-expand-icon` | `arrow_right` | section is collapsed |
+| `nav-section-collapse-icon` | `arrow_drop_down` | section is expanded |
+
+**Available pairs and their character:**
+
+| Expand icon | Collapse icon | Character |
+|---|---|---|
+| `arrow_right` | `arrow_drop_down` | Solid filled triangles — compact, classic |
+| `keyboard_arrow_right` | `keyboard_arrow_down` | Chevrons (›/˅) — lighter, more modern |
+| `keyboard_double_arrow_right` | `keyboard_double_arrow_down` | Double chevrons (»/⌄) — emphatic |
+| `expand_content` | `collapse_content` | Corner-arrows — editorial, spatial |
+| `add` | `minimize` | Plus/minus — very minimal, utilitarian |
+
+Mix and match freely — the expand and collapse icons do not have to come from
+the same pair, but keeping them visually related (same weight and style)
+usually reads better.
+
+**Matching icon style to nav style:** bold high-contrast themes (filled
+triangle, plus/minus) suit designs with strong typographic weight. Lighter
+themes pair better with chevrons. Editorial or magazine-style designs work
+well with `expand_content`/`collapse_content`.
+
+---
+
## Nav colour keys: when to set them
There are six nav colour keys divided into two groups: