5.9 Override colors

The themes provide a mechanism for overriding their color values. This is controlled by the variables modus-themes-operandi-color-overrides and modus-themes-vivendi-color-overrides, which are alists that should mirror a subset of the associations in modus-themes-operandi-colors and modus-themes-vivendi-colors respectively. As with all customizations, overriding must be done before loading the affected theme.

Visualize the active Modus theme’s palette.

Let us approach the present topic one step at a time. Here is a simplified excerpt of the default palette for Modus Operandi with some basic background values that apply to buffers and the mode line (remember to inspect the actual value to find out all the associations that can be overridden):

(defconst modus-themes-operandi-colors
  '((bg-main . "#ffffff")
    (bg-dim . "#f8f8f8")
    (bg-alt . "#f0f0f0")
    (bg-active . "#d7d7d7")
    (bg-inactive . "#efefef")))

As one can tell, we bind a key to a hexadecimal RGB color value. Now say we wish to override those specific values and have our changes propagate to all faces that use those keys. We could write something like this, which adds a subtle ocher tint:

(setq modus-themes-operandi-color-overrides
      '((bg-main . "#fefcf4")
        (bg-dim . "#faf6ef")
        (bg-alt . "#f7efe5")
        (bg-active . "#e8dfd1")
        (bg-inactive . "#f6ece5")))

Once this is evaluated, any subsequent loading of modus-operandi will use those values instead of the defaults. No further intervention is required.

To reset the changes, we apply this and reload the theme:

(setq modus-themes-operandi-color-overrides nil)

Users who wish to leverage such a mechanism can opt to implement it on-demand by means of a global minor mode. The following snippet covers both themes and expands to some more associations in the palette:

(define-minor-mode my-modus-themes-tinted
  "Tweak some Modus themes colors."
  :init-value nil
  :global t
  (if my-modus-themes-tinted
      (setq modus-themes-operandi-color-overrides
            '((bg-main . "#fefcf4")
              (bg-dim . "#faf6ef")
              (bg-alt . "#f7efe5")
              (bg-hl-line . "#f4f0e3")
              (bg-active . "#e8dfd1")
              (bg-inactive . "#f6ece5")
              (bg-region . "#c6bab1")
              (bg-header . "#ede3e0")
              (bg-tab-active . "#fdf6eb")
              (bg-tab-inactive . "#c8bab8"))
            modus-themes-vivendi-color-overrides
            '((bg-main . "#100b17")
              (bg-dim . "#161129")
              (bg-alt . "#181732")
              (bg-hl-line . "#191628")
              (bg-active . "#282e46")
              (bg-inactive . "#1a1e39")
              (bg-region . "#393a53")
              (bg-header . "#202037")
              (bg-tab-active . "#120f18")
              (bg-tab-inactive . "#3a3a5a")))
    (setq modus-themes-operandi-color-overrides nil
          modus-themes-vivendi-color-overrides nil)))

A more neutral style for modus-themes-operandi-color-overrides can look like this:

'((bg-main . "#f7f7f7")
  (bg-dim . "#f2f2f2")
  (bg-alt . "#e8e8e8")
  (bg-hl-line . "#eaeaef")
  (bg-active . "#e0e0e0")
  (bg-inactive . "#e6e6e6")
  (bg-region . "#b5b5b5")
  (bg-header . "#e4e4e4")
  (bg-tab-active . "#f5f5f5")
  (bg-tab-inactive . "#c0c0c0"))

With those in place, one can use M-x my-modus-themes-tinted and then load the Modus theme of their choice. The new palette subset will come into effect: subtle ocher tints (or shades of gray) for Modus Operandi and night sky blue shades for Modus Vivendi. Switching between the two themes, such as with M-x modus-themes-toggle will also use the overrides.

Given that this is a user-level customization, one is free to implement whatever color values they desire, even if the possible combinations fall below the minimum 7:1 contrast ratio that governs the design of the themes (the WCAG AAA legibility standard). Alternatively, this can also be done programmatically (Override color saturation).

The above are expanded into a fully fledged derivative elsewhere in this document (Override colors completely).

For manual interventions it is advised to inspect the source code of modus-themes-operandi-colors and modus-themes-vivendi-colors for the inline commentary: it explains what the intended use of each palette subset is.

Furthermore, users may benefit from the modus-themes-contrast function that we provide: test color combinations. It measures the contrast ratio between two color values, so it can help in overriding the palette (or a subset thereof) without making the end result inaccessible.