diff --git a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png
index a2e2fc3f1b967b26480683520384b0c83aa98999..db20f97c9684d79de15ae77daf85cae9ff409547 100644
Binary files a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png and b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-1-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png
index 6240ae33bc16d6a11b29a30885b9f498615b3459..dd98f0c1392566992385d5ef250c5c1a8cb355ec 100644
Binary files a/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png and b/packages/desktop-client/e2e/accounts.test.js-snapshots/Accounts-closes-an-account-2-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png
index 343c6cedfb66da0ce8a28f49a2b50bbea2399539..58229d4ae3e4a0aa362e4882381a67302bf34f95 100644
Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png and b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png
index dd9aab12b5f932ae5f6e467aca50e551088c1a3f..278d72136022b255b899859161b5f9763f4d3731 100644
Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png and b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png differ
diff --git a/packages/desktop-client/src/components/Modals.tsx b/packages/desktop-client/src/components/Modals.tsx
index bdd7cc587c733b56ef18348f80ef283428469e16..2953f58e4a03cf21dba2ead2a7e161c9623dace5 100644
--- a/packages/desktop-client/src/components/Modals.tsx
+++ b/packages/desktop-client/src/components/Modals.tsx
@@ -11,8 +11,10 @@ import * as monthUtils from 'loot-core/src/shared/months';
 import { useActions } from '../hooks/useActions';
 import { useSyncServerStatus } from '../hooks/useSyncServerStatus';
 
+import { ModalTitle } from './common/Modal';
 import { AccountAutocompleteModal } from './modals/AccountAutocompleteModal';
 import { AccountMenuModal } from './modals/AccountMenuModal';
+import { BudgetMenuModal } from './modals/BudgetMenuModal';
 import { CategoryAutocompleteModal } from './modals/CategoryAutocompleteModal';
 import { CategoryGroupMenuModal } from './modals/CategoryGroupMenuModal';
 import { CategoryMenuModal } from './modals/CategoryMenuModal';
@@ -46,7 +48,7 @@ import { ScheduledTransactionMenuModal } from './modals/ScheduledTransactionMenu
 import { SelectLinkedAccounts } from './modals/SelectLinkedAccounts';
 import { SimpleFinInitialise } from './modals/SimpleFinInitialise';
 import { SingleInputModal } from './modals/SingleInputModal';
-import { SwitchBudgetType } from './modals/SwitchBudgetType';
+import { SwitchBudgetTypeModal } from './modals/SwitchBudgetTypeModal';
 import { TransferModal } from './modals/TransferModal';
 import { DiscoverSchedules } from './schedules/DiscoverSchedules';
 import { PostsOfflineNotification } from './schedules/PostsOfflineNotification';
@@ -313,7 +315,7 @@ export function Modals() {
           return (
             <SingleInputModal
               modalProps={modalProps}
-              title="New Category"
+              title={<ModalTitle title="New Category" shrinkOnOverflow />}
               inputPlaceholder="Category name"
               buttonText="Add"
               onValidate={options.onValidate}
@@ -325,7 +327,7 @@ export function Modals() {
           return (
             <SingleInputModal
               modalProps={modalProps}
-              title="New Category Group"
+              title={<ModalTitle title="New Category Group" shrinkOnOverflow />}
               inputPlaceholder="Category group name"
               buttonText="Add"
               onValidate={options.onValidate}
@@ -400,10 +402,10 @@ export function Modals() {
 
         case 'switch-budget-type':
           return (
-            <SwitchBudgetType
+            <SwitchBudgetTypeModal
               key={name}
               modalProps={modalProps}
-              onSwitch={options?.onSwitch}
+              onSwitch={options.onSwitch}
             />
           );
 
@@ -549,6 +551,21 @@ export function Modals() {
             />
           );
 
+        case 'budget-menu':
+          return (
+            <NamespaceContext.Provider
+              key={name}
+              value={monthUtils.sheetForMonth(options.month)}
+            >
+              <BudgetMenuModal
+                modalProps={modalProps}
+                month={options.month}
+                onToggleHiddenCategories={options.onToggleHiddenCategories}
+                onSwitchBudgetType={options.onSwitchBudgetType}
+              />
+            </NamespaceContext.Provider>
+          );
+
         default:
           console.error('Unknown modal:', name);
           return null;
diff --git a/packages/desktop-client/src/components/common/Menu.tsx b/packages/desktop-client/src/components/common/Menu.tsx
index 38d0b9a9c3a106cf9b2dfd39557ea997974a7451..105f703aefdb59c162e95f900ff5a7b2120d12c9 100644
--- a/packages/desktop-client/src/components/common/Menu.tsx
+++ b/packages/desktop-client/src/components/common/Menu.tsx
@@ -144,7 +144,6 @@ export function Menu<T extends MenuItem>({
           );
         }
 
-        const lastItem = items[idx - 1];
         const Icon = item.icon;
 
         return (
@@ -153,14 +152,9 @@ export function Menu<T extends MenuItem>({
             key={item.name}
             style={{
               cursor: 'default',
-              padding: '9px 10px',
-              marginTop:
-                idx === 0 ||
-                lastItem === Menu.line ||
-                lastItem.type === Menu.label
-                  ? 0
-                  : -3,
+              padding: 10,
               flexDirection: 'row',
+              justifyContent: 'center',
               alignItems: 'center',
               color: theme.menuItemText,
               ...(item.disabled && { color: theme.buttonBareDisabledText }),
diff --git a/packages/desktop-client/src/components/common/Modal.tsx b/packages/desktop-client/src/components/common/Modal.tsx
index 9c07af48ff0f988864199c645326372c73309ae2..8435bdbedb47ac361f7b62b761a9dac461182d92 100644
--- a/packages/desktop-client/src/components/common/Modal.tsx
+++ b/packages/desktop-client/src/components/common/Modal.tsx
@@ -10,7 +10,9 @@ import { useHotkeysContext } from 'react-hotkeys-hook';
 import ReactModal from 'react-modal';
 
 import { AnimatedLoading } from '../../icons/AnimatedLoading';
+import { SvgLogo } from '../../icons/logo';
 import { SvgDelete } from '../../icons/v0';
+import { useResponsive } from '../../ResponsiveProvider';
 import { type CSSProperties, styles, theme } from '../../style';
 import { tokens } from '../../tokens';
 
@@ -19,21 +21,16 @@ import { Input } from './Input';
 import { Text } from './Text';
 import { View } from './View';
 
-type ModalChildrenProps = {
-  isEditingTitle: boolean;
-};
-
 export type ModalProps = {
-  title?: string;
+  title?: ReactNode;
   isCurrent?: boolean;
   isHidden?: boolean;
-  children: ReactNode | ((props: ModalChildrenProps) => ReactNode);
+  children: ReactNode | (() => ReactNode);
   size?: { width?: CSSProperties['width']; height?: CSSProperties['height'] };
   padding?: CSSProperties['padding'];
   showHeader?: boolean;
   leftHeaderContent?: ReactNode;
   showTitle?: boolean;
-  editableTitle?: boolean;
   showClose?: boolean;
   showOverlay?: boolean;
   loading?: boolean;
@@ -42,11 +39,9 @@ export type ModalProps = {
   stackIndex?: number;
   parent?: HTMLElement;
   style?: CSSProperties;
-  titleStyle?: CSSProperties;
   contentStyle?: CSSProperties;
   overlayStyle?: CSSProperties;
   onClose?: () => void;
-  onTitleUpdate?: (title: string) => void;
 };
 
 export const Modal = ({
@@ -58,7 +53,6 @@ export const Modal = ({
   showHeader = true,
   leftHeaderContent,
   showTitle = true,
-  editableTitle = false,
   showClose = true,
   showOverlay = true,
   loading = false,
@@ -67,13 +61,12 @@ export const Modal = ({
   stackIndex,
   parent,
   style,
-  titleStyle,
   contentStyle,
   overlayStyle,
   children,
   onClose,
-  onTitleUpdate,
 }: ModalProps) => {
+  const { isNarrowWidth } = useResponsive();
   const { enableScope, disableScope } = useHotkeysContext();
 
   // This deactivates any key handlers in the "app" scope
@@ -83,20 +76,6 @@ export const Modal = ({
     return () => disableScope(scopeId);
   }, [enableScope, disableScope, scopeId]);
 
-  const [isEditingTitle, setIsEditingTitle] = useState(false);
-  const [_title, setTitle] = useState(title);
-
-  const onTitleClick = () => {
-    setIsEditingTitle(true);
-  };
-
-  const _onTitleUpdate = newTitle => {
-    if (newTitle !== title) {
-      onTitleUpdate?.(newTitle);
-    }
-    setIsEditingTitle(false);
-  };
-
   return (
     <ReactModal
       isOpen={true}
@@ -171,38 +150,27 @@ export const Modal = ({
         {showHeader && (
           <View
             style={{
+              justifyContent: 'center',
+              alignItems: 'center',
               padding: 20,
               position: 'relative',
-              flexShrink: 0,
+              height: 80,
             }}
           >
             <View
               style={{
                 position: 'absolute',
                 left: 0,
-                top: 0,
-                bottom: 0,
-                justifyContent: 'center',
-                alignItems: 'center',
+                marginRight: !isNarrowWidth ? 5 : undefined,
+                marginLeft: !isNarrowWidth ? 15 : undefined,
               }}
             >
-              <View
-                style={{
-                  flexDirection: 'row',
-                  marginLeft: 15,
-                }}
-              >
-                {leftHeaderContent && !isEditingTitle
-                  ? leftHeaderContent
-                  : null}
-              </View>
+              {leftHeaderContent}
             </View>
 
             {showTitle && (
               <View
                 style={{
-                  flex: 1,
-                  alignSelf: 'center',
                   textAlign: 'center',
                   // We need to force a width for the text-overflow
                   // ellipses to work because we are aligning center.
@@ -210,37 +178,16 @@ export const Modal = ({
                   width: 'calc(100% - 40px)',
                 }}
               >
-                {isEditingTitle ? (
-                  <Input
-                    style={{
-                      fontSize: 25,
-                      fontWeight: 700,
-                      textAlign: 'center',
-                    }}
-                    value={_title}
-                    onChange={e => setTitle(e.target.value)}
-                    onKeyDown={e => {
-                      if (e.key === 'Enter') {
-                        e.preventDefault();
-                        _onTitleUpdate(e.currentTarget.value);
-                      }
-                    }}
-                    onBlur={e => _onTitleUpdate(e.target.value)}
+                {!title ? (
+                  <SvgLogo
+                    width={30}
+                    height={30}
+                    style={{ justifyContent: 'center', alignSelf: 'center' }}
                   />
+                ) : typeof title === 'string' || typeof title === 'number' ? (
+                  <ModalTitle title={`${title}`} />
                 ) : (
-                  <Text
-                    style={{
-                      fontSize: 25,
-                      fontWeight: 700,
-                      whiteSpace: 'nowrap',
-                      overflow: 'hidden',
-                      textOverflow: 'ellipsis',
-                      ...titleStyle,
-                    }}
-                    {...(editableTitle && { onPointerUp: onTitleClick })}
-                  >
-                    {_title}
-                  </Text>
+                  title
                 )}
               </View>
             )}
@@ -249,36 +196,25 @@ export const Modal = ({
               style={{
                 position: 'absolute',
                 right: 0,
-                top: 0,
-                bottom: 0,
-                justifyContent: 'center',
-                alignItems: 'center',
+                marginRight: !isNarrowWidth ? 15 : undefined,
+                marginLeft: !isNarrowWidth ? 5 : undefined,
               }}
             >
-              <View
-                style={{
-                  flexDirection: 'row',
-                  marginRight: 15,
-                }}
-              >
-                {showClose && !isEditingTitle && (
-                  <Button
-                    type="bare"
-                    onClick={onClose}
-                    style={{ padding: '10px 10px' }}
-                    aria-label="Close"
-                  >
-                    <SvgDelete width={10} style={{ color: 'inherit' }} />
-                  </Button>
-                )}
-              </View>
+              {showClose && (
+                <Button
+                  type="bare"
+                  onClick={onClose}
+                  style={{ padding: 10 }}
+                  aria-label="Close"
+                >
+                  <SvgDelete width={10} style={{ color: 'inherit' }} />
+                </Button>
+              )}
             </View>
           </View>
         )}
         <View style={{ padding, paddingTop: 0, flex: 1 }}>
-          {typeof children === 'function'
-            ? children({ isEditingTitle })
-            : children}
+          {typeof children === 'function' ? children() : children}
         </View>
         {loading && (
           <View
@@ -427,3 +363,102 @@ export const ModalButtons = ({
     </View>
   );
 };
+
+type ModalTitleProps = {
+  title: string;
+  isEditable?: boolean;
+  getStyle?: (isEditing: boolean) => CSSProperties;
+  onEdit?: (isEditing: boolean) => void;
+  onTitleUpdate?: (newName: string) => void;
+  shrinkOnOverflow?: boolean;
+};
+
+export function ModalTitle({
+  title,
+  isEditable,
+  getStyle,
+  onTitleUpdate,
+  shrinkOnOverflow = false,
+}: ModalTitleProps) {
+  const [isEditing, setIsEditing] = useState(false);
+  const style = getStyle?.(isEditing);
+
+  const _onEdit = () => {
+    if (!isEditable) {
+      return;
+    }
+
+    setIsEditing(true);
+  };
+
+  const _onTitleUpdate = newTitle => {
+    if (newTitle !== title) {
+      onTitleUpdate?.(newTitle);
+    }
+    setIsEditing(false);
+  };
+
+  const inputRef = useRef<HTMLInputElement>();
+  useEffect(() => {
+    if (isEditing) {
+      if (inputRef.current) {
+        inputRef.current.scrollLeft = 0;
+      }
+    }
+  }, [isEditing]);
+
+  // Dynamic font size to avoid ellipsis.
+  const textRef = useRef<HTMLSpanElement>();
+  const [textFontSize, setTextFontSize] = useState(25);
+  useEffect(() => {
+    if (shrinkOnOverflow) {
+      const containerWidth = textRef.current.offsetWidth;
+      const textWidth = textRef.current.scrollWidth;
+
+      if (textWidth > containerWidth) {
+        const newFontSize = Math.floor(
+          (containerWidth / textWidth) * textFontSize,
+        );
+        setTextFontSize(newFontSize);
+      }
+    }
+  }, [textFontSize, shrinkOnOverflow]);
+
+  return isEditing ? (
+    <Input
+      inputRef={inputRef}
+      style={{
+        fontSize: 25,
+        fontWeight: 700,
+        textAlign: 'center',
+        ...style,
+      }}
+      focused={isEditing}
+      defaultValue={title}
+      onUpdate={_onTitleUpdate}
+      onKeyDown={e => {
+        if (e.key === 'Enter') {
+          e.preventDefault();
+          _onTitleUpdate?.(e.currentTarget.value);
+        }
+      }}
+    />
+  ) : (
+    <Text
+      innerRef={textRef}
+      style={{
+        fontSize: textFontSize,
+        fontWeight: 700,
+        textAlign: 'center',
+        whiteSpace: 'nowrap',
+        overflow: 'hidden',
+        textOverflow: 'ellipsis',
+        ...(isEditable && styles.underlinedText),
+        ...style,
+      }}
+      onClick={_onEdit}
+    >
+      {title}
+    </Text>
+  );
+}
diff --git a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
index e004f887e4bcf90ebe04d365bed1adb28643501c..9e1f43d21bf08e0890a66d11243e7dc977a5b487 100644
--- a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
+++ b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
@@ -7,17 +7,13 @@ import { collapseModals, pushModal } from 'loot-core/client/actions';
 import { rolloverBudget, reportBudget } from 'loot-core/src/client/queries';
 import * as monthUtils from 'loot-core/src/shared/months';
 
-import { useFeatureFlag } from '../../../hooks/useFeatureFlag';
 import { useLocalPref } from '../../../hooks/useLocalPref';
 import {
   SingleActiveEditFormProvider,
   useSingleActiveEditForm,
 } from '../../../hooks/useSingleActiveEditForm';
-import {
-  SvgArrowThinLeft,
-  SvgArrowThinRight,
-  SvgDotsHorizontalTriple,
-} from '../../../icons/v1';
+import { SvgLogo } from '../../../icons/logo';
+import { SvgAdd, SvgArrowThinLeft, SvgArrowThinRight } from '../../../icons/v1';
 import { useResponsive } from '../../../ResponsiveProvider';
 import { theme, styles } from '../../../style';
 import { BalanceWithCarryover } from '../../budget/BalanceWithCarryover';
@@ -25,14 +21,12 @@ import { makeAmountGrey } from '../../budget/util';
 import { Button } from '../../common/Button';
 import { Card } from '../../common/Card';
 import { Label } from '../../common/Label';
-import { Menu } from '../../common/Menu';
 import { Text } from '../../common/Text';
 import { View } from '../../common/View';
 import { Page } from '../../Page';
 import { CellValue } from '../../spreadsheet/CellValue';
 import { useFormat } from '../../spreadsheet/useFormat';
 import { useSheetValue } from '../../spreadsheet/useSheetValue';
-import { Tooltip, useTooltip } from '../../tooltips';
 import { AmountInput } from '../../util/AmountInput';
 import { MOBILE_NAV_HEIGHT } from '../MobileNavTabs';
 import { PullToRefresh } from '../PullToRefresh';
@@ -1033,7 +1027,6 @@ function BudgetGroups({
   onSaveCategory,
   onDeleteCategory,
   onAddCategory,
-  onAddGroup,
   onReorderCategory,
   onReorderGroup,
   onBudgetAction,
@@ -1082,17 +1075,6 @@ function BudgetGroups({
             );
           })}
 
-        <View
-          style={{
-            alignItems: 'flex-start',
-            justifyContent: 'flex-start',
-          }}
-        >
-          <Button onClick={onAddGroup} style={{ fontSize: 12, margin: 10 }}>
-            Add Group
-          </Button>
-        </View>
-
         {incomeGroup && (
           <IncomeGroup
             type={type}
@@ -1118,7 +1100,7 @@ export function BudgetTable({
   categoryGroups,
   month,
   monthBounds,
-  editMode,
+  // editMode,
   // refreshControl,
   onPrevMonth,
   onNextMonth,
@@ -1128,30 +1110,28 @@ export function BudgetTable({
   onAddCategory,
   onSaveCategory,
   onDeleteCategory,
-  onEditMode,
   onReorderCategory,
   onReorderGroup,
   onShowBudgetSummary,
-  onOpenMonthActionMenu,
   onBudgetAction,
   onRefresh,
-  onSwitchBudgetType,
   onEditGroup,
   onEditCategory,
+  onOpenBudgetActionMenu,
 }) {
   const { width } = useResponsive();
   const show3Cols = width >= 360;
 
   // let editMode = false; // neuter editMode -- sorry, not rewriting drag-n-drop right now
   const format = useFormat();
-  const dispatch = useDispatch();
 
   const [showSpentColumn = false, setShowSpentColumnPref] = useLocalPref(
     'mobile.showSpentColumn',
   );
 
-  const [showHiddenCategories = false, setShowHiddenCategoriesPref] =
-    useLocalPref('budget.showHiddenCategories');
+  const [showHiddenCategories = false] = useLocalPref(
+    'budget.showHiddenCategories',
+  );
 
   function toggleDisplay() {
     setShowSpentColumnPref(!showSpentColumn);
@@ -1163,16 +1143,9 @@ export function BudgetTable({
     borderRadius: 'unset',
   };
 
-  const _onSwitchBudgetType = () => {
-    dispatch(
-      pushModal('switch-budget-type', {
-        onSwitch: onSwitchBudgetType,
-      }),
-    );
-  };
-
-  const onToggleHiddenCategories = () => {
-    setShowHiddenCategoriesPref(!showHiddenCategories);
+  const noBackgroundColorStyle = {
+    backgroundColor: 'transparent',
+    color: 'white',
   };
 
   return (
@@ -1186,31 +1159,33 @@ export function BudgetTable({
           onNextMonth={onNextMonth}
         />
       }
+      headerLeftContent={
+        <Button
+          type="bare"
+          style={{
+            color: theme.mobileHeaderText,
+            margin: 10,
+          }}
+          hoveredStyle={noBackgroundColorStyle}
+          activeStyle={noBackgroundColorStyle}
+          onClick={() => onOpenBudgetActionMenu?.(month)}
+        >
+          <SvgLogo width="20" height="20" />
+        </Button>
+      }
       headerRightContent={
-        !editMode ? (
-          <BudgetPageMenu
-            onEditMode={onEditMode}
-            onToggleHiddenCategories={onToggleHiddenCategories}
-            onSwitchBudgetType={_onSwitchBudgetType}
-          />
-        ) : (
-          <Button
-            type="bare"
-            hoveredStyle={{
-              color: theme.mobileHeaderText,
-              background: theme.mobileHeaderTextHover,
-            }}
-            style={{
-              ...styles.noTapHighlight,
-              ...styles.text,
-              backgroundColor: 'transparent',
-              color: theme.mobileHeaderText,
-            }}
-            onClick={() => onEditMode?.(false)}
-          >
-            Done
-          </Button>
-        )
+        <Button
+          type="bare"
+          style={{
+            color: theme.mobileHeaderText,
+            margin: 10,
+          }}
+          hoveredStyle={noBackgroundColorStyle}
+          activeStyle={noBackgroundColorStyle}
+          onClick={onAddGroup}
+        >
+          <SvgAdd width="20" height="20" />
+        </Button>
       }
       style={{ flex: 1 }}
     >
@@ -1347,154 +1322,35 @@ export function BudgetTable({
         </View>
       </View>
       <PullToRefresh onRefresh={onRefresh}>
-        {!editMode ? (
-          // <ScrollView
-          //   ref={el => (this.list = el)}
-          //   keyboardShouldPersistTaps="always"
-          //   refreshControl={refreshControl}
-          //   style={{ backgroundColor: colors.n10 }}
-          //   automaticallyAdjustContentInsets={false}
-          // >
-          <View
-            data-testid="budget-table"
-            style={{
-              paddingBottom: MOBILE_NAV_HEIGHT,
-            }}
-          >
-            <BudgetGroups
-              type={type}
-              categoryGroups={categoryGroups}
-              showBudgetedCol={!showSpentColumn}
-              show3Cols={show3Cols}
-              showHiddenCategories={showHiddenCategories}
-              // gestures={gestures}
-              month={month}
-              editMode={editMode}
-              onEditGroup={onEditGroup}
-              onEditCategory={onEditCategory}
-              onSaveCategory={onSaveCategory}
-              onDeleteCategory={onDeleteCategory}
-              onAddCategory={onAddCategory}
-              onAddGroup={onAddGroup}
-              onSaveGroup={onSaveGroup}
-              onDeleteGroup={onDeleteGroup}
-              onReorderCategory={onReorderCategory}
-              onReorderGroup={onReorderGroup}
-              onOpenMonthActionMenu={onOpenMonthActionMenu}
-              onBudgetAction={onBudgetAction}
-            />
-          </View>
-        ) : (
-          // </ScrollView>
-          // <DragDrop>
-          //   {({
-          //     dragging,
-          //     onGestureEvent,
-          //     onHandlerStateChange,
-          //     scrollRef,
-          //     onScroll
-          //   }) => (
-          <View data-testid="budget-table">
-            <BudgetGroups
-              type={type}
-              categoryGroups={categoryGroups}
-              showBudgetedCol={!showSpentColumn}
-              show3Cols={show3Cols}
-              showHiddenCategories={showHiddenCategories}
-              // gestures={gestures}
-              editMode={editMode}
-              onEditGroup={onEditGroup}
-              onEditCategory={onEditCategory}
-              onSaveCategory={onSaveCategory}
-              onDeleteCategory={onDeleteCategory}
-              onAddCategory={onAddCategory}
-              onAddGroup={onAddGroup}
-              onSaveGroup={onSaveGroup}
-              onDeleteGroup={onDeleteGroup}
-              onReorderCategory={onReorderCategory}
-              onReorderGroup={onReorderGroup}
-              onOpenMonthActionMenu={onOpenMonthActionMenu}
-              onBudgetAction={onBudgetAction}
-            />
-          </View>
-
-          // <DragDropHighlight />
-          // </DragDrop>
-        )}
-      </PullToRefresh>
-    </Page>
-  );
-}
-
-function BudgetPageMenu({
-  onEditMode,
-  onToggleHiddenCategories,
-  onSwitchBudgetType,
-}) {
-  const tooltip = useTooltip();
-  const isReportBudgetEnabled = useFeatureFlag('reportBudget');
-
-  const onMenuSelect = name => {
-    tooltip.close();
-    switch (name) {
-      case 'edit-mode':
-        onEditMode?.(true);
-        break;
-      case 'toggle-hidden-categories':
-        onToggleHiddenCategories?.();
-        break;
-      case 'switch-budget-type':
-        onSwitchBudgetType?.();
-        break;
-      default:
-        throw new Error(`Unrecognized menu option: ${name}`);
-    }
-  };
-
-  return (
-    <>
-      <Button
-        type="bare"
-        style={{
-          ...styles.noTapHighlight,
-        }}
-        hoveredStyle={{
-          color: theme.mobileHeaderText,
-          background: theme.mobileHeaderTextHover,
-        }}
-        {...tooltip.getOpenEvents()}
-      >
-        <SvgDotsHorizontalTriple
-          width="20"
-          height="20"
-          style={{ color: theme.mobileHeaderText }}
-        />
-      </Button>
-      {tooltip.isOpen && (
-        <Tooltip
-          position="bottom-right"
-          width={250}
-          style={{ padding: 0 }}
-          onClose={tooltip.close}
+        <View
+          data-testid="budget-table"
+          style={{
+            paddingBottom: MOBILE_NAV_HEIGHT,
+          }}
         >
-          <Menu
-            onMenuSelect={onMenuSelect}
-            items={[
-              // Removing for now until we work on mobile category drag and drop.
-              // { name: 'edit-mode', text: 'Edit mode' },
-              {
-                name: 'toggle-hidden-categories',
-                text: 'Toggle hidden categories',
-              },
-              isReportBudgetEnabled && {
-                name: 'switch-budget-type',
-                text: 'Switch budget type',
-              },
-            ]}
+          <BudgetGroups
+            type={type}
+            categoryGroups={categoryGroups}
+            showBudgetedCol={!showSpentColumn}
+            show3Cols={show3Cols}
+            showHiddenCategories={showHiddenCategories}
+            month={month}
+            // gestures={gestures}
+            // editMode={editMode}
+            onEditGroup={onEditGroup}
+            onEditCategory={onEditCategory}
+            onSaveCategory={onSaveCategory}
+            onDeleteCategory={onDeleteCategory}
+            onAddCategory={onAddCategory}
+            onSaveGroup={onSaveGroup}
+            onDeleteGroup={onDeleteGroup}
+            onReorderCategory={onReorderCategory}
+            onReorderGroup={onReorderGroup}
+            onBudgetAction={onBudgetAction}
           />
-        </Tooltip>
-      )}
-    </>
+        </View>
+      </PullToRefresh>
+    </Page>
   );
 }
 
diff --git a/packages/desktop-client/src/components/mobile/budget/index.tsx b/packages/desktop-client/src/components/mobile/budget/index.tsx
index eb5e5a7fd377efc4fb5ec11c9422370e5098aafa..4374b7246332173b91e65772fa692585b330151e 100644
--- a/packages/desktop-client/src/components/mobile/budget/index.tsx
+++ b/packages/desktop-client/src/components/mobile/budget/index.tsx
@@ -53,7 +53,7 @@ function BudgetInner(props: BudgetInnerProps) {
   const [bounds, setBounds] = useState({ start: currMonth, end: currMonth });
   const [currentMonth, setCurrentMonth] = useState(currMonth);
   const [initialized, setInitialized] = useState(false);
-  const [editMode, setEditMode] = useState(false);
+  // const [editMode, setEditMode] = useState(false);
 
   const [_numberFormat] = useLocalPref('numberFormat');
   const numberFormat = _numberFormat || 'comma-dot';
@@ -353,6 +353,36 @@ function BudgetInner(props: BudgetInnerProps) {
     );
   };
 
+  const _onSwitchBudgetType = () => {
+    dispatch(
+      pushModal('switch-budget-type', {
+        onSwitch: () => {
+          onSwitchBudgetType?.();
+          dispatch(collapseModals('budget-menu'));
+        },
+      }),
+    );
+  };
+
+  const [showHiddenCategories, setShowHiddenCategoriesPref] = useLocalPref(
+    'budget.showHiddenCategories',
+  );
+
+  const onToggleHiddenCategories = () => {
+    setShowHiddenCategoriesPref(!showHiddenCategories);
+    dispatch(collapseModals('budget-menu'));
+  };
+
+  const onOpenBudgetActionMenu = month => {
+    dispatch(
+      pushModal('budget-menu', {
+        month,
+        onToggleHiddenCategories,
+        onSwitchBudgetType: _onSwitchBudgetType,
+      }),
+    );
+  };
+
   if (!categoryGroups || !initialized) {
     return (
       <View
@@ -385,8 +415,7 @@ function BudgetInner(props: BudgetInnerProps) {
             type={budgetType}
             month={currentMonth}
             monthBounds={bounds}
-            editMode={editMode}
-            onEditMode={flag => setEditMode(flag)}
+            // editMode={editMode}
             onShowBudgetSummary={onShowBudgetSummary}
             onPrevMonth={onPrevMonth}
             onNextMonth={onNextMonth}
@@ -398,12 +427,11 @@ function BudgetInner(props: BudgetInnerProps) {
             onDeleteCategory={onDeleteCategory}
             onReorderCategory={onReorderCategory}
             onReorderGroup={onReorderGroup}
-            onOpenMonthActionMenu={() => {}} //onOpenMonthActionMenu}
             onBudgetAction={onBudgetAction}
             onRefresh={onRefresh}
-            onSwitchBudgetType={onSwitchBudgetType}
             onEditGroup={onEditGroup}
             onEditCategory={onEditCategory}
+            onOpenBudgetActionMenu={onOpenBudgetActionMenu}
           />
         )}
       </SyncRefresh>
diff --git a/packages/desktop-client/src/components/modals/AccountMenuModal.tsx b/packages/desktop-client/src/components/modals/AccountMenuModal.tsx
index c67599891926ce5b51d272c449ba6fc24e061087..33c456f873954c372473c641514afd018f4d0fcb 100644
--- a/packages/desktop-client/src/components/modals/AccountMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/AccountMenuModal.tsx
@@ -10,7 +10,7 @@ import { SvgNotesPaper } from '../../icons/v2';
 import { type CSSProperties, styles, theme } from '../../style';
 import { Button } from '../common/Button';
 import { Menu } from '../common/Menu';
-import { Modal } from '../common/Modal';
+import { Modal, ModalTitle } from '../common/Modal';
 import { View } from '../common/View';
 import { type CommonModalProps } from '../Modals';
 import { Notes } from '../Notes';
@@ -88,8 +88,9 @@ export function AccountMenuModal({
 
   return (
     <Modal
-      title={account.name}
-      titleStyle={styles.underlinedText}
+      title={
+        <ModalTitle isEditable title={account.name} onTitleUpdate={onRename} />
+      }
       showHeader
       focusAfterClose={false}
       {...modalProps}
@@ -101,8 +102,6 @@ export function AccountMenuModal({
         padding: '0 10px',
         borderRadius: '6px',
       }}
-      editableTitle={true}
-      onTitleUpdate={onRename}
       leftHeaderContent={
         <AdditionalAccountMenu
           account={account}
@@ -111,63 +110,51 @@ export function AccountMenuModal({
         />
       }
     >
-      {({ isEditingTitle }) => (
+      <View
+        style={{
+          flex: 1,
+          flexDirection: 'column',
+        }}
+      >
         <View
           style={{
+            overflowY: 'auto',
             flex: 1,
-            flexDirection: 'column',
           }}
         >
-          <View
-            style={{
-              overflowY: 'auto',
-              flex: 1,
-            }}
-          >
-            <Notes
-              notes={
-                originalNotes && originalNotes.length > 0
-                  ? originalNotes
-                  : 'No notes'
-              }
-              editable={false}
-              focused={false}
-              getStyle={() => ({
-                borderRadius: 6,
-                ...((!originalNotes || originalNotes.length === 0) && {
-                  justifySelf: 'center',
-                  alignSelf: 'center',
-                  color: theme.pageTextSubdued,
-                }),
-              })}
-            />
-          </View>
-          <View
-            style={{
-              flexDirection: 'row',
-              flexWrap: 'wrap',
-              justifyContent: 'space-between',
-              alignContent: 'space-between',
-              margin: '10px 0',
-            }}
-          >
-            <Button
-              style={{
-                ...buttonStyle,
-                display: isEditingTitle ? 'none' : undefined,
-              }}
-              onClick={_onEditNotes}
-            >
-              <SvgNotesPaper
-                width={20}
-                height={20}
-                style={{ paddingRight: 5 }}
-              />
-              Edit notes
-            </Button>
-          </View>
+          <Notes
+            notes={
+              originalNotes && originalNotes.length > 0
+                ? originalNotes
+                : 'No notes'
+            }
+            editable={false}
+            focused={false}
+            getStyle={() => ({
+              borderRadius: 6,
+              ...((!originalNotes || originalNotes.length === 0) && {
+                justifySelf: 'center',
+                alignSelf: 'center',
+                color: theme.pageTextSubdued,
+              }),
+            })}
+          />
+        </View>
+        <View
+          style={{
+            flexDirection: 'row',
+            flexWrap: 'wrap',
+            justifyContent: 'space-between',
+            alignContent: 'space-between',
+            margin: '10px 0',
+          }}
+        >
+          <Button style={buttonStyle} onClick={_onEditNotes}>
+            <SvgNotesPaper width={20} height={20} style={{ paddingRight: 5 }} />
+            Edit notes
+          </Button>
         </View>
-      )}
+      </View>
     </Modal>
   );
 }
diff --git a/packages/desktop-client/src/components/modals/BudgetMenuModal.tsx b/packages/desktop-client/src/components/modals/BudgetMenuModal.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..59a7d867c7e3b2fd5a5ab384da04b939ed236813
--- /dev/null
+++ b/packages/desktop-client/src/components/modals/BudgetMenuModal.tsx
@@ -0,0 +1,105 @@
+import React, { type ComponentPropsWithoutRef } from 'react';
+
+import { useFeatureFlag } from '../../hooks/useFeatureFlag';
+import { type CSSProperties, theme, styles } from '../../style';
+import { Menu } from '../common/Menu';
+import { Modal } from '../common/Modal';
+import { type CommonModalProps } from '../Modals';
+
+type BudgetMenuModalProps = ComponentPropsWithoutRef<typeof BudgetMenu> & {
+  modalProps: CommonModalProps;
+};
+
+export function BudgetMenuModal({
+  modalProps,
+  month,
+  onToggleHiddenCategories,
+  onSwitchBudgetType,
+}: BudgetMenuModalProps) {
+  const defaultMenuItemStyle: CSSProperties = {
+    ...styles.mobileMenuItem,
+    color: theme.menuItemText,
+    borderRadius: 0,
+    borderTop: `1px solid ${theme.pillBorder}`,
+  };
+
+  return (
+    <Modal
+      showHeader
+      focusAfterClose={false}
+      {...modalProps}
+      padding={0}
+      style={{
+        flex: 1,
+        padding: '0 10px',
+        paddingBottom: 10,
+        borderRadius: '6px',
+      }}
+    >
+      <BudgetMenu
+        getItemStyle={() => defaultMenuItemStyle}
+        month={month}
+        onToggleHiddenCategories={onToggleHiddenCategories}
+        onSwitchBudgetType={onSwitchBudgetType}
+      />
+    </Modal>
+  );
+}
+
+type BudgetMenuProps = Omit<
+  ComponentPropsWithoutRef<typeof Menu>,
+  'onMenuSelect' | 'items'
+> & {
+  month: string;
+  onToggleHiddenCategories: () => void;
+  onSwitchBudgetType: () => void;
+};
+
+function BudgetMenu({
+  // onEditMode,
+  month,
+  onToggleHiddenCategories,
+  onSwitchBudgetType,
+  ...props
+}: BudgetMenuProps) {
+  const isReportBudgetEnabled = useFeatureFlag('reportBudget');
+
+  const onMenuSelect = (name: string) => {
+    switch (name) {
+      // case 'edit-mode':
+      //   onEditMode?.(true);
+      //   break;
+      case 'toggle-hidden-categories':
+        onToggleHiddenCategories?.();
+        break;
+      case 'switch-budget-type':
+        onSwitchBudgetType?.();
+        break;
+      default:
+        throw new Error(`Unrecognized menu option: ${name}`);
+    }
+  };
+
+  return (
+    <Menu
+      {...props}
+      onMenuSelect={onMenuSelect}
+      items={[
+        // Removing for now until we work on mobile category drag and drop.
+        // { name: 'edit-mode', text: 'Edit mode' },
+        {
+          name: 'toggle-hidden-categories',
+          text: 'Toggle hidden categories',
+        },
+        ...(isReportBudgetEnabled
+          ? [
+              {
+                name: 'switch-budget-type',
+                text: 'Switch budget type',
+              },
+            ]
+          : []),
+      ]}
+    />
+  );
+}
diff --git a/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx b/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx
index daf67d511ecdbd842e671ddd2c3b4526b1d96372..3f99d8e2bfd6c24e2f51a641e57f9392fd84310b 100644
--- a/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx
@@ -14,7 +14,7 @@ import { SvgNotesPaper, SvgViewHide, SvgViewShow } from '../../icons/v2';
 import { type CSSProperties, styles, theme } from '../../style';
 import { Button } from '../common/Button';
 import { Menu } from '../common/Menu';
-import { Modal } from '../common/Modal';
+import { Modal, ModalTitle } from '../common/Modal';
 import { View } from '../common/View';
 import { type CommonModalProps } from '../Modals';
 import { Notes } from '../Notes';
@@ -94,7 +94,9 @@ export function CategoryGroupMenuModal({
 
   return (
     <Modal
-      title={group.name}
+      title={
+        <ModalTitle isEditable title={group.name} onTitleUpdate={onRename} />
+      }
       showHeader
       focusAfterClose={false}
       {...modalProps}
@@ -106,9 +108,6 @@ export function CategoryGroupMenuModal({
         padding: '0 10px',
         borderRadius: '6px',
       }}
-      editableTitle={true}
-      titleStyle={styles.underlinedText}
-      onTitleUpdate={onRename}
       leftHeaderContent={
         <AdditionalCategoryGroupMenu
           group={group}
@@ -117,72 +116,53 @@ export function CategoryGroupMenuModal({
         />
       }
     >
-      {({ isEditingTitle }) => (
+      <View
+        style={{
+          flex: 1,
+          flexDirection: 'column',
+        }}
+      >
         <View
           style={{
+            overflowY: 'auto',
             flex: 1,
-            flexDirection: 'column',
           }}
         >
-          <View
-            style={{
-              overflowY: 'auto',
-              flex: 1,
-            }}
-          >
-            <Notes
-              notes={notes?.length > 0 ? notes : 'No notes'}
-              editable={false}
-              focused={false}
-              getStyle={() => ({
-                ...styles.mediumText,
-                borderRadius: 6,
-                ...((!notes || notes.length === 0) && {
-                  justifySelf: 'center',
-                  alignSelf: 'center',
-                  color: theme.pageTextSubdued,
-                }),
-              })}
-            />
-          </View>
-          <View
-            style={{
-              flexDirection: 'row',
-              flexWrap: 'wrap',
-              justifyContent: 'space-between',
-              alignContent: 'space-between',
-              paddingTop: 10,
-              paddingBottom: 10,
-            }}
-          >
-            <Button
-              disabled={isEditingTitle}
-              style={{
-                ...buttonStyle,
-                display: isEditingTitle ? 'none' : undefined,
-              }}
-              onClick={_onAddCategory}
-            >
-              <SvgAdd width={17} height={17} style={{ paddingRight: 5 }} />
-              Add category
-            </Button>
-            <Button
-              style={{
-                ...buttonStyle,
-                display: isEditingTitle ? 'none' : undefined,
-              }}
-              onClick={_onEditNotes}
-            >
-              <SvgNotesPaper
-                width={20}
-                height={20}
-                style={{ paddingRight: 5 }}
-              />
-              Edit notes
-            </Button>
-          </View>
+          <Notes
+            notes={notes?.length > 0 ? notes : 'No notes'}
+            editable={false}
+            focused={false}
+            getStyle={() => ({
+              ...styles.mediumText,
+              borderRadius: 6,
+              ...((!notes || notes.length === 0) && {
+                justifySelf: 'center',
+                alignSelf: 'center',
+                color: theme.pageTextSubdued,
+              }),
+            })}
+          />
         </View>
-      )}
+        <View
+          style={{
+            flexDirection: 'row',
+            flexWrap: 'wrap',
+            justifyContent: 'space-between',
+            alignContent: 'space-between',
+            paddingTop: 10,
+            paddingBottom: 10,
+          }}
+        >
+          <Button style={buttonStyle} onClick={_onAddCategory}>
+            <SvgAdd width={17} height={17} style={{ paddingRight: 5 }} />
+            Add category
+          </Button>
+          <Button style={buttonStyle} onClick={_onEditNotes}>
+            <SvgNotesPaper width={20} height={20} style={{ paddingRight: 5 }} />
+            Edit notes
+          </Button>
+        </View>
+      </View>
     </Modal>
   );
 }
diff --git a/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx b/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx
index 449c97fa2ab158d24bcd279774ca45f6cd960a93..b88d52a0abf28a1370a3890f3cdde49ea3792992 100644
--- a/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/CategoryMenuModal.tsx
@@ -14,7 +14,7 @@ import { SvgNotesPaper, SvgViewHide, SvgViewShow } from '../../icons/v2';
 import { type CSSProperties, styles, theme } from '../../style';
 import { Button } from '../common/Button';
 import { Menu } from '../common/Menu';
-import { Modal } from '../common/Modal';
+import { Modal, ModalTitle } from '../common/Modal';
 import { View } from '../common/View';
 import { type CommonModalProps } from '../Modals';
 import { Notes } from '../Notes';
@@ -85,8 +85,9 @@ export function CategoryMenuModal({
 
   return (
     <Modal
-      title={category.name}
-      titleStyle={styles.underlinedText}
+      title={
+        <ModalTitle isEditable title={category.name} onTitleUpdate={onRename} />
+      }
       showHeader
       focusAfterClose={false}
       {...modalProps}
@@ -98,8 +99,6 @@ export function CategoryMenuModal({
         padding: '0 10px',
         borderRadius: '6px',
       }}
-      editableTitle={true}
-      onTitleUpdate={onRename}
       leftHeaderContent={
         <AdditionalCategoryMenu
           category={category}
@@ -108,59 +107,47 @@ export function CategoryMenuModal({
         />
       }
     >
-      {({ isEditingTitle }) => (
+      <View
+        style={{
+          flex: 1,
+          flexDirection: 'column',
+        }}
+      >
         <View
           style={{
+            overflowY: 'auto',
             flex: 1,
-            flexDirection: 'column',
           }}
         >
-          <View
-            style={{
-              overflowY: 'auto',
-              flex: 1,
-            }}
-          >
-            <Notes
-              notes={originalNotes?.length > 0 ? originalNotes : 'No notes'}
-              editable={false}
-              focused={false}
-              getStyle={() => ({
-                borderRadius: 6,
-                ...((!originalNotes || originalNotes.length === 0) && {
-                  justifySelf: 'center',
-                  alignSelf: 'center',
-                  color: theme.pageTextSubdued,
-                }),
-              })}
-            />
-          </View>
-          <View
-            style={{
-              flexDirection: 'row',
-              flexWrap: 'wrap',
-              justifyContent: 'space-between',
-              alignContent: 'space-between',
-              margin: '10px 0',
-            }}
-          >
-            <Button
-              style={{
-                ...buttonStyle,
-                display: isEditingTitle ? 'none' : undefined,
-              }}
-              onClick={_onEditNotes}
-            >
-              <SvgNotesPaper
-                width={20}
-                height={20}
-                style={{ paddingRight: 5 }}
-              />
-              Edit notes
-            </Button>
-          </View>
+          <Notes
+            notes={originalNotes?.length > 0 ? originalNotes : 'No notes'}
+            editable={false}
+            focused={false}
+            getStyle={() => ({
+              borderRadius: 6,
+              ...((!originalNotes || originalNotes.length === 0) && {
+                justifySelf: 'center',
+                alignSelf: 'center',
+                color: theme.pageTextSubdued,
+              }),
+            })}
+          />
+        </View>
+        <View
+          style={{
+            flexDirection: 'row',
+            flexWrap: 'wrap',
+            justifyContent: 'space-between',
+            alignContent: 'space-between',
+            margin: '10px 0',
+          }}
+        >
+          <Button style={buttonStyle} onClick={_onEditNotes}>
+            <SvgNotesPaper width={20} height={20} style={{ paddingRight: 5 }} />
+            Edit notes
+          </Button>
         </View>
-      )}
+      </View>
     </Modal>
   );
 }
diff --git a/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx b/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx
index 6c4d5e6e1eada91c9fba9df240502a0e0632b1b2..788d9e19d588aca0cb2e1b28cd860348c9de2227 100644
--- a/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/ReportBalanceMenuModal.tsx
@@ -25,7 +25,6 @@ export function ReportBalanceMenuModal({
 
   return (
     <Modal
-      title="Actions"
       showHeader
       focusAfterClose={false}
       {...modalProps}
@@ -37,13 +36,11 @@ export function ReportBalanceMenuModal({
         borderRadius: '6px',
       }}
     >
-      {() => (
-        <BalanceMenu
-          categoryId={categoryId}
-          getItemStyle={() => defaultMenuItemStyle}
-          onCarryover={onCarryover}
-        />
-      )}
+      <BalanceMenu
+        categoryId={categoryId}
+        getItemStyle={() => defaultMenuItemStyle}
+        onCarryover={onCarryover}
+      />
     </Modal>
   );
 }
diff --git a/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx b/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx
index 75c4159103f0ef8903f06c6bbe1b569e10ae6090..247fb0526f44c54fcd275000114907adae9190e0 100644
--- a/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/RolloverBalanceMenuModal.tsx
@@ -27,7 +27,6 @@ export function RolloverBalanceMenuModal({
 
   return (
     <Modal
-      title="Actions"
       showHeader
       focusAfterClose={false}
       {...modalProps}
@@ -39,15 +38,13 @@ export function RolloverBalanceMenuModal({
         borderRadius: '6px',
       }}
     >
-      {() => (
-        <BalanceMenu
-          categoryId={categoryId}
-          getItemStyle={() => defaultMenuItemStyle}
-          onCarryover={onCarryover}
-          onTransfer={onTransfer}
-          onCover={onCover}
-        />
-      )}
+      <BalanceMenu
+        categoryId={categoryId}
+        getItemStyle={() => defaultMenuItemStyle}
+        onCarryover={onCarryover}
+        onTransfer={onTransfer}
+        onCover={onCover}
+      />
     </Modal>
   );
 }
diff --git a/packages/desktop-client/src/components/modals/RolloverToBudgetMenuModal.tsx b/packages/desktop-client/src/components/modals/RolloverToBudgetMenuModal.tsx
index da62d53d08f696d4e9a5844517d68bcc9f0a3a2c..9daa6ac60b1d12ca16b0149728e974dce2370baf 100644
--- a/packages/desktop-client/src/components/modals/RolloverToBudgetMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/RolloverToBudgetMenuModal.tsx
@@ -26,7 +26,6 @@ export function RolloverToBudgetMenuModal({
 
   return (
     <Modal
-      title="Actions"
       showHeader
       focusAfterClose={false}
       {...modalProps}
@@ -38,14 +37,12 @@ export function RolloverToBudgetMenuModal({
         borderRadius: '6px',
       }}
     >
-      {() => (
-        <ToBudgetMenu
-          getItemStyle={() => defaultMenuItemStyle}
-          onTransfer={onTransfer}
-          onHoldBuffer={onHoldBuffer}
-          onResetHoldBuffer={onResetHoldBuffer}
-        />
-      )}
+      <ToBudgetMenu
+        getItemStyle={() => defaultMenuItemStyle}
+        onTransfer={onTransfer}
+        onHoldBuffer={onHoldBuffer}
+        onResetHoldBuffer={onResetHoldBuffer}
+      />
     </Modal>
   );
 }
diff --git a/packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx b/packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx
index cfadec05dab4e74ebec8f14455330a925129ea52..8a70ceb15723efc3a9b9224e91a5f24d60e0ec05 100644
--- a/packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx
+++ b/packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx
@@ -24,7 +24,6 @@ export function ScheduledTransactionMenuModal({
 
   return (
     <Modal
-      title="Actions"
       showHeader
       focusAfterClose={false}
       {...modalProps}
@@ -36,14 +35,12 @@ export function ScheduledTransactionMenuModal({
         borderRadius: '6px',
       }}
     >
-      {() => (
-        <ScheduledTransactionMenu
-          transactionId={transactionId}
-          onPost={onPost}
-          onSkip={onSkip}
-          getItemStyle={() => defaultMenuItemStyle}
-        />
-      )}
+      <ScheduledTransactionMenu
+        transactionId={transactionId}
+        onPost={onPost}
+        onSkip={onSkip}
+        getItemStyle={() => defaultMenuItemStyle}
+      />
     </Modal>
   );
 }
diff --git a/packages/desktop-client/src/components/modals/SingleInputModal.tsx b/packages/desktop-client/src/components/modals/SingleInputModal.tsx
index c95d820fabe9ffceab892d0615babf0c46c6dc37..7ea44494095c490f557d70a6377c5abdafd6b244 100644
--- a/packages/desktop-client/src/components/modals/SingleInputModal.tsx
+++ b/packages/desktop-client/src/components/modals/SingleInputModal.tsx
@@ -1,5 +1,5 @@
 // @ts-strict-ignore
-import React, { useState } from 'react';
+import React, { type ComponentProps, useState } from 'react';
 
 import { styles } from '../../style';
 import { Button } from '../common/Button';
@@ -12,7 +12,7 @@ import { type CommonModalProps } from '../Modals';
 
 type SingleInputModalProps = {
   modalProps: Partial<CommonModalProps>;
-  title: string;
+  title: ComponentProps<typeof Modal>['title'];
   buttonText: string;
   onSubmit: (value: string) => void;
   onValidate?: (value: string) => string[];
diff --git a/packages/desktop-client/src/components/modals/SwitchBudgetType.tsx b/packages/desktop-client/src/components/modals/SwitchBudgetTypeModal.tsx
similarity index 78%
rename from packages/desktop-client/src/components/modals/SwitchBudgetType.tsx
rename to packages/desktop-client/src/components/modals/SwitchBudgetTypeModal.tsx
index 2c9c66ef2c2a94fdfb8b45ebc48e1e860f2e37b2..27b92df6cb56195fb64827643487e0bf1ab4a547 100644
--- a/packages/desktop-client/src/components/modals/SwitchBudgetType.tsx
+++ b/packages/desktop-client/src/components/modals/SwitchBudgetTypeModal.tsx
@@ -2,6 +2,8 @@
 import React from 'react';
 
 import { useLocalPref } from '../../hooks/useLocalPref';
+import { useResponsive } from '../../ResponsiveProvider';
+import { styles } from '../../style';
 import { Button } from '../common/Button';
 import { Link } from '../common/Link';
 import { Modal } from '../common/Modal';
@@ -9,16 +11,22 @@ import { Paragraph } from '../common/Paragraph';
 import { Text } from '../common/Text';
 import { type CommonModalProps } from '../Modals';
 
-type SwitchBudgetTypeProps = {
+type SwitchBudgetTypeModalProps = {
   modalProps: CommonModalProps;
   onSwitch: () => void;
 };
 
-export function SwitchBudgetType({
+export function SwitchBudgetTypeModal({
   modalProps,
   onSwitch,
-}: SwitchBudgetTypeProps) {
+}: SwitchBudgetTypeModalProps) {
   const [budgetType] = useLocalPref('budgetType');
+  const { isNarrowWidth } = useResponsive();
+  const narrowStyle = isNarrowWidth
+    ? {
+        height: styles.mobileMinHeight,
+      }
+    : {};
   return (
     <Modal title="Switch budget type?" {...modalProps}>
       {() => (
@@ -32,8 +40,11 @@ export function SwitchBudgetType({
           </Paragraph>
           <Button
             type="primary"
+            style={{
+              ...narrowStyle,
+            }}
             onClick={() => {
-              onSwitch();
+              onSwitch?.();
               modalProps.onClose?.();
             }}
           >
diff --git a/packages/loot-core/src/client/state-types/modals.d.ts b/packages/loot-core/src/client/state-types/modals.d.ts
index f780f445e7f4c66c7072bb20b4beabdc15c4e868..4d4f45f8de2e887679d22fb04aa8ff1c29da1d72 100644
--- a/packages/loot-core/src/client/state-types/modals.d.ts
+++ b/packages/loot-core/src/client/state-types/modals.d.ts
@@ -215,6 +215,11 @@ type FinanceModals = {
     onPost: (transactionId: string) => void;
     onSkip: (transactionId: string) => void;
   };
+  'budget-menu': {
+    month: string;
+    onToggleHiddenCategories: () => void;
+    onSwitchBudgetType: () => void;
+  };
 };
 
 export type PushModalAction = {
diff --git a/upcoming-release-notes/2491.md b/upcoming-release-notes/2491.md
new file mode 100644
index 0000000000000000000000000000000000000000..ae89be45b967c9116ee5f52d1a1b03df635bba41
--- /dev/null
+++ b/upcoming-release-notes/2491.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [joel-jeremy]
+---
+
+Add + button to add a group on mobile budget page and a budget related menu.