
Unicode Color Accessibility
- 27 installs
- 50 repo stars
- Updated June 18, 2026
- josiahsiegel/claude-plugin-marketplace
Helps with ai & agent building tasks.
About
unicode-color-accessibility is a Claude Code skill for ai & agent building. It helps you ship faster with AI-assisted development.
- unicode-color-accessibility
- AI & Agent Building
- AI-coding skill
Unicode Color Accessibility by the numbers
- 27 all-time installs (skills.sh)
- Ranked #9,601 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill unicode-color-accessibilityAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 27 |
|---|---|
| repo stars | ★ 50 |
| Last updated | June 18, 2026 |
| Repository | josiahsiegel/claude-plugin-marketplace ↗ |
What it does
Helps with ai & agent building tasks.
Files
Unicode, Color, Accessibility, and Non-TUI Fallbacks
Use this skill when terminal output must be visually correct, readable, inclusive, and robust across fonts, locales, themes, and assistive technologies.
Text correctness rules
- Display width is not byte length, code point count, or user-perceived character count.
- Cursor movement and deletion should operate on grapheme clusters.
- Layout should measure printable text after stripping ANSI control sequences.
- Double-width characters, combining marks, emoji sequences, variation selectors, and zero-width joiners must be tested.
- Treat ambiguous East Asian width as narrow by default unless the target environment explicitly differs.
Visual design rules
- Use semantic roles: error, warning, success, info, muted, selected, focused, disabled.
- Do not encode meaning by color alone; pair color with text, shape, icon, or position.
- Provide ASCII fallback for box drawing, braille charts, block elements, emoji, and private-use icons.
- Avoid assuming Nerd Fonts or patched fonts.
- Support light and dark backgrounds, 16-color, 256-color, truecolor, and no-color modes.
Color preferences
Respect user and environment preferences:
NO_COLORdisables non-essential color.CLICOLOR,CLICOLOR_FORCE, andFORCE_COLORmay force color depending on ecosystem conventions.TERM=dumb, non-TTY output, and CI usually imply plain output unless overridden.- Provide explicit flags such as
--color=auto|always|never,--plain, and--ascii.
Accessibility requirements
- All functionality must be keyboard-operable.
- Focus indicators must be visible without relying on color alone.
- Avoid flashing more than three times per second.
- Allow spinner, animation, and live-region suppression for reduced motion, logs, and CI.
- Provide screen-reader friendly alternatives: plain prompts, line-oriented commands,
--json,--plain, or documented stdin/stdout workflows. - Use meaningful labels, stable ordering, and visible status messages.
Failure modes
| Symptom | Likely cause | Fix |
|---|---|---|
| Misaligned tables | byte length or ANSI counted as visible width | use ANSI-aware wcwidth/grapheme measurement |
| Cursor splits emoji | movement by code point | move by grapheme cluster |
| Borders look broken | font or width mismatch | provide ASCII mode and test common fonts |
| Error only shown in red | color-only meaning | add text/icon/label and contrast check |
| Screen reader unusable | full-screen repaint grid | provide non-TUI mode and line-oriented flows |
Reference files
references/text-measurement.md- Unicode width, graphemes, emoji, BiDi, and ANSI measurement.references/accessibility-fallbacks.md- Color policy, screen-reader alternatives, and inclusive UX checklist.
Accessibility and Fallback Reference
Accessible mode patterns
--no-tui: line-oriented interactive mode or direct CLI subcommands.--plain: no cursor control, minimal formatting, stable text order.--json: machine-readable state for scripts and assistive workflows.--color=never: no color dependency.--ascii: no box drawing, emoji, braille, or private-use icons.
Alternate flow contracts
Every full-screen workflow should have an equivalent plain or scriptable contract:
TUI action: select failed job, open detail, retry
Plain flow:
app jobs list --status failed --plain
app jobs show JOB_ID --plain
app jobs retry JOB_ID --confirm
JSON flow:
app jobs list --status failed --json
app jobs retry JOB_ID --json --confirmOutput contract examples:
# --plain
STATUS failed
JOB api-17
ERROR timeout waiting for db
NEXT_ACTION app jobs retry api-17 --confirm
# --json
{"status":"failed","job_id":"api-17","error":"timeout waiting for db","actions":[{"name":"retry","command":["app","jobs","retry","api-17","--confirm"]}]}Plain output should be stable, line-oriented, and free of cursor controls. JSON output should write machine-readable data to stdout and diagnostics to stderr.
Color and contrast
Semantic roles should map to theme-aware palettes. Check contrast for foreground/background pairs and meaningful borders or chart lines. Do not use dim text for required information. In no-color mode, preserve meaning with words, punctuation, alignment, or labels.
When designing custom palettes, perceptual color spaces such as OKLCH can help choose evenly spaced colors, but terminal output ultimately becomes user-theme RGB, 256-color indexes, or 16-color roles. Always test the final mapped colors. High-DPI displays can make glyphs sharper, but terminals still lay out in cells; do not design pixel-dependent UI.
No-color equivalence examples:
| Color UI | Accessible fallback |
|---|---|
| Red row for failed job | Prefix ERROR or FAILED; include failure count. |
| Green success check | Text OK or PASS; do not require icon. |
| Yellow warning border | Heading WARNING: and explanatory text. |
| Blue focused field | Text cursor, label Focused: Host, or visible brackets. |
| Dim disabled command | Append (disabled: requires selection). |
Cognitive and motion accessibility
Keep navigation stable, avoid surprise focus jumps, use clear labels, group related actions, and explain destructive consequences in plain language. Avoid flashing more than three times per second and allow spinners, progress animation, and live dashboard updates to be reduced or disabled.
Reduced-motion contract:
if --reduced-motion or CI or non-TTY:
spinner -> static "Loading..."
animated progress -> periodic line updates or final summary
live dashboard -> slower refresh or manual refreshScreen-reader reality
Many full-screen TUIs repaint a visual grid that screen readers cannot interpret well. The accessible solution is usually not more escape sequences; it is a parallel plain interface with the same core functionality.
Document discoverability in --help:
Accessibility:
--no-tui Use line-oriented prompts instead of full-screen UI.
--plain Print stable plain text with no cursor control.
--json Print machine-readable output for scripts.
--color=never Disable color.
--ascii Avoid Unicode drawing characters and emoji.Inclusive interaction checklist
- All actions reachable from keyboard.
- Help lists keybindings and non-TUI alternatives.
- Focus state is visible and textual where possible.
- Status and errors are announced in stable text regions or plain output.
- Animation can be disabled.
- Timeouts are avoidable or configurable.
- Destructive actions require confirmation that does not depend on color.
- Copy/export actions exist for content that may be hard to select from an alternate screen.
Text Measurement Reference
Width concepts
- Bytes: storage encoding, not visual width.
- Code points: Unicode scalar values, still not visual width.
- Grapheme clusters: user-perceived characters, useful for cursor movement and deletion.
- Cell width: terminal display columns, needed for layout.
A renderer usually needs both grapheme segmentation and width calculation.
UAX-to-implementation mapping
| Unicode spec | What it covers | TUI implementation use |
|---|---|---|
| UAX #9 Bidirectional Algorithm | Logical-to-visual ordering for RTL/LTR text | Keep data logical; test mixed RTL/LTR; avoid manual reordering unless you own BiDi rendering. |
| UAX #11 East Asian Width | Narrow, wide, fullwidth, ambiguous character classes | Feed width library decisions; default ambiguous width narrow unless target CJK environment says otherwise. |
| UAX #14 Line Breaking | Allowed line break opportunities | Wrap prose without splitting required clusters; combine with terminal cell width. |
| UAX #29 Text Segmentation | Grapheme, word, sentence boundaries | Cursor movement, deletion, selection, truncation boundaries. |
| Emoji data / variation selectors | Emoji presentation, ZWJ sequences, modifiers, flags | Keep emoji ZWJ/flag sequences intact; test terminal-specific width differences. |
Implementation pipeline:
input string
-> parse/remove ANSI controls into style spans
-> segment grapheme clusters (UAX #29)
-> assign display cell width per cluster (wcwidth/EAW/emoji policy)
-> wrap/truncate by accumulated cells (UAX #14 where wrapping prose)
-> render cells with style metadata, never counting escape bytesANSI-aware measurement
Strip or parse ANSI escape sequences before measuring visible text. Styled strings should preserve metadata separately where possible. Never let escape bytes contribute to table width, wrapping, truncation, or cursor position.
Styled truncation example:
input spans: [red "ERROR"], [plain ": database unavailable"]
limit: 12 cells
visible: "ERROR: datab"
output: SGR(red) "ERROR" SGR(reset) ": datab" SGR(reset)If truncating inside a styled span, close/reset the active style. If the parent style must continue after the truncated fragment, reset then reapply the parent style explicitly.
Test strings
Use these in unit, snapshot, and manual tests:
| Case | String | Expected concern |
|---|---|---|
| ASCII | abcXYZ123 | Width equals character count. |
| CJK | コンニチハ世界 | Most characters are 2 cells. |
| Fullwidth punctuation | ABC,:! | Fullwidth Latin/punctuation are wide. |
| Combining mark | e[0m[31m not recommended; é (e + U+0301) | One grapheme, usually 1 cell. |
| Precomposed | é | Same visual intent as combining form. |
| Emoji | 🙂 | Often 2 cells; terminals vary. |
| Emoji skin tone | 👍🏽 | One grapheme; do not split modifier. |
| ZWJ sequence | 👩💻 | One grapheme sequence; width varies but often 2 cells. |
| Family emoji | 👨👩👧👦 | Long ZWJ sequence; never truncate mid-sequence. |
| Flag | 🇺🇸 | Regional indicator pair; keep together. |
| Variation selector | ✈︎ ✈️ | Text vs emoji presentation can alter width. |
| RTL | abc שלום 123 | Logical storage with terminal/display BiDi behavior. |
| ANSI styled | \x1b[31mred\x1b[0m plain | Visible width excludes SGR. |
| Controls | safe\x1b[2Jspoof | Sanitizer must not execute ESC. |
| Ambiguous | ·Ω─ | Width may differ in CJK contexts. |
Double-width and zero-width cases
Test CJK ideographs, Hangul, fullwidth punctuation, combining accents, emoji with skin tone modifiers, zero-width joiner sequences, flag sequences, variation selectors, and private-use glyphs. Different terminals and fonts can disagree; keep fallbacks practical.
Truncation and wrapping
Truncate by grapheme and cell width, not bytes. Do not split a double-width glyph at the final column. When a styled string is truncated, close/reset styles safely. Wrapping should account for wide characters and preserve indentation semantics.
Pseudo-code:
truncate_to_cells(spans, limit):
out = []
used = 0
for span in spans:
for cluster in graphemes(span.text):
w = cell_width(cluster)
if used + w > limit: return close_styles(out)
out.append(cluster with span.style)
used += w
return close_styles(out)Line breaking and shaping
Unicode line breaking, grapheme segmentation, and terminal cell width are related but different. Wrapping should follow grapheme boundaries and avoid splitting combining sequences, emoji ZWJ sequences, flags, and double-width cells. Terminals generally do not expose full font shaping decisions to applications; ligatures and font-specific glyph substitution can change appearance without changing cell counts.
BiDi text
Keep text in logical order when possible and let terminal display behavior handle ordering. For full-screen cell renderers, test mixed LTR/RTL content and avoid manual reordering unless the application intentionally owns a BiDi strategy. If precise BiDi layout is required, document the strategy and test with UAX #9-style cases.
Symbol sets and fonts
Box drawing, block elements, braille patterns, powerline glyphs, Nerd Font icons, emoji presentation sequences, variation selectors, and private-use characters can render differently across fonts and terminals. Provide ASCII mode, avoid private-use icons for essential meaning, and test with common monospace fonts.