about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/view/shell/Drawer.tsx558
-rw-r--r--src/view/shell/NavSignupCard.tsx52
-rw-r--r--src/view/shell/index.tsx1
3 files changed, 265 insertions, 346 deletions
diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx
index 51375dd32..c6ae955a8 100644
--- a/src/view/shell/Drawer.tsx
+++ b/src/view/shell/Drawer.tsx
@@ -1,26 +1,17 @@
 import React, {ComponentProps} from 'react'
-import {
-  Linking,
-  SafeAreaView,
-  ScrollView,
-  StyleProp,
-  StyleSheet,
-  TouchableOpacity,
-  View,
-  ViewStyle,
-} from 'react-native'
-import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
+import {Linking, ScrollView, TouchableOpacity, View} from 'react-native'
+import {useSafeAreaInsets} from 'react-native-safe-area-context'
 import {msg, Plural, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {StackActions, useNavigation} from '@react-navigation/native'
 
 import {FEEDBACK_FORM_URL, HELP_DESK_URL} from '#/lib/constants'
+import {PressableScale} from '#/lib/custom-animations/PressableScale'
 import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState'
-import {usePalette} from '#/lib/hooks/usePalette'
 import {getTabState, TabState} from '#/lib/routes/helpers'
 import {NavigationProp} from '#/lib/routes/types'
-import {colors, s} from '#/lib/styles'
-import {useTheme} from '#/lib/ThemeContext'
+import {sanitizeHandle} from '#/lib/strings/handles'
+import {colors} from '#/lib/styles'
 import {isWeb} from '#/platform/detection'
 import {emitSoftReset} from '#/state/events'
 import {useKawaiiMode} from '#/state/preferences/kawaii'
@@ -29,12 +20,12 @@ import {useProfileQuery} from '#/state/queries/profile'
 import {SessionAccount, useSession} from '#/state/session'
 import {useSetDrawerOpen} from '#/state/shell'
 import {formatCount} from '#/view/com/util/numeric/format'
-import {Text} from '#/view/com/util/text/Text'
 import {UserAvatar} from '#/view/com/util/UserAvatar'
 import {NavSignupCard} from '#/view/shell/NavSignupCard'
 import {atoms as a} from '#/alf'
-import {useTheme as useAlfTheme} from '#/alf'
+import {useTheme} from '#/alf'
 import {Button, ButtonIcon, ButtonText} from '#/components/Button'
+import {Divider} from '#/components/Divider'
 import {
   Bell_Filled_Corner0_Rounded as BellFilled,
   Bell_Stroke2_Corner0_Rounded as Bell,
@@ -50,15 +41,19 @@ import {
 } from '#/components/icons/HomeOpen'
 import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass'
 import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2'
-import {Message_Stroke2_Corner0_Rounded as Message} from '#/components/icons/Message'
+import {
+  Message_Stroke2_Corner0_Rounded as Message,
+  Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,
+} from '#/components/icons/Message'
 import {SettingsGear2_Stroke2_Corner0_Rounded as Settings} from '#/components/icons/SettingsGear2'
 import {
   UserCircle_Filled_Corner0_Rounded as UserCircleFilled,
   UserCircle_Stroke2_Corner0_Rounded as UserCircle,
 } from '#/components/icons/UserCircle'
-import {TextLink} from '../com/util/Link'
+import {InlineLinkText} from '#/components/Link'
+import {Text} from '#/components/Typography'
 
-const iconWidth = 28
+const iconWidth = 26
 
 let DrawerProfileCard = ({
   account,
@@ -68,7 +63,7 @@ let DrawerProfileCard = ({
   onPressProfile: () => void
 }): React.ReactNode => {
   const {_, i18n} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
   const {data: profile} = useProfileQuery({did: account.did})
 
   return (
@@ -76,62 +71,52 @@ let DrawerProfileCard = ({
       testID="profileCardButton"
       accessibilityLabel={_(msg`Profile`)}
       accessibilityHint={_(msg`Navigates to your profile`)}
-      onPress={onPressProfile}>
+      onPress={onPressProfile}
+      style={[a.gap_sm]}>
       <UserAvatar
-        size={80}
+        size={52}
         avatar={profile?.avatar}
         // See https://github.com/bluesky-social/social-app/pull/1801:
         usePlainRNImage={true}
         type={profile?.associated?.labeler ? 'labeler' : 'user'}
       />
-      <Text
-        type="title-lg"
-        style={[pal.text, s.bold, styles.profileCardDisplayName]}
-        numberOfLines={1}>
-        {profile?.displayName || account.handle}
-      </Text>
-      <Text
-        type="2xl"
-        style={[pal.textLight, styles.profileCardHandle]}
-        numberOfLines={1}>
-        @{account.handle}
-      </Text>
-      <View
-        style={[
-          styles.profileCardFollowers,
-          a.gap_xs,
-          a.flex_row,
-          a.align_center,
-          a.flex_wrap,
-        ]}>
-        <Text type="xl" style={pal.textLight}>
-          <Trans>
-            <Text type="xl-medium" style={pal.text}>
-              {formatCount(i18n, profile?.followersCount ?? 0)}
-            </Text>{' '}
-            <Plural
-              value={profile?.followersCount || 0}
-              one="follower"
-              other="followers"
-            />
-          </Trans>
+      <View style={[a.gap_2xs]}>
+        <Text
+          emoji
+          style={[a.font_heavy, a.text_xl, a.mt_2xs, a.leading_tight]}
+          numberOfLines={1}>
+          {profile?.displayName || account.handle}
         </Text>
-        <Text type="xl" style={pal.textLight}>
-          &middot;
-        </Text>
-        <Text type="xl" style={pal.textLight}>
-          <Trans>
-            <Text type="xl-medium" style={pal.text}>
-              {formatCount(i18n, profile?.followsCount ?? 0)}
-            </Text>{' '}
-            <Plural
-              value={profile?.followsCount || 0}
-              one="following"
-              other="following"
-            />
-          </Trans>
+        <Text
+          emoji
+          style={[t.atoms.text_contrast_medium, a.text_md, a.leading_tight]}
+          numberOfLines={1}>
+          {sanitizeHandle(account.handle, '@')}
         </Text>
       </View>
+      <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
+        <Trans>
+          <Text style={[a.text_md, a.font_bold]}>
+            {formatCount(i18n, profile?.followersCount ?? 0)}
+          </Text>{' '}
+          <Plural
+            value={profile?.followersCount || 0}
+            one="follower"
+            other="followers"
+          />
+        </Trans>{' '}
+        &middot;{' '}
+        <Trans>
+          <Text style={[a.text_md, a.font_bold]}>
+            {formatCount(i18n, profile?.followsCount ?? 0)}
+          </Text>{' '}
+          <Plural
+            value={profile?.followsCount || 0}
+            one="following"
+            other="following"
+          />
+        </Trans>
+      </Text>
     </TouchableOpacity>
   )
 }
@@ -139,14 +124,19 @@ DrawerProfileCard = React.memo(DrawerProfileCard)
 export {DrawerProfileCard}
 
 let DrawerContent = ({}: {}): React.ReactNode => {
-  const theme = useTheme()
-  const t = useAlfTheme()
-  const pal = usePalette('default')
+  const t = useTheme()
   const {_} = useLingui()
+  const insets = useSafeAreaInsets()
   const setDrawerOpen = useSetDrawerOpen()
   const navigation = useNavigation<NavigationProp>()
-  const {isAtHome, isAtSearch, isAtFeeds, isAtNotifications, isAtMyProfile} =
-    useNavigationTabState()
+  const {
+    isAtHome,
+    isAtSearch,
+    isAtFeeds,
+    isAtNotifications,
+    isAtMyProfile,
+    isAtMessages,
+  } = useNavigationTabState()
   const {hasSession, currentAccount} = useSession()
   const kawaii = useKawaiiMode()
 
@@ -187,6 +177,11 @@ let DrawerContent = ({}: {}): React.ReactNode => {
     [onPressTab],
   )
 
+  const onPressMessages = React.useCallback(
+    () => onPressTab('Messages'),
+    [onPressTab],
+  )
+
   const onPressNotifications = React.useCallback(
     () => onPressTab('Notifications'),
     [onPressTab],
@@ -228,89 +223,91 @@ let DrawerContent = ({}: {}): React.ReactNode => {
   // =
 
   return (
-    <View
-      testID="drawer"
-      style={[
-        styles.view,
-        theme.colorScheme === 'light' ? pal.view : t.atoms.bg_contrast_25,
-      ]}>
-      <SafeAreaView style={s.flex1}>
-        <ScrollView style={styles.main}>
-          {hasSession && currentAccount ? (
-            <View style={{}}>
-              <DrawerProfileCard
-                account={currentAccount}
-                onPressProfile={onPressProfile}
-              />
-            </View>
-          ) : (
-            <View style={{paddingRight: 20}}>
-              <NavSignupCard />
-            </View>
-          )}
-
-          {hasSession ? (
-            <>
-              <View style={{height: 16}} />
-              <SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
-              <HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
-              <NotificationsMenuItem
-                isActive={isAtNotifications}
-                onPress={onPressNotifications}
-              />
-              <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} />
-              <ListsMenuItem onPress={onPressLists} />
-              <ProfileMenuItem
-                isActive={isAtMyProfile}
-                onPress={onPressProfile}
-              />
-              <SettingsMenuItem onPress={onPressSettings} />
-            </>
-          ) : (
-            <>
-              <HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
-              <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} />
-              <SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
-            </>
-          )}
-
-          <View style={styles.smallSpacer} />
-
-          <View style={[{flexWrap: 'wrap', gap: 12}, s.flexCol]}>
-            <TextLink
-              type="md"
-              style={pal.link}
-              href="https://bsky.social/about/support/tos"
-              text={_(msg`Terms of Service`)}
+    <View testID="drawer" style={[a.flex_1, t.atoms.bg]}>
+      <ScrollView
+        style={[a.flex_1]}
+        contentContainerStyle={[
+          a.px_xl,
+          {
+            paddingTop: Math.max(
+              insets.top + a.pt_xl.paddingTop,
+              a.pt_xl.paddingTop,
+            ),
+          },
+        ]}>
+        {hasSession && currentAccount ? (
+          <DrawerProfileCard
+            account={currentAccount}
+            onPressProfile={onPressProfile}
+          />
+        ) : (
+          <View style={[a.pr_xl]}>
+            <NavSignupCard />
+          </View>
+        )}
+
+        <Divider style={[a.mt_xl, a.mb_sm]} />
+
+        {hasSession ? (
+          <>
+            <SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
+            <HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
+            <ChatMenuItem isActive={isAtMessages} onPress={onPressMessages} />
+            <NotificationsMenuItem
+              isActive={isAtNotifications}
+              onPress={onPressNotifications}
             />
-            <TextLink
-              type="md"
-              style={pal.link}
-              href="https://bsky.social/about/support/privacy-policy"
-              text={_(msg`Privacy Policy`)}
+            <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} />
+            <ListsMenuItem onPress={onPressLists} />
+            <ProfileMenuItem
+              isActive={isAtMyProfile}
+              onPress={onPressProfile}
             />
-            {kawaii && (
-              <Text type="md" style={pal.textLight}>
+            <SettingsMenuItem onPress={onPressSettings} />
+          </>
+        ) : (
+          <>
+            <HomeMenuItem isActive={isAtHome} onPress={onPressHome} />
+            <FeedsMenuItem isActive={isAtFeeds} onPress={onPressMyFeeds} />
+            <SearchMenuItem isActive={isAtSearch} onPress={onPressSearch} />
+          </>
+        )}
+
+        <Divider style={[a.mb_xl, a.mt_sm]} />
+
+        <View style={[a.flex_col, a.gap_md, a.flex_wrap]}>
+          <InlineLinkText
+            style={[a.text_md]}
+            label={_(msg`Terms of Service`)}
+            to="https://bsky.social/about/support/tos">
+            <Trans>Terms of Service</Trans>
+          </InlineLinkText>
+          <InlineLinkText
+            style={[a.text_md]}
+            to="https://bsky.social/about/support/privacy-policy"
+            label={_(msg`Privacy Policy`)}>
+            <Trans>Privacy Policy</Trans>
+          </InlineLinkText>
+          {kawaii && (
+            <Text style={t.atoms.text_contrast_medium}>
+              <Trans>
                 Logo by{' '}
-                <TextLink
-                  type="md"
-                  href="/profile/sawaratsuki.bsky.social"
-                  text="@sawaratsuki.bsky.social"
-                  style={pal.link}
-                />
-              </Text>
-            )}
-          </View>
-
-          <View style={styles.smallSpacer} />
-          <View style={styles.smallSpacer} />
-        </ScrollView>
+                <InlineLinkText
+                  style={[a.text_md]}
+                  to="/profile/sawaratsuki.bsky.social"
+                  label="@sawaratsuki.bsky.social">
+                  @sawaratsuki.bsky.social
+                </InlineLinkText>
+              </Trans>
+            </Text>
+          )}
+        </View>
+      </ScrollView>
 
-        <DrawerFooter
-          onPressFeedback={onPressFeedback}
-          onPressHelp={onPressHelp}
-        />
-      </SafeAreaView>
+      <DrawerFooter
+        onPressFeedback={onPressFeedback}
+        onPressHelp={onPressHelp}
+      />
     </View>
   )
 }
@@ -325,8 +322,17 @@ let DrawerFooter = ({
   onPressHelp: () => void
 }): React.ReactNode => {
   const {_} = useLingui()
+  const insets = useSafeAreaInsets()
   return (
-    <View style={styles.footer}>
+    <View
+      style={[
+        a.flex_row,
+        a.gap_sm,
+        a.flex_wrap,
+        a.pl_xl,
+        a.pt_md,
+        {paddingBottom: Math.max(insets.bottom, a.pb_xl.paddingBottom)},
+      ]}>
       <Button
         label={_(msg`Send feedback`)}
         size="small"
@@ -356,7 +362,7 @@ let DrawerFooter = ({
 }
 DrawerFooter = React.memo(DrawerFooter)
 
-interface MenuItemProps extends ComponentProps<typeof TouchableOpacity> {
+interface MenuItemProps extends ComponentProps<typeof PressableScale> {
   icon: JSX.Element
   label: string
   count?: string
@@ -371,20 +377,14 @@ let SearchMenuItem = ({
   onPress: () => void
 }): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <MenuItem
       icon={
         isActive ? (
-          <MagnifyingGlassFilled
-            style={pal.text as StyleProp<ViewStyle>}
-            width={iconWidth}
-          />
+          <MagnifyingGlassFilled style={[t.atoms.text]} width={iconWidth} />
         ) : (
-          <MagnifyingGlass
-            style={pal.text as StyleProp<ViewStyle>}
-            width={iconWidth}
-          />
+          <MagnifyingGlass style={[t.atoms.text]} width={iconWidth} />
         )
       }
       label={_(msg`Search`)}
@@ -405,17 +405,14 @@ let HomeMenuItem = ({
   onPress: () => void
 }): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <MenuItem
       icon={
         isActive ? (
-          <HomeFilled
-            style={pal.text as StyleProp<ViewStyle>}
-            width={iconWidth}
-          />
+          <HomeFilled style={[t.atoms.text]} width={iconWidth} />
         ) : (
-          <Home style={pal.text as StyleProp<ViewStyle>} width={iconWidth} />
+          <Home style={[t.atoms.text]} width={iconWidth} />
         )
       }
       label={_(msg`Home`)}
@@ -428,6 +425,34 @@ let HomeMenuItem = ({
 }
 HomeMenuItem = React.memo(HomeMenuItem)
 
+let ChatMenuItem = ({
+  isActive,
+  onPress,
+}: {
+  isActive: boolean
+  onPress: () => void
+}): React.ReactNode => {
+  const {_} = useLingui()
+  const t = useTheme()
+  return (
+    <MenuItem
+      icon={
+        isActive ? (
+          <MessageFilled style={[t.atoms.text]} width={iconWidth} />
+        ) : (
+          <Message style={[t.atoms.text]} width={iconWidth} />
+        )
+      }
+      label={_(msg`Chats`)}
+      accessibilityLabel={_(msg`Chats`)}
+      accessibilityHint=""
+      bold={isActive}
+      onPress={onPress}
+    />
+  )
+}
+ChatMenuItem = React.memo(ChatMenuItem)
+
 let NotificationsMenuItem = ({
   isActive,
   onPress,
@@ -436,18 +461,15 @@ let NotificationsMenuItem = ({
   onPress: () => void
 }): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
   const numUnreadNotifications = useUnreadNotifications()
   return (
     <MenuItem
       icon={
         isActive ? (
-          <BellFilled
-            style={pal.text as StyleProp<ViewStyle>}
-            width={iconWidth}
-          />
+          <BellFilled style={[t.atoms.text]} width={iconWidth} />
         ) : (
-          <Bell style={pal.text as StyleProp<ViewStyle>} width={iconWidth} />
+          <Bell style={[t.atoms.text]} width={iconWidth} />
         )
       }
       label={_(msg`Notifications`)}
@@ -473,17 +495,14 @@ let FeedsMenuItem = ({
   onPress: () => void
 }): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <MenuItem
       icon={
         isActive ? (
-          <HashtagFilled
-            width={iconWidth}
-            style={pal.text as FontAwesomeIconStyle}
-          />
+          <HashtagFilled width={iconWidth} style={[t.atoms.text]} />
         ) : (
-          <Hashtag width={iconWidth} style={pal.text as FontAwesomeIconStyle} />
+          <Hashtag width={iconWidth} style={[t.atoms.text]} />
         )
       }
       label={_(msg`Feeds`)}
@@ -498,10 +517,11 @@ FeedsMenuItem = React.memo(FeedsMenuItem)
 
 let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
+
   return (
     <MenuItem
-      icon={<List style={pal.text} width={iconWidth} />}
+      icon={<List style={[t.atoms.text]} width={iconWidth} />}
       label={_(msg`Lists`)}
       accessibilityLabel={_(msg`Lists`)}
       accessibilityHint=""
@@ -519,20 +539,14 @@ let ProfileMenuItem = ({
   onPress: () => void
 }): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <MenuItem
       icon={
         isActive ? (
-          <UserCircleFilled
-            style={pal.text as StyleProp<ViewStyle>}
-            width={iconWidth}
-          />
+          <UserCircleFilled style={[t.atoms.text]} width={iconWidth} />
         ) : (
-          <UserCircle
-            style={pal.text as StyleProp<ViewStyle>}
-            width={iconWidth}
-          />
+          <UserCircle style={[t.atoms.text]} width={iconWidth} />
         )
       }
       label={_(msg`Profile`)}
@@ -546,12 +560,10 @@ ProfileMenuItem = React.memo(ProfileMenuItem)
 
 let SettingsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
     <MenuItem
-      icon={
-        <Settings style={pal.text as StyleProp<ViewStyle>} width={iconWidth} />
-      }
+      icon={<Settings style={[t.atoms.text]} width={iconWidth} />}
       label={_(msg`Settings`)}
       accessibilityLabel={_(msg`Settings`)}
       accessibilityHint=""
@@ -569,142 +581,58 @@ function MenuItem({
   bold,
   onPress,
 }: MenuItemProps) {
-  const pal = usePalette('default')
+  const t = useTheme()
   return (
-    <TouchableOpacity
+    <PressableScale
       testID={`menuItemButton-${label}`}
-      style={styles.menuItem}
+      style={[a.flex_row, a.align_center, a.gap_sm, {paddingVertical: 10}]}
       onPress={onPress}
       accessibilityRole="tab"
       accessibilityLabel={accessibilityLabel}
-      accessibilityHint="">
-      <View style={[styles.menuItemIconWrapper]}>
+      accessibilityHint=""
+      targetScale={0.95}>
+      <View style={[a.relative]}>
         {icon}
         {count ? (
           <View
             style={[
-              styles.menuItemCount,
-              a.rounded_full,
-              count.length > 2
-                ? styles.menuItemCountHundreds
-                : count.length > 1
-                ? styles.menuItemCountTens
-                : undefined,
+              a.absolute,
+              a.inset_0,
+              a.align_end,
+              {top: -4, right: a.gap_sm.gap * -1},
             ]}>
-            <Text
-              style={[styles.menuItemCountLabel, a.font_bold]}
-              numberOfLines={1}>
-              {count}
-            </Text>
+            <View
+              style={[
+                a.rounded_full,
+                {
+                  right: count.length === 1 ? 6 : 0,
+                  paddingHorizontal: 4,
+                  paddingVertical: 1,
+                  backgroundColor: t.palette.primary_500,
+                },
+              ]}>
+              <Text
+                style={[
+                  a.text_xs,
+                  a.leading_tight,
+                  a.font_bold,
+                  {
+                    fontVariant: ['tabular-nums'],
+                    color: colors.white,
+                  },
+                ]}
+                numberOfLines={1}>
+                {count}
+              </Text>
+            </View>
           </View>
         ) : undefined}
       </View>
       <Text
-        type={bold ? '2xl-bold' : '2xl'}
-        style={[pal.text, s.flex1]}
+        style={[a.flex_1, a.text_2xl, bold && a.font_bold]}
         numberOfLines={1}>
         {label}
       </Text>
-    </TouchableOpacity>
+    </PressableScale>
   )
 }
-
-const styles = StyleSheet.create({
-  view: {
-    flex: 1,
-    paddingBottom: 50,
-    maxWidth: 300,
-  },
-  viewDarkMode: {
-    backgroundColor: '#1B1919',
-  },
-  main: {
-    paddingHorizontal: 20,
-    paddingTop: 20,
-  },
-  smallSpacer: {
-    height: 20,
-  },
-
-  profileCardDisplayName: {
-    marginTop: 20,
-    paddingRight: 30,
-  },
-  profileCardHandle: {
-    marginTop: 4,
-    paddingRight: 30,
-  },
-  profileCardFollowers: {
-    marginTop: 16,
-  },
-
-  menuItem: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    paddingVertical: 16,
-  },
-  menuItemIconWrapper: {
-    width: 24,
-    height: 24,
-    alignItems: 'center',
-    justifyContent: 'center',
-    marginRight: 12,
-  },
-  menuItemCount: {
-    position: 'absolute',
-    width: 'auto',
-    right: -6,
-    top: -4,
-    backgroundColor: colors.blue3,
-    paddingHorizontal: 4,
-    paddingBottom: 1,
-    borderRadius: 6,
-  },
-  menuItemCountTens: {
-    width: 25,
-  },
-  menuItemCountHundreds: {
-    right: -12,
-    width: 34,
-  },
-  menuItemCountLabel: {
-    fontSize: 12,
-    fontVariant: ['tabular-nums'],
-    color: colors.white,
-  },
-
-  inviteCodes: {
-    paddingLeft: 0,
-    paddingVertical: 8,
-    flexDirection: 'row',
-  },
-  inviteCodesIcon: {
-    marginRight: 6,
-    flexShrink: 0,
-    marginTop: 2,
-  },
-
-  footer: {
-    flexWrap: 'wrap',
-    flexDirection: 'row',
-    gap: 8,
-    paddingRight: 20,
-    paddingTop: 20,
-    paddingLeft: 20,
-  },
-  footerBtn: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    padding: 10,
-    borderRadius: 25,
-  },
-  footerBtnFeedback: {
-    paddingHorizontal: 20,
-  },
-  footerBtnFeedbackLight: {
-    backgroundColor: '#DDEFFF',
-  },
-  footerBtnFeedbackDark: {
-    backgroundColor: colors.blue6,
-  },
-})
diff --git a/src/view/shell/NavSignupCard.tsx b/src/view/shell/NavSignupCard.tsx
index 12bfa7ea0..05533328c 100644
--- a/src/view/shell/NavSignupCard.tsx
+++ b/src/view/shell/NavSignupCard.tsx
@@ -5,18 +5,15 @@ import {useLingui} from '@lingui/react'
 
 import {useLoggedOutViewControls} from '#/state/shell/logged-out'
 import {useCloseAllActiveElements} from '#/state/util'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s} from 'lib/styles'
-import {Button} from '#/view/com/util/forms/Button'
-import {Text} from '#/view/com/util/text/Text'
 import {Logo} from '#/view/icons/Logo'
 import {atoms as a} from '#/alf'
 import {AppLanguageDropdown} from '#/components/AppLanguageDropdown'
+import {Button, ButtonText} from '#/components/Button'
 import {Link} from '#/components/Link'
+import {Text} from '#/components/Typography'
 
 let NavSignupCard = ({}: {}): React.ReactNode => {
   const {_} = useLingui()
-  const pal = usePalette('default')
   const {requestSwitchToAccount} = useLoggedOutViewControls()
   const closeAllActiveElements = useCloseAllActiveElements()
 
@@ -32,45 +29,38 @@ let NavSignupCard = ({}: {}): React.ReactNode => {
   }, [requestSwitchToAccount, closeAllActiveElements])
 
   return (
-    <View
-      style={{
-        alignItems: 'flex-start',
-        paddingTop: 6,
-        marginBottom: 24,
-      }}>
+    <View style={[{maxWidth: 200}]}>
       <Link to="/" label="Bluesky - Home">
-        <Logo width={48} />
+        <Logo width={32} />
       </Link>
 
-      <View style={{paddingTop: 18}}>
-        <Text type="md-bold" style={[pal.text]}>
-          <Trans>Sign up or sign in to join the conversation</Trans>
+      <View style={[a.pt_lg]}>
+        <Text
+          style={[a.text_3xl, a.font_heavy, {lineHeight: a.text_3xl.fontSize}]}>
+          <Trans>Join the conversation</Trans>
         </Text>
       </View>
 
-      <View
-        style={{
-          flexDirection: 'row',
-          flexWrap: 'wrap',
-          paddingTop: 12,
-          gap: 8,
-        }}>
+      <View style={[a.flex_row, a.flex_wrap, a.gap_sm, a.pt_md]}>
         <Button
           onPress={showCreateAccount}
-          accessibilityHint={_(msg`Sign up`)}
-          accessibilityLabel={_(msg`Sign up`)}>
-          <Text type="md" style={[{color: 'white'}, s.bold]}>
+          label={_(msg`Sign up`)}
+          size="small"
+          variant="solid"
+          color="primary">
+          <ButtonText>
             <Trans>Sign up</Trans>
-          </Text>
+          </ButtonText>
         </Button>
         <Button
-          type="default"
           onPress={showSignIn}
-          accessibilityHint={_(msg`Sign in`)}
-          accessibilityLabel={_(msg`Sign in`)}>
-          <Text type="md" style={[pal.text, s.bold]}>
+          label={_(msg`Sign in`)}
+          size="small"
+          variant="solid"
+          color="secondary">
+          <ButtonText>
             <Trans>Sign in</Trans>
-          </Text>
+          </ButtonText>
         </Button>
       </View>
 
diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx
index 43f8ee656..ae81a4eb4 100644
--- a/src/view/shell/index.tsx
+++ b/src/view/shell/index.tsx
@@ -96,6 +96,7 @@ function ShellInner() {
         <ErrorBoundary>
           <Drawer
             renderDrawerContent={renderDrawerContent}
+            drawerStyle={{width: Math.min(400, winDim.width * 0.8)}}
             open={isDrawerOpen}
             onOpen={onOpenDrawer}
             onClose={onCloseDrawer}