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;