# Shared navigation layout contract Core owns `NavigationPreferenceEditor`, ordered layout resolution, and rail rendering. Admin, Tenancy, personal Settings and Views reuse this editor. They own loading, authorization, Save, Reload and dirty-state guards; the editor emits a draft only after a real edit. A drag onto the same position, keyboard pickup/drop without movement, and opening inherited settings do not save or create an override. ## Stored document and precedence The version-1 navigation document retains `order`, `hidden` and `locked` and adds optional `separators`, each containing a stable `separator:`-prefixed ID and an optional plain-text label of at most 120 characters. Separator IDs and module navigation IDs occupy the same `order` list. Separators are presentation metadata and never become routes, modules, permissions or authorized surfaces. Omitting `separators` or using null preserves inherited grouping. An explicit empty array removes grouping. Resetting the entire navigation document to null removes that scope's override. Existing order-only documents remain readable; the editor materializes group markers into a draft only when edited. Unknown optional-module order IDs remain stored when currently visible items move, so uninstalling or temporarily disabling a module does not destroy its preference. User order and visibility take precedence over tenant and system preferences. System and tenant visibility locks accumulate; lower scopes cannot hide those destinations, but may move them. Views may supply a navigation presentation inside the already authorized and View-filtered destination set. An explicit personal order/layout or visibility preference takes precedence over that presentation, not over authorization or the View's surface restrictions. Views cannot introduce locks. When multiple modules contribute one product entry, it inherits the earliest effective rail position/section and all authorized contributors' locks; this does not change operational route selection. An owner alias in View layout refers to that composed entry. ## Interaction and reuse Drag the handle to move either a module or separator before/after another row. The handle also supports Space to pick up, arrow keys to move, Enter to drop, and Escape to restore the pre-drag draft. Up/down buttons offer the same moves. Add module restores an available hidden entry; Remove only hides navigation, never uninstalls a module or deletes records. Add separator inserts a new optional group label. Remove separator changes grouping only. Expanded rails display group labels without divider lines. Collapsed rails replace these labels with horizontal group dividers; empty groups are not rendered. Both modes use the same resolved order. The editor receives product-area metadata to show inherited grouping and uses container-responsive rows rather than a fixed dialog/page width. Its English and German labels load with the editor, not the initial shell bundle. Give the ordered list a full-span `GridItem` when a settings page contains multiple cards; do not squeeze the entire editor into an otherwise half-empty two-column settings grid. Central spacing tokens provide real row padding and separation at both wide and narrow sizes, covered by computed-style assertions. ## Verification Core navigation unit tests and HTTP settings/profile tests cover persistence, separator inheritance, explicit flat layouts, reset and locks. Module-capability tests cover View aliases, composed destinations and personal precedence. The browser conformance suite tests all four editor scopes, pointer/keyboard moves, no-op cleanliness, unavailable-module preservation, collapsed dividers and a German narrow read-only layout. Use the same shared component for future navigation-definition surfaces rather than implementing another sortable list.