Phase 1: rendering reliability and accessibility - #2
Merged
Conversation
- Keep the fixed 1280×720 scaled canvas on narrow screens (scrollActivationWidth: null) instead of reveal 6's scroll view, which clipped two-column slides on portrait phones. - Reserve a real strip for a compact footer on shallow screens (max-height 560px) so the footer can no longer cover slide content; desktop rendering is unchanged. - Make the image lightbox fully keyboard-accessible: zoomable images are focusable controls (Enter/Space opens), the dialog focuses its close button, traps Tab, keeps arrow-key navigation and Escape-to-close, restores focus on close, and mirrors its visual state with inert/aria-hidden. French strings added. - Fix TOC modal semantics and behaviour: entries wrapped in <li>, focus moves into the dialog and is restored on close, arrow keys move between entries instead of driving the deck, aria-current marks the active entry, unused data-toc-part removed. - Promote stable per-talk components (.byline .role, .byline.authors, .author-logo, .demo-wrap/.demo-shot) into shared/theme.css and slim the per-deck style blocks; remove the dead .shot-todo component. - Fit engine: measure horizontal overflow too, keep centred layouts centred when fitted, expose the applied scale as data-fit, warn below 0.95 and stamp data-fit-fail below 0.90 (data-fit-allow opts out), re-fit after late-loading media, ?no-fit/?audit disables fitting; ?check now shows the fit scale. - Generic file embeds (data-embed-src, data-source-url, data-error-message) with accessible loading/failure states. - Centralise live-iframe lazy-loading + offline fallback in deck.js. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er
- talks/talks.json: structured manifest of published talks (slug, date, language, event, venue, titles, description, presenters, tags). - tools/build-index.py: render the landing page's talk list statically from the manifest (works without JavaScript), embed a JSON copy for the client-side enhancement, and verify sync with --check. - index.html: static talk list between generated markers, per-talk extras row (presenters, language, PDF, offline copy), search and language/year/topic filters with the state mirrored in the URL, static footer links, canonical URL and Open Graph metadata. - tools/audit.py: one-command repository audit — missing local assets, duplicate ids, missing alt/iframe titles, _blank links without noopener, manifest/folder/landing-page sync, stale placeholders and placeholder QR codes, orphaned and duplicate assets, and (with --site) notes-free publication builds. Non-zero exit on failure. - tools/browser-check.mjs: Playwright checks for every deck at 1280×720, 844×390 and 390×844 — console errors, auto-fit failures, raw overflow, footer overlap, scroll-view regression — plus representative template screenshots for visual regression. - tools/visual-diff.mjs: tolerant screenshot comparison (pixelmatch), failure diffs written for CI artifacts, nothing committed. - Rhodes deck: real QR code (was the template placeholder) and the restored cover QR block; resolved the remaining TODO. - Existing dense slides carry an explicit data-fit-allow so the new below-0.90 fit gate documents them instead of silently passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er
- tools/strip-notes.py rebuilt: publishes from an explicit allowlist (index.html, CNAME, .nojekyll, shared/, non-underscored talks/) instead of copying the whole repo; strips <aside class=notes> in any quoting/class-order/case/multiline form; removes the reveal notes plugin tag and never copies the plugin file; refuses a destination that contains the source; counters are per-build; asserts the finished artifact is notes-free. tools/test_strip_notes.py covers all of it (13 tests). - Slim syntax highlighting: fetch-highlight.py pinned to highlight.js 11.11.1 with a CDN fallback, node --check verification and a provenance record in shared/vendor-manifest.json (also records the vendored reveal.js 6.0.1). shared/highlight.min.js (40 KB) replaces the 921 KB bundled plugin, which is deleted; decks with code load the slim build, decks without code load nothing. - Lazy media: non-cover deck images use reveal's data-src, live iframes are lazified centrally by deck.js, and local raster images carry explicit width/height so layout and fit measurement are stable before load. - Asset cleanup: six unused files removed (logo-bayreuth.webp, archive-backroom.jpg, kb-map-choropleth.png, logo-gemini-wordmark-2025.svg, notebooklm-qr-small.png, eisener-estate.svg); the seven files duplicated across decks (Ewé OCR scan + transcript, Brief/Extended demo shots, GLAM-E report, IWAC MCP server shot, MCP logo) moved to shared/assets/ with all references updated. _site/ and node_modules ignored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er
- talks/_showcase: the full living layout catalogue (the former template), with a stable-vs-experimental component inventory in its header; never published (underscore folders stay out of the artifact). - talks/_template: reduced to a minimal starter — cover, section divider, one content slide, closing — pointing authors at the showcase and the tooling. - tools/new-talk.py: scaffold a talk in one command — safe dated slug, template copy, DECK_CONFIG/cover metadata fill (en/fr aware), manifest registration, landing-page regeneration, QR code to the canonical URL (qrcode package optional, graceful otherwise), refuses to overwrite, prints preview URL and next steps. - audit: template/showcase placeholder assets exempt from the duplicate-file warning. (4.1 shared components, 4.2 generic embeds and 4.4 the talk manifest landed with Phases 1–2.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er
- tools/export-pdf.mjs: notes-free slides.pdf per deck (reveal ?print-pdf, backgrounds on, page count verified against the slide count) plus a 1280×720 cover screenshot as each deck's social card; content-hash skip so unchanged decks reuse cached artifacts. - tools/build-offline.py: one self-contained offline.zip per talk — deck at the root with shared/ references rewritten, assets, engine, fonts, the PDF, a serve.py launcher and local-server instructions. - Per-deck metadata: meta description, canonical URL, Open Graph + Twitter card (og:image = the generated social card), locale, and schema.org PresentationDigitalDocument JSON-LD with presenters, event, language and date. new-talk.py injects the same block for future talks. (Landing-page search/filter landed with Phase 2.) - LICENSE.md: MIT for the repository code, CC BY 4.0 for slide text and original figures, with vendored software, fonts, logos and externally sourced images explicitly carved out. - THIRD_PARTY_NOTICES.md: full reveal.js MIT, highlight.js BSD and SIL OFL 1.1 texts (EB Garamond, Libre Franklin), plus the status of institutional logos and external images. - .github/workflows/pages.yml: validation on pull requests and pushes — strip-notes tests, audit (repo + built site, strict), landing-page sync, Playwright browser checks at the three standard viewports; engine-change-gated visual regression on PRs with diff artifacts; build job produces the allowlisted notes-free site plus PDFs/social cards (cached by content hash) and offline bundles; deploy runs only from main after validation. Job timeouts set; first-party actions referenced by version tag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er
- sitemap.xml (generated by tools/build-index.py, sync-checked in CI), robots.txt and a branded 404 page, all added to the publication allowlist; audit resolves root-absolute references against the site root. - Luxembourg SKILL.md embed carries data-source-url so its failure state links to the source repository; showcase QR labels use the canonical domain; landing-page extras row aligns with the number column on small screens. - README rewritten for the new workflow: manifest-driven landing page, new-talk.py scaffolding, showcase/template split, slim highlighting, fit diagnostics (?check / ?no-fit / data-fit-allow), the validating deploy pipeline with PDFs and offline bundles, local validation commands, and licence pointers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er
The visual job compared merge-base screenshots of talks/_template against the head — but this PR intentionally rewrote the template (catalogue → minimal starter), so the comparison measured the edit itself and failed on ~95% pixel diffs. The check is only meaningful when the shared engine changes while the photographed deck does not: - screenshots now capture talks/_showcase (the actual catalogue), falling back to _template on older trees; - the workflow runs the comparison only when shared/theme.css, deck.js or reveal/ changed AND the catalogue deck did not, emitting an explanatory notice otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
(scrollActivationWidth: null) instead of reveal 6's scroll view,
which clipped two-column slides on portrait phones.
(max-height 560px) so the footer can no longer cover slide content;
desktop rendering is unchanged.
are focusable controls (Enter/Space opens), the dialog focuses its
close button, traps Tab, keeps arrow-key navigation and
Escape-to-close, restores focus on close, and mirrors its visual
state with inert/aria-hidden. French strings added.
focus moves into the dialog and is restored on close, arrow keys
move between entries instead of driving the deck, aria-current
marks the active entry, unused data-toc-part removed.
.author-logo, .demo-wrap/.demo-shot) into shared/theme.css and slim
the per-deck style blocks; remove the dead .shot-todo component.
centred when fitted, expose the applied scale as data-fit, warn
below 0.95 and stamp data-fit-fail below 0.90 (data-fit-allow opts
out), re-fit after late-loading media, ?no-fit/?audit disables
fitting; ?check now shows the fit scale.
data-error-message) with accessible loading/failure states.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_0122f4bMszLPwGVSkuLHt3er