diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed60db9..daaee0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
## [Unreleased]
### Changed
+- **Rehearser I/O extraction.** Session serialization, library save/load/autosave, REH/Fountain/FDX/OSF export, and
+ PDF/session import now live in `rehearser-io.js`.
- **Rehearser playback extraction.** WebAudio playback, transport controls, bounded decoded-audio prefetch, persistent
line-audio caching, and synth-all controls now live in `rehearser-playback.js`.
- **Audiobook namespace wiring.** Network helpers and public casting, recast, export, and save actions now register
diff --git a/TODO.md b/TODO.md
index 39b1ced..df705a5 100644
--- a/TODO.md
+++ b/TODO.md
@@ -121,7 +121,7 @@ architecture change: the larger Audiobook/Rehearser/style split.
## P1 — Modular frontend architecture
- [ ] Split `audiobook.js`, `rehearser.js`, and `style.css` by responsibility; Rehearser casting, playback, training,
- voice design, library, and stage blocks are now isolated, with import/event wiring and remaining Audiobook orchestration
+ voice design, I/O, library, and stage blocks are now isolated, with import/event wiring and remaining Audiobook orchestration
still in the monolith.
- [x] Extract Rehearser stage display and cast-sidebar controls into `rehearser-stage.js`.
- [ ] Replace broad globals with namespaces such as `window.TTVC.audiobook`; a compatibility namespace bridge now
diff --git a/VERSION b/VERSION
index e607a19..9be6d61 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.24.50
+1.24.51
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index c7aebd3..34b4763 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -34,6 +34,7 @@ Done incrementally as global-scope ordered files (no ES-module change needed)
- ✅ `rehearser-cast.js` — `renderCastList`, sort/filter, online voice picker, and character research.
- ✅ `rehearser-stage.js` — stage font/cast sidebar controls and cast-strip rendering.
- ✅ `rehearser-playback.js` — WebAudio playback, transport state, bounded decoded-audio prefetch, and persistent line-audio cache/synthesis controls.
+- ✅ `rehearser-io.js` — rehearsal serialization, library save/load, autosave, session/file export, and screenplay/PDF imports.
- ✅ `rehearser-voice-picker.js` — voice preview state, local matching, fish.audio search/import, and candidate assignment; DOM event registration remains in `rehearser-cast.js`.
- ✅ `rehearser-cast.js` — cast view, full cast-card rendering, sort/filter state handlers, and delegated cast toolbar wiring.
- ✅ `rehearser-voice-design.js` — character development, backend selection, and backend-refresh synchronization.
@@ -46,8 +47,8 @@ Done incrementally as global-scope ordered files (no ES-module change needed)
- ✅ `static/css/rehearser.css` — isolated Rehearser modal, cast, stage, training, bookshelf, and script-view styles.
- ✅ `static/css/audiobook.css` — isolated Reader/Audiobook controls, casting feed, page layout, character overlays, and review styles.
- ✅ `rehearser-train.js` — transcript normalization, LCS comparison, and word-level training feedback; microphone/state wiring remains in `rehearser.js`.
-- ✅ `rehearser-library.js` — SQLite persistence helpers and IndexedDB migration; import/export and auto-save remain
- in `rehearser.js` until their UI/event-handler dependencies are isolated.
+- ✅ `rehearser-library.js` — SQLite persistence helpers and IndexedDB migration; library rendering remains ordered with
+ the main module because it owns the phase UI.
**Pattern (proven):** extract a cohesive block whose only cross-file references resolve at *call time* (event handlers), not at module load. Top-level `const rehState` and top-level `addEventListener` registrations must stay ordered — extract those last and load them after their dependencies. Re-run `npx playwright test` after each extraction.
diff --git a/static/index.html b/static/index.html
index 577fd77..3782835 100644
--- a/static/index.html
+++ b/static/index.html
@@ -10,7 +10,7 @@
-
+
@@ -27,12 +27,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
@@ -397,7 +397,7 @@ window.toggleNavTree = function(treeId, chevronId) {
-
+