From 85f2c42fc5669325c274e7ec2bd3075c39d5cb6a Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Thu, 22 Jan 2026 22:02:45 +0100 Subject: [PATCH] Improve admin mobile dark mode contrast --- resources/js/admin/mobile/DashboardPage.tsx | 14 +++++-- .../js/admin/mobile/components/BottomNav.tsx | 8 ++-- .../admin/mobile/components/FormControls.tsx | 26 ++++++++---- .../js/admin/mobile/components/Primitives.tsx | 40 ++++++++++--------- resources/js/admin/mobile/theme.ts | 6 ++- 5 files changed, 59 insertions(+), 35 deletions(-) diff --git a/resources/js/admin/mobile/DashboardPage.tsx b/resources/js/admin/mobile/DashboardPage.tsx index 429386b..5fec460 100644 --- a/resources/js/admin/mobile/DashboardPage.tsx +++ b/resources/js/admin/mobile/DashboardPage.tsx @@ -46,14 +46,19 @@ function DashboardCard({ }: React.ComponentProps & { variant?: 'default' | 'embedded' }) { const theme = useAdminTheme(); const isEmbedded = variant === 'embedded'; + const cardSurface = isEmbedded + ? (theme.surfaceMuted ?? theme.glassSurface ?? theme.surface) + : (theme.glassSurfaceStrong ?? theme.surface); + const cardBorder = theme.glassBorder ?? theme.border; + const cardShadow = theme.glassShadow ?? theme.shadow; return ( (null); @@ -62,7 +62,7 @@ export function BottomNav({ active, onNavigate }: { active: NavKey; onNavigate: const IconCmp = item.icon; // Dynamic Styles - const color = activeState ? theme.primary : theme.subtle; + const color = activeState ? theme.primary : theme.muted; const strokeWidth = activeState ? 2.5 : 2; return ( diff --git a/resources/js/admin/mobile/components/FormControls.tsx b/resources/js/admin/mobile/components/FormControls.tsx index 8739c52..3feffaf 100644 --- a/resources/js/admin/mobile/components/FormControls.tsx +++ b/resources/js/admin/mobile/components/FormControls.tsx @@ -253,9 +253,13 @@ export function MobileSelect({ style, ...props }: MobileSelectProps) { - const { border, surface, text, primary, danger, subtle } = useAdminTheme(); - const borderColor = hasError ? danger : border; + const { border, surface, text, primary, danger, subtle, glassSurfaceStrong, surfaceMuted, glassBorder } = useAdminTheme(); + const borderColor = hasError ? danger : (glassBorder ?? border); const ringColor = hasError ? withAlpha(danger, 0.18) : withAlpha(primary, 0.18); + const triggerSurface = surfaceMuted ?? glassSurfaceStrong ?? surface; + const contentSurface = glassSurfaceStrong ?? surface; + const itemSurface = surface; + const itemHover = surfaceMuted ?? surface; const hasSizing = typeof containerStyle === 'object' && containerStyle !== null && @@ -298,7 +302,7 @@ export function MobileSelect({ borderRadius={12} borderWidth={1} borderColor={borderColor as any} - backgroundColor={surface as any} + backgroundColor={triggerSurface as any} paddingVertical={compact ? 6 : 10} paddingHorizontal="$3" disabled={props.disabled} @@ -320,14 +324,22 @@ export function MobileSelect({ zIndex={200000} {...({ borderRadius: 14 } as any)} borderWidth={1} - borderColor={border} - backgroundColor={surface as any} + borderColor={glassBorder ?? border} + backgroundColor={contentSurface as any} > {options.map((option, index) => ( - - {option.label} + + {option.label} ))} diff --git a/resources/js/admin/mobile/components/Primitives.tsx b/resources/js/admin/mobile/components/Primitives.tsx index d9714f1..a3280b7 100644 --- a/resources/js/admin/mobile/components/Primitives.tsx +++ b/resources/js/admin/mobile/components/Primitives.tsx @@ -44,27 +44,27 @@ export function PillBadge({ tone?: 'success' | 'warning' | 'danger' | 'muted'; children: React.ReactNode; }) { - const { theme } = useAdminTheme(); + const { successText, warningText, dangerText, muted, surfaceMuted, border } = useAdminTheme(); const palette: Record = { success: { - bg: String(theme.backgroundStrong?.val ?? '#ecfdf3'), - text: String(theme.green10?.val ?? '#047857'), - border: String(theme.green6?.val ?? '#bbf7d0'), + bg: withAlpha(successText, 0.16), + text: successText, + border: withAlpha(successText, 0.35), }, warning: { - bg: String(theme.yellow3?.val ?? '#fffbeb'), - text: String(theme.yellow11?.val ?? '#92400e'), - border: String(theme.yellow6?.val ?? '#fef3c7'), + bg: withAlpha(warningText, 0.16), + text: warningText, + border: withAlpha(warningText, 0.35), }, danger: { - bg: String(theme.red3?.val ?? '#FEE2E2'), - text: String(theme.red11?.val ?? '#B91C1C'), - border: String(theme.red6?.val ?? '#FCA5A5'), + bg: withAlpha(dangerText, 0.16), + text: dangerText, + border: withAlpha(dangerText, 0.35), }, muted: { - bg: String(theme.gray3?.val ?? '#f3f4f6'), - text: String(theme.gray11?.val ?? '#374151'), - border: String(theme.gray6?.val ?? '#e5e7eb'), + bg: surfaceMuted, + text: muted, + border, }, }; const colors = palette[tone] ?? palette.muted; @@ -210,7 +210,11 @@ export function KpiStrip({ tone?: 'accent' | 'neutral'; }> }) { - const { glassSurface, border, textStrong, textMuted, primary, surfaceMuted, surface } = useAdminTheme(); + const { glassSurface, glassSurfaceStrong, glassBorder, border, textStrong, textMuted, primary, surfaceMuted, surface } = useAdminTheme(); + const cardSurface = surfaceMuted ?? glassSurfaceStrong ?? glassSurface ?? surface; + const cardBorder = glassBorder ?? border; + const separatorColor = withAlpha(textStrong, 0.12); + const innerSeparatorColor = withAlpha(textStrong, 0.08); return ( @@ -222,10 +226,10 @@ export function KpiStrip({ return ( {item.value} - + {item.label} - + {item.note ? ( {item.note} diff --git a/resources/js/admin/mobile/theme.ts b/resources/js/admin/mobile/theme.ts index c0be95d..05d0a43 100644 --- a/resources/js/admin/mobile/theme.ts +++ b/resources/js/admin/mobile/theme.ts @@ -127,6 +127,8 @@ export function useAdminTheme() { border, text, textStrong: text, // Alias + textMuted: muted, // Alias for legacy usage + textSubtle: subtle, // Alias for legacy usage muted, // Now properly derived from text color subtle, // Now properly derived from text color primary, @@ -134,12 +136,12 @@ export function useAdminTheme() { accentSoft: String(theme.blue3?.val ?? ADMIN_COLORS.accentSoft), accentStrong: String(theme.blue11?.val ?? ADMIN_COLORS.primaryStrong), successBg: String(theme.backgroundStrong?.val ?? '#DCFCE7'), - successText: String(theme.green10?.val ?? '#166534'), + successText: String(theme.green10?.val ?? ADMIN_COLORS.success), dangerBg: String(theme.red3?.val ?? '#FEE2E2'), dangerText: String(theme.red11?.val ?? ADMIN_COLORS.danger), warningBg: String(theme.yellow3?.val ?? '#FEF3C7'), warningBorder: String(theme.yellow6?.val ?? '#FCD34D'), - warningText: String(theme.yellow11?.val ?? '#B45309'), + warningText: String(theme.yellow11?.val ?? ADMIN_COLORS.warning), infoBg: String(theme.blue3?.val ?? ADMIN_COLORS.accentSoft), infoText: String(theme.blue10?.val ?? ADMIN_COLORS.primaryStrong), danger: String(theme.danger?.val ?? ADMIN_COLORS.danger),