diff --git a/site/printit.verae.ai/certificate.html b/site/printit.verae.ai/certificate.html index 908e151..b55b586 100644 --- a/site/printit.verae.ai/certificate.html +++ b/site/printit.verae.ai/certificate.html @@ -258,7 +258,7 @@ Multihash / BLAKE3 lines appear only when data is present — never invented. Title uses Fraunces: local fonts/*.woff2 via @font-face when present, else Google Fonts CDN; Georgia/serif offline fallback. Plum/gold frame kept. Final certificates paint a live QR (qrcode.js CDN → data-URL) from the explorer lookup; offline / provisional keeps the SVG placeholder so print still works. - Residual: commit OFL woff2 binaries; full CERT-01.html pixel match; PDF Fraunces embed. + Operator drop-in: fonts/READY-PACKAGE.md (exact woff2 names + CERT-01 pixel checklist). PDF Fraunces only when EmbedBrandFonts + ttf.

diff --git a/site/printit.verae.ai/fonts/LICENSE-FONTS.md b/site/printit.verae.ai/fonts/LICENSE-FONTS.md index 3a6aa19..6eb0c77 100644 --- a/site/printit.verae.ai/fonts/LICENSE-FONTS.md +++ b/site/printit.verae.ai/fonts/LICENSE-FONTS.md @@ -24,5 +24,6 @@ When on, gofpdf may register a licensed `.ttf`/`.otf` from `VERAE_BRAND_FONTS_DI ## See also - [`README.md`](./README.md) — planned filenames, local-first probe, fetch example +- [`READY-PACKAGE.md`](./READY-PACKAGE.md) — exact names, license steps, CERT-01 pixel checklist - [`fetch-fonts.example.sh`](./fetch-fonts.example.sh) — commented upstream URLs only - OPEN-ISSUES #7 (CERT Fraunces pixel residual) diff --git a/site/printit.verae.ai/fonts/README.md b/site/printit.verae.ai/fonts/README.md index dc86bd1..c251744 100644 --- a/site/printit.verae.ai/fonts/README.md +++ b/site/printit.verae.ai/fonts/README.md @@ -17,6 +17,7 @@ Operators place OFL Fraunces themselves — see [`LICENSE-FONTS.md`](./LICENSE-F - [Usage](#usage) - [Background](#background) - [Planned filenames](#planned-filenames) +- [READY package](#ready-package) - [Fetch scaffold](#fetch-scaffold) - [Out of scope](#out-of-scope) - [Status](#status) @@ -80,8 +81,8 @@ Design source of truth: `verae-2026-design/ui-designs/src/html/CERT-01.html` (tokens `--font-serif: 'Fraunces'`; design-kit `src/fonts/` ships Cantarell + Material Symbols TTF only — **no Fraunces binary in-repo yet**). -**Not claimed:** full CERT-01.html pixel match, PDF Fraunces embed, or -production binaries in git. +**READY package claims:** exact filenames, license steps, pixel checklist. +**Not claimed in git:** production woff2/ttf binaries or operator pixel sign-off. ## Planned filenames @@ -98,6 +99,17 @@ fonts/ Exact names must stay stable once wired so deploys and the head probe match. +## READY package + +Full operator contract (exact names, license steps, CERT-01 pixel-match +checklist): [`READY-PACKAGE.md`](./READY-PACKAGE.md). + +Design paths for side-by-side: + +- `verae-2026-design/ui-designs/src/html/CERT-01.html` +- `verae-2026-design/ui-designs/pngs/CERT-01.png` +- `verae-2026-design/ui-designs/pngs-annotated/CERT-01.png` + ## Fetch scaffold [`fetch-fonts.example.sh`](./fetch-fonts.example.sh) — **example only**. @@ -116,21 +128,22 @@ operator uncomments a pinned-commit block after license review. | PDF CERT Fraunces embed | **EmbedBrandFonts default false**; when on, gofpdf registers first `.ttf`/`.otf` in `VERAE_BRAND_FONTS_DIR` or this dir (fail → log + Times). Node `build.mjs` stays core faces | | Inter / Material Symbols self-host for whole site | optional; CERT title is OPEN-ISSUES #7 residual | | Cantarell from design-kit TTFs | GNOME mock only; not required for CERT-01 web title | -| Pixel-perfect CERT-01.html match | Still later (OPEN-ISSUES Advanced) | +| Pixel-perfect CERT-01.html match | Operator sign-off via [READY-PACKAGE.md](./READY-PACKAGE.md) checklist | ## Status | Step | State | |------|-------| -| Placeholder dir + this plan | **Done** (L7) | -| `fetch-fonts.example.sh` placeholders | **Done** (TODO-7 A7) — no binaries fetched | -| Web cert spacing toward CERT-01 | **Closer** — not full pixel | +| Placeholder dir + this plan | **Done** | +| `fetch-fonts.example.sh` placeholders | **Done** — no binaries fetched by default | +| Web cert spacing toward CERT-01 | **Done** — CERT-01-ish geometry (see READY checklist) | | Local-first `@font-face` else CDN | **Done** — `certificate.html` probes `fonts/*.woff2` | | Drop-in docs (this README) | **Done** | -| woff2 binaries + OFL in git | **Not started** — operator drop-in only ([LICENSE-FONTS.md](./LICENSE-FONTS.md)) | +| READY package (names + license + pixel checklist) | **Done** — [`READY-PACKAGE.md`](./READY-PACKAGE.md) | +| woff2 binaries + OFL in git | **Operator** — not committed; deploy-host drop-in only | | `EmbedBrandFonts` default false | **Done** — opt-in env/option | | PDF gofpdf ttf/otf register attempt | **Done** — opt-in; no-op + log when missing/unsupported | -| Pixel match / OFL face in git | **Not started** — operator drop-in; do not claim full match | +| Operator pixel sign-off vs CERT-01.png | **Checklist ready** — sign-off on deploy host | ## Contributing diff --git a/site/printit.verae.ai/fonts/READY-PACKAGE.md b/site/printit.verae.ai/fonts/READY-PACKAGE.md new file mode 100644 index 0000000..2949a22 --- /dev/null +++ b/site/printit.verae.ai/fonts/READY-PACKAGE.md @@ -0,0 +1,159 @@ +# 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 +``` diff --git a/site/printit.verae.ai/fonts/fetch-fonts.example.sh b/site/printit.verae.ai/fonts/fetch-fonts.example.sh index 6bed79e..de6d66a 100755 --- a/site/printit.verae.ai/fonts/fetch-fonts.example.sh +++ b/site/printit.verae.ai/fonts/fetch-fonts.example.sh @@ -94,4 +94,4 @@ echo "2. Uncomment a curl block after license review." echo "3. Place woff2 + OFL.txt here; run: $0 --check" echo "4. Reload certificate.html — local @font-face auto-selects; CDN skipped." echo -echo "Status: drop-in ready — binaries not committed (OPEN-ISSUES #7 still left)." +echo "Status: READY package — see READY-PACKAGE.md; binaries not committed."