website

#astro#js#html#css

git clone https://git.pyrossh.dev/website

木 Personal website of pyrossh. Built with astrojs, shiki, vite.


68aad70 — pyrossh 2026-11-06T15:29:20+05:30
Fix commit diff colors in dark mode
Files changed (2) hide show
  1. assets/css/repos.css +40 -32
  2. tests/pages.test.js +17 -0
assets/css/repos.css CHANGED
@@ -430,38 +430,46 @@
430
430
  }
431
431
  }
432
432
 
433
- /* diff2html ships its own light/dark token sets as plain CSS custom
433
+ /* diff2html ships light tokens on :root and a dark set it only applies under
434
- properties on :root (see node_modules/diff2html/bundles/css) but only
434
+ a `.d2h-dark-color-scheme` class we never add. Redefining the base tokens
435
- applies the dark set under a `.d2h-dark-color-scheme` class we never
435
+ with light-dark() follows the same color-scheme as the rest of the site, so
436
- add. Remapping the base tokens it actually reads to their `--d2h-dark-*`
437
- counterparts under our own [data-theme="dark"] gets the same result
436
+ an OS dark preference and the theme toggle both work. Each light value is
437
+ diff2html's own default.
438
+
438
- without needing that class or a second copy of every diff2html rule.
439
+ `html:root` because diff2html.min.css comes later in the bundle and declares
440
+ these on plain :root, which would otherwise win.
441
+
442
+ Dark row backgrounds (ins/del/change/info) are solid: line numbers are
443
+ absolutely positioned over the code and share these colors, so a translucent
444
+ value lets code show through them when a long line scrolls sideways. They're
445
+ diff2html's translucent dark colors flattened onto --color-body-bg.
446
+
439
- This re-themes a third-party library's own classes rather than styling
447
+ This re-themes a third-party library's own classes rather than styling one
440
- one of our own, so it's left flat/global rather than nested. */
448
+ of our own, so it's left flat/global rather than nested. */
441
- :root[data-theme="dark"] {
449
+ html:root {
442
- --d2h-bg-color: var(--d2h-dark-bg-color);
450
+ --d2h-bg-color: light-dark(#fff, var(--color-body-bg));
443
- --d2h-border-color: var(--d2h-dark-border-color);
451
+ --d2h-border-color: light-dark(#ddd, var(--d2h-dark-border-color));
444
- --d2h-dim-color: var(--d2h-dark-dim-color);
452
+ --d2h-dim-color: light-dark(rgba(0, 0, 0, 0.3), var(--token-comment));
445
- --d2h-line-border-color: var(--d2h-dark-line-border-color);
453
+ --d2h-line-border-color: light-dark(#eee, var(--d2h-dark-line-border-color));
446
- --d2h-file-header-bg-color: var(--d2h-dark-file-header-bg-color);
454
+ --d2h-file-header-bg-color: light-dark(#f7f7f7, var(--color-box-bg));
447
- --d2h-file-header-border-color: var(--d2h-dark-file-header-border-color);
455
+ --d2h-file-header-border-color: light-dark(#d8d8d8, var(--d2h-dark-file-header-border-color));
448
- --d2h-empty-placeholder-bg-color: var(--d2h-dark-empty-placeholder-bg-color);
456
+ --d2h-empty-placeholder-bg-color: light-dark(#f1f1f1, var(--d2h-dark-empty-placeholder-bg-color));
449
- --d2h-empty-placeholder-border-color: var(--d2h-dark-empty-placeholder-border-color);
457
+ --d2h-empty-placeholder-border-color: light-dark(#e1e1e1, var(--d2h-dark-empty-placeholder-border-color));
450
- --d2h-selected-color: var(--d2h-dark-selected-color);
458
+ --d2h-selected-color: light-dark(#c8e1ff, var(--d2h-dark-selected-color));
451
- --d2h-ins-bg-color: var(--d2h-dark-ins-bg-color);
459
+ --d2h-ins-bg-color: light-dark(#dfd, #23382f);
452
- --d2h-ins-border-color: var(--d2h-dark-ins-border-color);
460
+ --d2h-ins-border-color: light-dark(#b4e2b4, var(--d2h-dark-ins-border-color));
453
- --d2h-ins-highlight-bg-color: var(--d2h-dark-ins-highlight-bg-color);
461
+ --d2h-ins-highlight-bg-color: light-dark(#97f295, var(--d2h-dark-ins-highlight-bg-color));
454
- --d2h-ins-label-color: var(--d2h-dark-ins-label-color);
462
+ --d2h-ins-label-color: light-dark(#399839, var(--d2h-dark-ins-label-color));
455
- --d2h-del-bg-color: var(--d2h-dark-del-bg-color);
463
+ --d2h-del-bg-color: light-dark(#fee8e9, #372a2e);
456
- --d2h-del-border-color: var(--d2h-dark-del-border-color);
464
+ --d2h-del-border-color: light-dark(#e9aeae, var(--d2h-dark-del-border-color));
457
- --d2h-del-highlight-bg-color: var(--d2h-dark-del-highlight-bg-color);
465
+ --d2h-del-highlight-bg-color: light-dark(#ffb6ba, var(--d2h-dark-del-highlight-bg-color));
458
- --d2h-del-label-color: var(--d2h-dark-del-label-color);
466
+ --d2h-del-label-color: light-dark(#c33, var(--d2h-dark-del-label-color));
459
- --d2h-change-del-color: var(--d2h-dark-change-del-color);
467
+ --d2h-change-del-color: light-dark(#fdf2d0, #443d29);
460
- --d2h-change-ins-color: var(--d2h-dark-change-ins-color);
468
+ --d2h-change-ins-color: light-dark(#ded, #244431);
461
- --d2h-info-bg-color: var(--d2h-dark-info-bg-color);
469
+ --d2h-info-bg-color: light-dark(#f8fafd, #233040);
462
- --d2h-info-border-color: var(--d2h-dark-info-border-color);
470
+ --d2h-info-border-color: light-dark(#d5e4f2, var(--d2h-dark-info-border-color));
463
- --d2h-change-label-color: var(--d2h-dark-change-label-color);
471
+ --d2h-change-label-color: light-dark(#d0b44c, var(--d2h-dark-change-label-color));
464
- --d2h-moved-label-color: var(--d2h-dark-moved-label-color);
472
+ --d2h-moved-label-color: light-dark(#3572b0, var(--color-link));
465
473
  }
466
474
 
467
475
  .d2h-wrapper {
tests/pages.test.js CHANGED
@@ -190,6 +190,23 @@ describe("repo pages", () => {
190
190
  assert.equal(await page.locator(".d2h-file-name", { hasText: "package-lock.json" }).count(), 0);
191
191
  });
192
192
 
193
+ test("commit diffs follow an OS dark preference with solid line numbers", async () => {
194
+ const hash = execFileSync("git", ["log", "-1", "--diff-filter=M", "--format=%H", "--", "eleventy.config.js"], {
195
+ encoding: "utf8",
196
+ }).trim();
197
+ await page.emulateMedia({ colorScheme: "dark" });
198
+ try {
199
+ await goto(`/repos/${repoId}/commits/${hash}/`);
200
+ const background = (selector) =>
201
+ page.locator(selector).first().evaluate((el) => getComputedStyle(el).backgroundColor);
202
+
203
+ assert.equal(await background(".d2h-code-linenumber:not(.d2h-ins, .d2h-del, .d2h-info)"), await background("body"));
204
+ assert.match(await background("td.d2h-ins.d2h-code-linenumber"), /^rgb\(/, "must be opaque, not rgba()");
205
+ } finally {
206
+ await page.emulateMedia({ colorScheme: null });
207
+ }
208
+ });
209
+
193
210
  test("repo files index renders the tree and a default file", async () => {
194
211
  const response = await goto(`/repos/${repoId}/files/`);
195
212
  assert.equal(response.status(), 200);