tui-designer
Skill17 starsChanged 4 months agoMITView on GitHub
Design and implement retro/cyberpunk/hacker-style terminal UIs. Covers React (Tuimorphic), SwiftUI (Metal shaders), and CSS approaches. Use when creating terminal aesthetics, CRT effects, neon glow, scanlines, phosphor green displays, or retro-futuristic interfaces.
- Reads credentials
- Installs packages
1 other project uses a version of this.
Other versions1 project uses a version of this.
Word for word · 1
- belentani7/manus-ai-skill-pack★ 0100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository60 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agent-browserSkill
- agent-engineeringSkill
- app-marketing-copySkill
- ascii-pixel-artSkill
- autopredictSkill
- autoresearchSkill
- babysit-prSkill
- bird-fastSkill
- blockchain-auditorSkill
- brainstormingSkill
- ceo-reviewSkill
- ck-reviewSkill
- cloudflare-managerSkill
- codex-advisorSkill
- content-trend-researcherSkill
- continuous-learningSkill
- coreml-optimizerSkill
- cto-reviewSkill
- direct-mail-strategistSkill
- evangelion-designSkill
- executing-plansSkill
- freshdesk-apiSkill
- gemini-image-generatorSkill
- gemini-visualSkill
- github-actions-templatesSkill
- googleSkill
- gsplat-optimizerSkill
- hyperagentSkill
- idea-mdSkill
- imagegenSkill
- ios-app-testerSkill
- llm-advisorSkill
- llm-evaluationSkill
- macos-appsSkill
- markdown-fetchSkill
- mcp-builderSkill
- mcp-testerSkill
- nano-bananaSkill
- opensea-apiSkill
- paperclipSkill
- playdate-devSkill
- poke-assistantSkill
- poplar-direct-mailSkill
- practical-typographySkill
- prompt-factorySkill
- qmdSkill
- scientific-critical-thinkingSkill
- security-best-practicesSkill
- security-threat-modelSkill
- seo-optimizerSkill
- shadertoySkill
- skill-finderSkill
- skimmableSkill
- subway-infoSkill
- systematic-debuggingSkill
- ui-designSkill
- video-editorSkill
- writing-plansSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
23 rules. About 0 are common, 13 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈13
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 12
Use this skill when:
- Distinctive: line 105
Terse and Direct: - Every word earns its place
- Distinctive: line 107
Mechanical Precision: - No hedging, apologies, or filler
- Very specific: line 513
Use will-change: transform for animated elements
- Very specific: line 514
Consider prefers-reduced-motion media query
- Distinctive: line 520
Test on older devices (A12 minimum for iOS 17)
- Distinctive: line 525
Consider lower resolution render targets for mobile
- Distinctive: line 560
Test on target terminals: iTerm2, Terminal.app, Windows Terminal, SSH Linux, Alacritty
- Very specific: line 562
Always reset attributes after styled text: \x1b[0m is your friend
- Very specific: line 582
Use viewport-relative units: vw, vh, or calc(100% - Xpx)
- Distinctive: line 584
Test at: 120 columns, 80 columns, 40 columns (mobile), ultra-wide
- Very specific: line 586
Use CSS @media or JS ResizeObserver to adapt layout dynamically
- Very specific: line 612
Use grapheme-aware libraries: Intl.Segmenter (modern), or graphemesplitter npm package
- Distinctive: line 616
Test on macOS (Command key), Windows (Alt), Linux (various WM behavior)
- Very specific: line 640
Use CSS @keyframes for continuous effects (GPU-accelerated)
- Very specific: line 643
Use will-change: transform, filter sparingly on elements that animate
- Distinctive: line 674
No focus indicators: After Tab-navigating to a button, there's no visible focus ring.
- Distinctive: line 679
Test with screen reader: VoiceOver (macOS), NVDA (Windows), JAWS
- Very specific: line 680
Add ARIA labels: aria-label="Start system", aria-describedby="help-text"
- Distinctive: line 681
Ensure 4.5:1 contrast ratio for text (WCAG AA standard)
- Distinctive: line 754
Use subtle scanlines: 10-15% opacity, visible but not interfering with text
- Very specific: line 757
Always provide prefers-reduced-motion escape hatch
- Distinctive: line 758
Test with actual users: "Can you read this comfortably?"
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
TUI Designer - Retro/Cyberpunk Terminal UI Expert
Expert guidance for designing and implementing text-based user interfaces with authentic retro computing aesthetics: CRT monitors, phosphor glow, scanlines, and cyberpunk neon.
When to Use This Skill
Use this skill when:
- Creating terminal-style or hacker aesthetic UIs
- Implementing CRT monitor effects (scanlines, glow, barrel distortion)
- Building cyberpunk/synthwave/retrowave interfaces
- Using Tuimorphic components in React
- Implementing Metal shaders for retro effects in SwiftUI
- Designing neon glow text and UI elements
- Choosing color palettes for retro computing aesthetics
- Working with monospace fonts and box-drawing characters
Design Principles
The Retro/Cyberpunk Aesthetic
This aesthetic draws from:
- CRT monitors: Phosphor glow, scanlines, screen curvature, flicker
- Terminal interfaces: Monospace fonts, box-drawing characters, green/amber text
- Cyberpunk fiction: Neon colors, dark backgrounds, high contrast
- 1980s computing: ASCII art, limited color palettes, blocky graphics
Visual Elements Checklist
- Dark background (near-black with subtle color tint)
- Monospace typography throughout
- Box-drawing characters for borders and frames
- Neon glow on text and/or borders
- Scanline effect (subtle horizontal lines)
- Limited color palette (1-3 accent colors)
- High contrast between text and background
- Optional: CRT curvature, chromatic aberration, flicker
Quick Reference: Color Palettes
Phosphor Green (Classic Terminal)
| Role | Hex | Usage |
| Bright | #00ff00 | Primary text, highlights |
| Medium | #00cc00 | Secondary text |
| Dark | #009900 | Dimmed elements |
| Background | #001100 | Main background |
| Deep BG | #000800 | Panel backgrounds |
Cyberpunk Neon
| Role | Hex | Usage |
| Cyan | #00ffff | Primary accent |
| Magenta | #ff00ff | Secondary accent |
| Electric Blue | #0066ff | Tertiary |
| Hot Pink | #ff1493 | Warnings |
| Background | #0a0a1a | Main background |
Amber CRT
| Role | Hex | Usage |
| Bright | #ffb000 | Primary text |
| Medium | #cc8800 | Secondary |
| Dark | #996600 | Dimmed |
| Background | #1a1000 | Main background |
See color-palettes.md for complete specifications.
Typography
Recommended Fonts
Web:
font-family: 'GNU Unifont', 'IBM Plex Mono', 'JetBrains Mono',
'SF Mono', 'Consolas', monospace;SwiftUI:
.font(.system(size: 14, weight: .regular, design: .monospaced))Box-Drawing Characters
Light: ─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼
Heavy: ━ ┃ ┏ ┓ ┗ ┛ ┣ ┫ ┳ ┻ ╋
Double: ═ ║ ╔ ╗ ╚ ╝ ╠ ╣ ╦ ╩ ╬
Rounded: ╭ ╮ ╰ ╯See typography-guide.md for complete reference.
Copywriting
Terminal interfaces have a distinct voice: terse, technical, authoritative. Use these defaults unless the project specifies otherwise.
Core Principles
- Terse and Direct - Every word earns its place
- Technical Authority - The system knows what it's doing
- Mechanical Precision - No hedging, apologies, or filler
Text Formatting
| Element | Case | Example |
| Headers/Titles | UPPERCASE | SYSTEM STATUS |
| Labels | UPPERCASE | CPU USAGE: |
| Status indicators | UPPERCASE | ONLINE, OFFLINE |
| Commands/Input | lowercase | > run diagnostic |
| Body text | Sentence case | Connection established |
Message Prefixes
[SYS] System message [ERR] Error
[USR] User action [WRN] Warning
[INF] Information [NET] NetworkVocabulary Quick Reference
| Action | Terminal Verbs |
| Start | INITIALIZE, BOOT, LAUNCH, ACTIVATE |
| Stop | TERMINATE, HALT, ABORT, KILL |
| Save | WRITE, COMMIT, STORE, PERSIST |
| Load | READ, FETCH, RETRIEVE, LOAD |
| Delete | PURGE, REMOVE, CLEAR, WIPE |
| State | Terminal Words |
| Working | PROCESSING, EXECUTING, RUNNING |
| Done | COMPLETE, SUCCESS, FINISHED |
| Failed | ERROR, FAULT, ABORTED |
| Ready | ONLINE, AVAILABLE, ARMED |
Common Patterns
> INITIALIZING SYSTEM...
> LOADING MODULES [████████░░] 80%
> AUTHENTICATION COMPLETE
> SYSTEM READY
ERROR: ACCESS DENIED
ERR_CONNECTION_REFUSED: Timeout after 30s
WARNING: Low disk space (< 10%)
CONFIRM DELETE? [Y/N]
SELECT OPTION [1-5]:Avoid
- "Please", "Sorry", "Oops"
- "Just", "Maybe", "Might"
- Excessive exclamation points
- Emoji (unless specifically requested)
See copywriting-guide.md for complete voice and tone reference.
Platform: React with Tuimorphic
Tuimorphic is a React component library providing 37 terminal-styled, accessible UI components.
Quick Start
npm install tuimorphicimport { Button, Card, Input } from 'tuimorphic';
import 'tuimorphic/styles.css';
function App() {
return (
<div className="theme-dark tint-green">
<Card>
<h1>SYSTEM ACCESS</h1>
<Input placeholder="Enter command..." />
<Button variant="primary">EXECUTE</Button>
</Card>
</div>
);
}Theme Configuration
Apply themes via CSS classes on a parent element:
// Dark mode with green tint
<div className="theme-dark tint-green">
// Light mode with cyan tint
<div className="theme-light tint-blue">Available tints: tint-green, tint-blue, tint-red, tint-yellow, tint-purple, tint-orange, tint-pink
Key Components
| Component | Usage |
Button | Actions with variant="primary|secondary|ghost" |
Input | Text input with terminal styling |
Card | Container with box-drawing borders |
Dialog | Modal dialogs |
Menu | Dropdown menus |
CodeBlock | Syntax-highlighted code |
Table | Data tables |
Tabs | Tabbed navigation |
TreeView | File tree display |
See tuimorphic-reference.md for complete API.
Adding Neon Glow
Enhance Tuimorphic with CSS glow effects:
/* Neon text glow */
.neon-text {
color: #0ff;
text-shadow:
0 0 5px #fff,
0 0 10px #fff,
0 0 20px #0ff,
0 0 40px #0ff,
0 0 80px #0ff;
}
/* Neon border glow */
.neon-border {
border-color: #0ff;
box-shadow:
0 0 5px #0ff,
0 0 10px #0ff,
inset 0 0 5px #0ff;
}
/* Flickering animation */
@keyframes flicker {
0%, 100% { opacity: 1; }
50% { opacity: 0.95; }
52% { opacity: 1; }
54% { opacity: 0.9; }
}
.flicker {
animation: flicker 3s infinite;
}Platform: SwiftUI with Metal Shaders
iOS 17+ supports Metal shaders directly in SwiftUI via .colorEffect(), .distortionEffect(), and .layerEffect().
CRT Effect Implementation
CRT.metal:
#include <metal_stdlib>
#include <SwiftUI/SwiftUI.h>
using namespace metal;
[[stitchable]] half4 crtEffect(
float2 position,
SwiftUI::Layer layer,
float time,
float2 size,
float scanlineIntensity,
float distortionStrength
) {
float2 uv = position / size;
// Barrel distortion
float2 center = uv - 0.5;
float dist = length(center);
float2 distorted = center * (1.0 + distortionStrength * dist * dist);
float2 samplePos = (distorted + 0.5) * size;
// Bounds check
if (samplePos.x < 0 || samplePos.x > size.x ||
samplePos.y < 0 || samplePos.y > size.y) {
return half4(0, 0, 0, 1);
}
// Sample color
half4 color = layer.sample(samplePos);
// Scanlines
float scanline = sin(position.y * 3.14159 * 2.0) * scanlineIntensity;
color.rgb *= 1.0 - scanline;
// Subtle color shift (chromatic aberration)
color.r *= 1.0 + 0.02 * sin(time * 2.0);
color.b *= 1.0 - 0.02 * sin(time * 2.0);
// Slight flicker
color.rgb *= 1.0 + 0.01 * sin(time * 60.0);
return color;
}SwiftUI View Modifier:
struct CRTEffectModifier: ViewModifier {
@State private var startTime = Date()
var scanlineIntensity: Float = 0.1
var distortionStrength: Float = 0.1
func body(content: Content) -> some View {
TimelineView(.animation) { timeline in
let time = Float(timeline.date.timeIntervalSince(startTime))
GeometryReader { geo in
content
.layerEffect(
ShaderLibrary.crtEffect(
.float(time),
.float2(geo.size),
.float(scanlineIntensity),
.float(distortionStrength)
),
maxSampleOffset: .init(width: 10, height: 10)
)
}
}
}
}
extension View {
func crtEffect(
scanlines: Float = 0.1,
distortion: Float = 0.1
) -> some View {
modifier(CRTEffectModifier(
scanlineIntensity: scanlines,
distortionStrength: distortion
))
}
}Usage:
Text("SYSTEM ONLINE")
.font(.system(size: 24, weight: .bold, design: .monospaced))
.foregroundColor(.green)
.crtEffect(scanlines: 0.15, distortion: 0.08)Neon Glow in SwiftUI
extension View {
func neonGlow(color: Color, radius: CGFloat = 10) -> some View {
self
.shadow(color: color.opacity(0.8), radius: radius / 4)
.shadow(color: color.opacity(0.6), radius: radius / 2)
.shadow(color: color.opacity(0.4), radius: radius)
.shadow(color: color.opacity(0.2), radius: radius * 2)
}
}
// Usage
Text("NEON")
.font(.system(size: 48, design: .monospaced))
.foregroundColor(.cyan)
.neonGlow(color: .cyan, radius: 15)See metal-shaders-ios.md for complete shader code.
Platform: CSS/Vanilla Web
Scanlines Overlay
.crt-container {
position: relative;
background: #000800;
}
.crt-container::after {
content: '';
position: absolute;
inset: 0;
background: repeating-linear-gradient(
0deg,
rgba(0, 0, 0, 0.15),
rgba(0, 0, 0, 0.15) 1px,
transparent 1px,
transparent 2px
);
pointer-events: none;
}Neon Text Effect
.neon-text {
color: #0ff;
text-shadow:
/* White core */
0 0 5px #fff,
0 0 10px #fff,
/* Colored glow layers */
0 0 20px #0ff,
0 0 30px #0ff,
0 0 40px #0ff,
0 0 55px #0ff,
0 0 75px #0ff;
}CRT Curvature (CSS Transform)
.crt-screen {
border-radius: 20px;
transform: perspective(1000px) rotateX(2deg);
box-shadow:
inset 0 0 50px rgba(0, 255, 0, 0.1),
0 0 20px rgba(0, 255, 0, 0.2);
}WebGL CRT with CRTFilter.js
<script type="module">
import { CRTFilterWebGL } from 'crtfilter';
const canvas = document.getElementById('crt-canvas');
const crt = new CRTFilterWebGL(canvas, {
scanlineIntensity: 0.15,
glowBloom: 0.3,
chromaticAberration: 0.002,
barrelDistortion: 0.1,
staticNoise: 0.03,
flicker: true,
retraceLines: true
});
crt.start();
</script>See crt-effects-web.md for complete techniques.
Effect Patterns
Scanlines
| Platform | Implementation |
| CSS | repeating-linear-gradient pseudo-element |
| SwiftUI | Metal shader with sin(position.y * frequency) |
| WebGL | Fragment shader brightness modulation |
Bloom/Glow
| Platform | Implementation |
| CSS | Multiple text-shadow with increasing blur |
| SwiftUI | Multiple .shadow() modifiers |
| WebGL | Gaussian blur pass + additive blend |
| Three.js | UnrealBloomPass with luminanceThreshold |
Chromatic Aberration
| Platform | Implementation |
| CSS | Three overlapping elements with color channel offset |
| SwiftUI | Sample texture at offset positions per RGB channel |
| WebGL | Sample UV with slight offset per channel |
Flicker
| Platform | Implementation |
| CSS | @keyframes animation varying opacity 0.9-1.0 |
| SwiftUI | Timer-driven opacity or shader time-based |
| WebGL | Time-based noise multiplier |
Performance Considerations
CSS Effects
box-shadowandtext-shadoware GPU-accelerated but expensive with many layers- Limit to 4-5 shadow layers for glow effects
- Use
will-change: transformfor animated elements - Consider
prefers-reduced-motionmedia query
SwiftUI/Metal
- Metal shaders run at 60-120fps on all devices supporting iOS 17+
.layerEffect()processes every pixel - keep shaders simple- Pre-compile shaders with
.compile()(iOS 18+) - Test on older devices (A12 minimum for iOS 17)
WebGL
- CRTFilter.js uses hardware acceleration, minimal performance impact
- Bloom effects in Three.js require render-to-texture passes
- Consider lower resolution render targets for mobile
General
- Reduce effect intensity on mobile devices
- Provide option to disable effects for accessibility
- Profile with actual content, not just empty screens
Templates
Ready-to-use starter files:
- react-tuimorphic-starter.tsx - React app with Tuimorphic
- swiftui-crt-view.swift - SwiftUI view with CRT effect
- crt-shader.metal - Complete Metal shader
- neon-glow.css - CSS neon effects
Common Pitfalls
This section documents real failure modes and edge cases that break TUI implementations. These are non-obvious gotchas discovered through practical use across platforms.
Terminal Compatibility Issues
Problem: Escape sequences vary across terminal emulators. What works in iTerm2 may fail in older xterm, SSH terminals, or Windows Terminal.
Common failures:
- 256-color vs ANSI: Terminals support different color depths. Code using
#rgbhex colors works in modern terminals but falls back to 16-color ANSI on older systems. - Reset sequences: Forgetting to reset text attributes (
\x1b[0mor\x1b[m) can poison the terminal state for subsequent output. - Unicode box-drawing on Windows: Windows PowerShell/Terminal may not render
─ │ ┌ ┐correctly. Test on Windows before shipping. - VT100 incompleteness: SSH to older Linux systems often hits VT100-only support. Box-drawing characters render as gibberish.
Prevention:
- Test on target terminals: iTerm2, Terminal.app, Windows Terminal, SSH Linux, Alacritty
- Fall back to ASCII when box-drawing fails: use
+,-,|as fallback - Always reset attributes after styled text:
\x1b[0mis your friend - Detect terminal capability: Check
TERMenv var (TERM=xterm-256colorvsTERM=xterm)
Example safe wrapper:
const supportsUnicode = process.env.TERM && process.env.TERM.includes('256');
const border = supportsUnicode ? '─' : '-';Layout Breaks on Resize
Problem: Fixed-width layouts collapse when terminal resizes. Common in web-based TUI where aspect ratio changes unexpectedly.
Common failures:
- Hardcoded line widths: A centered header assuming 80-column width breaks on a 60-column terminal.
- Overflow hidden without truncation: Content that's 100% width + padding exceeds container, causing text to spill or wrap unexpectedly.
- Aspect ratio assumptions: Scanline overlays, CRT curves assume 16:9. On ultra-wide or mobile, artifacts become obvious.
- Grid layouts with fixed items: Using
display: gridwithgrid-template-columns: 100px 200px 100pxfails to adapt to small screens.
Prevention:
- Use viewport-relative units:
vw,vh, orcalc(100% - Xpx) - Implement text truncation with ellipsis:
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - Test at: 120 columns, 80 columns, 40 columns (mobile), ultra-wide
- For scanline effects, use percentage-based frequency that scales with viewport
- Use CSS
@mediaor JSResizeObserverto adapt layout dynamically
Scanline example that fails:
/* ❌ Breaks on narrow screens */
background: repeating-linear-gradient(0deg, transparent, transparent 20px, black 20px, black 21px);Better approach:
/* ✅ Scales with viewport height */
background: repeating-linear-gradient(0deg, transparent, transparent calc(2% of height), black calc(2% of height), black calc(2% of height + 1px));Input Handling Edge Cases
Problem: User input isn't just alphanumeric. Real-world input includes multi-byte UTF-8, special keys, paste buffers, and autocomplete.
Common failures:
- UTF-8 character counting: JavaScript's
string.lengthcounts UTF-16 code units, not characters. A 4-byte emoji🎮haslength: 2, breaking cursor positioning and validation. - Paste buffer handling: Users paste large blocks of text. Input handlers without streaming cause UI to freeze.
- Arrow keys vs WASD: Terminal-based games assume WASD but users expect arrow keys. Missing support = bad UX.
- Special keys lost in translation: Ctrl+C, Ctrl+Z, Tab work differently across platforms. SSH terminals lose some meta-keys.
- IME composition: Input Method Engine (for Chinese, Japanese, Korean) sends partial characters before final composition. Validating on every keystroke breaks IME input.
Prevention:
- Use grapheme-aware libraries:
Intl.Segmenter(modern), orgraphemesplitternpm package - Implement paste as multi-character stream, not a single event
- Support both arrow keys AND WASD for navigation
- Handle IME: validate only on final
compositionend, notcompositionupdate - Test on macOS (Command key), Windows (Alt), Linux (various WM behavior)
Correct UTF-8 cursor positioning:
// ❌ Wrong: counts UTF-16 code units
const cursorPos = input.value.length; // "🎮🎮" = length: 4
// ✅ Correct: counts grapheme clusters
const segmenter = new Intl.Segmenter();
const cursorPos = [...segmenter.segment(input.value)].length; // "🎮🎮" = 2Performance Issues
Problem: TUI effects (scanlines, glow, flicker) are expensive. Naive implementations cause jank and CPU/battery drain.
Common failures:
- Continuous redraws: Updating DOM every frame via JS (not GPU) causes 60+ reflows per second. Leads to choppy animation, 100%+ CPU.
- Too many text-shadow layers: Each
text-shadow: 0 0 5px, 0 0 10px, 0 0 20px, ...requires a separate GPU pass. 10+ shadows = measurable lag. - Flickering at high frequency:
setInterval(..., 16ms)for flicker ties to animation frame time, causing stutter if main thread is busy. - Scanline overlay recompute: Recalculating
repeating-linear-gradienton every resize (without debounce) causes jank. - WebGL without throttling: Full-screen CRT shaders running at 120fps on low-end mobile = instant battery drain.
Prevention:
- Use CSS
@keyframesfor continuous effects (GPU-accelerated) - Limit neon glow to 3-4 text-shadow layers; test on mobile
- Debounce resize handlers:
ResizeObserverwith throttle, orwindow.requestAnimationFrame - Use
will-change: transform, filtersparingly on elements that animate - Provide reduced-motion option:
prefers-reduced-motion: reduce - On mobile, detect CPU capacity: throttle effects on low-power devices
Flicker that performs well:
/* ✅ GPU-accelerated, smooth */
@keyframes flicker {
0%, 100% { opacity: 1; }
50% { opacity: 0.95; }
}
.flicker { animation: flicker 3s infinite; }Flicker that causes jank:
// ❌ Main thread blocked, stutter
setInterval(() => {
element.style.opacity = Math.random() > 0.5 ? 1 : 0.9;
}, 50);Accessibility Gaps
Problem: Terminal UIs often ignore accessibility. Screen readers, keyboard navigation, color contrast all suffer.
Common failures:
- No keyboard navigation: Clickable elements only respond to mouse. Screen reader users and keyboard-only users are blocked.
- Color-only status indicators: Red text for error, green for success. Colorblind users (8% of males, 0.5% of females) can't distinguish.
- Missing ARIA labels: Screen readers announce "Button" instead of "Execute command". Confusing for blind users.
- Fixed-size text: Neon glow at 48px looks cool but breaks at 14px for visually impaired users. No zoom support = inaccessible.
- No focus indicators: After Tab-navigating to a button, there's no visible focus ring. Users lose their place.
- Animated elements without pause: Flicker and scanlines can trigger photosensitive epilepsy. Missing
prefers-reduced-motionsupport = legal/safety risk.
Prevention:
- Implement full keyboard navigation: Tab/Shift+Tab, Enter to activate, Arrow keys for lists
- Test with screen reader: VoiceOver (macOS), NVDA (Windows), JAWS
- Add ARIA labels:
aria-label="Start system",aria-describedby="help-text" - Ensure 4.5:1 contrast ratio for text (WCAG AA standard)
- Provide
prefers-reduced-motionalternative: disable flicker, scanlines, animations - Focus indicators:
:focus { outline: 2px solid #0ff; }is mandatory
Accessible neon button:
<button
aria-label="Execute diagnostic"
className="neon-button"
onClick={handleClick}
onKeyDown={(e) => e.key === 'Enter' && handleClick()}
>
EXECUTE
</button>
<style>
.neon-button:focus {
outline: 2px solid #0ff;
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
.neon-button {
text-shadow: none; /* Remove glow */
animation: none; /* Remove flicker */
}
}
</style>Terminal Emulator Differences
Quick reference for platform-specific behaviors:
| Emulator | Notable Quirks | Fix |
| iTerm2 (macOS) | Renders all Unicode correctly; true-color support | None needed |
| Terminal.app (macOS) | Limited color palette; older xterm behavior | Test with 256-color mode |
| Alacritty | Ultra-fast; true-color; may not render some Unicode | Works reliably if iTerm2 works |
| Windows Terminal | Supports true-color; WSL integration works well | None needed for modern code |
| PowerShell | Old versions render box-drawing as ?; use fallback | Check $PSVersionTable |
| SSH/xterm | VT100 only; no true-color; no mouse events | Fall back to ASCII + ANSI colors |
| Tmux | Passthrough mode required for true-color: set -g default-terminal "tmux-256color" | Configure tmux.conf |
| Screen | Even older terminal support; avoid fancy effects | Use ASCII-only mode |
Platform detection example:
if [[ "$TERM" == "xterm" ]]; then
# Old terminal: use ASCII
BORDER="+"
COLORS="ANSI"
elif [[ "$TERM" == *"256color"* ]]; then
# Modern terminal: use box-drawing + 256 colors
BORDER="─"
COLORS="256"
else
# Unknown: default to safe
BORDER="+"
COLORS="ANSI"
fiWhen CRT Effects Backfire
Problem: Scanlines, glow, and distortion look cool in mockups but cause problems in practice.
Common failures:
- Scanlines reduce readability: Fine horizontal lines over text make it harder to read, especially on mobile or at distance. People with low vision can't read it.
- Glow hides text: Heavy neon glow (
text-shadowwith 10+ layers) blurs text edges, reducing legibility. - Barrel distortion breaks alignment: CRT curvature looks authentic but makes content appear misaligned. Users think UI is broken.
- Flicker induces motion sickness: Subtle flicker causes nausea in some users. Photosensitive epilepsy is a real safety concern.
Prevention:
- Use subtle scanlines: 10-15% opacity, visible but not interfering with text
- Limit glow intensity: if glow radius > 20px, text becomes unreadable
- Distortion is decorative only: never use it for critical layout
- Always provide
prefers-reduced-motionescape hatch - Test with actual users: "Can you read this comfortably?"
Resources
Libraries
- Tuimorphic - React terminal UI components
- Inferno - Metal shaders for SwiftUI
- CRTFilter.js - WebGL CRT effects
- @react-three/postprocessing - React Three.js effects
Documentation
Inspiration
- SRCL / Sacred Computer - Design influence for Tuimorphic
- Cool Retro Term - Terminal emulator with CRT effects
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

