P44 OCR Viewer — Pass 1 Flag System Redesign
Scope: p44-ocr-viewer.js, p44-ocr-viewer.css, p44-ocr-viewer.html. Make all three changes in sequence. Do not touch PDF rendering, zoom, sync scroll, Pass 2 logic, or the corrections storage model.

PART 1 — HTML (p44-ocr-viewer.html)
In the right panel header, replace the five buttons:
html<button id="btn-flag-verified" ...>✓ Verified</button>
<button id="btn-flag-review"   ...>⚑ Review</button>
<button id="btn-flag-error"    ...>✗ Error</button>
<button id="btn-flag-clear"    ...>Clear</button>
<button id="btn-edit"          ...>Edit</button>
With these three buttons:
html<button id="btn-flag-done"    class="tb-btn flag-btn" title="Mark page as done — sends to Pass 2 queue. Cannot be undone.">✓ Done</button>
<button id="btn-flag-problem" class="tb-btn flag-btn" title="Flag page as a problem — OCR too bad to fix. Still goes to Pass 2.">⚠ Problem</button>
<button id="btn-edit"         class="tb-btn" title="Toggle edit mode">Edit</button>
Add a new read-only banner element inside #text-panel-body, immediately before #pass2-revert-bar:
html<div id="done-banner" style="display:none;"></div>

PART 2 — CSS (p44-ocr-viewer.css)
Remove the CSS rules for #btn-flag-verified, #btn-flag-review, #btn-flag-error if any exist by those IDs. The .flag-btn and .flag-btn.active rules stay — they apply to the new buttons too.
Add these new rules at the end of the file:
css/* ── Done-page read-only banner (Pass 1) ─────────────────────── */
#done-banner {
display: none;
align-items: center;
gap: 8px;
padding: 7px 16px;
background: #0f2a0f;
border-bottom: 1px solid #2e6e2e;
font-size: 10px;
color: #5cb85c;
letter-spacing: 0.05em;
flex-shrink: 0;
}

/* ── Problem flag indicator on page nav input ─────────────────── */
#page-input.problem { border-color: #c08020; }

/* ── Greyed-out done state on the OCR text panel ─────────────── */
#text-output.done-readonly {
opacity: 0.55;
pointer-events: none;
user-select: none;
}

PART 3 — JS (p44-ocr-viewer.js)
Make the following changes in order. Each change is isolated — do not touch any other function.
3a — DOM refs
Replace:
javascriptconst btnFlagVerified = document.getElementById('btn-flag-verified');
const btnFlagReview   = document.getElementById('btn-flag-review');
const btnFlagError    = document.getElementById('btn-flag-error');
const btnFlagClear    = document.getElementById('btn-flag-clear');
With:
javascriptconst btnFlagDone    = document.getElementById('btn-flag-done');
const btnFlagProblem = document.getElementById('btn-flag-problem');
3b — Flag label constants
Replace the PASS2_BTN_LABELS and PASS1_BTN_LABELS constants with:
javascriptconst PASS2_BTN_LABELS = { done: '✓ Pass 2 approved', problem: '⚠ Needs work' };
const PASS1_BTN_LABELS = { done: '✓ Done',             problem: '⚠ Problem'    };
3c — updateFlagButtons(pageNum)
Replace the entire function body with:
javascriptfunction updateFlagButtons(pageNum) {
const flagSrc = currentRole === 'pass2' ? pass2Flags : state.flags;
const flag = flagSrc[pageNum] || null;
btnFlagDone.classList.toggle('active',    flag === 'done');
btnFlagProblem.classList.toggle('active', flag === 'problem');

// Done pages are read-only in Pass 1 — disable both flag buttons and Edit
const isDone = currentRole === 'pass1' && flag === 'done';
btnFlagDone.disabled    = isDone;
btnFlagProblem.disabled = isDone;
btnEdit.disabled        = isDone;
btnEdit.style.opacity   = isDone ? '0.35' : '';
}
3d — setFlag(type)
Replace the entire function body with:
javascriptfunction setFlag(type) {
const p = state.currentPage;

if (currentRole === 'pass2') {
if (type === null) { delete pass2Flags[p]; } else { pass2Flags[p] = type; }
updateFlagButtons(p);
savePass2Flags();
return;
}

// Pass 1 — Done is one-way: once set it cannot be cleared by the volunteer
if (state.flags[p] === 'done') return;

// Problem is toggleable — clicking it again removes it
if (type === 'problem' && state.flags[p] === 'problem') {
delete state.flags[p];
} else if (type === null) {
delete state.flags[p];
} else {
state.flags[p] = type;
}

updateFlagButtons(p);
updateFlagsSummary();
saveFlags();
}
3e — showOCRPage(pageNum)
At the end of showOCRPage(), after the existing block that calls updateFlagButtons() and updateCorrectionIndicator(), add the following. Do not change any existing lines in showOCRPage() — only add this block at the end (before the closing brace), replacing the existing Pass 2 auto-edit-mode call:
javascript  // Pass 1 done-page read-only state
const doneBanner = document.getElementById('done-banner');
const isDonePage = currentRole === 'pass1' && state.flags[pageNum] === 'done';

if (isDonePage) {
// Show the final corrected text (same display logic as normal, already rendered above)
// Lock the panel visually
textOutput.classList.add('done-readonly');
doneBanner.innerHTML =
'✓ <strong>Done</strong> — submitted to Pass 2 queue. This page is locked.';
doneBanner.style.display = 'flex';
// Ensure editor is closed and stays closed
if (state.editMode) exitEditMode();
} else {
textOutput.classList.remove('done-readonly');
doneBanner.style.display = 'none';
}

// Pass 2 auto-edit mode (unchanged behaviour)
if (currentRole === 'pass2') {
if (!state.editMode) enterEditMode();
updatePass2NavButtons();
}
Note: this block replaces the existing two lines at the bottom of showOCRPage() that read:
javascript  if (currentRole === 'pass2') {
if (!state.editMode) enterEditMode();
updatePass2NavButtons();
}
3f — applyRole()
In applyRole(), replace the two label-setting lines for pass2 branch:
javascript    btnFlagVerified.textContent = PASS2_BTN_LABELS.verified;
btnFlagReview.textContent   = PASS2_BTN_LABELS.review;
btnFlagError.textContent    = PASS2_BTN_LABELS.error;
With:
javascript    btnFlagDone.textContent    = PASS2_BTN_LABELS.done;
btnFlagProblem.textContent = PASS2_BTN_LABELS.problem;
And replace the three label-setting lines for the pass1 branch:
javascript    btnFlagVerified.textContent = PASS1_BTN_LABELS.verified;
btnFlagReview.textContent   = PASS1_BTN_LABELS.review;
btnFlagError.textContent    = PASS1_BTN_LABELS.error;
With:
javascript    btnFlagDone.textContent    = PASS1_BTN_LABELS.done;
btnFlagProblem.textContent = PASS1_BTN_LABELS.problem;
3g — Event listeners
Replace:
javascriptbtnFlagVerified.addEventListener('click', () => setFlag('verified'));
btnFlagReview.addEventListener('click',   () => setFlag('review'));
btnFlagError.addEventListener('click',    () => setFlag('error'));
btnFlagClear.addEventListener('click',    () => setFlag(null));
With:
javascriptbtnFlagDone.addEventListener('click',    () => setFlag('done'));
btnFlagProblem.addEventListener('click', () => setFlag('problem'));
3h — updateFlagsSummary()
Replace the counting logic inside updateFlagsSummary():
javascript  Object.values(state.flags).forEach(f => {
if (f === 'verified') v++;
else if (f === 'review') r++;
else if (f === 'error') er++;
});
flagsSummary.textContent = v || r || er
? '✓ ' + v + '  ⚑ ' + r + '  ✗ ' + er
: '';
With:
javascript  let done = 0, problem = 0;
Object.values(state.flags).forEach(f => {
if (f === 'done')    done++;
else if (f === 'problem') problem++;
});
flagsSummary.textContent = done || problem
? '✓ ' + done + (problem ? '  ⚠ ' + problem : '')
: '';
3i — Keyboard shortcut
In the keydown handler, replace:
javascript    case 'v':
setFlag('verified'); break;
case 'r':
setFlag('review'); break;
case 'e':
setFlag('error'); break;
With:
javascript    case 'v':
setFlag('done'); break;
case 'p':
setFlag('problem'); break;
Update the footer kbd hint in p44-ocr-viewer.html from:
html<span id="kbd-hint">← → navigate &nbsp; v/r/e flag &nbsp; esc close</span>
To:
html<span id="kbd-hint">← → navigate &nbsp; v done &nbsp; p problem &nbsp; esc close</span>
3j — getVerifiedPages()
Replace:
javascript  .filter(k => state.flags[k] === 'verified')
With:
javascript  .filter(k => state.flags[k] === 'done')

VERIFICATION CHECKLIST — confirm each before closing the prompt:

Clicking ✓ Done on an unreviewed page: button highlights gold, page text goes grey, green Done banner appears, Edit button is disabled, cannot click Done or Problem again
Clicking ⚠ Problem on an unreviewed page: button highlights gold, page remains editable
Clicking ⚠ Problem again on a problem page: flag clears, button returns to inactive
Navigating to a Done page while in Pass 1 role: banner shows, editor locked, text visible as final corrected version
Switching to Pass 2 role: Done banner hidden, flag buttons show Pass 2 labels, auto-edit mode activates as before
Footer summary shows correct counts using ✓ and ⚠ symbols
Keyboard v sets Done, p sets/toggles Problem, no reference to old r or e keys anywhere