Accessibility First Statusline - Claude Code Statuslines
WCAG-compliant accessible statusline with screen reader announcements, high-contrast colors, semantic labels, keyboard hints, and reduced motion support.
Open the source and read safety notes before installing.
Prerequisites
- Claude Code CLI installed and configured
- Bash shell available (bash 4.0+ recommended)
- jq command-line JSON processor (jq 1.6+ recommended for error handling)
- Terminal with ANSI color code support
- Screen reader software (optional, for accessibility features: NVDA, JAWS, VoiceOver, or Orca)
- Write access to /tmp directory (for token tracking and initialization markers)
Schema details
- Install type
- config
- Reading time
- 2 min
- Difficulty score
- 10
- Troubleshooting
- Yes
- Breaking changes
- No
- Script language
- bash
Script body
#!/usr/bin/env bash
# Accessibility-First Statusline for Claude Code
# WCAG 2.1 AA compliant, screen reader friendly, high contrast
# Read JSON from stdin
read -r input
# Extract values
model=$(echo "$input" | jq -r '.model // "unknown"')
dir=$(echo "$input" | jq -r '.workspace.path // "~"' | sed "s|$HOME|~|")
tokens=$(echo "$input" | jq -r '.session.totalTokens // 0')
# Check for PREFERS_REDUCED_MOTION environment variable
if [ "$PREFERS_REDUCED_MOTION" = "1" ]; then
# No animations, static display
animation=""
else
# Minimal indicator (not flashing)
animation="▪"
fi
# High contrast WCAG AA compliant colors
# Contrast ratio > 4.5:1 against black background
# Using basic ANSI colors for maximum compatibility
WHITE_BOLD="\033[1;37m" # Bright white (high contrast)
CYAN_BOLD="\033[1;36m" # Bright cyan (high contrast)
YELLOW_BOLD="\033[1;33m" # Bright yellow (high contrast)
RESET="\033[0m"
# Semantic labels (screen reader friendly)
LABEL_MODEL="Model:"
LABEL_DIR="Directory:"
LABEL_TOKENS="Tokens:"
# Build statusline with semantic structure
statusline=""
statusline+="${animation} " # Activity indicator (if motion enabled)
statusline+="${WHITE_BOLD}${LABEL_MODEL}${RESET} ${CYAN_BOLD}${model}${RESET} | "
statusline+="${WHITE_BOLD}${LABEL_DIR}${RESET} ${CYAN_BOLD}${dir}${RESET} | "
statusline+="${WHITE_BOLD}${LABEL_TOKENS}${RESET} ${YELLOW_BOLD}${tokens}${RESET}"
# Output for visual display
echo -e "$statusline"
# Screen reader announcement (stderr for assistive tech)
# Only announce on significant changes (every 1000 tokens)
token_threshold=$((tokens / 1000 * 1000))
if [ -f "/tmp/claude_statusline_last_tokens" ]; then
last_tokens=$(cat /tmp/claude_statusline_last_tokens)
else
last_tokens=0
fi
if [ $token_threshold -ne $((last_tokens / 1000 * 1000)) ]; then
# Announce to screen reader (ARIA live region style)
echo "Status update: Using $model in directory $dir. Token count: $tokens." >&2
echo $tokens > /tmp/claude_statusline_last_tokens
fi
# Keyboard navigation hint (on first run)
if [ ! -f "/tmp/claude_statusline_initialized" ]; then
echo "Accessibility mode enabled. Press Ctrl+C to interrupt, Tab for completion suggestions." >&2
touch /tmp/claude_statusline_initialized
fiFull copyable content
{
"statusLine": {
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"
}
}About this resource
Features
- WCAG 2.1 AA compliant high-contrast colors (4.5:1 ratio minimum)
- Screen reader announcements via stderr for assistive technology
- Semantic labels (Model:, Directory:, Tokens:) for context clarity
- Reduced motion support via PREFERS_REDUCED_MOTION environment variable
- Keyboard navigation hints for non-mouse users
- Threshold-based announcements (every 1000 tokens) to reduce noise
- Basic ANSI colors for maximum terminal compatibility
- No complex Unicode characters or Powerline glyphs
Use Cases
- Developers using screen readers (NVDA, JAWS, VoiceOver)
- Users with visual impairments requiring high contrast
- Teams enforcing WCAG accessibility compliance
- Vestibular disorder users needing reduced motion
- Keyboard-only navigation workflows
- Inclusive design standard for enterprise environments
- Testing accessibility of AI-assisted development tools
Requirements
- Claude Code CLI installed and configured
- Bash shell available (bash 4.0+ recommended)
- jq command-line JSON processor (jq 1.6+ recommended for error handling)
- Terminal with ANSI color code support
- Screen reader software (optional, for accessibility features: NVDA, JAWS, VoiceOver, or Orca)
- Write access to /tmp directory (for token tracking and initialization markers)
Configuration
{
"statusLine": {
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"
}
}
Examples
Enhanced Accessibility Statusline with Cost Tracking
Extended version with cost information and improved error handling
#!/usr/bin/env bash
# Enhanced Accessibility-First Statusline with Cost Tracking
# WCAG 2.1 AA compliant with additional metrics
input=$(cat)
# Safe extraction with defaults
model=$(echo "$input" | jq -r '.model.display_name // "unknown"')
dir=$(echo "$input" | jq -r '.workspace.current_dir // "~"' | sed "s|$HOME|~|")
tokens=$(echo "$input" | jq -r '.cost.total_tokens // 0')
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
# Reduced motion support
if [ "$PREFERS_REDUCED_MOTION" = "1" ]; then
animation=""
else
animation="▪"
fi
# WCAG AA compliant colors
WHITE_BOLD="\033[1;37m"
CYAN_BOLD="\033[1;36m"
YELLOW_BOLD="\033[1;33m"
GREEN_BOLD="\033[1;32m"
RESET="\033[0m"
# Build statusline with cost
statusline="${animation} "
statusline+="${WHITE_BOLD}Model:${RESET} ${CYAN_BOLD}${model}${RESET} | "
statusline+="${WHITE_BOLD}Dir:${RESET} ${CYAN_BOLD}${dir}${RESET} | "
statusline+="${WHITE_BOLD}Tokens:${RESET} ${YELLOW_BOLD}${tokens}${RESET} | "
statusline+="${WHITE_BOLD}Cost:${RESET} ${GREEN_BOLD}$${cost}${RESET}"
echo -e "$statusline"
# Screen reader announcement with cost
token_threshold=$((tokens / 1000 * 1000))
if [ -f "/tmp/claude_statusline_last_tokens" ]; then
last_tokens=$(cat /tmp/claude_statusline_last_tokens)
else
last_tokens=0
fi
if [ $token_threshold -ne $((last_tokens / 1000 * 1000)) ]; then
echo "Status: $model in $dir. Tokens: $tokens. Cost: $${cost}." >&2
echo $tokens > /tmp/claude_statusline_last_tokens
fi
Accessibility Statusline with Custom Announcement Threshold
Configurable announcement frequency for different screen reader preferences
#!/usr/bin/env bash
# Accessibility Statusline with Custom Announcement Threshold
# Allows configuration via environment variable
input=$(cat)
# Configuration: announcement threshold (default 1000 tokens)
ANNOUNCE_THRESHOLD=${STATUSLINE_ANNOUNCE_THRESHOLD:-1000}
model=$(echo "$input" | jq -r '.model.display_name // "unknown"')
dir=$(echo "$input" | jq -r '.workspace.current_dir // "~"' | sed "s|$HOME|~|")
tokens=$(echo "$input" | jq -r '.cost.total_tokens // 0')
# Reduced motion
if [ "$PREFERS_REDUCED_MOTION" = "1" ]; then
animation=""
else
animation="▪"
fi
# WCAG colors
WHITE_BOLD="\033[1;37m"
CYAN_BOLD="\033[1;36m"
YELLOW_BOLD="\033[1;33m"
RESET="\033[0m"
statusline="${animation} ${WHITE_BOLD}Model:${RESET} ${CYAN_BOLD}${model}${RESET} | ${WHITE_BOLD}Dir:${RESET} ${CYAN_BOLD}${dir}${RESET} | ${WHITE_BOLD}Tokens:${RESET} ${YELLOW_BOLD}${tokens}${RESET}"
echo -e "$statusline"
# Announcement with custom threshold
token_threshold=$((tokens / ANNOUNCE_THRESHOLD * ANNOUNCE_THRESHOLD))
if [ -f "/tmp/claude_statusline_last_tokens" ]; then
last_tokens=$(cat /tmp/claude_statusline_last_tokens)
else
last_tokens=0
fi
if [ $token_threshold -ne $((last_tokens / ANNOUNCE_THRESHOLD * ANNOUNCE_THRESHOLD)) ]; then
echo "Status update: $model in $dir. Tokens: $tokens." >&2
echo $tokens > /tmp/claude_statusline_last_tokens
fi
Accessibility First Statusline Installation Example
Complete setup instructions with directory creation and permissions
#!/bin/bash
# Installation script for Accessibility First Statusline
# Create statuslines directory
mkdir -p .claude/statuslines
# Download or create the script
cat > .claude/statuslines/accessibility-first-statusline.sh << 'SCRIPT_EOF'
#!/usr/bin/env bash
# Paste the full statusline script from the primary example above before running this installer.
SCRIPT_EOF
# Make executable
chmod +x .claude/statuslines/accessibility-first-statusline.sh
# Add to settings.json
if [ ! -f .claude/settings.json ]; then
echo '{"statusLine":{"type":"command","command":"$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"}}' > .claude/settings.json
else
# Merge with existing settings (requires jq)
jq '.statusLine = {"type":"command","command":"$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"}' .claude/settings.json > .claude/settings.json.tmp
mv .claude/settings.json.tmp .claude/settings.json
fi
echo "Accessibility First Statusline installed successfully!"
Troubleshooting
Screen reader not announcing status updates even though script outputs to stderr
Verify screen reader is configured to read stderr output. Test with: echo 'test announcement' >&2. Check that /tmp/claude_statusline_last_tokens file exists and updates correctly. Adjust announcement threshold (currently 1000 tokens) in script if announcements are too frequent or infrequent. Some screen readers require specific terminal emulator settings to read stderr.
Colors appear too dim or hard to read on terminal background despite WCAG compliance
WCAG contrast ratios assume black/dark background. For light backgrounds, invert color scheme: Use dark ANSI codes (30-37) instead of bright (90-97). Test contrast using WebAIM contrast checker or similar tool. Adjust ANSI color codes based on terminal theme. Check terminal color profile settings.
Animation indicator (▪) still showing even with PREFERS_REDUCED_MOTION=1 set
Set environment variable: export PREFERS_REDUCED_MOTION=1. Add to ~/.bashrc or ~/.zshrc for persistence. Verify with: echo $PREFERS_REDUCED_MOTION (should show 1). Restart Claude Code session after setting environment variable. Check that script is reading environment variable correctly.
Keyboard navigation hints appearing every session instead of just once
Check /tmp/claude_statusline_initialized file exists and persists. Verify /tmp is writable: touch /tmp/test && rm /tmp/test. On system reboot, /tmp clears - this is expected behavior. Move initialization marker to ~/.cache/claude-statusline/ for persistence across reboots. Check file permissions on /tmp directory.
Semantic labels (Model:, Directory:, Tokens:) making statusline too verbose or crowded
Labels are essential for screen readers but can be shortened: 'M:' instead of 'Model:', 'D:' for 'Directory:', 'T:' for 'Tokens:'. Balance visual brevity with semantic meaning. Test with screen reader first before removing labels. Consider using abbreviated labels that maintain semantic meaning.
jq command not found error when script executes
Install jq: macOS (brew install jq), Linux (sudo apt-get install jq or sudo yum install jq), or download from https://stedolan.github.io/jq/download/. Verify installation: which jq. Check PATH includes jq location. Use full path to jq if not in PATH: /usr/local/bin/jq or /usr/bin/jq.
Statusline not appearing in Claude Code interface
Verify script is executable: chmod +x .claude/statuslines/accessibility-first-statusline.sh. Check script outputs to stdout (not stderr for main display). Verify .claude/settings.json has correct statusLine configuration. Test script manually: echo '{"model":{"display_name":"Test"},"workspace":{"current_dir":"/test"}}' | ./accessibility-first-statusline.sh
Token count always shows 0 or incorrect value
Check JSON input structure: jq -r '.cost.total_tokens' should extract token count. Verify Claude Code is passing cost data in JSON. Use fallback: jq -r '.cost.total_tokens // 0' for missing values. Test JSON parsing: echo '$input' | jq '.cost' to inspect cost object structure.
- Features
- Use Cases
- Requirements
- Configuration
- Examples
- Enhanced Accessibility Statusline with Cost Tracking
- Accessibility Statusline with Custom Announcement Threshold
- Accessibility First Statusline Installation Example
- Troubleshooting
- Screen reader not announcing status updates even though script outputs to stderr
- Colors appear too dim or hard to read on terminal background despite WCAG compliance
- Animation indicator (▪) still showing even with PREFERS_REDUCED_MOTION=1 set
- Keyboard navigation hints appearing every session instead of just once
- Semantic labels (Model:, Directory:, Tokens:) making statusline too verbose or crowded
- jq command not found error when script executes
- Statusline not appearing in Claude Code interface
Source citations
Signals
Loading live community signals…
A short, calm digest of reviewed Claude resources. Unsubscribe any time.