fix: keep grapheme clusters whole in block cursor and gradient writer
Apply review findings: the textarea block-cursor overlay dropped only the final rune (splitting a flag or ZWJ family at a line end), and Buffer.SetStringGradient was the last per-rune writer (over-counting clusters and splitting glyphs). Both now operate on whole clusters. Also cross-document the deliberate graphemeExtend vs isZeroWidthRune split.