How we build tools
Every tool on this site does its work inside your browser. Nothing you type is sent anywhere, and that is not a promise you have to take on faith: there is a test that fails the build if any tool page makes a network request it should not, and you can check the claim yourself in about ten seconds.
Check it yourself, in ten seconds
Open any tool on this site. Let it load, then turn off your wifi and use the tool. It keeps working.
Loading the page in the first place does need a connection. These tools run inside the page rather than being installed, so the promise is that nothing leaves your browser once you are there, not that the site is available with no network at all.
If you want to be stricter about it, open your browser's developer tools, go to the Network tab, and use the tool with the recording on. You will see the page and its assets load, and then nothing. No request goes out when you type, when you change an option, or when you copy a result.
That is the whole claim, and it is deliberately the kind of claim you can disprove. A privacy policy is a document. This is a behavior you can observe.
Two pages that make the check specific: is it safe to paste JSON into an online formatter and is it safe to use an online password generator. Once either tool page has loaded, the network tab should stay quiet when you paste or generate. The JSON formatter and the password generator are the tools those articles send you to.
The test that keeps it true
Claims decay. Someone adds a font from a CDN, or an analytics snippet, or a share button that phones home, and eighteen months later the sentence on the page is a lie that nobody meant to tell. So the claim is enforced by the build rather than by memory.
Every time this site is built, an automated check loads each page in a real browser, types a distinctive marker string into every input, clicks every button, and then inspects the network requests that session recorded on the document timeline. The build fails if:
- any page contacts a cross-origin server that is not on the published allowlist (disclosed hosts are named and counted; undisclosed ones fail the build);
- any page makes a background request at all after you interact with it;
- that marker string turns up anywhere in a request, in the address or the body;
- any link or form puts tool state into a query string, since query strings are sent to the server on every request.
On each tool page, the control strip's REQUESTS patch counts cross-origin entries from
the browser's Resource Timing API on the document timeline. That live count does not
include requests made inside a web worker, the final host after a redirect when only
the initial URL is recorded, or preconnect hints (Resource Timing does
not expose them). Worker and redirect coverage is tracked on the board as follow-up
work; the measured catch ratio on those shapes was three of six when last audited.
That last one is worth explaining, because it is the mistake this design nearly made.
Why share links use the part after the #
Several tools here let you share a configured link. When you copy a share link from the contrast grid, the palette travels in the URL. It looks like this:
benchvale.com/design/contrast-grid#p=131A22-1E5470-2FBFD0
Note the #. Everything after it is called a fragment, and browsers never
transmit it to a server. It exists only on your machine and on the machine of whoever
you send it to.
The obvious way to build that feature is a query string, with a ? instead
of a #. Every framework nudges you toward it and it works exactly the same
from the user's side. It is also wrong here, because a query string is sent to the
server with every single request. The moment anyone opened a shared link, the palette
would have arrived in a server log, and this page's central claim would have been
falsified by our own share button.
We caught that in review before anything shipped, and the build now refuses any navigation carrying a query string on a tool page. It is a small technical detail that decides whether the promise is real.
What we do load
A page here loads its own HTML, one small stylesheet, one font file, and for tool pages a small script. All of it is served from this domain. There is no CDN, no tag manager, no embedded widget, and no third-party font. Nothing is loaded from a server that is not ours or on the published allowlist, which means no other company learns that you visited unless we have named that host in advance.
The scripts are small on purpose. Every tool page ships under 100 KB of transferred JavaScript except the password strength checker, which may use up to 250 KB so it can score against a real leaked-password dictionary rather than a regex. The build fails on any page that exceeds its stated budget. The contrast grid stays small because a contrast ratio is six lines of arithmetic and does not need a framework; the budget gate compresses each served resource separately at the level measured on our host, matching what the Network panel exposes.
Where the math comes from
Anything that calculates says what it is calculating and where the rule comes from. We do not want you to trust the number, we want you to be able to check it.
Contrast ratios use the WCAG 2.2 definition, which is unchanged from 2.1 and 2.0. Each
color's relative luminance is computed from its sRGB channels, each channel is
linearized, and the three are weighted 0.2126 red, 0.7152 green, 0.0722 blue. The ratio
between two colors is (lighter + 0.05) / (darker + 0.05). The thresholds
are 4.5:1 for normal text and 3:1 for large text and interface graphics at AA, and 7:1
and 4.5:1 at AAA.
Where a tool has to make a judgment call rather than a calculation, it says so on the page rather than presenting a choice as a fact.
What the tools will not do
Some things are out of scope here even when a browser can do them. Optical character recognition on a scanned document can run in this tab, but a capable engine is a large download, and none of these tools has taken that into the JavaScript budget. A model too large to download still needs a server. We have not built any of those yet.
When we do, that tool will say plainly what leaves your device and where it goes, and the standing promise will not appear on its page. What will not happen is the promise quietly staying put while the behavior changes underneath it. A claim that is true on most pages is not a claim, it is a trap.
Accessibility
The first tool on this site checks WCAG contrast, so the site itself had better pass. Every build runs an automated accessibility audit against WCAG 2.2 A and AA, and fails on a violation. Every tool works from the keyboard, every input has a real label, and results are announced to screen readers when they change.
Automated auditing catches contrast, labels and roles. It does not catch whether the focus order makes sense or whether an interaction is actually usable without a mouse, so those are checked by hand. If something here does not work for you, please tell us. It goes in the changelog.
Errors
Tools have bugs. When one here produces a wrong answer, the fix and the date go in the changelog with a note about what was wrong, rather than being corrected silently. A tool that visibly gets fixed is a tool that is maintained.
We also correct ourselves in public where it matters. The contrast grid page describes a real failure in this site's own brand palette, with the real number, because it is the exact mistake the tool exists to catch and pretending we had never made it would make the page less useful.
How this site makes money
Advertising, eventually. There are no ads on the site today. When there are, they will sit below the tool and never above it, they will have a fixed reserved space so the page does not jump, and there will be none at all in the classroom projection modes.
Ads do not change the privacy claim about your input, because the tool still runs in your browser and your text still never leaves it. They do mean an advertising network will see that you loaded the page, which is a different thing, and the privacy page says so directly rather than burying it.
Last updated . Only changed when something material changed, which is why some of these dates are old.