# Whisper visual-confusables (v1.0)

The **font-grounded** companion to Unicode UTS#39 `confusables.txt`.

Unicode's confusables list is font-*agnostic*: it records that two codepoints have
been confused *somewhere, by someone, in some typeface*. A browser is not agnostic
— it paints the address bar in one specific font. This dataset records which
codepoint pairs actually render to the **same pixels** in the three font stacks
browsers paint into the URL bar, measured pixel-by-pixel.

Generated 2026-06-14 · License **CC-BY-4.0** · Whisper Security ·
<https://lookalikes.labs.whisper.security>

## Files
- `visual-confusables.json` — canonical, machine-readable. 2402 pairs, each with
  the two codepoints, names, scripts, and a per-cell verdict `{tier, iou, composite}`.
- `visual-confusables.android-ofl.txt` — Chrome / Android (Roboto + Noto)
- `visual-confusables.apple-sf.txt` — Safari / macOS / iOS (San Francisco)
- `visual-confusables.segoe-ui.txt` — Edge / Windows (Segoe UI)

  The `.txt` files mirror the UTS#39 line format (`SOURCE ; TARGET ; TIER`), are
  **directed and non-closing** (no transitive closure — that is what reintroduces
  phantom edges), and carry a tier: `VS` = strict (near-identical), `VG` =
  at-a-glance (fools a quick read at URL-bar size).

## Why per cell
Of 2402 confusable pairs across the three stacks, only
400 are confusable in all three — the rest are
browser-conditional. A single font-agnostic verdict is wrong for one browser or
another most of the time, which is the whole point of shipping one file per cell.

## Provenance
Candidate pairs come from Unicode UTS#39 `confusables.txt` (Unicode 16.0,
2024-08-14, sha256 `95bd0aad6dced5eb…`); each is rendered
through the real fonts (HarfBuzz+FreeType / CoreText / DirectWrite) and kept only
if it collides as drawn. Method `phase1c-2026-06-12`. No font binaries
are included or redistributed — codepoints and scores only.
