diff --git a/.changeset/fn-7450-mobile-chat-header.md b/.changeset/fn-7450-mobile-chat-header.md
new file mode 100644
index 0000000000..dce5e39365
--- /dev/null
+++ b/.changeset/fn-7450-mobile-chat-header.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Collapse mobile Chat thread controls into one compact header row.
+category: feature
+dev: Mobile direct-chat moves back/session controls into ViewHeader and floats the Markdown/plain toggle.
diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md
index d0064cb0c3..5f2d0a5a31 100644
--- a/docs/dashboard-guide.md
+++ b/docs/dashboard-guide.md
@@ -411,7 +411,8 @@ Chat view provides project-scoped conversations with agents.
- If you queue follow-up user messages while the assistant is still streaming, Chat persists them per session, stacks each queued preview above the input box with one shared divider, and restores/sends them one at a time in FIFO order once each active response finishes if you leave and return.
- Chat message lists now track near-bottom scroll state: while you are reading older messages, live streaming/new replies do not force-scroll; a **Latest** jump control appears until you return to the tail.
- On mobile direct-chat threads, entering a thread and restoring Chat after tab/page visibility returns re-anchors to the newest message (`scrollTop = scrollHeight`) so the view always opens at the live tail.
-- On mobile direct-chat threads, tapping the active title/identity in the thread header opens a lightweight conversation dropdown so you can switch to another direct session or start a New Chat without backing out to the sidebar list first; long conversation titles now stay readable in the dropdown via wrapped option text and taller touch-friendly rows.
+- On mobile direct-chat threads, the top Chat header collapses into one compact row: the back button and active conversation dropdown live beside the Chat icon, while the visible “Chat” title is hidden to preserve transcript space. Tapping the active conversation opens a lightweight dropdown so you can switch to another direct session or start a New Chat without backing out to the sidebar list first; long conversation titles stay readable in the dropdown via wrapped option text and taller touch-friendly rows.
+- On mobile direct-chat threads, the single thread-wide Markdown/plain eye toggle floats above the transcript/composer area instead of occupying a second header row; desktop/tablet keeps the toggle in the thread header.
- Direct chat sessions can be renamed from the sidebar row edit button, the desktop conversation context menu, and the mobile session switcher; blank rename submissions clear the custom title so the default session label is shown again.
diff --git a/packages/dashboard/app/components/ChatView.css b/packages/dashboard/app/components/ChatView.css
index 104f6af6ef..36a01af426 100644
--- a/packages/dashboard/app/components/ChatView.css
+++ b/packages/dashboard/app/components/ChatView.css
@@ -768,6 +768,33 @@ Mobile chat session switching needs a dedicated rename tap target beside each se
min-width: 0;
}
+/*
+FNXC:ChatHeader 2026-07-02-00:00:
+Mobile direct-chat detail uses ViewHeader as the only visible header row. Keep the Chat icon/title relationship available to assistive tech while visually collapsing only the text label, and let the moved session switcher consume the action row width without duplicating the old thread-header controls.
+*/
+.chat-view--mobile-direct-thread > .view-header .view-header__title span {
+ position: absolute;
+ inline-size: var(--btn-border-width);
+ block-size: var(--btn-border-width);
+ margin: calc(var(--btn-border-width) * -1);
+ overflow: hidden;
+ clip-path: inset(50%);
+ white-space: nowrap;
+}
+
+.chat-view--mobile-direct-thread > .view-header .view-header__actions {
+ flex: 1 1 auto;
+ justify-content: flex-start;
+}
+
+.chat-view--mobile-direct-thread .chat-back-btn {
+ flex: 0 0 auto;
+}
+
+.chat-view--mobile-direct-thread .chat-mobile-session-menu {
+ flex: 1 1 auto;
+}
+
@media (max-width: 768px), (max-height: 480px) {
.chat-view-header-scope-toggle {
flex-basis: clamp(112px, 42vw, 180px);
@@ -911,9 +938,10 @@ In the narrow/mobile chat layout there is no room for an expand/maximize afforda
}
}
-/* Single thread-wide markdown / plain-text toggle, anchored to the right of
- * the header next to "New Chat". Replaces the per-message eye toggle that
- * used to live inside every assistant bubble. */
+/*
+FNXC:ChatRenderMode 2026-07-02-00:00:
+Chat keeps one thread-wide Markdown/plain control: desktop/tablet anchors it in the thread identity header, while mobile direct-thread view floats the same button above the transcript/composer so it does not reintroduce a second header row or per-message toggles.
+*/
.chat-thread-header-render-toggle {
margin-left: auto;
flex-shrink: 0;
@@ -948,6 +976,25 @@ In the narrow/mobile chat layout there is no room for an expand/maximize afforda
color: var(--text);
}
+.chat-thread-header-render-toggle--floating {
+ position: absolute;
+ right: var(--space-md);
+ bottom: calc((var(--space-lg) * 2.5) + (var(--space-md) * 2) + var(--space-sm));
+ z-index: 3;
+ width: calc(var(--space-lg) * 2.25);
+ height: calc(var(--space-lg) * 2.25);
+ min-width: calc(var(--space-lg) * 2.25);
+ min-height: calc(var(--space-lg) * 2.25);
+ border: var(--btn-border-width) solid var(--border);
+ border-radius: var(--radius-full);
+ background: var(--surface);
+ box-shadow: var(--shadow-md);
+}
+
+.chat-thread-header-render-toggle--floating:hover {
+ background: var(--surface-hover);
+}
+
/* Messages */
.chat-messages {
flex: 1 1 auto;
diff --git a/packages/dashboard/app/components/ChatView.tsx b/packages/dashboard/app/components/ChatView.tsx
index 0436c64fd2..530f137545 100644
--- a/packages/dashboard/app/components/ChatView.tsx
+++ b/packages/dashboard/app/components/ChatView.tsx
@@ -2151,6 +2151,7 @@ export function ChatView({ projectId, addToast, floating = false, compactLayout
})
: null;
const showMobileSessionSwitcher = isChatMobile && chatScope === "direct" && !!activeSession;
+ const showMobileDirectThreadHeaderControls = isChatMobile && chatScope === "direct" && hasThreadInView;
const agentName =
agentsMap.get(activeSession?.agentId ?? "")?.name ||
@@ -2578,6 +2579,71 @@ export function ChatView({ projectId, addToast, floating = false, compactLayout
FNXC:ChatHeader 2026-06-22-18:44:
Very narrow chat headers collapse Direct/Rooms to icons while retaining aria-selected tabs and text labels for wider headers. The segmented control must stay height-aligned with the ViewHeader action row, so icon+label markup is stable and CSS hides only the label.
*/
+ const mobileDirectSessionSwitcher = showMobileSessionSwitcher ? (
+
+
+ {mobileSessionMenuOpen && (
+
+ {filteredSessions.map((session) => (
+
+
+
+
+ ))}
+ {/*
+ FNXC:Chat 2026-06-27-00:00:
+ Mobile Direct-scope quick session switching must let users start a new chat without leaving the open thread. Route this affordance through the same setShowNewDialog(true) / NewChatDialog path as the header and sidebar-footer controls.
+ */}
+
+