diff --git a/.Jules/changelog.md b/.Jules/changelog.md
index b3cfda1..007d653 100644
--- a/.Jules/changelog.md
+++ b/.Jules/changelog.md
@@ -7,6 +7,14 @@
## [Unreleased]
### Added
+- **Mobile Accessibility:** Completed accessibility audit for all mobile screens.
+ - **Features:**
+ - Added `accessibilityLabel` to all interactive elements (buttons, inputs, list items).
+ - Added `accessibilityRole` to ensure screen readers identify element types correctly.
+ - Added `accessibilityHint` for clearer context on destructive actions or complex interactions.
+ - Covered Auth, Dashboard, Groups, and Utility screens.
+ - **Technical:** Updated all files in `mobile/screens/` to compliant with React Native accessibility standards.
+
- **Mobile Pull-to-Refresh:** Implemented native pull-to-refresh interactions with haptic feedback for key lists.
- **Features:**
- Integrated `RefreshControl` into `HomeScreen`, `FriendsScreen`, and `GroupDetailsScreen`.
diff --git a/.Jules/knowledge.md b/.Jules/knowledge.md
index 3361c5d..43a9ab0 100644
--- a/.Jules/knowledge.md
+++ b/.Jules/knowledge.md
@@ -306,6 +306,17 @@ Commonly used components:
Most screens use `` - consider wrapping in `SafeAreaView` for notched devices.
+### Accessibility Patterns
+
+**Date:** 2026-01-29
+**Context:** Auditing and fixing mobile accessibility
+
+When building mobile screens with React Native Paper:
+1. **Explicit Labels:** Always add `accessibilityLabel` to `IconButton`, `FAB`, and `Card` components that act as buttons.
+2. **Roles:** Use `accessibilityRole="button"` for pressable elements, `accessibilityRole="header"` for titles.
+3. **Hints:** Use `accessibilityHint` for non-obvious actions (e.g., "Double tap to delete").
+4. **State:** For custom checkboxes or toggles, use `accessibilityState={{ checked: boolean }}`.
+
---
## API Response Patterns
diff --git a/.Jules/todo.md b/.Jules/todo.md
index 7797cfb..de49cb8 100644
--- a/.Jules/todo.md
+++ b/.Jules/todo.md
@@ -64,7 +64,8 @@
- Size: ~40 lines
- Added: 2026-01-01
-- [ ] **[a11y]** Complete accessibility labels for all screens
+- [x] **[a11y]** Complete accessibility labels for all screens
+ - Completed: 2026-01-29
- Files: All screens in `mobile/screens/`
- Context: Add accessibilityLabel, accessibilityHint, accessibilityRole throughout
- Impact: Screen reader users can use app fully
diff --git a/mobile/screens/AccountScreen.js b/mobile/screens/AccountScreen.js
index 5c73504..c4ed869 100644
--- a/mobile/screens/AccountScreen.js
+++ b/mobile/screens/AccountScreen.js
@@ -39,30 +39,41 @@ const AccountScreen = ({ navigation }) => {
title="Edit Profile"
left={() => }
onPress={() => navigation.navigate("EditProfile")}
+ accessibilityLabel="Edit Profile"
+ accessibilityRole="button"
/>
}
onPress={handleComingSoon}
+ accessibilityLabel="Email Settings"
+ accessibilityRole="button"
/>
}
onPress={handleComingSoon}
+ accessibilityLabel="Send Feedback"
+ accessibilityRole="button"
/>
}
onPress={() => navigation.navigate("SplitwiseImport")}
+ accessibilityLabel="Import from Splitwise"
+ accessibilityRole="button"
/>
}
onPress={handleLogout}
+ accessibilityLabel="Logout"
+ accessibilityRole="button"
+ accessibilityHint="Logs you out of the application"
/>
diff --git a/mobile/screens/AddExpenseScreen.js b/mobile/screens/AddExpenseScreen.js
index 59cb65e..f5f58a3 100644
--- a/mobile/screens/AddExpenseScreen.js
+++ b/mobile/screens/AddExpenseScreen.js
@@ -282,6 +282,11 @@ const AddExpenseScreen = ({ route, navigation }) => {
label={member.user.name}
status={selectedMembers[member.userId] ? "checked" : "unchecked"}
onPress={() => handleMemberSelect(member.userId)}
+ accessibilityLabel={`Select ${member.user.name}`}
+ accessibilityRole="checkbox"
+ accessibilityState={{
+ checked: !!selectedMembers[member.userId],
+ }}
/>
));
case "exact":
@@ -295,6 +300,7 @@ const AddExpenseScreen = ({ route, navigation }) => {
}
keyboardType="numeric"
style={styles.splitInput}
+ accessibilityLabel={`${member.user.name}'s exact amount`}
/>
));
case "percentage":
@@ -308,6 +314,7 @@ const AddExpenseScreen = ({ route, navigation }) => {
}
keyboardType="numeric"
style={styles.splitInput}
+ accessibilityLabel={`${member.user.name}'s percentage`}
/>
));
case "shares":
@@ -321,6 +328,7 @@ const AddExpenseScreen = ({ route, navigation }) => {
}
keyboardType="numeric"
style={styles.splitInput}
+ accessibilityLabel={`${member.user.name}'s shares`}
/>
));
default:
@@ -351,6 +359,7 @@ const AddExpenseScreen = ({ route, navigation }) => {
value={description}
onChangeText={setDescription}
style={styles.input}
+ accessibilityLabel="Expense Description"
/>
{
onChangeText={setAmount}
style={styles.input}
keyboardType="numeric"
+ accessibilityLabel="Expense Amount"
/>