- 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).
7.4 KiB
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)
- Confirm faces are SIL Open Font License 1.1 (OFL) only — Fraunces and JetBrains Mono are OFL upstream; do not drop proprietary faces here.
- Obtain sources (pin a commit or release; do not track
mainblindly): - Convert / subset to the planned woff2 names above (e.g.
fonttools+woff2_compress). Title glyphs only is enough for CERT web. - Copy upstream
OFL.txtnext to the binaries (never strip copyright). - Optional PDF: place a Fraunces
.ttf/.otf(name containingfrauncespreferred) in this dir orVERAE_BRAND_FONTS_DIR; enable embed only when intended (VERAE_EMBED_BRAND_FONTS=1orInput.EmbedBrandFonts). - Verify:
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
- 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, README.md,
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