diff --git a/.claude/ux-guidelines.md b/.claude/ux-guidelines.md
index 5863dfd..e862a13 100644
--- a/.claude/ux-guidelines.md
+++ b/.claude/ux-guidelines.md
@@ -177,3 +177,78 @@ History should remain collapsed unless the user chooses to inspect previous reas
### Original situation
Once an investigation has started, the original scenario becomes reference material rather than the primary focus.
+
+## Interaction Modes
+
+The Confidence Engine operates in two distinct modes.
+
+### Workspace Mode
+
+The user is reading, thinking, and providing information.
+
+The interface should:
+
+- present the current investigation
+- allow the user to answer
+- show the current understanding
+- provide investigation history
+
+The workspace is interactive.
+
+---
+
+### Reasoning Mode
+
+The engine is analysing the available evidence.
+
+The interface should:
+
+- clearly indicate that reasoning is in progress
+- temporarily suspend the workspace
+- reassure the user that their input has been accepted
+- avoid displaying partial or changing reasoning
+
+The workspace is paused until reasoning completes.
+
+---
+
+### Transition
+
+Every submission follows the same lifecycle:
+
+User submits information
+↓
+Workspace pauses
+↓
+Reasoning mode
+↓
+Updated workspace appears
+
+The interaction should be identical whether the submission is:
+
+- the initial situation
+- an investigation answer
+- a future uploaded document
+- any other evidence
+
+Users should never wonder whether their input has been accepted or whether the engine is still reasoning.
+
+---
+
+## Consistent Submission Lifecycle
+
+Every submission follows the same lifecycle regardless of context.
+
+1. User submits → workspace pauses immediately, stale content disappears
+2. Reasoning mode appears with loading overlay (spinner, rotating status messages, elapsed timer)
+3. Updated workspace returns or error state appears
+
+The loading card must appear before any async request begins and remain visible until the result arrives.
+
+During reasoning mode:
+- The workspace is fully hidden (not just disabled)
+- No stale question, response form, or active indicators are visible
+- The Investigation Summary Panel shows "Reasoning" rather than "Investigation in progress"
+- Recovery states render on top of the loading overlay when applicable
+
+This applies equally to initial analysis and all update submissions.
diff --git a/components/investigation-summary-panel.jsx b/components/investigation-summary-panel.jsx
index 875d794..c3a3b23 100644
--- a/components/investigation-summary-panel.jsx
+++ b/components/investigation-summary-panel.jsx
@@ -29,7 +29,7 @@ function humaniseDuration(seconds) {
/* ── Component ────────────────────────────────────────────── */
-function InvestigationSummaryPanel({ graph, selectedQuestion, result }) {
+function InvestigationSummaryPanel({ graph, selectedQuestion, result, updateStatus }) {
// ── Current status ────────────────────────────────────────────
// TODO: reasoning should emit an explicit status field such as
// "investigating", "evidence_limit_reached", "resolution_achieved".
@@ -38,7 +38,9 @@ function InvestigationSummaryPanel({ graph, selectedQuestion, result }) {
const hasGraph = Boolean(graph);
let currentStatus;
- if (!hasGraph) {
+ if (updateStatus === "loading") {
+ currentStatus = { label: "Reasoning", level: "investigating" };
+ } else if (!hasGraph) {
currentStatus = { label: "Not started", level: "idle" };
} else if (isInvestigating) {
currentStatus = { label: "Investigation in progress", level: "investigating" };
diff --git a/components/reasoning-workspace.jsx b/components/reasoning-workspace.jsx
index 3a7097e..661be78 100644
--- a/components/reasoning-workspace.jsx
+++ b/components/reasoning-workspace.jsx
@@ -673,7 +673,7 @@ export default function ReasoningWorkspace({
) : (
<>
{/* ── Investigation summary card ─────────────── */}
-
+
{/* ── Active investigation: question + form (top priority) ─ */}
{canAnswer && (
diff --git a/components/scenario-form.jsx b/components/scenario-form.jsx
index 109171e..91f677c 100644
--- a/components/scenario-form.jsx
+++ b/components/scenario-form.jsx
@@ -443,7 +443,7 @@ export default function ScenarioForm() {
)}
{/* ── Main result workspace ─────────────────────── */}
- {(status === "success" || status === "error" || updateStatus === "success") && (
+ {(status === "success" || status === "error") && updateStatus !== "loading" && (
)}
+ {/* ── Update loading (reasoning mode) ─────────── */}
+ {updateStatus === "loading" && status === "success" && (
+
+ )}
+
{/* ── Continue later banner when session was restored ── */}
{status === "success" && result?.updatedAt && (
{ clearSession(); setStatus("idle"); setResult(null); setAnswer(""); setUpdateStatus("idle"); setCurrentUnderstanding(null); }} />
diff --git a/tests/e2e/happy-path.spec.js b/tests/e2e/happy-path.spec.js
index bdb4b51..b987b52 100644
--- a/tests/e2e/happy-path.spec.js
+++ b/tests/e2e/happy-path.spec.js
@@ -304,4 +304,45 @@ test("loading overlay appears on submit and disappears after response", async ({
// Normal journey test: wait directly for the stable resulting state.
await waitForWorkspaceReady(page);
+});
+
+/* ═══════ Test: update loading hides workspace and shows overlay ═ */
+
+test("update submission hides workspace, shows reasoning overlay, then restores workspace", async ({ page }) => {
+ // Use normal (700ms) delay so the loading overlay is observable during updates
+ await page.goto("/");
+
+ await page.evaluate(() => {
+ window.__MOCK_ENABLED = true;
+ window.__MOCK_DELAY = "normal";
+ window.__MOCK_SCENARIO = "complete";
+ });
+
+ // Start investigation
+ const textarea = page.locator("textarea[placeholder*=Describe]");
+ await textarea.fill(INVESTIGATION_SCENARIOS[0].centralStatement);
+ await page.getByRole("button", { name: "Analyse" }).click();
+
+ await waitForWorkspaceReady(page);
+
+ // Workspace visible after initial analysis
+ await expect(page.locator('[data-testid="reasoning-workspace"]')).toBeVisible();
+
+ // Submit an answer to trigger update loading
+ const answerTextarea = page.locator('textarea[placeholder*=Answer]');
+ if (await answerTextarea.isVisible({ timeout: 3000 })) {
+ await answerTextarea.fill("The figures are comparable.");
+ await page.getByRole("button", { name: "Update situation" }).click();
+
+ // Workspace should disappear during update loading (reasoning mode)
+ await expect(page.locator('[data-testid="reasoning-workspace"]')).not.toBeVisible({ timeout: 5_000 });
+
+ // Loading overlay should be visible (with role="status" for accessibility)
+ const overlay = page.locator('[data-testid="loading-overlay"][role="status"]');
+ await expect(overlay).toBeVisible({ timeout: 5_000 });
+
+ // Status text should indicate reasoning mode (update-specific copy)
+ const statusText = overlay.getByRole("status");
+ await expect(statusText).toHaveText(/Working through your situation/);
+ }
});
\ No newline at end of file