diff --git a/lib/__tests__/theme-flat-fields-unread.test.ts b/lib/__tests__/theme-flat-fields-unread.test.ts
new file mode 100644
index 000000000..028734a19
--- /dev/null
+++ b/lib/__tests__/theme-flat-fields-unread.test.ts
@@ -0,0 +1,47 @@
+import { afterEach, describe, expect, it } from 'vitest';
+import { flatFieldsSkin } from '../theme-flat-fields';
+
+// Under Flat fields an unread sender (600) and a read one (500) looked the
+// same in Hanken Grotesk, so nobody could tell which mail was unread. The
+// skin pushes unread to 700 and read senders to 400.
+
+function mountRow(unread: boolean, nameClass: string) {
+ document.body.setAttribute('data-theme-skin', 'builtin-flat-fields');
+ const style = document.createElement('style');
+ // The app's own weights, which the skin has to beat.
+ style.textContent = `
+ .font-medium { font-weight: 500; }
+ .font-semibold { font-weight: 600; }
+ .font-bold { font-weight: 700; }
+ ` + flatFieldsSkin;
+ document.head.appendChild(style);
+ document.body.innerHTML = `
+
`;
+ return getComputedStyle(document.getElementById('name')!).fontWeight;
+}
+
+afterEach(() => {
+ document.head.innerHTML = '';
+ document.body.innerHTML = '';
+ document.body.removeAttribute('data-theme-skin');
+});
+
+describe('Flat fields unread weight', () => {
+ it('sets unread senders and subjects in 700', () => {
+ expect(mountRow(true, 'truncate text-sm font-semibold text-foreground')).toBe('700');
+ expect(mountRow(true, 'truncate text-sm font-bold text-foreground')).toBe('700');
+ });
+
+ it('sets read senders in 400', () => {
+ expect(mountRow(false, 'w-32 shrink-0 truncate text-sm font-medium text-foreground/80')).toBe('400');
+ expect(mountRow(false, 'truncate text-sm font-medium text-muted-foreground')).toBe('400');
+ });
+
+ it('leaves other medium text in read rows alone', () => {
+ expect(mountRow(false, 'inline-flex text-xs font-medium text-sky-700')).toBe('500');
+ });
+});
diff --git a/lib/theme-flat-fields.ts b/lib/theme-flat-fields.ts
index 0a661d6ec..2d6ffe554 100644
--- a/lib/theme-flat-fields.ts
+++ b/lib/theme-flat-fields.ts
@@ -321,11 +321,21 @@ body[data-theme-skin="builtin-flat-fields"] :is(input[type="checkbox"], input[ty
accent-color: var(--color-primary);
}
-/* Unread is a small square and a 600 weight, not a tinted row. */
+/* Unread is a small square and a heavy weight, not a tinted row. Hanken
+ Grotesk's 600 sits too close to the 500 of read senders to tell apart, so
+ unread sender and subject go to 700 and read senders drop to 400. */
body[data-theme-skin="builtin-flat-fields"] [data-tour="email-list"] .bg-accent\\/30:not(:hover) {
background-color: var(--color-background);
}
+body[data-theme-skin="builtin-flat-fields"] [data-tour="email-list"] [data-unread="true"] .text-foreground:is(.font-semibold, .font-bold) {
+ font-weight: 700;
+}
+
+body[data-theme-skin="builtin-flat-fields"] [data-tour="email-list"] [data-unread="false"] .font-medium:is([class~="text-foreground/80"], .text-muted-foreground) {
+ font-weight: 400;
+}
+
body[data-theme-skin="builtin-flat-fields"] [data-tour="email-list"] svg.fill-unread {
color: transparent;
fill: transparent;