Files
ada-font-analyzer/ada_tool_context.md
T

185 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADA §703 Font Compliance Analyzer — CoWork Context
**Tool file:** `ada-font-analyzer.html`
**Version:** 1.0
**Status:** Active
**Owner:** Bryan Gilliom — Message Point Media
**Built in:** claude.ai (May 2026)
**Adoption target:** CoWork (CoWork session should register this as a Tool-type project in the Project Registry)
---
## Purpose
Standalone browser-based tool for MPM's design and content team. Evaluates fonts against the **2010 ADA Standards for Accessible Design, Chapter 7 (Signs), Section §703.5** — the governing standard for digital signage character legibility. Used to select and validate fonts before deploying to the ~2,000-display RDMC/OnSign.tv installed base.
This tool lives in the MPM Odoo Knowledge base, embedded via iframe in the ADA Signage Guidelines article at `https://portal.mpmedia.tv/knowledge/article/4638`.
---
## What the Tool Does
Three tabs, all self-contained in a single HTML file. No backend. No API keys. No dependencies. Runs entirely in the browser.
### Tab 1 — Browse Curated Fonts
- 25 hand-curated Google Fonts pre-evaluated against all five §703.5 criteria
- Filter by: All / Fully compliant / Transit-tested / Use with caution
- Each card shows: live font preview, compliance badge, per-criterion dot indicators, notes
- Actions per card: Select for download, View on Google Fonts (specimen page), Download TTF/OTF (GF ZIP endpoint)
- Sidebar: selected font list with per-item download/specimen links, "Download all selected" bulk action (opens GF ZIP per family with stagger)
### Tab 2 — Test a Google Font
- User types any Google Fonts family name; tool loads it via the CSS2 API
- Renders uppercase I and O to a hidden HTML5 canvas at 120px
- Pixel-scans bounding boxes to derive O:I proportion ratio and stroke-to-height ratio
- Scores against all five §703.5 criteria; shows pass/fail per criterion with measured values
- Weight selector (100900) — re-scores live when weight changes
- Light-on-dark preview panel for contrast testing
- Download link to Google Fonts ZIP for the tested family
- "Add to selected fonts" button carries result back to Tab 1 sidebar
### Tab 3 — Upload TTF / OTF File
- Drag-and-drop or file picker; accepts TTF, OTF, WOFF, WOFF2
- **For TTF/OTF:** parses the binary font file directly using a custom JS DataView parser — no library
- **For WOFF/WOFF2:** falls back to canvas-only measurement (WOFF decompression not implemented)
- Live preview rendered via FontFace API + blob URL
- Raw metrics table showing exact values from each font table, with source attribution (TTF table vs. canvas)
- Full §703.5 scoring identical to Tab 2 but using higher-accuracy table-derived measurements
---
## ADA §703.5 Criteria Implemented
| Criterion | Standard ref | How measured |
|---|---|---|
| Sans-serif, conventional form | §703.5.3 | Name heuristics + `OS/2 panose bFamilyType` + `fsSelection` |
| O:I width ratio 55110% | §703.5.4 | Canvas: rendered pixel widths. TTF: `hmtx` advance widths ÷ `sCapHeight` |
| Stroke weight 1030% of height | §703.5.7 | Canvas: thinnest ink row scan. TTF: `usWeightClass` → stroke % mapping |
| Character spacing 1035% | §703.5.8 | Condensed-variant name detection |
| No italic/script/decorative | §703.5.3 | `fsSelection` italic/oblique bits + `panose` family type + name table |
---
## TTF Binary Parser — Tables Read
The Tab 3 parser (`parseTTF()` function) reads these tables directly from the binary:
| Table | Fields extracted |
|---|---|
| `head` | `unitsPerEm` |
| `OS/2` | `usWeightClass`, `fsSelection`, `panose[10]`, `sCapHeight` (ver≥2) |
| `hhea` | `ascender`, `lineGap` |
| `cmap` | Format 4 Unicode map → glyph IDs for U+0049 (I) and U+004F (O) |
| `hmtx` | Advance widths for glyphs I and O |
| `name` | `nameID=1` (family name), `nameID=2` (subfamily) — both platform 3 (UTF-16BE) and platform 1 |
Parser is pure JS, self-contained in the HTML file. No external libraries.
---
## Architecture Decisions
**Single-file, no build step.** Everything — HTML, CSS, JS, data, parser — is in one `ada-font-analyzer.html` file. This is intentional: Odoo Knowledge iframe embedding requires a stable hosted URL to a single file. No bundler, no node_modules, no deployment pipeline needed.
**Google Fonts CSS2 API for preview loading.** Tab 2 loads fonts via `https://fonts.googleapis.com/css2?family=...&display=swap`. No API key required. The Google Fonts download ZIP endpoint (`https://fonts.google.com/download?family=...`) is used for all download links — same endpoint GF's own website uses.
**Canvas measurement accuracy.** ~±5%. Sufficient for screening; not appropriate as a final compliance certification for permanent physical signage. This is documented in the UI.
**TTF parser accuracy.** O:I ratio from `hmtx` is exact (within font-unit precision). Stroke weight from `usWeightClass` is a model-based estimate (±2-3%). Canvas pixel scan runs as a cross-check and both values are shown.
**No localStorage, no cookies, no external requests except Google Fonts.** Tool is privacy-safe for Odoo embedding.
---
## Curated Font List — Maintenance Notes
The 25 curated fonts are defined in the `FONTS` array in the JavaScript. Each entry:
```js
{
name: "Font Name", // Display name — must match Google Fonts exactly for GF links
style: "Humanist", // Typographic classification
cat: "Description", // Short category label shown on card
tags: ["best","transit"], // Filter tags: "best"=fully compliant, "transit"=transit-tested, "caution"=use with caution
compliance: { // Per-criterion pass/fail (drives dot indicators and badge)
style: true,
proportion: true,
stroke: true,
spacing: true,
form: true
},
notes: "...", // Notes shown on card — weight restrictions, O:I ratio, etc.
gf: "Font+Name" // URL-encoded family name for Google Fonts API/download links
}
```
**To add a font:** append an entry to the `FONTS` array. Use Tab 2 or Tab 3 to measure it first.
**To update compliance data:** edit the `compliance` object and `notes` string for that entry.
**Transit-tested badge:** assigned to fonts with known real-world deployment in public transit signage systems (Roboto, Open Sans, Inter, Work Sans, Noto Sans, Atkinson Hyperlegible, Montserrat). Not a formal certification — update based on documented deployments.
---
## Known Limitations & Planned Improvements
| Item | Notes |
|---|---|
| WOFF/WOFF2 binary parsing | Not implemented — requires inflate/brotli decompression. Falls back to canvas. Future: add pako.js for WOFF2 support. |
| Google Fonts full catalog scan | The 25 curated fonts are a hand-selected subset of ~1,500+ GF fonts. A full programmatic scan would require the Google Fonts Developer API key + font file metric extraction pipeline. Candidate for a separate CoWork tool. |
| Line spacing check (§703.5.9) | Not currently measured. Requires rendering multi-line text and measuring baseline-to-baseline distance. Planned. |
| Weight-specific compliance | Currently the `compliance` object reflects worst-case (light weights). Could be enhanced to show per-weight compliance table. |
| OTF CFF table support | The TTF parser reads `hmtx`/`cmap` which also exist in OTF. CFF-flavored OTFs (PostScript outlines) may have glyph metrics in the `CFF ` table instead — parser falls back to canvas gracefully. |
| Odoo iframe sizing | At narrow viewport widths the two-column layout collapses to single column. Test at your iframe width. |
---
## Embedding in Odoo Knowledge
The tool is designed to be embedded as an iframe in the ADA Signage Guidelines Knowledge article.
```html
<iframe
src="https://git.alwisp.com/jason/ada-font-analyzer/raw/branch/main/ada-font-analyzer.html"
width="100%"
height="900px"
frameborder="0"
style="border-radius:8px;">
</iframe>
```
**Hosting options:**
1. Gitea raw file URL (CoWork-native, recommended) — `https://git.alwisp.com/jason/ada-font-analyzer/raw/branch/main/ada-font-analyzer.html`
2. MPM server / CDN static file host
3. Odoo attachment with direct URL (check if Odoo serves raw attachment files)
The file has no cross-origin dependencies other than `fonts.googleapis.com` and `fonts.gstatic.com`, both of which are public CDN resources.
---
## Session Handoff Instructions
When starting a CoWork session to maintain or extend this tool:
1. **Read this file first** to understand scope, architecture, and current limitations
2. **Load the HTML file** — from Gitea: `https://git.alwisp.com/jason/ada-font-analyzer/raw/branch/main/ada-font-analyzer.html`
3. **Key functions to know:**
- `parseTTF(buffer)` — binary font table parser, returns `{tables, metrics, errors}`
- `canvasMeasure(fontName, weight)` — canvas pixel scan, returns `{oiRatio, strokePct}`
- `renderScoreUI(...)` — shared scoring renderer used by both Tab 2 and Tab 3
- `FONTS[]` — curated font data array
- `renderGrid()` — re-renders Tab 1 grid from current filter/search state
4. **Do not add external library dependencies** without updating this context file
5. **Test all three tabs** after any change — they share the canvas element and score renderer
6. **Update the version number** in the `<title>` tag and in this context file when making changes
7. **Register this project in the CoWork Project Registry** if not already done — Type: Tool, Owner: Bryan Gilliom
---
## Change Log
| Date | Version | Change | Session |
|---|---|---|---|
| 2026-05-05 | 1.0 | Initial build — three tabs: Browse curated fonts, Test Google Font, Upload TTF/OTF. Binary TTF parser, canvas cross-check, GF download links. | claude.ai |
| 2026-05-05 | 1.0 | Registered as CW-005 in CoWork Project Registry. Gitea repo created. Drive coordination folder created. | CoWork |