;; -*- lexical-binding: t -*- (require 'color) (require-theme 'modus-themes) (deftheme eighters "Eighters gonna eight.") (defun eighters-hsl-to-hex (h s l) (apply 'color-rgb-to-hex `(,@(color-hsl-to-rgb h s l) 2))) (defun eighters-decline-hue-bg (name light-step) (interactive (list (read-color "Color to decline? ") (read-number "Light step? (1–100) "))) (pcase-let* ((`(,r ,g ,b) (color-name-to-rgb name)) (`(,h _ _) (color-rgb-to-hsl r g b))) (let ((variants (seq-map (lambda (l) (cons l (eighters-hsl-to-hex h 1.0 (/ l 100.0)))) (number-sequence 0 100 light-step))) (buf (format "*%s variants*" name))) (with-current-buffer (get-buffer-create buf) (pcase-dolist (`(,l . ,hex) variants) (insert (propertize (format "%s %3s\t%6.3f\n" hex l (modus-themes-contrast "#fff" hex)) 'face `(:background ,hex :extend t))))) (pop-to-buffer buf)))) ;; Let H be the set of all lightness variations of full-saturation hue h, ;; CR(c) be the WCAG contrast-ratio function applied to (c, #fff), ;; CR[S, P] be the set { CR(c) āˆ€ c∈S | P(c) }, ;; ;; bg-h is c such that CR(c) = min(CR[H, >15]) ;; bg-x-dim is c such that CR(c) = max(CR[H, <19]) ;; bg-x-dimmer is c such that CR(c) = max(CR[H, <20]) (defvar eighters-palette `((bg "#000") (bg-hl-dimmer "#0f0f0f") (bg-hl-dim "#181818") (bg-hl "#222") (fg-red "brown2") (fg-red-dim "brown") (bg-red "#560000") (bg-red-dim "#2d0000") (bg-red-dimmer "#1e0000") (fg-green "chartreuse2") (fg-green-dim "#60ae13") (fg-yellow "gold") (fg-yellow-dim "gold3") (bg-yellow "#2d2600") (bg-yellow-dim "#141100") (bg-yellow-dimmer "#0f0c00") (fg-blue "steelblue1") (bg-blue "#002647") (bg-blue-dim "#001323") (bg-blue-dimmer "#000b14") (fg-magenta "violet") (fg-magenta-dim "#e64be6") (bg-magenta "#470047") (bg-magenta-dim "#280028") (bg-magenta-dimmer "#190019") (fg-cyan "cadetblue1") (bg-cyan "#063237") (fg "#fff") (fg-dim "#bbb") (fg-dimmer "#888"))) (defun eighters-show-palette () (interactive) (list-colors-display (mapcar 'cadr eighters-palette) "*Eighters palette*")) (defface eighters-button nil "Face for text that can be hit with RET.") (defface eighters-title-1 nil "Face for level 1 headings.") (defface eighters-title-2 nil "Face for level 2 headings.") (defface eighters-title-3 nil "Face for level 3 headings.") (defface eighters-title-4 nil "Face for level 4 headings.") (defface eighters-title-5 nil "Face for level 5 headings.") (defface eighters-title-6 nil "Face for level 6 headings.") (defface eighters-ui nil "Face for inalterable UI elements.") (defmacro eighters-with-palette (&rest body) `(let ,eighters-palette ,@body)) (eighters-with-palette (custom-theme-set-faces 'eighters ;; Theme faces. `(eighters-button ((t (:background ,bg-hl-dimmer :box (:color ,bg-hl :style released-button) :inherit eighters-ui)))) `(eighters-title-1 ((t (:foreground ,fg-cyan :weight bold :height 1.40 :inherit variable-pitch)))) `(eighters-title-2 ((t (:foreground ,fg-green :weight bold :height 1.24 :inherit variable-pitch)))) `(eighters-title-3 ((t (:foreground ,fg-yellow :weight bold :height 1.18 :inherit variable-pitch)))) `(eighters-title-4 ((t (:foreground ,fg-red :weight bold :height 1.12 :inherit variable-pitch)))) `(eighters-title-5 ((t (:foreground ,fg-magenta :weight bold :inherit variable-pitch)))) `(eighters-title-6 ((t (:foreground ,fg-blue :slant italic :inherit variable-pitch)))) `(eighters-ui ((t (:inherit variable-pitch)))) ;; Standard faces. `(button ((t (:inherit eighters-button)))) `(completions-common-part ((t (:foreground ,fg-dimmer)))) `(custom-button ((t (:inherit eighters-button)))) `(completions-first-difference ((t (:foreground ,fg-magenta :weight bold)))) `(custom-comment ((t (:background ,bg-hl-dim :foreground ,fg-dim)))) `(custom-variable-tag ((t (:inherit eighters-title-3)))) `(default ((t (:background ,bg :foreground ,fg)))) `(dired-broken-symlink ((t (:background ,bg-red :foreground ,fg-yellow :weight bold)))) `(dired-header ((t (:inherit eighters-title-1)))) `(dired-special ((t (:foreground ,fg-yellow-dim)))) `(eldoc-highlight-function-argument ((t (:background ,bg-yellow :foreground ,fg-yellow :weight bold)))) `(error ((t :foreground ,fg-red :weight bold))) `(fringe ((t (:background ,bg-hl-dimmer)))) `(shadow ((t (:foreground ,fg-dimmer)))) `(help-key-binding ((t (:background ,bg-hl-dimmer :foreground ,fg-magenta :inherit fixed-pitch-serif)))) `(highlight ((t (:background ,bg-hl-dim)))) `(lazy-highlight ((t (:background ,bg-cyan)))) `(region ((t (:background ,bg-blue-dim)))) `(escape-glyph ((t (:foreground ,fg-red-dim)))) `(minibuffer-prompt ((t (:foreground ,fg-blue :weight bold)))) `(font-lock-builtin-face ((t (:foreground ,fg-blue)))) `(font-lock-comment-face ((t (:foreground ,fg-dim :slant italic)))) `(font-lock-constant-face ((t (:foreground ,fg-magenta)))) `(font-lock-doc-face ((t (:foreground ,fg-green-dim :slant italic)))) `(font-lock-function-name-face ((t (:foreground ,fg-blue :weight bold)))) `(font-lock-keyword-face ((t (:foreground ,fg-cyan :weight bold)))) `(font-lock-preprocessor-face ((t (:foreground ,fg-blue)))) `(font-lock-regexp-grouping-backslash ((t (:foreground ,fg-yellow-dim)))) `(font-lock-regexp-grouping-construct ((t (:foreground ,fg-yellow :weight bold)))) `(font-lock-string-face ((t (:foreground ,fg-green-dim)))) `(font-lock-type-face ((t (:foreground ,fg-green)))) `(font-lock-variable-name-face ((t (:foreground ,fg-yellow)))) `(font-lock-warning-face ((t (:inherit warning)))) `(header-line ((t (:background ,bg-hl :inherit eighters-ui)))) `(info-title-1 ((t (:inherit eighters-title-1)))) `(info-title-2 ((t (:inherit eighters-title-2)))) `(info-title-3 ((t (:inherit eighters-title-3)))) `(info-title-4 ((t (:inherit eighters-title-4)))) `(isearch ((t (:background ,bg-red :foreground ,fg-magenta :inverse-video t)))) `(isearch-fail ((t (:background ,bg-red :weight bold)))) `(isearch-group-1 ((t (:background ,bg-red :foreground ,fg-blue :inverse-video t)))) `(isearch-group-2 ((t (:background ,bg-red :foreground ,fg-cyan :inverse-video t)))) `(link ((t (:foreground ,fg-blue :underline t)))) `(link-visited ((t (:foreground ,fg-magenta-dim :underline t)))) `(Man-overstrike ((t (:foreground ,fg-cyan :inherit bold)))) `(mode-line ((t (:background ,bg-hl :box (:color ,fg) :inherit eighters-ui)))) `(mode-line-inactive ((t (:background ,bg-hl-dimmer :foreground ,fg-dimmer :box (:color ,bg-hl-dimmer) :inherit eighters-ui)))) `(outline-1 ((t (:inherit eighters-title-1)))) `(outline-2 ((t (:inherit eighters-title-2)))) `(outline-3 ((t (:inherit eighters-title-3)))) `(outline-4 ((t (:inherit eighters-title-4)))) `(outline-5 ((t (:inherit eighters-title-5)))) `(outline-6 ((t (:inherit eighters-title-6)))) `(separator-line ((t (:background ,bg-hl :height 0.1)))) `(tab-bar ((t (:background ,bg-hl-dimmer :inherit eighters-ui)))) `(tab-bar-tab ((t (:weight bold :box (:style released-button) :inherit tab-bar)))) `(tab-bar-tab-inactive ((t (:foreground ,fg-dimmer :weight normal :box (:style pressed-button) :inherit tab-bar-tab)))) `(tab-line ((t (:inherit tab-bar :height 0.9)))) `(tab-line-tab-current ((t (:inherit (tab-line-tab tab-bar-tab))))) `(tab-line-tab-inactive ((t (:inherit (tab-line-tab tab-bar-tab-inactive))))) `(transient-argument ((t :weight bold :inherit font-lock-string-face))) `(transient-key ((t :inherit help-key-binding))) `(transient-unreachable-key ((t :inherit (shadow help-key-binding)))) `(show-paren-match ((t (:foreground ,fg-cyan :inverse-video t)))) `(vertical-border ((t (:foreground ,bg-hl)))) `(warning ((t (:foreground ,fg-yellow :weight bold)))) `(widget-field ((t (:background ,bg-hl-dim)))) ;;; diff faces. `(diff-header ((t (:background ,bg-hl-dimmer :foreground ,fg-dim)))) `(diff-file-header ((t (:background ,bg-hl-dimmer :foreground ,fg :weight bold)))) `(diff-hunk-header ((t (:background ,bg-hl-dim :foreground ,fg-dim)))) `(diff-function ((t (:background ,bg-hl-dim :weight bold)))) `(diff-context ((t :foreground ,fg-dim))) `(diff-removed ((t (:background ,bg-red-dimmer)))) `(diff-refine-removed ((t (:background ,bg-red)))) `(diff-indicator-removed ((t (:foreground ,fg-red :inherit diff-removed)))) `(diff-added ((t :background ,bg-blue-dimmer))) `(diff-refine-added ((t (:background ,bg-blue)))) `(diff-indicator-added ((t (:foreground ,fg-blue :inherit diff-added)))) `(diff-changed ((t :background ,bg-yellow-dimmer))) `(diff-refine-changed ((t (:background ,bg-yellow)))) `(diff-indicator-changed ((t (:foreground ,fg-yellow :inherit diff-changed)))) `(ediff-even-diff-A ((t (:background ,bg-hl-dimmer)))) `(ediff-even-diff-B ((t (:background ,bg-hl-dimmer)))) `(ediff-even-diff-C ((t (:background ,bg-hl-dimmer)))) `(ediff-even-diff-Ancestor ((t (:background ,bg-hl-dimmer)))) `(ediff-odd-diff-A ((t (:background ,bg-hl-dimmer)))) `(ediff-odd-diff-B ((t (:background ,bg-hl-dimmer)))) `(ediff-odd-diff-C ((t (:background ,bg-hl-dimmer)))) `(ediff-odd-diff-Ancestor ((t (:background ,bg-hl-dimmer)))) `(ediff-current-diff-A ((t (:inherit diff-removed)))) `(ediff-current-diff-B ((t (:inherit diff-added)))) `(ediff-current-diff-C ((t (:inherit diff-changed)))) `(ediff-current-diff-Ancestor ((t (:background ,bg-magenta-dimmer)))) `(ediff-fine-diff-A ((t (:inherit diff-refine-removed)))) `(ediff-fine-diff-B ((t (:inherit diff-refine-added)))) `(ediff-fine-diff-C ((t (:inherit diff-refine-changed)))) `(ediff-fine-diff-Ancestor ((t (:background ,bg-magenta)))) ;; Third-party faces. `(diff-hl-delete ((t (:foreground ,fg-red :background ,bg-red)))) `(diff-hl-insert ((t (:foreground ,fg-blue :background ,bg-blue)))) `(diff-hl-change ((t (:foreground ,fg-yellow :background ,bg-yellow)))) `(which-key-group-description-face ((t (:foreground ,fg-green-dim)))) `(which-key-key-face ((t :weight bold :inherit help-key-binding))) ;;; Magit. ;;;; Section backgrounds. `(magit-section-highlight ((t :background ,bg-hl-dimmer))) `(magit-diff-revision-summary ((t (:weight bold :inherit magit-diff-hunk-heading)))) `(magit-diff-context ((t (:foreground ,fg-dim)))) `(magit-diff-context-highlight ((t (:background ,bg-hl-dimmer :inherit magit-diff-context)))) `(magit-diff-hunk-heading ((t (:background ,bg-hl-dim)))) `(magit-diff-hunk-heading-highlight ((t (:background ,bg-hl)))) ;;;; Diffs. `(magit-diff-removed ((t (:foreground ,fg-dim :inherit diff-removed)))) `(magit-diff-removed-highlight ((t (:background ,bg-red-dim)))) `(magit-diffstat-removed ((t (:foreground ,fg-red)))) `(magit-diff-added ((t (:foreground ,fg-dim :inherit diff-added)))) `(magit-diff-added-highlight ((t (:background ,bg-blue-dim)))) `(magit-diffstat-added ((t (:foreground ,fg-blue)))))) (provide-theme 'eighters)