Marker output

Colors only on a TTY, honoring NO_COLOR and TERM=dumb. Piped output stays plain but keeps the markers, so state survives in logs.

# [*] info [+] did [=] already converged [-] warn, kept going [x] fatal
if [ -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=
fi
hdr() { 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; }
esc