diff --git a/.project/designs/README.md b/.project/designs/README.md
index 1b48957f..d3b052c4 100644
--- a/.project/designs/README.md
+++ b/.project/designs/README.md
@@ -1,8 +1,22 @@
-# Tech / Culture Tree — Designs
+# Engineering Designs
-Visual reference for the research-tree UX. Both trees share the same screen
-(`KnowledgeTree` base scene); only the data source, vocabulary, and signal
-names change.
+Visual references for system architecture and screens. These designs document what is rendered, how data flows, and the geometric primitives the simulation runs on. They are not user-facing tutorials; they exist so someone modifying the relevant code can see the whole shape at once.
+
+## Hex grid
+
+The hex tile geometry — the SQ + QL formation duality that distinguishes our hex grid from every other 4X.
+
+| File | What it shows |
+|---|---|
+| [hex-formation-duality.md](hex-formation-duality.md) | Annotated hex with SQ-half / QL-half / spine; slot-direction lookup; ramifications inventory |
+| [hex-formation-sketch.html](hex-formation-sketch.html) | Interactive single-page mockup; click halves or slots to highlight |
+| [formation-slot-anatomy.md](formation-slot-anatomy.md) | A single slot's contents — role, exposure mask, damage order |
+
+**Source of truth.** [`public/games/age-of-dwarves/docs/HEX_GEOMETRY.md`](../../public/games/age-of-dwarves/docs/HEX_GEOMETRY.md) is the canonical specification. The engineering designs in this section illustrate it; if they conflict, the canonical doc wins.
+
+## Tech / Culture trees
+
+Visual reference for the research-tree UX. Both trees share the same screen (`KnowledgeTree` base scene); only the data source, vocabulary, and signal names change.
| File | What it shows |
|---|---|
@@ -15,16 +29,20 @@ names change.
| [data-flow.md](data-flow.md) | JSON → Rust → GDExtension → GDScript → UI pipeline |
| [unlock-categorization.md](unlock-categorization.md) | How each typed bucket renders (units / buildings / wonders / lenses / resources / mechanics) |
-**Audience.** These designs document what the screen *renders* and how the
-data flows. They are not user-facing tutorials; they exist so someone
-modifying the tree code (visual tweaks, a new pillar, a new unlock kind)
-can see the whole shape at once.
+**Source of truth.** The actual visual rendering lives in `src/game/engine/scenes/knowledge_tree/knowledge_tree.gd`. If a design disagrees with the code, the code wins — open a PR to update the design.
-**Source of truth.** The actual visual rendering lives in
-`src/game/engine/scenes/knowledge_tree/knowledge_tree.gd`. If a design
-disagrees with the code, the code wins — open a PR to update the design.
+## Other sketches
-**See also.** `UI_DESIGN_SYSTEM.md` (this directory) — top-level art
-direction brief covering mood, palette, and typography for the whole
-game. The per-screen designs above inherit those rules; they don't
-override them.
+Standalone HTML mockups for individual screens — not yet indexed under a category here:
+
+- `combat-preview-sketch.html`
+- `hud-sketch.html`
+- `main-menu-sketch.html`
+- `tech-tree-sketch.html`
+- `promotion-picker-sketch.html`
+- `city-screen-sketch.html`
+- `design-gallery.html`
+
+## See also
+
+`UI_DESIGN_SYSTEM.md` (this directory) — top-level art direction brief covering mood, palette, and typography for the whole game. The per-screen designs above inherit those rules; they don't override them.
diff --git a/public/games/age-of-dwarves/docs/combat/COMBAT_SYSTEM.md b/public/games/age-of-dwarves/docs/combat/COMBAT_SYSTEM.md
index 6e6cf0d4..7c294346 100644
--- a/public/games/age-of-dwarves/docs/combat/COMBAT_SYSTEM.md
+++ b/public/games/age-of-dwarves/docs/combat/COMBAT_SYSTEM.md
@@ -1,5 +1,16 @@
# Combat System
+## Formations & the Hex
+
+Combat in this game is positional in a way most hex 4Xs are not: every hex tile is two formation halves — a **square half (SQ)** and a **quadrilateral half (QL)** — joined at a 2-cell **spine**. `4 + 4 − 2 = 6`. Attackers from a given direction hit only the slots in the half that direction belongs to; spine units take damage from any direction; the leader is damaged last.
+
+Forest-cover-on-attack, flanking by direction-half partition, leader survivability, and facing-aware ZOC all derive from this geometry — they are not separate rules. The damage matrix and R/P/S system below layer on top of the positional model.
+
+- **Canonical geometry:** [`../HEX_GEOMETRY.md`](../HEX_GEOMETRY.md)
+- **Per-shape slot mapping:** [`FORMATIONS.md`](FORMATIONS.md)
+
+---
+
## Armor Types
| Armor | Description | Examples |
diff --git a/public/games/age-of-dwarves/docs/terrain/TERRAIN_SYSTEM.md b/public/games/age-of-dwarves/docs/terrain/TERRAIN_SYSTEM.md
index b8bf5420..8f22cdb0 100644
--- a/public/games/age-of-dwarves/docs/terrain/TERRAIN_SYSTEM.md
+++ b/public/games/age-of-dwarves/docs/terrain/TERRAIN_SYSTEM.md
@@ -1,5 +1,13 @@
# Terrain System
+## Tile structure
+
+Each hex tile carries **one** terrain (plains, forest, hill, …) at the data level — terrain fills the tile uniformly. The *perceived* boundary between two adjacent terrains is the shared hex edge, which is each tile's **QL** (quadrilateral half) on the side facing the other. This is the **biome contact membrane**: the geometric reason a forest unit attacking adjacent plains keeps its forest cover, and the reason all per-terrain combat modifiers are routed through the QL on the engagement side.
+
+For the SQ + QL partition itself and how it governs combat, flanking, and ZOC, see [`../HEX_GEOMETRY.md`](../HEX_GEOMETRY.md).
+
+---
+
## Terrain Types and Base Yields
| Terrain | Food | Production | Gold | Cultural resistance | Notes |
diff --git a/public/games/age-of-dwarves/guide/src/App.tsx b/public/games/age-of-dwarves/guide/src/App.tsx
index 6b8a6e39..53c2d0fa 100644
--- a/public/games/age-of-dwarves/guide/src/App.tsx
+++ b/public/games/age-of-dwarves/guide/src/App.tsx
@@ -25,7 +25,7 @@ import {
PopulationDashboardPage, EcologyWebPage, LairsPage, EvolutionMapPage,
RacesPage, PersonalityAxesPage, GovernmentPage, ErasPage, VictoryPage,
TechTreePage, CultureTreePage,
- UnitsPage, CombatPage, KeywordsPage, PromotionsPage, ItemsPage,
+ UnitsPage, CombatPage, HexGridPage, KeywordsPage, PromotionsPage, ItemsPage,
BuildingsPage, ImprovementsPage, WondersPage, CommunicationsPage,
HomePage, EarlyAccessPage,
EpisodeDwarvesPage, FullGamePage, ExpansionsPage, ToolsPage,
@@ -155,11 +155,13 @@ export default function App(): ReactElement {
{/* Military */}
} />
} />
+ } />
} />
} />
} />
} />
} />
+ } />
} />
} />
} />
diff --git a/public/games/age-of-dwarves/guide/src/app/lazy-pages.ts b/public/games/age-of-dwarves/guide/src/app/lazy-pages.ts
index 506a1721..9bd8ac58 100644
--- a/public/games/age-of-dwarves/guide/src/app/lazy-pages.ts
+++ b/public/games/age-of-dwarves/guide/src/app/lazy-pages.ts
@@ -43,6 +43,7 @@ export const CultureTreePage = lazy(() => import('@/pages/CultureTreePage
// Military
export const UnitsPage = lazy(() => import('@/pages/UnitsPage'))
export const CombatPage = lazy(() => import('@/pages/CombatPage'))
+export const HexGridPage = lazy(() => import('@/pages/HexGridPage'))
export const KeywordsPage = lazy(() => import('@/pages/KeywordsPage'))
export const PromotionsPage = lazy(() => import('@/pages/PromotionsPage'))
export const ItemsPage = lazy(() => import('@/pages/ItemsPage'))
diff --git a/public/games/age-of-dwarves/guide/src/pages/HexGridPage.tsx b/public/games/age-of-dwarves/guide/src/pages/HexGridPage.tsx
new file mode 100644
index 00000000..4d5a920b
--- /dev/null
+++ b/public/games/age-of-dwarves/guide/src/pages/HexGridPage.tsx
@@ -0,0 +1 @@
+export { HexGridPage as default } from '@magic-civ/guide-engine'
diff --git a/src/packages/guide/src/index.ts b/src/packages/guide/src/index.ts
index 6a64df92..1b3b9181 100644
--- a/src/packages/guide/src/index.ts
+++ b/src/packages/guide/src/index.ts
@@ -132,6 +132,7 @@ export { default as EcosystemPage } from './pages/engine/EcosystemPage'
export { default as EvolutionMapPage } from './pages/engine/EvolutionMapPage'
export { default as FoodWebPage } from './pages/engine/FoodWebPage'
export { default as MapTypesPage } from './pages/engine/MapTypesPage'
+export { default as HexGridPage } from './pages/engine/HexGridPage'
export { default as EpisodeDwarvesPage } from './pages/episodes/EpisodeDwarvesPage'
export { default as CrowdfundPage } from './pages/meta/CrowdfundPage'
export { default as ExpansionsPage } from './pages/meta/ExpansionsPage'
diff --git a/tooling/claude/CLAUDE.md b/tooling/claude/CLAUDE.md
index c91bf18e..2aada6a9 100644
--- a/tooling/claude/CLAUDE.md
+++ b/tooling/claude/CLAUDE.md
@@ -36,6 +36,7 @@ Modules live at `.claude/instructions/.md` (symlink resolves to `tooling/c
| When the task involves… | MUST load before acting… |
|---|---|
| Game 1 scope, Game 2 deferral, what-ships-where | `scope-game1-vs-game2.md` |
+| Hex tile geometry, formation duality (SQ + QL), why-hex, biome-edge contact | `public/games/age-of-dwarves/docs/HEX_GEOMETRY.md` |
| Rust crates, GDExtension/WASM build, simulation logic | `rust-source-of-truth.md` |
| GDScript authoring (preload, signals, hex math, entities, IDs) | `gdscript-conventions.md` |
| "Where does this file go?" / `src/` tree / symlinks | `file-organization.md` |