╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │907 .g = @intCast(@as(u16, c.g) * glyph_bg_brightness / 100), │ │908 .b = @intCast(@as(u16, c.b) * glyph_bg_brightness / 100), │ │909 }; │ │910 + } │ │911 + │ │912 + // terminals that don't support truecolor misparse a "38;2;r;g;b"/"48;2;…"│ │913 + // SGR as a list of plain SGR codes, so any channel value in 1..9 turns on│ │914 + // a text attribute (5/6 = blink, 7 = inverse, 8 = conceal, …). │ │915 + // snap such channels clear of that range so the backdrop doesn't blink or│ │916 + // hide text there; the ≤9/255 shift is imperceptible on terminals that │ │917 + // actually render truecolor. │ │918 + fn sgrSafe(color: ?Grid.Color) ?Grid.Color { │ │919 + const c = color orelse return null; │ │920 + const snap = struct { │ │921 + fn f(v: u8) u8 { │ │922 + return if (v >= 1 and v <= 9) 10 else v; │ │923 + } │ │924 + }.f; │ │925 + return .{ .r = snap(c.r), .g = snap(c.g), .b = snap(c.b) }; │ │926 } │ │927 │ │928 // composites ANSI art behind a foreground grid │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │949 const dst = &out.cells.items[idx]; │ │950 if (cellIsBlank(dst.*)) { │ │951 dst.* = src; │ │952 + dst.style.fg = sgrSafe(dst.style.fg); │ │953 + dst.style.bg = sgrSafe(dst.style.bg); │ │954 } else if (dst.style.bg == null) { │ │937 - dst.style.bg = dimColor(artCellColor(src.style)); │ │955 + dst.style.bg = sgrSafe(dimColor(artCellColor(src.style))); │ │956 if (dst.style.fg == null) dst.style.fg = glyph_fg_over_art;│ │957 } │ │958 } │ ╰────────────────────────────────────────────────────────────────────────────────────────╯