ca0ea881f4
W6a: Fix CJK/wide character width handling
- visual_width() now uses UnicodeWidthChar::width() instead of hardcoding 1
- count_wrapped_rows() iterates UTF-8 chars instead of raw bytes
- Control char fallback returns 0 (combining marks) instead of 1
W6b: Render bracket match flash highlight
- bracket_flash (computed but never rendered) now applies accent bg style
- push_rendered_text() accepts bracket_offsets + bracket_style params
- All 4 call sites updated (3 selection segments + 1 non-selection)
W6c: Add search wrap-around notification
- Editor: SearchState.last_wrapped field, 'Search wrapped' message on wrap
- Viewer: Search.last_wrapped field, flash_msg in footer_text
- Both find_next/find_prev and step() detect and report wrap
W6d: Editor status bar tab width indicator
- Added 'Tab:{}' to status_string showing current tab_width
- Hardcoded widget defaults verified as dead code (render_popup uses theme)
1381 tests pass, zero warnings.