diff --git a/frontend/src/app/pages/Dashboard/DashboardToolbar.tsx b/frontend/src/app/pages/Dashboard/DashboardToolbar.tsx
index dfa27b66..28bca414 100644
--- a/frontend/src/app/pages/Dashboard/DashboardToolbar.tsx
+++ b/frontend/src/app/pages/Dashboard/DashboardToolbar.tsx
@@ -9,10 +9,10 @@ import { styled } from '@mui/material/styles';
import AddRounded from '@mui/icons-material/AddRounded';
import HistoryRounded from '@mui/icons-material/HistoryRounded';
-// Custom rounded speech bubble with a small tail at the bottom-left,
-// outlined in currentColor with the bubble interior knocked out so the
-// orange button fill shows through. Matches Image #57 exactly; MUI's
-// rounded chat icons are either filled or tail-less.
+// Custom near-circular speech bubble with a teardrop tail at the
+// bottom-left. The bubble body is a rounded square with corner radius
+// ~half the body size, so it reads as a circle. Matches Image #57; MUI
+// rounded chat glyphs either fill the bubble or omit the tail.
function ChatBubbleTeardrop(props: { sx?: { fontSize?: number } }) {
const size = props.sx?.fontSize ?? 18;
return (
@@ -22,7 +22,7 @@ function ChatBubbleTeardrop(props: { sx?: { fontSize?: number } }) {
strokeLinecap="round" strokeLinejoin="round"
style={{ display: 'block' }}
>
-
+
);
}
@@ -406,52 +406,61 @@ const DashboardToolbar = React.forwardRef(
return (
<>
{(inputOpen || historyOpen) && (
- // Image #54: paired mode pills float above the composer/popover.
- // `+ New Chat` is decorative-active while inputOpen; clicking it
- // from history mode closes the popover and re-focuses the input.
- // `History` toggles the SchedulePopover.
-
+ // Image #54: paired mode pills above the composer/popover.
+ // The two states are mutually exclusive: opening one closes the
+ // other so the body underneath only renders one thing at a time.
+
{
- if (historyOpen) handleCloseHistory();
- if (!inputOpen) onNewAgent();
+ if (historyOpen) {
+ handleCloseHistory();
+ onNewAgent();
+ }
+ // If already in inputOpen, this is a no-op (we're already
+ // in new chat). The visible active styling tells the user
+ // that. Clicking again does nothing intentionally.
}}
role="button"
sx={{
- display: 'inline-flex', alignItems: 'center', gap: 0.4,
- fontSize: '0.82rem', fontWeight: 600,
+ display: 'inline-flex', alignItems: 'center', gap: 0.3,
+ fontSize: '0.74rem', fontWeight: 600,
color: c.text.primary,
bgcolor: c.bg.surface,
border: `1px solid ${inputOpen && !historyOpen ? c.border.medium : c.border.subtle}`,
boxShadow: inputOpen && !historyOpen ? c.shadow.sm : 'none',
- px: 1.1, py: 0.45, borderRadius: 999,
- cursor: 'pointer',
- '&:hover': { bgcolor: c.bg.elevated },
+ px: 0.85, py: 0.3, borderRadius: 999,
+ cursor: historyOpen ? 'pointer' : 'default',
+ '&:hover': historyOpen ? { bgcolor: c.bg.elevated } : {},
}}>
-
+
New Chat
{
- if (historyOpen) handleCloseHistory();
- else {
- setPopoverMode('search');
- setHistoryOpen(true);
+ if (historyOpen) {
+ handleCloseHistory();
+ return;
}
+ // Close the composer first; inputOpen takes precedence in
+ // the render branch below so the popover would be hidden
+ // behind it otherwise.
+ if (inputOpen) onCancel();
+ setPopoverMode('search');
+ setHistoryOpen(true);
}}
role="button"
sx={{
- display: 'inline-flex', alignItems: 'center', gap: 0.4,
- fontSize: '0.82rem', fontWeight: 600,
+ display: 'inline-flex', alignItems: 'center', gap: 0.3,
+ fontSize: '0.74rem', fontWeight: 600,
color: historyOpen ? c.text.primary : c.text.secondary,
bgcolor: c.bg.surface,
border: `1px solid ${historyOpen ? c.border.medium : c.border.subtle}`,
boxShadow: historyOpen ? c.shadow.sm : 'none',
- px: 1.1, py: 0.45, borderRadius: 999,
+ px: 0.85, py: 0.3, borderRadius: 999,
cursor: 'pointer',
'&:hover': { bgcolor: c.bg.elevated },
}}>
-
+
History