diff --git a/book/quarto/config/_quarto-html-vol1.yml b/book/quarto/config/_quarto-html-vol1.yml
index 7999578db5..861660b8a0 100644
--- a/book/quarto/config/_quarto-html-vol1.yml
+++ b/book/quarto/config/_quarto-html-vol1.yml
@@ -22,6 +22,7 @@ project:
post-render:
- scripts/clean_svgs.py
- scripts/resolve_cross_references.py
+ - scripts/fix_lightbox_paths.py
# Render-truth backstop: fail the build if any unresolved `?@xxx-yyy`
# literal survives the resolve-cross-references pass. See script header.
- scripts/verify_rendered_xrefs.py
diff --git a/book/quarto/config/_quarto-html-vol2.yml b/book/quarto/config/_quarto-html-vol2.yml
index d4395bb0cc..ecca3d3fb9 100644
--- a/book/quarto/config/_quarto-html-vol2.yml
+++ b/book/quarto/config/_quarto-html-vol2.yml
@@ -22,6 +22,7 @@ project:
post-render:
- scripts/clean_svgs.py
- scripts/resolve_cross_references.py
+ - scripts/fix_lightbox_paths.py
# Render-truth backstop: fail the build if any unresolved `?@xxx-yyy`
# literal survives the resolve-cross-references pass. See script header.
- scripts/verify_rendered_xrefs.py
diff --git a/book/quarto/scripts/fix_lightbox_paths.py b/book/quarto/scripts/fix_lightbox_paths.py
new file mode 100644
index 0000000000..124077dd9c
--- /dev/null
+++ b/book/quarto/scripts/fix_lightbox_paths.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+"""
+Post-render step: fix lightbox hrefs for mediabag SVGs.
+
+Quarto's lightbox feature generates for images stored in
+the mediabag directory, but the actual file lives at
+chapter_files/mediabag/HASH.svg. The
inside the anchor is correct;
+only the lightbox href is wrong. This causes a 404 when clicking a figure
+to enlarge it.
+
+This script rewrites each lightbox to use the path from
+the child
, making the enlarged-view link resolve correctly.
+
+Fixes: https://github.com/harvard-edge/cs249r_book/issues/1795
+"""
+
+import re
+import sys
+from pathlib import Path
+
+
+LIGHTBOX_PATTERN = re.compile(
+ r']*>)'
+ r'(
]*>)'
+)
+
+
+def fix_lightbox_hrefs(html_path: Path) -> int:
+ text = html_path.read_text(encoding="utf-8")
+ count = 0
+
+ def replacer(m: re.Match) -> str:
+ nonlocal count
+ old_href = m.group(1)
+ attrs = m.group(2)
+ img_tag = m.group(3)
+ img_src = m.group(4)
+ if old_href != img_src:
+ count += 1
+ return f''
+ return m.group(0)
+
+ new_text = LIGHTBOX_PATTERN.sub(replacer, text)
+ if count > 0:
+ html_path.write_text(new_text, encoding="utf-8")
+ return count
+
+
+def main() -> None:
+ if len(sys.argv) > 1:
+ build_dir = Path(sys.argv[1])
+ else:
+ script_dir = Path(__file__).resolve().parent
+ project_dir = script_dir.parent
+ build_dir = project_dir / "_build"
+ if not build_dir.exists():
+ build_dir = project_dir
+
+ html_files = sorted(build_dir.rglob("*.html"))
+ total_fixes = 0
+ files_fixed = 0
+
+ for html_file in html_files:
+ fixes = fix_lightbox_hrefs(html_file)
+ if fixes > 0:
+ total_fixes += fixes
+ files_fixed += 1
+
+ if total_fixes > 0:
+ print(f"[fix-lightbox] Fixed {total_fixes} lightbox href(s) in {files_fixed} file(s).")
+ else:
+ print("[fix-lightbox] No lightbox mediabag mismatches found.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/slides/tinyml/README-edx-original.md b/slides/tinyml/README-edx-original.md
index 771d59c1fe..dc827daa3f 100644
--- a/slides/tinyml/README-edx-original.md
+++ b/slides/tinyml/README-edx-original.md
@@ -17,7 +17,7 @@ TinyML on edX is designed in four chapters across 3 courses as described below.
## The TinyMLx Team:
### Course Instructors
-+ [Vijay Janapa Reddi](https://scholar.harvard.edu/vijay-janapa-reddi)
++ [Vijay Janapa Reddi](https://vijay.seas.harvard.edu)
+ [Laurence Maroney](http://www.laurencemoroney.com/)
+ [Pete Warden](https://petewarden.com/)
+ [Lara Suzuki](https://larissasuzuki.com/)