Capitals
A small project about which letters we choose to make big.
Every letter you know comes in two sizes. A and a are the same letter wearing different clothes, and somewhere in your head is a rule that turns one into the other. I taught that rule to a small neural network — not as a lookup table of "A goes with a," but as a transformation you can point at any shape. Then I pointed it at shapes that have no capital at all. Draw something and see.
Try it
Draw a letter or type any character, and the model cases it both ways. Switch the casing style to run a single-script specialist instead of the generalist — draw a Latin a, pick Greek only, and watch it try to Hellenize it.
Everything runs in your browser. Nothing you draw is uploaded, stored, or seen by anyone but you.
Run it into the ground
Casing a letter once is tidy. Casing its own output over and over is where it gets strange: drag the slider and watch a letter get re-cased again and again. Keep pushing it one direction, or alternate up and down. Spoiler — almost everything ends up as the same gray ghost.
Casing across borders
Each single-script model learned casing from only one alphabet. So what happens when the Greek model capitalizes Armenian, or the Latin model shouts in Cyrillic? Pick an alphabet and a model and watch one script get dragged through another's idea of "bigger."
It learned the shape of "make it bigger"
Same letter, both cases — produced by the model, not looked up. The striking part: it works in alphabets you may not be able to read.
Trained on ~94,000 letter pairs rendered from 431 fonts across twelve bicameral scripts — never a single hand-labeled example.
The letters other languages kept
English dropped most of these, but other Latin-script languages still use them — and the model cases them correctly.
Push into letters extinct for centuries — long-s, wynn, yogh — and it stops knowing and starts improvising:
So what's the capital of a 3?
The question everyone asks. The honest answer is funnier than a trick: none of these have a capital or a lowercase, so the model mostly hedges — a nudge here, a thickening there. But a few it commits to (the 9 still insists its capital is a G). Here's every number and mark, pushed both ways.
The hall of the weird
I let the model loose on every letter, number, and mark, then ranked them by how violently it transformed each one. These are its strangest confident guesses.
Scripts with no capitals
Most of the world's writing systems never invented a capital/small distinction. Hand the model Japanese, Hebrew, Arabic, or Devanagari and it does the only honest thing: almost nothing. There's no bigger version to reach for, so it hands the glyph back.
Cursive throws it a curveball
Russian cursive is famously disorienting: lowercase т is written like an m, и like a u, п like an n. The model has to find the capital of a shape that looks like a completely different letter.
Fancy Latin script fonts are harder still — all those connected flourishes are far from the clean type it trained on, and it shows:
The two things everyone draws
Let's be adults about this. You put a drawing box on the open internet, and within about four seconds someone draws a swastika, and within five, a penis. It is as reliable as gravity.
So here is the section about them. There are no pictures in it. Not out of primness — the model would earnestly hunt for the capital of either one, and the result is honestly kind of funny — but because this page runs in your browser and shows only what you draw. Nothing you make here is uploaded, saved, or shown to anyone else, which means the one person who has to look at your swastika is you. Draw whatever you like. I just don't have to host it.
The grown-up version: there's no server in the loop, so there's nothing to moderate and nothing to leak. The box is a mirror, not a megaphone.
How it works
The part for the engineers in the room.
The data makes itself. Instead of collecting hand-drawn letters, I render both cases of every letter from thousands of fonts. Each font gives a perfectly matched, same-style pair — and in the same hand — across every alphabet with upper- and lowercase at once. Unicode's own case tables supply the ground truth, so the pairing is never guessed. ~94,000 clean pairs over 431 fonts and twelve scripts, generated in minutes.
It's a conditional U-Net. Image in, a direction flag (upper / lower), image out. Because it learns casing as an operation on pixels rather than a dictionary of letters, it applies to inputs it was never trained on — which is the whole reason a 3 produces anything at all. There are seven of them: a generalist trained on every script, plus specialists for Latin, Cyrillic, Greek, Armenian, and two cursive sets — which is what the "casing style" selector swaps between.
Honest testing. The validation set is split by font family, not by sample — each model is scored only on typefaces it never saw during training.
It runs on your phone. Trained on a laptop GPU, exported to ONNX, quantized to ~5 MB each, executed in your browser with onnxruntime-web. No server does any of the thinking — which is also why nothing you draw ever leaves your device.