Give Kali Linux a Cyberwave or or Matrix Makeover: Dynamic Zsh Gradients, Terminator Themes, and Matching Wallpapers

I wanted to give my Kali Linux cybersecurity workspace a distinctive look without sacrificing readability. Specifically, I wanted a dark terminal, coordinated colors, and a continuous gradient across the commands I typed. Checkout these Kali terminal themes!

With ChatGPT’s help, I developed two themes: Matrix, using muted greens, and Lavender Cyberwave, using subdued purples and blues. Both themes customize Terminator and Zsh, including the Kali-style prompt, command-line highlighting, cursor, title bar, terminal output, and background.

We also created matching 1920 × 1080 world-map wallpapers to complete the desktop.

The following guide explains the requirements and provides copy-and-paste installation commands.

What Makes These Themes Different?

The most interesting feature is the continuous command-line gradient.

Rather than coloring commands according to syntax, the gradient interpolates between two colors across the entire editable command. It dynamically adjusts as you type or delete characters.

For example, typing a short command produces a complete transition from the starting color to the ending color. A longer command stretches that same transition across more characters.

This is accomplished with a custom highlighter integrated into Zsh’s syntax-highlighting system.

Both installers also configure the familiar two-line Kali prompt and apply their respective colors when a new interactive Zsh session starts.

Requirements

These themes are intended for Kali Linux using:

  • Xfce desktop environment
  • Terminator terminal
  • Zsh

Install the required packages:

sudo apt update && sudo apt install -y terminator zsh zsh-syntax-highlighting python3

The installers should be run as your normal user, not with sudo. They modify files in your home directory, including ~/.zshrc and ~/.config/terminator/config.

Both installers create backups before changing existing files.

Theme 1: Matrix

The Matrix theme uses a dark green-black background, muted green terminal output, a dark-green Kali prompt, and a continuous light-to-dark green command gradient.

Its steady green block cursor and forest-green title bar complete the look.

Matrix colors

ElementColor
Background#101810
Terminal output#91B99A
Prompt#397D4A
Gradient start#99FF99
Gradient end#1F6F39
Cursor#76C58A
Active title bar#285C39
Title-bar text#B2E8BA

Install Matrix

Copy and paste the entire command into Kali:

bash <<'INSTALL_MATRIX'
set -euo pipefail

command -v zsh >/dev/null || { echo "Zsh is required."; exit 1; }
command -v terminator >/dev/null || { echo "Terminator is required."; exit 1; }

test -r /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh || {
    echo "Install zsh-syntax-highlighting first."
    exit 1
}

python3 - <<'PY'
from pathlib import Path
from datetime import datetime
import shutil
import re

home = Path.home()
zshrc = home / ".zshrc"
cfg = home / ".config/terminator/config"
highlighter = home / ".config/zsh-matrix/highlighters/cybergradient/cybergradient-highlighter.zsh"

backup = home / "terminal-theme-backup" / (
    "matrix-" + datetime.now().strftime("%Y%m%d-%H%M%S-%f")
)
backup.mkdir(parents=True, exist_ok=True)

for path in (zshrc, cfg, highlighter):
    if path.exists():
        target = backup / path.relative_to(home)
        target.parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(path, target)

highlighter.parent.mkdir(parents=True, exist_ok=True)

highlighter.write_text(r'''
_zsh_highlight_highlighter_cybergradient_predicate() {
    return 0
}

_zsh_highlight_highlighter_cybergradient_paint() {
    emulate -L zsh
    local -i n=${#BUFFER} i t r g b

    (( n == 0 )) && return

    for (( i=0; i<n; i++ )); do
        (( t = n > 1 ? i * 1000 / (n-1) : 0 ))
        (( r = 153 + (31-153)*t/1000 ))
        (( g = 255 + (111-255)*t/1000 ))
        (( b = 153 + (57-153)*t/1000 ))

        region_highlight+=("$i $((i+1)) fg=$(printf '#%02X%02X%02X' $r $g $b)")
    done
}
''')

text = zshrc.read_text() if zshrc.exists() else ""

for name in ("MATRIX-CYBER", "LAVENDER-CYBERWAVE", "CYBER-THEME"):
    text = re.sub(
        r"(?ms)^# " + re.escape(name) +
        r" BEGIN\n.*?^# " + re.escape(name) + r" END\n?",
        "", text
    )

text += r'''
# CYBER-THEME BEGIN

# Matrix Kali prompt
PROMPT=$'%F{#397D4A}┌──(%n㉿%m)-[%~]\n└─%(!.#.$) %f'

# Load custom highlighter through zsh-syntax-highlighting.
ZSH_HIGHLIGHT_HIGHLIGHTERS=(cybergradient)
ZSH_HIGHLIGHT_HIGHLIGHTERS_DIR="$HOME/.config/zsh-matrix/highlighters"

source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

# Keep pasted text from overriding the command gradient.
zle_highlight=( "${(@)zle_highlight:#paste:*}" paste:none )

# Restore terminal colors at shell startup.
if [[ -o interactive && "$TERM" != dumb ]]; then
    printf '\e[0m\e[?5l\e]11;#101810\a\e]10;#91B99A\a\e]12;#76C58A\a\e[2 q'
fi

# CYBER-THEME END
'''

zshrc.write_text(text)

cfg.parent.mkdir(parents=True, exist_ok=True)
lines = cfg.read_text().splitlines() if cfg.exists() else []

def ensure(header, before=None):
    if header not in lines:
        pos = lines.index(before) if before in lines else len(lines)
        lines.insert(pos, header)

def update(header, settings, indent, boundary):
    start = lines.index(header)
    end = next(
        (i for i in range(start+1, len(lines)) if boundary(lines[i])),
        len(lines)
    )
    old = [
        s for s in lines[start+1:end]
        if s.strip().split("=", 1)[0].strip() not in settings
    ]
    lines[start+1:end] = [
        f"{indent}{k} = {v}" for k, v in settings.items()
    ] + old

ensure("[global_config]", "[profiles]")

update("[global_config]", {
    "putty_paste_style": "True",
    "putty_paste_style_source_clipboard": "True",
    "title_transmit_bg_color": '"#285C39"',
    "title_transmit_fg_color": '"#B2E8BA"',
    "title_receive_bg_color": '"#285C39"',
    "title_receive_fg_color": '"#B2E8BA"',
    "title_inactive_bg_color": '"#183524"',
    "title_inactive_fg_color": '"#8CB99A"',
}, "  ", lambda s: s.startswith("[") and not s.startswith(" "))

ensure("[profiles]", "[layouts]")
profile = "  [[matrix-cyber]]"

if profile not in lines:
    lines.insert(lines.index("[profiles]")+1, profile)

update(profile, {
    "use_theme_colors": "False",
    "background_color": '"#101810"',
    "foreground_color": '"#91B99A"',
    "cursor_color_default": "False",
    "cursor_bg_color": '"#76C58A"',
    "cursor_fg_color": '"#101810"',
    "cursor_blink": "False",
    "cursor_shape": "block",
}, "    ", lambda s: s.startswith("  [[") or
             (s.startswith("[") and not s.startswith(" ")))

cfg.write_text("\n".join(lines).rstrip()+"\n")

print("Matrix installed.")
print("Backup:", backup)
PY

zsh -n "$HOME/.zshrc"

echo "Close Terminator and launch:"
echo "terminator -p matrix-cyber"
INSTALL_MATRIX

After installation, close Terminator and launch the Matrix profile:

terminator -p matrix-cyber

Theme 2: Lavender Cyberwave

Lavender Cyberwave uses the same gradient technique but replaces the green palette with dusty lavender, violet, and muted blue.

The background is a very dark purple-black, while the cursor, prompt, and title bar use complementary lavender shades.

Lavender Cyberwave colors

ElementColor
Background#171520
Terminal output#B8A9C9
Prompt#9B8CB8
Gradient start#C9B8E0
Gradient end#526997
Cursor#9B8CB8
Active title bar#403052
Title-bar text#D9C8ED
Selection background (best-effort)#51436F

Install Lavender Cyberwave

Copy and paste this entire command:

bash <<'INSTALL_CYBERWAVE'
set -euo pipefail

command -v zsh >/dev/null || { echo "Zsh is required."; exit 1; }
command -v terminator >/dev/null || { echo "Terminator is required."; exit 1; }

test -r /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh || {
    echo "Install zsh-syntax-highlighting first."
    exit 1
}

python3 - <<'PY'
from pathlib import Path
from datetime import datetime
import shutil
import re

home = Path.home()
zshrc = home / ".zshrc"
cfg = home / ".config/terminator/config"
gtk = home / ".config/gtk-3.0/gtk.css"
highlighter = home / ".config/zsh-cyberwave/highlighters/cybergradient/cybergradient-highlighter.zsh"

backup = home / "terminal-theme-backup" / (
    "cyberwave-" + datetime.now().strftime("%Y%m%d-%H%M%S-%f")
)
backup.mkdir(parents=True, exist_ok=True)

for path in (zshrc, cfg, gtk, highlighter):
    if path.exists():
        target = backup / path.relative_to(home)
        target.parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(path, target)

highlighter.parent.mkdir(parents=True, exist_ok=True)

highlighter.write_text(r'''
_zsh_highlight_highlighter_cybergradient_predicate() {
    return 0
}

_zsh_highlight_highlighter_cybergradient_paint() {
    emulate -L zsh
    local -i n=${#BUFFER} i t r g b

    (( n == 0 )) && return

    for (( i=0; i<n; i++ )); do
        (( t = n > 1 ? i * 1000 / (n-1) : 0 ))
        (( r = 201 + (82-201)*t/1000 ))
        (( g = 184 + (105-184)*t/1000 ))
        (( b = 224 + (151-224)*t/1000 ))

        region_highlight+=("$i $((i+1)) fg=$(printf '#%02X%02X%02X' $r $g $b)")
    done
}
''')

text = zshrc.read_text() if zshrc.exists() else ""

for name in ("MATRIX-CYBER", "LAVENDER-CYBERWAVE", "CYBER-THEME"):
    text = re.sub(
        r"(?ms)^# " + re.escape(name) +
        r" BEGIN\n.*?^# " + re.escape(name) + r" END\n?",
        "", text
    )

text += r'''
# CYBER-THEME BEGIN

# Lavender Kali prompt
PROMPT=$'%F{#9B8CB8}┌──(%n㉿%m)-[%~]\n└─%(!.#.$) %f'

# Load the custom highlighter.
ZSH_HIGHLIGHT_HIGHLIGHTERS=(cybergradient)
ZSH_HIGHLIGHT_HIGHLIGHTERS_DIR="$HOME/.config/zsh-cyberwave/highlighters"

source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

zle_highlight=( "${(@)zle_highlight:#paste:*}" paste:none )

# Restore Cyberwave colors at shell startup.
if [[ -o interactive && "$TERM" != dumb ]]; then
    printf '\e[0m\e[?5l\e]11;#171520\a\e]10;#B8A9C9\a\e]12;#9B8CB8\a\e[2 q'
fi

# CYBER-THEME END
'''

zshrc.write_text(text)

cfg.parent.mkdir(parents=True, exist_ok=True)
lines = cfg.read_text().splitlines() if cfg.exists() else []

def ensure(header, before=None):
    if header not in lines:
        pos = lines.index(before) if before in lines else len(lines)
        lines.insert(pos, header)

def update(header, settings, indent, boundary):
    start = lines.index(header)
    end = next(
        (i for i in range(start+1, len(lines)) if boundary(lines[i])),
        len(lines)
    )
    old = [
        s for s in lines[start+1:end]
        if s.strip().split("=", 1)[0].strip() not in settings
    ]
    lines[start+1:end] = [
        f"{indent}{k} = {v}" for k, v in settings.items()
    ] + old

ensure("[global_config]", "[profiles]")

update("[global_config]", {
    "putty_paste_style": "True",
    "putty_paste_style_source_clipboard": "True",
    "title_transmit_bg_color": '"#403052"',
    "title_transmit_fg_color": '"#D9C8ED"',
    "title_receive_bg_color": '"#403052"',
    "title_receive_fg_color": '"#D9C8ED"',
    "title_inactive_bg_color": '"#241D30"',
    "title_inactive_fg_color": '"#A99BB9"',
}, "  ", lambda s: s.startswith("[") and not s.startswith(" "))

ensure("[profiles]", "[layouts]")
profile = "  [[lavender-cyberwave]]"

if profile not in lines:
    lines.insert(lines.index("[profiles]")+1, profile)

update(profile, {
    "use_theme_colors": "False",
    "background_color": '"#171520"',
    "foreground_color": '"#B8A9C9"',
    "cursor_color_default": "False",
    "cursor_bg_color": '"#9B8CB8"',
    "cursor_fg_color": '"#171520"',
    "cursor_blink": "False",
    "cursor_shape": "block",
    "use_system_font": "False",
    "font": '"Fira Code Medium 20"',
}, "    ", lambda s: s.startswith("  [[") or
             (s.startswith("[") and not s.startswith(" ")))

cfg.write_text("\n".join(lines).rstrip()+"\n")

# Best-effort GTK selection colors
gtk.parent.mkdir(parents=True, exist_ok=True)
css = gtk.read_text() if gtk.exists() else ""

start = "/* CYBERWAVE TERMINAL SELECTION START */"
end = "/* CYBERWAVE TERMINAL SELECTION END */"

if start in css and end in css:
    a = css.index(start)
    b = css.index(end, a) + len(end)
    css = css[:a] + css[b:]

css += '''
/* CYBERWAVE TERMINAL SELECTION START */
vte-terminal selection,
VteTerminal selection {
    background-color: #51436F;
    color: #D9C8ED;
}
/* CYBERWAVE TERMINAL SELECTION END */
'''

gtk.write_text(css)

print("Lavender Cyberwave installed.")
print("Backup:", backup)
PY

zsh -n "$HOME/.zshrc"

echo "Close Terminator and launch:"
echo "terminator -p lavender-cyberwave"
INSTALL_CYBERWAVE

After installation, close Terminator and launch:

terminator -p lavender-cyberwave

Matching Desktop Wallpapers

To complement the terminal themes, we used ChatGPT’s image generation capabilities to create two matching 1920 × 1080 world-map wallpapers.

Both depict a global network of illuminated cities, communication nodes, and sweeping connections between continents. After experimenting with brighter designs and simulated interface elements, I settled on darker, cleaner images without text or HUD overlays.

The result is a pair of wallpapers that complement their respective terminal themes without overwhelming the desktop.

Matrix wallpaper: A dark world map illuminated by muted green connections and network nodes.

Lavender Cyberwave wallpaper: A dark world map illuminated by lavender, violet, and muted blue connections.

How the Themes Work

Each installer configures three main components.

1. Terminator

Terminator stores the terminal background, foreground, cursor, and profile settings. The installers create separate profiles named matrix-cyber and lavender-cyberwave.

They also configure matching title-bar colors and enable right-click paste.

2. Zsh

Both installers update ~/.zshrc to configure the two-line Kali prompt, activate the custom gradient highlighter, and apply matching terminal colors during shell startup.

This ensures that the intended styling is restored when new interactive Zsh sessions begin.

3. Custom command gradient

The installers create a custom highlighter for zsh-syntax-highlighting. It calculates a separate RGB color for each character in the command line using linear interpolation.

Unlike traditional syntax highlighting, the color transition is based on character position rather than command type.

Persistence, Backups, and Compatibility

The configuration files are written to disk, so the themes are intended to persist across terminal restarts and system reboots. The installers do not rely on temporary shell commands alone.

Before modifying existing configuration files, each installer creates timestamped backups under:

~/terminal-theme-backup/

Both themes can have their Terminator profiles installed simultaneously. However, the Zsh configuration and global title-bar colors are shared, so installing one theme after the other changes the active styling. To restore the complete appearance of a particular theme, rerun its installer.

The Lavender Cyberwave installer also includes a GTK CSS override for selection highlighting. This is a best-effort adjustment because text-selection styling can depend on the versions of GTK and VTE in use.

These installers are designed for Kali Linux with Terminator and Zsh. They have not been independently validated on every Kali release or with every possible existing Zsh configuration. I recommend testing them in a VM snapshot before applying them to a heavily customized environment.

Final Thoughts

This project started with a simple goal: make my Kali terminal look better. It turned into an exploration of Zsh highlighting, terminal escape sequences, persistent configuration, and color coordination.

The finished themes offer two different aesthetics while preserving the same functionality. Matrix delivers a restrained green-on-black cybersecurity look, while Lavender Cyberwave provides a softer purple-and-blue alternative.

Combined with the matching world-map wallpapers, both give Kali Linux a more cohesive visual identity without requiring an entirely new desktop environment.

If you’re looking for something different from Kali’s default appearance, give one of them a try.

Leave Comment

Your email address will not be published. Required fields are marked *