07 · Accessibility & EPUB
← Docs home · Task: run the accessibility gate, server-render math, and build/validate an EPUB edition.
Source of truth: plan
docs/plans/2026-05-24-accessibility-and-epub-target.md; scripts inscripts/workflows/(a11y_audit.{py,mjs},katex_ssr.mjs,epub_build.py,epub_audit.py). Phase 2 is shipped; Phase 3 (Media Overlays) awaits a decision.
These run as scripts (no dedicated skill yet) — invoke them directly.
Accessibility gate (axe-core)
python scripts/workflows/a11y_audit.py # or: node scripts/workflows/a11y_audit.mjs
Checks alt text, ARIA labels, color contrast, and heading hierarchy against
axe-core. Report lands under _workspace/a11y_audit/. Tests:
scripts/workflows/a11y_audit.test.mjs.
The pages also support landmark patching helpers used at assemble/publish time:
patch_assembled_main_landmarks.py, patch_th_aria_labels.py.
What the reader gets (page chrome)
OpenDyslexic / Atkinson Hyperlegible / Lexend fonts, font-size control, dark mode, page search, language translate, and a read-aloud stack that speaks math correctly: Speech Rule Engine (MathML → MathSpeak) + kokoro-js neural TTS (Heart / Michael voices) + a System-default fallback, all client-side via transformers.js (WASM).
KaTeX server-side rendering
node scripts/workflows/katex_ssr.mjs # tests: katex_ssr.test.mjs
Pre-renders KaTeX math to static HTML so the math is present without JS — required for EPUB (offline) and better for indexing. (KaTeX is the Calculus math renderer; Stats / Finite Math use MathJax client-side.)
EPUB build & audit
# Build an EPUB for a section/chapter
python scripts/workflows/epub_build.py --project "Calculus Volume 1" --section 3.1
# Validate it (DAISY ACE)
python scripts/workflows/epub_audit.py <path-to.epub>
The builder assembles SSR’d HTML + images into a valid .epub; the audit runs
ACE for compliance. Baseline achieved: Calculus Chapter 3 EPUB passes ACE
with 0 critical / 0 serious / 0 moderate. Build/audit tests:
epub_build_test.py. After building, a manual Thorium smoke-read is the final
check (procedure in the plan).
The page’s “Save Offline” button is a browser HTML download — not the EPUB. The EPUB is the separate, validated artifact produced by
epub_build.py.
Status
Per project memory (A11y + EPUB Phase 2 shipped): axe-core HTML gate, KaTeX SSR, EPUB builder, and ACE gate are all in place. Phase 3 — Media Overlays (read-along highlighting in EPUB) is designed but awaits a go decision.