| author | |
| committer | |
| log | 52f9046260981270292e1fd9c77c2c3fd942be54 |
| tree | 6bd12d08325491c5dedccadd5ee55d2af3ee38f7 |
| parent | c32ade41390be10783246fbbeed45de7e3add79b |
| signature | Signed by PGP key B5690EEEBB952194 |
9 files changed, 301 insertions(+), 99 deletions(-)
apps/mobile/generated-uniwind-themes.css+58-58| ... | ... | @@ -337,7 +337,7 @@ |
| 337 | 337 | --color-composer-surface: rgba(250, 243, 251, 0.94); |
| 338 | 338 | --color-composer-border: rgba(238, 225, 237, 0.54); |
| 339 | 339 | --color-foreground: #501854; |
| 340 | --color-foreground-secondary: #ac1668; | |
| 340 | --color-foreground-secondary: #ab1668; | |
| 341 | 341 | --color-foreground-muted: #8d1255; |
| 342 | 342 | --color-foreground-tertiary: #ac1668; |
| 343 | 343 | --color-border: #eee1ed; |
| ... | ... | @@ -351,7 +351,7 @@ |
| 351 | 351 | --color-inline-skill-foreground: #454554; |
| 352 | 352 | --color-primary: #db2777; |
| 353 | 353 | --color-primary-foreground: #ffffff; |
| 354 | --color-primary-text: #d32572; | |
| 354 | --color-primary-text: #aa1e5d; | |
| 355 | 355 | --color-primary-shadow: #000000; |
| 356 | 356 | --color-secondary: #f1c4e6; |
| 357 | 357 | --color-secondary-foreground: #77347c; |
| ... | ... | @@ -371,7 +371,7 @@ |
| 371 | 371 | --color-input: #faf3fb; |
| 372 | 372 | --color-input-border: #e7c1dc; |
| 373 | 373 | --color-sidebar-search: #f8f8f7; |
| 374 | --color-placeholder: #8b5f90; | |
| 374 | --color-placeholder: #714e76; | |
| 375 | 375 | --color-icon: #501854; |
| 376 | 376 | --color-icon-muted: #ac1668; |
| 377 | 377 | --color-icon-subtle: #ac1668; |
| ... | ... | @@ -510,7 +510,7 @@ |
| 510 | 510 | --color-inline-skill-foreground: #f8f1f5; |
| 511 | 511 | --color-primary: #a3004c; |
| 512 | 512 | --color-primary-foreground: #fbd0e8; |
| 513 | --color-primary-text: #cc729c; | |
| 513 | --color-primary-text: #d07ea4; | |
| 514 | 514 | --color-primary-shadow: #000000; |
| 515 | 515 | --color-secondary: #362d3d; |
| 516 | 516 | --color-secondary-foreground: #d4c7e1; |
| ... | ... | @@ -530,7 +530,7 @@ |
| 530 | 530 | --color-input: #29232d; |
| 531 | 531 | --color-input-border: #302029; |
| 532 | 532 | --color-sidebar-search: #261922; |
| 533 | --color-placeholder: #968d9f; | |
| 533 | --color-placeholder: #9d94a5; | |
| 534 | 534 | --color-icon: #f9f8fb; |
| 535 | 535 | --color-icon-muted: #d4c7e1; |
| 536 | 536 | --color-icon-subtle: #e7d0dd; |
| ... | ... | @@ -642,7 +642,7 @@ |
| 642 | 642 | --color-sheet: rgba(243, 247, 244, 0.98); |
| 643 | 643 | --color-sheet-solid: #f3f7f4; |
| 644 | 644 | --color-card: #f3f7f4; |
| 645 | --color-grouped-card: #f3f7f4; | |
| 645 | --color-grouped-card: #ecefed; | |
| 646 | 646 | --color-card-alt: #ecefed; |
| 647 | 647 | --color-card-translucent: rgba(243, 247, 244, 0.8); |
| 648 | 648 | --color-thread-canvas: #f3f7f4; |
| ... | ... | @@ -652,11 +652,11 @@ |
| 652 | 652 | --color-thread-hover: #cae0d5; |
| 653 | 653 | --color-row-hover: #d5e6dd; |
| 654 | 654 | --color-composer-panel: rgba(243, 247, 244, 0.88); |
| 655 | --color-composer-surface: rgba(243, 247, 244, 0.94); | |
| 656 | --color-composer-border: rgba(203, 213, 209, 0.54); | |
| 655 | --color-composer-surface: rgba(236, 239, 237, 0.94); | |
| 656 | --color-composer-border: rgba(203, 213, 209, 0.8); | |
| 657 | 657 | --color-foreground: #241523; |
| 658 | --color-foreground-secondary: #726a71; | |
| 659 | --color-foreground-muted: #6e696f; | |
| 658 | --color-foreground-secondary: #6f686f; | |
| 659 | --color-foreground-muted: #6d686e; | |
| 660 | 660 | --color-foreground-tertiary: #746c73; |
| 661 | 661 | --color-border: #cbd5d1; |
| 662 | 662 | --color-focus: #1b7d50; |
| ... | ... | @@ -669,7 +669,7 @@ |
| 669 | 669 | --color-inline-skill-foreground: #241523; |
| 670 | 670 | --color-primary: #8f6410; |
| 671 | 671 | --color-primary-foreground: #fffaff; |
| 672 | --color-primary-text: #8f6410; | |
| 672 | --color-primary-text: #8d6210; | |
| 673 | 673 | --color-primary-shadow: #000000; |
| 674 | 674 | --color-secondary: #e2ede7; |
| 675 | 675 | --color-secondary-foreground: #241523; |
| ... | ... | @@ -689,7 +689,7 @@ |
| 689 | 689 | --color-input: #f3f7f4; |
| 690 | 690 | --color-input-border: #becbc5; |
| 691 | 691 | --color-sidebar-search: #d3dcd8; |
| 692 | --color-placeholder: #716971; | |
| 692 | --color-placeholder: #6f686f; | |
| 693 | 693 | --color-icon: #241523; |
| 694 | 694 | --color-icon-muted: #746c73; |
| 695 | 695 | --color-icon-subtle: #746c73; |
| ... | ... | @@ -697,7 +697,7 @@ |
| 697 | 697 | --color-header-foreground: #241523; |
| 698 | 698 | --color-header-border: #d5e6dd; |
| 699 | 699 | --color-glass-surface: rgba(231, 233, 232, 0.74); |
| 700 | --color-glass-fallback: rgba(243, 247, 244, 0.94); | |
| 700 | --color-glass-fallback: rgba(236, 239, 237, 0.94); | |
| 701 | 701 | --color-glass-tint: rgba(231, 233, 232, 0.22); |
| 702 | 702 | --color-status-bar: #f3f7f4; |
| 703 | 703 | --color-md-body: #241523; |
| ... | ... | @@ -801,7 +801,7 @@ |
| 801 | 801 | --color-sheet: rgba(27, 40, 33, 0.98); |
| 802 | 802 | --color-sheet-solid: #1b2821; |
| 803 | 803 | --color-card: #1b2821; |
| 804 | --color-grouped-card: #1b2821; | |
| 804 | --color-grouped-card: #36413c; | |
| 805 | 805 | --color-card-alt: #36413c; |
| 806 | 806 | --color-card-translucent: rgba(27, 40, 33, 0.8); |
| 807 | 807 | --color-thread-canvas: #1b2821; |
| ... | ... | @@ -811,11 +811,11 @@ |
| 811 | 811 | --color-thread-hover: #2a4938; |
| 812 | 812 | --color-row-hover: #325c46; |
| 813 | 813 | --color-composer-panel: rgba(27, 40, 33, 0.92); |
| 814 | --color-composer-surface: rgba(27, 40, 33, 0.9); | |
| 815 | --color-composer-border: rgba(65, 95, 79, 0.46); | |
| 814 | --color-composer-surface: rgba(54, 65, 60, 0.9); | |
| 815 | --color-composer-border: rgba(65, 95, 79, 0.8); | |
| 816 | 816 | --color-foreground: #fffaff; |
| 817 | --color-foreground-secondary: #a6aaaa; | |
| 818 | --color-foreground-muted: #a3aba8; | |
| 817 | --color-foreground-secondary: #afb1b1; | |
| 818 | --color-foreground-muted: #acb2b0; | |
| 819 | 819 | --color-foreground-tertiary: #919595; |
| 820 | 820 | --color-border: #415f4f; |
| 821 | 821 | --color-focus: #69d69a; |
| ... | ... | @@ -848,7 +848,7 @@ |
| 848 | 848 | --color-input: #1b2821; |
| 849 | 849 | --color-input-border: #4f725f; |
| 850 | 850 | --color-sidebar-search: #45554d; |
| 851 | --color-placeholder: #a9abab; | |
| 851 | --color-placeholder: #afb1b1; | |
| 852 | 852 | --color-icon: #fffaff; |
| 853 | 853 | --color-icon-muted: #919595; |
| 854 | 854 | --color-icon-subtle: #919595; |
| ... | ... | @@ -856,7 +856,7 @@ |
| 856 | 856 | --color-header-foreground: #fffaff; |
| 857 | 857 | --color-header-border: #36654c; |
| 858 | 858 | --color-glass-surface: rgba(68, 77, 73, 0.74); |
| 859 | --color-glass-fallback: rgba(27, 40, 33, 0.9); | |
| 859 | --color-glass-fallback: rgba(54, 65, 60, 0.9); | |
| 860 | 860 | --color-glass-tint: rgba(68, 77, 73, 0.22); |
| 861 | 861 | --color-status-bar: #1b2821; |
| 862 | 862 | --color-md-body: #fffaff; |
| ... | ... | @@ -960,7 +960,7 @@ |
| 960 | 960 | --color-sheet: rgba(245, 247, 248, 0.98); |
| 961 | 961 | --color-sheet-solid: #f5f7f8; |
| 962 | 962 | --color-card: #f5f7f8; |
| 963 | --color-grouped-card: #f5f7f8; | |
| 963 | --color-grouped-card: #edeff1; | |
| 964 | 964 | --color-card-alt: #edeff1; |
| 965 | 965 | --color-card-translucent: rgba(245, 247, 248, 0.8); |
| 966 | 966 | --color-thread-canvas: #f5f7f8; |
| ... | ... | @@ -970,10 +970,10 @@ |
| 970 | 970 | --color-thread-hover: #cdddea; |
| 971 | 971 | --color-row-hover: #d8e4ee; |
| 972 | 972 | --color-composer-panel: rgba(245, 247, 248, 0.88); |
| 973 | --color-composer-surface: rgba(245, 247, 248, 0.94); | |
| 974 | --color-composer-border: rgba(205, 212, 220, 0.54); | |
| 973 | --color-composer-surface: rgba(237, 239, 241, 0.94); | |
| 974 | --color-composer-border: rgba(205, 212, 220, 0.8); | |
| 975 | 975 | --color-foreground: #241523; |
| 976 | --color-foreground-secondary: #726a73; | |
| 976 | --color-foreground-secondary: #706870; | |
| 977 | 977 | --color-foreground-muted: #6f6873; |
| 978 | 978 | --color-foreground-tertiary: #746c75; |
| 979 | 979 | --color-border: #cdd4dc; |
| ... | ... | @@ -1007,7 +1007,7 @@ |
| 1007 | 1007 | --color-input: #f5f7f8; |
| 1008 | 1008 | --color-input-border: #c0c9d4; |
| 1009 | 1009 | --color-sidebar-search: #d5dbe2; |
| 1010 | --color-placeholder: #716972; | |
| 1010 | --color-placeholder: #706870; | |
| 1011 | 1011 | --color-icon: #241523; |
| 1012 | 1012 | --color-icon-muted: #746c75; |
| 1013 | 1013 | --color-icon-subtle: #746c75; |
| ... | ... | @@ -1015,7 +1015,7 @@ |
| 1015 | 1015 | --color-header-foreground: #241523; |
| 1016 | 1016 | --color-header-border: #d8e4ee; |
| 1017 | 1017 | --color-glass-surface: rgba(232, 233, 235, 0.74); |
| 1018 | --color-glass-fallback: rgba(245, 247, 248, 0.94); | |
| 1018 | --color-glass-fallback: rgba(237, 239, 241, 0.94); | |
| 1019 | 1019 | --color-glass-tint: rgba(232, 233, 235, 0.22); |
| 1020 | 1020 | --color-status-bar: #f5f7f8; |
| 1021 | 1021 | --color-md-body: #241523; |
| ... | ... | @@ -1119,7 +1119,7 @@ |
| 1119 | 1119 | --color-sheet: rgba(23, 33, 43, 0.98); |
| 1120 | 1120 | --color-sheet-solid: #17212b; |
| 1121 | 1121 | --color-card: #17212b; |
| 1122 | --color-grouped-card: #17212b; | |
| 1122 | --color-grouped-card: #333b45; | |
| 1123 | 1123 | --color-card-alt: #333b45; |
| 1124 | 1124 | --color-card-translucent: rgba(23, 33, 43, 0.8); |
| 1125 | 1125 | --color-thread-canvas: #17212b; |
| ... | ... | @@ -1129,11 +1129,11 @@ |
| 1129 | 1129 | --color-thread-hover: #283e50; |
| 1130 | 1130 | --color-row-hover: #324e66; |
| 1131 | 1131 | --color-composer-panel: rgba(23, 33, 43, 0.92); |
| 1132 | --color-composer-surface: rgba(23, 33, 43, 0.9); | |
| 1133 | --color-composer-border: rgba(64, 85, 103, 0.46); | |
| 1132 | --color-composer-surface: rgba(51, 59, 69, 0.9); | |
| 1133 | --color-composer-border: rgba(64, 85, 103, 0.8); | |
| 1134 | 1134 | --color-foreground: #fffaff; |
| 1135 | --color-foreground-secondary: #a2a3aa; | |
| 1136 | --color-foreground-muted: #9ea4ad; | |
| 1135 | --color-foreground-secondary: #a5a7ad; | |
| 1136 | --color-foreground-muted: #a2a7b0; | |
| 1137 | 1137 | --color-foreground-tertiary: #8d8f97; |
| 1138 | 1138 | --color-border: #405567; |
| 1139 | 1139 | --color-focus: #70b9ee; |
| ... | ... | @@ -1166,7 +1166,7 @@ |
| 1166 | 1166 | --color-input: #17212b; |
| 1167 | 1167 | --color-input-border: #4f677b; |
| 1168 | 1168 | --color-sidebar-search: #424e5a; |
| 1169 | --color-placeholder: #a4a4ac; | |
| 1169 | --color-placeholder: #a6a6ad; | |
| 1170 | 1170 | --color-icon: #fffaff; |
| 1171 | 1171 | --color-icon-muted: #8d8f97; |
| 1172 | 1172 | --color-icon-subtle: #8d8f97; |
| ... | ... | @@ -1174,7 +1174,7 @@ |
| 1174 | 1174 | --color-header-foreground: #fffaff; |
| 1175 | 1175 | --color-header-border: #36566f; |
| 1176 | 1176 | --color-glass-surface: rgba(65, 72, 81, 0.74); |
| 1177 | --color-glass-fallback: rgba(23, 33, 43, 0.9); | |
| 1177 | --color-glass-fallback: rgba(51, 59, 69, 0.9); | |
| 1178 | 1178 | --color-glass-tint: rgba(65, 72, 81, 0.22); |
| 1179 | 1179 | --color-status-bar: #17212b; |
| 1180 | 1180 | --color-md-body: #fffaff; |
| ... | ... | @@ -1278,7 +1278,7 @@ |
| 1278 | 1278 | --color-sheet: rgba(249, 247, 245, 0.98); |
| 1279 | 1279 | --color-sheet-solid: #f9f7f5; |
| 1280 | 1280 | --color-card: #f9f7f5; |
| 1281 | --color-grouped-card: #f9f7f5; | |
| 1281 | --color-grouped-card: #f1efee; | |
| 1282 | 1282 | --color-card-alt: #f1efee; |
| 1283 | 1283 | --color-card-translucent: rgba(249, 247, 245, 0.8); |
| 1284 | 1284 | --color-thread-canvas: #f9f7f5; |
| ... | ... | @@ -1288,11 +1288,11 @@ |
| 1288 | 1288 | --color-thread-hover: #ead8cf; |
| 1289 | 1289 | --color-row-hover: #eee0d9; |
| 1290 | 1290 | --color-composer-panel: rgba(249, 247, 245, 0.88); |
| 1291 | --color-composer-surface: rgba(249, 247, 245, 0.94); | |
| 1292 | --color-composer-border: rgba(221, 210, 206, 0.54); | |
| 1291 | --color-composer-surface: rgba(241, 239, 238, 0.94); | |
| 1292 | --color-composer-border: rgba(221, 210, 206, 0.8); | |
| 1293 | 1293 | --color-foreground: #241523; |
| 1294 | --color-foreground-secondary: #746a72; | |
| 1295 | --color-foreground-muted: #74686f; | |
| 1294 | --color-foreground-secondary: #726870; | |
| 1295 | --color-foreground-muted: #73686e; | |
| 1296 | 1296 | --color-foreground-tertiary: #766c74; |
| 1297 | 1297 | --color-border: #ddd2ce; |
| 1298 | 1298 | --color-focus: #ae552a; |
| ... | ... | @@ -1325,7 +1325,7 @@ |
| 1325 | 1325 | --color-input: #f9f7f5; |
| 1326 | 1326 | --color-input-border: #d4c6c1; |
| 1327 | 1327 | --color-sidebar-search: #e2d9d6; |
| 1328 | --color-placeholder: #736971; | |
| 1328 | --color-placeholder: #726870; | |
| 1329 | 1329 | --color-icon: #241523; |
| 1330 | 1330 | --color-icon-muted: #766c74; |
| 1331 | 1331 | --color-icon-subtle: #766c74; |
| ... | ... | @@ -1333,7 +1333,7 @@ |
| 1333 | 1333 | --color-header-foreground: #241523; |
| 1334 | 1334 | --color-header-border: #eee0d9; |
| 1335 | 1335 | --color-glass-surface: rgba(236, 233, 233, 0.74); |
| 1336 | --color-glass-fallback: rgba(249, 247, 245, 0.94); | |
| 1336 | --color-glass-fallback: rgba(241, 239, 238, 0.94); | |
| 1337 | 1337 | --color-glass-tint: rgba(236, 233, 233, 0.22); |
| 1338 | 1338 | --color-status-bar: #f9f7f5; |
| 1339 | 1339 | --color-md-body: #241523; |
| ... | ... | @@ -1437,7 +1437,7 @@ |
| 1437 | 1437 | --color-sheet: rgba(41, 30, 26, 0.98); |
| 1438 | 1438 | --color-sheet-solid: #291e1a; |
| 1439 | 1439 | --color-card: #291e1a; |
| 1440 | --color-grouped-card: #291e1a; | |
| 1440 | --color-grouped-card: #433835; | |
| 1441 | 1441 | --color-card-alt: #433835; |
| 1442 | 1442 | --color-card-translucent: rgba(41, 30, 26, 0.8); |
| 1443 | 1443 | --color-thread-canvas: #291e1a; |
| ... | ... | @@ -1447,11 +1447,11 @@ |
| 1447 | 1447 | --color-thread-hover: #4f3528; |
| 1448 | 1448 | --color-row-hover: #644330; |
| 1449 | 1449 | --color-composer-panel: rgba(41, 30, 26, 0.92); |
| 1450 | --color-composer-surface: rgba(41, 30, 26, 0.9); | |
| 1451 | --color-composer-border: rgba(102, 76, 63, 0.46); | |
| 1450 | --color-composer-surface: rgba(67, 56, 53, 0.9); | |
| 1451 | --color-composer-border: rgba(102, 76, 63, 0.8); | |
| 1452 | 1452 | --color-foreground: #fffaff; |
| 1453 | --color-foreground-secondary: #a8a2a2; | |
| 1454 | --color-foreground-muted: #aca19f; | |
| 1453 | --color-foreground-secondary: #aca5a6; | |
| 1454 | --color-foreground-muted: #afa5a2; | |
| 1455 | 1455 | --color-foreground-tertiary: #968e8f; |
| 1456 | 1456 | --color-border: #664c3f; |
| 1457 | 1457 | --color-focus: #f09a64; |
| ... | ... | @@ -1484,7 +1484,7 @@ |
| 1484 | 1484 | --color-input: #291e1a; |
| 1485 | 1485 | --color-input-border: #7a5d4d; |
| 1486 | 1486 | --color-sidebar-search: #584943; |
| 1487 | --color-placeholder: #aba3a5; | |
| 1487 | --color-placeholder: #aca5a6; | |
| 1488 | 1488 | --color-icon: #fffaff; |
| 1489 | 1489 | --color-icon-muted: #968e8f; |
| 1490 | 1490 | --color-icon-subtle: #968e8f; |
| ... | ... | @@ -1492,7 +1492,7 @@ |
| 1492 | 1492 | --color-header-foreground: #fffaff; |
| 1493 | 1493 | --color-header-border: #6e4934; |
| 1494 | 1494 | --color-glass-surface: rgba(79, 69, 67, 0.74); |
| 1495 | --color-glass-fallback: rgba(41, 30, 26, 0.9); | |
| 1495 | --color-glass-fallback: rgba(67, 56, 53, 0.9); | |
| 1496 | 1496 | --color-glass-tint: rgba(79, 69, 67, 0.22); |
| 1497 | 1497 | --color-status-bar: #291e1a; |
| 1498 | 1498 | --color-md-body: #fffaff; |
| ... | ... | @@ -1596,7 +1596,7 @@ |
| 1596 | 1596 | --color-sheet: rgba(248, 247, 249, 0.98); |
| 1597 | 1597 | --color-sheet-solid: #f8f7f9; |
| 1598 | 1598 | --color-card: #f8f7f9; |
| 1599 | --color-grouped-card: #f8f7f9; | |
| 1599 | --color-grouped-card: #f0eff2; | |
| 1600 | 1600 | --color-card-alt: #f0eff2; |
| 1601 | 1601 | --color-card-translucent: rgba(248, 247, 249, 0.8); |
| 1602 | 1602 | --color-thread-canvas: #f8f7f9; |
| ... | ... | @@ -1606,11 +1606,11 @@ |
| 1606 | 1606 | --color-thread-hover: #ded8ed; |
| 1607 | 1607 | --color-row-hover: #e5e0f0; |
| 1608 | 1608 | --color-composer-panel: rgba(248, 247, 249, 0.88); |
| 1609 | --color-composer-surface: rgba(248, 247, 249, 0.94); | |
| 1610 | --color-composer-border: rgba(214, 209, 222, 0.54); | |
| 1609 | --color-composer-surface: rgba(240, 239, 242, 0.94); | |
| 1610 | --color-composer-border: rgba(214, 209, 222, 0.8); | |
| 1611 | 1611 | --color-foreground: #241523; |
| 1612 | --color-foreground-secondary: #746a74; | |
| 1613 | --color-foreground-muted: #726874; | |
| 1612 | --color-foreground-secondary: #716871; | |
| 1613 | --color-foreground-muted: #716773; | |
| 1614 | 1614 | --color-foreground-tertiary: #766c76; |
| 1615 | 1615 | --color-border: #d6d1de; |
| 1616 | 1616 | --color-focus: #7253b9; |
| ... | ... | @@ -1643,7 +1643,7 @@ |
| 1643 | 1643 | --color-input: #f8f7f9; |
| 1644 | 1644 | --color-input-border: #ccc5d6; |
| 1645 | 1645 | --color-sidebar-search: #ddd9e3; |
| 1646 | --color-placeholder: #736973; | |
| 1646 | --color-placeholder: #716871; | |
| 1647 | 1647 | --color-icon: #241523; |
| 1648 | 1648 | --color-icon-muted: #766c76; |
| 1649 | 1649 | --color-icon-subtle: #766c76; |
| ... | ... | @@ -1651,7 +1651,7 @@ |
| 1651 | 1651 | --color-header-foreground: #241523; |
| 1652 | 1652 | --color-header-border: #e5e0f0; |
| 1653 | 1653 | --color-glass-surface: rgba(235, 233, 237, 0.74); |
| 1654 | --color-glass-fallback: rgba(248, 247, 249, 0.94); | |
| 1654 | --color-glass-fallback: rgba(240, 239, 242, 0.94); | |
| 1655 | 1655 | --color-glass-tint: rgba(235, 233, 237, 0.22); |
| 1656 | 1656 | --color-status-bar: #f8f7f9; |
| 1657 | 1657 | --color-md-body: #241523; |
| ... | ... | @@ -1755,7 +1755,7 @@ |
| 1755 | 1755 | --color-sheet: rgba(29, 25, 41, 0.98); |
| 1756 | 1756 | --color-sheet-solid: #1d1929; |
| 1757 | 1757 | --color-card: #1d1929; |
| 1758 | --color-grouped-card: #1d1929; | |
| 1758 | --color-grouped-card: #383443; | |
| 1759 | 1759 | --color-card-alt: #383443; |
| 1760 | 1760 | --color-card-translucent: rgba(29, 25, 41, 0.8); |
| 1761 | 1761 | --color-thread-canvas: #1d1929; |
| ... | ... | @@ -1765,8 +1765,8 @@ |
| 1765 | 1765 | --color-thread-hover: #352c4f; |
| 1766 | 1766 | --color-row-hover: #433765; |
| 1767 | 1767 | --color-composer-panel: rgba(29, 25, 41, 0.92); |
| 1768 | --color-composer-surface: rgba(29, 25, 41, 0.9); | |
| 1769 | --color-composer-border: rgba(77, 67, 102, 0.46); | |
| 1768 | --color-composer-surface: rgba(56, 52, 67, 0.9); | |
| 1769 | --color-composer-border: rgba(77, 67, 102, 0.8); | |
| 1770 | 1770 | --color-foreground: #fffaff; |
| 1771 | 1771 | --color-foreground-secondary: #a09da6; |
| 1772 | 1772 | --color-foreground-muted: #a19cab; |
| ... | ... | @@ -1810,7 +1810,7 @@ |
| 1810 | 1810 | --color-header-foreground: #fffaff; |
| 1811 | 1811 | --color-header-border: #4a3c70; |
| 1812 | 1812 | --color-glass-surface: rgba(69, 66, 80, 0.74); |
| 1813 | --color-glass-fallback: rgba(29, 25, 41, 0.9); | |
| 1813 | --color-glass-fallback: rgba(56, 52, 67, 0.9); | |
| 1814 | 1814 | --color-glass-tint: rgba(69, 66, 80, 0.22); |
| 1815 | 1815 | --color-status-bar: #1d1929; |
| 1816 | 1816 | --color-md-body: #fffaff; |
apps/mobile/src/features/pull-requests/MaterialFloatingToolbar.android.tsx+1-1| ... | ... | @@ -15,7 +15,7 @@ export function MaterialFloatingToolbar(props: { readonly children: ReactElement |
| 15 | 15 | > |
| 16 | 16 | <HorizontalFloatingToolbar |
| 17 | 17 | colors={{ |
| 18 | toolbarContainerColor: colors["--color-card-alt"], | |
| 18 | toolbarContainerColor: colors["--color-grouped-card"], | |
| 19 | 19 | toolbarContentColor: colors["--color-foreground"], |
| 20 | 20 | }} |
| 21 | 21 | > |
apps/mobile/src/features/pull-requests/PullRequestDescription.tsx+7-6| ... | ... | @@ -6,7 +6,7 @@ import { |
| 6 | 6 | } from "./PullRequestMedia"; |
| 7 | 7 | import { PullRequestSectionHeading } from "./PullRequestSectionHeading"; |
| 8 | 8 | import { useContext, useMemo, useState } from "react"; |
| 9 | import { Pressable, ScrollView, StyleSheet, View } from "react-native"; | |
| 9 | import { Platform, Pressable, ScrollView, StyleSheet, View } from "react-native"; | |
| 10 | 10 | import Svg, { Defs, LinearGradient, Rect, Stop } from "react-native-svg"; |
| 11 | 11 | import { pullRequestImageSource } from "./pullRequestMediaSource"; |
| 12 | 12 | import { parseMarkdownDocument } from "../../lib/markdownDocument"; |
| ... | ... | @@ -30,6 +30,7 @@ export function PullRequestDescription(props: { |
| 30 | 30 | const [bodyHeight, setBodyHeight] = useState(0); |
| 31 | 31 | const mediaContext = useContext(PullRequestMediaContext); |
| 32 | 32 | const { themeVariables: colors } = useAppearancePreferences(); |
| 33 | const fadeColor = colors[Platform.OS === "android" ? "--color-sheet-solid" : "--color-screen"]; | |
| 33 | 34 | const content = useMemo(() => { |
| 34 | 35 | const document = parseMarkdownDocument(props.markdown); |
| 35 | 36 | const content = pullRequestDescriptionContent(document, splitPullRequestBody(props.markdown)); |
| ... | ... | @@ -87,10 +88,10 @@ export function PullRequestDescription(props: { |
| 87 | 88 | y2="80" |
| 88 | 89 | gradientUnits="userSpaceOnUse" |
| 89 | 90 | > |
| 90 | <Stop offset="0" stopColor={colors["--color-screen"]} stopOpacity={0} /> | |
| 91 | <Stop offset="0.5" stopColor={colors["--color-screen"]} stopOpacity={0.94} /> | |
| 92 | <Stop offset="0.72" stopColor={colors["--color-screen"]} stopOpacity={1} /> | |
| 93 | <Stop offset="1" stopColor={colors["--color-screen"]} stopOpacity={1} /> | |
| 91 | <Stop offset="0" stopColor={fadeColor} stopOpacity={0} /> | |
| 92 | <Stop offset="0.5" stopColor={fadeColor} stopOpacity={0.94} /> | |
| 93 | <Stop offset="0.72" stopColor={fadeColor} stopOpacity={1} /> | |
| 94 | <Stop offset="1" stopColor={fadeColor} stopOpacity={1} /> | |
| 94 | 95 | </LinearGradient> |
| 95 | 96 | </Defs> |
| 96 | 97 | <Rect width="100%" height="100%" fill="url(#description-fade)" /> |
| ... | ... | @@ -102,7 +103,7 @@ export function PullRequestDescription(props: { |
| 102 | 103 | left: 0, |
| 103 | 104 | right: 0, |
| 104 | 105 | height: 44, |
| 105 | backgroundColor: colors["--color-screen"], | |
| 106 | backgroundColor: fadeColor, | |
| 106 | 107 | }} |
| 107 | 108 | /> |
| 108 | 109 | </View> |
apps/mobile/src/features/workspace/AndroidWorkspaceNavigation.android.tsx+6-10| ... | ... | @@ -12,7 +12,7 @@ import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 12 | 12 | import { useKeyboardState } from "react-native-keyboard-controller"; |
| 13 | 13 | |
| 14 | 14 | import { useAndroidControlSizing } from "../../components/useAndroidControlSizing"; |
| 15 | import { flattenThemeColor, themeColorWithAlpha } from "../../lib/mobileTheme"; | |
| 15 | import { androidWorkspaceNavigationColors } from "./android-workspace-navigation-colors"; | |
| 16 | 16 | import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; |
| 17 | 17 | import { useWorkspaceTabs } from "./WorkspaceTabsContext"; |
| 18 | 18 | import type { WorkspaceTab } from "./workspace-tabs-state"; |
| ... | ... | @@ -49,12 +49,8 @@ export function AndroidWorkspaceNavigation(props: { |
| 49 | 49 | const { themeAppearance, themeVariables: colors } = useAppearancePreferences(); |
| 50 | 50 | const { scale } = useAndroidControlSizing(); |
| 51 | 51 | const rail = Boolean(props.rail); |
| 52 | const containerColor = rail | |
| 53 | ? colors["--color-header"] | |
| 54 | : flattenThemeColor( | |
| 55 | themeColorWithAlpha(colors["--color-header-foreground"], 0.05), | |
| 56 | flattenThemeColor(colors["--color-header"], colors["--color-screen"]), | |
| 57 | ); | |
| 52 | const { containerColor, indicatorColor, selectedColor, unselectedColor } = | |
| 53 | androidWorkspaceNavigationColors(colors, rail); | |
| 58 | 54 | if (!rail && keyboardVisible) return null; |
| 59 | 55 | |
| 60 | 56 | return ( |
| ... | ... | @@ -77,9 +73,9 @@ export function AndroidWorkspaceNavigation(props: { |
| 77 | 73 | dark={themeAppearance === "dark"} |
| 78 | 74 | textScale={scale} |
| 79 | 75 | containerColor={nativeColor(containerColor)} |
| 80 | selectedColor={nativeColor(colors["--color-secondary-foreground"])} | |
| 81 | indicatorColor={nativeColor(colors["--color-secondary"])} | |
| 82 | unselectedColor={nativeColor(colors["--color-header-foreground"])} | |
| 76 | selectedColor={nativeColor(selectedColor)} | |
| 77 | indicatorColor={nativeColor(indicatorColor)} | |
| 78 | unselectedColor={nativeColor(unselectedColor)} | |
| 83 | 79 | onTabSelected={(event) => { |
| 84 | 80 | Keyboard.dismiss(); |
| 85 | 81 | const tab = event.nativeEvent.tab; |
apps/mobile/src/features/workspace/android-workspace-navigation-colors.test.ts created+110| ... | ... | @@ -0,0 +1,110 @@ |
| 1 | import { describe, expect, it } from "vite-plus/test"; | |
| 2 | import { Hct, SchemeTonalSpot, argbFromHex, hexFromArgb } from "@material/material-color-utilities"; | |
| 3 | ||
| 4 | import { MOBILE_THEME_IDS } from "../../lib/mobileTheme"; | |
| 5 | import { getMobileThemeRuntimeVariables } from "../../lib/mobileThemeVariables"; | |
| 6 | import { materialYouPaletteToMobileThemeVariables } from "../../lib/materialYouTheme.android"; | |
| 7 | import type { MaterialYouPalette } from "../../lib/materialYouPalette"; | |
| 8 | import { androidWorkspaceNavigationColors } from "./android-workspace-navigation-colors"; | |
| 9 | ||
| 10 | function luminance(hex: string) { | |
| 11 | const channels = hex | |
| 12 | .slice(1, 7) | |
| 13 | .match(/.{2}/g)! | |
| 14 | .map((channel) => Number.parseInt(channel, 16) / 255) | |
| 15 | .map((channel) => (channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4)); | |
| 16 | return 0.2126 * channels[0]! + 0.7152 * channels[1]! + 0.0722 * channels[2]!; | |
| 17 | } | |
| 18 | ||
| 19 | function contrast(first: string, second: string) { | |
| 20 | const firstLuminance = luminance(first); | |
| 21 | const secondLuminance = luminance(second); | |
| 22 | return ( | |
| 23 | (Math.max(firstLuminance, secondLuminance) + 0.05) / | |
| 24 | (Math.min(firstLuminance, secondLuminance) + 0.05) | |
| 25 | ); | |
| 26 | } | |
| 27 | ||
| 28 | function expectVisibleSelection(colors: ReturnType<typeof androidWorkspaceNavigationColors>) { | |
| 29 | expect(contrast(colors.indicatorColor, colors.containerColor)).toBeGreaterThanOrEqual(1.5); | |
| 30 | // Native labels sit below the indicator, while their icons sit within it. | |
| 31 | for (const surface of [colors.containerColor, colors.indicatorColor]) { | |
| 32 | expect(contrast(colors.selectedColor, surface)).toBeGreaterThanOrEqual(4.5); | |
| 33 | } | |
| 34 | expect(contrast(colors.unselectedColor, colors.containerColor)).toBeGreaterThanOrEqual(4.5); | |
| 35 | } | |
| 36 | ||
| 37 | describe("Android workspace navigation colors", () => { | |
| 38 | it.each(MOBILE_THEME_IDS)( | |
| 39 | "keeps %s selection visible in both navigation positions", | |
| 40 | (themeId) => { | |
| 41 | for (const appearance of ["light", "dark"] as const) { | |
| 42 | const variables = getMobileThemeRuntimeVariables(themeId, appearance, "android"); | |
| 43 | const snapshot = { ...variables }; | |
| 44 | for (const rail of [false, true]) { | |
| 45 | expectVisibleSelection(androidWorkspaceNavigationColors(variables, rail)); | |
| 46 | } | |
| 47 | expect(variables).toEqual(snapshot); | |
| 48 | } | |
| 49 | }, | |
| 50 | ); | |
| 51 | ||
| 52 | it.each(["#6750a4", "#006a6a", "#9c4146"])( | |
| 53 | "keeps Material You selection visible for system seed %s", | |
| 54 | (seed) => { | |
| 55 | for (const appearance of ["light", "dark"] as const) { | |
| 56 | const scheme = new SchemeTonalSpot( | |
| 57 | Hct.fromInt(argbFromHex(seed)), | |
| 58 | appearance === "dark", | |
| 59 | 0, | |
| 60 | ); | |
| 61 | const roles = [ | |
| 62 | "primary", | |
| 63 | "onPrimary", | |
| 64 | "primaryContainer", | |
| 65 | "onPrimaryContainer", | |
| 66 | "inversePrimary", | |
| 67 | "secondaryContainer", | |
| 68 | "onSecondaryContainer", | |
| 69 | "tertiary", | |
| 70 | "tertiaryContainer", | |
| 71 | "onTertiaryContainer", | |
| 72 | "surface", | |
| 73 | "onSurface", | |
| 74 | "onSurfaceVariant", | |
| 75 | "surfaceContainer", | |
| 76 | "surfaceContainerHigh", | |
| 77 | "surfaceContainerHighest", | |
| 78 | "surfaceContainerLow", | |
| 79 | "surfaceContainerLowest", | |
| 80 | "errorContainer", | |
| 81 | "onErrorContainer", | |
| 82 | "outline", | |
| 83 | "outlineVariant", | |
| 84 | "scrim", | |
| 85 | ] as const satisfies ReadonlyArray<keyof MaterialYouPalette>; | |
| 86 | const palette = Object.fromEntries( | |
| 87 | roles.map((role) => [role, `${hexFromArgb(scheme[role])}ff`]), | |
| 88 | ) as Record<(typeof roles)[number], string>; | |
| 89 | const variables = materialYouPaletteToMobileThemeVariables( | |
| 90 | palette, | |
| 91 | appearance, | |
| 92 | getMobileThemeRuntimeVariables("material-you", appearance, "android"), | |
| 93 | ); | |
| 94 | for (const rail of [false, true]) { | |
| 95 | expectVisibleSelection(androidWorkspaceNavigationColors(variables, rail)); | |
| 96 | } | |
| 97 | } | |
| 98 | }, | |
| 99 | ); | |
| 100 | ||
| 101 | it("preserves an already visible tonal fill", () => { | |
| 102 | const variables = getMobileThemeRuntimeVariables("t3-chat", "light", "android"); | |
| 103 | const colors = androidWorkspaceNavigationColors( | |
| 104 | { ...variables, "--color-secondary": "#e091cf" }, | |
| 105 | true, | |
| 106 | ); | |
| 107 | expect(colors.indicatorColor).toBe("#e091cf"); | |
| 108 | expectVisibleSelection(colors); | |
| 109 | }); | |
| 110 | }); |
apps/mobile/src/features/workspace/android-workspace-navigation-colors.ts created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | import { | |
| 2 | flattenThemeColor, | |
| 3 | themeColorWithAlpha, | |
| 4 | themeColorWithContrast, | |
| 5 | type MobileThemeVariables, | |
| 6 | } from "../../lib/mobileTheme"; | |
| 7 | ||
| 8 | /** Both navigation positions keep a visible tonal selection against their actual surface. */ | |
| 9 | export function androidWorkspaceNavigationColors(colors: MobileThemeVariables, rail: boolean) { | |
| 10 | const header = flattenThemeColor(colors["--color-header"], colors["--color-screen"]); | |
| 11 | const containerColor = rail | |
| 12 | ? header | |
| 13 | : flattenThemeColor(themeColorWithAlpha(colors["--color-header-foreground"], 0.05), header); | |
| 14 | const indicatorColor = themeColorWithContrast( | |
| 15 | flattenThemeColor(colors["--color-secondary"], containerColor), | |
| 16 | containerColor, | |
| 17 | 1.5, | |
| 18 | ); | |
| 19 | return { | |
| 20 | containerColor, | |
| 21 | indicatorColor, | |
| 22 | selectedColor: themeColorWithContrast( | |
| 23 | flattenThemeColor(colors["--color-secondary-foreground"], indicatorColor), | |
| 24 | [indicatorColor, containerColor], | |
| 25 | ), | |
| 26 | unselectedColor: flattenThemeColor(colors["--color-header-foreground"], containerColor), | |
| 27 | }; | |
| 28 | } |
apps/mobile/src/lib/mobileTheme.test-support.ts+6-2| ... | ... | @@ -9,14 +9,18 @@ import { |
| 9 | 9 | export function readDefaultMobileThemeVariables( |
| 10 | 10 | appearance: MobileThemeAppearance, |
| 11 | 11 | ): MobileThemeVariables { |
| 12 | return readGeneratedMobileThemeVariables(appearance); | |
| 13 | } | |
| 14 | ||
| 15 | export function readGeneratedMobileThemeVariables(themeName: string): MobileThemeVariables { | |
| 12 | 16 | const stylesheet = NodeFS.readFileSync( |
| 13 | 17 | new URL("../../generated-uniwind-themes.css", import.meta.url), |
| 14 | 18 | "utf8", |
| 15 | 19 | ); |
| 16 | const variant = new RegExp(`@variant ${appearance} \\{([\\s\\S]*?)\\n \\}`, "u").exec( | |
| 20 | const variant = new RegExp(`@variant ${themeName} \\{([\\s\\S]*?)\\n \\}`, "u").exec( | |
| 17 | 21 | stylesheet, |
| 18 | 22 | )?.[1]; |
| 19 | if (variant === undefined) throw new Error(`Missing generated default ${appearance} theme.`); | |
| 23 | if (variant === undefined) throw new Error(`Missing generated ${themeName} theme.`); | |
| 20 | 24 | |
| 21 | 25 | return Object.fromEntries( |
| 22 | 26 | Array.from(variant.matchAll(/(--color-[a-z0-9-]+):\s*([^;]+);/gu), ([, name, value]) => [ |
apps/mobile/src/lib/mobileTheme.test.ts+48-7| ... | ... | @@ -8,7 +8,10 @@ import { |
| 8 | 8 | MOBILE_THEME_IDS, |
| 9 | 9 | getThemeColorsForAppearance, |
| 10 | 10 | } from "@t3tools/shared/themePalettes"; |
| 11 | import { readDefaultMobileThemeVariables } from "./mobileTheme.test-support"; | |
| 11 | import { | |
| 12 | readDefaultMobileThemeVariables, | |
| 13 | readGeneratedMobileThemeVariables, | |
| 14 | } from "./mobileTheme.test-support"; | |
| 12 | 15 | import { getMobileThemeRuntimeVariables } from "./mobileThemeVariables"; |
| 13 | 16 | |
| 14 | 17 | import { |
| ... | ... | @@ -96,12 +99,7 @@ describe("mobile themes", () => { |
| 96 | 99 | ); |
| 97 | 100 | expect(variables["--color-card"]).toBe(themeColorToNativeColor(colors.surface)); |
| 98 | 101 | expect(variables["--color-composer-surface"]).toBe( |
| 99 | themeColorWithAlpha( | |
| 100 | themeId === DEFAULT_MOBILE_THEME_ID | |
| 101 | ? variables["--color-grouped-card"] | |
| 102 | : themeColorToNativeColor(colors.surface), | |
| 103 | appearance === "dark" ? 0.9 : 0.94, | |
| 104 | ), | |
| 102 | themeColorWithAlpha(variables["--color-grouped-card"], appearance === "dark" ? 0.9 : 0.94), | |
| 105 | 103 | ); |
| 106 | 104 | expect(variables["--color-thread-selected"]).toBe( |
| 107 | 105 | themeColorToNativeColor(colors.sidebarRowActive), |
| ... | ... | @@ -182,6 +180,49 @@ describe("mobile themes", () => { |
| 182 | 180 | expect(variables["--color-screen"]).toMatch(/^#/); |
| 183 | 181 | }); |
| 184 | 182 | |
| 183 | it.each(MOBILE_THEME_IDS)("separates %s filled groups from their sheets", (themeId) => { | |
| 184 | for (const appearance of ["light", "dark"] as const) { | |
| 185 | const generated = readGeneratedMobileThemeVariables( | |
| 186 | themeId === DEFAULT_MOBILE_THEME_ID ? appearance : `${themeId}-${appearance}`, | |
| 187 | ); | |
| 188 | expect(generated).toEqual(getMobileThemeVariables(themeId, appearance)); | |
| 189 | for (const platform of ["ios", "android"]) { | |
| 190 | const variables = getMobileThemeRuntimeVariables(themeId, appearance, platform); | |
| 191 | const sheet = variables["--color-sheet-solid"]; | |
| 192 | const group = variables["--color-grouped-card"]; | |
| 193 | expect( | |
| 194 | contrastRatio(group, sheet), | |
| 195 | `${platform} ${appearance}: grouped surface on sheet`, | |
| 196 | ).toBeGreaterThanOrEqual(1.025); | |
| 197 | for (const role of [ | |
| 198 | "--color-foreground", | |
| 199 | "--color-foreground-secondary", | |
| 200 | "--color-foreground-muted", | |
| 201 | "--color-placeholder", | |
| 202 | "--color-primary-text", | |
| 203 | ] as const) { | |
| 204 | expect( | |
| 205 | contrastRatio(variables[role], group), | |
| 206 | `${platform} ${appearance}: ${role} on grouped surface`, | |
| 207 | ).toBeGreaterThanOrEqual(4.5); | |
| 208 | } | |
| 209 | if (platform === "android") { | |
| 210 | const header = flattenThemeColor(variables["--color-header"], sheet); | |
| 211 | for (const role of ["--color-header-foreground", "--color-foreground-muted"] as const) { | |
| 212 | expect( | |
| 213 | contrastRatio(variables[role], header), | |
| 214 | `${appearance}: ${role} on Android header`, | |
| 215 | ).toBeGreaterThanOrEqual(4.5); | |
| 216 | } | |
| 217 | } | |
| 218 | expect( | |
| 219 | contrastRatio(variables["--color-foreground-muted"], variables["--color-secondary"]), | |
| 220 | `${platform} ${appearance}: muted label on secondary surface`, | |
| 221 | ).toBeGreaterThanOrEqual(4.5); | |
| 222 | } | |
| 223 | } | |
| 224 | }); | |
| 225 | ||
| 185 | 226 | it.each(["light", "dark"] as const)( |
| 186 | 227 | "separates default settings groups from their %s background", |
| 187 | 228 | (appearance) => { |
apps/mobile/src/lib/mobileTheme.ts+37-15| ... | ... | @@ -191,15 +191,23 @@ function contrastRatio( |
| 191 | 191 | ); |
| 192 | 192 | } |
| 193 | 193 | |
| 194 | /** Preserve the color's hue while giving text 4.5:1 contrast on every supplied surface. */ | |
| 195 | function readableTextColor(accent: string, surface: string | ReadonlyArray<string>): string { | |
| 194 | /** Keep the theme tint while adjusting lightness to contrast with every supplied surface. */ | |
| 195 | export function themeColorWithContrast( | |
| 196 | accent: string, | |
| 197 | surface: string | ReadonlyArray<string>, | |
| 198 | minimum = 4.5, | |
| 199 | ): string { | |
| 196 | 200 | const accentChannels = rgbChannels(accent); |
| 197 | 201 | const surfaceChannels = (typeof surface === "string" ? [surface] : surface) |
| 198 | 202 | .map(rgbChannels) |
| 199 | 203 | .filter((channels) => channels !== null); |
| 200 | 204 | const minimumContrast = (channels: readonly [number, number, number]) => |
| 201 | 205 | Math.min(...surfaceChannels.map((surface) => contrastRatio(channels, surface))); |
| 202 | if (!accentChannels || surfaceChannels.length === 0 || minimumContrast(accentChannels) >= 4.5) { | |
| 206 | if ( | |
| 207 | !accentChannels || | |
| 208 | surfaceChannels.length === 0 || | |
| 209 | minimumContrast(accentChannels) >= minimum | |
| 210 | ) { | |
| 203 | 211 | return accent; |
| 204 | 212 | } |
| 205 | 213 | |
| ... | ... | @@ -216,7 +224,7 @@ function readableTextColor(accent: string, surface: string | ReadonlyArray<strin |
| 216 | 224 | Math.round(accentChannels[1] + (target[1] - accentChannels[1]) * amount), |
| 217 | 225 | Math.round(accentChannels[2] + (target[2] - accentChannels[2]) * amount), |
| 218 | 226 | ]; |
| 219 | if (minimumContrast(candidate) >= 4.5) { | |
| 227 | if (minimumContrast(candidate) >= minimum) { | |
| 220 | 228 | readable = candidate; |
| 221 | 229 | upperAmount = amount; |
| 222 | 230 | } else { |
| ... | ... | @@ -242,7 +250,15 @@ export function createMobileThemeVariables( |
| 242 | 250 | ) { |
| 243 | 251 | const c = nativeColors(colors); |
| 244 | 252 | const groupedCard = themeColorToNativeColor(groupedCardColor); |
| 245 | const textSurfaces = [c.canvas, c.surface, c.surfaceRaised, c.chrome, groupedCard]; | |
| 253 | const textSurfaces = [ | |
| 254 | c.canvas, | |
| 255 | c.surface, | |
| 256 | c.surfaceRaised, | |
| 257 | c.chrome, | |
| 258 | c.sidebar, | |
| 259 | c.secondary, | |
| 260 | groupedCard, | |
| 261 | ]; | |
| 246 | 262 | return { |
| 247 | 263 | "--color-screen": c.canvas, |
| 248 | 264 | "--color-sheet": withAlpha(c.chrome, 0.98), |
| ... | ... | @@ -254,7 +270,7 @@ export function createMobileThemeVariables( |
| 254 | 270 | "--color-thread-canvas": c.canvas, |
| 255 | 271 | "--color-thread-selected": c.sidebarRowActive, |
| 256 | 272 | "--color-thread-selected-foreground": c.sidebarForeground, |
| 257 | "--color-thread-selected-foreground-muted": readableTextColor( | |
| 273 | "--color-thread-selected-foreground-muted": themeColorWithContrast( | |
| 258 | 274 | c.sidebarMutedForeground, |
| 259 | 275 | c.sidebarRowActive, |
| 260 | 276 | ), |
| ... | ... | @@ -270,8 +286,8 @@ export function createMobileThemeVariables( |
| 270 | 286 | groupedCard === c.surface ? (appearance === "dark" ? 0.46 : 0.54) : 0.8, |
| 271 | 287 | ), |
| 272 | 288 | "--color-foreground": c.text, |
| 273 | "--color-foreground-secondary": readableTextColor(c.textMuted, textSurfaces), | |
| 274 | "--color-foreground-muted": readableTextColor(c.mutedForeground, textSurfaces), | |
| 289 | "--color-foreground-secondary": themeColorWithContrast(c.textMuted, textSurfaces), | |
| 290 | "--color-foreground-muted": themeColorWithContrast(c.mutedForeground, textSurfaces), | |
| 275 | 291 | "--color-foreground-tertiary": c.secondaryLabel, |
| 276 | 292 | "--color-border": c.border, |
| 277 | 293 | "--color-focus": c.focus, |
| ... | ... | @@ -284,7 +300,7 @@ export function createMobileThemeVariables( |
| 284 | 300 | "--color-inline-skill-foreground": c.accentSurfaceForeground, |
| 285 | 301 | "--color-primary": c.messageAction, |
| 286 | 302 | "--color-primary-foreground": c.messageActionForeground, |
| 287 | "--color-primary-text": readableTextColor(c.messageAction, textSurfaces), | |
| 303 | "--color-primary-text": themeColorWithContrast(c.messageAction, textSurfaces), | |
| 288 | 304 | "--color-primary-shadow": "#000000", |
| 289 | 305 | "--color-secondary": c.secondary, |
| 290 | 306 | "--color-secondary-foreground": c.secondaryForeground, |
| ... | ... | @@ -304,7 +320,7 @@ export function createMobileThemeVariables( |
| 304 | 320 | "--color-input": c.surface, |
| 305 | 321 | "--color-input-border": c.input, |
| 306 | 322 | "--color-sidebar-search": c.sidebarControlSurface, |
| 307 | "--color-placeholder": readableTextColor(c.placeholder, textSurfaces), | |
| 323 | "--color-placeholder": themeColorWithContrast(c.placeholder, textSurfaces), | |
| 308 | 324 | "--color-icon": c.text, |
| 309 | 325 | "--color-icon-muted": c.iconMuted, |
| 310 | 326 | "--color-icon-subtle": c.secondaryLabel, |
| ... | ... | @@ -317,7 +333,7 @@ export function createMobileThemeVariables( |
| 317 | 333 | "--color-status-bar": c.canvas, |
| 318 | 334 | "--color-md-body": c.text, |
| 319 | 335 | "--color-md-strong": c.text, |
| 320 | "--color-md-link": readableTextColor(c.messageAction, c.canvas), | |
| 336 | "--color-md-link": themeColorWithContrast(c.messageAction, c.canvas), | |
| 321 | 337 | "--color-md-blockquote-border": c.border, |
| 322 | 338 | "--color-md-blockquote-bg": c.muted, |
| 323 | 339 | "--color-md-code-bg": c.codeBackground, |
| ... | ... | @@ -330,11 +346,14 @@ export function createMobileThemeVariables( |
| 330 | 346 | "--color-user-bubble": c.messageSurface, |
| 331 | 347 | "--color-user-bubble-foreground": c.messageForeground, |
| 332 | 348 | "--color-user-bubble-foreground-muted": withAlpha(c.messageForeground, 0.78), |
| 333 | "--color-user-bubble-skill-foreground": readableTextColor(c.messageAction, c.messageSurface), | |
| 349 | "--color-user-bubble-skill-foreground": themeColorWithContrast( | |
| 350 | c.messageAction, | |
| 351 | c.messageSurface, | |
| 352 | ), | |
| 334 | 353 | "--color-backdrop": withAlpha("#000000", appearance === "dark" ? 0.48 : 0.22), |
| 335 | 354 | "--color-drawer": c.sidebar, |
| 336 | 355 | "--color-drawer-foreground": c.sidebarForeground, |
| 337 | "--color-drawer-foreground-muted": readableTextColor(c.sidebarMutedForeground, [ | |
| 356 | "--color-drawer-foreground-muted": themeColorWithContrast(c.sidebarMutedForeground, [ | |
| 338 | 357 | c.sidebar, |
| 339 | 358 | c.sidebarRowHover, |
| 340 | 359 | ]), |
| ... | ... | @@ -368,13 +387,16 @@ export function getMobileThemeVariables( |
| 368 | 387 | ): MobileThemeVariables { |
| 369 | 388 | const colors = getMobileThemeColors(themeId, appearance); |
| 370 | 389 | // Mobile settings groups and fallback materials use tonal fills where desktop |
| 371 | // uses outlined cards. Regular cards retain their shared desktop surface. | |
| 390 | // uses outlined cards. Raise flat desktop surfaces above the sheet so grouped | |
| 391 | // content keeps a visible boundary. Regular cards retain their desktop surface. | |
| 372 | 392 | const groupedCard = |
| 373 | 393 | themeId === DEFAULT_MOBILE_THEME_ID |
| 374 | 394 | ? appearance === "light" |
| 375 | 395 | ? colors.toolbarControlHover |
| 376 | 396 | : colors.sidebarRowActive |
| 377 | : colors.surface; | |
| 397 | : colors.surface === colors.chrome | |
| 398 | ? colors.surfaceRaised | |
| 399 | : colors.surface; | |
| 378 | 400 | const mobileColors = |
| 379 | 401 | themeId === DEFAULT_MOBILE_THEME_ID |
| 380 | 402 | ? { |