From 56a4d909f566d8834f031e5ce69a846b48cf2bd3 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 5 May 2026 16:06:40 -0500 Subject: [PATCH] docs: add tool context and session handoff doc --- ada_tool_context.md | 184 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 ada_tool_context.md diff --git a/ada_tool_context.md b/ada_tool_context.md new file mode 100644 index 0000000..3a1b565 --- /dev/null +++ b/ada_tool_context.md @@ -0,0 +1,184 @@ +# 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 (100–900) — 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 55–110% | §703.5.4 | Canvas: rendered pixel widths. TTF: `hmtx` advance widths ÷ `sCapHeight` | +| Stroke weight 10–30% of height | §703.5.7 | Canvas: thinnest ink row scan. TTF: `usWeightClass` → stroke % mapping | +| Character spacing 10–35% | §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 + +``` + +**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 `` 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 |