diff --git a/skills/react-navigation/SKILL.md b/skills/react-navigation/SKILL.md
new file mode 100644
index 0000000..036ce68
--- /dev/null
+++ b/skills/react-navigation/SKILL.md
@@ -0,0 +1,66 @@
+---
+name: react-navigation
+description: Provides React Navigation UI patterns for stacks, tabs, drawers etc. Use when building navigation UIs with React Navigation, configuring headers, bottom sheets or handling safe areas and insets.
+license: MIT
+metadata:
+ author: Callstack
+ tags: react-navigation, navigation, ui, native-stack, header, bottom-tabs, native-bottom-tabs, material-top-tabs, drawer, form-sheet, status-bar, safe-area, nested-navigators
+---
+
+# React Navigation
+
+## Overview
+
+Guide for building navigation UIs with React Navigation.
+
+This skill only applies to React Navigation 7. The API and patterns may not work with different versions.
+
+## API Selection
+
+React Navigation offers two API - object-based `Static API` and component-based `Dynamic API`.
+
+- **Existing Apps**: Check the current navigation setup and follow the same API style when using the references
+- **New Apps**: If the app does not have an existing navigation setup yet, prefer `Static API`
+
+## When to Apply
+
+Reference this skill when:
+
+- Building navigation UI patterns such as stacks, tabs, drawers, sheets etc.
+- Configuring headers and other built-in navigator UI
+- Handling safe areas and insets in navigation UI
+
+## References
+
+| File | Description |
+| ------------------------------------------- | ------------------------------ |
+| [stacks.md][stacks] | Stack based navigation |
+| [form-sheet.md][form-sheet] | Bottom sheet and form sheets |
+| [bottom-tabs.md][bottom-tabs] | Cross-platform bottom tabs |
+| [native-bottom-tabs.md][native-bottom-tabs] | Native bottom tabs |
+| [material-top-tabs.md][material-top-tabs] | Swipeable Top tabs |
+| [drawers.md][drawers] | Drawer navigation and sidebars |
+| [header.md][header] | Configuring headers |
+| [safe-areas.md][safe-areas] | Safe-area handling |
+
+## Problem -> Skill Mapping
+
+| Problem | Start With |
+| ------------------------------------------------------------------------- | ------------------------------------------- |
+| Showing screens and modals in a stack | [stacks.md][stacks] |
+| Showing bottom sheets or form sheets | [form-sheet.md][form-sheet] |
+| Showing screens in bottom tabs or responsive sidebars with web support | [bottom-tabs.md][bottom-tabs] |
+| Showing screens in native tabs on iOS & Android | [native-bottom-tabs.md][native-bottom-tabs] |
+| Showing content in swipeable top tabs | [material-top-tabs.md][material-top-tabs] |
+| Using a drawer or sidebar | [drawers.md][drawers] |
+| Configuring the header in bottom tab or drawer navigator | [header.md][header] |
+| Handling safe-area such as status bar, header insets, tab bar insets etc. | [safe-areas.md][safe-areas] |
+
+[stacks]: references/stacks.md
+[form-sheet]: references/form-sheet.md
+[safe-areas]: references/safe-areas.md
+[bottom-tabs]: references/bottom-tabs.md
+[native-bottom-tabs]: references/native-bottom-tabs.md
+[material-top-tabs]: references/material-top-tabs.md
+[drawers]: references/drawers.md
+[header]: references/header.md
diff --git a/skills/react-navigation/references/bottom-tabs.md b/skills/react-navigation/references/bottom-tabs.md
new file mode 100644
index 0000000..5a9449c
--- /dev/null
+++ b/skills/react-navigation/references/bottom-tabs.md
@@ -0,0 +1,496 @@
+---
+title: Bottom Tabs
+impact: HIGH
+tags: react-navigation, bottom-tabs, tab-bar, icons, blur, sidebar, header
+---
+
+# Skill: Bottom Tabs
+
+## Description
+
+Use `createBottomTabNavigator` for cross-platform tab navigation with a tab bar that can stay at the bottom on smaller screens and move to the side on larger layouts if the app needs web support.
+
+Conditionally use [native-bottom-tabs.md](./native-bottom-tabs.md) on Android and iOS for a native tab bar.
+
+## When to Use
+
+- Building primary app destinations behind a tab bar
+- The app needs to run on web and mobile
+
+## Basic Example
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+
+
+
+ );
+}
+```
+
+## Common Features
+
+### Displaying Icons
+
+Use `tabBarIcon` in `screenOptions` or per-screen `options`. Optionally use `tabBarActiveTintColor` and `tabBarInactiveTintColor` to change the color passed to the icon.
+
+**Static API**
+
+```tsx
+import Ionicons from '@expo/vector-icons/Ionicons';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ screenOptions: ({ route }) => ({
+ tabBarIcon: ({ focused, color, size }) => {
+ let iconName;
+
+ switch (route.name) {
+ case 'Home':
+ iconName = focused ? 'home' : 'home-outline';
+ break;
+ default:
+ iconName = focused ? 'settings' : 'settings-outline';
+ break;
+ }
+
+ return ;
+ },
+ tabBarActiveTintColor: 'tomato',
+ tabBarInactiveTintColor: 'gray',
+ }),
+ screens: {
+ Home: HomeScreen,
+ Settings: SettingsScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import Ionicons from '@expo/vector-icons/Ionicons';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+ ({
+ tabBarIcon: ({ focused, color, size }) => {
+ let iconName;
+
+ switch (route.name) {
+ case 'Home':
+ iconName = focused ? 'home' : 'home-outline';
+ break;
+ default:
+ iconName = focused ? 'settings' : 'settings-outline';
+ break;
+ }
+
+ return ;
+ },
+ tabBarActiveTintColor: 'tomato',
+ tabBarInactiveTintColor: 'gray',
+ })}
+ >
+
+
+
+ );
+}
+```
+
+The `tabBarIcon` option can render any React element. Choose between the icon libraries that best fit the app's design and environment:
+
+- `@expo/vector-icons` if Expo SDK is configured in the app
+- `react-native-vector-icons` for an app using React Native Community CLI
+- `` for local images
+
+### Scroll to Top on Tab Press
+
+Use `useScrollToTop` on a scrollable ref inside a screen in the tab navigator to automatically scroll to the top when the tab is pressed while already focused.
+
+```tsx
+import * as React from 'react';
+import { ScrollView } from 'react-native';
+import { useScrollToTop } from '@react-navigation/native';
+
+function FeedScreen() {
+ const ref = React.useRef(null);
+
+ useScrollToTop(ref);
+
+ return {/* content */};
+}
+```
+
+### Custom Background Such as Blur
+
+Use `tabBarBackground` for custom chrome such as blur effects, image, or gradient backgrounds. When the background should show through the tab bar, set `tabBarStyle: { position: 'absolute' }` and use `useBottomTabBarHeight` inside the screens to pad the content.
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { BlurView } from 'expo-blur';
+import { StyleSheet } from 'react-native';
+
+const AppTabs = createBottomTabNavigator({
+ screenOptions: {
+ tabBarStyle: { position: 'absolute' },
+ tabBarBackground: () => (
+
+ ),
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { BlurView } from 'expo-blur';
+import { StyleSheet } from 'react-native';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+ (
+
+ ),
+ }}
+ >
+
+
+
+ );
+}
+```
+
+### Custom Tab Bar
+
+Use the `tabBar` option if a custom design is needed. Use the `state` prop to access the list of screens and `descriptors` to access the options for each screen. Use the `navigation` prop passed to the tab bar for navigation instead of `useNavigation`.
+
+```tsx
+import { Text, View } from 'react-native';
+import { useLinkBuilder } from '@react-navigation/native';
+import { PlatformPressable } from '@react-navigation/elements';
+
+function MyTabBar({ state, descriptors, navigation }) {
+ const { buildHref } = useLinkBuilder();
+
+ return (
+
+ {state.routes.map((route, index) => {
+ const { options } = descriptors[route.key];
+ const label =
+ options.tabBarLabel !== undefined
+ ? options.tabBarLabel
+ : options.title !== undefined
+ ? options.title
+ : route.name;
+
+ const isFocused = state.index === index;
+
+ return (
+ {
+ const event = navigation.emit({
+ type: 'tabPress',
+ target: route.key,
+ canPreventDefault: true,
+ });
+
+ if (!isFocused && !event.defaultPrevented) {
+ navigation.navigate(route.name, route.params);
+ }
+ }}
+ onLongPress={() =>
+ navigation.emit({
+ type: 'tabLongPress',
+ target: route.key,
+ })
+ }
+ style={{ flex: 1, alignItems: 'center', paddingVertical: 12 }}
+ >
+ {label}
+
+ );
+ })}
+
+ );
+}
+```
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ tabBar: (props) => ,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+ }>
+
+
+
+ );
+}
+```
+
+### Sidebar
+
+Set `tabBarPosition` to `left` or `right` to render the tab bar as a sidebar. Choose the position based on the screen width for responsive layouts.
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ screenOptions: {
+ tabBarPosition: 'left',
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+}).with(({ Navigator }) => {
+ const dimensions = useWindowDimensions();
+
+ return (
+ = 768 ? 'left' : 'bottom',
+ }}
+ />
+ );
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { useWindowDimensions } from 'react-native';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ const dimensions = useWindowDimensions();
+
+ return (
+ = 768 ? 'left' : 'bottom',
+ }}
+ >
+
+
+
+ );
+}
+```
+
+For a compact sidebar, use `tabBarVariant: 'material'` together with `tabBarLabelPosition: 'below-icon'`.
+
+### Customizing Header
+
+Bottom tabs show a header by default. Use [header.md](./header.md) for common customization patterns.
+
+A custom header can be shown with the `header` option if a custom design is needed.
+
+**Static API**
+
+```tsx
+import { getHeaderTitle } from '@react-navigation/elements';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerStyle: {
+ height: 80,
+ },
+ header: ({ route, options }) => {
+ const title = getHeaderTitle(options, route.name);
+
+ return ;
+ },
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { getHeaderTitle } from '@react-navigation/elements';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+ {
+ const title = getHeaderTitle(options, route.name);
+
+ return ;
+ },
+ }}
+ />
+
+ );
+}
+```
+
+- Set `headerShown: false` to hide the header.
+- If a custom header uses a non-default height, set `headerStyle: { height: ... }` explicitly to avoid measurement glitches.
+
+## Hiding Tab Bar on Certain Screens
+
+The tab bar is shown on all screens in the tab navigator. To hide the tab bar on certain screens, put those screens in a parent stack navigator instead.
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Feed: FeedScreen,
+ Notifications: NotificationsScreen,
+ },
+});
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Main: {
+ screen: HomeTabs,
+ options: {
+ headerShown: false,
+ },
+ },
+ Profile: ProfileScreen,
+ Settings: SettingsScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+const Tab = createBottomTabNavigator();
+
+function HomeTabs() {
+ return (
+
+
+
+
+
+ );
+}
+
+function AppStack() {
+ return (
+
+
+
+
+
+ );
+}
+```
+
+- Prefer this structure over trying to hide the parent tab bar from screens inside the tab navigator as it can lead to layout glitches.
+- Use [stacks.md](./stacks.md) for stack-specific options on the full-screen routes.
+
+## Canonical Docs
+
+- [Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator)
+- [Customizing bottom tab bar](https://reactnavigation.org/docs/customizing-tabbar)
+- [Hiding tab bar in specific screens](https://reactnavigation.org/docs/hiding-tabbar-in-screens)
+
+## Related Skills
+
+- [header.md](./header.md)
+- [native-bottom-tabs.md](./native-bottom-tabs.md)
+- [material-top-tabs.md](./material-top-tabs.md)
+- [safe-areas.md](./safe-areas.md)
diff --git a/skills/react-navigation/references/drawers.md b/skills/react-navigation/references/drawers.md
new file mode 100644
index 0000000..c178f43
--- /dev/null
+++ b/skills/react-navigation/references/drawers.md
@@ -0,0 +1,474 @@
+---
+title: Drawer Navigator
+impact: HIGH
+tags: react-navigation, drawer, sidebar, master-detail, header, responsive-layout
+---
+
+# Skill: Drawer Navigator
+
+## Description
+
+Use `createDrawerNavigator` for a navigation drawer or sidebar that switches between app sections. If using a drawer for displaying content instead of navigation, use [`react-native-drawer-layout`](https://reactnavigation.org/docs/drawer-layout/) instead.
+
+## When to Use
+
+- Building app sections behind a drawer or sidebar
+- Showing a permanent sidebar on larger screens and a drawer on smaller screens
+- Using the drawer as the master pane in a master-detail layout
+
+## Prerequisites
+
+Install and configure `react-native-gesture-handler`, `react-native-reanimated`, and `react-native-worklets` for drawer navigator to work on native platforms.
+
+## Basic Example
+
+**Static API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const AppDrawer = createDrawerNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const Drawer = createDrawerNavigator();
+
+function AppDrawer() {
+ return (
+
+
+
+
+ );
+}
+```
+
+## Opening and Closing the Drawer
+
+Use `navigation.openDrawer()`, `navigation.closeDrawer()`, and `navigation.toggleDrawer()` inside drawer screens to open or close the drawer programmatically.
+
+```tsx
+import { Button, View } from 'react-native';
+import { useNavigation } from '@react-navigation/native';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+
+ );
+}
+```
+
+## Nesting Drawers
+
+When nesting a drawer inside another drawer, use [`react-native-drawer-layout`](https://reactnavigation.org/docs/drawer-layout/) for the outer drawer and keep Drawer navigator for the inner navigation drawer.
+
+```tsx
+import * as React from 'react';
+import { Text } from 'react-native';
+import { Drawer } from 'react-native-drawer-layout';
+
+function App() {
+ const [rightDrawerOpen, setRightDrawerOpen] = React.useState(false);
+
+ return (
+ setRightDrawerOpen(true)}
+ onClose={() => setRightDrawerOpen(false)}
+ drawerPosition="right"
+ renderDrawerContent={() => Right drawer content}
+ >
+
+
+ );
+}
+```
+
+Use React context to expose methods for opening or closing the outer drawer from nested screens.
+
+## Common Features
+
+### Displaying Icons
+
+Use `drawerIcon` in `screenOptions` or per-screen `options`. `drawerActiveTintColor` and `drawerInactiveTintColor` control the color passed to the icon and label.
+
+**Static API**
+
+```tsx
+import Ionicons from '@expo/vector-icons/Ionicons';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const AppDrawer = createDrawerNavigator({
+ screenOptions: ({ route }) => ({
+ drawerIcon: ({ color, size }) => {
+ let iconName;
+
+ switch (route.name) {
+ case 'Home':
+ iconName = 'home-outline';
+ break;
+ default:
+ iconName = 'person-outline';
+ break;
+ }
+
+ return ;
+ },
+ drawerActiveTintColor: 'tomato',
+ drawerInactiveTintColor: 'gray',
+ }),
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import Ionicons from '@expo/vector-icons/Ionicons';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const Drawer = createDrawerNavigator();
+
+function AppDrawer() {
+ return (
+ ({
+ drawerIcon: ({ color, size }) => {
+ let iconName;
+
+ switch (route.name) {
+ case 'Home':
+ iconName = 'home-outline';
+ break;
+ default:
+ iconName = 'person-outline';
+ break;
+ }
+
+ return ;
+ },
+ drawerActiveTintColor: 'tomato',
+ drawerInactiveTintColor: 'gray',
+ })}
+ >
+
+
+
+ );
+}
+```
+
+The `drawerIcon` option can render any React element. Choose between the icon libraries that best fit the app's design and environment:
+
+- `@expo/vector-icons` if Expo SDK is configured in the app
+- `react-native-vector-icons` for an app using React Native Community CLI
+- `` for local images
+
+### Custom Drawer Content
+
+Use `drawerContent` to customize the content of drawer, such as adding a header, footer, or custom actions, or replacing with a custom design.
+
+Use `DrawerContentScrollView` to automatically adjust insets and `DrawerItemList` to keep default design. Use the `navigation` prop passed to the custom drawer content instead of `useNavigation`.
+
+```tsx
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItem,
+ DrawerItemList,
+} from '@react-navigation/drawer';
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.navigate('Help')}
+ />
+
+ );
+}
+```
+
+Replace the content with own element if a different design is needed. Use the `state` prop to access the list of screens and `descriptors` to access the options for each screen.
+
+**Static API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const AppDrawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ Help: HelpScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const Drawer = createDrawerNavigator();
+
+function AppDrawer() {
+ return (
+ }
+ >
+
+
+
+
+ );
+}
+```
+
+### Types of Drawer
+
+Use `drawerType` to choose how the drawer behaves.
+
+Choose between `front`, `back`, and `slide` on smaller screens. Use `permanent` for a sidebar on larger screens. Use `useWindowDimensions` to conditionally set the type based on screen width for responsive layouts.
+
+**Static API**
+
+```tsx
+import { useWindowDimensions } from 'react-native';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const AppDrawer = createDrawerNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+}).with(({ Navigator }) => {
+ const { width } = useWindowDimensions();
+
+ return (
+ = 768 ? 'permanent' : 'front',
+ }}
+ />
+ );
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { useWindowDimensions } from 'react-native';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const Drawer = createDrawerNavigator();
+
+function AppDrawer() {
+ const { width } = useWindowDimensions();
+
+ return (
+ = 768 ? 'permanent' : 'front',
+ }}
+ >
+
+
+
+ );
+}
+```
+
+### Drawer Position
+
+Use `drawerPosition` to place the drawer on the left or right side. The default is `left` in LTR languages and `right` in RTL languages.
+
+**Static API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const AppDrawer = createDrawerNavigator({
+ screenOptions: {
+ drawerPosition: 'right',
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const Drawer = createDrawerNavigator();
+
+function AppDrawer() {
+ return (
+
+
+
+
+ );
+}
+```
+
+### Master Detail Layout
+
+Combine `defaultStatus: 'open'` with `drawerType: 'back'` when the drawer should start open and behave like the master pane behind the detail screen.
+
+**Static API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const AppDrawer = createDrawerNavigator({
+ defaultStatus: 'open',
+ screenOptions: {
+ drawerType: 'back',
+ drawerStyle: { width: '100%' },
+ overlayColor: 'transparent',
+ },
+ screens: {
+ Inbox: InboxScreen,
+ Message: MessageScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const Drawer = createDrawerNavigator();
+
+function AppDrawer() {
+ return (
+
+
+
+
+ );
+}
+```
+
+With `defaultStatus: 'open'`, the drawer's default state is open. So if drawer is closed, the back button will open it.
+
+### Customizing Header
+
+Drawer screens show a header by default. Use [header.md](./header.md) for common customization patterns.
+
+A custom header can be shown with the `header` option if a custom design is needed.
+
+**Static API**
+
+```tsx
+import { getHeaderTitle } from '@react-navigation/elements';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const AppDrawer = createDrawerNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerStyle: {
+ height: 80,
+ },
+ header: ({ route, options }) => {
+ const title = getHeaderTitle(options, route.name);
+
+ return ;
+ },
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { getHeaderTitle } from '@react-navigation/elements';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+const Drawer = createDrawerNavigator();
+
+function AppDrawer() {
+ return (
+
+ {
+ const title = getHeaderTitle(options, route.name);
+
+ return ;
+ },
+ }}
+ />
+
+ );
+}
+```
+
+- Set `headerShown: false` to hide the header.
+- If a custom header uses a non-default height, set `headerStyle: { height: ... }` explicitly to avoid measurement glitches.
+
+## Notes
+
+- Swipe gestures and gesture-handler customization are not supported on web.
+- If a drawer is nested under a stack or tab navigator, it renders below that parent navigator's header or tab bar.
+
+## Canonical Docs
+
+- [Drawer Navigator](https://reactnavigation.org/docs/drawer-navigator)
+- [Multiple drawers](https://reactnavigation.org/docs/multiple-drawers)
+- [Static configuration](https://reactnavigation.org/docs/static-configuration)
+- [Configuring the header bar](https://reactnavigation.org/docs/headers)
+
+## Related Skills
+
+- [header.md](./header.md)
+- [bottom-tabs.md](./bottom-tabs.md)
+- [stacks.md](./stacks.md)
+- [safe-areas.md](./safe-areas.md)
diff --git a/skills/react-navigation/references/form-sheet.md b/skills/react-navigation/references/form-sheet.md
new file mode 100644
index 0000000..005b200
--- /dev/null
+++ b/skills/react-navigation/references/form-sheet.md
@@ -0,0 +1,305 @@
+---
+title: Form Sheets with Native Stack
+impact: MEDIUM
+tags: react-navigation, native-stack, form-sheet, bottom-sheet, modal, detents
+---
+
+# Skill: Form Sheets with Native Stack
+
+## Description
+
+Use native-stack `presentation: 'formSheet'` when a screen should open as a sheet.
+
+## When to Use
+
+- Presenting secondary flows such as edit forms, filters, pickers, or lightweight detail screens
+- Keeping the current screen visible underneath a native sheet presentation
+
+## Basic Example
+
+**Static API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ EditProfile: {
+ screen: EditProfileScreen,
+ options: {
+ presentation: 'formSheet',
+ headerShown: false,
+ sheetAllowedDetents: 'fitToContents',
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+## Configuring Sheet Sizes
+
+By default, a form sheet takes the full screen height. Use `sheetAllowedDetents` to control the heights where the sheet can rest.
+
+- Use `'fitToContents'` to size the sheet from its content.
+- Use an ascending array of fractions such as `[0.25, 0.5, 1]` for fixed detents.
+- On Android, only the first 3 detents are used.
+- Use `sheetInitialDetentIndex` to choose the opening detent, or `'last'` for the largest one.
+
+### Fit to Contents
+
+`sheetResizeAnimationEnabled` is Android only and controls the default resize animation when using `'fitToContents'`.
+
+**Static API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Filters: {
+ screen: FiltersScreen,
+ options: {
+ presentation: 'formSheet',
+ sheetAllowedDetents: 'fitToContents',
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+On iOS, a top-level `flex: 1` content container works with `'fitToContents'`.
+
+On Android, `'fitToContents'` does not work with a top-level `flex: 1` content container. The sheet can disappear and leave only the dimmed backdrop visible.
+
+### Fixed Detents and Initial Detent
+
+`sheetShouldOverflowTopInset` is Android only and changes whether detent fractions are measured against the full stack height or the inset-adjusted height.
+
+**Static API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Details: {
+ screen: DetailsScreen,
+ options: {
+ presentation: 'formSheet',
+ sheetAllowedDetents: [0.25, 0.5, 1],
+ sheetInitialDetentIndex: 1,
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+On iOS, fixed detents do not automatically make content fill the sheet height. Use `contentStyle.backgroundColor` if the uncovered area would otherwise look translucent.
+
+## Customizing Appearance
+
+- `sheetGrabberVisible` is iOS only and shows the grabber.
+- `sheetCornerRadius` overrides the default corner radius.
+- `sheetElevation` is Android only, adjusts the top-edge shadow, and cannot be changed after mount.
+- `sheetLargestUndimmedDetentIndex` controls when the background stays undimmed: `'none'` always dims, `'last'` never dims, and a number keeps the background undimmed up to that detent index. On iOS, the system can still add dimming if the sheet grows beyond that height without a detent change, such as when the keyboard appears.
+- `contentStyle.backgroundColor` sets an explicit background color for the whole sheet. This is especially useful on iOS with fixed detents, where the content does not automatically fill the sheet height.
+
+**Static API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Composer: {
+ screen: ComposerScreen,
+ options: {
+ presentation: 'formSheet',
+ sheetAllowedDetents: [0.5, 1],
+ sheetGrabberVisible: true,
+ sheetCornerRadius: 24,
+ sheetElevation: 12,
+ sheetLargestUndimmedDetentIndex: 0,
+ contentStyle: {
+ backgroundColor: '#fff',
+ },
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+## Scroll Behavior
+
+On iOS, scrolling can expand the sheet to a larger detent by default. `sheetExpandsWhenScrolledToEdge` is iOS only, and setting it to `false` prevents that behavior.
+
+For this to work, the `ScrollView` must be reachable by following the first child at each level from the screen component (aka first descendant chain).
+
+**Static API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Comments: {
+ screen: CommentsScreen,
+ options: {
+ presentation: 'formSheet',
+ sheetAllowedDetents: [0.5, 1],
+ sheetExpandsWhenScrolledToEdge: false,
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+On Android, nested `ScrollView` usage may require `nestedScrollEnabled`, and still does not work when the content is shorter than the scroll view.
+
+## Notes
+
+- On Android, `presentation: 'formSheet'` screens do not currently support nested stack navigators or `headerShown`.
+
+## Canonical Docs
+
+- [Native Stack Navigator](https://reactnavigation.org/docs/native-stack-navigator)
+
+## Related Skills
+
+- [stacks.md](./stacks.md)
+- [safe-areas.md](./safe-areas.md)
diff --git a/skills/react-navigation/references/header.md b/skills/react-navigation/references/header.md
new file mode 100644
index 0000000..c721c34
--- /dev/null
+++ b/skills/react-navigation/references/header.md
@@ -0,0 +1,270 @@
+---
+title: Header
+impact: MEDIUM
+tags: react-navigation, header, title, header-buttons, header-background, react-navigation-elements
+---
+
+# Skill: Header
+
+## Description
+
+Use this when customizing the header in bottom tabs or drawer which render a JS-based header.
+
+For native stack headers, use [stacks.md](./stacks.md) instead.
+
+## When to Use
+
+- Styling the built-in header in bottom tabs or drawer screens
+- Adding header buttons, custom title content, or a custom background
+
+## Basic Example
+
+The shared header options work the same in bottom tabs and drawer. The examples below use bottom tabs.
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ title: 'Home',
+ headerStyle: {
+ backgroundColor: '#fff',
+ },
+ headerTintColor: '#111',
+ headerRight: () => ,
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+ ,
+ }}
+ />
+
+ );
+}
+```
+
+- Use `title`, `headerStyle`, `headerTintColor`, `headerTitleStyle`, and `headerTitleAlign` for the default header. Put shared config in navigator `screenOptions` and per-screen overrides in `options`.
+- Use `headerShown: false` for screens that contain a navigator - the header from the child navigator should be shown instead.
+
+## Common Features
+
+### Buttons and Custom Content
+
+Use `headerLeft`, `headerRight`, `headerTitle`, and `headerBackground` when the default header layout is fine but specific pieces need customization.
+
+**Static API**
+
+```tsx
+import { Button, Text } from 'react-native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ screens: {
+ Inbox: {
+ screen: InboxScreen,
+ options: {
+ headerLeft: ({ tintColor }) => (
+ {}} />
+ ),
+ headerTitle: ({ tintColor, children }) => (
+ {children}
+ ),
+ headerRight: ({ tintColor }) => (
+ {}} />
+ ),
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { Button, Text } from 'react-native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+ (
+ {}} />
+ ),
+ headerTitle: ({ tintColor, children }) => (
+ {children}
+ ),
+ headerRight: ({ tintColor }) => (
+ {}} />
+ ),
+ }}
+ />
+
+ );
+}
+```
+
+- `headerLeft` and `headerRight` receive props such as `tintColor`, `pressColor`, and `pressOpacity`.
+- `headerTitle` is useful when the title needs custom typography, icons, or extra layout.
+- Use `headerTitleContainerStyle`, `headerLeftContainerStyle`, and `headerRightContainerStyle` to customize the container styles.
+
+### Search Bar
+
+Use `headerSearchBarOptions` to add a search button that expands into a search input in the header. If the search configuration depends on screen state, update it with `navigation.setOptions(...)`.
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const AppTabs = createBottomTabNavigator({
+ screens: {
+ Search: {
+ screen: SearchScreen,
+ options: {
+ headerSearchBarOptions: {
+ placeholder: 'Search',
+ onChangeText: (text) => {
+ // Do something
+ },
+ },
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+ {
+ // Do something
+ },
+ },
+ }}
+ />
+
+ );
+}
+```
+
+### Translucent Headers
+
+Use `headerTransparent: true` to let content show underneath the header. Combine it with `headerBackground` for effects such as a blur, gradient, or image background.
+
+**Static API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { BlurView } from 'expo-blur';
+import { StyleSheet } from 'react-native';
+
+const AppTabs = createBottomTabNavigator({
+ screens: {
+ Feed: {
+ screen: FeedScreen,
+ options: {
+ headerTransparent: true,
+ headerBackground: () => (
+
+ ),
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { BlurView } from 'expo-blur';
+import { StyleSheet } from 'react-native';
+
+const Tab = createBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+ (
+
+ ),
+ }}
+ />
+
+ );
+}
+```
+
+- `headerStyle` does not apply when `headerBackground` is used. Style the element returned from `headerBackground` instead.
+- Transparent headers overlap the content below. Add top spacing manually using `useHeaderHeight` hook from `@react-navigation/elements`
+
+## Canonical Docs
+
+- [Configuring the header bar](https://reactnavigation.org/docs/headers)
+- [Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator)
+- [Drawer Navigator](https://reactnavigation.org/docs/drawer-navigator)
+
+## Related Skills
+
+- [bottom-tabs.md](./bottom-tabs.md)
+- [drawers.md](./drawers.md)
+- [stacks.md](./stacks.md)
diff --git a/skills/react-navigation/references/material-top-tabs.md b/skills/react-navigation/references/material-top-tabs.md
new file mode 100644
index 0000000..31fac2a
--- /dev/null
+++ b/skills/react-navigation/references/material-top-tabs.md
@@ -0,0 +1,453 @@
+---
+title: Material Top Tabs
+impact: MEDIUM
+tags: react-navigation, material-top-tabs, swipe, pager-view, lazy, tab-animation
+---
+
+# Skill: Material Top Tabs
+
+## Description
+
+Use `createMaterialTopTabNavigator` for swipeable top tabs with a Material-style tab bar.
+
+## When to Use
+
+- Building segmented content that should switch by tap or horizontal swipe
+- Having a scrollable tab bar at the top of the screen
+
+## Prerequisites
+
+Install `react-native-pager-view` for material top tabs to work on native platforms.
+
+## Basic Example
+
+**Static API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const HomeTabs = createMaterialTopTabNavigator({
+ screens: {
+ Feed: FeedScreen,
+ Updates: UpdatesScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const Tab = createMaterialTopTabNavigator();
+
+function HomeTabs() {
+ return (
+
+
+
+
+ );
+}
+```
+
+## Common Features
+
+### Displaying Icons
+
+Icons are hidden by default. Set `tabBarShowIcon: true`, then provide `tabBarIcon`. Optionally use `tabBarActiveTintColor` and `tabBarInactiveTintColor` to change the color passed to the icon.
+
+**Static API**
+
+```tsx
+import Ionicons from '@expo/vector-icons/Ionicons';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const HomeTabs = createMaterialTopTabNavigator({
+ screenOptions: ({ route }) => ({
+ tabBarShowIcon: true,
+ tabBarIcon: ({ focused, color }) => {
+ let iconName;
+
+ switch (route.name) {
+ case 'Feed':
+ iconName = focused ? 'newspaper' : 'newspaper-outline';
+ break;
+ default:
+ iconName = focused ? 'notifications' : 'notifications-outline';
+ break;
+ }
+
+ return ;
+ },
+ tabBarActiveTintColor: 'tomato',
+ tabBarInactiveTintColor: 'gray',
+ }),
+ screens: {
+ Feed: FeedScreen,
+ Updates: UpdatesScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import Ionicons from '@expo/vector-icons/Ionicons';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const Tab = createMaterialTopTabNavigator();
+
+function HomeTabs() {
+ return (
+ ({
+ tabBarShowIcon: true,
+ tabBarIcon: ({ focused, color }) => {
+ let iconName;
+
+ switch (route.name) {
+ case 'Feed':
+ iconName = focused ? 'newspaper' : 'newspaper-outline';
+ break;
+ default:
+ iconName = focused ? 'notifications' : 'notifications-outline';
+ break;
+ }
+
+ return ;
+ },
+ tabBarActiveTintColor: 'tomato',
+ tabBarInactiveTintColor: 'gray',
+ })}
+ >
+
+
+
+ );
+}
+```
+
+The `tabBarIcon` option can render any React element. Choose between the icon libraries that best fit the app's design and environment:
+
+- `@expo/vector-icons` if Expo SDK is configured in the app
+- `react-native-vector-icons` for an app using React Native Community CLI
+- `` for local images
+
+### Scrollable Tab Bar
+
+Use `tabBarScrollEnabled: true` if the list of tabs won't fit on the screen to make the tab bar scrollable. Set a fixed width for each tab with `tabBarItemStyle` to make the scrollable tab bar work better.
+
+Use `tabBarItemStyle` with `{ width: 'auto' }` if the tab button width should fit the label instead of being equally divided.
+
+**Static API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const HomeTabs = createMaterialTopTabNavigator({
+ screenOptions: {
+ tabBarScrollEnabled: true,
+ },
+ screens: {
+ Feed: FeedScreen,
+ Updates: UpdatesScreen,
+ Mentions: MentionsScreen,
+ Saved: SavedScreen,
+ Archive: ArchiveScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const Tab = createMaterialTopTabNavigator();
+
+function HomeTabs() {
+ return (
+
+
+
+
+
+
+
+ );
+}
+```
+
+### Badges
+
+Use `tabBarBadge` to render a custom badge element for a tab.
+
+**Static API**
+
+```tsx
+import { Text, View } from 'react-native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const HomeTabs = createMaterialTopTabNavigator({
+ screens: {
+ Inbox: {
+ screen: InboxScreen,
+ options: {
+ tabBarBadge: () => (
+
+ 3
+
+ ),
+ },
+ },
+ Settings: SettingsScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { Text, View } from 'react-native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const Tab = createMaterialTopTabNavigator();
+
+function HomeTabs() {
+ return (
+
+ (
+
+ 3
+
+ ),
+ }}
+ />
+
+
+ );
+}
+```
+
+### Indicators
+
+Use `tabBarIndicatorStyle` to customize the indicator:
+
+- Use horizontal margin (`{ marginHorizontal: 16 }`) to make the indicator shorter than the tab button width.
+- Set width (`{ width: 24 }`) for a fixed-width indicator, with `marginHorizontal: 'auto'` to center it under the tab button.
+- Don't set `borderRadius` if `tabBarItemStyle` has `'auto'` width as it's not supported.
+
+If the default styling options aren't sufficient, use `tabBarIndicator` to render a custom indicator.
+
+**Static API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const HomeTabs = createMaterialTopTabNavigator({
+ screenOptions: {
+ tabBarIndicatorStyle: {
+ backgroundColor: '#111827',
+ height: 3,
+ marginHorizontal: 16,
+ },
+ },
+ screens: {
+ Feed: FeedScreen,
+ Updates: UpdatesScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const Tab = createMaterialTopTabNavigator();
+
+function HomeTabs() {
+ return (
+
+
+
+
+ );
+}
+```
+
+### Custom Tab Bar
+
+Use the `tabBar` option if a custom design is needed. Use the `navigation` prop passed to the tab bar instead of `useNavigation`.
+
+```tsx
+import { Text, View } from 'react-native';
+import { useLinkBuilder } from '@react-navigation/native';
+import { PlatformPressable } from '@react-navigation/elements';
+
+function MyTabBar({ state, descriptors, navigation }) {
+ const { buildHref } = useLinkBuilder();
+
+ return (
+
+ {state.routes.map((route, index) => {
+ const { options } = descriptors[route.key];
+ const label =
+ options.tabBarLabel !== undefined
+ ? options.tabBarLabel
+ : options.title !== undefined
+ ? options.title
+ : route.name;
+
+ const isFocused = state.index === index;
+
+ return (
+ {
+ const event = navigation.emit({
+ type: 'tabPress',
+ target: route.key,
+ canPreventDefault: true,
+ });
+
+ if (!isFocused && !event.defaultPrevented) {
+ navigation.navigate(route.name, route.params);
+ }
+ }}
+ onLongPress={() =>
+ navigation.emit({
+ type: 'tabLongPress',
+ target: route.key,
+ })
+ }
+ style={{ flex: 1, alignItems: 'center', paddingVertical: 12 }}
+ >
+ {label}
+
+ );
+ })}
+
+ );
+}
+```
+
+**Static API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const HomeTabs = createMaterialTopTabNavigator({
+ tabBar: (props) => ,
+ screens: {
+ Feed: FeedScreen,
+ Updates: UpdatesScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const Tab = createMaterialTopTabNavigator();
+
+function HomeTabs() {
+ return (
+ }>
+
+
+
+ );
+}
+```
+
+If the custom tab bar also needs proper web links, use `useLinkBuilder` when building each tab button.
+
+### Lazy Rendering
+
+All screens are mounted immediately by default for smoother swiping. Enable `lazy` only when rendering tabs upfront is too expensive.
+
+**Static API**
+
+```tsx
+import { ActivityIndicator, View } from 'react-native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const HomeTabs = createMaterialTopTabNavigator({
+ screenOptions: {
+ lazy: true,
+ },
+ screens: {
+ Feed: FeedScreen,
+ Updates: UpdatesScreen,
+ Mentions: MentionsScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { ActivityIndicator, View } from 'react-native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+const Tab = createMaterialTopTabNavigator();
+
+function HomeTabs() {
+ return (
+
+
+
+
+
+ );
+}
+```
+
+Customize lazy loading behavior with `lazyPlaceholder` to show a custom placeholder before the screen is loaded and `lazyPreloadDistance` to control how many screens away from the focused screen should be preloaded.
+
+## Canonical Docs
+
+- [Material Top Tabs Navigator](https://reactnavigation.org/docs/material-top-tab-navigator)
diff --git a/skills/react-navigation/references/native-bottom-tabs.md b/skills/react-navigation/references/native-bottom-tabs.md
new file mode 100644
index 0000000..002936c
--- /dev/null
+++ b/skills/react-navigation/references/native-bottom-tabs.md
@@ -0,0 +1,365 @@
+---
+title: Native Bottom Tabs
+impact: HIGH
+tags: react-navigation, native-bottom-tabs, native-stack, navigate, search-tab, bottom-accessory, sidebar
+---
+
+# Skill: Native Bottom Tabs
+
+## Description
+
+Use `createNativeBottomTabNavigator` for a native tab bar on iOS and Android.
+
+Conditionally use [bottom-tabs.md](./bottom-tabs.md) if web support is needed.
+
+## When to Use
+
+- Building primary app destinations behind a tab bar
+- The app runs on iOS or Android
+
+## Basic Example
+
+**Static API**
+
+```tsx
+import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
+
+const AppTabs = createNativeBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
+
+const Tab = createNativeBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+
+
+
+ );
+}
+```
+
+## Avoiding Overlap with the Tab Bar
+
+On iOS, content inset is automatically adjusted for scrollable views to avoid overlap with the tab bar.
+
+For non-scrollable content, or on Android, use the experimental `SafeAreaView` from `react-native-screens/experimental` to apply padding for the tab bar.
+
+```tsx
+import { SafeAreaView } from 'react-native-screens/experimental';
+
+function ProfileScreen() {
+ return {/* content */};
+}
+```
+
+## Common Features
+
+### Displaying Icons
+
+Use `tabBarIcon` in `screenOptions` or per-screen `options`. Optionally use `tabBarActiveTintColor` and `tabBarInactiveTintColor` to change the color of the icon (support varies based on platform).
+
+**Static API**
+
+```tsx
+const AppTabs = createNativeBottomTabNavigator({
+ screens: {
+ Feed: {
+ screen: FeedScreen,
+ options: {
+ tabBarIcon: Platform.select({
+ ios: {
+ type: 'sfSymbol',
+ name: 'favorites',
+ },
+ default: {
+ type: 'image',
+ source: require('./assets/feed.png'),
+ },
+ }),
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+const Tab = createNativeBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+
+
+ );
+}
+```
+
+The `tabBarIcon` option supports multiple types of icons:
+
+- SF Symbols on iOS with `type: 'sfSymbol'` and `name`.
+- Local images with `type: 'image'` and `source`.
+
+Prefer SF Symbols on iOS, and image icons for other platforms. Use `Platform.select` to specify different icons per platform if needed.
+
+When using image icons:
+
+- Provide `1x`, `2x`, and `3x` image assets (`image.png`, `image@2x.png`, `image@3x.png`) because iOS does not scale tab icons automatically.
+- Set `tinted: false` on iOS (`{ type: 'image', tinted: false, source: require('./assets/feed.png') }`) if the image should keep its original colors. Android always tints image icons.
+
+### Search Tab on iOS 26+
+
+Use the built-in `search` system item together with a nested native stack navigator whose focused screen defines `headerSearchBarOptions`.
+
+**Static API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const SearchStack = createNativeStackNavigator({
+ screens: {
+ FruitsList: {
+ screen: FruitsListScreen,
+ options: {
+ title: 'Search',
+ headerSearchBarOptions: {
+ placeholder: 'Search fruits',
+ },
+ },
+ },
+ },
+});
+
+const AppTabs = createNativeBottomTabNavigator({
+ screens: {
+ Search: {
+ screen: SearchStack,
+ options: {
+ tabBarSystemItem: 'search',
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+const Tab = createNativeBottomTabNavigator();
+
+function SearchStack() {
+ return (
+
+
+
+ );
+}
+
+function AppTabs() {
+ return (
+
+
+
+ );
+}
+```
+
+- This behavior is available on iOS 26 and above.
+- The tab bar transforms into a search field only when the selected tab renders a nested native stack navigator.
+- The focused screen in that nested native stack must define `headerSearchBarOptions`.
+
+### Bottom Accessory
+
+Use `bottomAccessory` to render content above the tab bar or inline with the collapsed bar.
+
+**Static API**
+
+```tsx
+const AppTabs = createNativeBottomTabNavigator({
+ screenOptions: {
+ bottomAccessory: ({ placement }) => {
+ return (
+
+ Placement: {placement}
+
+ );
+ },
+ },
+ screens: {
+ Home: HomeScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+const Tab = createNativeBottomTabNavigator();
+
+function AppTabs() {
+ return (
+ {
+ return (
+
+ Placement: {placement}
+
+ );
+ },
+ }}
+ >
+
+
+ );
+}
+```
+
+- `placement` is `regular` above the bar or `inline` when the bar is collapsed.
+- This is supported on iOS 26 and above.
+- The accessory renders twice, once per placement, so shared state should live outside the returned component.
+
+### Sidebar
+
+Use `tabBarControllerMode: 'tabSidebar'` to display the native tab controller as a sidebar.
+
+**Static API**
+
+```tsx
+const AppTabs = createNativeBottomTabNavigator({
+ screenOptions: {
+ tabBarControllerMode: 'tabSidebar',
+ },
+ screens: {
+ Home: HomeScreen,
+ Search: SearchScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+const Tab = createNativeBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+
+
+
+ );
+}
+```
+
+- `auto` lets the system choose the presentation.
+- `tabBar` forces the standard tab bar.
+- Sidebar mode is supported on iOS 18 and above and not on tvOS.
+
+### Minimize on Scroll
+
+Use `tabBarMinimizeBehavior` to let the system collapse the tab bar while scrolling.
+
+**Static API**
+
+```tsx
+const AppTabs = createNativeBottomTabNavigator({
+ screenOptions: {
+ tabBarMinimizeBehavior: 'onScrollDown',
+ },
+ screens: {
+ Home: HomeScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+const Tab = createNativeBottomTabNavigator();
+
+function AppTabs() {
+ return (
+
+
+
+ );
+}
+```
+
+- Supported values are `auto`, `never`, `onScrollDown`, and `onScrollUp`.
+- This is supported on iOS 26 and above.
+
+## Notes
+
+- React Native 0.79 or above is required. If you're using Expo, SDK 53 or above is required.
+- The app must use the latest `react-native-screens` along with the latest version of `@react-navigation/bottom-tabs` to avoid compatibility issues.
+- When using Expo, development builds maybe required to support the latest version of `react-native-screens`.
+- Liquid Glass effect on iOS 26+ requires your app to be built with Xcode 26 or above.
+- On Android, at most 5 tabs are supported. This is a limitation of the underlying native component.
+- No header is shown by default. A basic JS based header can be shown with `headerShown: true` option (see [header.md](./header.md)), or a native header can be shown by nesting a native stack navigator inside each tab screen.
+
+## Canonical Docs
+
+- [Native Bottom Tabs Navigator](https://reactnavigation.org/docs/native-bottom-tab-navigator)
+- [Native Stack Navigator](https://reactnavigation.org/docs/native-stack-navigator)
+
+## Related Skills
+
+- [bottom-tabs.md](./bottom-tabs.md)
+- [stacks.md](./stacks.md)
+- [safe-areas.md](./safe-areas.md)
+- [header.md](./header.md)
diff --git a/skills/react-navigation/references/safe-areas.md b/skills/react-navigation/references/safe-areas.md
new file mode 100644
index 0000000..8052b8c
--- /dev/null
+++ b/skills/react-navigation/references/safe-areas.md
@@ -0,0 +1,95 @@
+---
+title: Safe Areas
+impact: HIGH
+tags: react-navigation, safe-area, inset, safe-area-context, scroll-view, flatlist, edge-to-edge
+---
+
+# Skill: Safe Areas
+
+## Description
+
+Use this reference when content or scroll containers must avoid notches, system bars, home indicators, and other system UI.
+
+React Navigation already handles safe areas for its built-in UI such as headers, tab bars, and drawers. Apply insets manually only for your own screen content or when you replace the built-in navigation UI with custom components.
+
+## When to Use
+
+- Content is hidden behind the status bar, navigation bar, notch, or home indicator
+- A screen uses a custom header, custom tab bar, or custom drawer content
+- Fixed UI such as hero media, floating actions, or bottom actions needs selective safe-area padding
+
+## Edge-to-Edge on Android
+
+Edge-to-edge makes the app content extend behind translucent system bars on Android, similar to how it works on iOS. Enable edge-to-edge for consistent safe area handling across platforms.
+
+Android enables edge-to-edge by default from Android 15 (API level 35) for apps targeting API level 35. Edge-to-edge cannot be disabled from Android 16 (API level 36). For older Android versions, edge-to-edge can be enabled from React Native 0.81 onwards in `android/gradle.properties`:
+
+```ini
+edgeToEdgeEnabled=true
+```
+
+## Using `contentInsetAdjustmentBehavior` for `ScrollView`
+
+When the main screen content scrolls (such as a `ScrollView`, `FlatList`, `SectionList` etc.) on iOS, prefer `contentInsetAdjustmentBehavior="automatic"` so the scroll view adjusts for safe areas while still allowing edge-to-edge scrolling behavior.
+
+```tsx
+import { ScrollView } from 'react-native';
+
+function ArticleScreen() {
+ return (
+
+ {/* content */}
+
+ );
+}
+```
+
+On Android, conditionally use the `useSafeAreaInsets` hook from `react-native-safe-area-context` to apply paddings.
+
+## Using `useSafeAreaInsets`
+
+Use the `useSafeAreaInsets` hook from `react-native-safe-area-context` for custom layouts. It gives precise control over which edges should receive padding.
+
+```tsx
+import { View } from 'react-native';
+import { useSafeAreaInsets } from 'react-native-safe-area-context';
+
+function ScreenContent() {
+ const insets = useSafeAreaInsets();
+
+ return (
+
+ {/* content */}
+
+ );
+}
+```
+
+- Prefer the hook over `SafeAreaView`, as `SafeAreaView` can behave poorly during animations, and mixing `SafeAreaView` with the hook can cause flicker.
+- It is usually not necessary to wrap the app in `SafeAreaProvider` as it's done internally by React Navigation. Only add it when using in components not in stack, bottom tabs or drawer navigators.
+- Apply insets to only the specific edges that extend to the screen edge
+- Keep landscape orientation in mind, as the top and bottom insets become left and right insets
+- Do not wrap the whole app in a `SafeAreaView` to avoid wasting space.
+
+## Canonical Docs
+
+- [React Navigation: Supporting safe areas](https://reactnavigation.org/docs/handling-safe-area/)
+- [React Native: ScrollView](https://reactnative.dev/docs/scrollview)
+- [React Navigation: Native Stack Navigator](https://reactnavigation.org/docs/native-stack-navigator)
+- [React Native 0.81: Android 16 support and edge-to-edge](https://reactnative.dev/blog/2025/08/12/react-native-0.81)
+- [react-native-safe-area-context](https://github.com/AppAndFlow/react-native-safe-area-context)
+
+## Related Skills
+
+- [stacks.md](./stacks.md)
+- [bottom-tabs.md](./bottom-tabs.md)
+- [native-bottom-tabs.md](./native-bottom-tabs.md)
+- [drawers.md](./drawers.md)
diff --git a/skills/react-navigation/references/stacks.md b/skills/react-navigation/references/stacks.md
new file mode 100644
index 0000000..3b17cbb
--- /dev/null
+++ b/skills/react-navigation/references/stacks.md
@@ -0,0 +1,392 @@
+---
+title: Native Stack Navigator
+impact: HIGH
+tags: react-navigation, native-stack, navigation, header, header-items, search-bar, large-title, modal, animation, form-sheet
+---
+
+# Skill: Native Stack Navigator
+
+## Description
+
+Use `createNativeStackNavigator` for screen-to-screen flows.
+
+## When to Use
+
+- Building the default push-based flow for an app
+- Using platform-native headers, large titles, or a native search bar
+- Presenting modal or sheet screens with native-stack presentations
+
+## Basic Example
+
+**Static API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+## Common Features
+
+### Large Title
+
+Use `headerLargeTitleEnabled: true` for an iOS large title that collapses into the regular header on scroll.
+
+**Static API**
+
+```tsx
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Library: {
+ screen: LibraryScreen,
+ options: {
+ headerLargeTitleEnabled: true,
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+ );
+}
+```
+
+- Only supported on iOS.
+- The scroll view in the screen must use `contentInsetAdjustmentBehavior="automatic"`.
+- Don't set a background color on the header if large title is enabled as it makes title invisible on iOS 26.
+- Don't set `headerTransparent: false` if large title is enabled.
+- If the scrollable area does not fill the screen, the large title will not collapse on scroll.
+
+### Header Search Bar
+
+Use `headerSearchBarOptions` to render a native search bar. If the search configuration depends on screen state, update it with `navigation.setOptions(...)`.
+
+**Static API**
+
+```tsx
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Search: {
+ screen: SearchScreen,
+ options: {
+ headerSearchBarOptions: {
+ placeholder: 'Search',
+ },
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+ );
+}
+```
+
+- The scroll view in the screen must use `contentInsetAdjustmentBehavior="automatic"`.
+- If the screen doesn't have a scroll view, use `headerTopInsetEnabled: true`.
+
+### Header Buttons and Custom Content
+
+Use `unstable_headerLeftItems` and `unstable_headerRightItems` for native iOS header buttons or menus. Use `headerLeft`, `headerRight`, `headerTitle`, and `headerBackground` for custom React content, and as a fallback on other platforms.
+
+**Static API**
+
+```tsx
+import { Button, Text, View } from 'react-native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ options: {
+ headerTitle: ({ tintColor, children }) => (
+ {children}
+ ),
+ headerBackground: () => (
+
+ ),
+ unstable_headerLeftItems: () => [
+ {
+ type: 'button',
+ label: 'Edit',
+ onPress: () => {
+ // Do something
+ },
+ },
+ ],
+ unstable_headerRightItems: () => [
+ {
+ type: 'button',
+ label: 'Done',
+ icon: {
+ type: 'sfSymbol',
+ name: 'checkmark',
+ },
+ onPress: () => {
+ // Do something
+ },
+ },
+ ],
+ headerLeft: ({ tintColor }) => (
+ {}} />
+ ),
+ headerRight: ({ tintColor }) => (
+ {}} />
+ ),
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { Button, Text, View } from 'react-native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+ (
+ {children}
+ ),
+ headerBackground: () => (
+
+ ),
+ unstable_headerLeftItems: () => [
+ {
+ type: 'button',
+ label: 'Edit',
+ onPress: () => {
+ // Do something
+ },
+ },
+ ],
+ unstable_headerRightItems: () => [
+ {
+ type: 'button',
+ label: 'Done',
+ icon: {
+ type: 'sfSymbol',
+ name: 'checkmark',
+ },
+ onPress: () => {
+ // Do something
+ },
+ },
+ ],
+ headerLeft: ({ tintColor }) => (
+ {}} />
+ ),
+ headerRight: ({ tintColor }) => (
+ {}} />
+ ),
+ }}
+ />
+
+ );
+}
+```
+
+- `unstable_headerLeftItems` and `unstable_headerRightItems` are only supported on iOS and override `headerLeft` and `headerRight` when both are specified.
+- Use `headerLeft` when replacing the back button. Add `headerBackVisible: true` if the back button should still be shown alongside the custom left element.
+- `headerTitle` is useful when the title needs custom typography or extra layout, but custom title elements do not animate with the native title transition.
+- Use `headerBackground` for a gradient, image, or custom background view. For translucent native headers on iOS, prefer `headerTransparent: true` with `scrollEdgeEffects` for iOS 26+ or `headerBlurEffect` for earlier versions.
+- Some behavior differs between iOS versions. On iOS 26+, `unstable_headerRightItems` can collapse into the system overflow menu when there is not enough space.
+- Custom items with `type: 'custom'` in `unstable_headerRightItems` are not collapsed into the overflow menu.
+- Labels are used when items collapse into the overflow menu, and for accessibility.
+
+### Screen Presentations
+
+Use the screen `presentation` option to control whether a screen is pushed normally or shown as a modal or sheet.
+
+**Static API**
+
+```tsx
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Compose: {
+ screen: ComposeScreen,
+ options: {
+ presentation: 'modal',
+ animation: 'slide_from_bottom',
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+- Use `card` for the default push presentation.
+- Use `modal` for a standard modal presentation.
+- Use `containedModal` for a current-context modal presentation on iOS and the default modal presentation on Android.
+- Use `fullScreenModal` when the screen should take over the whole screen. On iOS, this presentation cannot be dismissed by gesture.
+- Use `transparentModal` or `containedTransparentModal` when the previous screen should remain visible behind translucent content.
+- Use `formSheet` when the design calls for a native sheet. Use [form-sheet.md](./form-sheet.md) for detents and platform-specific caveats.
+- Use the `animation` option in the section below when the default transition does not fit the flow.
+
+### Transition Animations
+
+Use `animation` option to customize the transition animation.
+
+**Static API**
+
+```tsx
+const AppStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Details: {
+ screen: DetailsScreen,
+ options: {
+ animation: 'fade_from_bottom',
+ animationDuration: 300,
+ },
+ },
+ },
+});
+```
+
+**Dynamic API**
+
+```tsx
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function AppStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+- Supported `animation` values include `default`, `fade`, `fade_from_bottom`, `simple_push`, `slide_from_bottom`, `slide_from_right`, `slide_from_left`, `flip`, and `none`.
+- `flip` requires `presentation: 'modal'` on iOS.
+- `slide_from_right` and `slide_from_left` fall back to the default transition on iOS.
+- `simple_push` removes the shadow and native header transition on iOS and falls back to the default transition on Android.
+- Use `animationTypeForReplace: 'pop'` when `navigation.replace(...)` should feel like going back, such as auth or onboarding flows.
+- Use `animationDuration` on iOS to tune `slide_from_bottom`, `fade_from_bottom`, `fade`, and `simple_push`. It does not apply to `default`, `flip`, or screens presented as `modal` or `formSheet`.
+- Gesture-related transition options are only supported on iOS.
+- Use `gestureEnabled` to disable swipe-to-dismiss when the animation should only run programmatically.
+- Use `fullScreenGestureEnabled` to start the dismiss gesture anywhere on the screen. This uses `simple_push`-style behavior, and the default iOS transition cannot be matched due to platform limitations.
+- Use `animationMatchesGesture` when the interactive dismiss gesture should follow the `animation` option. It does not affect screens presented modally.
+- Use `fullScreenGestureShadowEnabled` to control the shadow shown during a full-screen dismiss gesture.
+- On iOS, `gestureDirection: 'vertical'` implies `animation: 'slide_from_bottom'` together with full-screen dismissal gestures.
+
+## Notes
+
+- For scrollable content and `contentInsetAdjustmentBehavior="automatic"`, native stack needs it to be in the first-descendant chain — no views should be rendered before the scrollable view.
+
+## Canonical Docs
+
+- [Native Stack Navigator](https://reactnavigation.org/docs/native-stack-navigator)
+- [Moving between screens](https://reactnavigation.org/docs/navigating)
+- [Configuring the header bar](https://reactnavigation.org/docs/headers)
+- [Opening a modal](https://reactnavigation.org/docs/modal)
+
+## Related Skills
+
+- [form-sheet.md](./form-sheet.md)
+- [safe-areas.md](./safe-areas.md)