diff --git a/docs/i18n/MOBILE_BUILD_METADATA.md b/docs/i18n/MOBILE_BUILD_METADATA.md
new file mode 100644
index 0000000..5236fd6
--- /dev/null
+++ b/docs/i18n/MOBILE_BUILD_METADATA.md
@@ -0,0 +1,11 @@
+# Mobile build metadata localisation
+
+3 November 2026. Independent bounded UI-language fix on `codex/i18n-build-metadata`, based on accepted integration `d3d338376444b8abdcaf7200f682faa3daf1ad10`. The existing i18n worktree was reused; original codex/i18n-accessible-labels ref remains4172c23d. This branch does not include the newer A3 foundation/navigation increments and must not replace their tree wholesale.
+
+Defect reproduced: in the Bokmål mobile account menu, the version was translated but the revision line remained literal `commit abc1234`, while the existing catalogue already provides `applicationVersionCommit` with `revisjon`. The new regression passed for English and failed for Bokmål before the fix.
+
+The existing AppShell now uses the existing combined localised version/revision message in that menu, retaining the version-only fallback when no commit was supplied. Caller-controlled admin metadata visibility is unchanged. No new keys, enabled locales, provider/model operation, API, data model or physical document changes. Historical188 dynamic-call reviews are not reopened or recounted; AppShell is absent from that resolution register. This is a static literal correction, not complete European localisation.
+
+Validation: 24 targeted tests in five suites PASSED (new EN/NB commit and version-only menu checks plus existing metadata/visibility, mobile readiness, catalogue and language-provider checks). Typecheck, scoped zero-warning ESLint and a fresh static production build PASSED. An initial test used an unsupported Testing Library `exact` role option; removed it, retaining exact string-name matching. The failed intermediate typecheck/build were superseded by the final successful run. Native Jest report: evidence/mobile-build-metadata/TESTS.json. No fresh browser/native-device, provider, backend or integrated security qualification is claimed for this separate branch.
+
+Integration requirement: preserve pending navigation review artifact992608c7. When the next relevant implementation entry is authorised, port only this small AppShell hunk and its regression test onto the reconciled A3 branch, then run combined navigation/metadata/language checks and build as appropriate. Do not cherry-pick older branch application/theme files or alter the original frozen translation register. No main merge or deployment.
diff --git a/docs/i18n/evidence/mobile-build-metadata/SOURCE_MANIFEST.json b/docs/i18n/evidence/mobile-build-metadata/SOURCE_MANIFEST.json
new file mode 100644
index 0000000..dc37a89
--- /dev/null
+++ b/docs/i18n/evidence/mobile-build-metadata/SOURCE_MANIFEST.json
@@ -0,0 +1,24 @@
+{
+ "recordedAtUtc": "2026-11-03T07:52:44.745521+00:00",
+ "base": "d3d338376444b8abdcaf7200f682faa3daf1ad10",
+ "policy": "UTF8 text/JSON SHA-256 after LF normalisation",
+ "sources": {
+ "job-tracker-ui/src/layout/AppShell.tsx": "603afbe21d854ec4af7b17ec75a58cfdd65cc053e72d63769d20df7a81c7acc3",
+ "job-tracker-ui/src/build-metadata-localisation.test.tsx": "065c5550a18f7b3c7dca9bbb26c5564a53a53eaf389e7c9695596fcbb2c06f6e",
+ "job-tracker-ui/src/i18n/translations.ts": "ed99d129f8702181429e10ec02f65f734220409fcba4de51d0d77a0d60871ea4",
+ "job-tracker-ui/package.json": "3745394e406cefa40d30a87e840bccb359be147bac6ffba736e2ae90898a8626",
+ "job-tracker-ui/package-lock.json": "bf31e90d7af03e8af059db2aaf893925b9e8881a30a1688034ed88ef45d4fcab"
+ },
+ "testReport": "1c7fb362460f2475fb4a782e26b56d1ee112595c3883cd6294a5b7ac6d72dd15",
+ "validation": {
+ "tests": "24 passed,5 suites",
+ "typecheck": "exit0",
+ "scopedLint": "exit0",
+ "productionBuild": "exit0"
+ },
+ "limits": [
+ "no fresh browser/native acceptance",
+ "not combined with pending A3 navigation review992608c7",
+ "188 historical dynamic-call review remains unchanged"
+ ]
+}
diff --git a/docs/i18n/evidence/mobile-build-metadata/TESTS.json b/docs/i18n/evidence/mobile-build-metadata/TESTS.json
new file mode 100644
index 0000000..a608147
--- /dev/null
+++ b/docs/i18n/evidence/mobile-build-metadata/TESTS.json
@@ -0,0 +1 @@
+{"numFailedTestSuites":0,"numFailedTests":0,"numPassedTestSuites":5,"numPassedTests":24,"numPendingTestSuites":0,"numPendingTests":0,"numRuntimeErrorTestSuites":0,"numTodoTests":0,"numTotalTestSuites":5,"numTotalTests":24,"openHandles":[],"snapshot":{"added":0,"didUpdate":false,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0},"startTime":1793692213748,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":[],"duration":250,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"en mobile account menu localises the supplied build metadata (User)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793692216894,"status":"passed","title":"en mobile account menu localises the supplied build metadata (User)"},{"ancestorTitles":[],"duration":117,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"nb mobile account menu localises the supplied build metadata (Bruker)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793692217144,"status":"passed","title":"nb mobile account menu localises the supplied build metadata (Bruker)"},{"ancestorTitles":[],"duration":103,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"en mobile account menu localises the supplied build metadata (User)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793692217261,"status":"passed","title":"en mobile account menu localises the supplied build metadata (User)"},{"ancestorTitles":[],"duration":98,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"nb mobile account menu localises the supplied build metadata (Bruker)","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793692217364,"status":"passed","title":"nb mobile account menu localises the supplied build metadata (Bruker)"}],"endTime":1793692217463,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\i18n-00-audit\\Job tracker\\job-tracker-ui\\src\\build-metadata-localisation.test.tsx","startTime":1793692214612,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":24,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"migrates the legacy Norwegian code and persists Bokmål using nb-NO","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793692218126,"status":"passed","title":"migrates the legacy Norwegian code and persists Bokmål using nb-NO"},{"ancestorTitles":[],"duration":7,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"hydrates an authenticated server preference without writing it back","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793692218150,"status":"passed","title":"hydrates an authenticated server preference without writing it back"},{"ancestorTitles":[],"duration":297,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a failed account language save keeps the local choice and offers a localized retry: Norsk","invocations":1,"location":null,"numPassingAsserts":11,"retryReasons":[],"startAt":1793692218157,"status":"passed","title":"a failed account language save keeps the local choice and offers a localized retry: Norsk"},{"ancestorTitles":[],"duration":277,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a failed account language save keeps the local choice and offers a localized retry: English","invocations":1,"location":null,"numPassingAsserts":11,"retryReasons":[],"startAt":1793692218454,"status":"passed","title":"a failed account language save keeps the local choice and offers a localized retry: English"},{"ancestorTitles":[],"duration":11,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a delayed language-save failure cannot offer a retry for a newer successful choice","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793692218731,"status":"passed","title":"a delayed language-save failure cannot offer a retry for a newer successful choice"},{"ancestorTitles":[],"duration":48,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"a previously delivered language retry cannot reverse a newer choice","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793692218742,"status":"passed","title":"a previously delivered language retry cannot reverse a newer choice"}],"endTime":1793692218790,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\i18n-00-audit\\Job tracker\\job-tracker-ui\\src\\i18n-provider.test.tsx","startTime":1793692217476,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":101,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"notification bell exposes its unread count and keyboard-accessible action","invocations":1,"location":null,"numPassingAsserts":5,"retryReasons":[],"startAt":1793692219441,"status":"passed","title":"notification bell exposes its unread count and keyboard-accessible action"},{"ancestorTitles":[],"duration":84,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"shows localized en build metadata only when the caller supplies the admin-only badge","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793692219542,"status":"passed","title":"shows localized en build metadata only when the caller supplies the admin-only badge"},{"ancestorTitles":[],"duration":81,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"shows localized nb build metadata only when the caller supplies the admin-only badge","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793692219626,"status":"passed","title":"shows localized nb build metadata only when the caller supplies the admin-only badge"},{"ancestorTitles":[],"duration":62,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"shell icon controls expose accessible names","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793692219707,"status":"passed","title":"shell icon controls expose accessible names"},{"ancestorTitles":[],"duration":73,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-08 notifications] an unavailable unread count stays unknown and its description follows the UI language","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793692219769,"status":"passed","title":"[P7-08 notifications] an unavailable unread count stays unknown and its description follows the UI language"},{"ancestorTitles":[],"duration":53,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-08 notifications] a recorded zero unread count has a truthful separate description","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793692219842,"status":"passed","title":"[P7-08 notifications] a recorded zero unread count has a truthful separate description"},{"ancestorTitles":[],"duration":76,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P7-08 notifications] the known unread count is described in Bokmål without changing the bell action's name","invocations":1,"location":null,"numPassingAsserts":4,"retryReasons":[],"startAt":1793692219895,"status":"passed","title":"[P7-08 notifications] the known unread count is described in Bokmål without changing the bell action's name"}],"endTime":1793692219972,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\i18n-00-audit\\Job tracker\\job-tracker-ui\\src\\app-shell-notifications.test.tsx","startTime":1793692218797,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":247,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-00 PRES-E07 E08 A03] en mobile names/current route ignore desktop collapse and retain metadata","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793692220596,"status":"passed","title":"[P5-00 PRES-E07 E08 A03] en mobile names/current route ignore desktop collapse and retain metadata"},{"ancestorTitles":[],"duration":205,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-00 PRES-E07 E08 A03] nb mobile names/current route ignore desktop collapse and retain metadata","invocations":1,"location":null,"numPassingAsserts":7,"retryReasons":[],"startAt":1793692220843,"status":"passed","title":"[P5-00 PRES-E07 E08 A03] nb mobile names/current route ignore desktop collapse and retain metadata"},{"ancestorTitles":[],"duration":51,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-00 PRES-E08 S05] toast retains its full existing display duration and dismiss action","invocations":1,"location":null,"numPassingAsserts":3,"retryReasons":[],"startAt":1793692221048,"status":"passed","title":"[P5-00 PRES-E08 S05] toast retains its full existing display duration and dismiss action"},{"ancestorTitles":[],"duration":21,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"[P5-00 PRES-E08] toast action is explicit and executes once","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"startAt":1793692221099,"status":"passed","title":"[P5-00 PRES-E08] toast action is explicit and executes once"}],"endTime":1793692221120,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\i18n-00-audit\\Job tracker\\job-tracker-ui\\src\\shell-readiness.test.tsx","startTime":1793692219979,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":[],"duration":7,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"English and Bokmål expose the same UI message keys","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793692221351,"status":"passed","title":"English and Bokmål expose the same UI message keys"},{"ancestorTitles":[],"duration":4,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"Bokmål preserves every English substitution variable","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793692221358,"status":"passed","title":"Bokmål preserves every English substitution variable"},{"ancestorTitles":[],"duration":2,"failing":false,"failureDetails":[],"failureMessages":[],"fullName":"supported UI catalogues contain no blank messages","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"startAt":1793692221362,"status":"passed","title":"supported UI catalogues contain no blank messages"}],"endTime":1793692221365,"message":"","name":"C:\\Users\\Connor\\.codex\\worktrees\\i18n-00-audit\\Job tracker\\job-tracker-ui\\src\\translation-catalogue.test.ts","startTime":1793692221131,"status":"passed","summary":""}],"wasInterrupted":false}
diff --git a/job-tracker-ui/src/build-metadata-localisation.test.tsx b/job-tracker-ui/src/build-metadata-localisation.test.tsx
new file mode 100644
index 0000000..7388d13
--- /dev/null
+++ b/job-tracker-ui/src/build-metadata-localisation.test.tsx
@@ -0,0 +1,26 @@
+import React from "react";
+import "@testing-library/jest-dom";
+import { fireEvent, render, screen, within } from "@testing-library/react";
+import JobTrackerThemeProvider from "./ThemeProvider";
+import { I18nProvider } from "./i18n/I18nProvider";
+import AppShell from "./layout/AppShell";
+
+jest.mock("@mui/material/useMediaQuery", () => ({ __esModule: true, default: () => true }));
+afterEach(() => localStorage.clear());
+
+test.each([
+ ["en", "User", "commit abc1234", "abc1234"],
+ ["nb", "Bruker", "revisjon abc1234", "abc1234"],
+ ["en", "User", "Application version 2.4.1", undefined],
+ ["nb", "Bruker", "Applikasjonsversjon 2.4.1", undefined],
+] as const)("%s mobile account menu localises the supplied build metadata (%s)", (language, user, expected, commit) => {
+ localStorage.setItem("uiLanguage", language);
+ render(
+ Sample content
+ );
+ fireEvent.click(screen.getByRole("button", { name: user }));
+ expect(screen.getByRole("menu")).toHaveTextContent(expected);
+ expect(within(screen.getByRole("menu")).getByText(/2\.4\.1/)).toBeVisible();
+});
diff --git a/job-tracker-ui/src/layout/AppShell.tsx b/job-tracker-ui/src/layout/AppShell.tsx
index 4b57d55..a23c88f 100644
--- a/job-tracker-ui/src/layout/AppShell.tsx
+++ b/job-tracker-ui/src/layout/AppShell.tsx
@@ -559,8 +559,7 @@ export default function AppShell({
>
{isMobile && buildVersion ? (
- {t("applicationVersion", { version: buildVersion })}
- {buildCommit ? commit {buildCommit} : null}
+ {buildCommit ? t("applicationVersionCommit", { version: buildVersion, commit: buildCommit }) : t("applicationVersion", { version: buildVersion })}
) : null}