P44 OCR Viewer — Remove diff system, add Pass 2 split panel view Scope: p44-ocr-viewer.js, p44-ocr-viewer.css, p44-ocr-viewer.html. Complete removal of all diff logic, replace with a simple toggleable split panel for Pass 2. PART 1 — Remove diff entirely HTML — remove these elements:
wrapper — move its children (#line-numbers and #text-editor) back up directly inside #editor-wrap CSS — remove all rules for: #diff-toolbar #diff-toolbar .diff-legend #diff-toolbar .diff-count .diff-swatch .diff-swatch-del .diff-swatch-ins .diff-del .diff-ins #diff-reference #diff-reference-label #editor-bottom JS — remove these functions entirely: buildInlineDiff() renderInlineDiff() showDiffToolbar() applyDiffToDisplay() applyDiffToReference() toggleDiff() JS — remove these DOM refs: const btnDiff const diffToolbar const diffReference const editorBottom JS — remove state.diffMode from the state object. JS — in showOCRPage() remove the entire block added for diff auto-enable and toolbar display — the block starting with const corrForPage = state.corrections && state.corrections[pageNum] down to the closing } of the Pass 2 auto-diff block. Restore the original Pass 2 block at the bottom of showOCRPage(): javascript if (currentRole === 'pass2') { if (!state.editMode) enterEditMode(); updatePass2NavButtons(); } JS — in enterEditMode() remove the line applyDiffToReference(pageNum); JS — in exitEditMode() remove: diffReference.style.display = 'none'; if (state.diffMode) applyDiffToDisplay(pageNum); JS — in goToPage() remove the four lines: javascript state.diffMode = false; btnDiff.classList.remove('active'); diffToolbar.style.display = 'none'; diffReference.style.display = 'none'; PART 2 — HTML (p44-ocr-viewer.html) In the right panel header, add a toggle button immediately before #btn-edit: html Inside #text-panel-body, immediately before #text-output, add the original OCR reference pane: html PART 3 — CSS (p44-ocr-viewer.css) Add at the end of the file: css/* ── Split panel layout ───────────────────────────────────────── */ #text-panel-body { display: flex; flex-direction: column; overflow: hidden; } #split-pane { display: none; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; } #split-pane-header { font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold-dim); padding: 5px 16px; border-bottom: 1px solid var(--border); flex-shrink: 0; background: var(--surface); } #split-ocr-wrap { display: flex; flex: 1; min-height: 0; overflow-y: auto; padding: 12px 0; } #split-line-numbers { width: 48px; flex-shrink: 0; padding: 0 8px 0 12px; text-align: right; font-size: 11px; line-height: 1.75; color: var(--gold-dim); font-family: 'Courier New', monospace; user-select: none; border-right: 1px solid var(--border); margin-right: 12px; } #split-ocr-output { flex: 1; min-width: 0; font-size: 12.5px; line-height: 1.75; color: var(--text); white-space: pre-wrap; font-family: 'Georgia', 'Times New Roman', serif; padding-right: 16px; } #split-divider { height: 4px; background: var(--border); flex-shrink: 0; cursor: row-resize; border-top: 1px solid var(--gold-dim); border-bottom: 1px solid var(--gold-dim); } /* When split is active, text-output and editor-wrap each take half */ #text-panel-body.split-active #text-output, #text-panel-body.split-active #editor-wrap { flex: 1; min-height: 0; overflow-y: auto; } #text-panel-body.split-active { display: flex; flex-direction: column; } PART 4 — JS (p44-ocr-viewer.js) 4a — DOM refs Add: javascriptconst btnSplit = document.getElementById('btn-split'); const splitPane = document.getElementById('split-pane'); const splitDivider = document.getElementById('split-divider'); const splitOcrOutput = document.getElementById('split-ocr-output'); const splitLineNums = document.getElementById('split-line-numbers'); 4b — State flag Add to the state object: javascriptsplitMode: false, 4c — Line number generator for split pane Add this new function above showOCRPage(): javascriptfunction buildSplitLineNumbers(text) { const lines = (text || '').split('\n'); return lines.map((_, i) => i + 1).join('\n'); } 4d — showSplitPane(pageNum) Add this new function: javascriptfunction showSplitPane(pageNum) { const corr = state.corrections && state.corrections[pageNum]; const originalText = (corr && corr.original) || state.ocrPages[pageNum] || ''; splitOcrOutput.textContent = originalText; splitLineNums.textContent = buildSplitLineNumbers(originalText); splitPane.style.display = 'flex'; splitDivider.style.display = 'block'; textPanelBody.classList.add('split-active'); } 4e — hideSplitPane() Add this new function: javascriptfunction hideSplitPane() { splitPane.style.display = 'none'; splitDivider.style.display = 'none'; textPanelBody.classList.remove('split-active'); } 4f — toggleSplit() Add this new function: javascriptfunction toggleSplit() { state.splitMode = !state.splitMode; btnSplit.classList.toggle('active', state.splitMode); if (state.splitMode) { showSplitPane(state.currentPage); } else { hideSplitPane(); } } Add the event listener immediately after: javascriptbtnSplit.addEventListener('click', toggleSplit); 4g — applyRole() In applyRole(), in the pass2 branch add: javascript btnSplit.style.display = 'inline-block'; In the pass1 branch add: javascript btnSplit.style.display = 'none'; state.splitMode = false; hideSplitPane(); 4h — goToPage() At the start of goToPage(), after if (state.editMode) exitEditMode();, add: javascript if (state.splitMode) showSplitPane(n); This refreshes the split pane content for the new page without toggling it off. 4i — showOCRPage() At the end of showOCRPage(), after updatePass2NavButtons(), add: javascript if (state.splitMode) showSplitPane(pageNum); VERIFICATION CHECKLIST: Pass 1 role: Split button not visible Pass 2 role: Split button visible in panel header Clicking Split in Pass 2: right panel splits into original OCR on top and editor on bottom, both with line numbers, both scroll independently Clicking Split again: collapses back to single panel, editor fills full height Navigating to a new page while split is on: both panes update to the new page's content, split stays on Switching from Pass 2 to Pass 1 while split is on: split closes, button hides Original OCR pane shows raw unedited text — not the Pass 1 corrected version Line numbers visible in both panes and match the text lines