PrintToVeraeTimeStamp/site/printit.verae.ai/fonts/READY-PACKAGE.md
George Lambert 0efe762a23 docs(cert): OFL fonts READY package + CERT-01 pixel checklist
- Add fonts/READY-PACKAGE.md: exact woff2/ttf names, OFL license steps,
  pixel-match checklist vs verae-2026-design CERT-01.html/png
- Cross-link README, LICENSE-FONTS, fetch-fonts.example.sh status
- certificate.html residual points at READY-PACKAGE (ops drop-in)

Software path unchanged; go test pdfcert + statuslang PASS.
Binaries remain operator deploy-host only (not committed).
2026-10-14 04:17:44 -04:00

159 lines
7.4 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.

# CERT OFL fonts — READY package
Operator drop-in package for self-hosted CERT-01 type on printit.verae.ai.
Software path is complete (`certificate.html` local-first probe, `pdfcert`
`EmbedBrandFonts` opt-in). This file is the **exact contract** for filenames,
license steps, and pixel-match sign-off against the CERT-01 design.
**Binaries are not committed.** Place OFL files on the deploy host (or
uncomment `fetch-fonts.example.sh` after license review), then run
`./fetch-fonts.example.sh --check`.
## Exact filenames under `fonts/`
Directory: `site/printit.verae.ai/fonts/` (this folder).
### Web viewer (required for local @font-face)
| File | Required | Used by | Notes |
|------|----------|---------|-------|
| `fraunces-opsz-wght-700.woff2` | **yes** | `certificate.html` title weight 700 | wOFF2 magic `wOF2`; variable or static subset OK |
| `fraunces-opsz-wght-600.woff2` | **yes** (`--check`) | weight 600 body/serif accents | same family name `Fraunces` |
| `jetbrains-mono-500.woff2` | optional | digest / mono rows | family `JetBrains Mono` |
| `OFL.txt` | **yes** | license beside binaries | upstream SIL OFL 1.1 text; keep copyright notices |
Probe order in `certificate.html` (must match names exactly):
```
fonts/fraunces-opsz-wght-700.woff2 → Fraunces 700
fonts/fraunces-opsz-wght-600.woff2 → Fraunces 600
fonts/jetbrains-mono-500.woff2 → JetBrains Mono 500
```
Do **not** rename after first production deploy — the head script HEADs these
paths only.
### PDF embed (optional; `EmbedBrandFonts` / `VERAE_EMBED_BRAND_FONTS`)
| File | Required | Used by | Notes |
|------|----------|---------|-------|
| `Fraunces-opsz-wght.ttf` (or any `*fraunces*.ttf`) | optional | `internal/pdfcert` `findBrandFaceFile` | Prefer name containing `fraunces`; else first `.ttf`, else first `.otf` |
| `*.otf` Fraunces | optional | same | Used only if no `.ttf` found |
| `OFL.txt` | **yes** if any face present | same as web | |
Override scan dir with `VERAE_BRAND_FONTS_DIR`. Default scan is this `fonts/`
directory (repo-relative). Default embed is **off** — core Times/Helvetica.
## License steps (operator)
1. Confirm faces are **SIL Open Font License 1.1 (OFL)** only — Fraunces and
JetBrains Mono are OFL upstream; do not drop proprietary faces here.
2. Obtain sources (pin a commit or release; do not track `main` blindly):
- Fraunces: https://github.com/google/fonts/tree/main/ofl/fraunces
or https://github.com/underscript-type/fraunces
- JetBrains Mono: https://github.com/google/fonts/tree/main/ofl/jetbrainsmono
or https://github.com/JetBrains/JetBrainsMono
3. Convert / subset to the **planned woff2 names** above (e.g. `fonttools` +
`woff2_compress`). Title glyphs only is enough for CERT web.
4. Copy upstream **`OFL.txt`** next to the binaries (never strip copyright).
5. Optional PDF: place a Fraunces `.ttf`/`.otf` (name containing `fraunces`
preferred) in this dir or `VERAE_BRAND_FONTS_DIR`; enable embed only when
intended (`VERAE_EMBED_BRAND_FONTS=1` or `Input.EmbedBrandFonts`).
6. Verify:
```sh
cd site/printit.verae.ai/fonts
./fetch-fonts.example.sh --check # exit 0 when required set present
# open ../certificate.html — Network: no fonts.googleapis.com if local hits
# Offline smoke: block fonts.googleapis.com / fonts.gstatic.com; title still Fraunces or Georgia
```
7. Deploy with the static site (`rsync` → `/var/www/printit.verae.ai/`). No HTML
edit required. Do not enable the example fetch script in CI.
See also: [`LICENSE-FONTS.md`](./LICENSE-FONTS.md), [`README.md`](./README.md),
[`fetch-fonts.example.sh`](./fetch-fonts.example.sh).
## Pixel-match checklist vs CERT-01 design
**Design source of truth (in order):**
| Asset | Absolute path (Verae-Projects) |
|-------|--------------------------------|
| HTML mock | `verae-2026-design/ui-designs/src/html/CERT-01.html` |
| PNG | `verae-2026-design/ui-designs/pngs/CERT-01.png` |
| PNG v1 | `verae-2026-design/ui-designs/pngs/CERT-01-v1.png` |
| Annotated | `verae-2026-design/ui-designs/pngs-annotated/CERT-01.png` |
| Live viewer | `apps/PrintToVeraeTimeStamp/site/printit.verae.ai/certificate.html` |
Compare live `certificate.html` (print CSS + screen) side-by-side with
`CERT-01.png` / the HTML mock. Check each row; mark pass only when measured.
### Geometry (design → live)
| Token | CERT-01 design | Live `certificate.html` | Pass? |
|-------|----------------|-------------------------|-------|
| Canvas / column | shadow **816×1056**; outer pad **30px** | `.wrap` max-width **816px**; pad **30px 16px 48px** | |
| Outer plum frame | `inset:22px`; border **1.5px** `var(--plum)`; radius 4px | double box-shadow plum 1.5px + gold 0.5px (equivalent frame) | |
| Inner gold frame | `inset:28px`; border **0.5px** `var(--gold)` | gold inner ring via inset shadow | |
| Content pad | **56px 64px** | `.sheet` padding **56px 64px** | |
| Logo height | **40px** | brand logo ~40px row | |
| Title block margin | **26px 0 18px** | `.title-block` **26px 0 18px** | |
| Title type | Fraunces **700 / 26px**; color `--ink` | `.title` Fraunces 700 (local or CDN); size aligned ~26–28px | |
| Subtitle | **12.5px** muted; margin-top 6px | `.subtitle` 12.5px | |
| Gold rule | **2px × 120px**; margin 14px auto 0 | `.rule` 2×120 | |
| Final banner | border **2px** `--ok`; radius **10px**; pad **12×16**; gap 12 | `.banner.final` same | |
| KV grid | cols **150px 1fr**; gap **10×16**; margin-top 20px | `.kv` aligned | |
| Mono digests | **11px** JetBrains Mono / mono stack | `.mono` 11px | |
| Verify row | flex; gap **22px**; margin-top **22px**; pad **16px**; radius 10 | `.verify` same | |
| QR box | **130×130** SVG; pad 4px; radius 6; ink border | `.qr` **130px**; live data-URL when final | |
| Footer | muted **10px**; absolute band ~top 930 in mock | `.legal` / footer strip | |
| Tokens | `--plum #531B59`, `--gold #C4A85A`, `--ink #1D1534`, ok greens | `brand/tokens.css` | |
### Type / fonts
| Check | Pass? |
|-------|-------|
| With planned woff2 present: Network tab has **no** `fonts.googleapis.com` / `fonts.gstatic.com` request for Fraunces | |
| Title glyph shapes match CERT-01 PNG (Fraunces, not Georgia) at 100% zoom | |
| Without woff2: CDN Fraunces loads; offline → Georgia/serif still legible; plum/gold frame kept | |
| Digests use mono stack; optional `jetbrains-mono-500.woff2` when present | |
| Print stylesheet: frame + serif title survive; QR print-safe (data-URL or SVG placeholder) | |
### Behavioral (not pure pixels)
| Check | Pass? |
|-------|-------|
| Final + digest → live QR data-URL (`setVerifyQR` / qrcode.js) | |
| Provisional / offline → SVG placeholder, no broken image | |
| Multihash / blake3 fields only when digests present (never invented) | |
| PDF path: `EmbedBrandFonts` default false; with TTF + flag, register or fail closed to Times | |
### Sign-off
```
Operator: ____________ Date: ________ Host: ________
./fetch-fonts.example.sh --check → exit 0
Side-by-side vs CERT-01.png: geometry ____ type ____ QR ____
Notes: ________________________________________________
```
**Status:** READY package complete (filenames + license + checklist). Pixel
sign-off and binary drop-in remain operator actions on the deploy host — not
git content.
## Tree after drop-in (example)
```
fonts/
.gitkeep
README.md
LICENSE-FONTS.md
READY-PACKAGE.md ← this file
fetch-fonts.example.sh
fraunces-opsz-wght-700.woff2
fraunces-opsz-wght-600.woff2
jetbrains-mono-500.woff2 (optional)
Fraunces[opsz,wght].ttf (optional PDF; any *fraunces*.ttf)
OFL.txt
```