about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-10-14 22:09:47 +0300
committerGitHub <noreply@github.com>2024-10-14 22:09:47 +0300
commit2d88463453abfad1e9e45bbd6cdbcd5824a7e770 (patch)
tree40c411208b5e0c68d02814d5f525243c27cce306
parent0f40013963aaf4f3ac893ce58958ea30bc7a1efd (diff)
downloadvoidsky-2d88463453abfad1e9e45bbd6cdbcd5824a7e770.tar.zst
Remove top padding from shell, move down into individual screens (#5548)
-rw-r--r--src/Navigation.tsx26
-rw-r--r--src/components/Layout.tsx41
-rw-r--r--src/screens/E2E/SharedPreferencesTesterScreen.tsx199
-rw-r--r--src/screens/Hashtag.tsx31
-rw-r--r--src/screens/Messages/ChatList.tsx9
-rw-r--r--src/screens/Messages/Conversation.tsx13
-rw-r--r--src/screens/Messages/Settings.tsx175
-rw-r--r--src/screens/Moderation/index.tsx51
-rw-r--r--src/screens/Post/PostLikedBy.tsx18
-rw-r--r--src/screens/Post/PostQuotes.tsx18
-rw-r--r--src/screens/Post/PostRepostedBy.tsx18
-rw-r--r--src/screens/Profile/KnownFollowers.tsx28
-rw-r--r--src/screens/Profile/ProfileLabelerLikedBy.tsx6
-rw-r--r--src/screens/Settings/AppearanceSettings.tsx6
-rw-r--r--src/screens/StarterPack/StarterPackScreen.tsx27
-rw-r--r--src/screens/StarterPack/Wizard/index.tsx83
-rw-r--r--src/view/screens/AccessibilitySettings.tsx5
-rw-r--r--src/view/screens/AppPasswords.tsx9
-rw-r--r--src/view/screens/CommunityGuidelines.tsx24
-rw-r--r--src/view/screens/CopyrightPolicy.tsx24
-rw-r--r--src/view/screens/Debug.tsx47
-rw-r--r--src/view/screens/DebugMod.tsx577
-rw-r--r--src/view/screens/Feeds.tsx8
-rw-r--r--src/view/screens/Home.tsx21
-rw-r--r--src/view/screens/LanguageSettings.tsx421
-rw-r--r--src/view/screens/Lists.tsx5
-rw-r--r--src/view/screens/Log.tsx17
-rw-r--r--src/view/screens/ModerationBlockedAccounts.tsx145
-rw-r--r--src/view/screens/ModerationModlists.tsx5
-rw-r--r--src/view/screens/ModerationMutedAccounts.tsx143
-rw-r--r--src/view/screens/NotFound.tsx24
-rw-r--r--src/view/screens/Notifications.tsx64
-rw-r--r--src/view/screens/NotificationsSettings.tsx95
-rw-r--r--src/view/screens/PostThread.tsx15
-rw-r--r--src/view/screens/PreferencesExternalEmbeds.tsx12
-rw-r--r--src/view/screens/PreferencesFollowingFeed.tsx5
-rw-r--r--src/view/screens/PreferencesThreads.tsx5
-rw-r--r--src/view/screens/PrivacyPolicy.tsx24
-rw-r--r--src/view/screens/Profile.tsx11
-rw-r--r--src/view/screens/ProfileFeed.tsx55
-rw-r--r--src/view/screens/ProfileFeedLikedBy.tsx14
-rw-r--r--src/view/screens/ProfileFollowers.tsx24
-rw-r--r--src/view/screens/ProfileFollows.tsx24
-rw-r--r--src/view/screens/ProfileList.tsx9
-rw-r--r--src/view/screens/SavedFeeds.tsx222
-rw-r--r--src/view/screens/Search/Explore.tsx8
-rw-r--r--src/view/screens/Search/Search.tsx5
-rw-r--r--src/view/screens/Settings/index.tsx5
-rw-r--r--src/view/screens/Storybook/index.tsx15
-rw-r--r--src/view/screens/Support.tsx27
-rw-r--r--src/view/screens/TermsOfService.tsx24
-rw-r--r--src/view/shell/index.tsx28
-rw-r--r--src/view/shell/index.web.tsx15
53 files changed, 1545 insertions, 1385 deletions
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
index 323f668b7..81d08c7da 100644
--- a/src/Navigation.tsx
+++ b/src/Navigation.tsx
@@ -17,7 +17,6 @@ import {
 
 import {timeout} from '#/lib/async/timeout'
 import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
-import {usePalette} from '#/lib/hooks/usePalette'
 import {useWebScrollRestoration} from '#/lib/hooks/useWebScrollRestoration'
 import {buildStateObject} from '#/lib/routes/helpers'
 import {
@@ -93,6 +92,7 @@ import {
   StarterPackScreenShort,
 } from '#/screens/StarterPack/StarterPackScreen'
 import {Wizard} from '#/screens/StarterPack/Wizard'
+import {useTheme} from '#/alf'
 import {router} from '#/routes'
 import {Referrer} from '../modules/expo-bluesky-swiss-army'
 
@@ -412,7 +412,7 @@ function TabsNavigator() {
 }
 
 function HomeTabNavigator() {
-  const pal = usePalette('default')
+  const t = useTheme()
 
   return (
     <HomeTab.Navigator
@@ -422,7 +422,7 @@ function HomeTabNavigator() {
         gestureEnabled: true,
         fullScreenGestureEnabled: true,
         headerShown: false,
-        contentStyle: pal.view,
+        contentStyle: t.atoms.bg,
       }}>
       <HomeTab.Screen name="Home" getComponent={() => HomeScreen} />
       <HomeTab.Screen name="Start" getComponent={() => HomeScreen} />
@@ -432,7 +432,7 @@ function HomeTabNavigator() {
 }
 
 function SearchTabNavigator() {
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <SearchTab.Navigator
       screenOptions={{
@@ -441,7 +441,7 @@ function SearchTabNavigator() {
         gestureEnabled: true,
         fullScreenGestureEnabled: true,
         headerShown: false,
-        contentStyle: pal.view,
+        contentStyle: t.atoms.bg,
       }}>
       <SearchTab.Screen name="Search" getComponent={() => SearchScreen} />
       {commonScreens(SearchTab as typeof HomeTab)}
@@ -450,7 +450,7 @@ function SearchTabNavigator() {
 }
 
 function NotificationsTabNavigator() {
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <NotificationsTab.Navigator
       screenOptions={{
@@ -459,7 +459,7 @@ function NotificationsTabNavigator() {
         gestureEnabled: true,
         fullScreenGestureEnabled: true,
         headerShown: false,
-        contentStyle: pal.view,
+        contentStyle: t.atoms.bg,
       }}>
       <NotificationsTab.Screen
         name="Notifications"
@@ -472,7 +472,7 @@ function NotificationsTabNavigator() {
 }
 
 function MyProfileTabNavigator() {
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <MyProfileTab.Navigator
       screenOptions={{
@@ -481,7 +481,7 @@ function MyProfileTabNavigator() {
         gestureEnabled: true,
         fullScreenGestureEnabled: true,
         headerShown: false,
-        contentStyle: pal.view,
+        contentStyle: t.atoms.bg,
       }}>
       <MyProfileTab.Screen
         // @ts-ignore // TODO: fix this broken type in ProfileScreen
@@ -498,7 +498,7 @@ function MyProfileTabNavigator() {
 }
 
 function MessagesTabNavigator() {
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <MessagesTab.Navigator
       screenOptions={{
@@ -507,7 +507,7 @@ function MessagesTabNavigator() {
         gestureEnabled: true,
         fullScreenGestureEnabled: true,
         headerShown: false,
-        contentStyle: pal.view,
+        contentStyle: t.atoms.bg,
       }}>
       <MessagesTab.Screen
         name="Messages"
@@ -527,7 +527,7 @@ function MessagesTabNavigator() {
  * in a single ("flat") stack.
  */
 const FlatNavigator = () => {
-  const pal = usePalette('default')
+  const t = useTheme()
   const numUnread = useUnreadNotifications()
   const screenListeners = useWebScrollRestoration()
   const title = (page: MessageDescriptor) => bskyTitle(i18n._(page), numUnread)
@@ -541,7 +541,7 @@ const FlatNavigator = () => {
         gestureEnabled: true,
         fullScreenGestureEnabled: true,
         headerShown: false,
-        contentStyle: pal.view,
+        contentStyle: t.atoms.bg,
       }}>
       <Flat.Screen
         name="Home"
diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx
new file mode 100644
index 000000000..57e373164
--- /dev/null
+++ b/src/components/Layout.tsx
@@ -0,0 +1,41 @@
+import React from 'react'
+import {View, ViewStyle} from 'react-native'
+import {StyleProp} from 'react-native'
+import {useSafeAreaInsets} from 'react-native-safe-area-context'
+
+import {atoms as a} from '#/alf'
+
+// Every screen should have a Layout component wrapping it.
+// This component provides a default padding for the top of the screen.
+// This allows certain screens to avoid the top padding if they want to.
+//
+// In a future PR I will add a unified header component to this file and
+// things like a preconfigured scrollview.
+
+/**
+ * Every screen should have a Layout.Screen component wrapping it.
+ * This component provides a default padding for the top of the screen
+ * and height/minHeight
+ */
+let Screen = ({
+  disableTopPadding,
+  style,
+  ...props
+}: React.ComponentProps<typeof View> & {
+  disableTopPadding?: boolean
+  style?: StyleProp<ViewStyle>
+}): React.ReactNode => {
+  const {top} = useSafeAreaInsets()
+  return (
+    <View
+      style={[
+        {paddingTop: disableTopPadding ? 0 : top},
+        a.util_screen_outer,
+        style,
+      ]}
+      {...props}
+    />
+  )
+}
+Screen = React.memo(Screen)
+export {Screen}
diff --git a/src/screens/E2E/SharedPreferencesTesterScreen.tsx b/src/screens/E2E/SharedPreferencesTesterScreen.tsx
index 06bf538ea..5a9e6cd22 100644
--- a/src/screens/E2E/SharedPreferencesTesterScreen.tsx
+++ b/src/screens/E2E/SharedPreferencesTesterScreen.tsx
@@ -1,9 +1,10 @@
 import React from 'react'
 import {View} from 'react-native'
 
-import {ScrollView} from 'view/com/util/Views'
+import {ScrollView} from '#/view/com/util/Views'
 import {atoms as a} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
+import * as Layout from '#/components/Layout'
 import {Text} from '#/components/Typography'
 import {SharedPrefs} from '../../../modules/expo-bluesky-swiss-army'
 
@@ -11,103 +12,105 @@ export function SharedPreferencesTesterScreen() {
   const [currentTestOutput, setCurrentTestOutput] = React.useState<string>('')
 
   return (
-    <ScrollView contentContainerStyle={{backgroundColor: 'red'}}>
-      <View style={[a.flex_1]}>
-        <View>
-          <Text testID="testOutput">{currentTestOutput}</Text>
+    <Layout.Screen>
+      <ScrollView contentContainerStyle={{backgroundColor: 'red'}}>
+        <View style={[a.flex_1]}>
+          <View>
+            <Text testID="testOutput">{currentTestOutput}</Text>
+          </View>
+          <View style={[a.flex_wrap]}>
+            <Button
+              label="btn"
+              testID="setStringBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerString')
+                SharedPrefs.setValue('testerString', 'Hello')
+                const str = SharedPrefs.getString('testerString')
+                console.log(JSON.stringify(str))
+                setCurrentTestOutput(`${str}`)
+              }}>
+              <ButtonText>Set String</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="removeStringBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerString')
+                const str = SharedPrefs.getString('testerString')
+                setCurrentTestOutput(`${str}`)
+              }}>
+              <ButtonText>Remove String</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="setBoolBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerBool')
+                SharedPrefs.setValue('testerBool', true)
+                const bool = SharedPrefs.getBool('testerBool')
+                setCurrentTestOutput(`${bool}`)
+              }}>
+              <ButtonText>Set Bool</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="setNumberBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerNumber')
+                SharedPrefs.setValue('testerNumber', 123)
+                const num = SharedPrefs.getNumber('testerNumber')
+                setCurrentTestOutput(`${num}`)
+              }}>
+              <ButtonText>Set Number</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="addToSetBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeFromSet('testerSet', 'Hello!')
+                SharedPrefs.addToSet('testerSet', 'Hello!')
+                const contains = SharedPrefs.setContains('testerSet', 'Hello!')
+                setCurrentTestOutput(`${contains}`)
+              }}>
+              <ButtonText>Add to Set</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="removeFromSetBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeFromSet('testerSet', 'Hello!')
+                const contains = SharedPrefs.setContains('testerSet', 'Hello!')
+                setCurrentTestOutput(`${contains}`)
+              }}>
+              <ButtonText>Remove from Set</ButtonText>
+            </Button>
+          </View>
         </View>
-        <View style={[a.flex_wrap]}>
-          <Button
-            label="btn"
-            testID="setStringBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerString')
-              SharedPrefs.setValue('testerString', 'Hello')
-              const str = SharedPrefs.getString('testerString')
-              console.log(JSON.stringify(str))
-              setCurrentTestOutput(`${str}`)
-            }}>
-            <ButtonText>Set String</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="removeStringBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerString')
-              const str = SharedPrefs.getString('testerString')
-              setCurrentTestOutput(`${str}`)
-            }}>
-            <ButtonText>Remove String</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="setBoolBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerBool')
-              SharedPrefs.setValue('testerBool', true)
-              const bool = SharedPrefs.getBool('testerBool')
-              setCurrentTestOutput(`${bool}`)
-            }}>
-            <ButtonText>Set Bool</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="setNumberBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerNumber')
-              SharedPrefs.setValue('testerNumber', 123)
-              const num = SharedPrefs.getNumber('testerNumber')
-              setCurrentTestOutput(`${num}`)
-            }}>
-            <ButtonText>Set Number</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="addToSetBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeFromSet('testerSet', 'Hello!')
-              SharedPrefs.addToSet('testerSet', 'Hello!')
-              const contains = SharedPrefs.setContains('testerSet', 'Hello!')
-              setCurrentTestOutput(`${contains}`)
-            }}>
-            <ButtonText>Add to Set</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="removeFromSetBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeFromSet('testerSet', 'Hello!')
-              const contains = SharedPrefs.setContains('testerSet', 'Hello!')
-              setCurrentTestOutput(`${contains}`)
-            }}>
-            <ButtonText>Remove from Set</ButtonText>
-          </Button>
-        </View>
-      </View>
-    </ScrollView>
+      </ScrollView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Hashtag.tsx b/src/screens/Hashtag.tsx
index 964cb0191..adf5f0080 100644
--- a/src/screens/Hashtag.tsx
+++ b/src/screens/Hashtag.tsx
@@ -6,23 +6,24 @@ import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 import {NativeStackScreenProps} from '@react-navigation/native-stack'
 
-import {HITSLOP_10} from 'lib/constants'
-import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
-import {CommonNavigatorParams} from 'lib/routes/types'
-import {shareUrl} from 'lib/sharing'
-import {cleanError} from 'lib/strings/errors'
-import {sanitizeHandle} from 'lib/strings/handles'
-import {enforceLen} from 'lib/strings/helpers'
-import {isNative, isWeb} from 'platform/detection'
-import {useSearchPostsQuery} from 'state/queries/search-posts'
-import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from 'state/shell'
+import {HITSLOP_10} from '#/lib/constants'
+import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
+import {CommonNavigatorParams} from '#/lib/routes/types'
+import {shareUrl} from '#/lib/sharing'
+import {cleanError} from '#/lib/strings/errors'
+import {sanitizeHandle} from '#/lib/strings/handles'
+import {enforceLen} from '#/lib/strings/helpers'
+import {isNative, isWeb} from '#/platform/detection'
+import {useSearchPostsQuery} from '#/state/queries/search-posts'
+import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell'
 import {Pager} from '#/view/com/pager/Pager'
 import {TabBar} from '#/view/com/pager/TabBar'
+import {Post} from '#/view/com/post/Post'
+import {List} from '#/view/com/util/List'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
 import {CenteredView} from '#/view/com/util/Views'
-import {Post} from 'view/com/post/Post'
-import {List} from 'view/com/util/List'
-import {ViewHeader} from 'view/com/util/ViewHeader'
 import {ArrowOutOfBox_Stroke2_Corner0_Rounded} from '#/components/icons/ArrowOutOfBox'
+import * as Layout from '#/components/Layout'
 import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
 
 const renderItem = ({item}: ListRenderItemInfo<PostView>) => {
@@ -108,7 +109,7 @@ export default function HashtagScreen({
   }, [_, fullTag, author, activeTab])
 
   return (
-    <>
+    <Layout.Screen>
       <CenteredView sideBorders={true}>
         <ViewHeader
           showOnDesktop
@@ -155,7 +156,7 @@ export default function HashtagScreen({
           <View key={i}>{section.component}</View>
         ))}
       </Pager>
-    </>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/screens/Messages/ChatList.tsx b/src/screens/Messages/ChatList.tsx
index 9912456e1..45b3bf14f 100644
--- a/src/screens/Messages/ChatList.tsx
+++ b/src/screens/Messages/ChatList.tsx
@@ -28,6 +28,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico
 import {Message_Stroke2_Corner0_Rounded as Message} from '#/components/icons/Message'
 import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
 import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider'
+import * as Layout from '#/components/Layout'
 import {Link} from '#/components/Link'
 import {ListFooter} from '#/components/Lists'
 import {Loader} from '#/components/Loader'
@@ -149,7 +150,7 @@ export function MessagesScreen({navigation, route}: Props) {
 
   if (conversations.length < 1) {
     return (
-      <View style={a.flex_1}>
+      <Layout.Screen>
         <CenteredView sideBorders={gtMobile} style={[a.h_full_vh]}>
           {gtMobile ? (
             <DesktopHeader
@@ -231,12 +232,12 @@ export function MessagesScreen({navigation, route}: Props) {
         {!isLoading && !isError && (
           <NewChat onNewChat={onNewChat} control={newChatControl} />
         )}
-      </View>
+      </Layout.Screen>
     )
   }
 
   return (
-    <View style={a.flex_1}>
+    <Layout.Screen testID="messagesScreen">
       {!gtMobile && (
         <ViewHeader
           title={_(msg`Messages`)}
@@ -276,7 +277,7 @@ export function MessagesScreen({navigation, route}: Props) {
         // @ts-ignore our .web version only -sfn
         desktopFixedHeight
       />
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx
index 21fdfe0ea..651915738 100644
--- a/src/screens/Messages/Conversation.tsx
+++ b/src/screens/Messages/Conversation.tsx
@@ -18,10 +18,11 @@ import {useProfileQuery} from '#/state/queries/profile'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {CenteredView} from '#/view/com/util/Views'
 import {MessagesList} from '#/screens/Messages/components/MessagesList'
-import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
 import {MessagesListBlockedFooter} from '#/components/dms/MessagesListBlockedFooter'
 import {MessagesListHeader} from '#/components/dms/MessagesListHeader'
 import {Error} from '#/components/Error'
+import * as Layout from '#/components/Layout'
 import {Loader} from '#/components/Loader'
 
 type Props = NativeStackScreenProps<
@@ -64,9 +65,11 @@ export function MessagesConversationScreen({route}: Props) {
   )
 
   return (
-    <ConvoProvider key={convoId} convoId={convoId}>
-      <Inner />
-    </ConvoProvider>
+    <Layout.Screen testID="convoScreen" style={web([{minHeight: 0}, a.flex_1])}>
+      <ConvoProvider key={convoId} convoId={convoId}>
+        <Inner />
+      </ConvoProvider>
+    </Layout.Screen>
   )
 }
 
@@ -100,7 +103,7 @@ function Inner() {
 
   if (convoState.status === ConvoStatus.Error) {
     return (
-      <CenteredView style={a.flex_1} sideBorders>
+      <CenteredView style={[a.flex_1]} sideBorders>
         <MessagesListHeader />
         <Error
           title={_(msg`Something went wrong`)}
diff --git a/src/screens/Messages/Settings.tsx b/src/screens/Messages/Settings.tsx
index a7b55229f..93e3bc400 100644
--- a/src/screens/Messages/Settings.tsx
+++ b/src/screens/Messages/Settings.tsx
@@ -16,6 +16,7 @@ import {atoms as a} from '#/alf'
 import {Admonition} from '#/components/Admonition'
 import {Divider} from '#/components/Divider'
 import * as Toggle from '#/components/forms/Toggle'
+import * as Layout from '#/components/Layout'
 import {Text} from '#/components/Typography'
 import {useBackgroundNotificationPreferences} from '../../../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
 
@@ -55,91 +56,93 @@ export function MessagesSettingsScreen({}: Props) {
   )
 
   return (
-    <ScrollView stickyHeaderIndices={[0]}>
-      <ViewHeader title={_(msg`Chat Settings`)} showOnDesktop showBorder />
-      <View style={[a.p_lg, a.gap_md]}>
-        <Text style={[a.text_lg, a.font_bold]}>
-          <Trans>Allow new messages from</Trans>
-        </Text>
-        <Toggle.Group
-          label={_(msg`Allow new messages from`)}
-          type="radio"
-          values={[
-            (profile?.associated?.chat?.allowIncoming as AllowIncoming) ??
-              'following',
-          ]}
-          onChange={onSelectMessagesFrom}>
-          <View>
-            <Toggle.Item
-              name="all"
-              label={_(msg`Everyone`)}
-              style={[a.justify_between, a.py_sm]}>
-              <Toggle.LabelText>
-                <Trans>Everyone</Trans>
-              </Toggle.LabelText>
-              <Toggle.Radio />
-            </Toggle.Item>
-            <Toggle.Item
-              name="following"
-              label={_(msg`Users I follow`)}
-              style={[a.justify_between, a.py_sm]}>
-              <Toggle.LabelText>
-                <Trans>Users I follow</Trans>
-              </Toggle.LabelText>
-              <Toggle.Radio />
-            </Toggle.Item>
-            <Toggle.Item
-              name="none"
-              label={_(msg`No one`)}
-              style={[a.justify_between, a.py_sm]}>
-              <Toggle.LabelText>
-                <Trans>No one</Trans>
-              </Toggle.LabelText>
-              <Toggle.Radio />
-            </Toggle.Item>
-          </View>
-        </Toggle.Group>
-        <Admonition type="tip">
-          <Trans>
-            You can continue ongoing conversations regardless of which setting
-            you choose.
-          </Trans>
-        </Admonition>
-        {isNative && (
-          <>
-            <Divider style={a.my_md} />
-            <Text style={[a.text_lg, a.font_bold]}>
-              <Trans>Notification Sounds</Trans>
-            </Text>
-            <Toggle.Group
-              label={_(msg`Notification sounds`)}
-              type="radio"
-              values={[preferences.playSoundChat ? 'enabled' : 'disabled']}
-              onChange={onSelectSoundSetting}>
-              <View>
-                <Toggle.Item
-                  name="enabled"
-                  label={_(msg`Enabled`)}
-                  style={[a.justify_between, a.py_sm]}>
-                  <Toggle.LabelText>
-                    <Trans>Enabled</Trans>
-                  </Toggle.LabelText>
-                  <Toggle.Radio />
-                </Toggle.Item>
-                <Toggle.Item
-                  name="disabled"
-                  label={_(msg`Disabled`)}
-                  style={[a.justify_between, a.py_sm]}>
-                  <Toggle.LabelText>
-                    <Trans>Disabled</Trans>
-                  </Toggle.LabelText>
-                  <Toggle.Radio />
-                </Toggle.Item>
-              </View>
-            </Toggle.Group>
-          </>
-        )}
-      </View>
-    </ScrollView>
+    <Layout.Screen testID="messagesSettingsScreen">
+      <ScrollView stickyHeaderIndices={[0]}>
+        <ViewHeader title={_(msg`Chat Settings`)} showOnDesktop showBorder />
+        <View style={[a.p_lg, a.gap_md]}>
+          <Text style={[a.text_lg, a.font_bold]}>
+            <Trans>Allow new messages from</Trans>
+          </Text>
+          <Toggle.Group
+            label={_(msg`Allow new messages from`)}
+            type="radio"
+            values={[
+              (profile?.associated?.chat?.allowIncoming as AllowIncoming) ??
+                'following',
+            ]}
+            onChange={onSelectMessagesFrom}>
+            <View>
+              <Toggle.Item
+                name="all"
+                label={_(msg`Everyone`)}
+                style={[a.justify_between, a.py_sm]}>
+                <Toggle.LabelText>
+                  <Trans>Everyone</Trans>
+                </Toggle.LabelText>
+                <Toggle.Radio />
+              </Toggle.Item>
+              <Toggle.Item
+                name="following"
+                label={_(msg`Users I follow`)}
+                style={[a.justify_between, a.py_sm]}>
+                <Toggle.LabelText>
+                  <Trans>Users I follow</Trans>
+                </Toggle.LabelText>
+                <Toggle.Radio />
+              </Toggle.Item>
+              <Toggle.Item
+                name="none"
+                label={_(msg`No one`)}
+                style={[a.justify_between, a.py_sm]}>
+                <Toggle.LabelText>
+                  <Trans>No one</Trans>
+                </Toggle.LabelText>
+                <Toggle.Radio />
+              </Toggle.Item>
+            </View>
+          </Toggle.Group>
+          <Admonition type="tip">
+            <Trans>
+              You can continue ongoing conversations regardless of which setting
+              you choose.
+            </Trans>
+          </Admonition>
+          {isNative && (
+            <>
+              <Divider style={a.my_md} />
+              <Text style={[a.text_lg, a.font_bold]}>
+                <Trans>Notification Sounds</Trans>
+              </Text>
+              <Toggle.Group
+                label={_(msg`Notification sounds`)}
+                type="radio"
+                values={[preferences.playSoundChat ? 'enabled' : 'disabled']}
+                onChange={onSelectSoundSetting}>
+                <View>
+                  <Toggle.Item
+                    name="enabled"
+                    label={_(msg`Enabled`)}
+                    style={[a.justify_between, a.py_sm]}>
+                    <Toggle.LabelText>
+                      <Trans>Enabled</Trans>
+                    </Toggle.LabelText>
+                    <Toggle.Radio />
+                  </Toggle.Item>
+                  <Toggle.Item
+                    name="disabled"
+                    label={_(msg`Disabled`)}
+                    style={[a.justify_between, a.py_sm]}>
+                    <Toggle.LabelText>
+                      <Trans>Disabled</Trans>
+                    </Toggle.LabelText>
+                    <Toggle.Radio />
+                  </Toggle.Item>
+                </View>
+              </Toggle.Group>
+            </>
+          )}
+        </View>
+      </ScrollView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx
index 070b87950..222774e05 100644
--- a/src/screens/Moderation/index.tsx
+++ b/src/screens/Moderation/index.tsx
@@ -41,6 +41,7 @@ import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filte
 import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group'
 import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person'
 import * as LabelingService from '#/components/LabelingServiceCard'
+import * as Layout from '#/components/Layout'
 import {InlineLinkText, Link} from '#/components/Link'
 import {Loader} from '#/components/Loader'
 import {GlobalLabelPreference} from '#/components/moderation/LabelPreference'
@@ -94,31 +95,33 @@ export function ModerationScreen(
   const error = preferencesError
 
   return (
-    <CenteredView
-      testID="moderationScreen"
-      style={[
-        t.atoms.border_contrast_low,
-        t.atoms.bg,
-        {minHeight: height},
-        ...(gtMobile ? [a.border_l, a.border_r] : []),
-      ]}>
-      <ViewHeader title={_(msg`Moderation`)} showOnDesktop />
+    <Layout.Screen testID="moderationScreen">
+      <CenteredView
+        testID="moderationScreen"
+        style={[
+          t.atoms.border_contrast_low,
+          t.atoms.bg,
+          {minHeight: height},
+          ...(gtMobile ? [a.border_l, a.border_r] : []),
+        ]}>
+        <ViewHeader title={_(msg`Moderation`)} showOnDesktop />
 
-      {isLoading ? (
-        <View style={[a.w_full, a.align_center, a.pt_2xl]}>
-          <Loader size="xl" fill={t.atoms.text.color} />
-        </View>
-      ) : error || !preferences ? (
-        <ErrorState
-          error={
-            preferencesError?.toString() ||
-            _(msg`Something went wrong, please try again.`)
-          }
-        />
-      ) : (
-        <ModerationScreenInner preferences={preferences} />
-      )}
-    </CenteredView>
+        {isLoading ? (
+          <View style={[a.w_full, a.align_center, a.pt_2xl]}>
+            <Loader size="xl" fill={t.atoms.text.color} />
+          </View>
+        ) : error || !preferences ? (
+          <ErrorState
+            error={
+              preferencesError?.toString() ||
+              _(msg`Something went wrong, please try again.`)
+            }
+          />
+        ) : (
+          <ModerationScreenInner preferences={preferences} />
+        )}
+      </CenteredView>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/screens/Post/PostLikedBy.tsx b/src/screens/Post/PostLikedBy.tsx
index ea522488c..6fc485f34 100644
--- a/src/screens/Post/PostLikedBy.tsx
+++ b/src/screens/Post/PostLikedBy.tsx
@@ -5,12 +5,12 @@ import {useFocusEffect} from '@react-navigation/native'
 
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {isWeb} from 'platform/detection'
 import {PostLikedBy as PostLikedByComponent} from '#/view/com/post-thread/PostLikedBy'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostLikedBy'>
@@ -27,10 +27,12 @@ export const PostLikedByScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Liked By`)} />
-      <ViewHeader title={_(msg`Liked By`)} showBorder={!isWeb} />
-      <PostLikedByComponent uri={uri} />
-    </CenteredView>
+    <Layout.Screen>
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Liked By`)} />
+        <ViewHeader title={_(msg`Liked By`)} showBorder={!isWeb} />
+        <PostLikedByComponent uri={uri} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Post/PostQuotes.tsx b/src/screens/Post/PostQuotes.tsx
index 0d59418f1..71dd8ad8d 100644
--- a/src/screens/Post/PostQuotes.tsx
+++ b/src/screens/Post/PostQuotes.tsx
@@ -5,12 +5,12 @@ import {useFocusEffect} from '@react-navigation/native'
 
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {isWeb} from 'platform/detection'
 import {PostQuotes as PostQuotesComponent} from '#/view/com/post-thread/PostQuotes'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostQuotes'>
@@ -27,10 +27,12 @@ export const PostQuotesScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Quotes`)} />
-      <ViewHeader title={_(msg`Quotes`)} showBorder={!isWeb} />
-      <PostQuotesComponent uri={uri} />
-    </CenteredView>
+    <Layout.Screen>
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Quotes`)} />
+        <ViewHeader title={_(msg`Quotes`)} showBorder={!isWeb} />
+        <PostQuotesComponent uri={uri} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Post/PostRepostedBy.tsx b/src/screens/Post/PostRepostedBy.tsx
index f8c058ff7..c1e8b2987 100644
--- a/src/screens/Post/PostRepostedBy.tsx
+++ b/src/screens/Post/PostRepostedBy.tsx
@@ -5,12 +5,12 @@ import {useFocusEffect} from '@react-navigation/native'
 
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {isWeb} from 'platform/detection'
 import {PostRepostedBy as PostRepostedByComponent} from '#/view/com/post-thread/PostRepostedBy'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostRepostedBy'>
@@ -27,10 +27,12 @@ export const PostRepostedByScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Reposted By`)} />
-      <ViewHeader title={_(msg`Reposted By`)} showBorder={!isWeb} />
-      <PostRepostedByComponent uri={uri} />
-    </CenteredView>
+    <Layout.Screen>
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Reposted By`)} />
+        <ViewHeader title={_(msg`Reposted By`)} showBorder={!isWeb} />
+        <PostRepostedByComponent uri={uri} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Profile/KnownFollowers.tsx b/src/screens/Profile/KnownFollowers.tsx
index 5cb45a11e..7e396c350 100644
--- a/src/screens/Profile/KnownFollowers.tsx
+++ b/src/screens/Profile/KnownFollowers.tsx
@@ -1,20 +1,20 @@
 import React from 'react'
-import {View} from 'react-native'
 import {AppBskyActorDefs} from '@atproto/api'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {cleanError} from '#/lib/strings/errors'
 import {logger} from '#/logger'
 import {useProfileKnownFollowersQuery} from '#/state/queries/known-followers'
 import {useResolveDidQuery} from '#/state/queries/resolve-uri'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
 import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard'
 import {List} from '#/view/com/util/List'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 import {
   ListFooter,
   ListHeaderDesktop,
@@ -92,19 +92,21 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => {
 
   if (followers.length < 1) {
     return (
-      <ListMaybePlaceholder
-        isLoading={isDidLoading || isFollowersLoading}
-        isError={isError}
-        emptyType="results"
-        emptyMessage={_(msg`You don't follow any users who follow @${name}.`)}
-        errorMessage={cleanError(resolveError || error)}
-        onRetry={isError ? refetch : undefined}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={isDidLoading || isFollowersLoading}
+          isError={isError}
+          emptyType="results"
+          emptyMessage={_(msg`You don't follow any users who follow @${name}.`)}
+          errorMessage={cleanError(resolveError || error)}
+          onRetry={isError ? refetch : undefined}
+        />
+      </Layout.Screen>
     )
   }
 
   return (
-    <View style={{flex: 1}}>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Followers you know`)} />
       <List
         data={followers}
@@ -129,6 +131,6 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => {
         initialNumToRender={initialNumToRender}
         windowSize={11}
       />
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Profile/ProfileLabelerLikedBy.tsx b/src/screens/Profile/ProfileLabelerLikedBy.tsx
index 8650ac2e6..ccc270084 100644
--- a/src/screens/Profile/ProfileLabelerLikedBy.tsx
+++ b/src/screens/Profile/ProfileLabelerLikedBy.tsx
@@ -1,5 +1,4 @@
 import React from 'react'
-import {View} from 'react-native'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
@@ -8,6 +7,7 @@ import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 import {LikedByList} from '#/components/LikedByList'
 
 export function ProfileLabelerLikedByScreen({
@@ -25,9 +25,9 @@ export function ProfileLabelerLikedByScreen({
   )
 
   return (
-    <View style={{flex: 1}}>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Liked By`)} />
       <LikedByList uri={uri} />
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Settings/AppearanceSettings.tsx b/src/screens/Settings/AppearanceSettings.tsx
index 69e04f4af..c317c930f 100644
--- a/src/screens/Settings/AppearanceSettings.tsx
+++ b/src/screens/Settings/AppearanceSettings.tsx
@@ -10,7 +10,6 @@ import {useLingui} from '@lingui/react'
 
 import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
-import {s} from '#/lib/styles'
 import {useSetThemePrefs, useThemePrefs} from '#/state/shell'
 import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
 import {ScrollView} from '#/view/com/util/Views'
@@ -21,6 +20,7 @@ import {Moon_Stroke2_Corner0_Rounded as MoonIcon} from '#/components/icons/Moon'
 import {Phone_Stroke2_Corner0_Rounded as PhoneIcon} from '#/components/icons/Phone'
 import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/TextSize'
 import {TitleCase_Stroke2_Corner0_Rounded as Aa} from '#/components/icons/TitleCase'
+import * as Layout from '#/components/Layout'
 import {Text} from '#/components/Typography'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppearanceSettings'>
@@ -76,7 +76,7 @@ export function AppearanceSettingsScreen({}: Props) {
 
   return (
     <LayoutAnimationConfig skipExiting skipEntering>
-      <View testID="preferencesThreadsScreen" style={s.hContentRegion}>
+      <Layout.Screen testID="preferencesThreadsScreen">
         <ScrollView
           // @ts-ignore web only -prf
           dataSet={{'stable-gutters': 1}}
@@ -180,7 +180,7 @@ export function AppearanceSettingsScreen({}: Props) {
             </View>
           </View>
         </ScrollView>
-      </View>
+      </Layout.Screen>
     </LayoutAnimationConfig>
   )
 }
diff --git a/src/screens/StarterPack/StarterPackScreen.tsx b/src/screens/StarterPack/StarterPackScreen.tsx
index 68803ac00..4baec9ec1 100644
--- a/src/screens/StarterPack/StarterPackScreen.tsx
+++ b/src/screens/StarterPack/StarterPackScreen.tsx
@@ -53,6 +53,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico
 import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
 import {Pencil_Stroke2_Corner0_Rounded as Pencil} from '#/components/icons/Pencil'
 import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
+import * as Layout from '#/components/Layout'
 import {ListMaybePlaceholder} from '#/components/Lists'
 import {Loader} from '#/components/Loader'
 import * as Menu from '#/components/Menu'
@@ -76,7 +77,11 @@ type StarterPackScreenShortProps = NativeStackScreenProps<
 >
 
 export function StarterPackScreen({route}: StarterPackScreeProps) {
-  return <StarterPackScreenInner routeParams={route.params} />
+  return (
+    <Layout.Screen>
+      <StarterPackScreenInner routeParams={route.params} />
+    </Layout.Screen>
+  )
 }
 
 export function StarterPackScreenShort({route}: StarterPackScreenShortProps) {
@@ -91,15 +96,21 @@ export function StarterPackScreenShort({route}: StarterPackScreenShortProps) {
 
   if (isLoading || isError || !resolvedStarterPack) {
     return (
-      <ListMaybePlaceholder
-        isLoading={isLoading}
-        isError={isError}
-        errorMessage={_(msg`That starter pack could not be found.`)}
-        emptyMessage={_(msg`That starter pack could not be found.`)}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={isLoading}
+          isError={isError}
+          errorMessage={_(msg`That starter pack could not be found.`)}
+          emptyMessage={_(msg`That starter pack could not be found.`)}
+        />
+      </Layout.Screen>
     )
   }
-  return <StarterPackScreenInner routeParams={resolvedStarterPack} />
+  return (
+    <Layout.Screen>
+      <StarterPackScreenInner routeParams={resolvedStarterPack} />
+    </Layout.Screen>
+  )
 }
 
 export function StarterPackScreenInner({
diff --git a/src/screens/StarterPack/Wizard/index.tsx b/src/screens/StarterPack/Wizard/index.tsx
index 29ef44ee0..f8d503274 100644
--- a/src/screens/StarterPack/Wizard/index.tsx
+++ b/src/screens/StarterPack/Wizard/index.tsx
@@ -19,32 +19,32 @@ import {useLingui} from '@lingui/react'
 import {useFocusEffect, useNavigation} from '@react-navigation/native'
 import {NativeStackScreenProps} from '@react-navigation/native-stack'
 
-import {logger} from '#/logger'
-import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from 'lib/constants'
-import {createSanitizedDisplayName} from 'lib/moderation/create-sanitized-display-name'
-import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
-import {logEvent} from 'lib/statsig/statsig'
-import {sanitizeDisplayName} from 'lib/strings/display-names'
-import {sanitizeHandle} from 'lib/strings/handles'
-import {enforceLen} from 'lib/strings/helpers'
+import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
+import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
+import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
+import {logEvent} from '#/lib/statsig/statsig'
+import {sanitizeDisplayName} from '#/lib/strings/display-names'
+import {sanitizeHandle} from '#/lib/strings/handles'
+import {enforceLen} from '#/lib/strings/helpers'
 import {
   getStarterPackOgCard,
   parseStarterPackUri,
-} from 'lib/strings/starter-pack'
-import {isAndroid, isNative, isWeb} from 'platform/detection'
-import {useModerationOpts} from 'state/preferences/moderation-opts'
-import {useAllListMembersQuery} from 'state/queries/list-members'
-import {useProfileQuery} from 'state/queries/profile'
+} from '#/lib/strings/starter-pack'
+import {logger} from '#/logger'
+import {isAndroid, isNative, isWeb} from '#/platform/detection'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
+import {useAllListMembersQuery} from '#/state/queries/list-members'
+import {useProfileQuery} from '#/state/queries/profile'
 import {
   useCreateStarterPackMutation,
   useEditStarterPackMutation,
   useStarterPackQuery,
-} from 'state/queries/starter-packs'
-import {useSession} from 'state/session'
-import {useSetMinimalShellMode} from 'state/shell'
+} from '#/state/queries/starter-packs'
+import {useSession} from '#/state/session'
+import {useSetMinimalShellMode} from '#/state/shell'
 import * as Toast from '#/view/com/util/Toast'
-import {UserAvatar} from 'view/com/util/UserAvatar'
-import {CenteredView} from 'view/com/util/Views'
+import {UserAvatar} from '#/view/com/util/UserAvatar'
+import {CenteredView} from '#/view/com/util/Views'
 import {useWizardState, WizardStep} from '#/screens/StarterPack/Wizard/State'
 import {StepDetails} from '#/screens/StarterPack/Wizard/StepDetails'
 import {StepFeeds} from '#/screens/StarterPack/Wizard/StepFeeds'
@@ -52,6 +52,7 @@ import {StepProfiles} from '#/screens/StarterPack/Wizard/StepProfiles'
 import {atoms as a, useTheme} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
 import {useDialogControl} from '#/components/Dialog'
+import * as Layout from '#/components/Layout'
 import {ListMaybePlaceholder} from '#/components/Lists'
 import {Loader} from '#/components/Loader'
 import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog'
@@ -97,33 +98,39 @@ export function Wizard({
 
   if (!isReady) {
     return (
-      <ListMaybePlaceholder
-        isLoading={
-          isLoadingStarterPack || isLoadingProfiles || isLoadingProfile
-        }
-        isError={isErrorStarterPack || isErrorProfiles || isErrorProfile}
-        errorMessage={_(msg`That starter pack could not be found.`)}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={
+            isLoadingStarterPack || isLoadingProfiles || isLoadingProfile
+          }
+          isError={isErrorStarterPack || isErrorProfiles || isErrorProfile}
+          errorMessage={_(msg`That starter pack could not be found.`)}
+        />
+      </Layout.Screen>
     )
   } else if (isEdit && starterPack?.creator.did !== currentAccount?.did) {
     return (
-      <ListMaybePlaceholder
-        isLoading={false}
-        isError={true}
-        errorMessage={_(msg`That starter pack could not be found.`)}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={false}
+          isError={true}
+          errorMessage={_(msg`That starter pack could not be found.`)}
+        />
+      </Layout.Screen>
     )
   }
 
   return (
-    <Provider starterPack={starterPack} listItems={listItems}>
-      <WizardInner
-        currentStarterPack={starterPack}
-        currentListItems={listItems}
-        profile={profile}
-        moderationOpts={moderationOpts}
-      />
-    </Provider>
+    <Layout.Screen>
+      <Provider starterPack={starterPack} listItems={listItems}>
+        <WizardInner
+          currentStarterPack={starterPack}
+          currentListItems={listItems}
+          profile={profile}
+          moderationOpts={moderationOpts}
+        />
+      </Provider>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/AccessibilitySettings.tsx b/src/view/screens/AccessibilitySettings.tsx
index 5d314e8e6..bf9f5fcb5 100644
--- a/src/view/screens/AccessibilitySettings.tsx
+++ b/src/view/screens/AccessibilitySettings.tsx
@@ -27,6 +27,7 @@ import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
 import {Text} from '#/view/com/util/text/Text'
 import {ScrollView} from '#/view/com/util/Views'
 import {atoms as a} from '#/alf'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<
   CommonNavigatorParams,
@@ -54,7 +55,7 @@ export function AccessibilitySettingsScreen({}: Props) {
   )
 
   return (
-    <View style={s.hContentRegion} testID="accessibilitySettingsScreen">
+    <Layout.Screen testID="accessibilitySettingsScreen">
       <SimpleViewHeader
         showBackButton={isTabletOrMobile}
         style={[
@@ -128,7 +129,7 @@ export function AccessibilitySettingsScreen({}: Props) {
           </>
         )}
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/AppPasswords.tsx b/src/view/screens/AppPasswords.tsx
index 21a9cb0eb..48abd964f 100644
--- a/src/view/screens/AppPasswords.tsx
+++ b/src/view/screens/AppPasswords.tsx
@@ -30,10 +30,19 @@ import {ViewHeader} from '#/view/com/util/ViewHeader'
 import {CenteredView} from '#/view/com/util/Views'
 import {atoms as a} from '#/alf'
 import {useDialogControl} from '#/components/Dialog'
+import * as Layout from '#/components/Layout'
 import * as Prompt from '#/components/Prompt'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppPasswords'>
 export function AppPasswords({}: Props) {
+  return (
+    <Layout.Screen testID="AppPasswordsScreen">
+      <AppPasswordsInner />
+    </Layout.Screen>
+  )
+}
+
+function AppPasswordsInner() {
   const pal = usePalette('default')
   const {_} = useLingui()
   const setMinimalShellMode = useSetMinimalShellMode()
diff --git a/src/view/screens/CommunityGuidelines.tsx b/src/view/screens/CommunityGuidelines.tsx
index f6c29a3b8..76993d5b7 100644
--- a/src/view/screens/CommunityGuidelines.tsx
+++ b/src/view/screens/CommunityGuidelines.tsx
@@ -1,16 +1,18 @@
 import React from 'react'
 import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
-import {Text} from 'view/com/util/text/Text'
-import {TextLink} from 'view/com/util/Link'
-import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {ScrollView} from 'view/com/util/Views'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
+
+import {usePalette} from '#/lib/hooks/usePalette'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+import {TextLink} from '#/view/com/util/Link'
+import {Text} from '#/view/com/util/text/Text'
+import {ScrollView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
+import {ViewHeader} from '../com/util/ViewHeader'
 
 type Props = NativeStackScreenProps<
   CommonNavigatorParams,
@@ -28,7 +30,7 @@ export const CommunityGuidelinesScreen = (_props: Props) => {
   )
 
   return (
-    <View>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Community Guidelines`)} />
       <ScrollView style={[s.hContentRegion, pal.view]}>
         <View style={[s.p20]}>
@@ -45,6 +47,6 @@ export const CommunityGuidelinesScreen = (_props: Props) => {
         </View>
         <View style={s.footerSpacer} />
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/CopyrightPolicy.tsx b/src/view/screens/CopyrightPolicy.tsx
index 522a9e4db..fe2731c53 100644
--- a/src/view/screens/CopyrightPolicy.tsx
+++ b/src/view/screens/CopyrightPolicy.tsx
@@ -1,16 +1,18 @@
 import React from 'react'
 import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
-import {Text} from 'view/com/util/text/Text'
-import {TextLink} from 'view/com/util/Link'
-import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {ScrollView} from 'view/com/util/Views'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
+
+import {usePalette} from '#/lib/hooks/usePalette'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+import {TextLink} from '#/view/com/util/Link'
+import {Text} from '#/view/com/util/text/Text'
+import {ScrollView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
+import {ViewHeader} from '../com/util/ViewHeader'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'CopyrightPolicy'>
 export const CopyrightPolicyScreen = (_props: Props) => {
@@ -25,7 +27,7 @@ export const CopyrightPolicyScreen = (_props: Props) => {
   )
 
   return (
-    <View>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Copyright Policy`)} />
       <ScrollView style={[s.hContentRegion, pal.view]}>
         <View style={[s.p20]}>
@@ -42,6 +44,6 @@ export const CopyrightPolicyScreen = (_props: Props) => {
         </View>
         <View style={s.footerSpacer} />
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/Debug.tsx b/src/view/screens/Debug.tsx
index f26b1505a..60dc089dd 100644
--- a/src/view/screens/Debug.tsx
+++ b/src/view/screens/Debug.tsx
@@ -1,24 +1,29 @@
 import React from 'react'
 import {ScrollView, View} from 'react-native'
-import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {ThemeProvider, PaletteColorName} from 'lib/ThemeContext'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
-import * as Toast from 'view/com/util/Toast'
-import {Text} from '../com/util/text/Text'
-import {ViewSelector} from '../com/util/ViewSelector'
-import {EmptyState} from '../com/util/EmptyState'
-import * as LoadingPlaceholder from '../com/util/LoadingPlaceholder'
-import {Button, ButtonType} from '../com/util/forms/Button'
-import {DropdownButton, DropdownItem} from '../com/util/forms/DropdownButton'
-import {ToggleButton} from '../com/util/forms/ToggleButton'
-import {RadioGroup} from '../com/util/forms/RadioGroup'
-import {ErrorScreen} from '../com/util/error/ErrorScreen'
-import {ErrorMessage} from '../com/util/error/ErrorMessage'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
+import {usePalette} from '#/lib/hooks/usePalette'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
+import {PaletteColorName, ThemeProvider} from '#/lib/ThemeContext'
+import {EmptyState} from '#/view/com/util/EmptyState'
+import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
+import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
+import {Button, ButtonType} from '#/view/com/util/forms/Button'
+import {
+  DropdownButton,
+  DropdownItem,
+} from '#/view/com/util/forms/DropdownButton'
+import {RadioGroup} from '#/view/com/util/forms/RadioGroup'
+import {ToggleButton} from '#/view/com/util/forms/ToggleButton'
+import * as LoadingPlaceholder from '#/view/com/util/LoadingPlaceholder'
+import {Text} from '#/view/com/util/text/Text'
+import * as Toast from '#/view/com/util/Toast'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
+import {ViewSelector} from '#/view/com/util/ViewSelector'
+import * as Layout from '#/components/Layout'
+
 const MAIN_VIEWS = ['Base', 'Controls', 'Error', 'Notifs']
 
 export const DebugScreen = ({}: NativeStackScreenProps<
@@ -33,10 +38,12 @@ export const DebugScreen = ({}: NativeStackScreenProps<
   }
   return (
     <ThemeProvider theme={colorScheme}>
-      <DebugInner
-        colorScheme={colorScheme}
-        onToggleColorScheme={onToggleColorScheme}
-      />
+      <Layout.Screen>
+        <DebugInner
+          colorScheme={colorScheme}
+          onToggleColorScheme={onToggleColorScheme}
+        />
+      </Layout.Screen>
     </ThemeProvider>
   )
 }
diff --git a/src/view/screens/DebugMod.tsx b/src/view/screens/DebugMod.tsx
index d83623adc..b87fc8683 100644
--- a/src/view/screens/DebugMod.tsx
+++ b/src/view/screens/DebugMod.tsx
@@ -21,6 +21,7 @@ import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
 import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {moderationOptsOverrideContext} from '#/state/preferences/moderation-opts'
 import {FeedNotification} from '#/state/queries/notifications/types'
 import {
@@ -28,7 +29,6 @@ import {
   shouldFilterNotif,
 } from '#/state/queries/notifications/util'
 import {useSession} from '#/state/session'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
 import {CenteredView, ScrollView} from '#/view/com/util/Views'
 import {ProfileHeaderStandard} from '#/screens/Profile/Header/ProfileHeaderStandard'
 import {atoms as a, useTheme} from '#/alf'
@@ -41,6 +41,7 @@ import {
   ChevronBottom_Stroke2_Corner0_Rounded as ChevronBottom,
   ChevronTop_Stroke2_Corner0_Rounded as ChevronTop,
 } from '#/components/icons/Chevron'
+import * as Layout from '#/components/Layout'
 import {H1, H3, P, Text} from '#/components/Typography'
 import {ScreenHider} from '../../components/moderation/ScreenHider'
 import {FeedItem as NotifFeedItem} from '../com/notifications/FeedItem'
@@ -264,309 +265,325 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
   }, [post, modOpts])
 
   return (
-    <moderationOptsOverrideContext.Provider value={modOpts}>
-      <ScrollView>
-        <CenteredView style={[t.atoms.bg, a.px_lg, a.py_lg]}>
-          <H1 style={[a.text_5xl, a.font_bold, a.pb_lg]}>Moderation states</H1>
-
-          <Heading title="" subtitle="Scenario" />
-          <ToggleButton.Group
-            label="Scenario"
-            values={scenario}
-            onChange={setScenario}>
-            <ToggleButton.Button name="label" label="Label">
-              <ToggleButton.ButtonText>Label</ToggleButton.ButtonText>
-            </ToggleButton.Button>
-            <ToggleButton.Button name="block" label="Block">
-              <ToggleButton.ButtonText>Block</ToggleButton.ButtonText>
-            </ToggleButton.Button>
-            <ToggleButton.Button name="mute" label="Mute">
-              <ToggleButton.ButtonText>Mute</ToggleButton.ButtonText>
-            </ToggleButton.Button>
-          </ToggleButton.Group>
-
-          {scenario[0] === 'label' && (
-            <>
-              <View
-                style={[
-                  a.border,
-                  a.rounded_sm,
-                  a.mt_lg,
-                  a.mb_lg,
-                  a.p_lg,
-                  t.atoms.border_contrast_medium,
-                ]}>
-                <Toggle.Group
-                  label="Toggle"
-                  type="radio"
-                  values={label}
-                  onChange={setLabel}>
-                  <View style={[a.flex_row, a.gap_md, a.flex_wrap]}>
-                    {LABEL_VALUES.map(labelValue => {
-                      let targetFixed = target[0]
-                      if (
-                        targetFixed !== 'account' &&
-                        targetFixed !== 'profile'
-                      ) {
-                        targetFixed = 'content'
-                      }
-                      const disabled =
-                        isSelfLabel &&
-                        LABELS[labelValue].flags.includes('no-self')
-                      return (
-                        <Toggle.Item
-                          key={labelValue}
-                          name={labelValue}
-                          label={labelStrings[labelValue].name}
-                          disabled={disabled}
-                          style={disabled ? {opacity: 0.5} : undefined}>
-                          <Toggle.Radio />
-                          <Toggle.LabelText>{labelValue}</Toggle.LabelText>
-                        </Toggle.Item>
-                      )
-                    })}
-                    <Toggle.Item
-                      name="custom"
-                      label="Custom label"
-                      disabled={isSelfLabel}
-                      style={isSelfLabel ? {opacity: 0.5} : undefined}>
-                      <Toggle.Radio />
-                      <Toggle.LabelText>Custom label</Toggle.LabelText>
-                    </Toggle.Item>
-                  </View>
-                </Toggle.Group>
-
-                {label[0] === 'custom' ? (
-                  <CustomLabelForm
-                    def={customLabelDef}
-                    setDef={setCustomLabelDef}
-                  />
-                ) : (
-                  <>
-                    <View style={{height: 10}} />
-                    <Divider />
-                  </>
-                )}
-
-                <View style={{height: 10}} />
-
-                <SmallToggler label="Advanced">
+    <Layout.Screen>
+      <moderationOptsOverrideContext.Provider value={modOpts}>
+        <ScrollView>
+          <CenteredView style={[t.atoms.bg, a.px_lg, a.py_lg]}>
+            <H1 style={[a.text_5xl, a.font_bold, a.pb_lg]}>
+              Moderation states
+            </H1>
+
+            <Heading title="" subtitle="Scenario" />
+            <ToggleButton.Group
+              label="Scenario"
+              values={scenario}
+              onChange={setScenario}>
+              <ToggleButton.Button name="label" label="Label">
+                <ToggleButton.ButtonText>Label</ToggleButton.ButtonText>
+              </ToggleButton.Button>
+              <ToggleButton.Button name="block" label="Block">
+                <ToggleButton.ButtonText>Block</ToggleButton.ButtonText>
+              </ToggleButton.Button>
+              <ToggleButton.Button name="mute" label="Mute">
+                <ToggleButton.ButtonText>Mute</ToggleButton.ButtonText>
+              </ToggleButton.Button>
+            </ToggleButton.Group>
+
+            {scenario[0] === 'label' && (
+              <>
+                <View
+                  style={[
+                    a.border,
+                    a.rounded_sm,
+                    a.mt_lg,
+                    a.mb_lg,
+                    a.p_lg,
+                    t.atoms.border_contrast_medium,
+                  ]}>
                   <Toggle.Group
                     label="Toggle"
-                    type="checkbox"
-                    values={scenarioSwitches}
-                    onChange={setScenarioSwitches}>
-                    <View style={[a.gap_md, a.flex_row, a.flex_wrap, a.pt_md]}>
-                      <Toggle.Item name="targetMe" label="Target is me">
-                        <Toggle.Checkbox />
-                        <Toggle.LabelText>Target is me</Toggle.LabelText>
-                      </Toggle.Item>
-                      <Toggle.Item name="following" label="Following target">
-                        <Toggle.Checkbox />
-                        <Toggle.LabelText>Following target</Toggle.LabelText>
-                      </Toggle.Item>
-                      <Toggle.Item name="selfLabel" label="Self label">
-                        <Toggle.Checkbox />
-                        <Toggle.LabelText>Self label</Toggle.LabelText>
-                      </Toggle.Item>
-                      <Toggle.Item name="noAdult" label="Adult disabled">
-                        <Toggle.Checkbox />
-                        <Toggle.LabelText>Adult disabled</Toggle.LabelText>
-                      </Toggle.Item>
-                      <Toggle.Item name="loggedOut" label="Logged out">
-                        <Toggle.Checkbox />
-                        <Toggle.LabelText>Logged out</Toggle.LabelText>
+                    type="radio"
+                    values={label}
+                    onChange={setLabel}>
+                    <View style={[a.flex_row, a.gap_md, a.flex_wrap]}>
+                      {LABEL_VALUES.map(labelValue => {
+                        let targetFixed = target[0]
+                        if (
+                          targetFixed !== 'account' &&
+                          targetFixed !== 'profile'
+                        ) {
+                          targetFixed = 'content'
+                        }
+                        const disabled =
+                          isSelfLabel &&
+                          LABELS[labelValue].flags.includes('no-self')
+                        return (
+                          <Toggle.Item
+                            key={labelValue}
+                            name={labelValue}
+                            label={labelStrings[labelValue].name}
+                            disabled={disabled}
+                            style={disabled ? {opacity: 0.5} : undefined}>
+                            <Toggle.Radio />
+                            <Toggle.LabelText>{labelValue}</Toggle.LabelText>
+                          </Toggle.Item>
+                        )
+                      })}
+                      <Toggle.Item
+                        name="custom"
+                        label="Custom label"
+                        disabled={isSelfLabel}
+                        style={isSelfLabel ? {opacity: 0.5} : undefined}>
+                        <Toggle.Radio />
+                        <Toggle.LabelText>Custom label</Toggle.LabelText>
                       </Toggle.Item>
                     </View>
                   </Toggle.Group>
 
-                  {LABELS[label[0] as keyof typeof LABELS]?.configurable !==
-                    false && (
-                    <View style={[a.mt_md]}>
-                      <Text
-                        style={[a.font_bold, a.text_xs, t.atoms.text, a.pb_sm]}>
-                        Preference
-                      </Text>
-                      <Toggle.Group
-                        label="Preference"
-                        type="radio"
-                        values={visibility}
-                        onChange={setVisiblity}>
-                        <View
+                  {label[0] === 'custom' ? (
+                    <CustomLabelForm
+                      def={customLabelDef}
+                      setDef={setCustomLabelDef}
+                    />
+                  ) : (
+                    <>
+                      <View style={{height: 10}} />
+                      <Divider />
+                    </>
+                  )}
+
+                  <View style={{height: 10}} />
+
+                  <SmallToggler label="Advanced">
+                    <Toggle.Group
+                      label="Toggle"
+                      type="checkbox"
+                      values={scenarioSwitches}
+                      onChange={setScenarioSwitches}>
+                      <View
+                        style={[a.gap_md, a.flex_row, a.flex_wrap, a.pt_md]}>
+                        <Toggle.Item name="targetMe" label="Target is me">
+                          <Toggle.Checkbox />
+                          <Toggle.LabelText>Target is me</Toggle.LabelText>
+                        </Toggle.Item>
+                        <Toggle.Item name="following" label="Following target">
+                          <Toggle.Checkbox />
+                          <Toggle.LabelText>Following target</Toggle.LabelText>
+                        </Toggle.Item>
+                        <Toggle.Item name="selfLabel" label="Self label">
+                          <Toggle.Checkbox />
+                          <Toggle.LabelText>Self label</Toggle.LabelText>
+                        </Toggle.Item>
+                        <Toggle.Item name="noAdult" label="Adult disabled">
+                          <Toggle.Checkbox />
+                          <Toggle.LabelText>Adult disabled</Toggle.LabelText>
+                        </Toggle.Item>
+                        <Toggle.Item name="loggedOut" label="Logged out">
+                          <Toggle.Checkbox />
+                          <Toggle.LabelText>Logged out</Toggle.LabelText>
+                        </Toggle.Item>
+                      </View>
+                    </Toggle.Group>
+
+                    {LABELS[label[0] as keyof typeof LABELS]?.configurable !==
+                      false && (
+                      <View style={[a.mt_md]}>
+                        <Text
                           style={[
-                            a.flex_row,
-                            a.gap_md,
-                            a.flex_wrap,
-                            a.align_center,
+                            a.font_bold,
+                            a.text_xs,
+                            t.atoms.text,
+                            a.pb_sm,
                           ]}>
-                          <Toggle.Item name="hide" label="Hide">
+                          Preference
+                        </Text>
+                        <Toggle.Group
+                          label="Preference"
+                          type="radio"
+                          values={visibility}
+                          onChange={setVisiblity}>
+                          <View
+                            style={[
+                              a.flex_row,
+                              a.gap_md,
+                              a.flex_wrap,
+                              a.align_center,
+                            ]}>
+                            <Toggle.Item name="hide" label="Hide">
+                              <Toggle.Radio />
+                              <Toggle.LabelText>Hide</Toggle.LabelText>
+                            </Toggle.Item>
+                            <Toggle.Item name="warn" label="Warn">
+                              <Toggle.Radio />
+                              <Toggle.LabelText>Warn</Toggle.LabelText>
+                            </Toggle.Item>
+                            <Toggle.Item name="ignore" label="Ignore">
+                              <Toggle.Radio />
+                              <Toggle.LabelText>Ignore</Toggle.LabelText>
+                            </Toggle.Item>
+                          </View>
+                        </Toggle.Group>
+                      </View>
+                    )}
+                  </SmallToggler>
+                </View>
+
+                <View style={[a.flex_row, a.flex_wrap, a.gap_md]}>
+                  <View>
+                    <Text
+                      style={[
+                        a.font_bold,
+                        a.text_xs,
+                        t.atoms.text,
+                        a.pl_md,
+                        a.pb_xs,
+                      ]}>
+                      Target
+                    </Text>
+                    <View
+                      style={[
+                        a.border,
+                        a.rounded_full,
+                        a.px_md,
+                        a.py_sm,
+                        t.atoms.border_contrast_medium,
+                        t.atoms.bg,
+                      ]}>
+                      <Toggle.Group
+                        label="Target"
+                        type="radio"
+                        values={target}
+                        onChange={setTarget}>
+                        <View style={[a.flex_row, a.gap_md, a.flex_wrap]}>
+                          <Toggle.Item name="account" label="Account">
+                            <Toggle.Radio />
+                            <Toggle.LabelText>Account</Toggle.LabelText>
+                          </Toggle.Item>
+                          <Toggle.Item name="profile" label="Profile">
                             <Toggle.Radio />
-                            <Toggle.LabelText>Hide</Toggle.LabelText>
+                            <Toggle.LabelText>Profile</Toggle.LabelText>
                           </Toggle.Item>
-                          <Toggle.Item name="warn" label="Warn">
+                          <Toggle.Item name="post" label="Post">
                             <Toggle.Radio />
-                            <Toggle.LabelText>Warn</Toggle.LabelText>
+                            <Toggle.LabelText>Post</Toggle.LabelText>
                           </Toggle.Item>
-                          <Toggle.Item name="ignore" label="Ignore">
+                          <Toggle.Item name="embed" label="Embed">
                             <Toggle.Radio />
-                            <Toggle.LabelText>Ignore</Toggle.LabelText>
+                            <Toggle.LabelText>Embed</Toggle.LabelText>
                           </Toggle.Item>
                         </View>
                       </Toggle.Group>
                     </View>
-                  )}
-                </SmallToggler>
-              </View>
-
-              <View style={[a.flex_row, a.flex_wrap, a.gap_md]}>
-                <View>
-                  <Text
-                    style={[
-                      a.font_bold,
-                      a.text_xs,
-                      t.atoms.text,
-                      a.pl_md,
-                      a.pb_xs,
-                    ]}>
-                    Target
-                  </Text>
-                  <View
-                    style={[
-                      a.border,
-                      a.rounded_full,
-                      a.px_md,
-                      a.py_sm,
-                      t.atoms.border_contrast_medium,
-                      t.atoms.bg,
-                    ]}>
-                    <Toggle.Group
-                      label="Target"
-                      type="radio"
-                      values={target}
-                      onChange={setTarget}>
-                      <View style={[a.flex_row, a.gap_md, a.flex_wrap]}>
-                        <Toggle.Item name="account" label="Account">
-                          <Toggle.Radio />
-                          <Toggle.LabelText>Account</Toggle.LabelText>
-                        </Toggle.Item>
-                        <Toggle.Item name="profile" label="Profile">
-                          <Toggle.Radio />
-                          <Toggle.LabelText>Profile</Toggle.LabelText>
-                        </Toggle.Item>
-                        <Toggle.Item name="post" label="Post">
-                          <Toggle.Radio />
-                          <Toggle.LabelText>Post</Toggle.LabelText>
-                        </Toggle.Item>
-                        <Toggle.Item name="embed" label="Embed">
-                          <Toggle.Radio />
-                          <Toggle.LabelText>Embed</Toggle.LabelText>
-                        </Toggle.Item>
-                      </View>
-                    </Toggle.Group>
                   </View>
                 </View>
-              </View>
-            </>
-          )}
-
-          <Spacer />
-
-          <Heading title="" subtitle="Results" />
-
-          <ToggleButton.Group label="Results" values={view} onChange={setView}>
-            <ToggleButton.Button name="post" label="Post">
-              <ToggleButton.ButtonText>Post</ToggleButton.ButtonText>
-            </ToggleButton.Button>
-            <ToggleButton.Button name="notifications" label="Notifications">
-              <ToggleButton.ButtonText>Notifications</ToggleButton.ButtonText>
-            </ToggleButton.Button>
-            <ToggleButton.Button name="account" label="Account">
-              <ToggleButton.ButtonText>Account</ToggleButton.ButtonText>
-            </ToggleButton.Button>
-            <ToggleButton.Button name="data" label="Data">
-              <ToggleButton.ButtonText>Data</ToggleButton.ButtonText>
-            </ToggleButton.Button>
-          </ToggleButton.Group>
-
-          <View
-            style={[
-              a.border,
-              a.rounded_sm,
-              a.mt_lg,
-              a.p_md,
-              t.atoms.border_contrast_medium,
-            ]}>
-            {view[0] === 'post' && (
-              <>
-                <Heading title="Post" subtitle="in feed" />
-                <MockPostFeedItem post={post} moderation={postModeration} />
-
-                <Heading title="Post" subtitle="viewed directly" />
-                <MockPostThreadItem post={post} moderation={postModeration} />
-
-                <Heading title="Post" subtitle="reply in thread" />
-                <MockPostThreadItem
-                  post={post}
-                  moderation={postModeration}
-                  reply
-                />
-              </>
-            )}
-
-            {view[0] === 'notifications' && (
-              <>
-                <Heading title="Notification" subtitle="quote or reply" />
-                <MockNotifItem notif={replyNotif} moderationOpts={modOpts} />
-                <View style={{height: 20}} />
-                <Heading title="Notification" subtitle="follow or like" />
-                <MockNotifItem notif={followNotif} moderationOpts={modOpts} />
               </>
             )}
 
-            {view[0] === 'account' && (
-              <>
-                <Heading title="Account" subtitle="in listing" />
-                <MockAccountCard
-                  profile={profile}
-                  moderation={profileModeration}
-                />
-
-                <Heading title="Account" subtitle="viewing directly" />
-                <MockAccountScreen
-                  profile={profile}
-                  moderation={profileModeration}
-                  moderationOpts={modOpts}
-                />
-              </>
-            )}
+            <Spacer />
+
+            <Heading title="" subtitle="Results" />
+
+            <ToggleButton.Group
+              label="Results"
+              values={view}
+              onChange={setView}>
+              <ToggleButton.Button name="post" label="Post">
+                <ToggleButton.ButtonText>Post</ToggleButton.ButtonText>
+              </ToggleButton.Button>
+              <ToggleButton.Button name="notifications" label="Notifications">
+                <ToggleButton.ButtonText>Notifications</ToggleButton.ButtonText>
+              </ToggleButton.Button>
+              <ToggleButton.Button name="account" label="Account">
+                <ToggleButton.ButtonText>Account</ToggleButton.ButtonText>
+              </ToggleButton.Button>
+              <ToggleButton.Button name="data" label="Data">
+                <ToggleButton.ButtonText>Data</ToggleButton.ButtonText>
+              </ToggleButton.Button>
+            </ToggleButton.Group>
+
+            <View
+              style={[
+                a.border,
+                a.rounded_sm,
+                a.mt_lg,
+                a.p_md,
+                t.atoms.border_contrast_medium,
+              ]}>
+              {view[0] === 'post' && (
+                <>
+                  <Heading title="Post" subtitle="in feed" />
+                  <MockPostFeedItem post={post} moderation={postModeration} />
+
+                  <Heading title="Post" subtitle="viewed directly" />
+                  <MockPostThreadItem post={post} moderation={postModeration} />
+
+                  <Heading title="Post" subtitle="reply in thread" />
+                  <MockPostThreadItem
+                    post={post}
+                    moderation={postModeration}
+                    reply
+                  />
+                </>
+              )}
+
+              {view[0] === 'notifications' && (
+                <>
+                  <Heading title="Notification" subtitle="quote or reply" />
+                  <MockNotifItem notif={replyNotif} moderationOpts={modOpts} />
+                  <View style={{height: 20}} />
+                  <Heading title="Notification" subtitle="follow or like" />
+                  <MockNotifItem notif={followNotif} moderationOpts={modOpts} />
+                </>
+              )}
+
+              {view[0] === 'account' && (
+                <>
+                  <Heading title="Account" subtitle="in listing" />
+                  <MockAccountCard
+                    profile={profile}
+                    moderation={profileModeration}
+                  />
 
-            {view[0] === 'data' && (
-              <>
-                <ModerationUIView
-                  label="Profile Moderation UI"
-                  mod={profileModeration}
-                />
-                <ModerationUIView
-                  label="Post Moderation UI"
-                  mod={postModeration}
-                />
-                <DataView
-                  label={label[0]}
-                  data={LABELS[label[0] as keyof typeof LABELS]}
-                />
-                <DataView
-                  label="Profile Moderation Data"
-                  data={profileModeration}
-                />
-                <DataView label="Post Moderation Data" data={postModeration} />
-              </>
-            )}
-          </View>
+                  <Heading title="Account" subtitle="viewing directly" />
+                  <MockAccountScreen
+                    profile={profile}
+                    moderation={profileModeration}
+                    moderationOpts={modOpts}
+                  />
+                </>
+              )}
+
+              {view[0] === 'data' && (
+                <>
+                  <ModerationUIView
+                    label="Profile Moderation UI"
+                    mod={profileModeration}
+                  />
+                  <ModerationUIView
+                    label="Post Moderation UI"
+                    mod={postModeration}
+                  />
+                  <DataView
+                    label={label[0]}
+                    data={LABELS[label[0] as keyof typeof LABELS]}
+                  />
+                  <DataView
+                    label="Profile Moderation Data"
+                    data={profileModeration}
+                  />
+                  <DataView
+                    label="Post Moderation Data"
+                    data={postModeration}
+                  />
+                </>
+              )}
+            </View>
 
-          <View style={{height: 400}} />
-        </CenteredView>
-      </ScrollView>
-    </moderationOptsOverrideContext.Provider>
+            <View style={{height: 400}} />
+          </CenteredView>
+        </ScrollView>
+      </moderationOptsOverrideContext.Provider>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/Feeds.tsx b/src/view/screens/Feeds.tsx
index 87af59f7f..404145714 100644
--- a/src/view/screens/Feeds.tsx
+++ b/src/view/screens/Feeds.tsx
@@ -40,6 +40,7 @@ import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components
 import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
 import {ListMagnifyingGlass_Stroke2_Corner0_Rounded} from '#/components/icons/ListMagnifyingGlass'
 import {ListSparkle_Stroke2_Corner0_Rounded} from '#/components/icons/ListSparkle'
+import * as Layout from '#/components/Layout'
 import * as ListCard from '#/components/ListCard'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'Feeds'>
@@ -545,7 +546,7 @@ export function FeedsScreen(_props: Props) {
   )
 
   return (
-    <View style={[pal.view, styles.container]}>
+    <Layout.Screen testID="FeedsScreen">
       {isMobile && (
         <ViewHeader
           title={_(msg`Feeds`)}
@@ -582,7 +583,7 @@ export function FeedsScreen(_props: Props) {
           accessibilityHint=""
         />
       )}
-    </View>
+    </Layout.Screen>
   )
 }
 
@@ -768,9 +769,6 @@ function FeedsAboutHeader() {
 }
 
 const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-  },
   list: {
     height: '100%',
   },
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 4172d6408..237449383 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import {ActivityIndicator, StyleSheet, View} from 'react-native'
+import {ActivityIndicator, StyleSheet} from 'react-native'
 import {useFocusEffect} from '@react-navigation/native'
 
 import {PROD_DEFAULT_FEED} from '#/lib/constants'
@@ -23,12 +23,13 @@ import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell'
 import {useLoggedOutViewControls} from '#/state/shell/logged-out'
 import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed'
 import {FeedPage} from '#/view/com/feeds/FeedPage'
+import {HomeHeader} from '#/view/com/home/HomeHeader'
 import {Pager, PagerRef, RenderTabBarFnProps} from '#/view/com/pager/Pager'
 import {CustomFeedEmptyState} from '#/view/com/posts/CustomFeedEmptyState'
 import {FollowingEmptyState} from '#/view/com/posts/FollowingEmptyState'
 import {FollowingEndOfFeed} from '#/view/com/posts/FollowingEndOfFeed'
 import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned'
-import {HomeHeader} from '../com/home/HomeHeader'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home' | 'Start'>
 export function HomeScreen(props: Props) {
@@ -70,17 +71,19 @@ export function HomeScreen(props: Props) {
 
   if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) {
     return (
-      <HomeScreenReady
-        {...props}
-        preferences={preferences}
-        pinnedFeedInfos={pinnedFeedInfos}
-      />
+      <Layout.Screen testID="HomeScreen">
+        <HomeScreenReady
+          {...props}
+          preferences={preferences}
+          pinnedFeedInfos={pinnedFeedInfos}
+        />
+      </Layout.Screen>
     )
   } else {
     return (
-      <View style={styles.loading}>
+      <Layout.Screen style={styles.loading}>
         <ActivityIndicator size="large" />
-      </View>
+      </Layout.Screen>
     )
   }
 }
diff --git a/src/view/screens/LanguageSettings.tsx b/src/view/screens/LanguageSettings.tsx
index c1daa54e6..6af18103c 100644
--- a/src/view/screens/LanguageSettings.tsx
+++ b/src/view/screens/LanguageSettings.tsx
@@ -19,9 +19,10 @@ import {useModalControls} from '#/state/modals'
 import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {Button} from '#/view/com/util/forms/Button'
+import {Text} from '#/view/com/util/text/Text'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
 import {CenteredView} from '#/view/com/util/Views'
-import {Text} from '../com/util/text/Text'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'LanguageSettings'>
 
@@ -76,232 +77,234 @@ export function LanguageSettingsScreen(_props: Props) {
   }, [langPrefs.contentLanguages])
 
   return (
-    <CenteredView
-      style={[
-        pal.view,
-        pal.border,
-        styles.container,
-        isTabletOrDesktop && styles.desktopContainer,
-      ]}>
-      <ViewHeader title={_(msg`Language Settings`)} showOnDesktop />
+    <Layout.Screen testID="PreferencesLanguagesScreen">
+      <CenteredView
+        style={[
+          pal.view,
+          pal.border,
+          styles.container,
+          isTabletOrDesktop && styles.desktopContainer,
+        ]}>
+        <ViewHeader title={_(msg`Language Settings`)} showOnDesktop />
 
-      <View style={{paddingTop: 20, paddingHorizontal: 20}}>
-        {/* APP LANGUAGE */}
-        <View style={{paddingBottom: 20}}>
-          <Text type="title-sm" style={[pal.text, s.pb5]}>
-            <Trans>App Language</Trans>
-          </Text>
-          <Text style={[pal.text, s.pb10]}>
-            <Trans>
-              Select your app language for the default text to display in the
-              app.
-            </Trans>
-          </Text>
+        <View style={{paddingTop: 20, paddingHorizontal: 20}}>
+          {/* APP LANGUAGE */}
+          <View style={{paddingBottom: 20}}>
+            <Text type="title-sm" style={[pal.text, s.pb5]}>
+              <Trans>App Language</Trans>
+            </Text>
+            <Text style={[pal.text, s.pb10]}>
+              <Trans>
+                Select your app language for the default text to display in the
+                app.
+              </Trans>
+            </Text>
 
-          <View style={{position: 'relative'}}>
-            <RNPickerSelect
-              placeholder={{}}
-              value={sanitizeAppLanguageSetting(langPrefs.appLanguage)}
-              onValueChange={onChangeAppLanguage}
-              items={APP_LANGUAGES.filter(l => Boolean(l.code2)).map(l => ({
-                label: l.name,
-                value: l.code2,
-                key: l.code2,
-              }))}
-              style={{
-                inputAndroid: {
-                  backgroundColor: pal.viewLight.backgroundColor,
-                  color: pal.text.color,
-                  fontSize: 14,
-                  letterSpacing: 0.5,
-                  fontWeight: '600',
-                  paddingHorizontal: 14,
-                  paddingVertical: 8,
-                  borderRadius: 24,
-                },
-                inputIOS: {
-                  backgroundColor: pal.viewLight.backgroundColor,
-                  color: pal.text.color,
-                  fontSize: 14,
-                  letterSpacing: 0.5,
-                  fontWeight: '600',
-                  paddingHorizontal: 14,
-                  paddingVertical: 8,
-                  borderRadius: 24,
-                },
+            <View style={{position: 'relative'}}>
+              <RNPickerSelect
+                placeholder={{}}
+                value={sanitizeAppLanguageSetting(langPrefs.appLanguage)}
+                onValueChange={onChangeAppLanguage}
+                items={APP_LANGUAGES.filter(l => Boolean(l.code2)).map(l => ({
+                  label: l.name,
+                  value: l.code2,
+                  key: l.code2,
+                }))}
+                style={{
+                  inputAndroid: {
+                    backgroundColor: pal.viewLight.backgroundColor,
+                    color: pal.text.color,
+                    fontSize: 14,
+                    letterSpacing: 0.5,
+                    fontWeight: '600',
+                    paddingHorizontal: 14,
+                    paddingVertical: 8,
+                    borderRadius: 24,
+                  },
+                  inputIOS: {
+                    backgroundColor: pal.viewLight.backgroundColor,
+                    color: pal.text.color,
+                    fontSize: 14,
+                    letterSpacing: 0.5,
+                    fontWeight: '600',
+                    paddingHorizontal: 14,
+                    paddingVertical: 8,
+                    borderRadius: 24,
+                  },
+
+                  inputWeb: {
+                    cursor: 'pointer',
+                    // @ts-ignore web only
+                    '-moz-appearance': 'none',
+                    '-webkit-appearance': 'none',
+                    appearance: 'none',
+                    outline: 0,
+                    borderWidth: 0,
+                    backgroundColor: pal.viewLight.backgroundColor,
+                    color: pal.text.color,
+                    fontSize: 14,
+                    fontFamily: 'inherit',
+                    letterSpacing: 0.5,
+                    fontWeight: '600',
+                    paddingHorizontal: 14,
+                    paddingVertical: 8,
+                    borderRadius: 24,
+                  },
+                }}
+              />
 
-                inputWeb: {
-                  cursor: 'pointer',
-                  // @ts-ignore web only
-                  '-moz-appearance': 'none',
-                  '-webkit-appearance': 'none',
-                  appearance: 'none',
-                  outline: 0,
-                  borderWidth: 0,
+              <View
+                style={{
+                  position: 'absolute',
+                  top: 1,
+                  right: 1,
+                  bottom: 1,
+                  width: 40,
                   backgroundColor: pal.viewLight.backgroundColor,
-                  color: pal.text.color,
-                  fontSize: 14,
-                  fontFamily: 'inherit',
-                  letterSpacing: 0.5,
-                  fontWeight: '600',
-                  paddingHorizontal: 14,
-                  paddingVertical: 8,
                   borderRadius: 24,
-                },
-              }}
-            />
-
-            <View
-              style={{
-                position: 'absolute',
-                top: 1,
-                right: 1,
-                bottom: 1,
-                width: 40,
-                backgroundColor: pal.viewLight.backgroundColor,
-                borderRadius: 24,
-                pointerEvents: 'none',
-                alignItems: 'center',
-                justifyContent: 'center',
-              }}>
-              <FontAwesomeIcon
-                icon="chevron-down"
-                style={pal.text as FontAwesomeIconStyle}
-              />
+                  pointerEvents: 'none',
+                  alignItems: 'center',
+                  justifyContent: 'center',
+                }}>
+                <FontAwesomeIcon
+                  icon="chevron-down"
+                  style={pal.text as FontAwesomeIconStyle}
+                />
+              </View>
             </View>
           </View>
-        </View>
 
-        <View
-          style={{
-            height: 1,
-            backgroundColor: pal.border.borderColor,
-            marginBottom: 20,
-          }}
-        />
+          <View
+            style={{
+              height: 1,
+              backgroundColor: pal.border.borderColor,
+              marginBottom: 20,
+            }}
+          />
 
-        {/* PRIMARY LANGUAGE */}
-        <View style={{paddingBottom: 20}}>
-          <Text type="title-sm" style={[pal.text, s.pb5]}>
-            <Trans>Primary Language</Trans>
-          </Text>
-          <Text style={[pal.text, s.pb10]}>
-            <Trans>
-              Select your preferred language for translations in your feed.
-            </Trans>
-          </Text>
+          {/* PRIMARY LANGUAGE */}
+          <View style={{paddingBottom: 20}}>
+            <Text type="title-sm" style={[pal.text, s.pb5]}>
+              <Trans>Primary Language</Trans>
+            </Text>
+            <Text style={[pal.text, s.pb10]}>
+              <Trans>
+                Select your preferred language for translations in your feed.
+              </Trans>
+            </Text>
 
-          <View style={{position: 'relative'}}>
-            <RNPickerSelect
-              placeholder={{}}
-              value={langPrefs.primaryLanguage}
-              onValueChange={onChangePrimaryLanguage}
-              items={LANGUAGES.filter(l => Boolean(l.code2)).map(l => ({
-                label: l.name,
-                value: l.code2,
-                key: l.code2 + l.code3,
-              }))}
-              style={{
-                inputAndroid: {
-                  backgroundColor: pal.viewLight.backgroundColor,
-                  color: pal.text.color,
-                  fontSize: 14,
-                  letterSpacing: 0.5,
-                  fontWeight: '600',
-                  paddingHorizontal: 14,
-                  paddingVertical: 8,
-                  borderRadius: 24,
-                },
-                inputIOS: {
-                  backgroundColor: pal.viewLight.backgroundColor,
-                  color: pal.text.color,
-                  fontSize: 14,
-                  letterSpacing: 0.5,
-                  fontWeight: '600',
-                  paddingHorizontal: 14,
-                  paddingVertical: 8,
-                  borderRadius: 24,
-                },
-                inputWeb: {
-                  cursor: 'pointer',
-                  // @ts-ignore web only
-                  '-moz-appearance': 'none',
-                  '-webkit-appearance': 'none',
-                  appearance: 'none',
-                  outline: 0,
-                  borderWidth: 0,
+            <View style={{position: 'relative'}}>
+              <RNPickerSelect
+                placeholder={{}}
+                value={langPrefs.primaryLanguage}
+                onValueChange={onChangePrimaryLanguage}
+                items={LANGUAGES.filter(l => Boolean(l.code2)).map(l => ({
+                  label: l.name,
+                  value: l.code2,
+                  key: l.code2 + l.code3,
+                }))}
+                style={{
+                  inputAndroid: {
+                    backgroundColor: pal.viewLight.backgroundColor,
+                    color: pal.text.color,
+                    fontSize: 14,
+                    letterSpacing: 0.5,
+                    fontWeight: '600',
+                    paddingHorizontal: 14,
+                    paddingVertical: 8,
+                    borderRadius: 24,
+                  },
+                  inputIOS: {
+                    backgroundColor: pal.viewLight.backgroundColor,
+                    color: pal.text.color,
+                    fontSize: 14,
+                    letterSpacing: 0.5,
+                    fontWeight: '600',
+                    paddingHorizontal: 14,
+                    paddingVertical: 8,
+                    borderRadius: 24,
+                  },
+                  inputWeb: {
+                    cursor: 'pointer',
+                    // @ts-ignore web only
+                    '-moz-appearance': 'none',
+                    '-webkit-appearance': 'none',
+                    appearance: 'none',
+                    outline: 0,
+                    borderWidth: 0,
+                    backgroundColor: pal.viewLight.backgroundColor,
+                    color: pal.text.color,
+                    fontSize: 14,
+                    fontFamily: 'inherit',
+                    letterSpacing: 0.5,
+                    fontWeight: '600',
+                    paddingHorizontal: 14,
+                    paddingVertical: 8,
+                    borderRadius: 24,
+                  },
+                }}
+              />
+
+              <View
+                style={{
+                  position: 'absolute',
+                  top: 1,
+                  right: 1,
+                  bottom: 1,
+                  width: 40,
                   backgroundColor: pal.viewLight.backgroundColor,
-                  color: pal.text.color,
-                  fontSize: 14,
-                  fontFamily: 'inherit',
-                  letterSpacing: 0.5,
-                  fontWeight: '600',
-                  paddingHorizontal: 14,
-                  paddingVertical: 8,
                   borderRadius: 24,
-                },
-              }}
-            />
-
-            <View
-              style={{
-                position: 'absolute',
-                top: 1,
-                right: 1,
-                bottom: 1,
-                width: 40,
-                backgroundColor: pal.viewLight.backgroundColor,
-                borderRadius: 24,
-                pointerEvents: 'none',
-                alignItems: 'center',
-                justifyContent: 'center',
-              }}>
-              <FontAwesomeIcon
-                icon="chevron-down"
-                style={pal.text as FontAwesomeIconStyle}
-              />
+                  pointerEvents: 'none',
+                  alignItems: 'center',
+                  justifyContent: 'center',
+                }}>
+                <FontAwesomeIcon
+                  icon="chevron-down"
+                  style={pal.text as FontAwesomeIconStyle}
+                />
+              </View>
             </View>
           </View>
-        </View>
-
-        <View
-          style={{
-            height: 1,
-            backgroundColor: pal.border.borderColor,
-            marginBottom: 20,
-          }}
-        />
 
-        {/* CONTENT LANGUAGES */}
-        <View style={{paddingBottom: 20}}>
-          <Text type="title-sm" style={[pal.text, s.pb5]}>
-            <Trans>Content Languages</Trans>
-          </Text>
-          <Text style={[pal.text, s.pb10]}>
-            <Trans>
-              Select which languages you want your subscribed feeds to include.
-              If none are selected, all languages will be shown.
-            </Trans>
-          </Text>
+          <View
+            style={{
+              height: 1,
+              backgroundColor: pal.border.borderColor,
+              marginBottom: 20,
+            }}
+          />
 
-          <Button
-            type="default"
-            onPress={onPressContentLanguages}
-            style={styles.button}>
-            <FontAwesomeIcon
-              icon={myLanguages.length ? 'check' : 'plus'}
-              style={pal.text as FontAwesomeIconStyle}
-            />
-            <Text
-              type="button"
-              style={[pal.text, {flexShrink: 1, overflow: 'hidden'}]}
-              numberOfLines={1}>
-              {myLanguages.length ? myLanguages : _(msg`Select languages`)}
+          {/* CONTENT LANGUAGES */}
+          <View style={{paddingBottom: 20}}>
+            <Text type="title-sm" style={[pal.text, s.pb5]}>
+              <Trans>Content Languages</Trans>
             </Text>
-          </Button>
+            <Text style={[pal.text, s.pb10]}>
+              <Trans>
+                Select which languages you want your subscribed feeds to
+                include. If none are selected, all languages will be shown.
+              </Trans>
+            </Text>
+
+            <Button
+              type="default"
+              onPress={onPressContentLanguages}
+              style={styles.button}>
+              <FontAwesomeIcon
+                icon={myLanguages.length ? 'check' : 'plus'}
+                style={pal.text as FontAwesomeIconStyle}
+              />
+              <Text
+                type="button"
+                style={[pal.text, {flexShrink: 1, overflow: 'hidden'}]}
+                numberOfLines={1}>
+                {myLanguages.length ? myLanguages : _(msg`Select languages`)}
+              </Text>
+            </Button>
+          </View>
         </View>
-      </View>
-    </CenteredView>
+      </CenteredView>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/Lists.tsx b/src/view/screens/Lists.tsx
index d6a86e514..b79da6d54 100644
--- a/src/view/screens/Lists.tsx
+++ b/src/view/screens/Lists.tsx
@@ -16,6 +16,7 @@ import {MyLists} from '#/view/com/lists/MyLists'
 import {Button} from '#/view/com/util/forms/Button'
 import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
 import {Text} from '#/view/com/util/text/Text'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'Lists'>
 export function ListsScreen({}: Props) {
@@ -48,7 +49,7 @@ export function ListsScreen({}: Props) {
   }, [openModal, navigation])
 
   return (
-    <View style={s.hContentRegion} testID="listsScreen">
+    <Layout.Screen testID="listsScreen">
       <SimpleViewHeader
         showBackButton={isMobile}
         style={[
@@ -86,6 +87,6 @@ export function ListsScreen({}: Props) {
         </View>
       </SimpleViewHeader>
       <MyLists filter="curate" style={s.flexGrow1} />
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/Log.tsx b/src/view/screens/Log.tsx
index e6040b77e..026319baf 100644
--- a/src/view/screens/Log.tsx
+++ b/src/view/screens/Log.tsx
@@ -5,16 +5,17 @@ import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {usePalette} from '#/lib/hooks/usePalette'
 import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
 import {getEntries} from '#/logger/logDump'
 import {useTickEveryMinute} from '#/state/shell'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {usePalette} from 'lib/hooks/usePalette'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
-import {s} from 'lib/styles'
-import {Text} from '../com/util/text/Text'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {ScrollView} from '../com/util/Views'
+import {Text} from '#/view/com/util/text/Text'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
+import {ScrollView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 
 export function LogScreen({}: NativeStackScreenProps<
   CommonNavigatorParams,
@@ -42,7 +43,7 @@ export function LogScreen({}: NativeStackScreenProps<
   }
 
   return (
-    <View style={[s.flex1]}>
+    <Layout.Screen>
       <ViewHeader title="Log" />
       <ScrollView style={s.flex1}>
         {getEntries()
@@ -91,7 +92,7 @@ export function LogScreen({}: NativeStackScreenProps<
           })}
         <View style={s.footerSpacer} />
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/ModerationBlockedAccounts.tsx b/src/view/screens/ModerationBlockedAccounts.tsx
index 88a5df7ec..53e31d1d2 100644
--- a/src/view/screens/ModerationBlockedAccounts.tsx
+++ b/src/view/screens/ModerationBlockedAccounts.tsx
@@ -20,10 +20,11 @@ import {logger} from '#/logger'
 import {useMyBlockedAccountsQuery} from '#/state/queries/my-blocked-accounts'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {ProfileCard} from '#/view/com/profile/ProfileCard'
+import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
+import {Text} from '#/view/com/util/text/Text'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
 import {CenteredView} from '#/view/com/util/Views'
-import {ErrorScreen} from '../com/util/error/ErrorScreen'
-import {Text} from '../com/util/text/Text'
-import {ViewHeader} from '../com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<
   CommonNavigatorParams,
@@ -95,76 +96,78 @@ export function ModerationBlockedAccounts({}: Props) {
     />
   )
   return (
-    <CenteredView
-      style={[
-        styles.container,
-        isTabletOrDesktop && styles.containerDesktop,
-        pal.view,
-        pal.border,
-      ]}
-      testID="blockedAccountsScreen">
-      <ViewHeader title={_(msg`Blocked Accounts`)} showOnDesktop />
-      <Text
-        type="sm"
+    <Layout.Screen testID="blockedAccountsScreen">
+      <CenteredView
         style={[
-          styles.description,
-          pal.text,
-          isTabletOrDesktop && styles.descriptionDesktop,
-        ]}>
-        <Trans>
-          Blocked accounts cannot reply in your threads, mention you, or
-          otherwise interact with you. You will not see their content and they
-          will be prevented from seeing yours.
-        </Trans>
-      </Text>
-      {isEmpty ? (
-        <View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
-          {isError ? (
-            <ErrorScreen
-              title="Oops!"
-              message={cleanError(error)}
-              onPressTryAgain={refetch}
-            />
-          ) : (
-            <View style={[styles.empty, pal.viewLight]}>
-              <Text type="lg" style={[pal.text, styles.emptyText]}>
-                <Trans>
-                  You have not blocked any accounts yet. To block an account, go
-                  to their profile and select "Block account" from the menu on
-                  their account.
-                </Trans>
-              </Text>
-            </View>
-          )}
-        </View>
-      ) : (
-        <FlatList
-          style={[!isTabletOrDesktop && styles.flex1]}
-          data={profiles}
-          keyExtractor={(item: ActorDefs.ProfileView) => item.did}
-          refreshControl={
-            <RefreshControl
-              refreshing={isPTRing}
-              onRefresh={onRefresh}
-              tintColor={pal.colors.text}
-              titleColor={pal.colors.text}
-            />
-          }
-          onEndReached={onEndReached}
-          renderItem={renderItem}
-          initialNumToRender={15}
-          // FIXME(dan)
+          styles.container,
+          isTabletOrDesktop && styles.containerDesktop,
+          pal.view,
+          pal.border,
+        ]}
+        testID="blockedAccountsScreen">
+        <ViewHeader title={_(msg`Blocked Accounts`)} showOnDesktop />
+        <Text
+          type="sm"
+          style={[
+            styles.description,
+            pal.text,
+            isTabletOrDesktop && styles.descriptionDesktop,
+          ]}>
+          <Trans>
+            Blocked accounts cannot reply in your threads, mention you, or
+            otherwise interact with you. You will not see their content and they
+            will be prevented from seeing yours.
+          </Trans>
+        </Text>
+        {isEmpty ? (
+          <View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
+            {isError ? (
+              <ErrorScreen
+                title="Oops!"
+                message={cleanError(error)}
+                onPressTryAgain={refetch}
+              />
+            ) : (
+              <View style={[styles.empty, pal.viewLight]}>
+                <Text type="lg" style={[pal.text, styles.emptyText]}>
+                  <Trans>
+                    You have not blocked any accounts yet. To block an account,
+                    go to their profile and select "Block account" from the menu
+                    on their account.
+                  </Trans>
+                </Text>
+              </View>
+            )}
+          </View>
+        ) : (
+          <FlatList
+            style={[!isTabletOrDesktop && styles.flex1]}
+            data={profiles}
+            keyExtractor={(item: ActorDefs.ProfileView) => item.did}
+            refreshControl={
+              <RefreshControl
+                refreshing={isPTRing}
+                onRefresh={onRefresh}
+                tintColor={pal.colors.text}
+                titleColor={pal.colors.text}
+              />
+            }
+            onEndReached={onEndReached}
+            renderItem={renderItem}
+            initialNumToRender={15}
+            // FIXME(dan)
 
-          ListFooterComponent={() => (
-            <View style={styles.footer}>
-              {(isFetching || isFetchingNextPage) && <ActivityIndicator />}
-            </View>
-          )}
-          // @ts-ignore our .web version only -prf
-          desktopFixedHeight
-        />
-      )}
-    </CenteredView>
+            ListFooterComponent={() => (
+              <View style={styles.footer}>
+                {(isFetching || isFetchingNextPage) && <ActivityIndicator />}
+              </View>
+            )}
+            // @ts-ignore our .web version only -prf
+            desktopFixedHeight
+          />
+        )}
+      </CenteredView>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/ModerationModlists.tsx b/src/view/screens/ModerationModlists.tsx
index 39ba540b4..b147ba502 100644
--- a/src/view/screens/ModerationModlists.tsx
+++ b/src/view/screens/ModerationModlists.tsx
@@ -16,6 +16,7 @@ import {MyLists} from '#/view/com/lists/MyLists'
 import {Button} from '#/view/com/util/forms/Button'
 import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
 import {Text} from '#/view/com/util/text/Text'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'ModerationModlists'>
 export function ModerationModlistsScreen({}: Props) {
@@ -48,7 +49,7 @@ export function ModerationModlistsScreen({}: Props) {
   }, [openModal, navigation])
 
   return (
-    <View style={s.hContentRegion} testID="moderationModlistsScreen">
+    <Layout.Screen testID="moderationModlistsScreen">
       <SimpleViewHeader
         showBackButton={isMobile}
         style={
@@ -82,6 +83,6 @@ export function ModerationModlistsScreen({}: Props) {
         </View>
       </SimpleViewHeader>
       <MyLists filter="mod" style={s.flexGrow1} />
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/ModerationMutedAccounts.tsx b/src/view/screens/ModerationMutedAccounts.tsx
index bd29cb2d9..6d34c8a5f 100644
--- a/src/view/screens/ModerationMutedAccounts.tsx
+++ b/src/view/screens/ModerationMutedAccounts.tsx
@@ -20,10 +20,11 @@ import {logger} from '#/logger'
 import {useMyMutedAccountsQuery} from '#/state/queries/my-muted-accounts'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {ProfileCard} from '#/view/com/profile/ProfileCard'
+import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
+import {Text} from '#/view/com/util/text/Text'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
 import {CenteredView} from '#/view/com/util/Views'
-import {ErrorScreen} from '../com/util/error/ErrorScreen'
-import {Text} from '../com/util/text/Text'
-import {ViewHeader} from '../com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<
   CommonNavigatorParams,
@@ -95,75 +96,77 @@ export function ModerationMutedAccounts({}: Props) {
     />
   )
   return (
-    <CenteredView
-      style={[
-        styles.container,
-        isTabletOrDesktop && styles.containerDesktop,
-        pal.view,
-        pal.border,
-      ]}
-      testID="mutedAccountsScreen">
-      <ViewHeader title={_(msg`Muted Accounts`)} showOnDesktop />
-      <Text
-        type="sm"
+    <Layout.Screen testID="mutedAccountsScreen">
+      <CenteredView
         style={[
-          styles.description,
-          pal.text,
-          isTabletOrDesktop && styles.descriptionDesktop,
-        ]}>
-        <Trans>
-          Muted accounts have their posts removed from your feed and from your
-          notifications. Mutes are completely private.
-        </Trans>
-      </Text>
-      {isEmpty ? (
-        <View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
-          {isError ? (
-            <ErrorScreen
-              title="Oops!"
-              message={cleanError(error)}
-              onPressTryAgain={refetch}
-            />
-          ) : (
-            <View style={[styles.empty, pal.viewLight]}>
-              <Text type="lg" style={[pal.text, styles.emptyText]}>
-                <Trans>
-                  You have not muted any accounts yet. To mute an account, go to
-                  their profile and select "Mute account" from the menu on their
-                  account.
-                </Trans>
-              </Text>
-            </View>
-          )}
-        </View>
-      ) : (
-        <FlatList
-          style={[!isTabletOrDesktop && styles.flex1]}
-          data={profiles}
-          keyExtractor={item => item.did}
-          refreshControl={
-            <RefreshControl
-              refreshing={isPTRing}
-              onRefresh={onRefresh}
-              tintColor={pal.colors.text}
-              titleColor={pal.colors.text}
-            />
-          }
-          onEndReached={onEndReached}
-          renderItem={renderItem}
-          initialNumToRender={15}
-          // FIXME(dan)
+          styles.container,
+          isTabletOrDesktop && styles.containerDesktop,
+          pal.view,
+          pal.border,
+        ]}
+        testID="mutedAccountsScreen">
+        <ViewHeader title={_(msg`Muted Accounts`)} showOnDesktop />
+        <Text
+          type="sm"
+          style={[
+            styles.description,
+            pal.text,
+            isTabletOrDesktop && styles.descriptionDesktop,
+          ]}>
+          <Trans>
+            Muted accounts have their posts removed from your feed and from your
+            notifications. Mutes are completely private.
+          </Trans>
+        </Text>
+        {isEmpty ? (
+          <View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
+            {isError ? (
+              <ErrorScreen
+                title="Oops!"
+                message={cleanError(error)}
+                onPressTryAgain={refetch}
+              />
+            ) : (
+              <View style={[styles.empty, pal.viewLight]}>
+                <Text type="lg" style={[pal.text, styles.emptyText]}>
+                  <Trans>
+                    You have not muted any accounts yet. To mute an account, go
+                    to their profile and select "Mute account" from the menu on
+                    their account.
+                  </Trans>
+                </Text>
+              </View>
+            )}
+          </View>
+        ) : (
+          <FlatList
+            style={[!isTabletOrDesktop && styles.flex1]}
+            data={profiles}
+            keyExtractor={item => item.did}
+            refreshControl={
+              <RefreshControl
+                refreshing={isPTRing}
+                onRefresh={onRefresh}
+                tintColor={pal.colors.text}
+                titleColor={pal.colors.text}
+              />
+            }
+            onEndReached={onEndReached}
+            renderItem={renderItem}
+            initialNumToRender={15}
+            // FIXME(dan)
 
-          ListFooterComponent={() => (
-            <View style={styles.footer}>
-              {(isFetching || isFetchingNextPage) && <ActivityIndicator />}
-            </View>
-          )}
-          // @ts-ignore our .web version only -prf
-          desktopFixedHeight
-        />
-      )}
-    </CenteredView>
+            ListFooterComponent={() => (
+              <View style={styles.footer}>
+                {(isFetching || isFetchingNextPage) && <ActivityIndicator />}
+              </View>
+            )}
+            // @ts-ignore our .web version only -prf
+            desktopFixedHeight
+          />
+        )}
+      </CenteredView>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/NotFound.tsx b/src/view/screens/NotFound.tsx
index 7d51619b3..90d5e17dd 100644
--- a/src/view/screens/NotFound.tsx
+++ b/src/view/screens/NotFound.tsx
@@ -1,19 +1,21 @@
 import React from 'react'
 import {StyleSheet, View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {
-  useNavigation,
   StackActions,
   useFocusEffect,
+  useNavigation,
 } from '@react-navigation/native'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {Text} from '../com/util/text/Text'
-import {Button} from 'view/com/util/forms/Button'
-import {NavigationProp} from 'lib/routes/types'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
+
+import {usePalette} from '#/lib/hooks/usePalette'
+import {NavigationProp} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+import {Button} from '#/view/com/util/forms/Button'
+import {Text} from '#/view/com/util/text/Text'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 
 export const NotFoundScreen = () => {
   const pal = usePalette('default')
@@ -38,7 +40,7 @@ export const NotFoundScreen = () => {
   }, [navigation, canGoBack])
 
   return (
-    <View testID="notFoundView" style={pal.view}>
+    <Layout.Screen testID="notFoundView">
       <ViewHeader title={_(msg`Page Not Found`)} />
       <View style={styles.container}>
         <Text type="title-2xl" style={[pal.text, s.mb10]}>
@@ -61,7 +63,7 @@ export const NotFoundScreen = () => {
           onPress={onPressHome}
         />
       </View>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx
index 818d3d0ed..531d10a7f 100644
--- a/src/view/screens/Notifications.tsx
+++ b/src/view/screens/Notifications.tsx
@@ -34,6 +34,7 @@ import {CenteredView} from '#/view/com/util/Views'
 import {atoms as a, useTheme} from '#/alf'
 import {Button} from '#/components/Button'
 import {SettingsGear2_Stroke2_Corner0_Rounded as SettingsIcon} from '#/components/icons/SettingsGear2'
+import * as Layout from '#/components/Layout'
 import {Link} from '#/components/Link'
 import {Loader} from '#/components/Loader'
 import {Text} from '#/components/Typography'
@@ -192,39 +193,38 @@ export function NotificationsScreen({route: {params}}: Props) {
   }, [renderButton, isLoadingLatest])
 
   return (
-    <CenteredView
-      testID="notificationsScreen"
-      style={[s.hContentRegion, {paddingTop: 2}]}
-      sideBorders={true}>
-      <ViewHeader
-        title={_(msg`Notifications`)}
-        canGoBack={false}
-        showBorder={true}
-        renderButton={renderHeaderSpinner}
-      />
-      <MainScrollProvider>
-        <Feed
-          onScrolledDownChange={setIsScrolledDown}
-          scrollElRef={scrollElRef}
-          ListHeaderComponent={ListHeaderComponent}
-          overridePriorityNotifications={params?.show === 'all'}
+    <Layout.Screen testID="notificationsScreen">
+      <CenteredView style={[a.flex_1, {paddingTop: 2}]} sideBorders={true}>
+        <ViewHeader
+          title={_(msg`Notifications`)}
+          canGoBack={false}
+          showBorder={true}
+          renderButton={renderHeaderSpinner}
         />
-      </MainScrollProvider>
-      {(isScrolledDown || hasNew) && (
-        <LoadLatestBtn
-          onPress={onPressLoadLatest}
-          label={_(msg`Load new notifications`)}
-          showIndicator={hasNew}
+        <MainScrollProvider>
+          <Feed
+            onScrolledDownChange={setIsScrolledDown}
+            scrollElRef={scrollElRef}
+            ListHeaderComponent={ListHeaderComponent}
+            overridePriorityNotifications={params?.show === 'all'}
+          />
+        </MainScrollProvider>
+        {(isScrolledDown || hasNew) && (
+          <LoadLatestBtn
+            onPress={onPressLoadLatest}
+            label={_(msg`Load new notifications`)}
+            showIndicator={hasNew}
+          />
+        )}
+        <FAB
+          testID="composeFAB"
+          onPress={() => openComposer({})}
+          icon={<ComposeIcon2 strokeWidth={1.5} size={29} style={s.white} />}
+          accessibilityRole="button"
+          accessibilityLabel={_(msg`New post`)}
+          accessibilityHint=""
         />
-      )}
-      <FAB
-        testID="composeFAB"
-        onPress={() => openComposer({})}
-        icon={<ComposeIcon2 strokeWidth={1.5} size={29} style={s.white} />}
-        accessibilityRole="button"
-        accessibilityLabel={_(msg`New post`)}
-        accessibilityHint=""
-      />
-    </CenteredView>
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/NotificationsSettings.tsx b/src/view/screens/NotificationsSettings.tsx
index f395941df..f8d848a62 100644
--- a/src/view/screens/NotificationsSettings.tsx
+++ b/src/view/screens/NotificationsSettings.tsx
@@ -13,6 +13,7 @@ import {atoms as a, useTheme} from '#/alf'
 import {Admonition} from '#/components/Admonition'
 import {Error} from '#/components/Error'
 import * as Toggle from '#/components/forms/Toggle'
+import * as Layout from '#/components/Layout'
 import {Loader} from '#/components/Loader'
 import {Text} from '#/components/Typography'
 
@@ -35,52 +36,54 @@ export function NotificationsSettingsScreen({}: Props) {
     : serverPriority
 
   return (
-    <ScrollView stickyHeaderIndices={[0]}>
-      <ViewHeader
-        title={_(msg`Notification Settings`)}
-        showOnDesktop
-        showBorder
-      />
-      {isQueryError ? (
-        <Error
-          title={_(msg`Oops!`)}
-          message={_(msg`Something went wrong!`)}
-          onRetry={refetch}
-          sideBorders={false}
+    <Layout.Screen>
+      <ScrollView stickyHeaderIndices={[0]}>
+        <ViewHeader
+          title={_(msg`Notification Settings`)}
+          showOnDesktop
+          showBorder
         />
-      ) : (
-        <View style={[a.p_lg, a.gap_md]}>
-          <Text style={[a.text_lg, a.font_bold]}>
-            <FontAwesomeIcon icon="flask" style={t.atoms.text} />{' '}
-            <Trans>Notification filters</Trans>
-          </Text>
-          <Toggle.Group
-            label={_(msg`Priority notifications`)}
-            type="checkbox"
-            values={priority ? ['enabled'] : []}
-            onChange={onChangePriority}
-            disabled={typeof priority !== 'boolean' || isMutationPending}>
-            <View>
-              <Toggle.Item
-                name="enabled"
-                label={_(msg`Enable priority notifications`)}
-                style={[a.justify_between, a.py_sm]}>
-                <Toggle.LabelText>
-                  <Trans>Enable priority notifications</Trans>
-                </Toggle.LabelText>
-                {!data ? <Loader size="md" /> : <Toggle.Platform />}
-              </Toggle.Item>
-            </View>
-          </Toggle.Group>
-          <Admonition type="warning" style={[a.mt_sm]}>
-            <Trans>
-              Experimental: When this preference is enabled, you'll only receive
-              reply and quote notifications from users you follow. We'll
-              continue to add more controls here over time.
-            </Trans>
-          </Admonition>
-        </View>
-      )}
-    </ScrollView>
+        {isQueryError ? (
+          <Error
+            title={_(msg`Oops!`)}
+            message={_(msg`Something went wrong!`)}
+            onRetry={refetch}
+            sideBorders={false}
+          />
+        ) : (
+          <View style={[a.p_lg, a.gap_md]}>
+            <Text style={[a.text_lg, a.font_bold]}>
+              <FontAwesomeIcon icon="flask" style={t.atoms.text} />{' '}
+              <Trans>Notification filters</Trans>
+            </Text>
+            <Toggle.Group
+              label={_(msg`Priority notifications`)}
+              type="checkbox"
+              values={priority ? ['enabled'] : []}
+              onChange={onChangePriority}
+              disabled={typeof priority !== 'boolean' || isMutationPending}>
+              <View>
+                <Toggle.Item
+                  name="enabled"
+                  label={_(msg`Enable priority notifications`)}
+                  style={[a.justify_between, a.py_sm]}>
+                  <Toggle.LabelText>
+                    <Trans>Enable priority notifications</Trans>
+                  </Toggle.LabelText>
+                  {!data ? <Loader size="md" /> : <Toggle.Platform />}
+                </Toggle.Item>
+              </View>
+            </Toggle.Group>
+            <Admonition type="warning" style={[a.mt_sm]}>
+              <Trans>
+                Experimental: When this preference is enabled, you'll only
+                receive reply and quote notifications from users you follow.
+                We'll continue to add more controls here over time.
+              </Trans>
+            </Admonition>
+          </View>
+        )}
+      </ScrollView>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx
index 88d0726c1..c183569b7 100644
--- a/src/view/screens/PostThread.tsx
+++ b/src/view/screens/PostThread.tsx
@@ -2,11 +2,12 @@ import React from 'react'
 import {View} from 'react-native'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {makeRecordUri} from '#/lib/strings/url-helpers'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
-import {makeRecordUri} from 'lib/strings/url-helpers'
-import {s} from 'lib/styles'
-import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread'
+import {PostThread as PostThreadComponent} from '#/view/com/post-thread/PostThread'
+import {atoms as a} from '#/alf'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>
 export function PostThreadScreen({route}: Props) {
@@ -22,10 +23,10 @@ export function PostThreadScreen({route}: Props) {
   )
 
   return (
-    <View style={s.hContentRegion}>
-      <View style={s.flex1}>
+    <Layout.Screen testID="postThreadScreen">
+      <View style={a.flex_1}>
         <PostThreadComponent uri={uri} />
       </View>
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/PreferencesExternalEmbeds.tsx b/src/view/screens/PreferencesExternalEmbeds.tsx
index ae23b6e95..5a657ce84 100644
--- a/src/view/screens/PreferencesExternalEmbeds.tsx
+++ b/src/view/screens/PreferencesExternalEmbeds.tsx
@@ -10,17 +10,17 @@ import {
   EmbedPlayerSource,
   externalEmbedLabels,
 } from '#/lib/strings/embed-player'
-import {s} from '#/lib/styles'
 import {
   useExternalEmbedsPrefs,
   useSetExternalEmbedPref,
 } from '#/state/preferences'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {ToggleButton} from '#/view/com/util/forms/ToggleButton'
+import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
+import {Text} from '#/view/com/util/text/Text'
+import {ScrollView} from '#/view/com/util/Views'
 import {atoms as a} from '#/alf'
-import {SimpleViewHeader} from '../com/util/SimpleViewHeader'
-import {Text} from '../com/util/text/Text'
-import {ScrollView} from '../com/util/Views'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<
   CommonNavigatorParams,
@@ -38,7 +38,7 @@ export function PreferencesExternalEmbeds({}: Props) {
   )
 
   return (
-    <View style={s.hContentRegion} testID="preferencesExternalEmbedsScreen">
+    <Layout.Screen testID="preferencesExternalEmbedsScreen">
       <ScrollView
         // @ts-ignore web only -prf
         dataSet={{'stable-gutters': 1}}
@@ -81,7 +81,7 @@ export function PreferencesExternalEmbeds({}: Props) {
             />
           ))}
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/PreferencesFollowingFeed.tsx b/src/view/screens/PreferencesFollowingFeed.tsx
index 085250e3b..3d9928901 100644
--- a/src/view/screens/PreferencesFollowingFeed.tsx
+++ b/src/view/screens/PreferencesFollowingFeed.tsx
@@ -17,6 +17,7 @@ import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
 import {Text} from '#/view/com/util/text/Text'
 import {ScrollView} from '#/view/com/util/Views'
 import {atoms as a} from '#/alf'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<
   CommonNavigatorParams,
@@ -35,7 +36,7 @@ export function PreferencesFollowingFeed({}: Props) {
   )
 
   return (
-    <View testID="preferencesHomeFeedScreen" style={s.hContentRegion}>
+    <Layout.Screen testID="preferencesHomeFeedScreen">
       <ScrollView
         // @ts-ignore web only -sfn
         dataSet={{'stable-gutters': 1}}
@@ -185,7 +186,7 @@ export function PreferencesFollowingFeed({}: Props) {
           </View>
         </View>
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/PreferencesThreads.tsx b/src/view/screens/PreferencesThreads.tsx
index 7a5a88869..c3992276a 100644
--- a/src/view/screens/PreferencesThreads.tsx
+++ b/src/view/screens/PreferencesThreads.tsx
@@ -18,6 +18,7 @@ import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
 import {Text} from '#/view/com/util/text/Text'
 import {ScrollView} from '#/view/com/util/Views'
 import {atoms as a} from '#/alf'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PreferencesThreads'>
 export function PreferencesThreads({}: Props) {
@@ -38,7 +39,7 @@ export function PreferencesThreads({}: Props) {
   )
 
   return (
-    <View testID="preferencesThreadsScreen" style={s.hContentRegion}>
+    <Layout.Screen testID="preferencesThreadsScreen">
       <ScrollView
         // @ts-ignore web only -prf
         dataSet={{'stable-gutters': 1}}
@@ -134,7 +135,7 @@ export function PreferencesThreads({}: Props) {
           <ActivityIndicator style={a.flex_1} />
         )}
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx
index 776d83918..57e4652b5 100644
--- a/src/view/screens/PrivacyPolicy.tsx
+++ b/src/view/screens/PrivacyPolicy.tsx
@@ -1,16 +1,18 @@
 import React from 'react'
 import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
-import {Text} from 'view/com/util/text/Text'
-import {TextLink} from 'view/com/util/Link'
-import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {ScrollView} from 'view/com/util/Views'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
+
+import {usePalette} from '#/lib/hooks/usePalette'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+import {TextLink} from '#/view/com/util/Link'
+import {Text} from '#/view/com/util/text/Text'
+import {ScrollView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
+import {ViewHeader} from '../com/util/ViewHeader'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PrivacyPolicy'>
 export const PrivacyPolicyScreen = (_props: Props) => {
@@ -25,7 +27,7 @@ export const PrivacyPolicyScreen = (_props: Props) => {
   )
 
   return (
-    <View>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Privacy Policy`)} />
       <ScrollView style={[s.hContentRegion, pal.view]}>
         <View style={[s.p20]}>
@@ -42,6 +44,6 @@ export const PrivacyPolicyScreen = (_props: Props) => {
         </View>
         <View style={s.footerSpacer} />
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index 772625695..677fe09f4 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -45,6 +45,7 @@ import {ProfileHeader, ProfileHeaderLoading} from '#/screens/Profile/Header'
 import {ProfileFeedSection} from '#/screens/Profile/Sections/Feed'
 import {ProfileLabelsSection} from '#/screens/Profile/Sections/Labels'
 import {web} from '#/alf'
+import * as Layout from '#/components/Layout'
 import {ScreenHider} from '#/components/moderation/ScreenHider'
 import {ProfileStarterPacks} from '#/components/StarterPack/ProfileStarterPacks'
 import {navigate} from '#/Navigation'
@@ -55,7 +56,15 @@ interface SectionRef {
 }
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
-export function ProfileScreen({route}: Props) {
+export function ProfileScreen(props: Props) {
+  return (
+    <Layout.Screen testID="profileScreen">
+      <ProfileScreenInner {...props} />
+    </Layout.Screen>
+  )
+}
+
+function ProfileScreenInner({route}: Props) {
   const {_} = useLingui()
   const {currentAccount} = useSession()
   const queryClient = useQueryClient()
diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx
index a094cc3dd..6b9288f3b 100644
--- a/src/view/screens/ProfileFeed.tsx
+++ b/src/view/screens/ProfileFeed.tsx
@@ -61,6 +61,7 @@ import {
 } from '#/components/icons/Heart2'
 import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
 import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
+import * as Layout from '#/components/Layout'
 import {InlineLinkText} from '#/components/Link'
 import * as Menu from '#/components/Menu'
 import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
@@ -96,36 +97,42 @@ export function ProfileFeedScreen(props: Props) {
 
   if (error) {
     return (
-      <CenteredView>
-        <View style={[pal.view, pal.border, styles.notFoundContainer]}>
-          <Text type="title-lg" style={[pal.text, s.mb10]}>
-            <Trans>Could not load feed</Trans>
-          </Text>
-          <Text type="md" style={[pal.text, s.mb20]}>
-            {error.toString()}
-          </Text>
-
-          <View style={{flexDirection: 'row'}}>
-            <Button
-              type="default"
-              accessibilityLabel={_(msg`Go back`)}
-              accessibilityHint={_(msg`Returns to previous page`)}
-              onPress={onPressBack}
-              style={{flexShrink: 1}}>
-              <Text type="button" style={pal.text}>
-                <Trans>Go Back</Trans>
-              </Text>
-            </Button>
+      <Layout.Screen testID="profileFeedScreenError">
+        <CenteredView>
+          <View style={[pal.view, pal.border, styles.notFoundContainer]}>
+            <Text type="title-lg" style={[pal.text, s.mb10]}>
+              <Trans>Could not load feed</Trans>
+            </Text>
+            <Text type="md" style={[pal.text, s.mb20]}>
+              {error.toString()}
+            </Text>
+
+            <View style={{flexDirection: 'row'}}>
+              <Button
+                type="default"
+                accessibilityLabel={_(msg`Go back`)}
+                accessibilityHint={_(msg`Returns to previous page`)}
+                onPress={onPressBack}
+                style={{flexShrink: 1}}>
+                <Text type="button" style={pal.text}>
+                  <Trans>Go Back</Trans>
+                </Text>
+              </Button>
+            </View>
           </View>
-        </View>
-      </CenteredView>
+        </CenteredView>
+      </Layout.Screen>
     )
   }
 
   return resolvedUri ? (
-    <ProfileFeedScreenIntermediate feedUri={resolvedUri.uri} />
+    <Layout.Screen>
+      <ProfileFeedScreenIntermediate feedUri={resolvedUri.uri} />
+    </Layout.Screen>
   ) : (
-    <LoadingScreen />
+    <Layout.Screen>
+      <LoadingScreen />
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/ProfileFeedLikedBy.tsx b/src/view/screens/ProfileFeedLikedBy.tsx
index bb9ec2bae..b796480f3 100644
--- a/src/view/screens/ProfileFeedLikedBy.tsx
+++ b/src/view/screens/ProfileFeedLikedBy.tsx
@@ -1,14 +1,14 @@
 import React from 'react'
-import {View} from 'react-native'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {makeRecordUri} from '#/lib/strings/url-helpers'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
-import {makeRecordUri} from 'lib/strings/url-helpers'
-import {PostLikedBy as PostLikedByComponent} from '../com/post-thread/PostLikedBy'
-import {ViewHeader} from '../com/util/ViewHeader'
+import {PostLikedBy as PostLikedByComponent} from '#/view/com/post-thread/PostLikedBy'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFeedLikedBy'>
 export const ProfileFeedLikedByScreen = ({route}: Props) => {
@@ -24,9 +24,9 @@ export const ProfileFeedLikedByScreen = ({route}: Props) => {
   )
 
   return (
-    <View style={{flex: 1}}>
+    <Layout.Screen testID="postLikedByScreen">
       <ViewHeader title={_(msg`Liked By`)} />
       <PostLikedByComponent uri={uri} />
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/ProfileFollowers.tsx b/src/view/screens/ProfileFollowers.tsx
index 3a01edff5..9fa98cb1a 100644
--- a/src/view/screens/ProfileFollowers.tsx
+++ b/src/view/screens/ProfileFollowers.tsx
@@ -3,14 +3,14 @@ import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
-import {isWeb} from 'platform/detection'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {ProfileFollowers as ProfileFollowersComponent} from '#/view/com/profile/ProfileFollowers'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
-import {ProfileFollowers as ProfileFollowersComponent} from '../com/profile/ProfileFollowers'
-import {ViewHeader} from '../com/util/ViewHeader'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollowers'>
 export const ProfileFollowersScreen = ({route}: Props) => {
@@ -25,10 +25,12 @@ export const ProfileFollowersScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Followers`)} />
-      <ViewHeader title={_(msg`Followers`)} showBorder={!isWeb} />
-      <ProfileFollowersComponent name={name} />
-    </CenteredView>
+    <Layout.Screen testID="profileFollowersScreen">
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Followers`)} />
+        <ViewHeader title={_(msg`Followers`)} showBorder={!isWeb} />
+        <ProfileFollowersComponent name={name} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/ProfileFollows.tsx b/src/view/screens/ProfileFollows.tsx
index 762a84a37..483ee93ec 100644
--- a/src/view/screens/ProfileFollows.tsx
+++ b/src/view/screens/ProfileFollows.tsx
@@ -3,14 +3,14 @@ import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
-import {isWeb} from 'platform/detection'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {ProfileFollows as ProfileFollowsComponent} from '#/view/com/profile/ProfileFollows'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
-import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileFollows'
-import {ViewHeader} from '../com/util/ViewHeader'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollows'>
 export const ProfileFollowsScreen = ({route}: Props) => {
@@ -25,10 +25,12 @@ export const ProfileFollowsScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Following`)} />
-      <ViewHeader title={_(msg`Following`)} showBorder={!isWeb} />
-      <ProfileFollowsComponent name={name} />
-    </CenteredView>
+    <Layout.Screen testID="profileFollowsScreen">
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Following`)} />
+        <ViewHeader title={_(msg`Following`)} showBorder={!isWeb} />
+        <ProfileFollowsComponent name={name} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/ProfileList.tsx b/src/view/screens/ProfileList.tsx
index e0fd18ae9..cb333befa 100644
--- a/src/view/screens/ProfileList.tsx
+++ b/src/view/screens/ProfileList.tsx
@@ -73,6 +73,7 @@ import {CenteredView} from '#/view/com/util/Views'
 import {ListHiddenScreen} from '#/screens/List/ListHiddenScreen'
 import {atoms as a, useTheme} from '#/alf'
 import {useDialogControl} from '#/components/Dialog'
+import * as Layout from '#/components/Layout'
 import * as Hider from '#/components/moderation/Hider'
 import * as Prompt from '#/components/Prompt'
 import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
@@ -87,6 +88,14 @@ interface SectionRef {
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileList'>
 export function ProfileListScreen(props: Props) {
+  return (
+    <Layout.Screen testID="profileListScreen">
+      <ProfileListScreenInner {...props} />
+    </Layout.Screen>
+  )
+}
+
+function ProfileListScreenInner(props: Props) {
   const {_} = useLingui()
   const {name: handleOrDid, rkey} = props.route.params
   const {data: resolvedUri, error: resolveError} = useResolveUriQuery(
diff --git a/src/view/screens/SavedFeeds.tsx b/src/view/screens/SavedFeeds.tsx
index 2334abb5d..e88866f5b 100644
--- a/src/view/screens/SavedFeeds.tsx
+++ b/src/view/screens/SavedFeeds.tsx
@@ -32,6 +32,7 @@ import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType'
 import {atoms as a, useTheme} from '#/alf'
 import {Button, ButtonIcon, ButtonText} from '#/components/Button'
 import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
+import * as Layout from '#/components/Layout'
 import {Loader} from '#/components/Loader'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
@@ -106,120 +107,117 @@ function SavedFeedsInner({
   }, [_, isDesktop, onSaveChanges, hasUnsavedChanges, isOverwritePending])
 
   return (
-    <CenteredView
-      style={[
-        s.hContentRegion,
-        pal.border,
-        isTabletOrDesktop && styles.desktopContainer,
-      ]}>
-      <ViewHeader
-        title={_(msg`Edit My Feeds`)}
-        showOnDesktop
-        showBorder
-        renderButton={renderHeaderBtn}
-      />
-      <ScrollView style={s.flex1} contentContainerStyle={[styles.noBorder]}>
-        {noSavedFeedsOfAnyType && (
-          <View
-            style={[pal.border, {borderBottomWidth: StyleSheet.hairlineWidth}]}>
-            <NoSavedFeedsOfAnyType />
+    <Layout.Screen>
+      <CenteredView
+        style={[a.util_screen_outer]}
+        sideBorders={isTabletOrDesktop}>
+        <ViewHeader
+          title={_(msg`Edit My Feeds`)}
+          showOnDesktop
+          showBorder
+          renderButton={renderHeaderBtn}
+        />
+        <ScrollView style={[a.flex_1]} contentContainerStyle={[a.border_0]}>
+          {noSavedFeedsOfAnyType && (
+            <View style={[pal.border, a.border_b]}>
+              <NoSavedFeedsOfAnyType />
+            </View>
+          )}
+
+          <View style={[pal.text, pal.border, styles.title]}>
+            <Text type="title" style={pal.text}>
+              <Trans>Pinned Feeds</Trans>
+            </Text>
           </View>
-        )}
 
-        <View style={[pal.text, pal.border, styles.title]}>
-          <Text type="title" style={pal.text}>
-            <Trans>Pinned Feeds</Trans>
-          </Text>
-        </View>
+          {preferences ? (
+            !pinnedFeeds.length ? (
+              <View
+                style={[
+                  pal.border,
+                  isMobile && s.flex1,
+                  pal.viewLight,
+                  styles.empty,
+                ]}>
+                <Text type="lg" style={[pal.text]}>
+                  <Trans>You don't have any pinned feeds.</Trans>
+                </Text>
+              </View>
+            ) : (
+              pinnedFeeds.map(f => (
+                <ListItem
+                  key={f.id}
+                  feed={f}
+                  isPinned
+                  currentFeeds={currentFeeds}
+                  setCurrentFeeds={setCurrentFeeds}
+                  preferences={preferences}
+                />
+              ))
+            )
+          ) : (
+            <ActivityIndicator style={{marginTop: 20}} />
+          )}
 
-        {preferences ? (
-          !pinnedFeeds.length ? (
-            <View
-              style={[
-                pal.border,
-                isMobile && s.flex1,
-                pal.viewLight,
-                styles.empty,
-              ]}>
-              <Text type="lg" style={[pal.text]}>
-                <Trans>You don't have any pinned feeds.</Trans>
-              </Text>
+          {noFollowingFeed && (
+            <View style={[pal.border, a.border_b]}>
+              <NoFollowingFeed />
             </View>
-          ) : (
-            pinnedFeeds.map(f => (
-              <ListItem
-                key={f.id}
-                feed={f}
-                isPinned
-                currentFeeds={currentFeeds}
-                setCurrentFeeds={setCurrentFeeds}
-                preferences={preferences}
-              />
-            ))
-          )
-        ) : (
-          <ActivityIndicator style={{marginTop: 20}} />
-        )}
+          )}
 
-        {noFollowingFeed && (
-          <View
-            style={[pal.border, {borderBottomWidth: StyleSheet.hairlineWidth}]}>
-            <NoFollowingFeed />
+          <View style={[pal.text, pal.border, styles.title]}>
+            <Text type="title" style={pal.text}>
+              <Trans>Saved Feeds</Trans>
+            </Text>
           </View>
-        )}
-
-        <View style={[pal.text, pal.border, styles.title]}>
-          <Text type="title" style={pal.text}>
-            <Trans>Saved Feeds</Trans>
-          </Text>
-        </View>
-        {preferences ? (
-          !unpinnedFeeds.length ? (
-            <View
-              style={[
-                pal.border,
-                isMobile && s.flex1,
-                pal.viewLight,
-                styles.empty,
-              ]}>
-              <Text type="lg" style={[pal.text]}>
-                <Trans>You don't have any saved feeds.</Trans>
-              </Text>
-            </View>
+          {preferences ? (
+            !unpinnedFeeds.length ? (
+              <View
+                style={[
+                  pal.border,
+                  isMobile && s.flex1,
+                  pal.viewLight,
+                  styles.empty,
+                ]}>
+                <Text type="lg" style={[pal.text]}>
+                  <Trans>You don't have any saved feeds.</Trans>
+                </Text>
+              </View>
+            ) : (
+              unpinnedFeeds.map(f => (
+                <ListItem
+                  key={f.id}
+                  feed={f}
+                  isPinned={false}
+                  currentFeeds={currentFeeds}
+                  setCurrentFeeds={setCurrentFeeds}
+                  preferences={preferences}
+                />
+              ))
+            )
           ) : (
-            unpinnedFeeds.map(f => (
-              <ListItem
-                key={f.id}
-                feed={f}
-                isPinned={false}
-                currentFeeds={currentFeeds}
-                setCurrentFeeds={setCurrentFeeds}
-                preferences={preferences}
-              />
-            ))
-          )
-        ) : (
-          <ActivityIndicator style={{marginTop: 20}} />
-        )}
+            <ActivityIndicator style={{marginTop: 20}} />
+          )}
 
-        <View style={styles.footerText}>
-          <Text type="sm" style={pal.textLight}>
-            <Trans>
-              Feeds are custom algorithms that users build with a little coding
-              expertise.{' '}
-              <TextLink
-                type="sm"
-                style={pal.link}
-                href="https://github.com/bluesky-social/feed-generator"
-                text={_(msg`See this guide`)}
-              />{' '}
-              for more information.
-            </Trans>
-          </Text>
-        </View>
-        <View style={{height: 100}} />
-      </ScrollView>
-    </CenteredView>
+          <View style={styles.footerText}>
+            <Text type="sm" style={pal.textLight}>
+              <Trans>
+                Feeds are custom algorithms that users build with a little
+                coding expertise.{' '}
+                <TextLink
+                  type="sm"
+                  style={pal.link}
+                  href="https://github.com/bluesky-social/feed-generator"
+                  text={_(msg`See this guide`)}
+                />{' '}
+                for more information.
+              </Trans>
+            </Text>
+          </View>
+          <View style={{height: 100}} />
+        </ScrollView>
+      </CenteredView>
+    </Layout.Screen>
   )
 }
 
@@ -434,12 +432,6 @@ function FollowingFeedCard() {
 }
 
 const styles = StyleSheet.create({
-  desktopContainer: {
-    borderLeftWidth: 1,
-    borderRightWidth: 1,
-    // @ts-ignore only rendered on web
-    minHeight: '100vh',
-  },
   empty: {
     paddingHorizontal: 20,
     paddingVertical: 20,
@@ -463,10 +455,4 @@ const styles = StyleSheet.create({
     paddingTop: 22,
     paddingBottom: 100,
   },
-  noBorder: {
-    borderBottomWidth: 0,
-    borderRightWidth: 0,
-    borderLeftWidth: 0,
-    borderTopWidth: 0,
-  },
 })
diff --git a/src/view/screens/Search/Explore.tsx b/src/view/screens/Search/Explore.tsx
index 650fd4354..6aff9b88a 100644
--- a/src/view/screens/Search/Explore.tsx
+++ b/src/view/screens/Search/Explore.tsx
@@ -10,20 +10,20 @@ import {
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
+import {cleanError} from '#/lib/strings/errors'
 import {logger} from '#/logger'
 import {isWeb} from '#/platform/detection'
 import {useModerationOpts} from '#/state/preferences/moderation-opts'
 import {useGetPopularFeedsQuery} from '#/state/queries/feed'
 import {usePreferencesQuery} from '#/state/queries/preferences'
 import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
-import {cleanError} from 'lib/strings/errors'
 import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard'
 import {List} from '#/view/com/util/List'
-import {UserAvatar} from '#/view/com/util/UserAvatar'
 import {
   FeedFeedLoadingPlaceholder,
   ProfileCardFeedLoadingPlaceholder,
-} from 'view/com/util/LoadingPlaceholder'
+} from '#/view/com/util/LoadingPlaceholder'
+import {UserAvatar} from '#/view/com/util/UserAvatar'
 import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
 import {Button} from '#/components/Button'
 import * as FeedCard from '#/components/FeedCard'
@@ -564,6 +564,8 @@ export function Explore() {
     [t, moderationOpts],
   )
 
+  // note: actually not a screen, instead it's nested within
+  // the search screen. so we don't need Layout.Screen
   return (
     <List
       data={items}
diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx
index f4bbde567..5b4faacec 100644
--- a/src/view/screens/Search/Search.tsx
+++ b/src/view/screens/Search/Search.tsx
@@ -65,6 +65,7 @@ import * as FeedCard from '#/components/FeedCard'
 import {SearchInput} from '#/components/forms/SearchInput'
 import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron'
 import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
+import * as Layout from '#/components/Layout'
 
 function Loader() {
   const pal = usePalette('default')
@@ -852,7 +853,7 @@ export function SearchScreen(
   }, [setShowAutocomplete])
 
   return (
-    <View style={isWeb ? null : {flex: 1}}>
+    <Layout.Screen testID="searchScreen">
       <CenteredView
         style={[
           a.p_md,
@@ -957,7 +958,7 @@ export function SearchScreen(
           headerHeight={headerHeight}
         />
       </View>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx
index a40cc4f26..ce21a043b 100644
--- a/src/view/screens/Settings/index.tsx
+++ b/src/view/screens/Settings/index.tsx
@@ -57,6 +57,7 @@ import {atoms as a, useTheme} from '#/alf'
 import {useDialogControl} from '#/components/Dialog'
 import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings'
 import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog'
+import * as Layout from '#/components/Layout'
 import {Email2FAToggle} from './Email2FAToggle'
 import {ExportCarDialog} from './ExportCarDialog'
 
@@ -286,7 +287,7 @@ export function SettingsScreen({}: Props) {
   const {mutate: onPressDeleteChatDeclaration} = useDeleteActorDeclaration()
 
   return (
-    <View style={s.hContentRegion} testID="settingsScreen">
+    <Layout.Screen testID="settingsScreen">
       <ExportCarDialog control={exportCarControl} />
       <BirthDateSettingsDialog control={birthdayControl} />
 
@@ -919,7 +920,7 @@ export function SettingsScreen({}: Props) {
         </View>
         <View style={s.footerSpacer} />
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx
index c737dad5b..f1152fb7e 100644
--- a/src/view/screens/Storybook/index.tsx
+++ b/src/view/screens/Storybook/index.tsx
@@ -7,6 +7,7 @@ import {CenteredView} from '#/view/com/util/Views'
 import {ListContained} from '#/view/screens/Storybook/ListContained'
 import {atoms as a, ThemeProvider, useTheme} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
+import * as Layout from '#/components/Layout'
 import {Admonitions} from './Admonitions'
 import {Breakpoints} from './Breakpoints'
 import {Buttons} from './Buttons'
@@ -21,12 +22,16 @@ import {Theming} from './Theming'
 import {Typography} from './Typography'
 
 export function Storybook() {
-  if (isWeb) return <StorybookInner />
-
   return (
-    <ScrollView>
-      <StorybookInner />
-    </ScrollView>
+    <Layout.Screen>
+      {isWeb ? (
+        <StorybookInner />
+      ) : (
+        <ScrollView>
+          <StorybookInner />
+        </ScrollView>
+      )}
+    </Layout.Screen>
   )
 }
 
diff --git a/src/view/screens/Support.tsx b/src/view/screens/Support.tsx
index 9e7d36ec7..8782e911b 100644
--- a/src/view/screens/Support.tsx
+++ b/src/view/screens/Support.tsx
@@ -1,17 +1,18 @@
 import React from 'react'
-import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
-import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {Text} from 'view/com/util/text/Text'
-import {TextLink} from 'view/com/util/Link'
-import {CenteredView} from 'view/com/util/Views'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
-import {HELP_DESK_URL} from 'lib/constants'
+
+import {HELP_DESK_URL} from '#/lib/constants'
+import {usePalette} from '#/lib/hooks/usePalette'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+import {TextLink} from '#/view/com/util/Link'
+import {Text} from '#/view/com/util/text/Text'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'Support'>
 export const SupportScreen = (_props: Props) => {
@@ -26,7 +27,7 @@ export const SupportScreen = (_props: Props) => {
   )
 
   return (
-    <View>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Support`)} />
       <CenteredView>
         <Text type="title-xl" style={[pal.text, s.p20, s.pb5]}>
@@ -44,6 +45,6 @@ export const SupportScreen = (_props: Props) => {
           </Trans>
         </Text>
       </CenteredView>
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx
index 47aa9f268..fa40fbca3 100644
--- a/src/view/screens/TermsOfService.tsx
+++ b/src/view/screens/TermsOfService.tsx
@@ -1,16 +1,18 @@
 import React from 'react'
 import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
-import {Text} from 'view/com/util/text/Text'
-import {TextLink} from 'view/com/util/Link'
-import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {ScrollView} from 'view/com/util/Views'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
+
+import {usePalette} from '#/lib/hooks/usePalette'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
+import {s} from '#/lib/styles'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+import {TextLink} from '#/view/com/util/Link'
+import {Text} from '#/view/com/util/text/Text'
+import {ScrollView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
+import {ViewHeader} from '../com/util/ViewHeader'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'TermsOfService'>
 export const TermsOfServiceScreen = (_props: Props) => {
@@ -25,7 +27,7 @@ export const TermsOfServiceScreen = (_props: Props) => {
   )
 
   return (
-    <View>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Terms of Service`)} />
       <ScrollView style={[s.hContentRegion, pal.view]}>
         <View style={[s.p20]}>
@@ -40,6 +42,6 @@ export const TermsOfServiceScreen = (_props: Props) => {
         </View>
         <View style={s.footerSpacer} />
       </ScrollView>
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx
index 79fc1a069..43f8ee656 100644
--- a/src/view/shell/index.tsx
+++ b/src/view/shell/index.tsx
@@ -1,14 +1,7 @@
 import React from 'react'
-import {
-  BackHandler,
-  DimensionValue,
-  StyleSheet,
-  useWindowDimensions,
-  View,
-} from 'react-native'
+import {BackHandler, StyleSheet, useWindowDimensions, View} from 'react-native'
 import {Drawer} from 'react-native-drawer-layout'
 import Animated from 'react-native-reanimated'
-import {useSafeAreaInsets} from 'react-native-safe-area-context'
 import * as NavigationBar from 'expo-navigation-bar'
 import {StatusBar} from 'expo-status-bar'
 import {useNavigation, useNavigationState} from '@react-navigation/native'
@@ -32,6 +25,7 @@ import {useCloseAnyActiveElement} from '#/state/util'
 import {Lightbox} from '#/view/com/lightbox/Lightbox'
 import {ModalsContainer} from '#/view/com/modals/Modal'
 import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
+import {atoms as a} from '#/alf'
 import {MutedWordsDialog} from '#/components/dialogs/MutedWords'
 import {SigninDialog} from '#/components/dialogs/Signin'
 import {Outlet as PortalOutlet} from '#/components/Portal'
@@ -46,11 +40,7 @@ function ShellInner() {
   const isDrawerSwipeDisabled = useIsDrawerSwipeDisabled()
   const setIsDrawerOpen = useSetDrawerOpen()
   const winDim = useWindowDimensions()
-  const safeAreaInsets = useSafeAreaInsets()
-  const containerPadding = React.useMemo(
-    () => ({height: '100%' as DimensionValue, paddingTop: safeAreaInsets.top}),
-    [safeAreaInsets],
-  )
+
   const renderDrawerContent = React.useCallback(() => <DrawerContent />, [])
   const onOpenDrawer = React.useCallback(
     () => setIsDrawerOpen(true),
@@ -68,14 +58,14 @@ function ShellInner() {
   useNotificationsHandler()
 
   React.useEffect(() => {
-    let listener = {remove() {}}
     if (isAndroid) {
-      listener = BackHandler.addEventListener('hardwareBackPress', () => {
+      const listener = BackHandler.addEventListener('hardwareBackPress', () => {
         return closeAnyActiveElement()
       })
-    }
-    return () => {
-      listener.remove()
+
+      return () => {
+        listener.remove()
+      }
     }
   }, [closeAnyActiveElement])
 
@@ -102,7 +92,7 @@ function ShellInner() {
 
   return (
     <>
-      <Animated.View style={containerPadding}>
+      <Animated.View style={[a.h_full]}>
         <ErrorBoundary>
           <Drawer
             renderDrawerContent={renderDrawerContent}
diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx
index 2c7cd7b08..eeb1f13dd 100644
--- a/src/view/shell/index.web.tsx
+++ b/src/view/shell/index.web.tsx
@@ -7,19 +7,20 @@ import {useNavigation} from '@react-navigation/native'
 import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
 import {useIntentHandler} from '#/lib/hooks/useIntentHandler'
 import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
+import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
 import {NavigationProp} from '#/lib/routes/types'
-import {colors, s} from '#/lib/styles'
+import {colors} from '#/lib/styles'
 import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell'
 import {useComposerKeyboardShortcut} from '#/state/shell/composer/useComposerKeyboardShortcut'
 import {useCloseAllActiveElements} from '#/state/util'
+import {Lightbox} from '#/view/com/lightbox/Lightbox'
+import {ModalsContainer} from '#/view/com/modals/Modal'
+import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
+import {atoms as a} from '#/alf'
 import {MutedWordsDialog} from '#/components/dialogs/MutedWords'
 import {SigninDialog} from '#/components/dialogs/Signin'
 import {Outlet as PortalOutlet} from '#/components/Portal'
-import {useWebMediaQueries} from '../../lib/hooks/useWebMediaQueries'
-import {FlatNavigator, RoutesContainer} from '../../Navigation'
-import {Lightbox} from '../com/lightbox/Lightbox'
-import {ModalsContainer} from '../com/modals/Modal'
-import {ErrorBoundary} from '../com/util/ErrorBoundary'
+import {FlatNavigator, RoutesContainer} from '#/Navigation'
 import {Composer} from './Composer.web'
 import {DrawerContent} from './Drawer'
 
@@ -78,7 +79,7 @@ function ShellInner() {
 export const Shell: React.FC = function ShellImpl() {
   const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
   return (
-    <View style={[s.hContentRegion, pageBg]}>
+    <View style={[a.util_screen_outer, pageBg]}>
       <RoutesContainer>
         <ShellInner />
       </RoutesContainer>