diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7fa5eb2..3c3d1db 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -12,6 +12,7 @@ Thank you for your interest in contributing to Project NOMAD! Community contribu
- [Before You Start](#before-you-start)
- [Getting Started](#getting-started)
- [Development Workflow](#development-workflow)
+- [UI Consistency](#ui-consistency)
- [Commit Messages](#commit-messages)
- [Release Notes](#release-notes)
- [Versioning](#versioning)
@@ -102,6 +103,34 @@ Because NOMAD relies heavily on Docker, we actually recommend against installing
---
+## UI Consistency
+
+N.O.M.A.D.'s guiding principle is that **user-friendliness is paramount**: a control that looks or behaves differently from the rest of the app reads as broken to a non-technical user. New frontend (inertia/React) work should be visually and behaviorally uniform with what is already there. Before adding a UI element, look at its neighbors and reuse the shared building blocks rather than hand-rolling a one-off.
+
+**Reuse the shared components** in `admin/inertia/components/` (and `.../components/inputs/`):
+
+| Need | Use | Not |
+|------|-----|-----|
+| Binary on/off setting | `Switch` | a raw `` |
+| Explanatory hover help | `InfoTooltip` | a raw `title=` attribute or a bespoke tooltip |
+| Modal / confirmation dialog | `StyledModal` | a hand-built overlay |
+| Text field | `Input` | a bare `` |
+| Section heading | `StyledSectionHeader` | ad-hoc heading markup |
+
+Grep for an existing component before building a new one.
+
+**Match the neighbors.** Copy the exact classes and conventions of adjacent elements:
+
+- **Labels:** match punctuation and casing of sibling labels. If the field beside yours reads `Model:` (with a colon), yours should read `Thinking:`, not `Thinking`. Reuse the same typography tokens (e.g. `text-sm text-text-secondary`).
+- **Theme:** use design tokens (`text-*`, `bg-*`, `border-*`) so the element works in light and dark mode. Never hardcode colors.
+- **Placement:** make sure popovers and tooltips are not clipped or crushed against a viewport edge, including when the trigger sits near an edge of the screen.
+
+**When a raw control is fine.** These conventions are about matching intent, not banning primitives. A raw checkbox is appropriate for a multi-select list or a consent box; radio groups and native selects are fine where a shared component does not exist. The point is to reach for the shared component when your case matches its intent (a binary setting toggle should be a `Switch`), not to eliminate primitives.
+
+**Test UI changes in a real browser.** Most of these conventions are judgment calls that tooling cannot fully enforce, so the single most important habit is to load your change in a browser against a running instance before submitting. Several classes of issue (clipped or cramped tooltips, layout breaking at different window widths, blank-screen render errors) are invisible to type-checking and only show up when you actually look at the page. Check the states that should appear *and* the states that should be hidden, and try more than one window width when layout or positioning is involved.
+
+---
+
## Commit Messages
This project uses [Conventional Commits](https://www.conventionalcommits.org/). All commit messages must follow this format: