diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b11c963c7ef13ea581a5d2f0a7503ae0db42c7a5..bbd2b555704e607c8ef5477d9667ea916fc145d0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,7 @@
 variables:
   YARN_CACHE_FOLDER: '$CI_PROJECT_DIR/.yarn/cache'
   YARN_ENABLE_GLOBAL_CACHE: 'false'
+  GIT_DEPTH: 50
 
 .yarn-cache-rw:
   key:
@@ -97,6 +98,7 @@ lint_compile_test:
     - yarn format:check
     - yarn check-types
     - git fetch origin main:main # needed for 'yarn workspaces foreach ... (lint_all task)'
+    - git fetch origin $CI_COMMIT_BRANCH:$CI_COMMIT_BRANCH
     - yarn lint_all
     - yarn test
   interruptible: true
diff --git a/apps/mobile/notifications/chatNotifications.ts b/apps/mobile/notifications/chatNotifications.ts
index f5f14bb00e261ebab696636a37b91e44d095e480..7157b868fc8374ea0cdba5d54395a1ae76cc3ffd 100644
--- a/apps/mobile/notifications/chatNotifications.ts
+++ b/apps/mobile/notifications/chatNotifications.ts
@@ -1,11 +1,11 @@
 import * as Notifications from 'expo-notifications'
 import type { NotificationContentInput } from 'expo-notifications'
 
-import { type Route } from '@react-navigation/native'
+import type { Route } from '@react-navigation/native'
 
 import { getLogger } from '@holi/core/helpers/logging'
 import { RouteName } from '@holi/mobile/navigation/routeName'
-import { NotificationData } from '@holi/mobile/notifications'
+import type { NotificationData } from '@holi/mobile/notifications'
 
 const logger = getLogger('Notifications')
 
@@ -107,7 +107,7 @@ const createAndroidRoomMemberChangePush = (event: AndroidRoomMemberChange): Noti
   if (event.membership === 'invite') {
     return {
       title: 'Invitation',
-      body: 'Someone invited you to a ' + (event.content.is_direct ? 'direct chat' : 'chat') + '.',
+      body: 'Someone invited you to a ' + (event?.content?.is_direct ? 'direct chat' : 'chat') + '.',
       data: {
         room_id: event.room_id,
       },
@@ -115,7 +115,7 @@ const createAndroidRoomMemberChangePush = (event: AndroidRoomMemberChange): Noti
   } else {
     return {
       title: 'Channel Update',
-      body: 'Someone updated ' + (event.content.is_direct ? 'your direct chat' : 'a chat you are part of') + '.',
+      body: 'Someone updated ' + (event?.content?.is_direct ? 'your direct chat' : 'a chat you are part of') + '.',
       data: {
         room_id: event.room_id,
       },
diff --git a/apps/mobile/package.json b/apps/mobile/package.json
index 54ea47e0681a92e681d4ac7a743fc401ebf6460e..7ec0502e00d2ab1e59a9351e48bd755eb90656bb 100644
--- a/apps/mobile/package.json
+++ b/apps/mobile/package.json
@@ -68,7 +68,7 @@
     "react-native-get-random-values": "^1.11.0",
     "react-native-image-crop-picker": "^0.41.2",
     "react-native-image-pan-zoom": "^2.1.12",
-    "react-native-keyboard-controller": "^1.15.2",
+    "react-native-keyboard-controller": "^1.16.3",
     "react-native-media-query": "^2.0.1",
     "react-native-reanimated": "~3.10.1",
     "react-native-reanimated-carousel": "^3.5.1",
diff --git a/apps/web/__tests__/sitemap/static.xml.test.ts b/apps/web/__tests__/sitemap/static.xml.test.ts
index 5cb3ee783426853eee62fcebcc68b9c383328236..88414dc98a1fd5cd4e894361f2908193efd58e81 100644
--- a/apps/web/__tests__/sitemap/static.xml.test.ts
+++ b/apps/web/__tests__/sitemap/static.xml.test.ts
@@ -1,6 +1,6 @@
 import { HttpResponse } from 'msw'
 import { setupServer } from 'msw/node'
-import { NextPageContext } from 'next'
+import type { NextPageContext } from 'next'
 
 import { createPageContextMock, graphqlLink } from '@holi/web/__tests__/helpers'
 import { getServerSideProps, topicSlugsQuery } from '@holi/web/pages/sitemap/static.xml'
@@ -8,6 +8,7 @@ import { getServerSideProps, topicSlugsQuery } from '@holi/web/pages/sitemap/sta
 jest.mock('@holi/core/helpers/isSSR', () => ({
   isSSR: true,
 }))
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 const server = setupServer(
   graphqlLink.query(topicSlugsQuery, () => {
diff --git a/core/components/Screen/index.tsx b/core/components/Screen/index.tsx
index fa60a5ec991a68e8cf6681f293a2744b5489846e..4cfb9e8b4c34ee2aa0e8222ab53e56d4a0352487 100644
--- a/core/components/Screen/index.tsx
+++ b/core/components/Screen/index.tsx
@@ -108,15 +108,20 @@ type BottomComponentWrapperProps = {
   StickyBottomComponent: ScreenProps['StickyBottomComponent']
   padding?: ScreenProps['padding']
   onLayout?: ((event: LayoutChangeEvent) => void) | undefined
+  footerHidden?: boolean
 }
-const BottomComponentWrapper = ({ StickyBottomComponent, padding, onLayout }: BottomComponentWrapperProps) => {
+const BottomComponentWrapper = ({
+  StickyBottomComponent,
+  padding,
+  onLayout,
+  footerHidden,
+}: BottomComponentWrapperProps) => {
   const { styles } = useStyles(stylesheet)
   const { bottomDistance } = useGradualAnimation()
-  const { bottom } = useSafeAreaInsets()
-  const toSubtract = dimensions.bottomBarHeight + (isIos ? bottom : 0)
+  const bottomBar = footerHidden ? 0 : dimensions.bottomBarHeight
   const bottomInputStyle = useAnimatedStyle(
     () => ({
-      bottom: bottomDistance.value - toSubtract < 0 ? 0 : bottomDistance.value - toSubtract,
+      bottom: bottomDistance.value - bottomBar < 0 ? 0 : bottomDistance.value - bottomBar,
     }),
     []
   )
@@ -128,6 +133,7 @@ const BottomComponentWrapper = ({ StickyBottomComponent, padding, onLayout }: Bo
   )
 }
 
+const DEFAULT_VERTICAL_OFFSET = 100
 export const Screen = (props: ScreenProps) => {
   const {
     preset = 'fixed',
@@ -140,7 +146,7 @@ export const Screen = (props: ScreenProps) => {
     headerOptions,
     StickyTopComponent,
     padding,
-    contentContainerPadding = { left: 'xs', right: 'xs' },
+    contentContainerPadding,
     testID,
     ...otherProps
   } = props
@@ -152,6 +158,11 @@ export const Screen = (props: ScreenProps) => {
   })
   const safeAreaInsets = useSafeAreaInsets()
   const navigationOptions = useScreenOptions()
+  const footerHidden = headerOptions?.navigationCustomOptions?.footerShown === false
+  const _keyboardVerticalOffset = keyboardVerticalOffset
+    ? keyboardVerticalOffset
+    : DEFAULT_VERTICAL_OFFSET + (Platform.OS === 'ios' ? stickyBottomOffset || 0 : 0)
+
   return (
     <SafeAreaView
       edges={safeAreaEdges}
@@ -167,15 +178,15 @@ export const Screen = (props: ScreenProps) => {
       <StatusBar {...statusBarProps} barStyle={themeName === 'dark' ? 'light-content' : 'dark-content'} />
 
       <KeyboardAvoidingView
-        behavior={isIos ? 'padding' : 'height'}
-        keyboardVerticalOffset={keyboardVerticalOffset}
         {...keyboardAvoidingViewProps}
+        behavior={isIos ? 'padding' : 'height'}
+        keyboardVerticalOffset={_keyboardVerticalOffset}
         style={[
           keyboardAvoidingViewProps?.style,
           styles.flex1,
           styles.relative,
           styles.contentContainerPadding(navigationOptions.headerShown, safeAreaInsets.top, contentContainerPadding),
-          StickyBottomComponent ? styles.stickyBottomOffset(stickyBottomOffset) : null,
+          StickyBottomComponent && preset === 'fixed' ? styles.stickyBottomOffset(stickyBottomOffset) : null,
           StickyTopComponent ? styles.stickyTopOffset(stickyTopOffset) : null,
         ]}
       >
@@ -201,6 +212,7 @@ export const Screen = (props: ScreenProps) => {
       {StickyBottomComponent && (
         <BottomComponentWrapper
           StickyBottomComponent={StickyBottomComponent}
+          footerHidden={footerHidden}
           padding={padding}
           onLayout={stickyBottomLayout}
         />
diff --git a/core/components/Screen/index.web.tsx b/core/components/Screen/index.web.tsx
index cd5a92ae7a9257e7985099ddda0f828272510e9b..9cb3e8109386b43a2abfd7c2693ca1331474782a 100644
--- a/core/components/Screen/index.web.tsx
+++ b/core/components/Screen/index.web.tsx
@@ -14,7 +14,7 @@ export const Screen = (props: ScreenProps) => {
     StickyBottomComponent,
     StickyTopComponent,
     padding,
-    contentContainerPadding = { left: 'xs', right: 'xs' },
+    contentContainerPadding,
     headerOptions,
     testID,
     children,
@@ -26,24 +26,25 @@ export const Screen = (props: ScreenProps) => {
   const { styles, theme } = useStyles(stylesheet)
   const { stickyBottomLayout, stickyBottomOffset, stickyTopLayout, stickyTopOffset, headerHeight } =
     useScreenComponentInternal({ headerOptions })
+
   return (
     <View
       testID={testID}
       style={[styles.padding(padding), styles.container, { backgroundColor: theme.colors.bg[backgroundColor] }]}
     >
-      <HoliContainer flex={1} noPadding>
+      <HoliContainer flex={1}>
         <View
           style={[
             styles.flex1,
-            styles.webContainer,
             keyboardAvoidingViewProps?.style,
+            styles.webContainer,
             StickyTopComponent ? styles.stickyTopOffset(stickyTopOffset) : null,
             StickyBottomComponent ? styles.stickyBottomOffset(stickyBottomOffset) : null,
           ]}
         >
           {StickyTopComponent && (
             <View style={[styles.stickyTopWeb(headerHeight), { position: 'fixed' }]} onLayout={stickyTopLayout}>
-              <HoliContainer noPadding>{StickyTopComponent}</HoliContainer>
+              <HoliContainer>{StickyTopComponent}</HoliContainer>
             </View>
           )}
 
@@ -56,8 +57,14 @@ export const Screen = (props: ScreenProps) => {
           </ScrollViewRefreshable>
 
           {StickyBottomComponent && (
-            <View style={[styles.stickyBottomWeb, { position: 'fixed' }]} onLayout={stickyBottomLayout}>
-              <HoliContainer noPadding>{StickyBottomComponent}</HoliContainer>
+            <View
+              style={[
+                styles.stickyBottomWeb(headerOptions?.navigationCustomOptions?.footerShown === false),
+                { position: 'fixed' },
+              ]}
+              onLayout={stickyBottomLayout}
+            >
+              <HoliContainer>{StickyBottomComponent}</HoliContainer>
             </View>
           )}
         </View>
diff --git a/core/components/Screen/mock.ts b/core/components/Screen/mock.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5f564d4dc5c6c9a26a3150788d5c7c58653d096a
--- /dev/null
+++ b/core/components/Screen/mock.ts
@@ -0,0 +1,11 @@
+jest.mock('react-native-safe-area-context', () => {
+  const mock = jest.requireActual('react-native-safe-area-context/jest/mock')
+  return {
+    ...mock.default,
+  }
+})
+
+jest.mock('react-native-keyboard-controller', () => ({
+  ...require('react-native-keyboard-controller/jest'),
+  useReanimatedKeyboardAnimation: () => ({ height: 0 }),
+}))
diff --git a/core/components/Screen/styles.ts b/core/components/Screen/styles.ts
index dddbafdf6d9511974eae0386ec97176f14974569..7d9aaea16e44fc44f9c8df23db41e8ba491f450d 100644
--- a/core/components/Screen/styles.ts
+++ b/core/components/Screen/styles.ts
@@ -2,6 +2,7 @@ import type { ScreenPadding } from '@holi/core/components/Screen/types'
 import { dimensions } from '@holi/ui/styles/globalVars'
 import { Spacing } from 'holi-bricks/tokens'
 import { createStyleSheet } from 'holi-bricks/utils'
+import { Platform } from 'react-native'
 
 const makePadding = (padding?: ScreenPadding) => ({
   paddingTop: padding?.top ? Spacing[padding?.top] : 0,
@@ -40,7 +41,8 @@ export const stylesheet = createStyleSheet(() => {
     },
     stickyBottomOffset: (offset: number) => {
       return {
-        paddingBottom: offset,
+        marginBottom: Platform.OS === 'ios' ? offset : 0,
+        paddingBottom: Platform.OS === 'android' || Platform.OS === 'web' ? offset : 0,
       }
     },
     stickyTopOffset: (offset: number) => {
@@ -64,15 +66,15 @@ export const stylesheet = createStyleSheet(() => {
         zIndex: 10,
       }
     },
-    stickyBottomWeb: {
+    stickyBottomWeb: (footerHidden) => ({
       width: '100%',
       maxWidth: dimensions.maxScreenWidth,
-      bottom: dimensions.bottomBarHeight,
+      bottom: footerHidden ? 0 : dimensions.bottomBarHeight,
       left: 0,
       right: 0,
       marginHorizontal: 'auto',
       zIndex: 10,
-    },
+    }),
     stickyBottom: {
       position: 'absolute',
       bottom: 0,
diff --git a/core/components/Screen/useScreenComponentInternal.ts b/core/components/Screen/useScreenComponentInternal.ts
index 2b2a2eca5cbff80add2964d7ff4665a349078773..74cc7f12fb5123c713eea92e87182e15dce3bd64 100644
--- a/core/components/Screen/useScreenComponentInternal.ts
+++ b/core/components/Screen/useScreenComponentInternal.ts
@@ -12,13 +12,20 @@ export const useScreenComponentInternal = ({ headerOptions }: UseScreenComponent
   const setScreenOptions = useSetScreenOptions()
   const [stickyBottomOffset, setStickyBottomOffset] = useState(0)
 
-  const stickyBottomLayout = useCallback((e: LayoutChangeEvent) => {
-    setStickyBottomOffset(e.nativeEvent.layout.height)
-  }, [])
+  const stickyBottomLayout = useCallback(
+    (e: LayoutChangeEvent) => {
+      if (e.nativeEvent.layout.height !== stickyBottomOffset) setStickyBottomOffset(e.nativeEvent.layout.height)
+    },
+    [stickyBottomOffset]
+  )
+
   const [stickyTopOffset, setStickyTopOffset] = useState(0)
-  const stickyTopLayout = useCallback((e: LayoutChangeEvent) => {
-    setStickyTopOffset(e.nativeEvent.layout.height)
-  }, [])
+  const stickyTopLayout = useCallback(
+    (e: LayoutChangeEvent) => {
+      if (e.nativeEvent.layout.height !== stickyTopOffset) setStickyTopOffset(e.nativeEvent.layout.height)
+    },
+    [stickyTopOffset]
+  )
 
   useEffect(() => {
     if (headerOptions) {
diff --git a/core/package.json b/core/package.json
index 6e94eeb6ddb5a3447a40a8f2f8f4fe93b254ae57..da0af1e594f8d499cd455fff1697084cf12bdb04 100644
--- a/core/package.json
+++ b/core/package.json
@@ -7,7 +7,7 @@
     "graphql-tag": "^2.12.6",
     "react": "18.2.0",
     "react-native": "0.74.6",
-    "react-native-keyboard-controller": "^1.15.2",
+    "react-native-keyboard-controller": "^1.16.3",
     "react-native-phone-number-input": "^2.1.0",
     "react-native-reanimated-carousel": "^3.5.1",
     "react-native-url-polyfill": "^1.3.0",
diff --git a/core/screens/act/__tests__/ActHome.test.tsx b/core/screens/act/__tests__/ActHome.test.tsx
index 1bfa02e0754cf0e4b706d0f92aab67f0e7cda331..65015dc3427fc4e4f7d985c51557ffe3937c1896 100644
--- a/core/screens/act/__tests__/ActHome.test.tsx
+++ b/core/screens/act/__tests__/ActHome.test.tsx
@@ -10,6 +10,7 @@ jest.mock('@holi/core/tracking/PosthogCrossPlatform', () => ({
 }))
 
 jest.mock('@holi/core/navigation/hooks/useParam')
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 const mockActSection = jest.fn()
 jest.mock('@holi/core/screens/act/ActSection', () => {
diff --git a/core/screens/chat/ChatHome.tsx b/core/screens/chat/ChatHome.tsx
index 36a4325a27088de66a437655034455b846dee2fb..1f5ff6cd0a8c370e34f0e309f3678b1e35d01ce7 100644
--- a/core/screens/chat/ChatHome.tsx
+++ b/core/screens/chat/ChatHome.tsx
@@ -47,11 +47,11 @@ const ChatHome = () => {
       headerRight: () => <NotificationAndSearchHeader />,
     })
   }, [navigate, setScreenOptions, t, title, colors.background20])
-  if (chatFeatureFlag.inMaintenance) {
+  if (chatFeatureFlag.inMaintenance || chatFeatureFlag.isOff) {
     return <ChatMaintenance />
   } else if (chatFeatureFlag.isOn) {
     return <ChatHomeContent />
-  } else {
+  } else if (chatFeatureFlag.isUnknown) {
     // unknown status (= missing feature toggle) || disabled
     return (
       <ScrollView style={{ backgroundColor: colors.background20 }}>
diff --git a/core/screens/chat/ChatRoomView.tsx b/core/screens/chat/ChatRoomView.tsx
index a9fdfaab331d3d3f2b2b6b41d7fbae5c784721ee..247be363ab73bbe0e1004548b6a1eef8663dd10d 100644
--- a/core/screens/chat/ChatRoomView.tsx
+++ b/core/screens/chat/ChatRoomView.tsx
@@ -2,7 +2,7 @@ import { useAtomValue } from 'jotai'
 import React, { useCallback, useEffect, useMemo } from 'react'
 import { useTranslation } from 'react-i18next'
 // eslint-disable-next-line no-restricted-imports
-import { Keyboard, Platform, SafeAreaView, View } from 'react-native'
+import { Keyboard, Platform } from 'react-native'
 
 import { useChatInitialized } from '@holi/chat/src/client/chatState'
 import ChatProfileCard from '@holi/chat/src/components/ChatProfileCard'
@@ -26,22 +26,15 @@ import { useLoggedInUser } from '@holi/core/auth/hooks/useLoggedInUser'
 import PermissionsGuard, { PermissionsType } from '@holi/core/components/PermissionsGuard'
 import { logError } from '@holi/core/errors/helpers'
 import { getInitials } from '@holi/core/helpers'
-import useIsomorphicLayoutEffect from '@holi/core/helpers/useIsomorphicLayoutEffect'
 import { useShowHeaderOnScreenFocus } from '@holi/core/helpers/useShowHeaderOnScreenFocus'
 import HeaderBackButton from '@holi/core/navigation/components/HeaderBackButton'
 import createParamHooks from '@holi/core/navigation/hooks/useParam'
 import useRouting from '@holi/core/navigation/hooks/useRouting'
-import { useSetScreenOptions } from '@holi/core/navigation/hooks/useScreenOptions'
-import HoliContainer from '@holi/ui/components/atoms/HoliContainer'
-import { HoliTransition } from '@holi/ui/components/atoms/HoliTransition'
 import HoliLoader from '@holi/ui/components/molecules/HoliLoader'
 import { HoliToastType, useToast } from '@holi/ui/components/molecules/HoliToastProvider'
-import HoliKeyboardSafeAreaView from '@holi/ui/components/organisms/HoliKeyboardSafeAreaView'
-import { dimensions } from '@holi/ui/styles/globalVars'
-import { useStyles } from 'holi-bricks/hooks'
 import { TrackingEvent } from '@holi/core/tracking'
 import useTracking from '@holi/core/tracking/hooks/useTracking'
-import { createStyleSheet } from 'holi-bricks/utils'
+import { Screen } from '@holi/core/components/Screen'
 
 const WAIT_FOR_CHATROOM_DELAY = 5000
 
@@ -51,13 +44,13 @@ export type ChatRoomPageParams = {
 
 const { useParam } = createParamHooks<ChatRoomPageParams>()
 
-const NUMBER_OF_TEXT_MESSAGES_NEEDED_TO_FILL_A_SCREEN_AND_CAUSE_SCROLLBARS = 40
+// number of text messages needed to fill a screen and cause scrollbars
+const NUMBER_OF_INITIAL_MSGS = 40
 
 const ChatRoomView = () => {
   const { t } = useTranslation()
   const { navigateBack, replaceRoute } = useRouting()
   const chatInitialized = useChatInitialized()
-  const { styles } = useStyles(stylesheet)
   const { track } = useTracking()
 
   const [roomId = ''] = useParam('roomId')
@@ -65,8 +58,7 @@ const ChatRoomView = () => {
   const { user: loggedInUser } = useLoggedInUser()
   const chatPartner = useAtomValue(useMemo(() => chatPartnerAtomCreator(roomId, loggedInUser), [loggedInUser, roomId]))
 
-  const requestMessages = useRequestRoomMessages(NUMBER_OF_TEXT_MESSAGES_NEEDED_TO_FILL_A_SCREEN_AND_CAUSE_SCROLLBARS)
-  const setScreenOptions = useSetScreenOptions()
+  const requestMessages = useRequestRoomMessages(NUMBER_OF_INITIAL_MSGS)
 
   const roomMemberIds = room?.members.map((m) => m.id) ?? []
   const { matrixIdToHoliUserRecord, loading: loadingUsers } = useMatrixIdToHoliUserRecord(roomMemberIds)
@@ -97,62 +89,44 @@ const ChatRoomView = () => {
     }
   }, [navigateBack, roomId])
 
-  useIsomorphicLayoutEffect(() => {
-    setScreenOptions({
-      headerRight: () =>
-        !!chatPartner &&
-        !isSpaceRoom && (
-          <ChatRoomActionDrawer
-            roomId={roomId}
-            chatPartner={chatPartner}
-            chatPartnerFullName={chatPartnerHoliUser?.fullName ?? chatPartner.name}
+  const headerTitle = () => {
+    if (loadingUsers) return null
+    switch (room?.type) {
+      case 'private':
+        return chatPartnerHoliUser ? (
+          <ChatRoomHeaderTitle
+            href={'/profile/' + chatPartnerHoliUser.id}
+            name={room.name}
+            imageSrc={chatPartner?.avatar}
+            imageBlurhash={chatPartnerHoliUser.avatarBlurhash}
+            initials={getChatInitials(chatPartner?.name)}
+            defaultColor={getDefaultAvatarColor(chatPartner?.name)}
           />
-        ),
-      headerLeft: ({ tintColor }) => <HeaderBackButton tintColor={tintColor} onPress={handleBackPress} />,
-      headerTitle: () => {
-        if (loadingUsers) return null
-
-        switch (room?.type) {
-          case 'private':
-            return chatPartnerHoliUser ? (
-              <ChatRoomHeaderTitle
-                href={'/profile/' + chatPartnerHoliUser.id}
-                name={room.name}
-                imageSrc={chatPartner?.avatar}
-                imageBlurhash={chatPartnerHoliUser.avatarBlurhash}
-                initials={getChatInitials(chatPartner?.name)}
-                defaultColor={getDefaultAvatarColor(chatPartner?.name)}
-              />
-            ) : (
-              <ChatRoomHeaderTitle
-                name={room.name}
-                imageSrc={chatPartner?.avatar}
-                initials={getChatInitials(chatPartner?.name)}
-                defaultColor={getDefaultAvatarColor(chatPartner?.name)}
-              />
-            )
-
-          case 'space.child':
-            return (
-              <ChatRoomHeaderTitle
-                href={'/spaces/' + room.content.holiSpaceId}
-                name={room.content.spaceName}
-                initials={getInitials(room.content.spaceName)}
-                imageSrc={room.avatar}
-                defaultColor={room.content.avatarDefaultColor}
-                shape="square"
-              />
-            )
+        ) : (
+          <ChatRoomHeaderTitle
+            name={room.name}
+            imageSrc={chatPartner?.avatar}
+            initials={getChatInitials(chatPartner?.name)}
+            defaultColor={getDefaultAvatarColor(chatPartner?.name)}
+          />
+        )
+
+      case 'space.child':
+        return (
+          <ChatRoomHeaderTitle
+            href={'/spaces/' + room.content.holiSpaceId}
+            name={room.content.spaceName}
+            initials={getInitials(room.content.spaceName)}
+            imageSrc={room.avatar}
+            defaultColor={room.content.avatarDefaultColor}
+            shape="square"
+          />
+        )
 
-          default:
-            return null
-        }
-      },
-      navigationCustomOptions: {
-        footerShown: false,
-      },
-    })
-  }, [handleBackPress, chatPartner, setScreenOptions, chatPartnerHoliUser, roomId, room, isSpaceRoom, t, loadingUsers])
+      default:
+        return null
+    }
+  }
 
   useEffect(() => {
     if (chatInitialized && !room) {
@@ -208,95 +182,66 @@ const ChatRoomView = () => {
   if (!chatInitialized || !room || loadingUsers) return <HoliLoader testID={'chat-room-loader'} />
 
   return (
-    <HoliKeyboardSafeAreaView>
-      <View style={styles.layoutWrapper}>
-        <PermissionsGuard permissionType={PermissionsType.AUTH} redirectRoute="/chat">
-          <HoliTransition.Fade visible style={{ flex: 1 }}>
-            <SafeAreaView style={styles.safeArea}>
-              <View style={styles.container}>
-                <View style={styles.listContainer}>
-                  {room.hasInvitation ? (
-                    <ChatProfileCard
-                      member={chatPartner}
-                      roomId={roomId}
-                      user={chatPartnerHoliUser}
-                      userIsLoading={loadingUsers}
-                    />
-                  ) : (
-                    <RoomMessageList
-                      roomId={room.id}
-                      messages={messages || []}
-                      matrixIdToHoliUserRecord={matrixIdToHoliUserRecord}
-                      starter={
-                        amIRoomCreator &&
-                        chatPartnerHoliUser && (
-                          <View style={styles.listStage}>
-                            <RoomMessageListStart member={chatPartner} chatPartnerHoliUser={chatPartnerHoliUser} />
-                          </View>
-                        )
-                      }
-                      onScroll={({ nativeEvent: { contentOffset, contentSize, layoutMeasurement } }) => {
-                        const needToLoad = contentSize.height - contentOffset.y < layoutMeasurement.height * 2
-
-                        if (needToLoad) {
-                          requestMessages(roomId, false)
-                        }
-                      }}
-                    />
-                  )}
-                </View>
-
-                <HoliContainer noPadding>
-                  <ChatTextInput
-                    isVisible={!room.hasInvitation}
-                    userName={chatPartnerHoliUser?.fullName}
-                    roomId={roomId}
-                    onMessageSent={sendTrackingEvent}
-                  />
-                </HoliContainer>
-              </View>
-            </SafeAreaView>
-          </HoliTransition.Fade>
-        </PermissionsGuard>
-      </View>
-    </HoliKeyboardSafeAreaView>
+    <PermissionsGuard permissionType={PermissionsType.AUTH} redirectRoute="/chat">
+      <Screen
+        preset="fixed"
+        keyboardVerticalOffset={Platform.OS == 'ios' ? 168 : undefined} //FIXME: This is needed cause of a bug inside screen component that must be addressed.
+        StickyBottomComponent={
+          <ChatTextInput
+            isVisible={!room.hasInvitation}
+            userName={chatPartnerHoliUser?.fullName}
+            roomId={roomId}
+            onMessageSent={sendTrackingEvent}
+          />
+        }
+        contentContainerStyle={{ flex: 1 }}
+        headerOptions={{
+          headerTitle,
+          headerLeft: ({ tintColor }) => <HeaderBackButton tintColor={tintColor} onPress={handleBackPress} />,
+          headerRight: () =>
+            !!chatPartner &&
+            !isSpaceRoom && (
+              <ChatRoomActionDrawer
+                roomId={roomId}
+                chatPartner={chatPartner}
+                chatPartnerFullName={chatPartnerHoliUser?.fullName ?? chatPartner.name}
+              />
+            ),
+          navigationCustomOptions: {
+            footerShown: false,
+          },
+        }}
+      >
+        {room.hasInvitation ? (
+          <ChatProfileCard
+            member={chatPartner}
+            roomId={roomId}
+            user={chatPartnerHoliUser}
+            userIsLoading={loadingUsers}
+          />
+        ) : (
+          <RoomMessageList
+            roomId={room.id}
+            messages={messages || []}
+            matrixIdToHoliUserRecord={matrixIdToHoliUserRecord}
+            starter={
+              amIRoomCreator &&
+              chatPartnerHoliUser && (
+                <RoomMessageListStart member={chatPartner} chatPartnerHoliUser={chatPartnerHoliUser} />
+              )
+            }
+            onScroll={({ nativeEvent: { contentOffset, contentSize, layoutMeasurement } }) => {
+              const needToLoad = contentSize.height - contentOffset.y < layoutMeasurement.height * 2
+
+              if (needToLoad) {
+                requestMessages(roomId, false)
+              }
+            }}
+          />
+        )}
+      </Screen>
+    </PermissionsGuard>
   )
 }
 
 export default ChatRoomView
-
-const stylesheet = createStyleSheet((theme) => ({
-  layoutWrapper: {
-    ...Platform.select({
-      web: {
-        height: '100%',
-      },
-      native: {
-        flex: 1,
-      },
-    }),
-  },
-  safeArea: {
-    flex: 1,
-  },
-  headerTitle: {
-    alignItems: 'center',
-    flexDirection: 'row',
-    gap: 8,
-  },
-  container: {
-    flex: 1,
-    alignItems: 'center',
-    backgroundColor: theme.colors.bg.container,
-  },
-  listContainer: {
-    flex: 1,
-    height: '100%',
-    width: '100%',
-  },
-  listStage: {
-    alignSelf: 'center',
-    paddingHorizontal: 16,
-    maxWidth: dimensions.maxScreenWidth,
-  },
-}))
diff --git a/core/screens/comments/components/CommentText.tsx b/core/screens/comments/components/CommentText.tsx
index 2b00d4381e4b28e7f88b1b66ff36f4886bc02c04..d1caa55ac89d3dd04748b47c5cfcc684ab9d1196 100644
--- a/core/screens/comments/components/CommentText.tsx
+++ b/core/screens/comments/components/CommentText.tsx
@@ -2,12 +2,11 @@ import React, { useState } from 'react'
 import { useTranslation } from 'react-i18next'
 
 import HoliTranslate from '@holi/core/components/HoliTranslate'
-import { Comment } from '@holi/core/screens/comments/types'
+import type { Comment } from '@holi/core/screens/comments/types'
 import { TrackingEvent } from '@holi/core/tracking'
-import { HoliTextProps } from '@holi/ui/components/atoms/HoliText'
-import HoliRichTextOutput from '@holi/ui/components/organisms/HoliRichTextOutput'
+import HoliRichTextOutput, { type HoliRichTextProps } from '@holi/ui/components/organisms/HoliRichTextOutput'
 
-type CommentTextProps = HoliTextProps & {
+type CommentTextProps = Omit<HoliRichTextProps, 'text'> & {
   comment: Comment
   linkMentionsToProfile?: boolean
 }
@@ -22,9 +21,9 @@ const CommentText = ({ comment, ...textProps }: CommentTextProps) => {
   return (
     <>
       <HoliRichTextOutput
+        {...textProps}
         text={text}
         users={comment.mentions || []}
-        {...textProps}
         allowAllLinks
         loading={loadingTranslation}
         skeletonOptions={{ numberOfLines: 3 }}
diff --git a/core/screens/individualPosts/components/GenericPostCard.tsx b/core/screens/individualPosts/components/GenericPostCard.tsx
index 3f9280a0d1dd9c25cbcb6bdba05d554eb819bdc0..517b07548381814e12efb290c2beb15e72eaed7e 100644
--- a/core/screens/individualPosts/components/GenericPostCard.tsx
+++ b/core/screens/individualPosts/components/GenericPostCard.tsx
@@ -171,7 +171,7 @@ const GenericPostCard = ({ post, showVisibilityBadge, allTopics }: GenericPostCa
               onPressText={() => {
                 goToDetailView()
               }}
-              color="gray300"
+              color="support"
               users={feedPost.mentionedUsers}
             />
           </HoliReadMore>
@@ -327,7 +327,7 @@ const GenericPostCard = ({ post, showVisibilityBadge, allTopics }: GenericPostCa
               onPressText={() => {
                 goToDetailView()
               }}
-              color="gray300"
+              color="support"
               users={spacePost.mentions}
             />
           </HoliReadMore>
diff --git a/core/screens/individualPosts/components/PostCard.tsx b/core/screens/individualPosts/components/PostCard.tsx
index f08a09e67a43cead804bfbafbe77706013ad4bbe..04345efa3bc49d35da71dc002e8205b34b2b4fd0 100644
--- a/core/screens/individualPosts/components/PostCard.tsx
+++ b/core/screens/individualPosts/components/PostCard.tsx
@@ -5,11 +5,11 @@ import { StyleSheet, View } from 'react-native'
 
 import { useLoggedInUser } from '@holi/core/auth/hooks/useLoggedInUser'
 import HoliMediaAuthorHeader from '@holi/core/components/HoliMediaAuthorHeader'
-import { Term, User } from '@holi/core/domain/shared/types'
+import type { Term, User } from '@holi/core/domain/shared/types'
 import useRouting from '@holi/core/navigation/hooks/useRouting'
 import FeedPostReactions from '@holi/core/screens/individualPosts/components/FeedPostReactions'
 import PostDrawer from '@holi/core/screens/individualPosts/components/PostDrawer'
-import { FeedPost, VisibilityLevel } from '@holi/core/screens/individualPosts/types'
+import { type FeedPost, VisibilityLevel } from '@holi/core/screens/individualPosts/types'
 import { TrackingEvent } from '@holi/core/tracking'
 import useTracking from '@holi/core/tracking/hooks/useTracking'
 import { HoliIcon } from '@holi/icons/src/HoliIcon'
@@ -24,7 +24,7 @@ import HoliRichTextOutput from '@holi/ui/components/organisms/HoliRichTextOutput
 import HoliUserAvatarPile from '@holi/ui/components/organisms/HoliUserAvatarPile'
 import Spacing from '@holi/ui/foundations/Spacing'
 import { colors } from '@holi/ui/styles/globalVars'
-import { HoliTheme, useTheme } from '@holi/ui/styles/theme'
+import { type HoliTheme, useTheme } from '@holi/ui/styles/theme'
 
 type PostCardProps = {
   post: FeedPost
@@ -118,7 +118,7 @@ const PostCard = ({ post, showVisibilityBadge, allTopics }: PostCardProps) => {
             onPressText={() => {
               goToDetailView()
             }}
-            color="gray300"
+            color="support"
             users={post.mentionedUsers}
           />
         </HoliReadMore>
diff --git a/core/screens/insights/discussions/DiscussionCard.tsx b/core/screens/insights/discussions/DiscussionCard.tsx
index 4b41c51f03748e20c64b4b0f0629f4e522992148..c41c63e0554aa1f0aaecca0b1656ca49b3204a3a 100644
--- a/core/screens/insights/discussions/DiscussionCard.tsx
+++ b/core/screens/insights/discussions/DiscussionCard.tsx
@@ -94,8 +94,8 @@ const DiscussionCard = ({ discussion, insightId }: DiscussionCardProps) => {
                   </HoliText>
                   <CommentText
                     comment={topComment}
-                    size="small"
-                    color="gray300"
+                    size="sm"
+                    color="support"
                     numberOfLines={2}
                     linkMentionsToProfile={false}
                   />
diff --git a/core/screens/notifications/components/__tests__/NotificationsOverview.test.tsx b/core/screens/notifications/components/__tests__/NotificationsOverview.test.tsx
index c3b85ce0def6ec5ddff08f6093c583f3458efd1a..765760969da595f152e4a433f251dd41a22d5a93 100644
--- a/core/screens/notifications/components/__tests__/NotificationsOverview.test.tsx
+++ b/core/screens/notifications/components/__tests__/NotificationsOverview.test.tsx
@@ -25,6 +25,7 @@ const loggedOut = (): LoginState => ({
 })
 const useLoginStateMock = useLoginState as jest.Mock
 const mockUseNotifications = jest.fn()
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 jest.mock('@holi/core/auth/loginState', () => ({
   useLoginState: jest.fn(),
diff --git a/core/screens/onboarding/__tests__/Onboarding.test.tsx b/core/screens/onboarding/__tests__/Onboarding.test.tsx
index e679d438682664a11ae7c9b7e7811cb5e6df477a..596efdbad94ca8e05793165fce3877946af67db8 100644
--- a/core/screens/onboarding/__tests__/Onboarding.test.tsx
+++ b/core/screens/onboarding/__tests__/Onboarding.test.tsx
@@ -36,6 +36,7 @@ const mockUseRedirect = useRedirect as jest.Mock
 jest.mock('@holi/core/navigation/hooks/useRedirect', () => ({
   useRedirect: jest.fn(),
 }))
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 const mockUseTracking = useTracking as jest.Mock
 jest.mock('@holi/core/tracking/hooks/useTracking', () => jest.fn())
diff --git a/core/screens/polls/components/PollResults.tsx b/core/screens/polls/components/PollResults.tsx
index c16696dc37c78e2a7613b0891377884ef0b22a39..7df6bbc4cbd48be1d2a8977f65b7c77287cf989f 100644
--- a/core/screens/polls/components/PollResults.tsx
+++ b/core/screens/polls/components/PollResults.tsx
@@ -1,10 +1,11 @@
 import React, { useMemo, useRef } from 'react'
 import { Animated, StyleSheet, View } from 'react-native'
 
-import { Choice } from '@holi/core/screens/polls/types'
-import HoliText from '@holi/ui/components/atoms/HoliText'
+import type { Choice } from '@holi/core/screens/polls/types'
 import HoliRichTextOutput from '@holi/ui/components/organisms/HoliRichTextOutput'
-import { HoliTheme, useTheme } from '@holi/ui/styles/theme'
+import { type HoliTheme, useTheme } from '@holi/ui/styles/theme'
+import { Text } from 'holi-bricks/components/text'
+import Spacing from '@holi/ui/foundations/Spacing'
 
 interface PollResultsProps {
   choice: Choice
@@ -35,11 +36,11 @@ const PollResults = ({ choice, votesSum, selected }: PollResultsProps) => {
           users={[]}
           links={[]}
           allowAllLinks
-          size="small"
+          size="sm"
         />
-        <HoliText style={styles.percentText} size="small" testID="poll-result-percentage">
+        <Text size="sm" testID="poll-result-percentage">
           {percentage}%
-        </HoliText>
+        </Text>
       </View>
       <View style={styles.progressBar}>
         <Animated.View style={{ ...styles.innerBar, width: progressWidth }} />
@@ -63,6 +64,7 @@ const getStyles = (theme: HoliTheme) =>
       alignItems: 'flex-start',
       flex: 1,
       marginBottom: 5,
+      gap: Spacing['lg'],
     },
     optionsTextStyle: {
       flexWrap: 'wrap',
@@ -84,11 +86,6 @@ const getStyles = (theme: HoliTheme) =>
       backgroundColor: theme.colors.brandColorB30,
       borderRadius: 12,
     },
-    percentText: {
-      fontSize: 14,
-      marginLeft: 30,
-      color: theme.colors.foreground30,
-    },
   })
 
 export default PollResults
diff --git a/core/screens/polls/components/PollSelection.tsx b/core/screens/polls/components/PollSelection.tsx
index 4f39f9218fddabf614332b30e5efe1fe0a20d985..4e8d2d914e83953c8a566f33cf88baf6a0958233 100644
--- a/core/screens/polls/components/PollSelection.tsx
+++ b/core/screens/polls/components/PollSelection.tsx
@@ -1,12 +1,12 @@
 import React, { useCallback, useMemo, useState } from 'react'
 import { Platform, StyleSheet, View } from 'react-native'
 
-import { Choice } from '@holi/core/screens/polls/types'
+import type { Choice } from '@holi/core/screens/polls/types'
 import HoliBox from '@holi/ui/components/atoms/HoliBox'
 import HoliButton from '@holi/ui/components/molecules/HoliButton'
 import HoliCheckbox from '@holi/ui/components/molecules/HoliCheckbox'
 import HoliRichTextOutput from '@holi/ui/components/organisms/HoliRichTextOutput'
-import { HoliTheme, useTheme } from '@holi/ui/styles/theme'
+import { type HoliTheme, useTheme } from '@holi/ui/styles/theme'
 
 export type PollSelectionProps = {
   answerOptions: Choice[]
@@ -49,7 +49,7 @@ const PollSelection = ({ answerOptions, onSelected }: PollSelectionProps) => {
             />
           </HoliBox>
           <View style={[styles.userItemContent]}>
-            <HoliRichTextOutput text={answer.choiceText} users={[]} links={[]} allowAllLinks size="small" />
+            <HoliRichTextOutput text={answer.choiceText} users={[]} links={[]} allowAllLinks size="sm" />
           </View>
         </HoliButton>
       </View>
diff --git a/core/screens/polls/components/__tests__/__snapshots__/PollResults.test.tsx.snap b/core/screens/polls/components/__tests__/__snapshots__/PollResults.test.tsx.snap
index 0b3799c4e722835d4f646b493d8eb57d92cef3ff..f0bb384fe33cb2b6475f2055cdfb23e55763bfe9 100644
--- a/core/screens/polls/components/__tests__/__snapshots__/PollResults.test.tsx.snap
+++ b/core/screens/polls/components/__tests__/__snapshots__/PollResults.test.tsx.snap
@@ -20,31 +20,28 @@ exports[`PollResults renders correctly as expected 1`] = `
         "alignItems": "flex-start",
         "flex": 1,
         "flexDirection": "row",
+        "gap": 32,
         "marginBottom": 5,
       }
     }
   >
     <Text
       accessible={false}
-      collapsable={false}
-      jestAnimatedStyle={
-        {
-          "value": {},
-        }
-      }
-      numberOfLines={2}
+      role="none"
       selectable={true}
       style={
         {
-          "color": "#262424",
-          "flexWrap": "wrap",
+          "color": "#676565",
           "fontFamily": "InstrumentSans-Regular",
-          "fontSize": 14,
+          "fontSize": 15,
+          "fontVariant": [
+            "lining-nums",
+            "tabular-nums",
+          ],
           "fontWeight": "400",
-          "lineHeight": 19.599999999999998,
-          "marginRight": "auto",
-          "maxWidth": "80%",
-          "paddingRight": "auto",
+          "letterSpacing": -0.12,
+          "lineHeight": 21,
+          "textAlign": undefined,
           "userSelect": "auto",
         }
       }
@@ -53,21 +50,21 @@ exports[`PollResults renders correctly as expected 1`] = `
     </Text>
     <Text
       accessible={false}
-      collapsable={false}
-      jestAnimatedStyle={
-        {
-          "value": {},
-        }
-      }
+      role="none"
       selectable={true}
       style={
         {
           "color": "#262424",
           "fontFamily": "InstrumentSans-Regular",
-          "fontSize": 14,
+          "fontSize": 15,
+          "fontVariant": [
+            "lining-nums",
+            "tabular-nums",
+          ],
           "fontWeight": "400",
-          "lineHeight": 19.599999999999998,
-          "marginLeft": 30,
+          "letterSpacing": -0.12,
+          "lineHeight": 21,
+          "textAlign": undefined,
           "userSelect": "auto",
         }
       }
diff --git a/core/screens/polls/components/__tests__/__snapshots__/PollSelection.test.tsx.snap b/core/screens/polls/components/__tests__/__snapshots__/PollSelection.test.tsx.snap
index 8f05f9db25dd70e6fb64233d4b9441dbf41c3dce..0aa3171ac6d36e057b9138cc8c8e356c43fe3edc 100644
--- a/core/screens/polls/components/__tests__/__snapshots__/PollSelection.test.tsx.snap
+++ b/core/screens/polls/components/__tests__/__snapshots__/PollSelection.test.tsx.snap
@@ -166,20 +166,21 @@ exports[`PollSelection renders poll selection correctly 1`] = `
         >
           <Text
             accessible={false}
-            collapsable={false}
-            jestAnimatedStyle={
-              {
-                "value": {},
-              }
-            }
+            role="none"
             selectable={true}
             style={
               {
-                "color": "#262424",
+                "color": "#676565",
                 "fontFamily": "InstrumentSans-Regular",
-                "fontSize": 14,
+                "fontSize": 15,
+                "fontVariant": [
+                  "lining-nums",
+                  "tabular-nums",
+                ],
                 "fontWeight": "400",
-                "lineHeight": 19.599999999999998,
+                "letterSpacing": -0.12,
+                "lineHeight": 21,
+                "textAlign": undefined,
                 "userSelect": "auto",
               }
             }
@@ -354,20 +355,21 @@ exports[`PollSelection renders poll selection correctly 1`] = `
         >
           <Text
             accessible={false}
-            collapsable={false}
-            jestAnimatedStyle={
-              {
-                "value": {},
-              }
-            }
+            role="none"
             selectable={true}
             style={
               {
-                "color": "#262424",
+                "color": "#676565",
                 "fontFamily": "InstrumentSans-Regular",
-                "fontSize": 14,
+                "fontSize": 15,
+                "fontVariant": [
+                  "lining-nums",
+                  "tabular-nums",
+                ],
                 "fontWeight": "400",
-                "lineHeight": 19.599999999999998,
+                "letterSpacing": -0.12,
+                "lineHeight": 21,
+                "textAlign": undefined,
                 "userSelect": "auto",
               }
             }
@@ -548,20 +550,21 @@ exports[`PollSelection renders poll selection correctly with one option 1`] = `
       >
         <Text
           accessible={false}
-          collapsable={false}
-          jestAnimatedStyle={
-            {
-              "value": {},
-            }
-          }
+          role="none"
           selectable={true}
           style={
             {
-              "color": "#262424",
+              "color": "#676565",
               "fontFamily": "InstrumentSans-Regular",
-              "fontSize": 14,
+              "fontSize": 15,
+              "fontVariant": [
+                "lining-nums",
+                "tabular-nums",
+              ],
               "fontWeight": "400",
-              "lineHeight": 19.599999999999998,
+              "letterSpacing": -0.12,
+              "lineHeight": 21,
+              "textAlign": undefined,
               "userSelect": "auto",
             }
           }
diff --git a/core/screens/posts/components/PostPreview.tsx b/core/screens/posts/components/PostPreview.tsx
index 51f1b40a23bbfa93f05564fe4ca2ba56de32764d..0eb0b2894df7abe71839268420a940b46436c994 100644
--- a/core/screens/posts/components/PostPreview.tsx
+++ b/core/screens/posts/components/PostPreview.tsx
@@ -235,8 +235,7 @@ const PostPreview = ({
               users={post?.mentions || []}
               links={post?.links || []}
               allowAllLinks
-              size="default"
-              color="gray300"
+              color="default"
             />
           </HoliReadMore>
         )}
diff --git a/core/screens/search/typesense/Search.tsx b/core/screens/search/typesense/Search.tsx
index 49b3b649aa7709e32e649669869c9fae45d74790..a79b8007fe27f1c009e82588655d8b0e98e69607 100644
--- a/core/screens/search/typesense/Search.tsx
+++ b/core/screens/search/typesense/Search.tsx
@@ -65,7 +65,6 @@ export const Search = () => {
       <Screen
         backgroundColor="page"
         preset="fixed"
-        contentContainerPadding={{}}
         contentContainerStyle={{ flex: 1 }} // this is needed because flash list has no initial size, it calculates it while rendering.
         style={styles.screen}
         headerOptions={{
diff --git a/core/screens/spaces/appointments/AppointmentDetails.tsx b/core/screens/spaces/appointments/AppointmentDetails.tsx
index 849627efc31bc539e0431d9bff97bc5c5176b651..43aa3ca1e233a704b3ea5f270d478c92b71e03e4 100644
--- a/core/screens/spaces/appointments/AppointmentDetails.tsx
+++ b/core/screens/spaces/appointments/AppointmentDetails.tsx
@@ -320,8 +320,8 @@ const AppointmentDetails = () => {
           <HoliRichTextOutput
             style={styles.description}
             text={appointment.description}
-            color="gray300"
-            size="small"
+            color="support"
+            size="sm"
             allowAllLinks
             testID="appointment-description"
           />
diff --git a/core/screens/spaces/details/__tests__/SpaceDetails.test.tsx b/core/screens/spaces/details/__tests__/SpaceDetails.test.tsx
index d98faf6196cc7a81a04ddff69d7fe3f7416a504b..14d7f7b1bac91d8570dafd70a998b90b71e7d109 100644
--- a/core/screens/spaces/details/__tests__/SpaceDetails.test.tsx
+++ b/core/screens/spaces/details/__tests__/SpaceDetails.test.tsx
@@ -72,6 +72,9 @@ jest.mock('@holi/core/featureFlags/hooks/useFeatureFlag', () => ({
   useFeatureFlag: (flag: FeatureFlagKey) => mockUseFeatureFlag(flag),
 }))
 
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
+jest.useFakeTimers()
+
 jest.mock('@holi/core/navigation/hooks/useParam')
 
 describe('SpaceDetails', () => {
diff --git a/core/screens/spaces/details/components/__tests__/SpaceFollow.test.tsx b/core/screens/spaces/details/components/__tests__/SpaceFollow.test.tsx
index c14ab059ac59157e26e9a47020718b8233c0a569..f72c61b65ef0f7a090a9a0f71576e92d6cebf395 100644
--- a/core/screens/spaces/details/components/__tests__/SpaceFollow.test.tsx
+++ b/core/screens/spaces/details/components/__tests__/SpaceFollow.test.tsx
@@ -2,7 +2,7 @@ import { MockedProvider } from '@apollo/client/testing'
 import { fireEvent, render, screen, waitFor } from '@testing-library/react-native'
 import React from 'react'
 
-import { LoginState } from '@holi/core/auth/loginState'
+import type { LoginState } from '@holi/core/auth/loginState'
 import { authenticatedUserV2Query } from '@holi/core/domain/shared/queries'
 import { mockParameters } from '@holi/core/navigation/hooks/useParam/__mocks__/mockParameters'
 import { space } from '@holi/core/screens/spaces/__tests__/testData'
@@ -24,6 +24,7 @@ jest.mock('@holi/core/errors/hooks/useErrorHandling', () => ({
     displayError: jest.fn(),
   }),
 }))
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 const authenticatedUserRequest = {
   request: {
diff --git a/core/screens/spaces/details/components/__tests__/__snapshots__/SpaceInvolvement.test.tsx.snap b/core/screens/spaces/details/components/__tests__/__snapshots__/SpaceInvolvement.test.tsx.snap
index 3395ef5373c8983e16ef10dd531dcaf5efc0ffd7..84a383e35c676d216daa22e4a9a227e7bbc1ba88 100644
--- a/core/screens/spaces/details/components/__tests__/__snapshots__/SpaceInvolvement.test.tsx.snap
+++ b/core/screens/spaces/details/components/__tests__/__snapshots__/SpaceInvolvement.test.tsx.snap
@@ -784,20 +784,21 @@ exports[`SpaceInvolvement renders correctly for the public 1`] = `
                   />
                   <Text
                     accessible={false}
-                    collapsable={false}
-                    jestAnimatedStyle={
-                      {
-                        "value": {},
-                      }
-                    }
+                    role="none"
                     selectable={true}
                     style={
                       {
-                        "color": "#262424",
+                        "color": "#676565",
                         "fontFamily": "InstrumentSans-Regular",
-                        "fontSize": 14,
+                        "fontSize": 15,
+                        "fontVariant": [
+                          "lining-nums",
+                          "tabular-nums",
+                        ],
                         "fontWeight": "400",
-                        "lineHeight": 19.599999999999998,
+                        "letterSpacing": -0.12,
+                        "lineHeight": 21,
+                        "textAlign": undefined,
                         "userSelect": "auto",
                       }
                     }
@@ -1489,20 +1490,21 @@ exports[`SpaceInvolvement renders correctly for the public 1`] = `
                   />
                   <Text
                     accessible={false}
-                    collapsable={false}
-                    jestAnimatedStyle={
-                      {
-                        "value": {},
-                      }
-                    }
+                    role="none"
                     selectable={true}
                     style={
                       {
-                        "color": "#262424",
+                        "color": "#676565",
                         "fontFamily": "InstrumentSans-Regular",
-                        "fontSize": 14,
+                        "fontSize": 15,
+                        "fontVariant": [
+                          "lining-nums",
+                          "tabular-nums",
+                        ],
                         "fontWeight": "400",
-                        "lineHeight": 19.599999999999998,
+                        "letterSpacing": -0.12,
+                        "lineHeight": 21,
+                        "textAlign": undefined,
                         "userSelect": "auto",
                       }
                     }
diff --git a/core/screens/spaces/discover/__tests__/Spaces.test.tsx b/core/screens/spaces/discover/__tests__/Spaces.test.tsx
index 58ee3080393a13356f8e17ab13f70dfbe1adea7a..cd40db713a0dbec80cc870274971ef241b59c993 100644
--- a/core/screens/spaces/discover/__tests__/Spaces.test.tsx
+++ b/core/screens/spaces/discover/__tests__/Spaces.test.tsx
@@ -27,6 +27,7 @@ const loginStateLoggedIn = {
 jest.mock('@holi/core/auth/hooks/useLoggedInUser', () => ({
   useLoggedInUser: () => loginStateLoggedIn,
 }))
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 jest.mock('@holi/core/helpers/useLogout', () => ({
   useLogout: () => ({ logout: jest.fn() }),
diff --git a/core/screens/spaces/edit/components/__tests__/EditSpaceCollaborators.test.tsx b/core/screens/spaces/edit/components/__tests__/EditSpaceCollaborators.test.tsx
index dc29bba83127a0a8053b15702a0f5326a1518dbc..59b38af08fbe19b0c810092c262da1bf2ac18628 100644
--- a/core/screens/spaces/edit/components/__tests__/EditSpaceCollaborators.test.tsx
+++ b/core/screens/spaces/edit/components/__tests__/EditSpaceCollaborators.test.tsx
@@ -1,5 +1,5 @@
 import { ApolloError } from '@apollo/client'
-import { GraphQLErrors } from '@apollo/client/errors'
+import type { GraphQLErrors } from '@apollo/client/errors'
 import { MockedProvider } from '@apollo/client/testing'
 import { act, render, screen, userEvent, waitFor, waitForElementToBeRemoved } from '@testing-library/react-native'
 import React from 'react'
@@ -18,6 +18,7 @@ import {
 import EditSpaceCollaborators from '@holi/core/screens/spaces/edit/components/EditSpaceCollaborators'
 import { spaceMembershipByIdQuery } from '@holi/core/screens/spaces/queries'
 import { SpaceConnectionType } from '@holi/core/screens/spaces/types'
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 const spaceForAdmin = {
   ...space,
diff --git a/core/screens/spaces/filter/components/__tests__/FilteredSpaces.test.tsx b/core/screens/spaces/filter/components/__tests__/FilteredSpaces.test.tsx
index 6ca704608e1cf6f3217d9ea07ded96feb54b08c2..c220ea0975af12ede00f1492f88d83842c049897 100644
--- a/core/screens/spaces/filter/components/__tests__/FilteredSpaces.test.tsx
+++ b/core/screens/spaces/filter/components/__tests__/FilteredSpaces.test.tsx
@@ -1,8 +1,8 @@
-import { MockedProvider, MockedResponse } from '@apollo/client/testing'
+import { MockedProvider, type MockedResponse } from '@apollo/client/testing'
 import { act, fireEvent, render, screen, waitFor } from '@testing-library/react-native'
 import React from 'react'
 
-import { NavigationRouteContext, Route } from '@react-navigation/native'
+import { NavigationRouteContext, type Route } from '@react-navigation/native'
 
 import { createCache } from '@holi/api/graphql/client'
 import { HoliError } from '@holi/core/errors/classes/HoliError'
@@ -14,6 +14,7 @@ import { spacesQuery } from '@holi/core/screens/spaces/filter/queries'
 import { HoliToastType, ToastProvider } from '@holi/ui/components/molecules/HoliToastProvider'
 
 jest.spyOn(window, 'requestAnimationFrame').mockImplementation(() => Date.now())
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
 
 // prevent logging about incomplete apollo mocks,
 // because we didn't flesh out the response data
diff --git a/core/screens/spaces/tasks/components/SpaceTaskTile/Full.tsx b/core/screens/spaces/tasks/components/SpaceTaskTile/Full.tsx
index 0396429d26c3cff2c70e61edc880ed16d61b7daf..a0f62a7cfe97790187e26b71a505316e428dd92c 100644
--- a/core/screens/spaces/tasks/components/SpaceTaskTile/Full.tsx
+++ b/core/screens/spaces/tasks/components/SpaceTaskTile/Full.tsx
@@ -54,7 +54,7 @@ const List = ({ loading, task, space }: PropsWithSkeleton<BaseProps>) => {
         </HoliLink>
         <HoliGap size={'s'} />
 
-        <Content task={task} richTextOutputColor="gray300" descriptionWithDetails />
+        <Content task={task} richTextOutputColor="support" descriptionWithDetails />
       </HoliCardComponent.ContentContainer>
     </HoliCardComponent.CardContainer>
   )
diff --git a/core/screens/spaces/tasks/components/SpaceTaskTile/components/Content.tsx b/core/screens/spaces/tasks/components/SpaceTaskTile/components/Content.tsx
index 7f491cc4d967bf433b419b2f45a030bcacede3de..448607319b73a2169e63cb332d7bb4271ae6016d 100644
--- a/core/screens/spaces/tasks/components/SpaceTaskTile/components/Content.tsx
+++ b/core/screens/spaces/tasks/components/SpaceTaskTile/components/Content.tsx
@@ -15,22 +15,23 @@ import {
   TimeFilled,
 } from '@holi/icons/src/generated'
 import { HoliGap } from '@holi/ui/components/atoms/HoliGap'
-import HoliText, { type HoliTextProps } from '@holi/ui/components/atoms/HoliText'
+import HoliText from '@holi/ui/components/atoms/HoliText'
 import HoliButton from '@holi/ui/components/molecules/HoliButton'
 import HoliRichTextOutput from '@holi/ui/components/organisms/HoliRichTextOutput'
 import { useTheme } from '@holi/ui/styles/theme'
 import { Avatar } from 'holi-bricks/components/avatar'
+import type { TextColor } from 'holi-bricks/components/text'
 
 export interface Props {
   task: Task
-  richTextOutputColor?: HoliTextProps['color']
+  richTextOutputColor?: TextColor
   descriptionWithDetails?: boolean
   recommendation?: boolean
 }
 
 const Content = ({
   task,
-  richTextOutputColor = 'black300',
+  richTextOutputColor = 'support',
   descriptionWithDetails = false,
   recommendation = false,
 }: Props) => {
@@ -92,7 +93,7 @@ const Content = ({
         {...(recommendation ? { numberOfLines: 2 } : {})}
         text={task.description}
         color={richTextOutputColor}
-        size="small"
+        size="sm"
         allowAllLinks
         testID="task-description"
       />
diff --git a/core/screens/spaces/tasks/components/__tests__/__snapshots__/SpaceTaskList.test.tsx.snap b/core/screens/spaces/tasks/components/__tests__/__snapshots__/SpaceTaskList.test.tsx.snap
index dc7791096da2ae259ca1e1511bdccdab6c707413..c4f61ddd6dbaa8370c09f242bf9461d97e654a75 100644
--- a/core/screens/spaces/tasks/components/__tests__/__snapshots__/SpaceTaskList.test.tsx.snap
+++ b/core/screens/spaces/tasks/components/__tests__/__snapshots__/SpaceTaskList.test.tsx.snap
@@ -649,20 +649,21 @@ exports[`SpaceTaskList renders correctly when there are tasks within space 1`] =
           />
           <Text
             accessible={false}
-            collapsable={false}
-            jestAnimatedStyle={
-              {
-                "value": {},
-              }
-            }
+            role="none"
             selectable={true}
             style={
               {
-                "color": "#262424",
+                "color": "#676565",
                 "fontFamily": "InstrumentSans-Regular",
-                "fontSize": 14,
+                "fontSize": 15,
+                "fontVariant": [
+                  "lining-nums",
+                  "tabular-nums",
+                ],
                 "fontWeight": "400",
-                "lineHeight": 19.599999999999998,
+                "letterSpacing": -0.12,
+                "lineHeight": 21,
+                "textAlign": undefined,
                 "userSelect": "auto",
               }
             }
@@ -1354,20 +1355,21 @@ exports[`SpaceTaskList renders correctly when there are tasks within space 1`] =
           />
           <Text
             accessible={false}
-            collapsable={false}
-            jestAnimatedStyle={
-              {
-                "value": {},
-              }
-            }
+            role="none"
             selectable={true}
             style={
               {
-                "color": "#262424",
+                "color": "#676565",
                 "fontFamily": "InstrumentSans-Regular",
-                "fontSize": 14,
+                "fontSize": 15,
+                "fontVariant": [
+                  "lining-nums",
+                  "tabular-nums",
+                ],
                 "fontWeight": "400",
-                "lineHeight": 19.599999999999998,
+                "letterSpacing": -0.12,
+                "lineHeight": 21,
+                "textAlign": undefined,
                 "userSelect": "auto",
               }
             }
@@ -2059,20 +2061,21 @@ exports[`SpaceTaskList renders correctly when there are tasks within space 1`] =
           />
           <Text
             accessible={false}
-            collapsable={false}
-            jestAnimatedStyle={
-              {
-                "value": {},
-              }
-            }
+            role="none"
             selectable={true}
             style={
               {
-                "color": "#262424",
+                "color": "#676565",
                 "fontFamily": "InstrumentSans-Regular",
-                "fontSize": 14,
+                "fontSize": 15,
+                "fontVariant": [
+                  "lining-nums",
+                  "tabular-nums",
+                ],
                 "fontWeight": "400",
-                "lineHeight": 19.599999999999998,
+                "letterSpacing": -0.12,
+                "lineHeight": 21,
+                "textAlign": undefined,
                 "userSelect": "auto",
               }
             }
diff --git a/global.d.ts b/global.d.ts
index c9d67a6f12a19a933af6d626fd03ccfdabdaafa2..367a01f4bc770f6a5187a126d92be87a10a04419 100644
--- a/global.d.ts
+++ b/global.d.ts
@@ -1,8 +1,8 @@
 /* eslint-disable no-var */
 import type { ScreenOptions } from '@react-navigation/native'
 
-import { TrackingEvent } from '@holi/core/tracking'
-import { HoliToastType } from '@holi/ui/components/molecules/HoliToastProvider'
+import type { TrackingEvent } from '@holi/core/tracking'
+import type { HoliToastType } from '@holi/ui/components/molecules/HoliToastProvider'
 
 declare global {
   var mockNavigate: (routeName: string) => void
diff --git a/holi-apps/volunteering/screens/__tests__/VolunteeringSimilarRecos.test.tsx b/holi-apps/volunteering/screens/__tests__/VolunteeringSimilarRecos.test.tsx
index 736d7ac9c51dc58c27e6f10665a5daad7471e629..94412518c802fd3aeea00883addf057c48b749b9 100644
--- a/holi-apps/volunteering/screens/__tests__/VolunteeringSimilarRecos.test.tsx
+++ b/holi-apps/volunteering/screens/__tests__/VolunteeringSimilarRecos.test.tsx
@@ -1,20 +1,20 @@
 import { render, screen, waitFor } from '@testing-library/react-native'
 import React from 'react'
 
-import { MockedProvider, MockedResponse } from '@apollo/client/testing'
+import { MockedProvider, type MockedResponse } from '@apollo/client/testing'
 import { allSkills, allTopics } from '@holi-apps/volunteering/__tests__/helpers/fixtures'
 import { makeEngagement } from '@holi-apps/volunteering/__tests__/helpers/generators'
 import {
-  AppVolunteeringEngagementByIdResponse,
-  AppVolunteeringEngagementByIdVariables,
-  VolunteeringSimilarRecosQueryResponse,
-  VolunteeringSimilarRecosQueryVariables,
+  type AppVolunteeringEngagementByIdResponse,
+  type AppVolunteeringEngagementByIdVariables,
+  type VolunteeringSimilarRecosQueryResponse,
+  type VolunteeringSimilarRecosQueryVariables,
   engagementByIdQuery,
   trackEngagementViewMutation,
   volunteeringSimilarRecosQuery,
 } from '@holi-apps/volunteering/queries'
 import { ExportedForTesting } from '@holi-apps/volunteering/screens/VolunteeringEngagementDetail'
-import {
+import type {
   AppVolunteering_TrackEngagementViewResponse,
   MutationAppVolunteering_TrackEngagementViewArgs,
 } from '@holi/api/graphql/graphql-codegen'
@@ -23,6 +23,8 @@ import { mockParameters } from '@holi/core/navigation/hooks/useParam/__mocks__/m
 
 const mockEngagementId = '123'
 
+jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
+
 const mockEngagementDetailQuery: MockedResponse<
   AppVolunteeringEngagementByIdResponse,
   AppVolunteeringEngagementByIdVariables
diff --git a/holi-bricks/components/text/Text.tsx b/holi-bricks/components/text/Text.tsx
index b46f357bfa22ddc1fdd7593504cd33142effd156..e5282ad1dde15b87796f31f5889b4536c6d1f9c7 100644
--- a/holi-bricks/components/text/Text.tsx
+++ b/holi-bricks/components/text/Text.tsx
@@ -46,6 +46,7 @@ export interface TextProps {
   textAlign?: TextStyle['textAlign']
   ellipsizeMode?: RNTextProps['ellipsizeMode']
   headingLevel?: TextHeadingLevel
+  testID?: string
 }
 
 // Change import in HOLI-10369
@@ -86,6 +87,7 @@ export const Text = ({
   ellipsizeMode,
   headingLevel,
   children,
+  testID,
   ...rest
 }: React.PropsWithChildren<TextProps>) => {
   const { styles } = useStyles(stylesheet, { size })
@@ -100,6 +102,7 @@ export const Text = ({
     <RNText
       {...textAccessibilityProps}
       {...accessibilityProps(rest)}
+      testID={testID}
       selectable={Platform.OS !== 'web' ? selectable : undefined}
       numberOfLines={numberOfLines}
       ellipsizeMode={ellipsizeMode}
diff --git a/holi-bricks/jest.config.ts b/holi-bricks/jest.config.ts
index 23a4c52c5589dbcf439a1c13a4e1798db55e4d20..f93549688c1b88017b54967357718410391b2d34 100644
--- a/holi-bricks/jest.config.ts
+++ b/holi-bricks/jest.config.ts
@@ -7,9 +7,7 @@ import type { Config } from 'jest'
 const config: Config = {
   preset: 'jest-expo',
   setupFiles: ['<rootDir>/jest.setup.ts'],
-  clearMocks: true,
-  // collectCoverage: true,
-  // coverageDirectory: ".coverage",
+  clearMocks: false,
   testEnvironment: 'jsdom',
   moduleNameMapper: {
     'holi-bricks/(.*)': '<rootDir>/$1',
diff --git a/holi-bricks/utils/index.ts b/holi-bricks/utils/index.ts
index 40cc838f426da58ce24598459ed59845890a835b..71cfa4b074178f1de828b225e4e0823c243f4f3f 100644
--- a/holi-bricks/utils/index.ts
+++ b/holi-bricks/utils/index.ts
@@ -1,3 +1,4 @@
-import { createStyleSheet as unistylesCreateStylesheet } from 'react-native-unistyles'
+import { createStyleSheet as unistylesCreateStylesheet, mq as unistylesMq } from 'react-native-unistyles'
 
 export const createStyleSheet = unistylesCreateStylesheet
+export const mq = unistylesMq
diff --git a/jest.setup.ts b/jest.setup.ts
index 239e42bc8a825fc058a14dc4e786b31700f70bdd..553f12670b5c95267671384ea824602cf297ac75 100644
--- a/jest.setup.ts
+++ b/jest.setup.ts
@@ -5,7 +5,6 @@ import mockSafeAreaContext from 'react-native-safe-area-context/jest/mock'
 
 import i18n from '@holi/core/i18n'
 import type { TrackingEventHandler, TrackingHook } from '@holi/core/tracking/types'
-import { TrackingEvent } from '@holi/core/tracking'
 
 // Added to fix the following error: https://github.com/facebook/react-native/issues/42904#issuecomment-2306382117
 // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unused-vars
@@ -52,8 +51,6 @@ jest.mock('react-native/Libraries/Linking/Linking', () => ({
   openURL: global.mockOpenURL,
 }))
 
-jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'))
-
 jest.mock('expo-linking', () => {
   const module: typeof import('expo-linking') = {
     ...jest.requireActual('expo-linking'),
diff --git a/packages/chat/src/components/ChatTextInput.tsx b/packages/chat/src/components/ChatTextInput.tsx
index d0afc308abf9ccef2ede4e5215d82e64108f1710..f1e6bc05d402cba5b2316a052f3bedca6f003522 100644
--- a/packages/chat/src/components/ChatTextInput.tsx
+++ b/packages/chat/src/components/ChatTextInput.tsx
@@ -6,7 +6,6 @@ import { Platform, StyleSheet, type TextInputKeyPressEventData, View } from 'rea
 import { sendMessage } from '@holi/chat/src/store'
 import { useErrorHandling } from '@holi/core/errors/hooks'
 import { SendPlane } from '@holi/icons/src/generated'
-import { HoliTransition } from '@holi/ui/components/atoms/HoliTransition'
 import { ButtonIcon } from 'holi-bricks/components/button'
 import HoliTextInput from '@holi/ui/components/molecules/HoliTextInput'
 import { type HoliTheme, useTheme } from '@holi/ui/styles/theme'
@@ -59,11 +58,9 @@ export const ChatTextInput = ({ roomId, isVisible, userName = '', onMessageSent
     }
   }
 
-  const PLACEHOLDER_MIN_HIGHT = SEND_BUTTON_SIZE + Spacing.xxs * 2 + BORDER_WIDTH * 2
-
-  return (
-    <View style={{ minHeight: PLACEHOLDER_MIN_HIGHT, width: '100%' }}>
-      <HoliTransition.SlideDown visible={isVisible} style={styles.container}>
+  return isVisible ? (
+    <View style={styles.wrapper}>
+      <View style={styles.container}>
         <HoliTextInput
           aria-label={t('chat.room.input.placeholder', { fullName: userName })}
           placeholder={t('chat.room.input.placeholder', { fullName: userName })}
@@ -88,24 +85,24 @@ export const ChatTextInput = ({ roomId, isVisible, userName = '', onMessageSent
         />
 
         <View style={styles.buttonWrapper}>
-          {inputValue.trim().length > 0 && (
-            <HoliTransition.Fade visible>
-              <ButtonIcon
-                label={t('chat.room.sendButton.label')}
-                disabled={inputValue.trim().length === 0}
-                onPress={handleSendMessage}
-                icon={SendPlane}
-              />
-            </HoliTransition.Fade>
-          )}
+          <ButtonIcon
+            label={t('chat.room.sendButton.label')}
+            disabled={inputValue.trim().length === 0}
+            onPress={handleSendMessage}
+            icon={SendPlane}
+          />
         </View>
-      </HoliTransition.SlideDown>
+      </View>
     </View>
-  )
+  ) : null
 }
 
 const getStyles = (theme: HoliTheme) =>
   StyleSheet.create({
+    wrapper: {
+      minHeight: SEND_BUTTON_SIZE + Spacing.xxs * 2 + BORDER_WIDTH * 2,
+      width: '100%',
+    },
     container: {
       flexDirection: 'row',
       alignItems: 'center',
diff --git a/packages/chat/src/components/RoomMessageList/RoomMessage.tsx b/packages/chat/src/components/RoomMessageList/RoomMessage.tsx
index bcc075cf1e469b77ae0f71f30f6adcf50bba76ae..6b4135e9452d6b66b54f7a1720b954e1fb7ea9ec 100644
--- a/packages/chat/src/components/RoomMessageList/RoomMessage.tsx
+++ b/packages/chat/src/components/RoomMessageList/RoomMessage.tsx
@@ -5,7 +5,8 @@ import type { ChatRoomMessage } from '@holi/chat/src/client/types'
 import RoomMembershipBadge from '@holi/chat/src/components/RoomMessageList/RoomMembershipBadge'
 import RoomTextMessage from '@holi/chat/src/components/RoomMessageList/RoomTextMessage'
 import { roomMembersAtomCreator } from '@holi/chat/src/store'
-import { User } from '@holi/core/domain/shared/types'
+import type { User } from '@holi/core/domain/shared/types'
+import { useLoggedInUser } from '@holi/core/auth/hooks/useLoggedInUser'
 
 interface Props {
   message: ChatRoomMessage
@@ -20,10 +21,21 @@ interface Props {
 const RoomMessage = ({ holiUser, message, roomId, ...props }: Props) => {
   const membersRecord = useAtomValue(useMemo(() => roomMembersAtomCreator(roomId), [roomId]))
   const member = membersRecord[message.sender ?? '']
+  const { isLoading, user: loggedInUser } = useLoggedInUser()
+
+  if (isLoading) return null
 
   switch (message.type) {
     case 'message':
-      return <RoomTextMessage member={member} holiUser={holiUser} message={message} {...props} />
+      return (
+        <RoomTextMessage
+          member={member}
+          isSender={loggedInUser?.id === holiUser?.id}
+          holiUser={holiUser}
+          message={message}
+          {...props}
+        />
+      )
     case 'membership':
       return <RoomMembershipBadge member={member} user={holiUser} message={message} />
   }
diff --git a/packages/chat/src/components/RoomMessageList/RoomTextMessage.tsx b/packages/chat/src/components/RoomMessageList/RoomTextMessage.tsx
index 6b6784066730b308bbf8d4dce6b9cbfb4230b6ad..28aff8e6a778b784b0730b4670545acbad4a5076 100644
--- a/packages/chat/src/components/RoomMessageList/RoomTextMessage.tsx
+++ b/packages/chat/src/components/RoomMessageList/RoomTextMessage.tsx
@@ -1,7 +1,7 @@
 import { useAtomValue } from 'jotai'
-import React, { useMemo } from 'react'
+import React from 'react'
 import { useTranslation } from 'react-i18next'
-import { StyleSheet, View } from 'react-native'
+import { View } from 'react-native'
 
 import type { ChatRoomMember, ChatRoomMessage } from '@holi/chat/src/client/types'
 import { isMsgTextContent } from '@holi/chat/src/client/utils'
@@ -10,11 +10,13 @@ import { getChatInitials, getChatMemberName } from '@holi/chat/src/utils'
 import { getTimeFormat } from '@holi/core/i18n/helpers/dateHelper'
 import { getLocale } from '@holi/core/i18n/helpers/dateHelper'
 import HoliBox from '@holi/ui/components/atoms/HoliBox'
-import HoliText from '@holi/ui/components/atoms/HoliText'
 import HoliRichTextOutput from '@holi/ui/components/organisms/HoliRichTextOutput'
-import { type HoliTheme, useTheme } from '@holi/ui/styles/theme'
 import { Avatar } from 'holi-bricks/components/avatar'
 import type { User } from '@holi/core/domain/shared/types'
+import { createStyleSheet } from 'holi-bricks/utils'
+import { useStyles } from 'holi-bricks/hooks'
+import { BorderRadius } from 'holi-bricks/tokens'
+import { Text } from 'holi-bricks/components/text'
 
 interface Props {
   message: ChatRoomMessage
@@ -24,6 +26,7 @@ interface Props {
   isPrevMessageFromSameUser?: boolean
   isNextMessageFromSameUser?: boolean
   testID?: string
+  isSender?: boolean
 }
 
 const RoomTextMessage = ({
@@ -33,12 +36,12 @@ const RoomTextMessage = ({
   showAvatar = false,
   isPrevMessageFromSameUser = false,
   isNextMessageFromSameUser = false,
+  isSender,
   testID,
 }: Props) => {
   const { i18n, t } = useTranslation()
   const locale = getLocale(i18n.language)
-  const { theme } = useTheme()
-  const styles = useMemo(() => getStyles(theme), [theme])
+  const { styles } = useStyles(stylesheet)
 
   const myId = useAtomValue(loggedInMemberIdAtom)
   const isMyMessage = message.sender === myId
@@ -67,24 +70,26 @@ const RoomTextMessage = ({
           <HoliBox padding={[0, 16]} />
         )}
 
-        <View testID={testID} style={styles.wrapper}>
+        <View testID={testID} style={styles.wrapper(isSender)}>
           <HoliBox padding={[4, 8, 8, 8]}>
             {!isMyMessage && !isPrevMessageFromSameUser && (
               <HoliBox padding={[0, 0, 4, 0]}>
-                <HoliText bold>{getChatMemberName(t, member?.name)}</HoliText>
+                <Text size="sm" color="support">
+                  {getChatMemberName(t, member?.name)}
+                </Text>
               </HoliBox>
             )}
 
             {content.body ? (
-              <HoliRichTextOutput text={content.body} allowAllLinks />
+              <HoliRichTextOutput size="md" text={content.body} allowAllLinks />
             ) : (
-              <HoliText>{t('chat.message.deleted')}</HoliText>
+              <Text size="md">{t('chat.message.deleted')}</Text>
             )}
 
             <View style={styles.date}>
-              <HoliText size="extrasmall" color="gray300">
+              <Text size="xs" color={'default'}>
                 {getTimeFormat(locale, timestamp)}
-              </HoliText>
+              </Text>
             </View>
           </HoliBox>
         </View>
@@ -95,21 +100,20 @@ const RoomTextMessage = ({
 
 export default RoomTextMessage
 
-const getStyles = (theme: HoliTheme) =>
-  StyleSheet.create({
-    wrapper: {
-      borderColor: theme.colors.background30,
-      borderWidth: 1,
-      borderRadius: 12,
-      backgroundColor: theme.colors.white100,
-      flexShrink: 1,
-    },
-    rowWrapper: {
-      flexDirection: 'row',
-      alignItems: 'flex-end',
-      justifyContent: 'flex-start',
-    },
-    date: {
-      alignItems: 'flex-end',
-    },
-  })
+const stylesheet = createStyleSheet((theme) => ({
+  wrapper: (isSender?: boolean) => ({
+    borderColor: isSender ? theme.colors.decorative.purpleLight : theme.colors.bg.container,
+    borderWidth: 1,
+    borderRadius: BorderRadius.sm,
+    backgroundColor: isSender ? theme.colors.decorative.purpleLight : theme.colors.bg.container,
+    flexShrink: 1,
+  }),
+  rowWrapper: {
+    flexDirection: 'row',
+    alignItems: 'flex-end',
+    justifyContent: 'flex-start',
+  },
+  date: {
+    alignItems: 'flex-end',
+  },
+}))
diff --git a/packages/chat/src/components/RoomMessageList/index.tsx b/packages/chat/src/components/RoomMessageList/index.tsx
index 082409091d4d5179e125e64b1215ed66ae7496a3..c1d06d3be3604a6ccf2f9f33b8fd5970172b1864 100644
--- a/packages/chat/src/components/RoomMessageList/index.tsx
+++ b/packages/chat/src/components/RoomMessageList/index.tsx
@@ -1,18 +1,17 @@
+import React from 'react'
+import { useTranslation } from 'react-i18next'
+import { View } from 'react-native'
 import type { ChatRoomMessage } from '@holi/chat/src/client/types'
 import RoomMessageSection from '@holi/chat/src/components/RoomMessageList/RoomMessageSection'
 import { type MessageItem, isMessageSection, isTextMessageItem } from '@holi/chat/src/components/RoomMessageList/types'
+import { FlashList } from '@shopify/flash-list'
 import { getSectionDisplayDate } from '@holi/chat/src/utils/date'
 import { getLocale } from '@holi/core/i18n/helpers/dateHelper'
-import { dimensions } from '@holi/ui/styles/globalVars'
-import React from 'react'
-import { useTranslation } from 'react-i18next'
-import { View } from 'react-native'
-import Animated, { LayoutAnimationConfig, ZoomInEasyDown, LinearTransition } from 'react-native-reanimated'
-
-import { useStyles } from 'holi-bricks/hooks'
-import { createStyleSheet } from 'holi-bricks/utils'
 import RoomMessage from './RoomMessage'
 import type { RoomMessageListProps } from './types'
+import { createStyleSheet } from 'holi-bricks/utils'
+import { useStyles } from 'holi-bricks/hooks'
+import { Spacing } from 'holi-bricks/tokens'
 
 const groupByDate = (messages: ChatRoomMessage[], locale: string): MessageItem[] => {
   const groupedMessages: Record<string, MessageItem[]> = {}
@@ -20,21 +19,21 @@ const groupByDate = (messages: ChatRoomMessage[], locale: string): MessageItem[]
 
   for (const message of messages) {
     const { timestamp } = message
-    let formatedDate = ''
+    let formattedDate = ''
 
     if (timestamp) {
       const date = new Date(timestamp)
-      formatedDate = Intl.DateTimeFormat(locale, {
+      formattedDate = Intl.DateTimeFormat(locale, {
         year: 'numeric',
         month: 'numeric',
         day: 'numeric',
       }).format(date)
     }
 
-    groupedMessages[formatedDate] = groupedMessages[formatedDate] ?? [
+    groupedMessages[formattedDate] = groupedMessages[formattedDate] ?? [
       { title: getSectionDisplayDate(locale, timestamp) },
     ]
-    groupedMessages[formatedDate].unshift(message)
+    groupedMessages[formattedDate].unshift(message)
   }
 
   return Object.values(groupedMessages).reverse().flat()
@@ -51,47 +50,41 @@ const RoomMessageList = ({
   const { styles } = useStyles(stylesheet)
 
   const groupedMessages = groupByDate(messages, i18n.language)
-
   return (
-    // skip entering animation for the first render
-    <LayoutAnimationConfig skipEntering>
-      <Animated.FlatList
-        data={groupedMessages}
-        renderItem={({ item: message, index }) => {
-          if (isMessageSection(message)) return <RoomMessageSection messageSection={message} />
+    <FlashList
+      renderItem={({ item: message, index }) => {
+        if (isMessageSection(message)) return <RoomMessageSection messageSection={message} />
 
-          const isFirstMessageInSection = index === 0
-          const prevMessage = groupedMessages[index + 1]
-          const isPrevMessageFromSameUser =
-            !!prevMessage && isTextMessageItem(prevMessage) && prevMessage?.sender === message.sender
-          const nextMessage = groupedMessages[index - 1]
-          const isNextMessageFromSameUser =
-            !!nextMessage && isTextMessageItem(nextMessage) && nextMessage?.sender === message.sender
+        const isFirstMessageInSection = index === 0
+        const prevMessage = groupedMessages[index + 1]
+        const isPrevMessageFromSameUser =
+          !!prevMessage && isTextMessageItem(prevMessage) && prevMessage?.sender === message.sender
+        const nextMessage = groupedMessages[index - 1]
+        const isNextMessageFromSameUser =
+          !!nextMessage && isTextMessageItem(nextMessage) && nextMessage?.sender === message.sender
 
-          return (
-            <Animated.View entering={ZoomInEasyDown}>
-              <RoomMessage
-                roomId={roomId}
-                message={message}
-                holiUser={matrixIdToHoliUserRecord[message.sender ?? '']}
-                showAvatar={isFirstMessageInSection || !isNextMessageFromSameUser}
-                isPrevMessageFromSameUser={isPrevMessageFromSameUser}
-                isNextMessageFromSameUser={isNextMessageFromSameUser}
-              />
-            </Animated.View>
-          )
-        }}
-        initialNumToRender={15}
-        // BE CAREFUL: this section list is inverted! So, ListHeaderComponent is shown bellow and ListFooterComponent above in the list
-        // use ListFooterComponent to add padding bottom for HeaderAnimated
-        inverted={true}
-        onScroll={onScroll}
-        keyboardDismissMode="interactive"
-        ListHeaderComponent={() => <View style={styles.listHeaderSpacer} />}
-        ListFooterComponent={() => <View style={styles.listFooterSpacer}>{starter}</View>}
-        itemLayoutAnimation={LinearTransition.springify().damping(14).stiffness(90)}
-      />
-    </LayoutAnimationConfig>
+        return (
+          <RoomMessage
+            roomId={roomId}
+            message={message}
+            holiUser={matrixIdToHoliUserRecord[message.sender ?? '']}
+            showAvatar={isFirstMessageInSection || !isNextMessageFromSameUser}
+            isPrevMessageFromSameUser={isPrevMessageFromSameUser}
+            isNextMessageFromSameUser={isNextMessageFromSameUser}
+          />
+        )
+      }}
+      data={groupedMessages}
+      // BE CAREFUL: this section list is inverted! So, ListHeaderComponent is shown bellow and ListFooterComponent above in the list
+      // use ListFooterComponent to add padding bottom for HeaderAnimated
+      inverted={true}
+      onScroll={onScroll}
+      estimatedItemSize={52}
+      removeClippedSubviews
+      keyboardDismissMode="interactive"
+      ListHeaderComponent={() => <View style={styles.listHeaderSpacer} />}
+      ListFooterComponent={() => <View style={styles.listFooterSpacer}>{starter}</View>}
+    />
   )
 }
 
@@ -99,16 +92,9 @@ export default RoomMessageList
 
 const stylesheet = createStyleSheet(() => ({
   listFooterSpacer: {
-    paddingTop: dimensions.topBarHeight,
+    paddingHorizontal: Spacing['xs'],
   },
   listHeaderSpacer: {
     height: 20,
   },
-  container: {
-    flex: 1,
-  },
-  contentContainer: {
-    justifyContent: 'flex-end',
-    flexGrow: 1,
-  },
 }))
diff --git a/packages/chat/src/components/RoomMessageList/index.web.tsx b/packages/chat/src/components/RoomMessageList/index.web.tsx
deleted file mode 100644
index 48cd00dec47023ca29966cb198960a76e91c4375..0000000000000000000000000000000000000000
--- a/packages/chat/src/components/RoomMessageList/index.web.tsx
+++ /dev/null
@@ -1,123 +0,0 @@
-import React, { useMemo } from 'react'
-import { useTranslation } from 'react-i18next'
-import { SectionList, View } from 'react-native'
-import { StyleSheet } from 'react-native'
-
-import type { ChatRoomMessage } from '@holi/chat/src/client/types'
-import RoomMessageSection from '@holi/chat/src/components/RoomMessageList/RoomMessageSection'
-import { getSectionDisplayDate } from '@holi/chat/src/utils/date'
-import { getLocale } from '@holi/core/i18n/helpers/dateHelper'
-import { dimensions } from '@holi/ui/styles/globalVars'
-import { HoliTheme, useTheme } from '@holi/ui/styles/theme'
-
-import RoomMessage from './RoomMessage'
-import { RoomMessageListProps, isTextMessageItem } from './types'
-
-interface MessageDateGroup {
-  title: string
-  data: ChatRoomMessage[]
-}
-
-const groupByDate = (messages: ChatRoomMessage[], locale: string): MessageDateGroup[] => {
-  const groupedMessages: Record<string, MessageDateGroup> = {}
-  locale = getLocale(locale)
-
-  for (const message of messages) {
-    const { timestamp } = message
-    let formattedDate = ''
-
-    if (timestamp) {
-      const date = new Date(timestamp)
-      formattedDate = Intl.DateTimeFormat(locale, {
-        year: 'numeric',
-        month: 'numeric',
-        day: 'numeric',
-      }).format(date)
-    }
-
-    groupedMessages[formattedDate] = groupedMessages[formattedDate] ?? {
-      title: getSectionDisplayDate(locale, timestamp),
-      data: [],
-    }
-    groupedMessages[formattedDate].data.unshift(message)
-  }
-
-  return Object.values(groupedMessages).reverse()
-}
-
-const RoomMessageList = ({
-  messages = [],
-  matrixIdToHoliUserRecord,
-  starter,
-  onScroll,
-  roomId,
-}: RoomMessageListProps) => {
-  const { i18n } = useTranslation()
-  const { theme } = useTheme()
-  const styles = useMemo(() => getStyles(theme), [theme])
-
-  const groupedMessages = groupByDate(messages, i18n.language)
-
-  return (
-    <SectionList
-      sections={groupedMessages}
-      keyExtractor={(item) => item.id}
-      renderItem={({ item: message, index, section: { data: list } }) => {
-        const isFirstMessageInSection = index === 0
-        const prevMessage = list[index + 1]
-        const isPrevMessageFromSameUser =
-          !!prevMessage && isTextMessageItem(prevMessage) && prevMessage.sender === message.sender
-        const nextMessage = list[index - 1]
-        const isNextMessageFromSameUser =
-          !!nextMessage && isTextMessageItem(prevMessage) && nextMessage.sender === message.sender
-
-        return (
-          <View style={styles.listItemContainer}>
-            <RoomMessage
-              roomId={roomId}
-              message={message}
-              holiUser={matrixIdToHoliUserRecord[message.sender ?? '']}
-              showAvatar={isFirstMessageInSection || !isNextMessageFromSameUser}
-              isPrevMessageFromSameUser={isPrevMessageFromSameUser}
-              isNextMessageFromSameUser={isNextMessageFromSameUser}
-            />
-          </View>
-        )
-      }}
-      renderSectionFooter={({ section }) => <RoomMessageSection messageSection={section} />}
-      // BE CAREFUL: this section list is inverted! So, ListHeaderComponent is shown bellow and ListFooterComponent above in the list
-      // use ListFooterComponent to add padding bottom for HeaderAnimated
-      ListHeaderComponent={() => <View style={styles.listHeaderSpacer} />}
-      ListFooterComponent={() => <View style={styles.listFooterSpacer}>{starter}</View>}
-      stickySectionHeadersEnabled={false}
-      inverted={true}
-      style={styles.list}
-      removeClippedSubviews
-      updateCellsBatchingPeriod={20}
-      windowSize={11}
-      onScroll={onScroll}
-    />
-  )
-}
-
-export default RoomMessageList
-
-const getStyles = (theme: HoliTheme) =>
-  StyleSheet.create({
-    list: {
-      width: '100%',
-      height: '100%',
-      backgroundColor: theme.colors.background20,
-    },
-    listItemContainer: {
-      alignSelf: 'center',
-      width: '100%',
-      maxWidth: dimensions.maxScreenWidth,
-    },
-    listFooterSpacer: {
-      paddingTop: dimensions.topBarHeight,
-    },
-    listHeaderSpacer: {
-      height: 20,
-    },
-  })
diff --git a/packages/chat/src/components/__tests__/ChatRoomView.test.tsx b/packages/chat/src/components/__tests__/ChatRoomView.test.tsx
index 64fef6c2cc3ff19092aa767098a98f43903d59db..22494e9757645d7289ab8c6835ed00184a30c66b 100644
--- a/packages/chat/src/components/__tests__/ChatRoomView.test.tsx
+++ b/packages/chat/src/components/__tests__/ChatRoomView.test.tsx
@@ -1,3 +1,4 @@
+import '@holi/core/components/Screen/mock'
 import type { DefaultOptions } from '@apollo/client'
 import { MockedProvider } from '@apollo/client/testing'
 import { act, render, screen, waitForElementToBeRemoved } from '@testing-library/react-native'
diff --git a/packages/ui/components/organisms/HoliRichTextOutput.tsx b/packages/ui/components/organisms/HoliRichTextOutput.tsx
index cb613d6c69ada1978935cdfd6bbcacbefa7bf620..39ea2c06fecfa9a0f21408053cd1a6ae5a544497 100644
--- a/packages/ui/components/organisms/HoliRichTextOutput.tsx
+++ b/packages/ui/components/organisms/HoliRichTextOutput.tsx
@@ -1,16 +1,17 @@
-import { Text } from 'holi-bricks/components/text'
+import { Text, type TextLinkProps, type TextLinkSize } from 'holi-bricks/components/text'
 import React from 'react'
-import { Platform, type StyleProp, type TextStyle, type ViewStyle } from 'react-native'
+import { Platform, View, type StyleProp, type TextStyle, type ViewStyle } from 'react-native'
 
 import type { User } from '@holi/core/domain/shared/types'
 import { createUUID } from '@holi/core/helpers/strings'
 import { HoliTextLink } from '@holi/core/navigation/components/HoliTextLink'
 import type { Link } from '@holi/core/screens/posts/types'
-import HoliText from '@holi/ui/components/atoms/HoliText'
-import type { HoliTextProps } from '@holi/ui/components/atoms/HoliText'
 import { REGEX_URL, REGEX_USER_MENTIONS, ensureProtocolPrefix, isValidUrl } from '@holi/ui/helper/richText'
+import type { SkeletonTextOptions } from '@holi/ui/components/atoms/HoliSkeleton/types'
+import { defaultTextOptionsAsProps } from '@holi/ui/components/atoms/HoliSkeleton/defaults'
+import HoliSkeleton from '@holi/ui/components/atoms/HoliSkeleton'
 
-export interface Props extends HoliTextProps {
+export interface HoliRichTextProps extends Omit<Omit<TextLinkProps, 'variant'>, 'size'> {
   text: string
   users?: User[]
   links?: Link[]
@@ -20,6 +21,9 @@ export interface Props extends HoliTextProps {
   allowAllLinks?: boolean
   testID?: string
   onPressText?: () => void
+  loading?: boolean
+  size?: TextLinkSize
+  skeletonOptions?: SkeletonTextOptions
 }
 
 const HoliRichTextOutput = ({
@@ -27,14 +31,16 @@ const HoliRichTextOutput = ({
   users = [],
   links = [],
   testID,
-  size,
+  size = 'md',
   allowAllLinks = false,
   linkMentionsToProfile = true,
+  loading,
+  skeletonOptions,
+  numberOfLines,
   onPressText,
+  color = 'support',
   ...props
-}: Props) => {
-  const linkSize = size === undefined || size === 'extralarge' || size === 'large' ? 'md' : 'sm'
-
+}: HoliRichTextProps) => {
   /**
    * Replaces each @<USER-ID>
    * with the highlighted fullName
@@ -61,14 +67,14 @@ const HoliRichTextOutput = ({
               label={user.fullName ?? ''}
               href={`/profile/${user.id}`}
               key={index}
-              size={linkSize}
+              size={size}
               color="informative"
             >
               {mentionPrefix}
               {replaced}
             </HoliTextLink>
           ) : (
-            <Text key={index} size={linkSize}>
+            <Text key={index} size={size} color={color}>
               {mentionPrefix}
               {replaced}
             </Text>
@@ -102,7 +108,7 @@ const HoliRichTextOutput = ({
             <HoliTextLink
               href={link.requestedUrl}
               label={link.title}
-              size={linkSize}
+              size={size}
               key={link.requestedUrl}
               external={isExternalLink(link.requestedUrl)}
               color="informative"
@@ -110,9 +116,9 @@ const HoliRichTextOutput = ({
               {link.title}
             </HoliTextLink>
           ) : !!textPart.trim() && onPressText ? (
-            <HoliText key={createUUID()} onPress={onPressText} {...props}>
+            <Text size={size} key={createUUID()} onPress={onPressText} color={color} {...props}>
               {textPart}
-            </HoliText>
+            </Text>
           ) : (
             textPart
           )
@@ -120,10 +126,26 @@ const HoliRichTextOutput = ({
       })
   })()
 
+  const sizesToSkeletonHeight = {
+    md: 16,
+    sm: 15,
+    xs: 12,
+  }
+
+  if (loading) {
+    return (
+      <View style={props?.style}>
+        <HoliSkeleton
+          {...defaultTextOptionsAsProps(skeletonOptions, numberOfLines, sizesToSkeletonHeight[size], '60%')}
+        />
+      </View>
+    )
+  }
+
   return (
-    <HoliText testID={testID} size={size} {...props}>
+    <Text testID={testID} size={size} color={color} {...props}>
       {textWithMentions}
-    </HoliText>
+    </Text>
   )
 }
 
diff --git a/packages/ui/components/organisms/__tests__/__snapshots__/HoliRichTextOutput.test.tsx.snap b/packages/ui/components/organisms/__tests__/__snapshots__/HoliRichTextOutput.test.tsx.snap
index b6805475aebd6f2524d4c61b0b2789645f674342..259823342b0b0a7b838af3af8aebd5320a523436 100644
--- a/packages/ui/components/organisms/__tests__/__snapshots__/HoliRichTextOutput.test.tsx.snap
+++ b/packages/ui/components/organisms/__tests__/__snapshots__/HoliRichTextOutput.test.tsx.snap
@@ -3,20 +3,21 @@
 exports[`HoliRichTextOutput full text starting with word followed by colon is not a link 1`] = `
 <Text
   accessible={false}
-  collapsable={false}
-  jestAnimatedStyle={
-    {
-      "value": {},
-    }
-  }
+  role="none"
   selectable={true}
   style={
     {
-      "color": "#262424",
+      "color": "#676565",
       "fontFamily": "InstrumentSans-Regular",
       "fontSize": 16,
+      "fontVariant": [
+        "lining-nums",
+        "tabular-nums",
+      ],
       "fontWeight": "400",
-      "lineHeight": 22.4,
+      "letterSpacing": -0.128,
+      "lineHeight": 23.68,
+      "textAlign": undefined,
       "userSelect": "auto",
     }
   }
@@ -29,20 +30,21 @@ exports[`HoliRichTextOutput full text starting with word followed by colon is no
 exports[`HoliRichTextOutput link surrounded by whitespace is rendered as a link 1`] = `
 <Text
   accessible={false}
-  collapsable={false}
-  jestAnimatedStyle={
-    {
-      "value": {},
-    }
-  }
+  role="none"
   selectable={true}
   style={
     {
-      "color": "#262424",
+      "color": "#676565",
       "fontFamily": "InstrumentSans-Regular",
       "fontSize": 16,
+      "fontVariant": [
+        "lining-nums",
+        "tabular-nums",
+      ],
       "fontWeight": "400",
-      "lineHeight": 22.4,
+      "letterSpacing": -0.128,
+      "lineHeight": 23.68,
+      "textAlign": undefined,
       "userSelect": "auto",
     }
   }
diff --git a/yarn.lock b/yarn.lock
index 483c061a8b5de9e575f4be8eca5c50439bf387df..0f8cc57659d616e927ed0a610598c675bfa992fc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5684,7 +5684,7 @@ __metadata:
     jest-offline: "npm:^1.0.1"
     react: "npm:18.2.0"
     react-native: "npm:0.74.6"
-    react-native-keyboard-controller: "npm:^1.15.2"
+    react-native-keyboard-controller: "npm:^1.16.3"
     react-native-phone-number-input: "npm:^2.1.0"
     react-native-reanimated-carousel: "npm:^3.5.1"
     react-native-url-polyfill: "npm:^1.3.0"
@@ -5837,7 +5837,7 @@ __metadata:
     react-native-get-random-values: "npm:^1.11.0"
     react-native-image-crop-picker: "npm:^0.41.2"
     react-native-image-pan-zoom: "npm:^2.1.12"
-    react-native-keyboard-controller: "npm:^1.15.2"
+    react-native-keyboard-controller: "npm:^1.16.3"
     react-native-media-query: "npm:^2.0.1"
     react-native-reanimated: "npm:~3.10.1"
     react-native-reanimated-carousel: "npm:^3.5.1"
@@ -29402,16 +29402,16 @@ __metadata:
   languageName: node
   linkType: hard
 
-"react-native-keyboard-controller@npm:^1.15.2":
-  version: 1.15.2
-  resolution: "react-native-keyboard-controller@npm:1.15.2"
+"react-native-keyboard-controller@npm:^1.16.3":
+  version: 1.16.3
+  resolution: "react-native-keyboard-controller@npm:1.16.3"
   dependencies:
     react-native-is-edge-to-edge: "npm:^1.1.6"
   peerDependencies:
     react: "*"
     react-native: "*"
     react-native-reanimated: ">=3.0.0"
-  checksum: 10c0/7603bdcbeef5c453e385517d97efce829495fb67d3e18ba5044f159ec734941893a33d6e368177f32a31e4c6a71d73efad62dfc0b28469080ef36b4a4747c4a7
+  checksum: 10c0/5c2e52214b3b537e424dca5368116970e5cd87e136c47cae40c3b6c05872c3c16a5deea6c22d08733d2cc1c056faca1a7dd0d534d272b5765883fb388f87ee06
   languageName: node
   linkType: hard