;;; org-faces-config.el --- Custom faces for the org agenda header row -*- lexical-binding: t; coding: utf-8; -*- ;; author Craig Jennings ;;; Commentary: ;; ;; Layer: 2 (Core UX). ;; Category: C/S. ;; Load shape: eager. ;; Eager reason: the faces must exist before org renders the agenda. ;; Top-level side effects: defines the org-faces-* faces; sets ;; org-todo-keyword-faces and org-priority-faces once org loads. ;; Runtime requires: none (org wiring is deferred via with-eval-after-load). ;; ;; Custom faces for the agenda "header row" -- the TODO keyword and the ;; priority cookie -- so each keyword and each priority is its own themeable ;; element rather than sharing org's built-in org-todo / org-done / org-priority. ;; They are named org-faces-* (not org-*) so it's obvious they are this config's ;; layer, not built-in org. Each carries a real default color so the agenda is ;; legible on any theme; a theme (e.g. one generated by theme-studio's ;; "org-faces" app) overrides them. The -dim variants are the dimmed colors ;; auto-dim-config.el remaps these to in non-selected windows, so keywords stay ;; recognizable when a window recedes. ;; ;; Note: this file is org-faces-CONFIG, not org-faces -- org ships its own ;; `org-faces' feature (lisp/org/org-faces.el), so reusing that name would ;; shadow org's face definitions on the load path. ;;; Code: (eval-when-compile (require 'org)) (defgroup org-faces-config nil "Custom faces for the org agenda header row (keywords and priorities)." :group 'org) ;; --------------------------- Keyword faces (focused) ------------------------- (defface org-faces-todo '((t (:foreground "#8fbf73" :weight bold))) "Face for the TODO keyword." :group 'org-faces-config) (defface org-faces-project '((t (:foreground "#7a9abe" :weight bold))) "Face for the PROJECT keyword." :group 'org-faces-config) (defface org-faces-doing '((t (:foreground "#e8c668" :weight bold))) "Face for the DOING keyword." :group 'org-faces-config) (defface org-faces-waiting '((t (:foreground "#c9b08a" :weight bold))) "Face for the WAITING keyword." :group 'org-faces-config) (defface org-faces-verify '((t (:foreground "#d98a5a" :weight bold))) "Face for the VERIFY keyword." :group 'org-faces-config) (defface org-faces-stalled '((t (:foreground "#9a8fb0" :weight bold))) "Face for the STALLED keyword." :group 'org-faces-config) (defface org-faces-delegated '((t (:foreground "#7fc0a8" :weight bold))) "Face for the DELEGATED keyword." :group 'org-faces-config) (defface org-faces-failed '((t (:foreground "#d05a5a" :weight bold))) "Face for the FAILED keyword." :group 'org-faces-config) (defface org-faces-done '((t (:foreground "#6f7a82" :weight bold))) "Face for the DONE keyword." :group 'org-faces-config) (defface org-faces-cancelled '((t (:foreground "#6f7a82" :weight bold :strike-through t))) "Face for the CANCELLED keyword." :group 'org-faces-config) ;; -------------------------- Priority faces (focused) ------------------------- (defface org-faces-priority-a '((t (:foreground "#7aa0d0" :weight bold))) "Face for the [#A] priority cookie." :group 'org-faces-config) (defface org-faces-priority-b '((t (:foreground "#e8c668"))) "Face for the [#B] priority cookie." :group 'org-faces-config) (defface org-faces-priority-c '((t (:foreground "#8fbf73"))) "Face for the [#C] priority cookie." :group 'org-faces-config) (defface org-faces-priority-d '((t (:foreground "#8a8a8a"))) "Face for the [#D] priority cookie." :group 'org-faces-config) ;; ----------------------------- Keyword faces (dim) --------------------------- ;; auto-dim-config.el remaps the focused faces above to these in non-selected ;; windows; a darker shade of the same hue keeps the keyword recognizable. (defface org-faces-todo-dim '((t (:foreground "#5f7a4d" :weight bold))) "Dimmed TODO keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-project-dim '((t (:foreground "#4f6680" :weight bold))) "Dimmed PROJECT keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-doing-dim '((t (:foreground "#9a8544" :weight bold))) "Dimmed DOING keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-waiting-dim '((t (:foreground "#87745c" :weight bold))) "Dimmed WAITING keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-verify-dim '((t (:foreground "#8f5a3c" :weight bold))) "Dimmed VERIFY keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-stalled-dim '((t (:foreground "#665e75" :weight bold))) "Dimmed STALLED keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-delegated-dim '((t (:foreground "#547d6c" :weight bold))) "Dimmed DELEGATED keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-failed-dim '((t (:foreground "#8a3c3c" :weight bold))) "Dimmed FAILED keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-done-dim '((t (:foreground "#4a5158" :weight bold))) "Dimmed DONE keyword for non-selected windows." :group 'org-faces-config) (defface org-faces-cancelled-dim '((t (:foreground "#4a5158" :weight bold :strike-through t))) "Dimmed CANCELLED keyword for non-selected windows." :group 'org-faces-config) ;; ---------------------------- Priority faces (dim) --------------------------- (defface org-faces-priority-a-dim '((t (:foreground "#4f6a8a" :weight bold))) "Dimmed [#A] priority cookie for non-selected windows." :group 'org-faces-config) (defface org-faces-priority-b-dim '((t (:foreground "#9a8544"))) "Dimmed [#B] priority cookie for non-selected windows." :group 'org-faces-config) (defface org-faces-priority-c-dim '((t (:foreground "#5f7a4d"))) "Dimmed [#C] priority cookie for non-selected windows." :group 'org-faces-config) (defface org-faces-priority-d-dim '((t (:foreground "#5a5a5a"))) "Dimmed [#D] priority cookie for non-selected windows." :group 'org-faces-config) ;; ---------------------------------- Wiring ----------------------------------- ;; Map each keyword string and priority char to its face once org is loaded, so ;; the values stick regardless of when org initializes. (with-eval-after-load 'org (setq org-todo-keyword-faces '(("TODO" . org-faces-todo) ("PROJECT" . org-faces-project) ("DOING" . org-faces-doing) ("WAITING" . org-faces-waiting) ("VERIFY" . org-faces-verify) ("STALLED" . org-faces-stalled) ("DELEGATED" . org-faces-delegated) ("FAILED" . org-faces-failed) ("DONE" . org-faces-done) ("CANCELLED" . org-faces-cancelled))) (setq org-priority-faces '((?A . org-faces-priority-a) (?B . org-faces-priority-b) (?C . org-faces-priority-c) (?D . org-faces-priority-d)))) (provide 'org-faces-config) ;;; org-faces-config.el ends here