aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-07 08:30:31 -0500
committerCraig Jennings <c@cjennings.net>2026-06-07 08:30:31 -0500
commit8c2204a24169d5a9817fc2212a6deed0270c46f8 (patch)
treec155a548e249bb8d0ba6525798175c00da291b87
parent988a801e3fd922825f2de639e0b8ea19d988823e (diff)
downloaddotemacs-8c2204a24169d5a9817fc2212a6deed0270c46f8.tar.gz
dotemacs-8c2204a24169d5a9817fc2212a6deed0270c46f8.zip
fix(dupre): make diff-changed and diff-refine-changed legible
diff-refine-changed rendered the default foreground (#f0fef0) on the bright-gold yellow-1 (#ffd700) at WCAG contrast 1.35, unreadable wherever the face is a plain background, not inside diff-mode's own foreground overlay. diff-changed was weak too at 2.78. Both now use the default foreground on the dark amber yellow-2 (#875f00), already in dupre's palette, for a contrast of 5.49. diff-refine-changed keeps its bold weight so it stays stronger than diff-changed. A WCAG-contrast test guards both faces from dropping below 4.5.
-rw-r--r--tests/test-dupre-theme.el34
-rw-r--r--themes/dupre-faces.el4
-rw-r--r--themes/dupre-palette.el2
3 files changed, 37 insertions, 3 deletions
diff --git a/tests/test-dupre-theme.el b/tests/test-dupre-theme.el
index dec648d1..4d0e786c 100644
--- a/tests/test-dupre-theme.el
+++ b/tests/test-dupre-theme.el
@@ -223,5 +223,39 @@ The defface registration in dupre-faces.el is what makes direct use work."
(should (string= (face-attribute 'dupre-org-todo-dim :foreground nil 'default)
"#869038")))
+;;; Diff face legibility (WCAG contrast)
+
+(defun dupre-test--channel-luminance (c)
+ "Linearize an 8-bit channel value C (0-255) per the WCAG formula."
+ (let ((x (/ c 255.0)))
+ (if (<= x 0.03928) (/ x 12.92) (expt (/ (+ x 0.055) 1.055) 2.4))))
+
+(defun dupre-test--relative-luminance (hex)
+ "WCAG relative luminance of HEX color \"#rrggbb\"."
+ (+ (* 0.2126 (dupre-test--channel-luminance (string-to-number (substring hex 1 3) 16)))
+ (* 0.7152 (dupre-test--channel-luminance (string-to-number (substring hex 3 5) 16)))
+ (* 0.0722 (dupre-test--channel-luminance (string-to-number (substring hex 5 7) 16)))))
+
+(defun dupre-test--contrast (fg bg)
+ "WCAG contrast ratio between hex colors FG and BG."
+ (let ((l1 (dupre-test--relative-luminance fg))
+ (l2 (dupre-test--relative-luminance bg)))
+ (/ (+ (max l1 l2) 0.05) (+ (min l1 l2) 0.05))))
+
+(ert-deftest dupre-diff-changed-faces-meet-wcag-aa ()
+ "Error/Regression: diff-changed and diff-refine-changed must stay legible as
+standalone backgrounds (WCAG AA, >= 4.5:1 for normal text). Guards the bug
+where diff-refine-changed rendered the default fg (#f0fef0) on the bright-gold
+yellow-1 (#ffd700) at 1.35:1 -- unreadable wherever the face is used as a plain
+background, not just inside diff-mode's own foreground overlay."
+ (require 'diff-mode)
+ (load-theme 'dupre t)
+ (dolist (face '(diff-changed diff-refine-changed))
+ (let ((fg (face-attribute face :foreground nil t))
+ (bg (face-attribute face :background nil t)))
+ (should (string-match-p "^#[0-9a-fA-F]\\{6\\}$" fg))
+ (should (string-match-p "^#[0-9a-fA-F]\\{6\\}$" bg))
+ (should (>= (dupre-test--contrast fg bg) 4.5)))))
+
(provide 'test-dupre-theme)
;;; test-dupre-theme.el ends here
diff --git a/themes/dupre-faces.el b/themes/dupre-faces.el
index 8fad4c62..17daa41c 100644
--- a/themes/dupre-faces.el
+++ b/themes/dupre-faces.el
@@ -164,10 +164,10 @@
;;;;; Diff mode
`(diff-added ((t (:foreground ,green :background ,green-2))))
`(diff-removed ((t (:foreground ,red :background ,red-3))))
- `(diff-changed ((t (:foreground ,yellow :background ,yellow-2))))
+ `(diff-changed ((t (:foreground ,fg :background ,yellow-2))))
`(diff-refine-added ((t (:foreground ,fg :background ,green-1 :weight bold))))
`(diff-refine-removed ((t (:foreground ,fg :background ,red-2 :weight bold))))
- `(diff-refine-changed ((t (:foreground ,fg :background ,yellow-1 :weight bold))))
+ `(diff-refine-changed ((t (:foreground ,fg :background ,yellow-2 :weight bold))))
`(diff-header ((t (:foreground ,fg :background ,bg+2))))
`(diff-file-header ((t (:foreground ,blue :background ,bg+2 :weight bold))))
`(diff-hunk-header ((t (:foreground ,gray+1 :background ,bg+1))))
diff --git a/themes/dupre-palette.el b/themes/dupre-palette.el
index 3901ef82..d6715a78 100644
--- a/themes/dupre-palette.el
+++ b/themes/dupre-palette.el
@@ -95,7 +95,7 @@ Each entry is (NAME VALUE) where VALUE is a hex color string.")
(diff-removed-bg red-3)
(diff-removed-fg red)
(diff-changed-bg yellow-2)
- (diff-changed-fg yellow))
+ (diff-changed-fg fg))
"Semantic color mappings for dupre-theme.
Each entry maps a semantic name to a palette color name.")