diff --git a/AGENTS.md b/AGENTS.md
index 1a183f1..f44ec6d 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -154,6 +154,7 @@ make docker-multiarch IMAGE=ghcr.io/owner/yggdrasil:latest # amd64+arm64, push
- **`unreachable!()` is permitted ONLY in `#[cfg(not(feature = "server"))]` stubs** of server functions — these branches are compiled out of the real server build and exist solely to satisfy the WASM target's type checker.
- **Build-tool binaries** (`src/bin/*`) and **`#[cfg(test)]` modules** are exempt — `unwrap`/`expect`/`panic` are idiomatic in tests and one-shot codegen tools.
- **If clippy's `unwrap_used` / `expect_used` lints are later wired in** (`[lints]` table in `Cargo.toml`), the exemptions above are the intended `allow` set; do not relax them further without a documented invariant.
+17. **Reuse shared UI components — never hand-roll a duplicate.** Before writing any `rsx!` element with an inline Tailwind class string, scan `src/components/` for an existing component or style constant and reuse it. Two modules own this surface: `ui.rs` (display atoms — `Pagination`, `StatusBadge`, `Tooltip`, `Popover`, `FilterTabs`, `LoadingButton`; plus class constants `BTN_PRIMARY`/`BTN_PRIMARY_SM`/`BTN_OUTLINE`/`BTN_DANGER_OUTLINE`/`BTN_SECONDARY`/`BTN_TEXT_*`/`BTN_SOLID_*`/`BTN_CLOSE_ICON`/`BTN_ICON`/`ADMIN_CARD_CLASS`/`ADMIN_TABLE_CLASS`/`ADMIN_ROW_HOVER`/`BADGE_BASE`/`CHECKBOX_CLASS`/`SPINNER_SVG`) and `forms.rs` (form controls — `FormInput`, `FormSelect`, `FormLabel`, `AlertBox`; plus class constants `INPUT_CLASS`/`INPUT_INLINE_CLASS`/`BUTTON_PRIMARY_CLASS`/`FORM_SELECT_COMPACT_CLASS`). Use `FormInput` with the right `class` prop (`INPUT_CLASS` = full-width form field, `INPUT_INLINE_CLASS` = flank a button / fill remaining width) instead of a bespoke ``; use `FormSelect` instead of a native `