Active Fedference treats the validated HTML manuscript as its canonical, accessibility-enhanced manuscript reading surface. Reveal.js is the paired accessibility-enhanced slide-reading surface: it retains semantic headings, keyboard navigation, responsive tables, figure alternatives and descriptions, high-contrast focus states, and a link to the complete HTML manuscript. The Beamer slide PDFs are explicitly untagged presentation derivatives; successful visual rendering does not promote them to the manuscript's tagged-PDF contract.
The combined manuscript PDF is generated through the source-controlled
LuaLaTeX/tagpdf path requested by metadata.tagged_pdf: true. Its release gate
requires pdfinfo to report Tagged: yes, qpdf JSON to expose a non-empty
catalog /Lang and a StructTreeRoot, and the source-bound language check to
pass. Some Poppler builds omit the language line from pdfinfo; that is why
the validator checks the PDF catalog as well. Figure alternatives are bound
from src/figures/_metadata.py through the figure registry.
Tagged structure is not the same as PDF/UA certification. A PDF/UA claim is allowed only when the retained veraPDF report and manual reading-order, keyboard, reflow/zoom, mathematical-content, and screen-reader checks pass. If those checks are not complete, the accurate status is “tagged PDF producer enabled; PDF/UA conformance not established.” The public v1.0.3 artifact may retain older surface properties; the published v1.0.4 artifact and its regenerated reviewer snapshot satisfy the repository's tagged-structure gate, while PDF/UA conformance remains unestablished.
This is a scoped engineering contract, not a declaration of WCAG conformance. The automated rules cover deterministic properties that this repository can enforce. A public accessibility claim still requires manual keyboard, screen-reader, zoom/reflow, contrast, reading-order, and mathematical-content review.
src/publication/web_package.py::validate_web_package fails every generated
HTML page unless it has:
- exactly one non-empty document language and title;
- exactly one focusable
<main id="main-content" tabindex="-1">landmark; - exactly one
.skip-linktargeting that landmark as the first interactive element; - a non-empty
altattribute on every image; - a
<figcaption>for every figure containing an image; - an
aria-labelon every full-size figure link; - no duplicate element identifiers;
- no missing local assets, broken fragments, raw typed references, or leaked figure Markdown.
These rules support the semantic structure, text alternatives, page language, page title, and bypass-block concerns in WCAG 2.2. The skip-link pattern follows the W3C G1 technique. Passing the checks does not establish WCAG A, AA, or AAA conformance because the validator does not determine alternative-text quality, contrast, meaningful sequence, keyboard usability, assistive-technology behavior, or whether visual encodings remain understandable without color.
Figure descriptions originate in manuscript captions and the figure registry,
not in generated HTML edits. Captions must identify the estimand, encodings,
units, uncertainty, source relation, and claim boundary without relying on
color alone. Complex figures additionally carry a structured
long_description; the HTML renderer places it in a labeled disclosure after
the caption while keeping the image's concise alternative distinct. Full-size
links name the figure and title rather than exposing a generic “open image”
label.
Seven quantitative figures also declare stable fig-values:* fallback
identifiers. Analysis derives their exact-value tables from the same typed
reports used for plotting and writes both machine-readable JSON and a
human-readable Markdown table under output/figures/. The figure registry must
bind every declared identifier to those artifacts. At release review, inspect
whether alternative, caption, long description, and exact table complement one
another without needless repetition in at least one screen reader.
qpdf --check, pdftotext, clean LaTeX logs, raster inspection, and
pdfinfo Tagged: yes answer important but different questions. They do not
prove PDF/UA reading order, table structure, or assistive-technology
interoperability. Tagged PDF supplies a semantic structure and figure
alternatives for those purposes; see the
PDF Association accessibility resources.
A source-current tagged manuscript PDF requires all of the following from the sibling rendering producer:
- the combined manuscript is produced from source, never post-hoc hand-edited;
- the source document language and title are present;
- figure alternatives are complete in the typed registry and bound to every embedded figure;
pdfinforeportsTagged: yes, qpdf exposes/Langand aStructTreeRoot, and the source-bound language check passes;- the source-bound render and release receipts are regenerated after any producer change.
Until the additional veraPDF and manual checks pass, publication prose must say “HTML accessibility-enhanced; tagged PDF structure verified, PDF/UA conformance not established,” not “fully accessible,” “WCAG conformant,” or “PDF/UA conformant.”
The opt-in render.slides.profile: accessible contract separately limits a
frame to 80 prose words and eight displayed table-body rows, reserves at least
70% of usable space for figure-led frames, and enforces 28/20/16-point floors
for titles, body text, and figure labels. It splits only at semantic block
boundaries and rejects uncomposable density rather than splitting equations,
lists, code, tables, or figures or silently reducing type. Reveal.js carries
the accessible reading affordances and links to the full manuscript; Beamer
remains a projection derivative. Passing these automated checks establishes
neither a WCAG conformance result for Reveal.js nor PDF/UA conformance for
either PDF surface.
Dense figures use source-owned presentation manifests selected by the
manuscript's data-slide-manifest attribute. The canonical portrait PNG/PDF
pair is retained. Each generator declares the complete ordered panel inventory;
the shared presentation saver records the smallest visible Matplotlib label in
pixels, binds it to the raster digest, checks a conservative design envelope,
and emits a typed manifest. The renderer independently checks actual PDF image
scale against the unchanged 16-point floor. The registry verifies both files in
each declared panel pair and every raster digest, while stage provenance binds
the source, manifest, and panel bytes. A successful subset is not a complete
figure-label audit: every required figure must have measured presentation
coverage before release. All required figure families implement this path,
and the manuscript selectors are checked against the declared manifest inventory.
Final source-bound production, embedded-label measurements, and complete PDF/HTML
visual inspection remain release gates.
Desktop browser checks also verify that no clipping ancestor hides the edges of widened figure images. A figure can fit within the viewport yet be cut off by a narrower prose container, so viewport-overflow checks alone are insufficient. The browser suite checks this separately from narrow-layout reflow, keyboard focus, full-size link names, and disclosure operation. Geometry is measured after MathJax typesetting, pending viewport reflow, fonts, and images have completed. A separate live-resize check moves an already rendered page between desktop, 200%, and 400% equivalent widths, verifying that equation numbers remain visible and the input mathematics is unchanged. Loading a page at a narrow width alone does not establish this behavior.
Run source validation first, then generate analysis, hydrate the manuscript, render through the sibling producer, prepare the web package, and execute:
uv run --locked python scripts/validate_web_package.py
uv run --locked python scripts/validate_rendered_surfaces.py
pdfinfo output/pdf/active_fedference_combined.pdf | grep '^Tagged:'
qpdf --json --json-stream-data=none output/pdf/active_fedference_combined.pdf \
| grep -Eq '"/(Lang|StructTreeRoot)"'
verapdf --format text --flavour ua2 \
output/pdf/active_fedference_combined.pdf > .tmp/verapdf-ua2.txtTreat the veraPDF command as a conformance probe, not as a pass by invocation;
inspect and retain its complete report. Finally perform the manual checks above
in a real browser and PDF reader. Record findings with the render receipt. Do
not repair generated files in output/; fix the manuscript, figure producer,
or sibling renderer and rerun the producer chain.