@entropy-softworks/ui 2026.8.15 → 2026.8.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/lib/components/auth/LockOverlay.jsx +1 -1
  3. package/lib/components/auth/LockOverlay.jsx.map +1 -1
  4. package/lib/components/auth/ProtectedRoute.jsx +1 -1
  5. package/lib/components/auth/ProtectedRoute.jsx.map +1 -1
  6. package/lib/components/card.jsx +1 -1
  7. package/lib/components/card.jsx.map +1 -1
  8. package/lib/components/context-menu.jsx +1 -1
  9. package/lib/components/context-menu.jsx.map +1 -1
  10. package/lib/components/data-table.jsx +2 -2
  11. package/lib/components/data-table.jsx.map +1 -1
  12. package/lib/components/dropdown-menu.jsx +4 -4
  13. package/lib/components/dropdown-menu.jsx.map +1 -1
  14. package/lib/components/entropy-mark.jsx +1 -1
  15. package/lib/components/entropy-mark.jsx.map +1 -1
  16. package/lib/components/error-boundary.jsx +2 -2
  17. package/lib/components/error-boundary.jsx.map +1 -1
  18. package/lib/components/pagination.jsx +1 -1
  19. package/lib/components/pagination.jsx.map +1 -1
  20. package/lib/components/password-generator.jsx +18 -18
  21. package/lib/components/password-generator.jsx.map +1 -1
  22. package/lib/components/pin-pad.d.ts.map +1 -1
  23. package/lib/components/pin-pad.jsx +5 -5
  24. package/lib/components/pin-pad.jsx.map +1 -1
  25. package/lib/components/popover.jsx +1 -1
  26. package/lib/components/popover.jsx.map +1 -1
  27. package/lib/components/settings-row.jsx +2 -2
  28. package/lib/components/settings-row.jsx.map +1 -1
  29. package/lib/screens/auth/AccountPickerScreen.jsx +1 -1
  30. package/lib/screens/auth/AccountPickerScreen.jsx.map +1 -1
  31. package/lib/screens/auth/AuthScreen.jsx +2 -2
  32. package/lib/screens/auth/AuthScreen.jsx.map +1 -1
  33. package/lib/screens/auth/ConsentScreen.jsx +3 -3
  34. package/lib/screens/auth/ConsentScreen.jsx.map +1 -1
  35. package/lib/screens/auth/ErrorScreen.jsx +2 -2
  36. package/lib/screens/auth/ErrorScreen.jsx.map +1 -1
  37. package/lib/screens/auth/ExpiredLinkScreen.jsx +2 -2
  38. package/lib/screens/auth/ExpiredLinkScreen.jsx.map +1 -1
  39. package/lib/screens/auth/ForgotPasswordScreen.jsx +3 -3
  40. package/lib/screens/auth/ForgotPasswordScreen.jsx.map +1 -1
  41. package/lib/screens/auth/ImportDataScreen.jsx +2 -2
  42. package/lib/screens/auth/ImportDataScreen.jsx.map +1 -1
  43. package/lib/screens/auth/LoginScreen.jsx +2 -2
  44. package/lib/screens/auth/LoginScreen.jsx.map +1 -1
  45. package/lib/screens/auth/MfaEnrollScreen.jsx +3 -3
  46. package/lib/screens/auth/MfaEnrollScreen.jsx.map +1 -1
  47. package/lib/screens/auth/PasskeyEnrollScreen.jsx +3 -3
  48. package/lib/screens/auth/PasskeyEnrollScreen.jsx.map +1 -1
  49. package/lib/screens/auth/RegisterScreen.jsx +2 -2
  50. package/lib/screens/auth/RegisterScreen.jsx.map +1 -1
  51. package/lib/screens/auth/ResetPasswordScreen.jsx +3 -3
  52. package/lib/screens/auth/ResetPasswordScreen.jsx.map +1 -1
  53. package/lib/screens/auth/ServerConfigScreen.jsx +23 -23
  54. package/lib/screens/auth/ServerConfigScreen.jsx.map +1 -1
  55. package/lib/screens/auth/VerifyEmailScreen.jsx +1 -1
  56. package/lib/screens/auth/VerifyEmailScreen.jsx.map +1 -1
  57. package/lib/screens/auth/WelcomeScreen.jsx +1 -1
  58. package/lib/screens/auth/WelcomeScreen.jsx.map +1 -1
  59. package/package.json +1 -1
  60. package/src/components/auth/LockOverlay.tsx +1 -1
  61. package/src/components/auth/ProtectedRoute.tsx +1 -1
  62. package/src/components/card.tsx +1 -1
  63. package/src/components/context-menu.tsx +1 -1
  64. package/src/components/data-table.tsx +2 -2
  65. package/src/components/dropdown-menu.tsx +5 -5
  66. package/src/components/entropy-mark.tsx +1 -1
  67. package/src/components/error-boundary.tsx +2 -2
  68. package/src/components/pagination.tsx +1 -1
  69. package/src/components/password-generator.tsx +18 -18
  70. package/src/components/pin-pad.tsx +7 -5
  71. package/src/components/popover.tsx +1 -1
  72. package/src/components/settings-row.tsx +2 -2
  73. package/src/screens/auth/AccountPickerScreen.tsx +1 -1
  74. package/src/screens/auth/AuthScreen.tsx +2 -2
  75. package/src/screens/auth/ConsentScreen.tsx +3 -3
  76. package/src/screens/auth/ErrorScreen.tsx +2 -2
  77. package/src/screens/auth/ExpiredLinkScreen.tsx +2 -2
  78. package/src/screens/auth/ForgotPasswordScreen.tsx +3 -3
  79. package/src/screens/auth/ImportDataScreen.tsx +2 -2
  80. package/src/screens/auth/LoginScreen.tsx +2 -2
  81. package/src/screens/auth/MfaEnrollScreen.tsx +3 -3
  82. package/src/screens/auth/PasskeyEnrollScreen.tsx +3 -3
  83. package/src/screens/auth/RegisterScreen.tsx +2 -2
  84. package/src/screens/auth/ResetPasswordScreen.tsx +3 -3
  85. package/src/screens/auth/ServerConfigScreen.tsx +23 -23
  86. package/src/screens/auth/VerifyEmailScreen.tsx +1 -1
  87. package/src/screens/auth/WelcomeScreen.tsx +1 -1
@@ -157,9 +157,9 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
157
157
 
158
158
  return (
159
159
  <>
160
- <View className="mb-4 rounded-lg border border-border bg-card p-4 dark:bg-neutral-900/50">
160
+ <View className="mb-4 rounded-lg border border-border dark:border-neutral-800 bg-card p-4 dark:bg-neutral-900/50">
161
161
  <View className="mb-3 flex-row items-center justify-between">
162
- <Text className="text-sm font-medium text-muted-foreground">Generated Password</Text>
162
+ <Text className="text-sm font-medium text-muted-foreground dark:text-neutral-400">Generated Password</Text>
163
163
  <View className="flex-row items-center">
164
164
  <View
165
165
  className="h-2 w-2 rounded-full"
@@ -171,9 +171,9 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
171
171
  </View>
172
172
  </View>
173
173
 
174
- <View className="mb-2 rounded-lg bg-background p-3">
174
+ <View className="mb-2 rounded-lg bg-background dark:bg-black p-3">
175
175
  <Text
176
- className="font-mono text-base text-foreground"
176
+ className="font-mono text-base text-foreground dark:text-white"
177
177
  selectable
178
178
  numberOfLines={2}
179
179
  testID="generator-output"
@@ -187,7 +187,7 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
187
187
  {breach === "checking" ? (
188
188
  <>
189
189
  <ActivityIndicator size="small" color={isDark ? "#a3a3a3" : "#737373"} />
190
- <Text className="text-xs text-muted-foreground">Checking breach database…</Text>
190
+ <Text className="text-xs text-muted-foreground dark:text-neutral-400">Checking breach database…</Text>
191
191
  </>
192
192
  ) : breach === "safe" ? (
193
193
  <>
@@ -203,7 +203,7 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
203
203
  size={12}
204
204
  color={isDark ? "#a3a3a3" : "#737373"}
205
205
  />
206
- <Text className="text-xs text-muted-foreground">
206
+ <Text className="text-xs text-muted-foreground dark:text-neutral-400">
207
207
  Couldn&apos;t check breaches (offline)
208
208
  </Text>
209
209
  </>
@@ -213,14 +213,14 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
213
213
  <View className="flex-row gap-2">
214
214
  <Pressable
215
215
  onPress={handleGenerate}
216
- className="active:scale-98 flex-1 rounded-lg bg-primary px-4 py-3"
216
+ className="active:scale-98 flex-1 rounded-lg bg-primary dark:bg-white px-4 py-3"
217
217
  accessibilityRole="button"
218
218
  accessibilityLabel="Generate password"
219
219
  testID="generator-generate"
220
220
  >
221
221
  <View className="flex-row items-center justify-center">
222
222
  <Ionicons name="refresh" size={18} color={isDark ? "black" : "white"} />
223
- <Text className="ml-2 font-semibold text-primary-foreground">Generate</Text>
223
+ <Text className="ml-2 font-semibold text-primary-foreground dark:text-black">Generate</Text>
224
224
  </View>
225
225
  </Pressable>
226
226
 
@@ -228,14 +228,14 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
228
228
  <Pressable
229
229
  onPress={handleCopy}
230
230
  disabled={!password}
231
- className="active:scale-98 rounded-lg bg-secondary px-4 py-3"
231
+ className="active:scale-98 rounded-lg bg-secondary dark:bg-neutral-800 px-4 py-3"
232
232
  accessibilityRole="button"
233
233
  accessibilityLabel="Copy password"
234
234
  accessibilityState={{ disabled: !password }}
235
235
  >
236
236
  <View className="flex-row items-center justify-center">
237
237
  <Ionicons name="copy-outline" size={18} color={isDark ? "white" : "black"} />
238
- <Text className="ml-2 font-semibold text-foreground">Copy</Text>
238
+ <Text className="ml-2 font-semibold text-foreground dark:text-white">Copy</Text>
239
239
  </View>
240
240
  </Pressable>
241
241
  )}
@@ -244,27 +244,27 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
244
244
  <Pressable
245
245
  onPress={() => onSelect(password)}
246
246
  disabled={!password}
247
- className="active:scale-98 rounded-lg bg-secondary px-4 py-3"
247
+ className="active:scale-98 rounded-lg bg-secondary dark:bg-neutral-800 px-4 py-3"
248
248
  accessibilityRole="button"
249
249
  accessibilityLabel="Use password"
250
250
  accessibilityState={{ disabled: !password }}
251
251
  >
252
252
  <View className="flex-row items-center justify-center">
253
253
  <Ionicons name="checkmark" size={18} color={isDark ? "white" : "black"} />
254
- <Text className="ml-2 font-semibold text-foreground">Use</Text>
254
+ <Text className="ml-2 font-semibold text-foreground dark:text-white">Use</Text>
255
255
  </View>
256
256
  </Pressable>
257
257
  )}
258
258
  </View>
259
259
  </View>
260
260
 
261
- <View className="rounded-lg border border-border bg-card p-4 dark:bg-neutral-900/50">
262
- <Text className="mb-4 text-base font-semibold text-foreground">Options</Text>
261
+ <View className="rounded-lg border border-border dark:border-neutral-800 bg-card p-4 dark:bg-neutral-900/50">
262
+ <Text className="mb-4 text-base font-semibold text-foreground dark:text-white">Options</Text>
263
263
 
264
264
  <View className="mb-5">
265
265
  <View className="mb-2 flex-row items-center justify-between">
266
- <Text className="text-sm text-foreground">Password Length</Text>
267
- <Text className="font-mono text-sm font-semibold text-primary">{length}</Text>
266
+ <Text className="text-sm text-foreground dark:text-white">Password Length</Text>
267
+ <Text className="font-mono text-sm font-semibold text-primary dark:text-white">{length}</Text>
268
268
  </View>
269
269
  <Slider
270
270
  value={length}
@@ -280,8 +280,8 @@ export const PasswordGenerator = React.memo(function PasswordGenerator({
280
280
  accessibilityRole="adjustable"
281
281
  />
282
282
  <View className="mt-1 flex-row justify-between">
283
- <Text className="text-xs text-muted-foreground">8</Text>
284
- <Text className="text-xs text-muted-foreground">128</Text>
283
+ <Text className="text-xs text-muted-foreground dark:text-neutral-400">8</Text>
284
+ <Text className="text-xs text-muted-foreground dark:text-neutral-400">128</Text>
285
285
  </View>
286
286
  </View>
287
287
 
@@ -107,9 +107,9 @@ export function PinPad({
107
107
  className={
108
108
  i < pin.length
109
109
  ? error
110
- ? "h-3.5 w-3.5 rounded-full bg-destructive"
111
- : "h-3.5 w-3.5 rounded-full bg-primary"
112
- : "h-3.5 w-3.5 rounded-full border-2 border-border"
110
+ ? "h-3.5 w-3.5 rounded-full bg-destructive dark:bg-red-900"
111
+ : "h-3.5 w-3.5 rounded-full bg-primary dark:bg-white"
112
+ : "h-3.5 w-3.5 rounded-full border-2 border-border dark:border-neutral-800"
113
113
  }
114
114
  />
115
115
  ))}
@@ -144,11 +144,13 @@ function Key({
144
144
  return (
145
145
  <Pressable
146
146
  onPress={onPress}
147
- className="h-20 w-20 items-center justify-center rounded-full active:bg-secondary"
147
+ className="h-20 w-20 items-center justify-center rounded-full active:bg-secondary dark:active:bg-neutral-800"
148
148
  accessibilityRole="button"
149
149
  accessibilityLabel={label ?? "key"}
150
150
  >
151
- {icon ?? <Text className="font-sans-medium text-2xl text-foreground">{label}</Text>}
151
+ {icon ?? (
152
+ <Text className="font-sans-medium text-2xl text-foreground dark:text-white">{label}</Text>
153
+ )}
152
154
  </Pressable>
153
155
  );
154
156
  }
@@ -23,7 +23,7 @@ const PopoverContent = React.forwardRef<
23
23
  align={align}
24
24
  side={side}
25
25
  className={cn(
26
- "z-50 w-72 rounded-lg border border-border p-4",
26
+ "z-50 w-72 rounded-lg border border-border dark:border-neutral-800 p-4",
27
27
  isDark ? "bg-neutral-900" : "bg-white",
28
28
  Platform.OS === "web" && "shadow-lg",
29
29
  className
@@ -72,7 +72,7 @@ export function SettingsRow({
72
72
  <Text
73
73
  className={cn(
74
74
  "text-sm font-medium",
75
- destructive ? "text-destructive" : "text-foreground"
75
+ destructive ? "text-destructive dark:text-red-900" : "text-foreground"
76
76
  )}
77
77
  >
78
78
  {label}
@@ -113,7 +113,7 @@ export function SettingsSection({ title, destructive, children }: SettingsSectio
113
113
  <Text
114
114
  className={cn(
115
115
  "mb-2 text-xs font-semibold tracking-wider",
116
- destructive ? "text-destructive" : "text-muted-foreground"
116
+ destructive ? "text-destructive dark:text-red-900" : "text-muted-foreground dark:text-neutral-400"
117
117
  )}
118
118
  >
119
119
  {title}
@@ -47,7 +47,7 @@ export function AccountPickerScreen({
47
47
  const isDark = colorScheme === "dark";
48
48
 
49
49
  return (
50
- <SafeAreaView className="flex-1 bg-background">
50
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
51
51
  <StatusBar style={isDark ? "light" : "dark"} />
52
52
  <ScrollView
53
53
  className="flex-1"
@@ -666,7 +666,7 @@ export function AuthScreen({
666
666
  </>
667
667
  )}
668
668
  </CardContent>
669
- <CardFooter className="flex-col gap-3 border-t-0 pt-0">
669
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0 pt-0">
670
670
  {forgotSent ? (
671
671
  <Button
672
672
  className="w-full"
@@ -908,7 +908,7 @@ export function AuthScreen({
908
908
  )}
909
909
  </CardContent>
910
910
 
911
- <CardFooter className="flex-col gap-3 border-t-0 pt-0">
911
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0 pt-0">
912
912
  <FormError message={firstError} />
913
913
 
914
914
  <Button
@@ -51,7 +51,7 @@ export function ConsentScreen({
51
51
  const isDark = colorScheme === "dark";
52
52
 
53
53
  return (
54
- <SafeAreaView className="flex-1 bg-background">
54
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
55
55
  <StatusBar style={isDark ? "light" : "dark"} />
56
56
  <ScrollView
57
57
  className="flex-1"
@@ -85,11 +85,11 @@ export function ConsentScreen({
85
85
  ))
86
86
  )}
87
87
  {error ? (
88
- <Text className="text-sm text-destructive">{error}</Text>
88
+ <Text className="text-sm text-destructive dark:text-red-900">{error}</Text>
89
89
  ) : null}
90
90
  </CardContent>
91
91
 
92
- <CardFooter className="flex-col gap-3 border-t-0">
92
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
93
93
  <Button
94
94
  className="w-full"
95
95
  telemetryId="auth.consent.allow"
@@ -43,7 +43,7 @@ export function ErrorScreen({
43
43
  const isDark = colorScheme === "dark";
44
44
 
45
45
  return (
46
- <SafeAreaView className="flex-1 bg-background">
46
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
47
47
  <StatusBar style={isDark ? "light" : "dark"} />
48
48
  <ScrollView
49
49
  className="flex-1"
@@ -63,7 +63,7 @@ export function ErrorScreen({
63
63
  ) : null}
64
64
 
65
65
  {onRetry || onHome ? (
66
- <CardFooter className="flex-col gap-3 border-t-0">
66
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
67
67
  {onRetry ? (
68
68
  <Button
69
69
  className="w-full"
@@ -40,7 +40,7 @@ export function ExpiredLinkScreen({
40
40
  const isDark = colorScheme === "dark";
41
41
 
42
42
  return (
43
- <SafeAreaView className="flex-1 bg-background">
43
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
44
44
  <StatusBar style={isDark ? "light" : "dark"} />
45
45
  <ScrollView
46
46
  className="flex-1"
@@ -54,7 +54,7 @@ export function ExpiredLinkScreen({
54
54
  </CardHeader>
55
55
 
56
56
  {onRequestNew || onHome ? (
57
- <CardFooter className="flex-col gap-3 border-t-0">
57
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
58
58
  {onRequestNew ? (
59
59
  <Button
60
60
  className="w-full"
@@ -70,7 +70,7 @@ export function ForgotPasswordScreen() {
70
70
  };
71
71
 
72
72
  return (
73
- <SafeAreaView className="flex-1 bg-background">
73
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
74
74
  <StatusBar style={isDark ? "light" : "dark"} />
75
75
  <ScrollView
76
76
  className="flex-1"
@@ -119,7 +119,7 @@ export function ForgotPasswordScreen() {
119
119
  />
120
120
  </CardContent>
121
121
 
122
- <CardFooter className="flex-col gap-3 border-t-0">
122
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
123
123
  <Button
124
124
  className="w-full"
125
125
  telemetryId="auth.forgot_password.submit"
@@ -145,7 +145,7 @@ export function ForgotPasswordScreen() {
145
145
  </CardFooter>
146
146
  </>
147
147
  ) : (
148
- <CardFooter className="flex-col gap-3 border-t-0">
148
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
149
149
  <Button
150
150
  className="w-full"
151
151
  telemetryId="auth.forgot_password.push_2"
@@ -55,7 +55,7 @@ export function ImportDataScreen({ renderImport }: ImportDataScreenProps = {}) {
55
55
 
56
56
  if (renderImport) {
57
57
  return (
58
- <SafeAreaView className="flex-1 bg-background">
58
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
59
59
  <StatusBar style={isDark ? "light" : "dark"} />
60
60
  {renderImport({ onComplete: completeAndNavigate, onSkip: completeAndNavigate })}
61
61
  </SafeAreaView>
@@ -63,7 +63,7 @@ export function ImportDataScreen({ renderImport }: ImportDataScreenProps = {}) {
63
63
  }
64
64
 
65
65
  return (
66
- <SafeAreaView className="flex-1 bg-background">
66
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
67
67
  <StatusBar style={isDark ? "light" : "dark"} />
68
68
  <ScrollView
69
69
  className="flex-1"
@@ -269,7 +269,7 @@ export function LoginScreen({
269
269
 
270
270
  return (
271
271
  <>
272
- <SafeAreaView className="flex-1 bg-background">
272
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
273
273
  <StatusBar style={isDark ? "light" : "dark"} />
274
274
  <ScrollView
275
275
  className="flex-1"
@@ -387,7 +387,7 @@ export function LoginScreen({
387
387
  </View>
388
388
  </CardContent>
389
389
 
390
- <CardFooter className="flex-col gap-3 border-t-0">
390
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
391
391
  <MutedText className="text-center text-sm">
392
392
  Don&apos;t have an account?{" "}
393
393
  <Text
@@ -160,7 +160,7 @@ export function MfaEnrollScreen({ authenticatorAppPromo }: MfaEnrollScreenProps
160
160
  };
161
161
 
162
162
  return (
163
- <SafeAreaView className="flex-1 bg-background">
163
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
164
164
  <StatusBar style={isDark ? "light" : "dark"} />
165
165
  <ScrollView
166
166
  className="flex-1"
@@ -189,7 +189,7 @@ export function MfaEnrollScreen({ authenticatorAppPromo }: MfaEnrollScreenProps
189
189
  <CardContent className="gap-3">{authenticatorAppPromo}</CardContent>
190
190
  ) : null}
191
191
 
192
- <CardFooter className="flex-col gap-3 border-t-0">
192
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
193
193
  <Button
194
194
  className="w-full"
195
195
  telemetryId="auth.mfa_enroll.start_setup"
@@ -293,7 +293,7 @@ export function MfaEnrollScreen({ authenticatorAppPromo }: MfaEnrollScreenProps
293
293
  </View>
294
294
  </CardContent>
295
295
 
296
- <CardFooter className="flex-col gap-3 border-t-0">
296
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
297
297
  <Button
298
298
  className="w-full"
299
299
  telemetryId="auth.mfa_enroll.verify_code"
@@ -39,7 +39,7 @@ export function PasskeyEnrollScreen({
39
39
  const isDark = colorScheme === "dark";
40
40
 
41
41
  return (
42
- <SafeAreaView className="flex-1 bg-background">
42
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
43
43
  <StatusBar style={isDark ? "light" : "dark"} />
44
44
  <ScrollView
45
45
  className="flex-1"
@@ -58,7 +58,7 @@ export function PasskeyEnrollScreen({
58
58
 
59
59
  <CardContent className="gap-2">
60
60
  {error ? (
61
- <Text className="text-sm text-destructive">{error}</Text>
61
+ <Text className="text-sm text-destructive dark:text-red-900">{error}</Text>
62
62
  ) : (
63
63
  <MutedText className="text-sm">
64
64
  You can always add or remove passkeys later in your account
@@ -67,7 +67,7 @@ export function PasskeyEnrollScreen({
67
67
  )}
68
68
  </CardContent>
69
69
 
70
- <CardFooter className="flex-col gap-3 border-t-0">
70
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
71
71
  <Button
72
72
  className="w-full"
73
73
  telemetryId="auth.passkey_enroll.enroll"
@@ -210,7 +210,7 @@ export function RegisterScreen({
210
210
  };
211
211
 
212
212
  return (
213
- <SafeAreaView className="flex-1 bg-background">
213
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
214
214
  <StatusBar style={isDark ? "light" : "dark"} />
215
215
  <KeyboardAvoidingView
216
216
  behavior={Platform.OS === "ios" ? "padding" : "height"}
@@ -381,7 +381,7 @@ export function RegisterScreen({
381
381
  </ShakeField>
382
382
  </CardContent>
383
383
 
384
- <CardFooter className="flex-col gap-3 border-t-0">
384
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
385
385
  <MutedText className="text-center text-sm">
386
386
  Already have an account?{" "}
387
387
  <Text
@@ -219,7 +219,7 @@ export function ResetPasswordScreen({ encryptionWarning }: ResetPasswordScreenPr
219
219
  };
220
220
 
221
221
  return (
222
- <SafeAreaView className="flex-1 bg-background">
222
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
223
223
  <StatusBar style={isDark ? "light" : "dark"} />
224
224
  <ScrollView
225
225
  className="flex-1"
@@ -267,7 +267,7 @@ export function ResetPasswordScreen({ encryptionWarning }: ResetPasswordScreenPr
267
267
  </ShakeField>
268
268
  </CardContent>
269
269
 
270
- <CardFooter className="flex-col gap-3 border-t-0">
270
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
271
271
  <FormError message={firstError} />
272
272
 
273
273
  <Button
@@ -345,7 +345,7 @@ export function ResetPasswordScreen({ encryptionWarning }: ResetPasswordScreenPr
345
345
  </ShakeField>
346
346
  </CardContent>
347
347
 
348
- <CardFooter className="flex-col gap-3 border-t-0">
348
+ <CardFooter className="flex-col items-stretch gap-3 border-t-0">
349
349
  <FormError message={firstError} />
350
350
 
351
351
  <Button
@@ -223,7 +223,7 @@ export function ServerConfigScreen({
223
223
 
224
224
  if (isLoading) {
225
225
  return (
226
- <SafeAreaView className="flex-1 bg-background">
226
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
227
227
  <View className="flex-1 items-center justify-center">
228
228
  <ActivityIndicator size="large" color={isDark ? "white" : "black"} />
229
229
  </View>
@@ -238,7 +238,7 @@ export function ServerConfigScreen({
238
238
  ];
239
239
 
240
240
  return (
241
- <SafeAreaView className="flex-1 bg-background">
241
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
242
242
  <StatusBar style="auto" />
243
243
  <ScrollView className="flex-1">
244
244
  <View className="px-6 py-6">
@@ -247,15 +247,15 @@ export function ServerConfigScreen({
247
247
  onPress={withClickTracking("auth.server_config.back", () => router.back())}
248
248
  accessibilityRole="button"
249
249
  accessibilityLabel="Go back"
250
- className="active:scale-98 h-10 w-10 items-center justify-center rounded-lg bg-secondary"
250
+ className="active:scale-98 h-10 w-10 items-center justify-center rounded-lg bg-secondary dark:bg-neutral-800"
251
251
  >
252
252
  <Ionicons name="close" size={24} color={isDark ? "white" : "black"} />
253
253
  </Pressable>
254
- <Text className="text-lg font-semibold text-foreground">Server Configuration</Text>
254
+ <Text className="text-lg font-semibold text-foreground dark:text-white">Server Configuration</Text>
255
255
  <View className="h-10 w-10" />
256
256
  </View>
257
257
 
258
- <View className="mb-6 rounded-lg bg-secondary p-4">
258
+ <View className="mb-6 rounded-lg bg-secondary dark:bg-neutral-800 p-4">
259
259
  <View className="flex-row items-start">
260
260
  <Ionicons
261
261
  name="information-circle"
@@ -263,10 +263,10 @@ export function ServerConfigScreen({
263
263
  color={isDark ? "#3b82f6" : "#2563eb"}
264
264
  />
265
265
  <View className="ml-3 flex-1">
266
- <Text className="mb-1 text-sm font-semibold text-foreground">
266
+ <Text className="mb-1 text-sm font-semibold text-foreground dark:text-white">
267
267
  Self-Hosted Server
268
268
  </Text>
269
- <Text className="text-xs text-muted-foreground">
269
+ <Text className="text-xs text-muted-foreground dark:text-neutral-400">
270
270
  Configure your own {appName} server for complete control over your data. Default
271
271
  server: {defaultUrl}
272
272
  </Text>
@@ -275,8 +275,8 @@ export function ServerConfigScreen({
275
275
  </View>
276
276
 
277
277
  <View className="mb-6">
278
- <Text className="mb-2 text-sm font-medium text-foreground">Server URL</Text>
279
- <View className="flex-row items-center rounded-lg border border-border bg-background px-3 py-3">
278
+ <Text className="mb-2 text-sm font-medium text-foreground dark:text-white">Server URL</Text>
279
+ <View className="flex-row items-center rounded-lg border border-border dark:border-neutral-800 bg-background dark:bg-black px-3 py-3">
280
280
  <Ionicons
281
281
  name="globe-outline"
282
282
  size={20}
@@ -294,7 +294,7 @@ export function ServerConfigScreen({
294
294
  autoCorrect={false}
295
295
  keyboardType="url"
296
296
  accessibilityLabel="Server URL"
297
- className="ml-2 flex-1 text-base text-foreground"
297
+ className="ml-2 flex-1 text-base text-foreground dark:text-white"
298
298
  />
299
299
  {connectionStatus === "success" && (
300
300
  <Ionicons name="checkmark-circle" size={20} color="#22c55e" />
@@ -310,12 +310,12 @@ export function ServerConfigScreen({
310
310
  disabled={isTestingConnection}
311
311
  accessibilityRole="button"
312
312
  accessibilityLabel="Test connection"
313
- className="active:scale-98 mb-3 w-full rounded-lg border border-border bg-background px-6 py-4"
313
+ className="active:scale-98 mb-3 w-full rounded-lg border border-border dark:border-neutral-800 bg-background dark:bg-black px-6 py-4"
314
314
  >
315
315
  {isTestingConnection ? (
316
316
  <View className="flex-row items-center justify-center">
317
317
  <ActivityIndicator size="small" color={isDark ? "white" : "black"} />
318
- <Text className="ml-2 text-base font-semibold text-foreground">
318
+ <Text className="ml-2 text-base font-semibold text-foreground dark:text-white">
319
319
  Testing Connection
320
320
  {testAttempt > 0 ? ` (Attempt ${testAttempt}/${defaultMaxRetries})` : "..."}
321
321
  </Text>
@@ -323,7 +323,7 @@ export function ServerConfigScreen({
323
323
  ) : (
324
324
  <View className="flex-row items-center justify-center">
325
325
  <Ionicons name="wifi-outline" size={20} color={isDark ? "white" : "black"} />
326
- <Text className="ml-2 text-base font-semibold text-foreground">
326
+ <Text className="ml-2 text-base font-semibold text-foreground dark:text-white">
327
327
  Test Connection
328
328
  </Text>
329
329
  </View>
@@ -334,11 +334,11 @@ export function ServerConfigScreen({
334
334
  onPress={withClickTracking("auth.server_config.use_default", handleUseDefault)}
335
335
  accessibilityRole="button"
336
336
  accessibilityLabel="Use default server"
337
- className="active:scale-98 mb-3 w-full rounded-lg border border-border bg-background px-6 py-4"
337
+ className="active:scale-98 mb-3 w-full rounded-lg border border-border dark:border-neutral-800 bg-background dark:bg-black px-6 py-4"
338
338
  >
339
339
  <View className="flex-row items-center justify-center">
340
340
  <Ionicons name="cloud-outline" size={20} color={isDark ? "white" : "black"} />
341
- <Text className="ml-2 text-base font-semibold text-foreground">
341
+ <Text className="ml-2 text-base font-semibold text-foreground dark:text-white">
342
342
  Use Default Server
343
343
  </Text>
344
344
  </View>
@@ -348,11 +348,11 @@ export function ServerConfigScreen({
348
348
  onPress={withClickTracking("auth.server_config.clear_configuration", handleClearConfiguration)}
349
349
  accessibilityRole="button"
350
350
  accessibilityLabel="Clear all settings"
351
- className="active:scale-98 mb-3 w-full rounded-lg border border-destructive bg-background px-6 py-3"
351
+ className="active:scale-98 mb-3 w-full rounded-lg border border-destructive dark:border-red-900 bg-background dark:bg-black px-6 py-3"
352
352
  >
353
353
  <View className="flex-row items-center justify-center">
354
354
  <Ionicons name="trash-outline" size={20} color="#ef4444" />
355
- <Text className="ml-2 text-base font-medium text-destructive">
355
+ <Text className="ml-2 text-base font-medium text-destructive dark:text-red-900">
356
356
  Clear All Settings
357
357
  </Text>
358
358
  </View>
@@ -362,20 +362,20 @@ export function ServerConfigScreen({
362
362
  onPress={withClickTracking("auth.server_config.save", handleSave)}
363
363
  accessibilityRole="button"
364
364
  accessibilityLabel="Save configuration"
365
- className="active:scale-98 mb-6 w-full rounded-lg bg-primary px-6 py-4"
365
+ className="active:scale-98 mb-6 w-full rounded-lg bg-primary dark:bg-white px-6 py-4"
366
366
  >
367
- <Text className="text-center text-base font-semibold text-primary-foreground">
367
+ <Text className="text-center text-base font-semibold text-primary-foreground dark:text-black">
368
368
  Save Configuration
369
369
  </Text>
370
370
  </Pressable>
371
371
 
372
- <View className="rounded-lg bg-card p-4">
373
- <Text className="mb-3 text-sm font-semibold text-foreground">Need Help?</Text>
372
+ <View className="rounded-lg bg-card dark:bg-neutral-900/50 p-4">
373
+ <Text className="mb-3 text-sm font-semibold text-foreground dark:text-white">Need Help?</Text>
374
374
  <View className="space-y-2">
375
375
  {bullets.map((bullet, idx) => (
376
376
  <View key={idx} className="flex-row items-start">
377
- <Text className="mr-2 text-sm text-muted-foreground">•</Text>
378
- <Text className="flex-1 text-sm text-muted-foreground">{bullet}</Text>
377
+ <Text className="mr-2 text-sm text-muted-foreground dark:text-neutral-400">•</Text>
378
+ <Text className="flex-1 text-sm text-muted-foreground dark:text-neutral-400">{bullet}</Text>
379
379
  </View>
380
380
  ))}
381
381
  </View>
@@ -214,7 +214,7 @@ export function VerifyEmailScreen() {
214
214
  };
215
215
 
216
216
  return (
217
- <SafeAreaView className="flex-1 bg-background">
217
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
218
218
  <StatusBar style={isDark ? "light" : "dark"} />
219
219
  <ScrollView
220
220
  className="flex-1"
@@ -30,7 +30,7 @@ export function WelcomeScreen({ decoration, topAccessory }: WelcomeScreenProps)
30
30
  const { appName, Logo, routes, tagline } = useAppConfig();
31
31
 
32
32
  return (
33
- <SafeAreaView className="flex-1 bg-background">
33
+ <SafeAreaView className="flex-1 bg-background dark:bg-black">
34
34
  <StatusBar style={isDark ? "light" : "dark"} />
35
35
  <View className="flex-1 items-center justify-center px-6 py-8">
36
36
  {topAccessory}