diff --git a/packages/desktop-client/src/components/FinancesApp.js b/packages/desktop-client/src/components/FinancesApp.js
index eccbab12aedd8528fb9b926cfc2fa88aea845fae..bdc6f44822249a2565f7d06c66d9853e7a95a8bd 100644
--- a/packages/desktop-client/src/components/FinancesApp.js
+++ b/packages/desktop-client/src/components/FinancesApp.js
@@ -24,9 +24,11 @@ import BankSyncStatus from './BankSyncStatus';
 import Budget from './budget';
 import FloatableSidebar, { SidebarProvider } from './FloatableSidebar';
 import GlobalKeys from './GlobalKeys';
+import { ManageRulesPage } from './ManageRulesPage';
 import Modals from './Modals';
 import Notifications from './Notifications';
 import { PageTypeProvider } from './Page';
+import { ManagePayeesPage } from './payees/ManagePayeesPage';
 import Reports from './reports';
 import Schedules from './schedules';
 import DiscoverSchedules from './schedules/DiscoverSchedules';
@@ -97,6 +99,8 @@ function Routes({ location }) {
           component={PostsOfflineNotification}
         />
 
+        <Route path="/rules" exact component={ManageRulesPage} />
+        <Route path="/payees" exact component={ManagePayeesPage} />
         <Route path="/tools/fix-splits" exact component={FixSplitsTool} />
 
         <Route
diff --git a/packages/desktop-client/src/components/modals/ManageRules.js b/packages/desktop-client/src/components/ManageRules.js
similarity index 84%
rename from packages/desktop-client/src/components/modals/ManageRules.js
rename to packages/desktop-client/src/components/ManageRules.js
index 93eb2a0f383aea01310c9d04e04d5d149e920103..37c8bc0f790c18c0ca8d1343f9fdfdd66772d8a8 100644
--- a/packages/desktop-client/src/components/modals/ManageRules.js
+++ b/packages/desktop-client/src/components/ManageRules.js
@@ -43,6 +43,8 @@ import useSelected, {
 import { colors } from 'loot-design/src/style';
 import ArrowRight from 'loot-design/src/svg/RightArrow2';
 
+import { Page } from './Page';
+
 let SchedulesQuery = liveQueryContext(q('schedules').select('*'));
 
 export function Value({
@@ -448,7 +450,7 @@ function RulesHeader() {
   let dispatchSelected = useSelectedDispatch();
 
   return (
-    <TableHeader>
+    <TableHeader version="v2" style={{}}>
       <SelectCell
         exposed={true}
         focused={false}
@@ -500,14 +502,17 @@ function RulesList({
   );
 }
 
-export default function ManageRules({ history, modalProps, payeeId }) {
+export default function ManageRules({
+  isModal,
+  payeeId,
+  setLoading = () => {}
+}) {
   let [allRules, setAllRules] = useState(null);
   let [rules, setRules] = useState(null);
   let dispatch = useDispatch();
   let navigator = useTableNavigator(rules, ['select', 'edit']);
   let selectedInst = useSelected('manage-rules', allRules, []);
   let [hoveredRule, setHoveredRule] = useState(null);
-  let [loading, setLoading] = useState(true);
   let tableRef = useRef(null);
 
   async function loadRules() {
@@ -515,7 +520,9 @@ export default function ManageRules({ history, modalProps, payeeId }) {
 
     let loadedRules = null;
     if (payeeId) {
-      loadedRules = await send('payees-get-rules', { id: payeeId });
+      loadedRules = await send('payees-get-rules', {
+        id: payeeId
+      });
     } else {
       loadedRules = await send('rules-get');
     }
@@ -594,7 +601,14 @@ export default function ManageRules({ history, modalProps, payeeId }) {
         rule: {
           stage: null,
           conditions: [{ op: 'is', field: 'payee', value: null, type: 'id' }],
-          actions: [{ op: 'set', field: 'category', value: null, type: 'id' }]
+          actions: [
+            {
+              op: 'set',
+              field: 'category',
+              value: null,
+              type: 'id'
+            }
+          ]
         },
         onSave: async newRule => {
           let newRules = await loadRules();
@@ -620,89 +634,78 @@ export default function ManageRules({ history, modalProps, payeeId }) {
     return null;
   }
 
-  return (
-    <Modal
-      title="Rules"
-      padding={0}
-      loading={loading}
-      {...modalProps}
-      style={[modalProps.style, { flex: 1, maxWidth: '90%' }]}
+  let actions = (
+    <View
+      style={{
+        flexDirection: 'row',
+        alignItems: 'center',
+        padding: isModal ? '13px 15px' : '0 0 15px',
+        borderTop: '1px solid ' + colors.border
+      }}
     >
-      {() => (
-        <SchedulesQuery.Provider>
-          <SelectedProvider instance={selectedInst}>
-            <View style={{ height: '70vh' }}>
-              <View style={{ flex: 1 }}>
-                <RulesHeader />
-                <SimpleTable
-                  ref={tableRef}
-                  data={rules}
-                  navigator={navigator}
-                  loadMore={loadMore}
-                  // Hide the last border of the item in the table
-                  style={{ marginBottom: -1 }}
-                >
-                  <RulesList
-                    rules={rules}
-                    selectedItems={selectedInst.items}
-                    navigator={navigator}
-                    hoveredRule={hoveredRule}
-                    onHover={onHover}
-                    onEditRule={onEditRule}
-                  />
-                </SimpleTable>
-              </View>
-
-              <View
-                style={{
-                  flexDirection: 'row',
-                  alignItems: 'center',
-                  padding: '13px 15px',
-                  borderTop: '1px solid ' + colors.border
-                }}
-              >
-                <View
-                  style={{
-                    color: colors.n4,
-                    flexDirection: 'row',
-                    alignItems: 'center',
-                    width: '50%'
-                  }}
-                >
-                  <Text>
-                    Rules are always run in the order that you see them.{' '}
-                    <ExternalLink
-                      asAnchor={true}
-                      href="https://actualbudget.github.io/docs/Budgeting/rules/"
-                      style={{ color: colors.n4 }}
-                    >
-                      Learn more
-                    </ExternalLink>
-                  </Text>
-                </View>
-
-                <View style={{ flex: 1 }} />
-
-                <Stack
-                  direction="row"
-                  align="center"
-                  justify="flex-end"
-                  spacing={2}
-                >
-                  {selectedInst.items.size > 0 && (
-                    <Button onClick={onDeleteSelected}>
-                      Delete {selectedInst.items.size} rules
-                    </Button>
-                  )}
-                  <Button primary onClick={onCreateRule}>
-                    Create new rule
-                  </Button>
-                </Stack>
-              </View>
-            </View>
-          </SelectedProvider>
-        </SchedulesQuery.Provider>
-      )}
-    </Modal>
+      <View
+        style={{
+          color: colors.n4,
+          flexDirection: 'row',
+          alignItems: 'center',
+          width: '50%'
+        }}
+      >
+        <Text>
+          Rules are always run in the order that you see them.{' '}
+          <ExternalLink
+            asAnchor={true}
+            href="https://actualbudget.github.io/docs/Budgeting/rules/"
+            style={{ color: colors.n4 }}
+          >
+            Learn more
+          </ExternalLink>
+        </Text>
+      </View>
+
+      <View style={{ flex: 1 }} />
+
+      <Stack direction="row" align="center" justify="flex-end" spacing={2}>
+        {selectedInst.items.size > 0 && (
+          <Button onClick={onDeleteSelected}>
+            Delete {selectedInst.items.size} rules
+          </Button>
+        )}
+        <Button primary onClick={onCreateRule}>
+          Create new rule
+        </Button>
+      </Stack>
+    </View>
+  );
+
+  return (
+    <SchedulesQuery.Provider>
+      <SelectedProvider instance={selectedInst}>
+        <View style={{ overflow: 'hidden' }}>
+          {!isModal && actions}
+          <View style={{ flex: 1 }}>
+            <RulesHeader />
+            <SimpleTable
+              ref={tableRef}
+              data={rules}
+              navigator={navigator}
+              loadMore={loadMore}
+              // Hide the last border of the item in the table
+              style={{ marginBottom: -1 }}
+            >
+              <RulesList
+                rules={rules}
+                selectedItems={selectedInst.items}
+                navigator={navigator}
+                hoveredRule={hoveredRule}
+                onHover={onHover}
+                onEditRule={onEditRule}
+              />
+            </SimpleTable>
+          </View>
+          {isModal && actions}
+        </View>
+      </SelectedProvider>
+    </SchedulesQuery.Provider>
   );
 }
diff --git a/packages/desktop-client/src/components/ManageRulesPage.js b/packages/desktop-client/src/components/ManageRulesPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..e1ebfbfc409ad8778cf02eb70f68f1287f816aca
--- /dev/null
+++ b/packages/desktop-client/src/components/ManageRulesPage.js
@@ -0,0 +1,12 @@
+import React from 'react';
+
+import ManageRules from './ManageRules';
+import { Page } from './Page';
+
+export function ManageRulesPage() {
+  return (
+    <Page title="Rules">
+      <ManageRules />
+    </Page>
+  );
+}
diff --git a/packages/desktop-client/src/components/Modals.js b/packages/desktop-client/src/components/Modals.js
index 2dc967f42c53b4b0d71f551a84b17e93588122c2..008778629eec9d0eac07d76126ff6971c1c1fdd5 100644
--- a/packages/desktop-client/src/components/Modals.js
+++ b/packages/desktop-client/src/components/Modals.js
@@ -22,10 +22,9 @@ import CreateAccount from './modals/CreateAccount';
 import CreateEncryptionKey from './modals/CreateEncryptionKey';
 import EditRule from './modals/EditRule';
 import FixEncryptionKey from './modals/FixEncryptionKey';
-import ManageRules from './modals/ManageRules';
+import ManageRulesModal from './modals/ManageRulesModal';
 import MergeUnusedPayees from './modals/MergeUnusedPayees';
 import WelcomeScreen from './modals/WelcomeScreen';
-import ManagePayeesWithData from './payees/ManagePayeesWithData';
 
 function Modals({
   history,
@@ -150,26 +149,11 @@ function Modals({
           }}
         />
 
-        <Route
-          path="/manage-payees"
-          render={() => {
-            return (
-              <ManagePayeesWithData
-                history={history}
-                modalProps={modalProps}
-                initialSelectedIds={
-                  options.selectedPayee ? [options.selectedPayee] : undefined
-                }
-              />
-            );
-          }}
-        />
-
         <Route
           path="/manage-rules"
           render={() => {
             return (
-              <ManageRules
+              <ManageRulesModal
                 history={history}
                 modalProps={modalProps}
                 payeeId={options.payeeId}
diff --git a/packages/desktop-client/src/components/accounts/Account.js b/packages/desktop-client/src/components/accounts/Account.js
index 1a240eb165ab7837b8c5eca7daf15e289114ff9e..11e0f511b65b68b97d05389a9ee3ae2507c54f73 100644
--- a/packages/desktop-client/src/components/accounts/Account.js
+++ b/packages/desktop-client/src/components/accounts/Account.js
@@ -1400,10 +1400,6 @@ class AccountInternal extends React.PureComponent {
     return this.props.matchedTransactions.includes(id);
   };
 
-  onManagePayees = id => {
-    this.props.pushModal('manage-payees', { selectedPayee: id });
-  };
-
   onCreatePayee = name => {
     let trimmed = name.trim();
     if (trimmed !== '') {
@@ -1790,7 +1786,6 @@ class AccountInternal extends React.PureComponent {
                     onCloseAddTransaction={() =>
                       this.setState({ isAdding: false })
                     }
-                    onManagePayees={this.onManagePayees}
                     onCreatePayee={this.onCreatePayee}
                   />
                 </View>
diff --git a/packages/desktop-client/src/components/accounts/Filters.js b/packages/desktop-client/src/components/accounts/Filters.js
index d366dd6cfdaadad0f77aac522ae9f99192942466..0899e512322a1520d0f6b757e55d2f03c1dfdbe8 100644
--- a/packages/desktop-client/src/components/accounts/Filters.js
+++ b/packages/desktop-client/src/components/accounts/Filters.js
@@ -34,7 +34,7 @@ import { colors } from 'loot-design/src/style';
 import DeleteIcon from 'loot-design/src/svg/Delete';
 import SettingsSliderAlternate from 'loot-design/src/svg/v2/SettingsSliderAlternate';
 
-import { Value } from '../modals/ManageRules';
+import { Value } from '../ManageRules';
 import GenericInput from '../util/GenericInput';
 
 let filterFields = [
diff --git a/packages/desktop-client/src/components/accounts/TransactionList.js b/packages/desktop-client/src/components/accounts/TransactionList.js
index 8e2f16ba00612cd1f64d215873363e9f8bb34cba..eb030b3179fc9ab0297cc61442f0a7bfb9a65437 100644
--- a/packages/desktop-client/src/components/accounts/TransactionList.js
+++ b/packages/desktop-client/src/components/accounts/TransactionList.js
@@ -1,5 +1,6 @@
 import React, { useRef, useEffect, useCallback, useLayoutEffect } from 'react';
 import { useDispatch } from 'react-redux';
+import { useHistory } from 'react-router';
 
 import { send } from 'loot-core/src/platform/client/fetch';
 import {
@@ -78,13 +79,13 @@ export default function TransactionList({
   onRefetch,
   onRefetchUpToRow,
   onCloseAddTransaction,
-  onManagePayees,
   onCreatePayee
 }) {
   let dispatch = useDispatch();
   let table = useRef();
   let transactionsLatest = useRef();
   let scrollTo = useRef();
+  let history = useHistory();
 
   // useEffect(() => {
   //   if (scrollTo.current) {
@@ -160,6 +161,13 @@ export default function TransactionList({
     return newTransaction;
   }, []);
 
+  let onManagePayees = useCallback(
+    id => {
+      history.push('/payees', { selectedPayee: id });
+    },
+    [history]
+  );
+
   return (
     <TransactionTable
       ref={tableRef}
diff --git a/packages/desktop-client/src/components/modals/ManageRulesModal.js b/packages/desktop-client/src/components/modals/ManageRulesModal.js
new file mode 100644
index 0000000000000000000000000000000000000000..9362a1ee5d59a3706cdb1346d0858e698b9c9692
--- /dev/null
+++ b/packages/desktop-client/src/components/modals/ManageRulesModal.js
@@ -0,0 +1,31 @@
+import React, { useState } from 'react';
+
+import { Modal } from 'loot-design/src/components/common';
+import {
+  isDevelopmentEnvironment,
+  isPreviewEnvironment
+} from 'loot-design/src/util/environment';
+
+import ManageRules from '../ManageRules';
+
+export default function ManageRulesModal({ modalProps, payeeId }) {
+  let [loading, setLoading] = useState(true);
+  if (isDevelopmentEnvironment() || isPreviewEnvironment()) {
+    if (location.pathname !== '/payees') {
+      throw new Error(
+        `Possibly invalid use of ManageRulesModal, add the current url '${location.pathname}' to the allowlist if you're confident the modal can never appear on top of the '/rules' page.`
+      );
+    }
+  }
+  return (
+    <Modal
+      title="Rules"
+      padding={0}
+      loading={loading}
+      {...modalProps}
+      style={[modalProps.style, { flex: 1, maxWidth: '90%', maxHeight: '90%' }]}
+    >
+      {() => <ManageRules isModal payeeId={payeeId} setLoading={setLoading} />}
+    </Modal>
+  );
+}
diff --git a/packages/desktop-client/src/components/payees/ManagePayeesPage.js b/packages/desktop-client/src/components/payees/ManagePayeesPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..9c28b860105c039d58140f341368aec1dfde2fee
--- /dev/null
+++ b/packages/desktop-client/src/components/payees/ManagePayeesPage.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import { useLocation } from 'react-router';
+
+import { Page } from '../Page';
+import ManagePayeesWithData from './ManagePayeesWithData';
+
+export function ManagePayeesPage() {
+  let location = useLocation();
+  return (
+    <Page title="Payees">
+      <ManagePayeesWithData
+        initialSelectedIds={
+          location.state && location.state.selectedPayee
+            ? [location.state.selectedPayee]
+            : null
+        }
+      />
+    </Page>
+  );
+}
diff --git a/packages/desktop-client/src/components/payees/ManagePayeesWithData.js b/packages/desktop-client/src/components/payees/ManagePayeesWithData.js
index 2b7c56619d7541b94c4bc8677a91966532e437de..ade382cb11557fe5bc51d2f01b7b8a05d2d25f02 100644
--- a/packages/desktop-client/src/components/payees/ManagePayeesWithData.js
+++ b/packages/desktop-client/src/components/payees/ManagePayeesWithData.js
@@ -8,7 +8,6 @@ import { applyChanges } from 'loot-core/src/shared/util';
 import { ManagePayees } from 'loot-design/src/components/payees';
 
 function ManagePayeesWithData({
-  history,
   modalProps,
   initialSelectedIds,
   lastUndoState,
@@ -53,10 +52,7 @@ function ManagePayeesWithData({
       }
     });
 
-    undo.setUndoState('openModal', 'manage-payees');
-
     return () => {
-      undo.setUndoState('openModal', null);
       unlisten();
     };
   }, []);
diff --git a/packages/desktop-client/src/components/schedules/DiscoverSchedules.js b/packages/desktop-client/src/components/schedules/DiscoverSchedules.js
index f9fff59daf1fb46eb33bd1e36ecd8695fc802a53..cd161bbda7c36d7884e339caa027959b0f3f15e8 100644
--- a/packages/desktop-client/src/components/schedules/DiscoverSchedules.js
+++ b/packages/desktop-client/src/components/schedules/DiscoverSchedules.js
@@ -26,13 +26,14 @@ import useSelected, {
 } from 'loot-design/src/components/useSelected';
 import { colors } from 'loot-design/src/style';
 
-import { Page } from '../Page';
+import { Page, usePageType } from '../Page';
 import DisplayId from '../util/DisplayId';
 import { ScheduleAmountCell } from './SchedulesTable';
 
 let ROW_HEIGHT = 43;
 
 function DiscoverSchedulesTable({ schedules, loading }) {
+  let pageType = usePageType();
   let selectedItems = useSelectedItems();
   let dispatchSelected = useSelectedDispatch();
 
@@ -100,9 +101,12 @@ function DiscoverSchedulesTable({ schedules, loading }) {
       </TableHeader>
       <Table
         rowHeight={ROW_HEIGHT}
-        backgroundColor="transparent"
         version="v2"
-        style={{ flex: 1, backgroundColor: 'transparent' }}
+        backgroundColor={pageType.type === 'modal' ? 'transparent' : undefined}
+        style={{
+          flex: 1,
+          backgroundColor: pageType.type === 'modal' ? 'transparent' : undefined
+        }}
         items={schedules}
         loading={loading}
         isSelected={id => selectedItems.has(id)}
@@ -114,7 +118,7 @@ function DiscoverSchedulesTable({ schedules, loading }) {
 }
 
 export default function DiscoverSchedules() {
-  let location = useLocation();
+  let pageType = usePageType();
   let history = useHistory();
   let [schedules, setSchedules] = useState();
   let [creating, setCreating] = useState(false);
@@ -174,11 +178,7 @@ export default function DiscoverSchedules() {
         on all transactions for a schedule to be the same payee.
       </P>
       <P>
-        You can always do this later
-        {Platform.isBrowser
-          ? ' from the "Find schedules" item in the sidebar menu'
-          : ' from the "Tools > Find schedules" menu item'}
-        .
+        You can always do this later from “More Tools” &rarr; “Find Schedules.”
       </P>
 
       <SelectedProvider instance={selectedInst}>
@@ -192,9 +192,11 @@ export default function DiscoverSchedules() {
         direction="row"
         align="center"
         justify="flex-end"
-        style={{ paddingTop: 20 }}
+        style={{
+          paddingTop: 20,
+          paddingBottom: pageType.type === 'modal' ? 0 : 20
+        }}
       >
-        <Button onClick={() => history.goBack()}>Do nothing</Button>
         <ButtonWithLoading
           primary
           loading={creating}
diff --git a/packages/desktop-electron/index.js b/packages/desktop-electron/index.js
index 3ef5c6d4a73fde7bd1f20abc0f70be6c836803d9..631810808845011f9b6d127c22b440c24934d86b 100644
--- a/packages/desktop-electron/index.js
+++ b/packages/desktop-electron/index.js
@@ -217,11 +217,7 @@ function updateMenu(isBudgetOpen) {
   const fileItems = file.submenu.items;
   fileItems
     .filter(
-      item =>
-        item.label === 'Start Tutorial' ||
-        item.label === 'Manage Payees...' ||
-        item.label === 'Manage Rules...' ||
-        item.label === 'Load Backup...'
+      item => item.label === 'Start Tutorial' || item.label === 'Load Backup...'
     )
 
     .map(item => (item.enabled = isBudgetOpen));
diff --git a/packages/desktop-electron/menu.js b/packages/desktop-electron/menu.js
index bd797f2cebec4f58571e15ff695dc9d73770ab14..05fe9caa2e1d437ddcc345975401aeaea7551784 100644
--- a/packages/desktop-electron/menu.js
+++ b/packages/desktop-electron/menu.js
@@ -19,34 +19,6 @@ function getMenu(isDev, createWindow) {
         //     }
         //   }
         // },
-        {
-          label: 'Manage Payees...',
-          enabled: false,
-          click(item, focusedWindow) {
-            if (
-              focusedWindow &&
-              focusedWindow.webContents.getTitle() === 'Actual'
-            ) {
-              focusedWindow.webContents.executeJavaScript(
-                '__actionsForMenu.pushModal("manage-payees")'
-              );
-            }
-          }
-        },
-        {
-          label: 'Manage Rules...',
-          enabled: false,
-          click(item, focusedWindow) {
-            if (
-              focusedWindow &&
-              focusedWindow.webContents.getTitle() === 'Actual'
-            ) {
-              focusedWindow.webContents.executeJavaScript(
-                '__actionsForMenu.pushModal("manage-rules")'
-              );
-            }
-          }
-        },
         {
           label: 'Load Backup...',
           enabled: false,
diff --git a/packages/loot-design/src/components/common.js b/packages/loot-design/src/components/common.js
index 4ce357e24d053b75a5412783bad2af5f9903c29f..7403dcf98d1f3e5998b947a02fd48da9502c6a0b 100644
--- a/packages/loot-design/src/components/common.js
+++ b/packages/loot-design/src/components/common.js
@@ -823,7 +823,8 @@ export function Modal({
           <View
             style={{
               padding: 20,
-              position: 'relative'
+              position: 'relative',
+              flexShrink: 0
             }}
           >
             {showTitle && (
diff --git a/packages/loot-design/src/components/payees.js b/packages/loot-design/src/components/payees.js
index 009f8f91f1b367eb68cc990a07214d91b67a5429..35d5a75eaf0fbd20fa5d230300828373551d44bf 100644
--- a/packages/loot-design/src/components/payees.js
+++ b/packages/loot-design/src/components/payees.js
@@ -30,6 +30,7 @@ import {
 } from './common';
 import {
   Table,
+  TableHeader,
   Row,
   Cell,
   InputCell,
@@ -230,7 +231,7 @@ function PayeeTableHeader() {
 
   return (
     <View>
-      <Row
+      <TableHeader
         borderColor={borderColor}
         style={{
           backgroundColor: 'white',
@@ -239,6 +240,7 @@ function PayeeTableHeader() {
           userSelect: 'none'
         }}
         collapsed={true}
+        version="v2"
       >
         <SelectCell
           exposed={true}
@@ -247,7 +249,7 @@ function PayeeTableHeader() {
           onSelect={() => dispatchSelected({ type: 'select-all' })}
         />
         <Cell value="Name" width="flex" />
-      </Row>
+      </TableHeader>
     </View>
   );
 }
@@ -470,108 +472,90 @@ export const ManagePayees = React.forwardRef(
     let payeesById = getPayeesById(payees);
 
     return (
-      <Modal
-        title="Payees"
-        padding={0}
-        {...modalProps}
-        style={[modalProps.style, { flex: 'inherit', maxWidth: '90%' }]}
-      >
+      <View style={{ height: '100%' }}>
         <View
           style={{
-            maxWidth: '100%',
-            width: 900,
-            height: 550
+            flexDirection: 'row',
+            alignItems: 'center',
+            padding: '0 10px 5px'
           }}
         >
+          <Component initialState={{ menuOpen: false }}>
+            {({ state, setState }) => (
+              <View>
+                <Button
+                  bare
+                  style={{ marginRight: 10 }}
+                  disabled={buttonsDisabled}
+                  onClick={() => setState({ menuOpen: true })}
+                >
+                  {buttonsDisabled
+                    ? 'No payees selected'
+                    : selected.items.size +
+                      ' ' +
+                      plural(selected.items.size, 'payee', 'payees')}
+                  <ExpandArrow width={8} height={8} style={{ marginLeft: 5 }} />
+                </Button>
+                {state.menuOpen && (
+                  <PayeeMenu
+                    payeesById={payeesById}
+                    selectedPayees={selected.items}
+                    onClose={() => setState({ menuOpen: false })}
+                    onDelete={onDelete}
+                    onMerge={onMerge}
+                  />
+                )}
+              </View>
+            )}
+          </Component>
+          <View style={{ flex: 1 }} />
+          <Input
+            placeholder="Filter payees..."
+            value={filter}
+            onChange={e => {
+              applyFilter(e.target.value);
+              tableNavigator.onEdit(null);
+            }}
+            style={{
+              width: 350,
+              borderColor: 'transparent',
+              backgroundColor: colors.n11,
+              ':focus': {
+                backgroundColor: 'white',
+                '::placeholder': { color: colors.n8 }
+              }
+            }}
+          />
+        </View>
+
+        <SelectedProvider instance={selected} fetchAllIds={getSelectableIds}>
           <View
             style={{
-              flexDirection: 'row',
-              alignItems: 'center',
-              padding: '0 10px'
+              flex: 1,
+              border: '1px solid ' + colors.border,
+              borderRadius: 4,
+              overflow: 'hidden'
             }}
           >
-            <Component initialState={{ menuOpen: false }}>
-              {({ state, setState }) => (
-                <View>
-                  <Button
-                    bare
-                    style={{ marginRight: 10 }}
-                    disabled={buttonsDisabled}
-                    onClick={() => setState({ menuOpen: true })}
-                  >
-                    {buttonsDisabled
-                      ? 'No payees selected'
-                      : selected.items.size +
-                        ' ' +
-                        plural(selected.items.size, 'payee', 'payees')}
-                    <ExpandArrow
-                      width={8}
-                      height={8}
-                      style={{ marginLeft: 5 }}
-                    />
-                  </Button>
-                  {state.menuOpen && (
-                    <PayeeMenu
-                      payeesById={payeesById}
-                      selectedPayees={selected.items}
-                      onClose={() => setState({ menuOpen: false })}
-                      onDelete={onDelete}
-                      onMerge={onMerge}
-                    />
-                  )}
-                </View>
-              )}
-            </Component>
-            <View style={{ flex: 1 }} />
-            <Input
-              placeholder="Filter payees..."
-              value={filter}
-              onChange={e => {
-                applyFilter(e.target.value);
-                tableNavigator.onEdit(null);
-              }}
-              style={{
-                width: 350,
-                borderColor: 'transparent',
-                backgroundColor: colors.n11,
-                ':focus': {
-                  backgroundColor: 'white',
-                  '::placeholder': { color: colors.n8 }
-                }
-              }}
-            />
+            <PayeeTableHeader />
+            {filteredPayees.length === 0 ? (
+              <EmptyMessage text="No payees" style={{ marginTop: 15 }} />
+            ) : (
+              <PayeeTable
+                ref={table}
+                payees={filteredPayees}
+                ruleCounts={ruleCounts}
+                categoryGroups={categoryGroups}
+                highlightedRows={highlightedRows}
+                navigator={tableNavigator}
+                onUpdate={onUpdate}
+                onViewRules={onViewRules}
+                onCreateRule={onCreateRule}
+              />
+            )}
           </View>
-
-          <SelectedProvider instance={selected} fetchAllIds={getSelectableIds}>
-            <View
-              style={{
-                flex: 1,
-                border: '1px solid ' + colors.border,
-                borderRadius: 4,
-                overflow: 'hidden',
-                margin: 5
-              }}
-            >
-              <PayeeTableHeader />
-              {filteredPayees.length === 0 ? (
-                <EmptyMessage text="No payees" style={{ marginTop: 15 }} />
-              ) : (
-                <PayeeTable
-                  ref={table}
-                  payees={filteredPayees}
-                  ruleCounts={ruleCounts}
-                  categoryGroups={categoryGroups}
-                  highlightedRows={highlightedRows}
-                  navigator={tableNavigator}
-                  onUpdate={onUpdate}
-                  onViewRules={onViewRules}
-                  onCreateRule={onCreateRule}
-                />
-              )}
-            </View>
-          </SelectedProvider>
-        </View>
-      </Modal>
+        </SelectedProvider>
+      </View>
     );
   }
 );
diff --git a/packages/loot-design/src/components/sidebar.js b/packages/loot-design/src/components/sidebar.js
index 669c69fd05a681566bbee46c773167a324939b3e..a5f0218c0db8fc8add44dda44d966f175c5852aa 100644
--- a/packages/loot-design/src/components/sidebar.js
+++ b/packages/loot-design/src/components/sidebar.js
@@ -1,5 +1,7 @@
-import React, { useState, useMemo } from 'react';
+import React, { useState, useMemo, useCallback, useEffect } from 'react';
+import { RectButton } from 'react-native-gesture-handler';
 import { useDispatch } from 'react-redux';
+import { useLocation, useHistory } from 'react-router';
 import { withRouter } from 'react-router-dom';
 
 import { css } from 'glamor';
@@ -11,10 +13,12 @@ import PiggyBank from 'loot-design/src/svg/v1/PiggyBank';
 
 import { styles, colors } from '../style';
 import Add from '../svg/v1/Add';
+import ChevronRight from '../svg/v1/CheveronRight';
 import Cog from '../svg/v1/Cog';
 import DotsHorizontalTriple from '../svg/v1/DotsHorizontalTriple';
 import Reports from '../svg/v1/Reports';
 import Wallet from '../svg/v1/Wallet';
+import Wrench from '../svg/v1/Wrench';
 import ArrowButtonLeft1 from '../svg/v2/ArrowButtonLeft1';
 import CalendarIcon from '../svg/v2/Calendar';
 import {
@@ -32,64 +36,73 @@ import CellValue from './spreadsheet/CellValue';
 
 export const SIDEBAR_WIDTH = 240;
 
-export function Item({
+function Item({
   children,
   icon,
   title,
   style,
+  indent = 0,
   to,
   exact,
-  onButtonPress
+  onClick,
+  button,
+  forceHover = false,
+  forceActive = false
 }) {
-  const showButton = title === 'Accounts';
+  const hoverStyle = {
+    backgroundColor: colors.n2
+  };
+  const activeStyle = {
+    borderLeft: '4px solid ' + colors.p8,
+    paddingLeft: 19 + indent - 4,
+    color: colors.p8
+  };
+  const linkStyle = [
+    {
+      ...styles.mediumText,
+      paddingTop: 9,
+      paddingBottom: 9,
+      paddingLeft: 19 + indent,
+      paddingRight: 10,
+      textDecoration: 'none',
+      color: colors.n9,
+      ...(forceHover ? hoverStyle : {}),
+      ...(forceActive ? activeStyle : {})
+    },
+    { ':hover': hoverStyle }
+  ];
+
+  const content = (
+    <View
+      style={{
+        flexDirection: 'row',
+        alignItems: 'center',
+        height: 20
+      }}
+    >
+      {icon}
+      <Block style={{ marginLeft: 8 }}>{title}</Block>
+      <View style={{ flex: 1 }} />
+      {button}
+    </View>
+  );
 
   return (
-    <View style={style}>
-      <AnchorLink
-        style={[
-          {
-            ...styles.mediumText,
-            paddingTop: 9,
-            paddingBottom: 9,
-            paddingLeft: 19,
-            paddingRight: 10,
-            textDecoration: 'none',
-            color: colors.n9
-          },
-          { ':hover': { backgroundColor: colors.n2 } }
-        ]}
-        to={to}
-        exact={exact}
-        activeStyle={{
-          borderLeft: '4px solid ' + colors.p8,
-          paddingLeft: 19 - 4,
-          color: colors.p8
-        }}
-      >
-        <View
-          style={{
-            flexDirection: 'row',
-            alignItems: 'center',
-            height: 20
-          }}
+    <View style={[{ flexShrink: 0 }, style]}>
+      {onClick ? (
+        <RectButton onClick={onClick}>
+          <View style={linkStyle}>{content}</View>
+        </RectButton>
+      ) : (
+        <AnchorLink
+          style={linkStyle}
+          to={to}
+          exact={exact}
+          activeStyle={activeStyle}
         >
-          {icon}
-          <Block style={{ marginLeft: 8 }}>{title}</Block>
-          <View style={{ flex: 1 }} />
-          {showButton && (
-            <Button
-              bare
-              onClick={e => {
-                e.stopPropagation();
-                e.preventDefault();
-                onButtonPress();
-              }}
-            >
-              <Add width={12} height={12} style={{ color: colors.n6 }} />
-            </Button>
-          )}
-        </View>
-      </AnchorLink>
+          {content}
+        </AnchorLink>
+      )}
 
       {children ? <View style={{ marginTop: 5 }}>{children}</View> : null}
     </View>
@@ -212,13 +225,10 @@ function Account({
   );
 }
 
-export function Accounts({
+function Accounts({
   accounts,
   failedAccounts,
   updatedAccounts,
-  to,
-  icon,
-  history,
   getAccountPath,
   budgetedAccountPath,
   offBudgetAccountPath,
@@ -269,98 +279,89 @@ export function Accounts({
   };
 
   return (
-    <Item
-      title="Accounts"
-      to={to}
-      icon={icon}
-      exact={true}
-      style={{ marginBottom: 5, flex: 1 }}
-      onButtonPress={onAddAccount}
-    >
-      <View style={{ overflow: 'auto', marginTop: -5 }}>
-        {budgetedAccounts.length > 0 && (
-          <Account
-            name="For budget"
-            to={budgetedAccountPath}
-            query={getOnBudgetBalance()}
-            style={{ marginTop: 15, color: colors.n6 }}
-          />
-        )}
+    <View>
+      {budgetedAccounts.length > 0 && (
+        <Account
+          name="For budget"
+          to={budgetedAccountPath}
+          query={getOnBudgetBalance()}
+          style={{ marginTop: 15, color: colors.n6 }}
+        />
+      )}
 
-        {budgetedAccounts.map((account, i) => (
-          <Account
-            key={account.id}
-            name={account.name}
-            account={account}
-            connected={!!account.bankId}
-            failed={failedAccounts && failedAccounts.has(account.id)}
-            updated={updatedAccounts && updatedAccounts.includes(account.id)}
-            to={getAccountPath(account)}
-            query={getBalanceQuery(account)}
-            onDragChange={onDragChange}
-            onDrop={onReorder}
-            outerStyle={makeDropPadding(i, budgetedAccounts.length)}
-          />
-        ))}
+      {budgetedAccounts.map((account, i) => (
+        <Account
+          key={account.id}
+          name={account.name}
+          account={account}
+          connected={!!account.bankId}
+          failed={failedAccounts && failedAccounts.has(account.id)}
+          updated={updatedAccounts && updatedAccounts.includes(account.id)}
+          to={getAccountPath(account)}
+          query={getBalanceQuery(account)}
+          onDragChange={onDragChange}
+          onDrop={onReorder}
+          outerStyle={makeDropPadding(i, budgetedAccounts.length)}
+        />
+      ))}
+
+      {offbudgetAccounts.length > 0 && (
+        <Account
+          name="Off budget"
+          to={offBudgetAccountPath}
+          query={getOffBudgetBalance()}
+          style={{ color: colors.n6 }}
+        />
+      )}
 
-        {offbudgetAccounts.length > 0 && (
-          <Account
-            name="Off budget"
-            to={offBudgetAccountPath}
-            query={getOffBudgetBalance()}
-            style={{ color: colors.n6 }}
-          />
-        )}
+      {offbudgetAccounts.map((account, i) => (
+        <Account
+          key={account.id}
+          name={account.name}
+          account={account}
+          connected={!!account.bankId}
+          failed={failedAccounts && failedAccounts.has(account.id)}
+          updated={updatedAccounts && updatedAccounts.includes(account.id)}
+          to={getAccountPath(account)}
+          query={getBalanceQuery(account)}
+          onDragChange={onDragChange}
+          onDrop={onReorder}
+          outerStyle={makeDropPadding(i, offbudgetAccounts.length)}
+        />
+      ))}
+
+      {closedAccounts.length > 0 && (
+        <View
+          style={[
+            accountNameStyle,
+            {
+              marginTop: 15,
+              color: colors.n6,
+              flexDirection: 'row',
+              userSelect: 'none',
+              alignItems: 'center',
+              flexShrink: 0
+            }
+          ]}
+          onClick={onToggleClosedAccounts}
+        >
+          {'Closed Accounts' + (showClosedAccounts ? '' : '...')}
+        </View>
+      )}
 
-        {offbudgetAccounts.map((account, i) => (
+      {showClosedAccounts &&
+        closedAccounts.map((account, i) => (
           <Account
             key={account.id}
             name={account.name}
             account={account}
-            connected={!!account.bankId}
-            failed={failedAccounts && failedAccounts.has(account.id)}
-            updated={updatedAccounts && updatedAccounts.includes(account.id)}
             to={getAccountPath(account)}
             query={getBalanceQuery(account)}
             onDragChange={onDragChange}
             onDrop={onReorder}
-            outerStyle={makeDropPadding(i, offbudgetAccounts.length)}
           />
         ))}
-
-        {closedAccounts.length > 0 && (
-          <View
-            style={[
-              accountNameStyle,
-              {
-                marginTop: 15,
-                color: colors.n6,
-                flexDirection: 'row',
-                userSelect: 'none',
-                alignItems: 'center',
-                flexShrink: 0
-              }
-            ]}
-            onClick={onToggleClosedAccounts}
-          >
-            {'Closed Accounts' + (showClosedAccounts ? '' : '...')}
-          </View>
-        )}
-
-        {showClosedAccounts &&
-          closedAccounts.map((account, i) => (
-            <Account
-              key={account.id}
-              name={account.name}
-              account={account}
-              to={getAccountPath(account)}
-              query={getBalanceQuery(account)}
-              onDragChange={onDragChange}
-              onDrop={onReorder}
-            />
-          ))}
-      </View>
-    </Item>
+    </View>
   );
 }
 
@@ -382,18 +383,6 @@ const MenuButton = withRouter(function MenuButton({ history }) {
     setMenuOpen(false);
 
     switch (type) {
-      case 'open-payees':
-        dispatch(pushModal('manage-payees'));
-        break;
-      case 'open-rules':
-        dispatch(pushModal('manage-rules'));
-        break;
-      case 'find-schedules':
-        history.push('/schedule/discover', { locationPtr: history.location });
-        break;
-      case 'repair-splits':
-        history.push('/tools/fix-splits', { locationPtr: history.location });
-        break;
       case 'settings':
         history.push('/settings');
         break;
@@ -408,11 +397,6 @@ const MenuButton = withRouter(function MenuButton({ history }) {
   }
 
   let items = [
-    { name: 'open-payees', text: 'Manage Payees' },
-    { name: 'open-rules', text: 'Manage Rules' },
-    { name: 'find-schedules', text: 'Find schedules' },
-    { name: 'repair-splits', text: 'Repair split transactions' },
-    Menu.line,
     { name: 'settings', text: 'Settings' },
     { name: 'help', text: 'Help' },
     { name: 'close', text: 'Close File' }
@@ -446,6 +430,78 @@ const MenuButton = withRouter(function MenuButton({ history }) {
   );
 });
 
+function Tools() {
+  let [isOpen, setOpen] = useState(false);
+  let location = useLocation();
+  let history = useHistory();
+  let onToggle = useCallback(() => setOpen(open => !open), []);
+
+  let items = [
+    { name: 'payees', text: 'Payees' },
+    { name: 'rules', text: 'Rules' },
+    { name: 'find-schedules', text: 'Find schedules' },
+    { name: 'repair-splits', text: 'Repair split transactions' }
+  ];
+
+  let onMenuSelect = useCallback(
+    type => {
+      switch (type) {
+        case 'payees':
+          history.push('/payees');
+          break;
+        case 'rules':
+          history.push('/rules');
+          break;
+        case 'find-schedules':
+          history.push('/schedule/discover');
+          break;
+        case 'repair-splits':
+          history.push('/tools/fix-splits', { locationPtr: history.location });
+          break;
+        default:
+      }
+      setOpen(false);
+    },
+    [history]
+  );
+
+  return (
+    <View style={{ flexShrink: 0 }}>
+      <Item
+        title="More Tools"
+        icon={<Wrench width={15} height={15} style={{ color: 'inherit' }} />}
+        exact={true}
+        onClick={onToggle}
+        style={{ pointerEvents: isOpen ? 'none' : 'auto' }}
+        forceHover={isOpen}
+        forceActive={[
+          '/payees',
+          '/rules',
+          '/tools',
+          '/schedule/discover'
+        ].some(route => location.pathname.startsWith(route))}
+        button={
+          <ChevronRight
+            width={12}
+            height={12}
+            style={{ color: colors.n6, marginRight: 6 }}
+          />
+        }
+      />
+      {isOpen && (
+        <Tooltip
+          position="right"
+          offset={-8}
+          style={{ padding: 0 }}
+          onClose={onToggle}
+        >
+          <Menu onMenuSelect={onMenuSelect} items={items} />
+        </Tooltip>
+      )}
+    </View>
+  );
+}
+
 export function Sidebar({
   style,
   budgetName,
@@ -470,7 +526,6 @@ export function Sidebar({
         {
           width: SIDEBAR_WIDTH,
           color: colors.n9,
-          overflow: 'auto',
           backgroundColor: colors.n1,
           '& .float': {
             opacity: 0,
@@ -540,40 +595,66 @@ export function Sidebar({
         {!hasWindowButtons && <ToggleButton onFloat={onFloat} />}
         {Platform.isBrowser && <MenuButton />}
       </View>
-      <Item
-        title="Budget"
-        icon={<Wallet width={15} height={15} style={{ color: 'inherit' }} />}
-        to="/budget"
-      />
-      <Item
-        title="Reports"
-        icon={<Reports width={15} height={15} style={{ color: 'inherit' }} />}
-        to="/reports"
-      />
-      <Item
-        title="Schedules"
-        icon={
-          <CalendarIcon width={15} height={15} style={{ color: 'inherit' }} />
-        }
-        to="/schedules"
-      />
-      <Accounts
-        to="/accounts"
-        icon={<PiggyBank width={15} height={15} style={{ color: 'inherit' }} />}
-        accounts={accounts}
-        failedAccounts={failedAccounts}
-        updatedAccounts={updatedAccounts}
-        getAccountPath={account => `/accounts/${account.id}`}
-        budgetedAccountPath="/accounts/budgeted"
-        offBudgetAccountPath="/accounts/offbudget"
-        getBalanceQuery={getBalanceQuery}
-        getOnBudgetBalance={getOnBudgetBalance}
-        getOffBudgetBalance={getOffBudgetBalance}
-        showClosedAccounts={showClosedAccounts}
-        onAddAccount={onAddAccount}
-        onToggleClosedAccounts={onToggleClosedAccounts}
-        onReorder={onReorder}
-      />
+
+      <View style={{ overflow: 'auto' }}>
+        <Item
+          title="Budget"
+          icon={<Wallet width={15} height={15} style={{ color: 'inherit' }} />}
+          to="/budget"
+        />
+        <Item
+          title="Reports"
+          icon={<Reports width={15} height={15} style={{ color: 'inherit' }} />}
+          to="/reports"
+        />
+
+        <Item
+          title="Schedules"
+          icon={
+            <CalendarIcon width={15} height={15} style={{ color: 'inherit' }} />
+          }
+          to="/schedules"
+        />
+
+        <Tools />
+
+        <Item
+          title="Accounts"
+          to="/accounts"
+          icon={
+            <PiggyBank width={15} height={15} style={{ color: 'inherit' }} />
+          }
+          exact={true}
+          button={
+            <Button
+              bare
+              onClick={e => {
+                e.stopPropagation();
+                e.preventDefault();
+                onAddAccount();
+              }}
+            >
+              <Add width={12} height={12} style={{ color: colors.n6 }} />
+            </Button>
+          }
+        />
+
+        <Accounts
+          accounts={accounts}
+          failedAccounts={failedAccounts}
+          updatedAccounts={updatedAccounts}
+          getAccountPath={account => `/accounts/${account.id}`}
+          budgetedAccountPath="/accounts/budgeted"
+          offBudgetAccountPath="/accounts/offbudget"
+          getBalanceQuery={getBalanceQuery}
+          getOnBudgetBalance={getOnBudgetBalance}
+          getOffBudgetBalance={getOffBudgetBalance}
+          showClosedAccounts={showClosedAccounts}
+          onAddAccount={onAddAccount}
+          onToggleClosedAccounts={onToggleClosedAccounts}
+          onReorder={onReorder}
+        />
+      </View>
     </View>
   );
 }
diff --git a/packages/loot-design/src/components/table.js b/packages/loot-design/src/components/table.js
index 37cf78bb243b696b0685432f2186350f50162aff..8f2dbecc40dc1e1e41800ab824359e29f2d3b0fd 100644
--- a/packages/loot-design/src/components/table.js
+++ b/packages/loot-design/src/components/table.js
@@ -720,7 +720,11 @@ export function TableHeader({ headers, children, version, ...rowProps }) {
   return (
     <View
       style={
-        version === 'v2' && { borderRadius: '6px 6px 0 0', overflow: 'hidden' }
+        version === 'v2' && {
+          borderRadius: '6px 6px 0 0',
+          overflow: 'hidden',
+          flexShrink: 0
+        }
       }
     >
       <Row
@@ -984,7 +988,14 @@ export const Table = React.forwardRef(
     if (loading) {
       return (
         <View
-          style={[{ flex: 1, justifyContent: 'center', alignItems: 'center' }]}
+          style={[
+            {
+              flex: 1,
+              justifyContent: 'center',
+              alignItems: 'center',
+              backgroundColor
+            }
+          ]}
         >
           <AnimatedLoading width={25} color={colors.n1} />
         </View>
diff --git a/packages/loot-design/src/components/tooltips.js b/packages/loot-design/src/components/tooltips.js
index 1543446722a32bbdd034bc84e7b67a40369a2957..b82f12c73dc81eb50a313e7cabc17bd64da094b0 100644
--- a/packages/loot-design/src/components/tooltips.js
+++ b/packages/loot-design/src/components/tooltips.js
@@ -242,6 +242,8 @@ export class Tooltip extends React.Component {
         return 'top-center';
       case 'top-center':
         return 'bottom-center';
+      case 'right':
+        return 'right';
       default:
     }
   }
@@ -300,6 +302,9 @@ export class Tooltip extends React.Component {
       style.top = anchorRect.top + anchorRect.height + offset + 'px';
       style.left = anchorRect.left + 'px';
       style.width = anchorRect.width + 'px';
+    } else if (position === 'right') {
+      style.top = anchorRect.top + 'px';
+      style.left = anchorRect.left + anchorRect.width + offset + 'px';
     } else {
       throw new Error('Invalid position for Tooltip: ' + position);
     }