The marker carries the state, the color reinforces it. Colors only on a
TTY, honoring NO_COLOR and TERM=dumb; piped output stays plain, markers
intact.
# [*] info [+] did something [=] already converged [-] warn, kept going [x] fatalif [ -t 1 ] && [ -z "${NO_COLOR:-}" ] && [ "${TERM:-}" != dumb ]; then B='\033[1;34m' G='\033[1;32m' Y='\033[1;33m' R='\033[31m' D='\033[2m' N='\033[0m'else B= G= Y= R= D= N=fihdr() { printf "${B}[*]${N} %s\n" "$1"; }ok() { printf "${G}[+]${N} %s\n" "$1"; }skip() { printf "${D}[=] %s${N}\n" "$1"; }warn() { printf "${Y}[-]${N} %s\n" "$1" >&2; }die() { printf "${R}[x]${N} %s\n" "$1" >&2; exit 1; }