authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-10-11 22:31:13-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-11 22:31:13-07:00
log679b03e1c680d983cf89f5162c545342d6036ad3
treeb8ec6b8c7a7c6e995a5aea73ad69211a375a8284
parent462e7f4de4fd4ae14d2b4439fd983fa9ced2790e
signature Signed by PGP key B5690EEEBB952194

fix(mobile): preserve theme contrast across surfaces and actions (#18506)


19 files changed, 167 insertions(+), 68 deletions(-)

apps/mobile/generated-uniwind-default-theme-variables.json+4
...@@ -30,6 +30,8 @@...@@ -30,6 +30,8 @@
30 "--color-inline-skill-border": "rgba(27, 78, 216, 0.42)",30 "--color-inline-skill-border": "rgba(27, 78, 216, 0.42)",
31 "--color-inline-skill-foreground": "#18181b",31 "--color-inline-skill-foreground": "#18181b",
32 "--color-primary": "#1b4ed8",32 "--color-primary": "#1b4ed8",
33 "--color-prominent-action": "#27272a",
34 "--color-prominent-action-foreground": "#fcfcfc",
33 "--color-primary-foreground": "#ffffff",35 "--color-primary-foreground": "#ffffff",
34 "--color-primary-text": "#1b4ed8",36 "--color-primary-text": "#1b4ed8",
35 "--color-primary-shadow": "#000000",37 "--color-primary-shadow": "#000000",
...@@ -119,6 +121,8 @@...@@ -119,6 +121,8 @@
119 "--color-inline-skill-border": "rgba(52, 107, 241, 0.42)",121 "--color-inline-skill-border": "rgba(52, 107, 241, 0.42)",
120 "--color-inline-skill-foreground": "#f5f5f5",122 "--color-inline-skill-foreground": "#f5f5f5",
121 "--color-primary": "#346bf1",123 "--color-primary": "#346bf1",
124 "--color-prominent-action": "#f5f5f5",
125 "--color-prominent-action-foreground": "#0a0a0a",
122 "--color-primary-foreground": "#ffffff",126 "--color-primary-foreground": "#ffffff",
123 "--color-primary-text": "#4b7cf3",127 "--color-primary-text": "#4b7cf3",
124 "--color-primary-shadow": "#000000",128 "--color-primary-shadow": "#000000",
apps/mobile/generated-uniwind-themes.css+52-28
...@@ -32,6 +32,8 @@...@@ -32,6 +32,8 @@
32 --color-inline-skill-border: rgba(27, 78, 216, 0.42);32 --color-inline-skill-border: rgba(27, 78, 216, 0.42);
33 --color-inline-skill-foreground: #18181b;33 --color-inline-skill-foreground: #18181b;
34 --color-primary: #1b4ed8;34 --color-primary: #1b4ed8;
35 --color-prominent-action: #27272a;
36 --color-prominent-action-foreground: #fcfcfc;
35 --color-primary-foreground: #ffffff;37 --color-primary-foreground: #ffffff;
36 --color-primary-text: #1b4ed8;38 --color-primary-text: #1b4ed8;
37 --color-primary-shadow: #000000;39 --color-primary-shadow: #000000;
...@@ -191,6 +193,8 @@...@@ -191,6 +193,8 @@
191 --color-inline-skill-border: rgba(52, 107, 241, 0.42);193 --color-inline-skill-border: rgba(52, 107, 241, 0.42);
192 --color-inline-skill-foreground: #f5f5f5;194 --color-inline-skill-foreground: #f5f5f5;
193 --color-primary: #346bf1;195 --color-primary: #346bf1;
196 --color-prominent-action: #f5f5f5;
197 --color-prominent-action-foreground: #0a0a0a;
194 --color-primary-foreground: #ffffff;198 --color-primary-foreground: #ffffff;
195 --color-primary-text: #4b7cf3;199 --color-primary-text: #4b7cf3;
196 --color-primary-shadow: #000000;200 --color-primary-shadow: #000000;
...@@ -324,7 +328,7 @@...@@ -324,7 +328,7 @@
324 --color-sheet: rgba(253, 247, 253, 0.98);328 --color-sheet: rgba(253, 247, 253, 0.98);
325 --color-sheet-solid: #fdf7fd;329 --color-sheet-solid: #fdf7fd;
326 --color-card: #faf3fb;330 --color-card: #faf3fb;
327 --color-grouped-card: #faf3fb;331 --color-grouped-card: #f3e6f5;
328 --color-card-alt: #fdfafd;332 --color-card-alt: #fdfafd;
329 --color-card-translucent: rgba(250, 243, 251, 0.8);333 --color-card-translucent: rgba(250, 243, 251, 0.8);
330 --color-thread-canvas: #fdf7fd;334 --color-thread-canvas: #fdf7fd;
...@@ -334,8 +338,8 @@...@@ -334,8 +338,8 @@
334 --color-thread-hover: #f8f8f7;338 --color-thread-hover: #f8f8f7;
335 --color-row-hover: #eccfe3;339 --color-row-hover: #eccfe3;
336 --color-composer-panel: rgba(253, 247, 253, 0.88);340 --color-composer-panel: rgba(253, 247, 253, 0.88);
337 --color-composer-surface: rgba(250, 243, 251, 0.94);341 --color-composer-surface: rgba(243, 230, 245, 0.94);
338 --color-composer-border: rgba(238, 225, 237, 0.54);342 --color-composer-border: rgba(238, 225, 237, 0.8);
339 --color-foreground: #501854;343 --color-foreground: #501854;
340 --color-foreground-secondary: #ab1668;344 --color-foreground-secondary: #ab1668;
341 --color-foreground-muted: #8d1255;345 --color-foreground-muted: #8d1255;
...@@ -350,6 +354,8 @@...@@ -350,6 +354,8 @@
350 --color-inline-skill-border: rgba(219, 39, 119, 0.42);354 --color-inline-skill-border: rgba(219, 39, 119, 0.42);
351 --color-inline-skill-foreground: #454554;355 --color-inline-skill-foreground: #454554;
352 --color-primary: #db2777;356 --color-primary: #db2777;
357 --color-prominent-action: #501854;
358 --color-prominent-action-foreground: #fdf7fd;
353 --color-primary-foreground: #ffffff;359 --color-primary-foreground: #ffffff;
354 --color-primary-text: #aa1e5d;360 --color-primary-text: #aa1e5d;
355 --color-primary-shadow: #000000;361 --color-primary-shadow: #000000;
...@@ -379,7 +385,7 @@...@@ -379,7 +385,7 @@
379 --color-header-foreground: #501854;385 --color-header-foreground: #501854;
380 --color-header-border: #efbdeb;386 --color-header-border: #efbdeb;
381 --color-glass-surface: rgba(255, 255, 255, 0.74);387 --color-glass-surface: rgba(255, 255, 255, 0.74);
382 --color-glass-fallback: rgba(250, 243, 251, 0.94);388 --color-glass-fallback: rgba(243, 230, 245, 0.94);
383 --color-glass-tint: rgba(255, 255, 255, 0.22);389 --color-glass-tint: rgba(255, 255, 255, 0.22);
384 --color-status-bar: #fdf7fd;390 --color-status-bar: #fdf7fd;
385 --color-md-body: #501854;391 --color-md-body: #501854;
...@@ -509,6 +515,8 @@...@@ -509,6 +515,8 @@
509 --color-inline-skill-border: rgba(163, 0, 76, 0.42);515 --color-inline-skill-border: rgba(163, 0, 76, 0.42);
510 --color-inline-skill-foreground: #f8f1f5;516 --color-inline-skill-foreground: #f8f1f5;
511 --color-primary: #a3004c;517 --color-primary: #a3004c;
518 --color-prominent-action: #fbd0e8;
519 --color-prominent-action-foreground: #a3004c;
512 --color-primary-foreground: #fbd0e8;520 --color-primary-foreground: #fbd0e8;
513 --color-primary-text: #d07ea4;521 --color-primary-text: #d07ea4;
514 --color-primary-shadow: #000000;522 --color-primary-shadow: #000000;
...@@ -642,7 +650,7 @@...@@ -642,7 +650,7 @@
642 --color-sheet: rgba(243, 247, 244, 0.98);650 --color-sheet: rgba(243, 247, 244, 0.98);
643 --color-sheet-solid: #f3f7f4;651 --color-sheet-solid: #f3f7f4;
644 --color-card: #f3f7f4;652 --color-card: #f3f7f4;
645 --color-grouped-card: #ecefed;653 --color-grouped-card: #e6f0ea;
646 --color-card-alt: #ecefed;654 --color-card-alt: #ecefed;
647 --color-card-translucent: rgba(243, 247, 244, 0.8);655 --color-card-translucent: rgba(243, 247, 244, 0.8);
648 --color-thread-canvas: #f3f7f4;656 --color-thread-canvas: #f3f7f4;
...@@ -652,7 +660,7 @@...@@ -652,7 +660,7 @@
652 --color-thread-hover: #cae0d5;660 --color-thread-hover: #cae0d5;
653 --color-row-hover: #d5e6dd;661 --color-row-hover: #d5e6dd;
654 --color-composer-panel: rgba(243, 247, 244, 0.88);662 --color-composer-panel: rgba(243, 247, 244, 0.88);
655 --color-composer-surface: rgba(236, 239, 237, 0.94);663 --color-composer-surface: rgba(230, 240, 234, 0.94);
656 --color-composer-border: rgba(203, 213, 209, 0.8);664 --color-composer-border: rgba(203, 213, 209, 0.8);
657 --color-foreground: #241523;665 --color-foreground: #241523;
658 --color-foreground-secondary: #6f686f;666 --color-foreground-secondary: #6f686f;
...@@ -668,6 +676,8 @@...@@ -668,6 +676,8 @@
668 --color-inline-skill-border: rgba(27, 125, 80, 0.42);676 --color-inline-skill-border: rgba(27, 125, 80, 0.42);
669 --color-inline-skill-foreground: #241523;677 --color-inline-skill-foreground: #241523;
670 --color-primary: #8f6410;678 --color-primary: #8f6410;
679 --color-prominent-action: #8f6410;
680 --color-prominent-action-foreground: #fffaff;
671 --color-primary-foreground: #fffaff;681 --color-primary-foreground: #fffaff;
672 --color-primary-text: #8d6210;682 --color-primary-text: #8d6210;
673 --color-primary-shadow: #000000;683 --color-primary-shadow: #000000;
...@@ -697,7 +707,7 @@...@@ -697,7 +707,7 @@
697 --color-header-foreground: #241523;707 --color-header-foreground: #241523;
698 --color-header-border: #d5e6dd;708 --color-header-border: #d5e6dd;
699 --color-glass-surface: rgba(231, 233, 232, 0.74);709 --color-glass-surface: rgba(231, 233, 232, 0.74);
700 --color-glass-fallback: rgba(236, 239, 237, 0.94);710 --color-glass-fallback: rgba(230, 240, 234, 0.94);
701 --color-glass-tint: rgba(231, 233, 232, 0.22);711 --color-glass-tint: rgba(231, 233, 232, 0.22);
702 --color-status-bar: #f3f7f4;712 --color-status-bar: #f3f7f4;
703 --color-md-body: #241523;713 --color-md-body: #241523;
...@@ -801,7 +811,7 @@...@@ -801,7 +811,7 @@
801 --color-sheet: rgba(27, 40, 33, 0.98);811 --color-sheet: rgba(27, 40, 33, 0.98);
802 --color-sheet-solid: #1b2821;812 --color-sheet-solid: #1b2821;
803 --color-card: #1b2821;813 --color-card: #1b2821;
804 --color-grouped-card: #36413c;814 --color-grouped-card: #253e31;
805 --color-card-alt: #36413c;815 --color-card-alt: #36413c;
806 --color-card-translucent: rgba(27, 40, 33, 0.8);816 --color-card-translucent: rgba(27, 40, 33, 0.8);
807 --color-thread-canvas: #1b2821;817 --color-thread-canvas: #1b2821;
...@@ -811,7 +821,7 @@...@@ -811,7 +821,7 @@
811 --color-thread-hover: #2a4938;821 --color-thread-hover: #2a4938;
812 --color-row-hover: #325c46;822 --color-row-hover: #325c46;
813 --color-composer-panel: rgba(27, 40, 33, 0.92);823 --color-composer-panel: rgba(27, 40, 33, 0.92);
814 --color-composer-surface: rgba(54, 65, 60, 0.9);824 --color-composer-surface: rgba(37, 62, 49, 0.9);
815 --color-composer-border: rgba(65, 95, 79, 0.8);825 --color-composer-border: rgba(65, 95, 79, 0.8);
816 --color-foreground: #fffaff;826 --color-foreground: #fffaff;
817 --color-foreground-secondary: #afb1b1;827 --color-foreground-secondary: #afb1b1;
...@@ -827,6 +837,8 @@...@@ -827,6 +837,8 @@
827 --color-inline-skill-border: rgba(105, 214, 154, 0.42);837 --color-inline-skill-border: rgba(105, 214, 154, 0.42);
828 --color-inline-skill-foreground: #fffaff;838 --color-inline-skill-foreground: #fffaff;
829 --color-primary: #e3b34e;839 --color-primary: #e3b34e;
840 --color-prominent-action: #e3b34e;
841 --color-prominent-action-foreground: #241523;
830 --color-primary-foreground: #241523;842 --color-primary-foreground: #241523;
831 --color-primary-text: #e3b34e;843 --color-primary-text: #e3b34e;
832 --color-primary-shadow: #000000;844 --color-primary-shadow: #000000;
...@@ -856,7 +868,7 @@...@@ -856,7 +868,7 @@
856 --color-header-foreground: #fffaff;868 --color-header-foreground: #fffaff;
857 --color-header-border: #36654c;869 --color-header-border: #36654c;
858 --color-glass-surface: rgba(68, 77, 73, 0.74);870 --color-glass-surface: rgba(68, 77, 73, 0.74);
859 --color-glass-fallback: rgba(54, 65, 60, 0.9);871 --color-glass-fallback: rgba(37, 62, 49, 0.9);
860 --color-glass-tint: rgba(68, 77, 73, 0.22);872 --color-glass-tint: rgba(68, 77, 73, 0.22);
861 --color-status-bar: #1b2821;873 --color-status-bar: #1b2821;
862 --color-md-body: #fffaff;874 --color-md-body: #fffaff;
...@@ -960,7 +972,7 @@...@@ -960,7 +972,7 @@
960 --color-sheet: rgba(245, 247, 248, 0.98);972 --color-sheet: rgba(245, 247, 248, 0.98);
961 --color-sheet-solid: #f5f7f8;973 --color-sheet-solid: #f5f7f8;
962 --color-card: #f5f7f8;974 --color-card: #f5f7f8;
963 --color-grouped-card: #edeff1;975 --color-grouped-card: #e8eff4;
964 --color-card-alt: #edeff1;976 --color-card-alt: #edeff1;
965 --color-card-translucent: rgba(245, 247, 248, 0.8);977 --color-card-translucent: rgba(245, 247, 248, 0.8);
966 --color-thread-canvas: #f5f7f8;978 --color-thread-canvas: #f5f7f8;
...@@ -970,7 +982,7 @@...@@ -970,7 +982,7 @@
970 --color-thread-hover: #cdddea;982 --color-thread-hover: #cdddea;
971 --color-row-hover: #d8e4ee;983 --color-row-hover: #d8e4ee;
972 --color-composer-panel: rgba(245, 247, 248, 0.88);984 --color-composer-panel: rgba(245, 247, 248, 0.88);
973 --color-composer-surface: rgba(237, 239, 241, 0.94);985 --color-composer-surface: rgba(232, 239, 244, 0.94);
974 --color-composer-border: rgba(205, 212, 220, 0.8);986 --color-composer-border: rgba(205, 212, 220, 0.8);
975 --color-foreground: #241523;987 --color-foreground: #241523;
976 --color-foreground-secondary: #706870;988 --color-foreground-secondary: #706870;
...@@ -986,6 +998,8 @@...@@ -986,6 +998,8 @@
986 --color-inline-skill-border: rgba(38, 114, 175, 0.42);998 --color-inline-skill-border: rgba(38, 114, 175, 0.42);
987 --color-inline-skill-foreground: #241523;999 --color-inline-skill-foreground: #241523;
988 --color-primary: #0a6f75;1000 --color-primary: #0a6f75;
1001 --color-prominent-action: #0a6f75;
1002 --color-prominent-action-foreground: #fffaff;
989 --color-primary-foreground: #fffaff;1003 --color-primary-foreground: #fffaff;
990 --color-primary-text: #0a6f75;1004 --color-primary-text: #0a6f75;
991 --color-primary-shadow: #000000;1005 --color-primary-shadow: #000000;
...@@ -1015,7 +1029,7 @@...@@ -1015,7 +1029,7 @@
1015 --color-header-foreground: #241523;1029 --color-header-foreground: #241523;
1016 --color-header-border: #d8e4ee;1030 --color-header-border: #d8e4ee;
1017 --color-glass-surface: rgba(232, 233, 235, 0.74);1031 --color-glass-surface: rgba(232, 233, 235, 0.74);
1018 --color-glass-fallback: rgba(237, 239, 241, 0.94);1032 --color-glass-fallback: rgba(232, 239, 244, 0.94);
1019 --color-glass-tint: rgba(232, 233, 235, 0.22);1033 --color-glass-tint: rgba(232, 233, 235, 0.22);
1020 --color-status-bar: #f5f7f8;1034 --color-status-bar: #f5f7f8;
1021 --color-md-body: #241523;1035 --color-md-body: #241523;
...@@ -1119,7 +1133,7 @@...@@ -1119,7 +1133,7 @@
1119 --color-sheet: rgba(23, 33, 43, 0.98);1133 --color-sheet: rgba(23, 33, 43, 0.98);
1120 --color-sheet-solid: #17212b;1134 --color-sheet-solid: #17212b;
1121 --color-card: #17212b;1135 --color-card: #17212b;
1122 --color-grouped-card: #333b45;1136 --color-grouped-card: #233544;
1123 --color-card-alt: #333b45;1137 --color-card-alt: #333b45;
1124 --color-card-translucent: rgba(23, 33, 43, 0.8);1138 --color-card-translucent: rgba(23, 33, 43, 0.8);
1125 --color-thread-canvas: #17212b;1139 --color-thread-canvas: #17212b;
...@@ -1129,7 +1143,7 @@...@@ -1129,7 +1143,7 @@
1129 --color-thread-hover: #283e50;1143 --color-thread-hover: #283e50;
1130 --color-row-hover: #324e66;1144 --color-row-hover: #324e66;
1131 --color-composer-panel: rgba(23, 33, 43, 0.92);1145 --color-composer-panel: rgba(23, 33, 43, 0.92);
1132 --color-composer-surface: rgba(51, 59, 69, 0.9);1146 --color-composer-surface: rgba(35, 53, 68, 0.9);
1133 --color-composer-border: rgba(64, 85, 103, 0.8);1147 --color-composer-border: rgba(64, 85, 103, 0.8);
1134 --color-foreground: #fffaff;1148 --color-foreground: #fffaff;
1135 --color-foreground-secondary: #a5a7ad;1149 --color-foreground-secondary: #a5a7ad;
...@@ -1145,6 +1159,8 @@...@@ -1145,6 +1159,8 @@
1145 --color-inline-skill-border: rgba(112, 185, 238, 0.42);1159 --color-inline-skill-border: rgba(112, 185, 238, 0.42);
1146 --color-inline-skill-foreground: #fffaff;1160 --color-inline-skill-foreground: #fffaff;
1147 --color-primary: #5bd0d6;1161 --color-primary: #5bd0d6;
1162 --color-prominent-action: #5bd0d6;
1163 --color-prominent-action-foreground: #241523;
1148 --color-primary-foreground: #241523;1164 --color-primary-foreground: #241523;
1149 --color-primary-text: #5bd0d6;1165 --color-primary-text: #5bd0d6;
1150 --color-primary-shadow: #000000;1166 --color-primary-shadow: #000000;
...@@ -1174,7 +1190,7 @@...@@ -1174,7 +1190,7 @@
1174 --color-header-foreground: #fffaff;1190 --color-header-foreground: #fffaff;
1175 --color-header-border: #36566f;1191 --color-header-border: #36566f;
1176 --color-glass-surface: rgba(65, 72, 81, 0.74);1192 --color-glass-surface: rgba(65, 72, 81, 0.74);
1177 --color-glass-fallback: rgba(51, 59, 69, 0.9);1193 --color-glass-fallback: rgba(35, 53, 68, 0.9);
1178 --color-glass-tint: rgba(65, 72, 81, 0.22);1194 --color-glass-tint: rgba(65, 72, 81, 0.22);
1179 --color-status-bar: #17212b;1195 --color-status-bar: #17212b;
1180 --color-md-body: #fffaff;1196 --color-md-body: #fffaff;
...@@ -1278,7 +1294,7 @@...@@ -1278,7 +1294,7 @@
1278 --color-sheet: rgba(249, 247, 245, 0.98);1294 --color-sheet: rgba(249, 247, 245, 0.98);
1279 --color-sheet-solid: #f9f7f5;1295 --color-sheet-solid: #f9f7f5;
1280 --color-card: #f9f7f5;1296 --color-card: #f9f7f5;
1281 --color-grouped-card: #f1efee;1297 --color-grouped-card: #f4ede9;
1282 --color-card-alt: #f1efee;1298 --color-card-alt: #f1efee;
1283 --color-card-translucent: rgba(249, 247, 245, 0.8);1299 --color-card-translucent: rgba(249, 247, 245, 0.8);
1284 --color-thread-canvas: #f9f7f5;1300 --color-thread-canvas: #f9f7f5;
...@@ -1288,7 +1304,7 @@...@@ -1288,7 +1304,7 @@
1288 --color-thread-hover: #ead8cf;1304 --color-thread-hover: #ead8cf;
1289 --color-row-hover: #eee0d9;1305 --color-row-hover: #eee0d9;
1290 --color-composer-panel: rgba(249, 247, 245, 0.88);1306 --color-composer-panel: rgba(249, 247, 245, 0.88);
1291 --color-composer-surface: rgba(241, 239, 238, 0.94);1307 --color-composer-surface: rgba(244, 237, 233, 0.94);
1292 --color-composer-border: rgba(221, 210, 206, 0.8);1308 --color-composer-border: rgba(221, 210, 206, 0.8);
1293 --color-foreground: #241523;1309 --color-foreground: #241523;
1294 --color-foreground-secondary: #726870;1310 --color-foreground-secondary: #726870;
...@@ -1304,6 +1320,8 @@...@@ -1304,6 +1320,8 @@
1304 --color-inline-skill-border: rgba(174, 85, 42, 0.42);1320 --color-inline-skill-border: rgba(174, 85, 42, 0.42);
1305 --color-inline-skill-foreground: #241523;1321 --color-inline-skill-foreground: #241523;
1306 --color-primary: #b23535;1322 --color-primary: #b23535;
1323 --color-prominent-action: #b23535;
1324 --color-prominent-action-foreground: #fffaff;
1307 --color-primary-foreground: #fffaff;1325 --color-primary-foreground: #fffaff;
1308 --color-primary-text: #b23535;1326 --color-primary-text: #b23535;
1309 --color-primary-shadow: #000000;1327 --color-primary-shadow: #000000;
...@@ -1333,7 +1351,7 @@...@@ -1333,7 +1351,7 @@
1333 --color-header-foreground: #241523;1351 --color-header-foreground: #241523;
1334 --color-header-border: #eee0d9;1352 --color-header-border: #eee0d9;
1335 --color-glass-surface: rgba(236, 233, 233, 0.74);1353 --color-glass-surface: rgba(236, 233, 233, 0.74);
1336 --color-glass-fallback: rgba(241, 239, 238, 0.94);1354 --color-glass-fallback: rgba(244, 237, 233, 0.94);
1337 --color-glass-tint: rgba(236, 233, 233, 0.22);1355 --color-glass-tint: rgba(236, 233, 233, 0.22);
1338 --color-status-bar: #f9f7f5;1356 --color-status-bar: #f9f7f5;
1339 --color-md-body: #241523;1357 --color-md-body: #241523;
...@@ -1437,7 +1455,7 @@...@@ -1437,7 +1455,7 @@
1437 --color-sheet: rgba(41, 30, 26, 0.98);1455 --color-sheet: rgba(41, 30, 26, 0.98);
1438 --color-sheet-solid: #291e1a;1456 --color-sheet-solid: #291e1a;
1439 --color-card: #291e1a;1457 --color-card: #291e1a;
1440 --color-grouped-card: #433835;1458 --color-grouped-card: #432e23;
1441 --color-card-alt: #433835;1459 --color-card-alt: #433835;
1442 --color-card-translucent: rgba(41, 30, 26, 0.8);1460 --color-card-translucent: rgba(41, 30, 26, 0.8);
1443 --color-thread-canvas: #291e1a;1461 --color-thread-canvas: #291e1a;
...@@ -1447,7 +1465,7 @@...@@ -1447,7 +1465,7 @@
1447 --color-thread-hover: #4f3528;1465 --color-thread-hover: #4f3528;
1448 --color-row-hover: #644330;1466 --color-row-hover: #644330;
1449 --color-composer-panel: rgba(41, 30, 26, 0.92);1467 --color-composer-panel: rgba(41, 30, 26, 0.92);
1450 --color-composer-surface: rgba(67, 56, 53, 0.9);1468 --color-composer-surface: rgba(67, 46, 35, 0.9);
1451 --color-composer-border: rgba(102, 76, 63, 0.8);1469 --color-composer-border: rgba(102, 76, 63, 0.8);
1452 --color-foreground: #fffaff;1470 --color-foreground: #fffaff;
1453 --color-foreground-secondary: #aca5a6;1471 --color-foreground-secondary: #aca5a6;
...@@ -1463,6 +1481,8 @@...@@ -1463,6 +1481,8 @@
1463 --color-inline-skill-border: rgba(240, 154, 100, 0.42);1481 --color-inline-skill-border: rgba(240, 154, 100, 0.42);
1464 --color-inline-skill-foreground: #fffaff;1482 --color-inline-skill-foreground: #fffaff;
1465 --color-primary: #f78a7a;1483 --color-primary: #f78a7a;
1484 --color-prominent-action: #f78a7a;
1485 --color-prominent-action-foreground: #241523;
1466 --color-primary-foreground: #241523;1486 --color-primary-foreground: #241523;
1467 --color-primary-text: #f78a7a;1487 --color-primary-text: #f78a7a;
1468 --color-primary-shadow: #000000;1488 --color-primary-shadow: #000000;
...@@ -1492,7 +1512,7 @@...@@ -1492,7 +1512,7 @@
1492 --color-header-foreground: #fffaff;1512 --color-header-foreground: #fffaff;
1493 --color-header-border: #6e4934;1513 --color-header-border: #6e4934;
1494 --color-glass-surface: rgba(79, 69, 67, 0.74);1514 --color-glass-surface: rgba(79, 69, 67, 0.74);
1495 --color-glass-fallback: rgba(67, 56, 53, 0.9);1515 --color-glass-fallback: rgba(67, 46, 35, 0.9);
1496 --color-glass-tint: rgba(79, 69, 67, 0.22);1516 --color-glass-tint: rgba(79, 69, 67, 0.22);
1497 --color-status-bar: #291e1a;1517 --color-status-bar: #291e1a;
1498 --color-md-body: #fffaff;1518 --color-md-body: #fffaff;
...@@ -1596,7 +1616,7 @@...@@ -1596,7 +1616,7 @@
1596 --color-sheet: rgba(248, 247, 249, 0.98);1616 --color-sheet: rgba(248, 247, 249, 0.98);
1597 --color-sheet-solid: #f8f7f9;1617 --color-sheet-solid: #f8f7f9;
1598 --color-card: #f8f7f9;1618 --color-card: #f8f7f9;
1599 --color-grouped-card: #f0eff2;1619 --color-grouped-card: #f0edf6;
1600 --color-card-alt: #f0eff2;1620 --color-card-alt: #f0eff2;
1601 --color-card-translucent: rgba(248, 247, 249, 0.8);1621 --color-card-translucent: rgba(248, 247, 249, 0.8);
1602 --color-thread-canvas: #f8f7f9;1622 --color-thread-canvas: #f8f7f9;
...@@ -1606,7 +1626,7 @@...@@ -1606,7 +1626,7 @@
1606 --color-thread-hover: #ded8ed;1626 --color-thread-hover: #ded8ed;
1607 --color-row-hover: #e5e0f0;1627 --color-row-hover: #e5e0f0;
1608 --color-composer-panel: rgba(248, 247, 249, 0.88);1628 --color-composer-panel: rgba(248, 247, 249, 0.88);
1609 --color-composer-surface: rgba(240, 239, 242, 0.94);1629 --color-composer-surface: rgba(240, 237, 246, 0.94);
1610 --color-composer-border: rgba(214, 209, 222, 0.8);1630 --color-composer-border: rgba(214, 209, 222, 0.8);
1611 --color-foreground: #241523;1631 --color-foreground: #241523;
1612 --color-foreground-secondary: #716871;1632 --color-foreground-secondary: #716871;
...@@ -1622,6 +1642,8 @@...@@ -1622,6 +1642,8 @@
1622 --color-inline-skill-border: rgba(114, 83, 185, 0.42);1642 --color-inline-skill-border: rgba(114, 83, 185, 0.42);
1623 --color-inline-skill-foreground: #241523;1643 --color-inline-skill-foreground: #241523;
1624 --color-primary: #a82c87;1644 --color-primary: #a82c87;
1645 --color-prominent-action: #a82c87;
1646 --color-prominent-action-foreground: #fffaff;
1625 --color-primary-foreground: #fffaff;1647 --color-primary-foreground: #fffaff;
1626 --color-primary-text: #a82c87;1648 --color-primary-text: #a82c87;
1627 --color-primary-shadow: #000000;1649 --color-primary-shadow: #000000;
...@@ -1651,7 +1673,7 @@...@@ -1651,7 +1673,7 @@
1651 --color-header-foreground: #241523;1673 --color-header-foreground: #241523;
1652 --color-header-border: #e5e0f0;1674 --color-header-border: #e5e0f0;
1653 --color-glass-surface: rgba(235, 233, 237, 0.74);1675 --color-glass-surface: rgba(235, 233, 237, 0.74);
1654 --color-glass-fallback: rgba(240, 239, 242, 0.94);1676 --color-glass-fallback: rgba(240, 237, 246, 0.94);
1655 --color-glass-tint: rgba(235, 233, 237, 0.22);1677 --color-glass-tint: rgba(235, 233, 237, 0.22);
1656 --color-status-bar: #f8f7f9;1678 --color-status-bar: #f8f7f9;
1657 --color-md-body: #241523;1679 --color-md-body: #241523;
...@@ -1755,7 +1777,7 @@...@@ -1755,7 +1777,7 @@
1755 --color-sheet: rgba(29, 25, 41, 0.98);1777 --color-sheet: rgba(29, 25, 41, 0.98);
1756 --color-sheet-solid: #1d1929;1778 --color-sheet-solid: #1d1929;
1757 --color-card: #1d1929;1779 --color-card: #1d1929;
1758 --color-grouped-card: #383443;1780 --color-grouped-card: #2d2643;
1759 --color-card-alt: #383443;1781 --color-card-alt: #383443;
1760 --color-card-translucent: rgba(29, 25, 41, 0.8);1782 --color-card-translucent: rgba(29, 25, 41, 0.8);
1761 --color-thread-canvas: #1d1929;1783 --color-thread-canvas: #1d1929;
...@@ -1765,7 +1787,7 @@...@@ -1765,7 +1787,7 @@
1765 --color-thread-hover: #352c4f;1787 --color-thread-hover: #352c4f;
1766 --color-row-hover: #433765;1788 --color-row-hover: #433765;
1767 --color-composer-panel: rgba(29, 25, 41, 0.92);1789 --color-composer-panel: rgba(29, 25, 41, 0.92);
1768 --color-composer-surface: rgba(56, 52, 67, 0.9);1790 --color-composer-surface: rgba(45, 38, 67, 0.9);
1769 --color-composer-border: rgba(77, 67, 102, 0.8);1791 --color-composer-border: rgba(77, 67, 102, 0.8);
1770 --color-foreground: #fffaff;1792 --color-foreground: #fffaff;
1771 --color-foreground-secondary: #a09da6;1793 --color-foreground-secondary: #a09da6;
...@@ -1781,6 +1803,8 @@...@@ -1781,6 +1803,8 @@
1781 --color-inline-skill-border: rgba(157, 125, 242, 0.42);1803 --color-inline-skill-border: rgba(157, 125, 242, 0.42);
1782 --color-inline-skill-foreground: #fffaff;1804 --color-inline-skill-foreground: #fffaff;
1783 --color-primary: #f099d8;1805 --color-primary: #f099d8;
1806 --color-prominent-action: #f099d8;
1807 --color-prominent-action-foreground: #241523;
1784 --color-primary-foreground: #241523;1808 --color-primary-foreground: #241523;
1785 --color-primary-text: #f099d8;1809 --color-primary-text: #f099d8;
1786 --color-primary-shadow: #000000;1810 --color-primary-shadow: #000000;
...@@ -1810,7 +1834,7 @@...@@ -1810,7 +1834,7 @@
1810 --color-header-foreground: #fffaff;1834 --color-header-foreground: #fffaff;
1811 --color-header-border: #4a3c70;1835 --color-header-border: #4a3c70;
1812 --color-glass-surface: rgba(69, 66, 80, 0.74);1836 --color-glass-surface: rgba(69, 66, 80, 0.74);
1813 --color-glass-fallback: rgba(56, 52, 67, 0.9);1837 --color-glass-fallback: rgba(45, 38, 67, 0.9);
1814 --color-glass-tint: rgba(69, 66, 80, 0.22);1838 --color-glass-tint: rgba(69, 66, 80, 0.22);
1815 --color-status-bar: #1d1929;1839 --color-status-bar: #1d1929;
1816 --color-md-body: #fffaff;1840 --color-md-body: #fffaff;
apps/mobile/src/components/ProjectCloneBanner.tsx+1-1
...@@ -73,7 +73,7 @@ function BannerAction(props: { readonly label: string; readonly onPress: () => v...@@ -73,7 +73,7 @@ function BannerAction(props: { readonly label: string; readonly onPress: () => v
73 <Pressable73 <Pressable
74 accessibilityRole="button"74 accessibilityRole="button"
75 accessibilityLabel={props.label}75 accessibilityLabel={props.label}
76 className="rounded-full border border-border bg-background px-3 py-1.5"76 className="rounded-full border border-border bg-card px-3 py-1.5"
77 onPress={props.onPress}77 onPress={props.onPress}
78 >78 >
79 <Text className="font-t3-medium text-xs">{props.label}</Text>79 <Text className="font-t3-medium text-xs">{props.label}</Text>
apps/mobile/src/features/browser/PreviewStreamWebView.tsx+3-1
...@@ -461,7 +461,9 @@ function PreviewStreamDocumentView({...@@ -461,7 +461,9 @@ function PreviewStreamDocumentView({
461 {control.dialog.type === "prompt" ? (461 {control.dialog.type === "prompt" ? (
462 <TextInput462 <TextInput
463 accessibilityLabel="Dialog response"463 accessibilityLabel="Dialog response"
464 className="rounded-lg border border-secondary-border bg-background px-3 py-2 text-foreground"464 className="rounded-lg border border-input-border bg-input px-3 py-2 text-foreground"
465 placeholderTextColorClassName="accent-placeholder"
466 selectionColorClassName="accent-focus/32"
465 value={promptText}467 value={promptText}
466 onChangeText={setPromptText}468 onChangeText={setPromptText}
467 />469 />
apps/mobile/src/features/files/FileTreeBrowser.tsx+3-2
...@@ -54,6 +54,7 @@ const FileTreeRow = memo(function FileTreeRow(props: {...@@ -54,6 +54,7 @@ const FileTreeRow = memo(function FileTreeRow(props: {
54 <Pressable54 <Pressable
55 accessibilityRole="button"55 accessibilityRole="button"
56 accessibilityLabel={node.path}56 accessibilityLabel={node.path}
57 accessibilityState={{ selected: props.selected }}
57 onPressIn={() => {58 onPressIn={() => {
58 if (node.kind === "file") {59 if (node.kind === "file") {
59 props.onPreviewFile?.(node.path);60 props.onPreviewFile?.(node.path);
...@@ -68,7 +69,7 @@ const FileTreeRow = memo(function FileTreeRow(props: {...@@ -68,7 +69,7 @@ const FileTreeRow = memo(function FileTreeRow(props: {
68 }}69 }}
69 className={cn(70 className={cn(
70 "mx-2 min-h-[42px] flex-row items-center gap-2 rounded-[12px] px-2 active:bg-subtle",71 "mx-2 min-h-[42px] flex-row items-center gap-2 rounded-[12px] px-2 active:bg-subtle",
71 props.selected && "bg-subtle-strong",72 props.selected && "bg-thread-selected",
72 )}73 )}
73 style={{ paddingLeft: 8 + depth * 18 }}74 style={{ paddingLeft: 8 + depth * 18 }}
74 >75 >
...@@ -87,7 +88,7 @@ const FileTreeRow = memo(function FileTreeRow(props: {...@@ -87,7 +88,7 @@ const FileTreeRow = memo(function FileTreeRow(props: {
87 className={cn(88 className={cn(
88 "min-w-0 flex-1 text-sm leading-normal",89 "min-w-0 flex-1 text-sm leading-normal",
89 props.selected90 props.selected
90 ? "font-t3-bold text-foreground"91 ? "font-t3-bold text-thread-selected-foreground"
91 : node.ignored92 : node.ignored
92 ? "font-t3-medium text-foreground-tertiary"93 ? "font-t3-medium text-foreground-tertiary"
93 : "font-t3-medium text-foreground-secondary",94 : "font-t3-medium text-foreground-secondary",
apps/mobile/src/features/pull-requests/PullRequestControls.tsx+3-3
...@@ -23,7 +23,7 @@ export function PullRequestCardGroup(props: { readonly children: ReactNode }) {...@@ -23,7 +23,7 @@ export function PullRequestCardGroup(props: { readonly children: ReactNode }) {
23 return (23 return (
24 <Animated.View24 <Animated.View
25 layout={PR_ROW_LAYOUT}25 layout={PR_ROW_LAYOUT}
26 className="overflow-hidden rounded-[22px] border-continuous bg-grouped-card"26 className="overflow-hidden rounded-[22px] border border-composer-border border-continuous bg-grouped-card"
27 >27 >
28 {props.children}28 {props.children}
29 </Animated.View>29 </Animated.View>
...@@ -218,7 +218,7 @@ export function PullRequestActionToolbar(props: {...@@ -218,7 +218,7 @@ export function PullRequestActionToolbar(props: {
218 : "bubble.left.and.bubble.right"218 : "bubble.left.and.bubble.right"
219 : undefined219 : undefined
220 }220 }
221 tintColor={colors["--color-foreground"]}221 tintColor={colors["--color-prominent-action"]}
222 disabled={primaryDisabled}222 disabled={primaryDisabled}
223 separateBackground223 separateBackground
224 >224 >
...@@ -237,7 +237,7 @@ export function PullRequestActionToolbar(props: {...@@ -237,7 +237,7 @@ export function PullRequestActionToolbar(props: {
237 : "bubble.left.and.bubble.right"237 : "bubble.left.and.bubble.right"
238 : undefined238 : undefined
239 }239 }
240 tintColor={colors["--color-foreground"]}240 tintColor={colors["--color-prominent-action"]}
241 disabled={primaryDisabled}241 disabled={primaryDisabled}
242 onPress={primaryPress}242 onPress={primaryPress}
243 separateBackground243 separateBackground
apps/mobile/src/features/pull-requests/PullRequestFiles.tsx+1-1
...@@ -125,7 +125,7 @@ export function usePullRequestFilesContent(props: {...@@ -125,7 +125,7 @@ export function usePullRequestFilesContent(props: {
125 <SymbolView125 <SymbolView
126 name="checkmark.circle.fill"126 name="checkmark.circle.fill"
127 size={18}127 size={18}
128 tintColorClassName="accent-success-foreground"128 tintColorClassName="accent-adaptive-emerald-600-400"
129 />129 />
130 ) : null}130 ) : null}
131 <SymbolView name="chevron.right" size={12} tintColorClassName="accent-icon-muted" />131 <SymbolView name="chevron.right" size={12} tintColorClassName="accent-icon-muted" />
apps/mobile/src/features/pull-requests/PullRequestMergeControls.tsx+8-4
...@@ -169,7 +169,7 @@ export function PullRequestMergeControls(props: {...@@ -169,7 +169,7 @@ export function PullRequestMergeControls(props: {
169 className={169 className={
170 Platform.OS === "android"170 Platform.OS === "android"
171 ? "flex-row items-center gap-2"171 ? "flex-row items-center gap-2"
172 : `flex-row overflow-hidden rounded-xl border-continuous ${canMerge ? "bg-foreground" : "bg-subtle-strong"}`172 : `flex-row overflow-hidden rounded-xl border-continuous ${canMerge ? "bg-prominent-action" : "bg-subtle-strong"}`
173 }173 }
174 >174 >
175 {Platform.OS === "android" ? (175 {Platform.OS === "android" ? (
...@@ -200,11 +200,13 @@ export function PullRequestMergeControls(props: {...@@ -200,11 +200,13 @@ export function PullRequestMergeControls(props: {
200 <SymbolView200 <SymbolView
201 name="arrow.triangle.merge"201 name="arrow.triangle.merge"
202 size={16}202 size={16}
203 tintColorClassName={canMerge ? "accent-screen" : "accent-icon-muted"}203 tintColorClassName={
204 canMerge ? "accent-prominent-action-foreground" : "accent-icon-muted"
205 }
204 />206 />
205 )}207 )}
206 <Text208 <Text
207 className={`shrink text-center text-sm font-t3-semibold ${canMerge ? "text-screen" : "text-foreground-muted"}`}209 className={`shrink text-center text-sm font-t3-semibold ${canMerge ? "text-prominent-action-foreground" : "text-foreground-muted"}`}
208 >210 >
209 {busy ? "Working…" : !permissions.connected ? "Reconnect to merge" : label}211 {busy ? "Working…" : !permissions.connected ? "Reconnect to merge" : label}
210 </Text>212 </Text>
...@@ -255,7 +257,9 @@ export function PullRequestMergeControls(props: {...@@ -255,7 +257,9 @@ export function PullRequestMergeControls(props: {
255 <SymbolView257 <SymbolView
256 name="chevron.down"258 name="chevron.down"
257 size={13}259 size={13}
258 tintColorClassName={canMerge ? "accent-screen" : "accent-icon-muted"}260 tintColorClassName={
261 canMerge ? "accent-prominent-action-foreground" : "accent-icon-muted"
262 }
259 />263 />
260 </Pressable>264 </Pressable>
261 )}265 )}
apps/mobile/src/features/pull-requests/PullRequestStackCard.tsx+1-1
...@@ -54,7 +54,7 @@ export function PullRequestStackCard(props: {...@@ -54,7 +54,7 @@ export function PullRequestStackCard(props: {
54 isDraft: layer.isDraft === true,54 isDraft: layer.isDraft === true,
55 });55 });
56 return (56 return (
57 <View key={layer.number} className={selected ? "bg-subtle-strong" : undefined}>57 <View key={layer.number} className={selected ? "bg-thread-selected" : undefined}>
58 <PullRequestCardRow58 <PullRequestCardRow
59 title={layer.title ?? layer.headBranch}59 title={layer.title ?? layer.headBranch}
60 icon={status.icon}60 icon={status.icon}
apps/mobile/src/features/threads/HtmlRenderWebView.tsx+1-1
...@@ -271,7 +271,7 @@ export function ThreadHtmlRender(props: {...@@ -271,7 +271,7 @@ export function ThreadHtmlRender(props: {
271 accessibilityRole="button"271 accessibilityRole="button"
272 accessibilityLabel={`Open ${title}`}272 accessibilityLabel={`Open ${title}`}
273 hitSlop={8}273 hitSlop={8}
274 className="absolute right-1.5 top-1.5 h-7 w-7 items-center justify-center rounded-full border border-border/60 bg-surface/80"274 className="absolute right-1.5 top-1.5 h-7 w-7 items-center justify-center rounded-full border border-border/60 bg-card/80"
275 onPress={() =>275 onPress={() =>
276 navigation.navigate("ThreadAttachment", {276 navigation.navigate("ThreadAttachment", {
277 environmentId: String(props.environmentId),277 environmentId: String(props.environmentId),
apps/mobile/src/features/threads/McpAppFullscreenScreen.tsx+1-1
...@@ -120,7 +120,7 @@ export function McpAppFullscreenScreen({ route }: McpAppFullscreenScreenProps) {...@@ -120,7 +120,7 @@ export function McpAppFullscreenScreen({ route }: McpAppFullscreenScreenProps) {
120 }, [awaitingUser, exitRequested, focused, navigation]);120 }, [awaitingUser, exitRequested, focused, navigation]);
121121
122 return (122 return (
123 <View className="flex-1 bg-background" style={{ paddingTop: insets.top }}>123 <View className="flex-1 bg-screen" style={{ paddingTop: insets.top }}>
124 <View className="h-11 flex-row items-center justify-between px-3">124 <View className="h-11 flex-row items-center justify-between px-3">
125 <Text className="text-base font-semibold text-foreground" numberOfLines={1}>125 <Text className="text-base font-semibold text-foreground" numberOfLines={1}>
126 {app?.server ?? "App"}126 {app?.server ?? "App"}
apps/mobile/src/features/threads/PendingApprovalCard.tsx+2-2
...@@ -47,7 +47,7 @@ export function PendingApprovalCard(props: PendingApprovalCardProps) {...@@ -47,7 +47,7 @@ export function PendingApprovalCard(props: PendingApprovalCardProps) {
47 </Text>47 </Text>
48 ) : null}48 ) : null}
49 {!canRespond ? (49 {!canRespond ? (
50 <Text className="font-sans text-sm leading-5 text-adaptive-neutral-600-400">50 <Text className="font-sans text-sm leading-5 text-foreground-muted">
51 The provider process for this request is no longer available. Interrupt or restart the run51 The provider process for this request is no longer available. Interrupt or restart the run
52 to continue.52 to continue.
53 </Text>53 </Text>
...@@ -73,7 +73,7 @@ export function PendingApprovalCard(props: PendingApprovalCardProps) {...@@ -73,7 +73,7 @@ export function PendingApprovalCard(props: PendingApprovalCardProps) {
73 ))}73 ))}
74 </View>74 </View>
75 {!props.canOperateThread ? (75 {!props.canOperateThread ? (
76 <Text className="font-sans text-xs text-adaptive-neutral-500-400">76 <Text className="font-sans text-xs text-foreground-muted">
77 This connection cannot respond to approvals.77 This connection cannot respond to approvals.
78 </Text>78 </Text>
79 ) : null}79 ) : null}
apps/mobile/src/features/threads/PendingUserInputCard.tsx+1-1
...@@ -265,7 +265,7 @@ export function PendingUserInputCard(props: PendingUserInputCardProps) {...@@ -265,7 +265,7 @@ export function PendingUserInputCard(props: PendingUserInputCardProps) {
265 style={{ flexShrink: 1 }}265 style={{ flexShrink: 1 }}
266 >266 >
267 {!canRespond ? (267 {!canRespond ? (
268 <Text className="font-sans text-sm leading-5 text-adaptive-neutral-600-400">268 <Text className="font-sans text-sm leading-5 text-foreground-muted">
269 The provider process for this request is no longer available. Interrupt or restart the269 The provider process for this request is no longer available. Interrupt or restart the
270 run to continue.270 run to continue.
271 </Text>271 </Text>
apps/mobile/src/features/threads/ThreadFeed.tsx+1-1
...@@ -2758,7 +2758,7 @@ function ThreadFeedLoadEarlierControl(props: ThreadFeedHistoryControls) {...@@ -2758,7 +2758,7 @@ function ThreadFeedLoadEarlierControl(props: ThreadFeedHistoryControls) {
2758 accessibilityLabel="Load earlier activity"2758 accessibilityLabel="Load earlier activity"
2759 disabled={props.loading}2759 disabled={props.loading}
2760 onPress={props.onLoadEarlier}2760 onPress={props.onLoadEarlier}
2761 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"2761 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"
2762 >2762 >
2763 {props.loading ? (2763 {props.loading ? (
2764 <AppActivityIndicator size="small" color={accentColor} />2764 <AppActivityIndicator size="small" color={accentColor} />
apps/mobile/src/features/threads/thread-context-divider.tsx+2-2
...@@ -14,7 +14,7 @@ export function ThreadContextDivider(props: {...@@ -14,7 +14,7 @@ export function ThreadContextDivider(props: {
14}) {14}) {
15 return (15 return (
16 <View className="mb-3 flex-row items-center gap-3 px-1 py-1">16 <View className="mb-3 flex-row items-center gap-3 px-1 py-1">
17 <View className="h-px min-w-2 flex-1 bg-adaptive-neutral-200-a80-white-a8" />17 <View className="h-px min-w-2 flex-1 bg-separator" />
18 <View className="shrink flex-row flex-wrap items-center justify-center gap-1.5">18 <View className="shrink flex-row flex-wrap items-center justify-center gap-1.5">
19 <SymbolView name={props.icon} size={12} tintColor={props.iconColor} type="monochrome" />19 <SymbolView name={props.icon} size={12} tintColor={props.iconColor} type="monochrome" />
20 {props.active ? (20 {props.active ? (
...@@ -40,7 +40,7 @@ export function ThreadContextDivider(props: {...@@ -40,7 +40,7 @@ export function ThreadContextDivider(props: {
40 )}40 )}
41 {props.children}41 {props.children}
42 </View>42 </View>
43 <View className="h-px min-w-2 flex-1 bg-adaptive-neutral-200-a80-white-a8" />43 <View className="h-px min-w-2 flex-1 bg-separator" />
44 </View>44 </View>
45 );45 );
46}46}
apps/mobile/src/features/threads/thread-work-log.tsx+1-1
...@@ -1535,7 +1535,7 @@ function ToolActivityImage(props: {...@@ -1535,7 +1535,7 @@ function ToolActivityImage(props: {
1535 const [loaded, setLoaded] = useState(false);1535 const [loaded, setLoaded] = useState(false);
1536 const [failed, setFailed] = useState(false);1536 const [failed, setFailed] = useState(false);
1537 return (1537 return (
1538 <View className="h-4 w-4 items-center justify-center overflow-hidden rounded-[3px] bg-background">1538 <View className="h-4 w-4 items-center justify-center overflow-hidden rounded-[3px] bg-screen">
1539 {!loaded || failed ? <WorkLogIcon icon={props.fallback} color={props.color} /> : null}1539 {!loaded || failed ? <WorkLogIcon icon={props.fallback} color={props.color} /> : null}
1540 {!failed ? (1540 {!failed ? (
1541 <View1541 <View
apps/mobile/src/features/workspace/WorkspaceDock.tsx+2-11
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1import { Keyboard, Platform, PlatformColor, Pressable, View } from "react-native";1import { Keyboard, Pressable, View } from "react-native";
22
3import { SymbolView } from "../../components/AppSymbol";3import { SymbolView } from "../../components/AppSymbol";
4import { GlassSurface } from "../../components/GlassSurface";4import { GlassSurface } from "../../components/GlassSurface";
...@@ -43,16 +43,7 @@ export function WorkspaceDock(props: { readonly onNewTask: () => void }) {...@@ -43,16 +43,7 @@ export function WorkspaceDock(props: { readonly onNewTask: () => void }) {
43 <SymbolView43 <SymbolView
44 name={tab === "threads" ? "text.bubble" : "arrow.triangle.pull"}44 name={tab === "threads" ? "text.bubble" : "arrow.triangle.pull"}
45 size={23}45 size={23}
46 tintColor={46 tintColorClassName={selected ? "accent-focus" : "accent-icon"}
47 selected && Platform.OS === "ios" ? PlatformColor("systemBlue") : undefined
48 }
49 tintColorClassName={
50 selected && Platform.OS === "ios"
51 ? undefined
52 : selected
53 ? "accent-focus"
54 : "accent-icon"
55 }
56 />47 />
57 </Pressable>48 </Pressable>
58 );49 );
apps/mobile/src/lib/mobileTheme.test.ts+60
...@@ -255,6 +255,66 @@ describe("mobile themes", () => {...@@ -255,6 +255,66 @@ describe("mobile themes", () => {
255 },255 },
256 );256 );
257257
258 it("keeps T3 Chat light grouped cards distinct from the sheet", () => {
259 const variables = getMobileThemeVariables("t3-chat", "light");
260 const group = variables["--color-grouped-card"];
261 expect(contrastRatio(group, variables["--color-sheet-solid"])).toBeGreaterThanOrEqual(1.1);
262 for (const role of ["--color-foreground", "--color-foreground-muted"] as const) {
263 expect(contrastRatio(variables[role], group)).toBeGreaterThanOrEqual(4.5);
264 }
265 });
266
267 it.each(MOBILE_THEME_IDS)("keeps %s prominent actions readable and themed", (themeId) => {
268 for (const appearance of ["light", "dark"] as const) {
269 const variables = getMobileThemeVariables(themeId, appearance);
270 const fill = variables["--color-prominent-action"];
271 expect(
272 contrastRatio(variables["--color-prominent-action-foreground"], fill),
273 ).toBeGreaterThanOrEqual(4.5);
274 expect(fill).toBe(
275 variables[
276 themeId === "t3-chat" && appearance === "dark"
277 ? "--color-primary-foreground"
278 : themeId === DEFAULT_MOBILE_THEME_ID || themeId === "t3-chat"
279 ? "--color-foreground"
280 : "--color-primary"
281 ],
282 );
283 }
284 });
285
286 it.each(["grove", "ocean", "ember", "iris"] as const)(
287 "keeps %s grouped cards and floating controls visibly tinted",
288 (themeId) => {
289 const saturation = (hex: string) => {
290 const channels = hex
291 .slice(1)
292 .match(/.{2}/g)!
293 .map((value) => parseInt(value, 16));
294 return (Math.max(...channels) - Math.min(...channels)) / Math.max(...channels);
295 };
296 for (const appearance of ["light", "dark"] as const) {
297 const variables = getMobileThemeVariables(themeId, appearance);
298 const sheet = variables["--color-sheet-solid"];
299 const group = variables["--color-grouped-card"];
300 expect(contrastRatio(group, sheet)).toBeGreaterThanOrEqual(1.06);
301 for (const role of ["--color-composer-surface", "--color-glass-fallback"] as const) {
302 const surface = flattenThemeColor(variables[role], sheet);
303 expect(contrastRatio(surface, sheet)).toBeGreaterThanOrEqual(1.06);
304 expect(contrastRatio(variables["--color-placeholder"], surface)).toBeGreaterThanOrEqual(
305 4.5,
306 );
307 if (appearance === "dark") {
308 expect(saturation(surface)).toBeGreaterThanOrEqual(saturation(sheet));
309 }
310 }
311 if (appearance === "dark") {
312 expect(saturation(group)).toBeGreaterThanOrEqual(saturation(sheet));
313 }
314 }
315 },
316 );
317
258 it.each(["light", "dark"] as const)(318 it.each(["light", "dark"] as const)(
259 "slightly strengthens default %s messages and separates fallback materials",319 "slightly strengthens default %s messages and separates fallback materials",
260 (appearance) => {320 (appearance) => {
apps/mobile/src/lib/mobileTheme.ts+20-7
...@@ -247,6 +247,7 @@ export function createMobileThemeVariables(...@@ -247,6 +247,7 @@ export function createMobileThemeVariables(
247 colors: ThemeColors,247 colors: ThemeColors,
248 appearance: MobileThemeAppearance,248 appearance: MobileThemeAppearance,
249 groupedCardColor = colors.surface,249 groupedCardColor = colors.surface,
250 prominentAction: readonly [string, string] = [colors.text, colors.canvas],
250) {251) {
251 const c = nativeColors(colors);252 const c = nativeColors(colors);
252 const groupedCard = themeColorToNativeColor(groupedCardColor);253 const groupedCard = themeColorToNativeColor(groupedCardColor);
...@@ -299,6 +300,8 @@ export function createMobileThemeVariables(...@@ -299,6 +300,8 @@ export function createMobileThemeVariables(
299 "--color-inline-skill-border": withAlpha(c.accent, 0.42),300 "--color-inline-skill-border": withAlpha(c.accent, 0.42),
300 "--color-inline-skill-foreground": c.accentSurfaceForeground,301 "--color-inline-skill-foreground": c.accentSurfaceForeground,
301 "--color-primary": c.messageAction,302 "--color-primary": c.messageAction,
303 "--color-prominent-action": themeColorToNativeColor(prominentAction[0]),
304 "--color-prominent-action-foreground": themeColorToNativeColor(prominentAction[1]),
302 "--color-primary-foreground": c.messageActionForeground,305 "--color-primary-foreground": c.messageActionForeground,
303 "--color-primary-text": themeColorWithContrast(c.messageAction, textSurfaces),306 "--color-primary-text": themeColorWithContrast(c.messageAction, textSurfaces),
304 "--color-primary-shadow": "#000000",307 "--color-primary-shadow": "#000000",
...@@ -386,17 +389,18 @@ export function getMobileThemeVariables(...@@ -386,17 +389,18 @@ export function getMobileThemeVariables(
386 overrides: Partial<MobileThemeVariables> | null = null,389 overrides: Partial<MobileThemeVariables> | null = null,
387): MobileThemeVariables {390): MobileThemeVariables {
388 const colors = getMobileThemeColors(themeId, appearance);391 const colors = getMobileThemeColors(themeId, appearance);
389 // Mobile settings groups and fallback materials use tonal fills where desktop392 // Mobile groups and floating controls need a tonal fill, rather than the
390 // uses outlined cards. Raise flat desktop surfaces above the sheet so grouped393 // nearly neutral raised surface used by desktop outlined cards.
391 // content keeps a visible boundary. Regular cards retain their desktop surface.
392 const groupedCard =394 const groupedCard =
393 themeId === DEFAULT_MOBILE_THEME_ID395 themeId === DEFAULT_MOBILE_THEME_ID
394 ? appearance === "light"396 ? appearance === "light"
395 ? colors.toolbarControlHover397 ? colors.toolbarControlHover
396 : colors.sidebarRowActive398 : colors.sidebarRowActive
397 : colors.surface === colors.chrome399 : themeId === "t3-chat"
398 ? colors.surfaceRaised400 ? appearance === "light"
399 : colors.surface;401 ? colors.toolbarControl
402 : colors.surface
403 : colors.muted;
400 const mobileColors =404 const mobileColors =
401 themeId === DEFAULT_MOBILE_THEME_ID405 themeId === DEFAULT_MOBILE_THEME_ID
402 ? {406 ? {
...@@ -410,7 +414,16 @@ export function getMobileThemeVariables(...@@ -410,7 +414,16 @@ export function getMobileThemeVariables(
410 ),414 ),
411 }415 }
412 : colors;416 : colors;
413 const baseVariables = createMobileThemeVariables(mobileColors, appearance, groupedCard);417 const baseVariables = createMobileThemeVariables(
418 mobileColors,
419 appearance,
420 groupedCard,
421 themeId === "t3-chat" && appearance === "dark"
422 ? [colors.messageActionForeground, colors.messageAction]
423 : themeId !== DEFAULT_MOBILE_THEME_ID && themeId !== "t3-chat"
424 ? [colors.messageAction, colors.messageActionForeground]
425 : undefined,
426 );
414427
415 // The complete base record guarantees that optional overrides cannot leave a token undefined.428 // The complete base record guarantees that optional overrides cannot leave a token undefined.
416 return overrides ? ({ ...baseVariables, ...overrides } as MobileThemeVariables) : baseVariables;429 return overrides ? ({ ...baseVariables, ...overrides } as MobileThemeVariables) : baseVariables;