Skip to content

Commit 4332f05

Browse files
committed
Fix dark theme contrast regressions
1 parent 7c5a6fa commit 4332f05

3 files changed

Lines changed: 293 additions & 6 deletions

File tree

apps/desktop/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7247,7 +7247,7 @@ function WindowChrome({
72477247
onMouseDown={handleChromeMouseDown}
72487248
>
72497249
<div className="native-traffic-space" aria-hidden="true" />
7250-
<div data-tauri-drag-region>{title}</div>
7250+
<div className="window-title" data-tauri-drag-region>{title}</div>
72517251
<div
72527252
className="window-chrome-actions"
72537253
data-tauri-drag-region={(!onMetaClick && !showWindowControls) || undefined}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { readFileSync } from "node:fs";
2+
3+
import { describe, expect, it } from "vitest";
4+
5+
const appSource = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
6+
const styles = readFileSync(new URL("./styles.css", import.meta.url), "utf8");
7+
8+
describe("dark theme UI contrast", () => {
9+
it("uses a stable title hook for the desktop chrome", () => {
10+
expect(appSource).toMatch(/className="window-title"/);
11+
expect(styles).toMatch(/:root\[data-theme="dark"\] \.window-chrome\s*\{/);
12+
expect(styles).toMatch(/:root\[data-theme="dark"\] \.window-title\s*\{[\s\S]*?color:\s*#f1f8f5;/s);
13+
});
14+
15+
it("keeps sidebar status tooltips inside the app window", () => {
16+
expect(styles).toMatch(
17+
/\.sidebar-status \.status-pill\.has-tooltip:hover::after,[\s\S]*?bottom:\s*calc\(100% \+ 10px\);/s,
18+
);
19+
expect(styles).toMatch(
20+
/:root\[data-theme="dark"\] \.status-pill\.has-tooltip:hover::after,[\s\S]*?background:\s*#223035;/s,
21+
);
22+
});
23+
24+
it("defines dark surfaces for home stats, Live Mode, and tray popover", () => {
25+
expect(styles).toMatch(/:root\[data-theme="dark"\] \.home-stat\s*\{/);
26+
expect(styles).toMatch(/:root\[data-theme="dark"\] \.live-mode-control\s*\{/);
27+
expect(styles).toMatch(/:root\[data-theme="dark"\] \.tray-popover\s*\{/);
28+
expect(styles).not.toMatch(/:root\[data-theme="dark"\] \.tray-live-mode-control,[\s\S]*?\.file-row\.expanded/s);
29+
});
30+
});

apps/desktop/src/styles.css

Lines changed: 262 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,37 @@ p {
193193
user-select: none;
194194
}
195195

196+
.window-title {
197+
overflow: hidden;
198+
color: #24313f;
199+
font-weight: 900;
200+
text-overflow: ellipsis;
201+
white-space: nowrap;
202+
}
203+
204+
:root[data-theme="dark"] .window-chrome {
205+
border-bottom-color: rgba(163, 183, 190, 0.14);
206+
background: linear-gradient(180deg, rgba(29, 40, 44, 0.98), rgba(22, 31, 34, 0.95));
207+
color: #9fb0ad;
208+
}
209+
210+
:root[data-theme="dark"] .window-title {
211+
color: #f1f8f5;
212+
}
213+
214+
:root[data-theme="dark"] .window-meta-button:hover {
215+
background: rgba(163, 183, 190, 0.14);
216+
color: #f1f8f5;
217+
}
218+
219+
:root[data-theme="dark"] .window-control-button {
220+
color: #c2d0cc;
221+
}
222+
223+
:root[data-theme="dark"] .window-control-button:hover {
224+
background: rgba(163, 183, 190, 0.14);
225+
}
226+
196227
.window-chrome.windows-chrome {
197228
grid-template-columns: 150px 1fr 190px;
198229
min-height: 40px;
@@ -778,6 +809,14 @@ p {
778809
white-space: normal;
779810
}
780811

812+
:root[data-theme="dark"] .live-mode-control.has-tooltip:hover::after,
813+
:root[data-theme="dark"] .live-mode-control.has-tooltip:focus-visible::after {
814+
border-color: rgba(163, 183, 190, 0.22);
815+
background: #223035;
816+
box-shadow: 0 16px 34px rgba(0, 0, 0, 0.3);
817+
color: #eef7f4;
818+
}
819+
781820
.secondary-button:disabled,
782821
.text-button:disabled {
783822
opacity: 0.58;
@@ -1611,6 +1650,15 @@ p {
16111650
background: rgba(28, 38, 42, 0.92);
16121651
}
16131652

1653+
:root[data-theme="dark"] .sidebar-brand-mark strong {
1654+
color: #f1f8f5;
1655+
}
1656+
1657+
:root[data-theme="dark"] .sidebar .locality-logo img,
1658+
:root[data-theme="dark"] .tray-title .locality-logo img {
1659+
filter: invert(1) brightness(1.08);
1660+
}
1661+
16141662
:root[data-theme="dark"] .sidebar-link {
16151663
color: #93a39f;
16161664
}
@@ -1899,6 +1947,34 @@ button.home-stat:hover {
18991947
cursor: default;
19001948
}
19011949

1950+
:root[data-theme="dark"] .home-stat {
1951+
border-color: rgba(163, 183, 190, 0.18);
1952+
background: rgba(31, 42, 46, 0.92);
1953+
box-shadow: 0 10px 26px rgba(0, 0, 0, 0.16);
1954+
color: #f2faf7;
1955+
}
1956+
1957+
:root[data-theme="dark"] button.home-stat:hover {
1958+
border-color: rgba(42, 161, 152, 0.34);
1959+
background: rgba(36, 50, 54, 0.98);
1960+
}
1961+
1962+
:root[data-theme="dark"] .home-stat span {
1963+
color: #c7d6d2;
1964+
}
1965+
1966+
:root[data-theme="dark"] .home-stat strong {
1967+
color: #f6fbfa;
1968+
}
1969+
1970+
:root[data-theme="dark"] .home-stat strong.warn {
1971+
color: #e0b24b;
1972+
}
1973+
1974+
:root[data-theme="dark"] .home-stat strong.danger {
1975+
color: #f08b8b;
1976+
}
1977+
19021978
.workspace-card h2,
19031979
.attention-panel h2 {
19041980
margin-top: 5px;
@@ -4139,7 +4215,6 @@ button.home-stat:hover {
41394215
}
41404216

41414217
:root[data-theme="dark"] .live-mode-control.active,
4142-
:root[data-theme="dark"] .tray-live-mode-control,
41434218
:root[data-theme="dark"] .connector-option.available,
41444219
:root[data-theme="dark"] .connector-option.selectable:hover:not(:disabled),
41454220
:root[data-theme="dark"] .connector-option.selectable.selected,
@@ -4155,8 +4230,7 @@ button.home-stat:hover {
41554230
:root[data-theme="dark"] .connector-choice-card,
41564231
:root[data-theme="dark"] .connector-choice-card.mounted,
41574232
:root[data-theme="dark"] .workspace-path-row,
4158-
:root[data-theme="dark"] .workspace-facts span,
4159-
:root[data-theme="dark"] .tray-change-list button {
4233+
:root[data-theme="dark"] .workspace-facts span {
41604234
border-color: var(--line);
41614235
background: rgba(22, 31, 34, 0.9);
41624236
color: var(--ink);
@@ -4165,8 +4239,7 @@ button.home-stat:hover {
41654239
:root[data-theme="dark"] .connector-choice-heading p,
41664240
:root[data-theme="dark"] .mount-card-title span span,
41674241
:root[data-theme="dark"] .mount-card-footer > span,
4168-
:root[data-theme="dark"] .file-row span,
4169-
:root[data-theme="dark"] .tray-change-list small {
4242+
:root[data-theme="dark"] .file-row span {
41704243
color: var(--muted);
41714244
}
41724245

@@ -4177,6 +4250,24 @@ button.home-stat:hover {
41774250
color: #c4d4d0;
41784251
}
41794252

4253+
:root[data-theme="dark"] .live-mode-control {
4254+
border-color: rgba(163, 183, 190, 0.22);
4255+
background: rgba(22, 31, 34, 0.92);
4256+
color: #d8e7e3;
4257+
}
4258+
4259+
:root[data-theme="dark"] .live-mode-control:hover:not(:disabled) {
4260+
border-color: rgba(42, 161, 152, 0.34);
4261+
background: rgba(28, 43, 46, 0.96);
4262+
color: #eef7f4;
4263+
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.18);
4264+
}
4265+
4266+
:root[data-theme="dark"] .live-mode-control.active {
4267+
color: #eef7f4;
4268+
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.22);
4269+
}
4270+
41804271
:root[data-theme="dark"] .toggle {
41814272
background: #334247;
41824273
}
@@ -4302,6 +4393,35 @@ button.home-stat:hover {
43024393
white-space: normal;
43034394
}
43044395

4396+
.sidebar-status .status-pill.has-tooltip:hover::after,
4397+
.sidebar-status .status-pill.has-tooltip:focus-visible::after {
4398+
top: auto;
4399+
right: auto;
4400+
bottom: calc(100% + 10px);
4401+
left: 0;
4402+
width: min(280px, calc(100vw - 28px));
4403+
}
4404+
4405+
.sidebar-collapsed .status-pill.has-tooltip:hover,
4406+
.sidebar-collapsed .status-pill.has-tooltip:focus-visible {
4407+
overflow: visible;
4408+
}
4409+
4410+
.sidebar-collapsed .sidebar-status .status-pill.has-tooltip:hover::after,
4411+
.sidebar-collapsed .sidebar-status .status-pill.has-tooltip:focus-visible::after {
4412+
bottom: 0;
4413+
left: calc(100% + 12px);
4414+
width: min(250px, calc(100vw - 86px));
4415+
}
4416+
4417+
:root[data-theme="dark"] .status-pill.has-tooltip:hover::after,
4418+
:root[data-theme="dark"] .status-pill.has-tooltip:focus-visible::after {
4419+
border-color: rgba(163, 183, 190, 0.24);
4420+
background: #223035;
4421+
box-shadow: 0 16px 34px rgba(0, 0, 0, 0.32);
4422+
color: #eef7f4;
4423+
}
4424+
43054425
.status-pill.ready {
43064426
background: var(--green-soft);
43074427
color: var(--green);
@@ -4317,6 +4437,21 @@ button.home-stat:hover {
43174437
color: var(--red);
43184438
}
43194439

4440+
:root[data-theme="dark"] .status-pill.ready {
4441+
background: rgba(35, 132, 95, 0.2);
4442+
color: #87d4b1;
4443+
}
4444+
4445+
:root[data-theme="dark"] .status-pill.warn {
4446+
background: rgba(192, 138, 0, 0.2);
4447+
color: #e4bc59;
4448+
}
4449+
4450+
:root[data-theme="dark"] .status-pill.danger {
4451+
background: rgba(220, 38, 38, 0.18);
4452+
color: #f59696;
4453+
}
4454+
43204455
.locality-logo {
43214456
position: relative;
43224457
display: inline-grid;
@@ -4949,6 +5084,128 @@ button.home-stat:hover {
49495084
color: var(--red);
49505085
}
49515086

5087+
:root[data-theme="dark"] .tray-popover {
5088+
border-color: rgba(163, 183, 190, 0.18);
5089+
background: #1f2b2f;
5090+
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.34);
5091+
color: var(--ink);
5092+
}
5093+
5094+
:root[data-theme="dark"] .tray-header,
5095+
:root[data-theme="dark"] .tray-footer,
5096+
:root[data-theme="dark"] .tray-section,
5097+
:root[data-theme="dark"] .tray-status-row,
5098+
:root[data-theme="dark"] .tray-controls-row {
5099+
border-color: rgba(163, 183, 190, 0.14);
5100+
}
5101+
5102+
:root[data-theme="dark"] .tray-title strong,
5103+
:root[data-theme="dark"] .tray-list-row strong,
5104+
:root[data-theme="dark"] .tray-review-button strong,
5105+
:root[data-theme="dark"] .tray-suggestion-row strong {
5106+
color: #f1f8f5;
5107+
}
5108+
5109+
:root[data-theme="dark"] .tray-section-heading,
5110+
:root[data-theme="dark"] .tray-live-inline,
5111+
:root[data-theme="dark"] .tray-empty-row,
5112+
:root[data-theme="dark"] .tray-account,
5113+
:root[data-theme="dark"] .tray-list-row small,
5114+
:root[data-theme="dark"] .tray-review-button small,
5115+
:root[data-theme="dark"] .tray-recent-files small,
5116+
:root[data-theme="dark"] .tray-result code,
5117+
:root[data-theme="dark"] .tray-change-list small {
5118+
color: #b6c2bf;
5119+
}
5120+
5121+
:root[data-theme="dark"] .tray-locate-row,
5122+
:root[data-theme="dark"] .tray-search-results button,
5123+
:root[data-theme="dark"] .tray-result,
5124+
:root[data-theme="dark"] .tray-change-list button,
5125+
:root[data-theme="dark"] .tray-quit-menu {
5126+
border-color: rgba(163, 183, 190, 0.18);
5127+
background: rgba(22, 31, 34, 0.92);
5128+
color: var(--ink);
5129+
}
5130+
5131+
:root[data-theme="dark"] .tray-locate-row input {
5132+
border: 0;
5133+
background: transparent;
5134+
color: var(--ink);
5135+
}
5136+
5137+
:root[data-theme="dark"] .tray-locate-row svg {
5138+
color: #9fb0ad;
5139+
}
5140+
5141+
:root[data-theme="dark"] .tray-search-results button:hover,
5142+
:root[data-theme="dark"] .tray-change-list button:hover:not(:disabled),
5143+
:root[data-theme="dark"] .tray-quit-menu button:hover:not(:disabled) {
5144+
border-color: rgba(42, 161, 152, 0.3);
5145+
background: rgba(28, 43, 46, 0.96);
5146+
}
5147+
5148+
:root[data-theme="dark"] .tray-locate-row button {
5149+
background: var(--accent);
5150+
color: #f7fffd;
5151+
}
5152+
5153+
:root[data-theme="dark"] .tray-locate-row button:disabled {
5154+
background: #344348;
5155+
color: #a9b7b4;
5156+
}
5157+
5158+
:root[data-theme="dark"] .tray-live-mode-control,
5159+
:root[data-theme="dark"] .tray-live-inline,
5160+
:root[data-theme="dark"] .tray-status-copy,
5161+
:root[data-theme="dark"] .tray-list-row,
5162+
:root[data-theme="dark"] .tray-review-button {
5163+
color: var(--ink);
5164+
}
5165+
5166+
:root[data-theme="dark"] .tray-review-summary {
5167+
border-color: rgba(192, 138, 0, 0.24);
5168+
background: rgba(192, 138, 0, 0.14);
5169+
}
5170+
5171+
:root[data-theme="dark"] .tray-review-button b {
5172+
background: rgba(255, 255, 255, 0.1);
5173+
color: #e4bc59;
5174+
}
5175+
5176+
:root[data-theme="dark"] .search-state {
5177+
background: rgba(35, 132, 95, 0.22);
5178+
color: #87d4b1;
5179+
}
5180+
5181+
:root[data-theme="dark"] .search-state.online_only,
5182+
:root[data-theme="dark"] .search-state.preparing,
5183+
:root[data-theme="dark"] .search-state.remote_update_available {
5184+
background: rgba(96, 165, 250, 0.18);
5185+
color: #93c5fd;
5186+
}
5187+
5188+
:root[data-theme="dark"] .search-state.pending_changes {
5189+
background: rgba(217, 119, 6, 0.2);
5190+
color: #f0b45d;
5191+
}
5192+
5193+
:root[data-theme="dark"] .search-state.conflict,
5194+
:root[data-theme="dark"] .search-state.no_access,
5195+
:root[data-theme="dark"] .search-state.not_found {
5196+
background: rgba(220, 38, 38, 0.18);
5197+
color: #f59696;
5198+
}
5199+
5200+
:root[data-theme="dark"] .tray-section-heading button,
5201+
:root[data-theme="dark"] .tray-result button,
5202+
:root[data-theme="dark"] .tray-suggestion button,
5203+
:root[data-theme="dark"] .tray-controls-row button,
5204+
:root[data-theme="dark"] .tray-footer button,
5205+
:root[data-theme="dark"] .tray-list-row em {
5206+
color: #67c7bd;
5207+
}
5208+
49525209
@keyframes spin {
49535210
to {
49545211
transform: rotate(360deg);

0 commit comments

Comments
 (0)