diff --git a/apps/mobile/generated-uniwind-default-theme-variables.json b/apps/mobile/generated-uniwind-default-theme-variables.json index 961a0df24cd46f6932622ecb60f86fb72a8caf29..82542b6fb6c34a5b109d35db08fc557e7a5d0b92 100644 --- a/apps/mobile/generated-uniwind-default-theme-variables.json +++ b/apps/mobile/generated-uniwind-default-theme-variables.json @@ -30,6 +30,8 @@ "--color-inline-skill-border": "rgba(27, 78, 216, 0.42)", "--color-inline-skill-foreground": "#18181b", "--color-primary": "#1b4ed8", + "--color-prominent-action": "#27272a", + "--color-prominent-action-foreground": "#fcfcfc", "--color-primary-foreground": "#ffffff", "--color-primary-text": "#1b4ed8", "--color-primary-shadow": "#000000", @@ -119,6 +121,8 @@ "--color-inline-skill-border": "rgba(52, 107, 241, 0.42)", "--color-inline-skill-foreground": "#f5f5f5", "--color-primary": "#346bf1", + "--color-prominent-action": "#f5f5f5", + "--color-prominent-action-foreground": "#0a0a0a", "--color-primary-foreground": "#ffffff", "--color-primary-text": "#4b7cf3", "--color-primary-shadow": "#000000", diff --git a/apps/mobile/generated-uniwind-themes.css b/apps/mobile/generated-uniwind-themes.css index d7720bc50bd92b14a261ae394f74e0b028289bbd..caf91e40348b087c4c4220ccadeb34ead860917c 100644 --- a/apps/mobile/generated-uniwind-themes.css +++ b/apps/mobile/generated-uniwind-themes.css @@ -32,6 +32,8 @@ --color-inline-skill-border: rgba(27, 78, 216, 0.42); --color-inline-skill-foreground: #18181b; --color-primary: #1b4ed8; + --color-prominent-action: #27272a; + --color-prominent-action-foreground: #fcfcfc; --color-primary-foreground: #ffffff; --color-primary-text: #1b4ed8; --color-primary-shadow: #000000; @@ -191,6 +193,8 @@ --color-inline-skill-border: rgba(52, 107, 241, 0.42); --color-inline-skill-foreground: #f5f5f5; --color-primary: #346bf1; + --color-prominent-action: #f5f5f5; + --color-prominent-action-foreground: #0a0a0a; --color-primary-foreground: #ffffff; --color-primary-text: #4b7cf3; --color-primary-shadow: #000000; @@ -324,7 +328,7 @@ --color-sheet: rgba(253, 247, 253, 0.98); --color-sheet-solid: #fdf7fd; --color-card: #faf3fb; - --color-grouped-card: #faf3fb; + --color-grouped-card: #f3e6f5; --color-card-alt: #fdfafd; --color-card-translucent: rgba(250, 243, 251, 0.8); --color-thread-canvas: #fdf7fd; @@ -334,8 +338,8 @@ --color-thread-hover: #f8f8f7; --color-row-hover: #eccfe3; --color-composer-panel: rgba(253, 247, 253, 0.88); - --color-composer-surface: rgba(250, 243, 251, 0.94); - --color-composer-border: rgba(238, 225, 237, 0.54); + --color-composer-surface: rgba(243, 230, 245, 0.94); + --color-composer-border: rgba(238, 225, 237, 0.8); --color-foreground: #501854; --color-foreground-secondary: #ab1668; --color-foreground-muted: #8d1255; @@ -350,6 +354,8 @@ --color-inline-skill-border: rgba(219, 39, 119, 0.42); --color-inline-skill-foreground: #454554; --color-primary: #db2777; + --color-prominent-action: #501854; + --color-prominent-action-foreground: #fdf7fd; --color-primary-foreground: #ffffff; --color-primary-text: #aa1e5d; --color-primary-shadow: #000000; @@ -379,7 +385,7 @@ --color-header-foreground: #501854; --color-header-border: #efbdeb; --color-glass-surface: rgba(255, 255, 255, 0.74); - --color-glass-fallback: rgba(250, 243, 251, 0.94); + --color-glass-fallback: rgba(243, 230, 245, 0.94); --color-glass-tint: rgba(255, 255, 255, 0.22); --color-status-bar: #fdf7fd; --color-md-body: #501854; @@ -509,6 +515,8 @@ --color-inline-skill-border: rgba(163, 0, 76, 0.42); --color-inline-skill-foreground: #f8f1f5; --color-primary: #a3004c; + --color-prominent-action: #fbd0e8; + --color-prominent-action-foreground: #a3004c; --color-primary-foreground: #fbd0e8; --color-primary-text: #d07ea4; --color-primary-shadow: #000000; @@ -642,7 +650,7 @@ --color-sheet: rgba(243, 247, 244, 0.98); --color-sheet-solid: #f3f7f4; --color-card: #f3f7f4; - --color-grouped-card: #ecefed; + --color-grouped-card: #e6f0ea; --color-card-alt: #ecefed; --color-card-translucent: rgba(243, 247, 244, 0.8); --color-thread-canvas: #f3f7f4; @@ -652,7 +660,7 @@ --color-thread-hover: #cae0d5; --color-row-hover: #d5e6dd; --color-composer-panel: rgba(243, 247, 244, 0.88); - --color-composer-surface: rgba(236, 239, 237, 0.94); + --color-composer-surface: rgba(230, 240, 234, 0.94); --color-composer-border: rgba(203, 213, 209, 0.8); --color-foreground: #241523; --color-foreground-secondary: #6f686f; @@ -668,6 +676,8 @@ --color-inline-skill-border: rgba(27, 125, 80, 0.42); --color-inline-skill-foreground: #241523; --color-primary: #8f6410; + --color-prominent-action: #8f6410; + --color-prominent-action-foreground: #fffaff; --color-primary-foreground: #fffaff; --color-primary-text: #8d6210; --color-primary-shadow: #000000; @@ -697,7 +707,7 @@ --color-header-foreground: #241523; --color-header-border: #d5e6dd; --color-glass-surface: rgba(231, 233, 232, 0.74); - --color-glass-fallback: rgba(236, 239, 237, 0.94); + --color-glass-fallback: rgba(230, 240, 234, 0.94); --color-glass-tint: rgba(231, 233, 232, 0.22); --color-status-bar: #f3f7f4; --color-md-body: #241523; @@ -801,7 +811,7 @@ --color-sheet: rgba(27, 40, 33, 0.98); --color-sheet-solid: #1b2821; --color-card: #1b2821; - --color-grouped-card: #36413c; + --color-grouped-card: #253e31; --color-card-alt: #36413c; --color-card-translucent: rgba(27, 40, 33, 0.8); --color-thread-canvas: #1b2821; @@ -811,7 +821,7 @@ --color-thread-hover: #2a4938; --color-row-hover: #325c46; --color-composer-panel: rgba(27, 40, 33, 0.92); - --color-composer-surface: rgba(54, 65, 60, 0.9); + --color-composer-surface: rgba(37, 62, 49, 0.9); --color-composer-border: rgba(65, 95, 79, 0.8); --color-foreground: #fffaff; --color-foreground-secondary: #afb1b1; @@ -827,6 +837,8 @@ --color-inline-skill-border: rgba(105, 214, 154, 0.42); --color-inline-skill-foreground: #fffaff; --color-primary: #e3b34e; + --color-prominent-action: #e3b34e; + --color-prominent-action-foreground: #241523; --color-primary-foreground: #241523; --color-primary-text: #e3b34e; --color-primary-shadow: #000000; @@ -856,7 +868,7 @@ --color-header-foreground: #fffaff; --color-header-border: #36654c; --color-glass-surface: rgba(68, 77, 73, 0.74); - --color-glass-fallback: rgba(54, 65, 60, 0.9); + --color-glass-fallback: rgba(37, 62, 49, 0.9); --color-glass-tint: rgba(68, 77, 73, 0.22); --color-status-bar: #1b2821; --color-md-body: #fffaff; @@ -960,7 +972,7 @@ --color-sheet: rgba(245, 247, 248, 0.98); --color-sheet-solid: #f5f7f8; --color-card: #f5f7f8; - --color-grouped-card: #edeff1; + --color-grouped-card: #e8eff4; --color-card-alt: #edeff1; --color-card-translucent: rgba(245, 247, 248, 0.8); --color-thread-canvas: #f5f7f8; @@ -970,7 +982,7 @@ --color-thread-hover: #cdddea; --color-row-hover: #d8e4ee; --color-composer-panel: rgba(245, 247, 248, 0.88); - --color-composer-surface: rgba(237, 239, 241, 0.94); + --color-composer-surface: rgba(232, 239, 244, 0.94); --color-composer-border: rgba(205, 212, 220, 0.8); --color-foreground: #241523; --color-foreground-secondary: #706870; @@ -986,6 +998,8 @@ --color-inline-skill-border: rgba(38, 114, 175, 0.42); --color-inline-skill-foreground: #241523; --color-primary: #0a6f75; + --color-prominent-action: #0a6f75; + --color-prominent-action-foreground: #fffaff; --color-primary-foreground: #fffaff; --color-primary-text: #0a6f75; --color-primary-shadow: #000000; @@ -1015,7 +1029,7 @@ --color-header-foreground: #241523; --color-header-border: #d8e4ee; --color-glass-surface: rgba(232, 233, 235, 0.74); - --color-glass-fallback: rgba(237, 239, 241, 0.94); + --color-glass-fallback: rgba(232, 239, 244, 0.94); --color-glass-tint: rgba(232, 233, 235, 0.22); --color-status-bar: #f5f7f8; --color-md-body: #241523; @@ -1119,7 +1133,7 @@ --color-sheet: rgba(23, 33, 43, 0.98); --color-sheet-solid: #17212b; --color-card: #17212b; - --color-grouped-card: #333b45; + --color-grouped-card: #233544; --color-card-alt: #333b45; --color-card-translucent: rgba(23, 33, 43, 0.8); --color-thread-canvas: #17212b; @@ -1129,7 +1143,7 @@ --color-thread-hover: #283e50; --color-row-hover: #324e66; --color-composer-panel: rgba(23, 33, 43, 0.92); - --color-composer-surface: rgba(51, 59, 69, 0.9); + --color-composer-surface: rgba(35, 53, 68, 0.9); --color-composer-border: rgba(64, 85, 103, 0.8); --color-foreground: #fffaff; --color-foreground-secondary: #a5a7ad; @@ -1145,6 +1159,8 @@ --color-inline-skill-border: rgba(112, 185, 238, 0.42); --color-inline-skill-foreground: #fffaff; --color-primary: #5bd0d6; + --color-prominent-action: #5bd0d6; + --color-prominent-action-foreground: #241523; --color-primary-foreground: #241523; --color-primary-text: #5bd0d6; --color-primary-shadow: #000000; @@ -1174,7 +1190,7 @@ --color-header-foreground: #fffaff; --color-header-border: #36566f; --color-glass-surface: rgba(65, 72, 81, 0.74); - --color-glass-fallback: rgba(51, 59, 69, 0.9); + --color-glass-fallback: rgba(35, 53, 68, 0.9); --color-glass-tint: rgba(65, 72, 81, 0.22); --color-status-bar: #17212b; --color-md-body: #fffaff; @@ -1278,7 +1294,7 @@ --color-sheet: rgba(249, 247, 245, 0.98); --color-sheet-solid: #f9f7f5; --color-card: #f9f7f5; - --color-grouped-card: #f1efee; + --color-grouped-card: #f4ede9; --color-card-alt: #f1efee; --color-card-translucent: rgba(249, 247, 245, 0.8); --color-thread-canvas: #f9f7f5; @@ -1288,7 +1304,7 @@ --color-thread-hover: #ead8cf; --color-row-hover: #eee0d9; --color-composer-panel: rgba(249, 247, 245, 0.88); - --color-composer-surface: rgba(241, 239, 238, 0.94); + --color-composer-surface: rgba(244, 237, 233, 0.94); --color-composer-border: rgba(221, 210, 206, 0.8); --color-foreground: #241523; --color-foreground-secondary: #726870; @@ -1304,6 +1320,8 @@ --color-inline-skill-border: rgba(174, 85, 42, 0.42); --color-inline-skill-foreground: #241523; --color-primary: #b23535; + --color-prominent-action: #b23535; + --color-prominent-action-foreground: #fffaff; --color-primary-foreground: #fffaff; --color-primary-text: #b23535; --color-primary-shadow: #000000; @@ -1333,7 +1351,7 @@ --color-header-foreground: #241523; --color-header-border: #eee0d9; --color-glass-surface: rgba(236, 233, 233, 0.74); - --color-glass-fallback: rgba(241, 239, 238, 0.94); + --color-glass-fallback: rgba(244, 237, 233, 0.94); --color-glass-tint: rgba(236, 233, 233, 0.22); --color-status-bar: #f9f7f5; --color-md-body: #241523; @@ -1437,7 +1455,7 @@ --color-sheet: rgba(41, 30, 26, 0.98); --color-sheet-solid: #291e1a; --color-card: #291e1a; - --color-grouped-card: #433835; + --color-grouped-card: #432e23; --color-card-alt: #433835; --color-card-translucent: rgba(41, 30, 26, 0.8); --color-thread-canvas: #291e1a; @@ -1447,7 +1465,7 @@ --color-thread-hover: #4f3528; --color-row-hover: #644330; --color-composer-panel: rgba(41, 30, 26, 0.92); - --color-composer-surface: rgba(67, 56, 53, 0.9); + --color-composer-surface: rgba(67, 46, 35, 0.9); --color-composer-border: rgba(102, 76, 63, 0.8); --color-foreground: #fffaff; --color-foreground-secondary: #aca5a6; @@ -1463,6 +1481,8 @@ --color-inline-skill-border: rgba(240, 154, 100, 0.42); --color-inline-skill-foreground: #fffaff; --color-primary: #f78a7a; + --color-prominent-action: #f78a7a; + --color-prominent-action-foreground: #241523; --color-primary-foreground: #241523; --color-primary-text: #f78a7a; --color-primary-shadow: #000000; @@ -1492,7 +1512,7 @@ --color-header-foreground: #fffaff; --color-header-border: #6e4934; --color-glass-surface: rgba(79, 69, 67, 0.74); - --color-glass-fallback: rgba(67, 56, 53, 0.9); + --color-glass-fallback: rgba(67, 46, 35, 0.9); --color-glass-tint: rgba(79, 69, 67, 0.22); --color-status-bar: #291e1a; --color-md-body: #fffaff; @@ -1596,7 +1616,7 @@ --color-sheet: rgba(248, 247, 249, 0.98); --color-sheet-solid: #f8f7f9; --color-card: #f8f7f9; - --color-grouped-card: #f0eff2; + --color-grouped-card: #f0edf6; --color-card-alt: #f0eff2; --color-card-translucent: rgba(248, 247, 249, 0.8); --color-thread-canvas: #f8f7f9; @@ -1606,7 +1626,7 @@ --color-thread-hover: #ded8ed; --color-row-hover: #e5e0f0; --color-composer-panel: rgba(248, 247, 249, 0.88); - --color-composer-surface: rgba(240, 239, 242, 0.94); + --color-composer-surface: rgba(240, 237, 246, 0.94); --color-composer-border: rgba(214, 209, 222, 0.8); --color-foreground: #241523; --color-foreground-secondary: #716871; @@ -1622,6 +1642,8 @@ --color-inline-skill-border: rgba(114, 83, 185, 0.42); --color-inline-skill-foreground: #241523; --color-primary: #a82c87; + --color-prominent-action: #a82c87; + --color-prominent-action-foreground: #fffaff; --color-primary-foreground: #fffaff; --color-primary-text: #a82c87; --color-primary-shadow: #000000; @@ -1651,7 +1673,7 @@ --color-header-foreground: #241523; --color-header-border: #e5e0f0; --color-glass-surface: rgba(235, 233, 237, 0.74); - --color-glass-fallback: rgba(240, 239, 242, 0.94); + --color-glass-fallback: rgba(240, 237, 246, 0.94); --color-glass-tint: rgba(235, 233, 237, 0.22); --color-status-bar: #f8f7f9; --color-md-body: #241523; @@ -1755,7 +1777,7 @@ --color-sheet: rgba(29, 25, 41, 0.98); --color-sheet-solid: #1d1929; --color-card: #1d1929; - --color-grouped-card: #383443; + --color-grouped-card: #2d2643; --color-card-alt: #383443; --color-card-translucent: rgba(29, 25, 41, 0.8); --color-thread-canvas: #1d1929; @@ -1765,7 +1787,7 @@ --color-thread-hover: #352c4f; --color-row-hover: #433765; --color-composer-panel: rgba(29, 25, 41, 0.92); - --color-composer-surface: rgba(56, 52, 67, 0.9); + --color-composer-surface: rgba(45, 38, 67, 0.9); --color-composer-border: rgba(77, 67, 102, 0.8); --color-foreground: #fffaff; --color-foreground-secondary: #a09da6; @@ -1781,6 +1803,8 @@ --color-inline-skill-border: rgba(157, 125, 242, 0.42); --color-inline-skill-foreground: #fffaff; --color-primary: #f099d8; + --color-prominent-action: #f099d8; + --color-prominent-action-foreground: #241523; --color-primary-foreground: #241523; --color-primary-text: #f099d8; --color-primary-shadow: #000000; @@ -1810,7 +1834,7 @@ --color-header-foreground: #fffaff; --color-header-border: #4a3c70; --color-glass-surface: rgba(69, 66, 80, 0.74); - --color-glass-fallback: rgba(56, 52, 67, 0.9); + --color-glass-fallback: rgba(45, 38, 67, 0.9); --color-glass-tint: rgba(69, 66, 80, 0.22); --color-status-bar: #1d1929; --color-md-body: #fffaff; diff --git a/apps/mobile/src/components/ProjectCloneBanner.tsx b/apps/mobile/src/components/ProjectCloneBanner.tsx index 06c121960d79c11d67705d1e3b5e34a993ff8b12..b52a2d4fe0377366b87c19570b45f0706adc7da6 100644 --- a/apps/mobile/src/components/ProjectCloneBanner.tsx +++ b/apps/mobile/src/components/ProjectCloneBanner.tsx @@ -73,7 +73,7 @@ function BannerAction(props: { readonly label: string; readonly onPress: () => v {props.label} diff --git a/apps/mobile/src/features/browser/PreviewStreamWebView.tsx b/apps/mobile/src/features/browser/PreviewStreamWebView.tsx index 9a6bd6a684022676e9bef85497f27728a0d3b7d7..081e81f1357c1a391e7b330a3c6d7dddb3fe6224 100644 --- a/apps/mobile/src/features/browser/PreviewStreamWebView.tsx +++ b/apps/mobile/src/features/browser/PreviewStreamWebView.tsx @@ -461,7 +461,9 @@ function PreviewStreamDocumentView({ {control.dialog.type === "prompt" ? ( diff --git a/apps/mobile/src/features/files/FileTreeBrowser.tsx b/apps/mobile/src/features/files/FileTreeBrowser.tsx index 30e034ac9859708c77d5b570b6359a9f08a42caa..f96de3cbe5edbbffd32b7822c31109195e1a9514 100644 --- a/apps/mobile/src/features/files/FileTreeBrowser.tsx +++ b/apps/mobile/src/features/files/FileTreeBrowser.tsx @@ -54,6 +54,7 @@ const FileTreeRow = memo(function FileTreeRow(props: { { if (node.kind === "file") { props.onPreviewFile?.(node.path); @@ -68,7 +69,7 @@ const FileTreeRow = memo(function FileTreeRow(props: { }} className={cn( "mx-2 min-h-[42px] flex-row items-center gap-2 rounded-[12px] px-2 active:bg-subtle", - props.selected && "bg-subtle-strong", + props.selected && "bg-thread-selected", )} style={{ paddingLeft: 8 + depth * 18 }} > @@ -87,7 +88,7 @@ const FileTreeRow = memo(function FileTreeRow(props: { className={cn( "min-w-0 flex-1 text-sm leading-normal", props.selected - ? "font-t3-bold text-foreground" + ? "font-t3-bold text-thread-selected-foreground" : node.ignored ? "font-t3-medium text-foreground-tertiary" : "font-t3-medium text-foreground-secondary", diff --git a/apps/mobile/src/features/pull-requests/PullRequestControls.tsx b/apps/mobile/src/features/pull-requests/PullRequestControls.tsx index 5bad565b2a40f35e0bc1a4f03d010219734a359c..804be98dfc4bc7e1f235620653f118e44ae5a8a9 100644 --- a/apps/mobile/src/features/pull-requests/PullRequestControls.tsx +++ b/apps/mobile/src/features/pull-requests/PullRequestControls.tsx @@ -23,7 +23,7 @@ export function PullRequestCardGroup(props: { readonly children: ReactNode }) { return ( {props.children} @@ -218,7 +218,7 @@ export function PullRequestActionToolbar(props: { : "bubble.left.and.bubble.right" : undefined } - tintColor={colors["--color-foreground"]} + tintColor={colors["--color-prominent-action"]} disabled={primaryDisabled} separateBackground > @@ -237,7 +237,7 @@ export function PullRequestActionToolbar(props: { : "bubble.left.and.bubble.right" : undefined } - tintColor={colors["--color-foreground"]} + tintColor={colors["--color-prominent-action"]} disabled={primaryDisabled} onPress={primaryPress} separateBackground diff --git a/apps/mobile/src/features/pull-requests/PullRequestFiles.tsx b/apps/mobile/src/features/pull-requests/PullRequestFiles.tsx index d51671955a272b6b86111a69956ae4d12baa1ba6..0e4b8d7b69bd7a1e5f8ffad9a2f5985a2b7a0885 100644 --- a/apps/mobile/src/features/pull-requests/PullRequestFiles.tsx +++ b/apps/mobile/src/features/pull-requests/PullRequestFiles.tsx @@ -125,7 +125,7 @@ export function usePullRequestFilesContent(props: { ) : null} diff --git a/apps/mobile/src/features/pull-requests/PullRequestMergeControls.tsx b/apps/mobile/src/features/pull-requests/PullRequestMergeControls.tsx index 2718b12a10629f26da06d33bd5f81e43ede592e3..84247a982193c7af269c6fafbd6aa81cc6981e00 100644 --- a/apps/mobile/src/features/pull-requests/PullRequestMergeControls.tsx +++ b/apps/mobile/src/features/pull-requests/PullRequestMergeControls.tsx @@ -169,7 +169,7 @@ export function PullRequestMergeControls(props: { className={ Platform.OS === "android" ? "flex-row items-center gap-2" - : `flex-row overflow-hidden rounded-xl border-continuous ${canMerge ? "bg-foreground" : "bg-subtle-strong"}` + : `flex-row overflow-hidden rounded-xl border-continuous ${canMerge ? "bg-prominent-action" : "bg-subtle-strong"}` } > {Platform.OS === "android" ? ( @@ -200,11 +200,13 @@ export function PullRequestMergeControls(props: { )} {busy ? "Working…" : !permissions.connected ? "Reconnect to merge" : label} @@ -255,7 +257,9 @@ export function PullRequestMergeControls(props: { )} diff --git a/apps/mobile/src/features/pull-requests/PullRequestStackCard.tsx b/apps/mobile/src/features/pull-requests/PullRequestStackCard.tsx index 4a8c1be20b71584b6029c5aeb89360ea24e63b4c..9b4ea96cc43ea6e423b6ba272bde36b98b6e317f 100644 --- a/apps/mobile/src/features/pull-requests/PullRequestStackCard.tsx +++ b/apps/mobile/src/features/pull-requests/PullRequestStackCard.tsx @@ -54,7 +54,7 @@ export function PullRequestStackCard(props: { isDraft: layer.isDraft === true, }); return ( - + navigation.navigate("ThreadAttachment", { environmentId: String(props.environmentId), diff --git a/apps/mobile/src/features/threads/McpAppFullscreenScreen.tsx b/apps/mobile/src/features/threads/McpAppFullscreenScreen.tsx index 0a09941fe78dff6d290495cbddc99caa92a75b4f..b9186ec19f8c5dfa1bc774c6124111e59dc3d946 100644 --- a/apps/mobile/src/features/threads/McpAppFullscreenScreen.tsx +++ b/apps/mobile/src/features/threads/McpAppFullscreenScreen.tsx @@ -120,7 +120,7 @@ export function McpAppFullscreenScreen({ route }: McpAppFullscreenScreenProps) { }, [awaitingUser, exitRequested, focused, navigation]); return ( - + {app?.server ?? "App"} diff --git a/apps/mobile/src/features/threads/PendingApprovalCard.tsx b/apps/mobile/src/features/threads/PendingApprovalCard.tsx index fcdb9e3563f82e0df582becdf5dc5069542cbf7e..937d2e9ed4f08a36198d919e60e9e37dea07d463 100644 --- a/apps/mobile/src/features/threads/PendingApprovalCard.tsx +++ b/apps/mobile/src/features/threads/PendingApprovalCard.tsx @@ -47,7 +47,7 @@ export function PendingApprovalCard(props: PendingApprovalCardProps) { ) : null} {!canRespond ? ( - + The provider process for this request is no longer available. Interrupt or restart the run to continue. @@ -73,7 +73,7 @@ export function PendingApprovalCard(props: PendingApprovalCardProps) { ))} {!props.canOperateThread ? ( - + This connection cannot respond to approvals. ) : null} diff --git a/apps/mobile/src/features/threads/PendingUserInputCard.tsx b/apps/mobile/src/features/threads/PendingUserInputCard.tsx index 9c2ba09425601eae4a72f3ce4379f3be3bcf0e87..172eb627645bd66885c62f9195eeb5e990c657e5 100644 --- a/apps/mobile/src/features/threads/PendingUserInputCard.tsx +++ b/apps/mobile/src/features/threads/PendingUserInputCard.tsx @@ -265,7 +265,7 @@ export function PendingUserInputCard(props: PendingUserInputCardProps) { style={{ flexShrink: 1 }} > {!canRespond ? ( - + The provider process for this request is no longer available. Interrupt or restart the run to continue. diff --git a/apps/mobile/src/features/threads/ThreadFeed.tsx b/apps/mobile/src/features/threads/ThreadFeed.tsx index 7c463af350dedfa5f2800c9f5413dce8d7b75445..06fd90043d4c0d68fe03ac13af13ebc3ef844d99 100644 --- a/apps/mobile/src/features/threads/ThreadFeed.tsx +++ b/apps/mobile/src/features/threads/ThreadFeed.tsx @@ -2758,7 +2758,7 @@ function ThreadFeedLoadEarlierControl(props: ThreadFeedHistoryControls) { accessibilityLabel="Load earlier activity" disabled={props.loading} onPress={props.onLoadEarlier} - className="min-h-9 flex-row items-center justify-center gap-2 rounded-full border border-border/60 bg-surface/80 px-4 py-2 disabled:opacity-50" + className="min-h-9 flex-row items-center justify-center gap-2 rounded-full border border-border/60 bg-card/80 px-4 py-2 disabled:opacity-50" > {props.loading ? ( diff --git a/apps/mobile/src/features/threads/thread-context-divider.tsx b/apps/mobile/src/features/threads/thread-context-divider.tsx index 7915593db4def6d8c95367e2918906dcdeb57aea..d4759f0bbb802b9c9c0d7e321b6addeafadf55ae 100644 --- a/apps/mobile/src/features/threads/thread-context-divider.tsx +++ b/apps/mobile/src/features/threads/thread-context-divider.tsx @@ -14,7 +14,7 @@ export function ThreadContextDivider(props: { }) { return ( - + {props.active ? ( @@ -40,7 +40,7 @@ export function ThreadContextDivider(props: { )} {props.children} - + ); } diff --git a/apps/mobile/src/features/threads/thread-work-log.tsx b/apps/mobile/src/features/threads/thread-work-log.tsx index dc7a1f32dad175dd57ead54ac029d2d92311943f..3ae002fa95454853119bf6b37b3331665a9df680 100644 --- a/apps/mobile/src/features/threads/thread-work-log.tsx +++ b/apps/mobile/src/features/threads/thread-work-log.tsx @@ -1535,7 +1535,7 @@ function ToolActivityImage(props: { const [loaded, setLoaded] = useState(false); const [failed, setFailed] = useState(false); return ( - + {!loaded || failed ? : null} {!failed ? ( void }) { ); diff --git a/apps/mobile/src/lib/mobileTheme.test.ts b/apps/mobile/src/lib/mobileTheme.test.ts index 0793a6f174360291c593a84e32e7a1ac61f64bd6..b2d8d460a83e39933dafc30cd4155e8f638112ff 100644 --- a/apps/mobile/src/lib/mobileTheme.test.ts +++ b/apps/mobile/src/lib/mobileTheme.test.ts @@ -255,6 +255,66 @@ describe("mobile themes", () => { }, ); + it("keeps T3 Chat light grouped cards distinct from the sheet", () => { + const variables = getMobileThemeVariables("t3-chat", "light"); + const group = variables["--color-grouped-card"]; + expect(contrastRatio(group, variables["--color-sheet-solid"])).toBeGreaterThanOrEqual(1.1); + for (const role of ["--color-foreground", "--color-foreground-muted"] as const) { + expect(contrastRatio(variables[role], group)).toBeGreaterThanOrEqual(4.5); + } + }); + + it.each(MOBILE_THEME_IDS)("keeps %s prominent actions readable and themed", (themeId) => { + for (const appearance of ["light", "dark"] as const) { + const variables = getMobileThemeVariables(themeId, appearance); + const fill = variables["--color-prominent-action"]; + expect( + contrastRatio(variables["--color-prominent-action-foreground"], fill), + ).toBeGreaterThanOrEqual(4.5); + expect(fill).toBe( + variables[ + themeId === "t3-chat" && appearance === "dark" + ? "--color-primary-foreground" + : themeId === DEFAULT_MOBILE_THEME_ID || themeId === "t3-chat" + ? "--color-foreground" + : "--color-primary" + ], + ); + } + }); + + it.each(["grove", "ocean", "ember", "iris"] as const)( + "keeps %s grouped cards and floating controls visibly tinted", + (themeId) => { + const saturation = (hex: string) => { + const channels = hex + .slice(1) + .match(/.{2}/g)! + .map((value) => parseInt(value, 16)); + return (Math.max(...channels) - Math.min(...channels)) / Math.max(...channels); + }; + for (const appearance of ["light", "dark"] as const) { + const variables = getMobileThemeVariables(themeId, appearance); + const sheet = variables["--color-sheet-solid"]; + const group = variables["--color-grouped-card"]; + expect(contrastRatio(group, sheet)).toBeGreaterThanOrEqual(1.06); + for (const role of ["--color-composer-surface", "--color-glass-fallback"] as const) { + const surface = flattenThemeColor(variables[role], sheet); + expect(contrastRatio(surface, sheet)).toBeGreaterThanOrEqual(1.06); + expect(contrastRatio(variables["--color-placeholder"], surface)).toBeGreaterThanOrEqual( + 4.5, + ); + if (appearance === "dark") { + expect(saturation(surface)).toBeGreaterThanOrEqual(saturation(sheet)); + } + } + if (appearance === "dark") { + expect(saturation(group)).toBeGreaterThanOrEqual(saturation(sheet)); + } + } + }, + ); + it.each(["light", "dark"] as const)( "slightly strengthens default %s messages and separates fallback materials", (appearance) => { diff --git a/apps/mobile/src/lib/mobileTheme.ts b/apps/mobile/src/lib/mobileTheme.ts index 933f214f215c0a7b4acabbcbe610853d19258716..2da47f91cd74e4852d3fd95b65dfe79cfccf6435 100644 --- a/apps/mobile/src/lib/mobileTheme.ts +++ b/apps/mobile/src/lib/mobileTheme.ts @@ -247,6 +247,7 @@ export function createMobileThemeVariables( colors: ThemeColors, appearance: MobileThemeAppearance, groupedCardColor = colors.surface, + prominentAction: readonly [string, string] = [colors.text, colors.canvas], ) { const c = nativeColors(colors); const groupedCard = themeColorToNativeColor(groupedCardColor); @@ -299,6 +300,8 @@ export function createMobileThemeVariables( "--color-inline-skill-border": withAlpha(c.accent, 0.42), "--color-inline-skill-foreground": c.accentSurfaceForeground, "--color-primary": c.messageAction, + "--color-prominent-action": themeColorToNativeColor(prominentAction[0]), + "--color-prominent-action-foreground": themeColorToNativeColor(prominentAction[1]), "--color-primary-foreground": c.messageActionForeground, "--color-primary-text": themeColorWithContrast(c.messageAction, textSurfaces), "--color-primary-shadow": "#000000", @@ -386,17 +389,18 @@ export function getMobileThemeVariables( overrides: Partial | null = null, ): MobileThemeVariables { const colors = getMobileThemeColors(themeId, appearance); - // Mobile settings groups and fallback materials use tonal fills where desktop - // uses outlined cards. Raise flat desktop surfaces above the sheet so grouped - // content keeps a visible boundary. Regular cards retain their desktop surface. + // Mobile groups and floating controls need a tonal fill, rather than the + // nearly neutral raised surface used by desktop outlined cards. const groupedCard = themeId === DEFAULT_MOBILE_THEME_ID ? appearance === "light" ? colors.toolbarControlHover : colors.sidebarRowActive - : colors.surface === colors.chrome - ? colors.surfaceRaised - : colors.surface; + : themeId === "t3-chat" + ? appearance === "light" + ? colors.toolbarControl + : colors.surface + : colors.muted; const mobileColors = themeId === DEFAULT_MOBILE_THEME_ID ? { @@ -410,7 +414,16 @@ export function getMobileThemeVariables( ), } : colors; - const baseVariables = createMobileThemeVariables(mobileColors, appearance, groupedCard); + const baseVariables = createMobileThemeVariables( + mobileColors, + appearance, + groupedCard, + themeId === "t3-chat" && appearance === "dark" + ? [colors.messageActionForeground, colors.messageAction] + : themeId !== DEFAULT_MOBILE_THEME_ID && themeId !== "t3-chat" + ? [colors.messageAction, colors.messageActionForeground] + : undefined, + ); // The complete base record guarantees that optional overrides cannot leave a token undefined. return overrides ? ({ ...baseVariables, ...overrides } as MobileThemeVariables) : baseVariables;