Marcelo Paiva
A man seen from behind holds a magnifying glass up toward a framed picture, surrounded by swirls and dots.Meant to show: A developer with low vision reading a terminal through a magnifier, a reader nobody measured that screen for.

Is a terminal a user interface?

We argued for twenty years that screens should be readable, then moved our working day into one nobody ever measured.

Take a terminal palette where the "helpfully de-emphasized" output sits at 2.1:1 against its background. WCAG 1.4.3 asks for 4.5:1 on body text, and this is software that runs for eight hours a day.

We've spent twenty years making one argument, which is that a screen someone has to read must be readable by the people who have to read it. We made it about web pages, then about apps, and then about documents, email and dashboards.

Somewhere in the middle of that, an enormous amount of professional work moved into a black rectangle full of low-contrast gray text, and almost nobody carried the argument across.

A terminal is a user interface and it has readers with low vision, though hardly anyone is saying so.

A default theme leaves real people out

I want to start with a specific person, because "accessibility issue" is a phrase that lets everyone stay comfortable.

Picture a developer with low vision, or a designer with astigmatism reading dim text at the end of a long day. It could be anyone whose contrast sensitivity is ordinary rather than excellent.

The second-order effect is the one that bothers me most. If the tools of a trade are only comfortable for people with a particular kind of eyesight, then fewer people can work in that trade.

Nobody decides that. It happens one default theme at a time. And since these are the tools we build everything else with, they decide who gets to do the building, so I can't file this under niche concerns.

Nobody is at fault either, and I want to say that plainly.

Coding agent tooling is roughly eighteen months old as a category, and its conventions are still soft. That covers keyboard behavior, focus, contrast and how a long-running job announces it has finished.

All of it is being decided now, mostly by people solving a hard problem who have never been asked to think about exclusion.

These are projects that would take a patch from anyone who turned up with one. Very few people take them up on it.

The order of the work mattered more than the code

Atomic (opens in a new tab) is an open-source coding agent runtime by Bastani.ai that turns an engineering process into explicit, checkable execution graphs.

I contribute accessibility to it, starting with the interactive theme, and the order I worked in turned out to matter more than the code. There were three passes, and the middle one is where I had it wrong.

The first was a contrast helper with a report-only baseline. I made it report-only on purpose, because turning a new gate on hard in someone else's project breaks their build on day one.

That teaches everyone to resent the gate, and the gate is the thing we're trying to keep. So measure first and publish the number, even if it's uncomfortable, and tighten after that.

I've watched well-intentioned accessibility work fail this way more than once. The work wasn't wrong, but it arrived as an obstacle before it arrived as information.

The second pass was a correction. My first version measured colors against an artificial canvas. It took a foreground hex and a background hex and computed the ratio, which is tidy, and is not what a terminal does.

A terminal theme is more than a set of colors in a file. It's what the terminal actually paints once a palette, a transparency setting, a dimming rule and a background have all layered on top of each other.

The number in the config and the light that reaches someone's eye are two different numbers. Contrast failures live in the gap between them, and the tool had been looking at the wrong side of it.

The third pass saved a baseline into the repository, so a change has to argue with it. Otherwise it's a number somebody ran once on their machine, in a week nobody remembers.

Terminals are not the only interface we exempt

Terminals are the clearest case, but they aren't the only one. Once you start looking, the list of interfaces we exempt from our own standards gets uncomfortable:

  • CI output, which people read under pressure when something has broken
  • Internal dashboards built in an afternoon
  • Error states in our own design tooling
  • Documentation sites with gray-on-gray code samples
  • The admin interfaces nobody demos

Every one of these has readers, and almost none of them have ever been measured.

They have one thing in common. We build them ourselves, for ourselves, and that's the assumption that hides exclusion. For us ends up meaning for people who work the way I do.

So internal tools belong in the standard too. If it has a reader, it has a contrast requirement, whatever the audit scope says.

What I'd carry over from the three passes is the order. Measure what renders, publish the number before you gate on it, and then commit it.

People don't ship inaccessible terminals because they don't care. They ship them because nothing in the toolchain ever mentioned that the contrast was 2.1:1.

The conventions of this category are still being written, and in a young category they're changed by whoever arrives with a working diff.

So pick one tool your team stares at all day, measure what it actually paints and turn up with the number.

About the drawing

The drawing for this piece was generated, not chosen. Hashing the piece’s name fixes one point on the color wheel; the other two follow from it. The same name always gives the same three colors.

#3a78ac#85396f#769d54

How this drawing was made

The line under the drawing marked “Meant to show” is written by a person, not the model. A generated drawing keeps what is large and loses what is small, so the detail that decides who someone is can go missing, and a picture only reaches people who can see it. Where the drawing and that line disagree, the line is the intent.

Or press the left arrow and the right arrow.