Add ReOrg-style modal popup for newsletter subscriptions that appears
when clicking the Subscribe link in navbar. Provides smoother UX by
keeping users on site instead of navigating to external Buttondown page.
Features:
- Clean, minimal design with smooth animations
- Backdrop blur and slide-up effect
- Integrates with existing Buttondown account (mlsysbook)
- Collects first name, last name, email, role, and organization
- Success message shown after submission
- Auto-closes after 3 seconds
- Closes on overlay click, close button, or ESC key
- Dark mode support
- Fully responsive
The modal intercepts the navbar Subscribe link and provides an
elegant on-site subscription experience.
- Create dedicated subscribe.qmd page with embedded form
- Beautiful on-brand design matching MLSysBook aesthetic
- Collects: first name, last name, email, role, organization
- Shows benefits: new chapters, lab updates, TinyTorch news
- Update navbar Subscribe link to point to new page
- Form submits to buttondown.email/mlsysbook
- Includes success message and mobile responsive design
- Feature TinyTorch first (new release)
- Group direct actions together: TinyTorch, Subscribe, Star, Support
- Move all dropdowns to the end: Hands-on, Downloads, GitHub
- Improves visual hierarchy and user flow
- Change Netlify from proxy (status 200) to redirect (status 301)
- Reduces bandwidth costs from 100% to near-zero
- Netlify now only handles tiny redirect headers, GitHub Pages serves content
- Group Labs and Kits under 'Hands-on' dropdown in navbar
- Feature TinyTorch prominently as new release
- Add Newsletter subscribe button
- Group PDF and EPUB under 'Downloads' dropdown
- Cleaner navbar with better organization
- Move redirect HTML files from root to directories with index.html
- Enables mlsysbook.ai/pdf instead of mlsysbook.ai/pdf.html
- GitHub Pages serves /path/ and /path as /path/index.html automatically
- Changes: pdf.html → pdf/index.html (same for epub, kits, labs, changelog, tinytorch)
- Add client-side redirect pages for short links (pdf, epub, kits, labs, changelog, tinytorch)
- Enables migration away from Netlify to reduce bandwidth costs
- Redirects use meta refresh + JavaScript for instant redirection
- Will work seamlessly once DNS points directly to GitHub Pages
Previously redirected to GitHub Pages URL, which itself redirected to
tinytorch.ai, creating an unnecessary hop. Now redirects directly to
tinytorch.ai for better performance and cleaner URL routing.
Updated:
- quarto/_redirects: /tinytorch -> https://tinytorch.ai
- netlify.toml: /tinytorch -> https://tinytorch.ai
Remove tracked build artifacts that should be regenerated:
- Diagram PDFs (3 files): Auto-generated by Quarto diagram extension
- Quarto HTML support files (frontiers_files): Bootstrap, clipboard, etc.
Update .gitignore to prevent future tracking:
- Add **/*_files/ pattern for Quarto HTML support directories
- These are auto-generated and should not be in version control
Cleanup also performed locally (not tracked in git):
- Removed .bak backup files
- Removed Python __pycache__ directories
- Removed loose diagram-*.pdf files from quarto root
All removed files will be regenerated automatically during builds.
Replaced fix_epub_references.sh with epub_postprocess.py to support
Windows builds. The new Python wrapper provides identical functionality
using only Python stdlib (zipfile, tempfile, shutil) and imports the
existing fix_cross_references.py module directly.
Key changes:
- Created epub_postprocess.py: Cross-platform wrapper for EPUB post-processing
- Updated _quarto-epub.yml: Changed post-render hook from .sh to .py
- Removed dependency on bash/shell for Windows compatibility
The wrapper extracts the EPUB, runs cross-reference fixes using the
existing dynamic section mapping system, and re-packages the EPUB
following EPUB3 standards (uncompressed mimetype first).
- Created fix_epub_references.sh wrapper script to extract, fix, and repackage EPUBs
- Enhanced fix_cross_references.py to support extracted EPUB directory structure
- Added dynamic EPUB section mapping that scans actual chapter files
- Fixed Pattern 3 (EPUB-specific) references to use chapter-to-chapter links
- Links now correctly resolve to ch00X.xhtml#sec-id format instead of HTML paths
- Updated _quarto-epub.yml to use new wrapper script in post-render hook
This resolves the issue where @sec- references in lab overview files were
showing as unresolved .qmd paths in EPUB builds. The script now properly
converts them to working EPUB chapter references.
Fix 6 more problematic .qmd file-path references that would cause
broken links in EPUB:
- labs.qmd: Convert 4 setup guide links to @sec- references
- motion_classification.qmd: Convert 2 DSP Spectral Features links
These cross-directory references need section IDs to work properly
in EPUB builds, just like the lab overview pages fixed earlier.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Convert broken .qmd file-path references to semantic @sec- references
that Quarto can resolve properly in EPUB builds.
This fixes the 19 EPUB validation errors where links in lab overview pages
pointed to non-existent .qmd files (e.g., href="./setup/setup.qmd").
Changes:
- Convert 17 file-path links to @sec- references across 4 lab overview pages
- Add Pattern 3 to fix_cross_references.py for EPUB (href="@sec-xxx")
- Add 23 lab section mappings to CHAPTER_MAPPING
- Add EPUB detection logic to post-render script
- Configure EPUB build to run fix_cross_references.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed XHTML validation error where li elements were used directly
inside table cells without ul wrapper. EPUB/XHTML spec requires
li elements to be children of ul or ol, not direct children of td.
EPUB validation error fixed:
- ERROR: ch017.xhtml:542:35 element li not allowed here
File: quarto/contents/core/hw_acceleration/hw_acceleration.qmd
Table: tbl-hw-evolution (Hardware Specialization Trends)
Lines: 252-274
Fixed typo where backtick was misplaced in 'Replace' causing
<raspberry_pi_ip> to be parsed as invalid custom HTML element
instead of being properly formatted as inline code.
EPUB validation error fixed:
- ERROR: element raspberry_pi_ip not allowed here
File: quarto/contents/labs/raspi/object_detection/object_detection.qmd
Line: 356
- Replace frameborder="0" with border: none in CSS
- Updates YouTube embed iframes to be HTML5/EPUB3 compliant
- Fixes epubcheck validation errors for invalid attributes
- Create validate_epub.py utility for EPUB validation
- Integrates official epubcheck validator when available
- Custom checks for CSS variables and XML comment violations
- Detects common XHTML errors (unclosed tags, unescaped characters)
- Validates EPUB structure (mimetype, container.xml, OPF)
- Supports --quick flag to skip epubcheck for faster validation
- Provides detailed error reporting with file paths and line numbers
- Add explicit --all flag requirement for building entire book
- Commands now require either chapter name or --all flag
- Update help text and examples to show new --all flag usage
- Running commands without arguments now shows helpful error message
Addresses #1052
## Problem
The EPUB version was failing to open in ClearView with XML parsing errors:
"Comment must not contain '--' (double-hyphen)" at multiple lines.
## Root Cause
CSS custom properties (--crimson, --text-primary, etc.) contain double
hyphens which violate XML comment specifications when processed by strict
XML parsers in some EPUB readers like ClearView.
## Solution
- Removed :root CSS variable definitions
- Replaced all 66 instances of var() references with literal hex values
- Added documentation explaining why variables were removed
- Maintained color reference guide for future maintenance
## Changes
- Removed :root { --crimson: #A51C30; ... } block
- Replaced all var(--crimson) → #A51C30
- Replaced all var(--text-primary) → #1a202c
- Replaced all var(--text-secondary) → #4a5568
- Replaced all var(--text-muted) → #6c757d
- Replaced all var(--background-light) → #f8f9fa
- Replaced all var(--background-code) → #f1f3f4
- Replaced all var(--border-light) → #e9ecef
- Replaced all var(--border-medium) → #dee2e6
- Replaced all var(--crimson-dark) → #8B1729
## Testing
- Verified no remaining var() references in epub.css
- Verified no remaining CSS variable definitions
- Visual appearance remains identical (same hex values)
Addresses #1052
## Problem
The EPUB version was failing to open in ClearView with XML parsing errors:
"Comment must not contain '--' (double-hyphen)" at multiple lines.
## Root Cause
CSS custom properties (--crimson, --text-primary, etc.) contain double
hyphens which violate XML comment specifications. While the stylesheet
is linked externally in the built EPUB, some readers may embed or process
the CSS in ways that trigger strict XML parsers.
## Solution
Replaced all 66 instances of CSS variables with their literal hex color
values throughout epub.css. This ensures EPUB compatibility across
different readers while maintaining the same visual appearance.
## Changes
- quarto/assets/styles/epub.css: Removed :root variables, replaced all
var() references with literal values, added documentation
- quarto/config/_quarto-epub.yml: Added note about inkscape requirement
## Testing
Built EPUB successfully, validated XHTML files with xmllint. CSS variables
confirmed present in original, absent in fixed version.
Remove obsolete files that should not be tracked:
- 3 diagram PDF cache files (auto-generated by Quarto)
- 4 empty footnote_catalog.json files
All removed files are build artifacts or empty placeholders
that provide no ongoing value.
Addresses Dependabot security alert for arbitrary code injection
vulnerability in lycheeverse/lychee-action < 2.0.2.
- Upgrade from v1.9.3 to v2.0.2
- Fixes potential attack vector via lycheeVersion input
- Impact: Low, vulnerability in link checker action
Refactors callout styling to be self-contained within the custom-numbered-blocks extension.
This eliminates duplication in dark mode styles, ensures consistency across all callout types, and simplifies maintenance by centralizing all callout styling logic in `foldbox.css`. Host stylesheets now only handle minimal Quarto interference prevention.
Removes a symbolic link to a config file that is no
longer used.
Adds the symbolic link filename to the .gitignore file
to prevent it from being accidentally added back to
the repository.