Accuracy is not completion
HTML for this example
Select the code and use your copy shortcut. Changes in this preview are temporary.
<!doctype html>
<html lang="en-US"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Accuracy is not completion</title><style>
:root{color-scheme:light;--accent:#32536e;--wash:#e8f1f7;--ink:#202d3b;--paper:#fffdf9}*{box-sizing:border-box}body{margin:0;color:var(--ink);background:#eeeae2;font:17px/1.65 system-ui,-apple-system,"Segoe UI",sans-serif}main{max-width:980px;margin:auto;padding:28px 24px 40px}header{border-top:6px solid var(--accent);padding:20px 0 24px}.kicker{color:var(--accent);font-weight:750;letter-spacing:.06em;margin:0 0 8px}h1{font:700 clamp(30px,5vw,46px)/1.15 Georgia,serif;margin:0 0 14px;max-width:780px}h2{font-size:23px;line-height:1.3;margin:0 0 14px}h3{font-size:19px;margin:12px 0 8px}p{margin:0 0 16px}button,input,textarea,select{font:inherit}button{background:white;border:1px solid #87949b;color:var(--ink);border-radius:8px;padding:11px 16px;min-height:48px;cursor:pointer;font-weight:650}button:hover{background:var(--wash)}button[aria-pressed=true],button.primary{background:var(--accent);color:white;border-color:var(--accent)}:focus-visible{outline:3px solid #b45a1e;outline-offset:3px}label{display:block;font-weight:650;margin:14px 0 6px}input:not([type=checkbox]):not([type=radio]),textarea,select{display:block;width:100%;min-width:0;max-width:100%;border:1px solid #80909b;border-radius:7px;padding:11px;background:white;color:var(--ink)}input[type=checkbox],input[type=radio]{width:21px;height:21px;accent-color:var(--accent)}textarea{resize:vertical}.panel{background:var(--paper);border:1px solid #ccd2d1;border-radius:12px;padding:24px;margin-bottom:20px}.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}.two>.panel{margin:0}.two{margin-bottom:20px}.actions{display:flex;flex-wrap:wrap;gap:10px;margin:18px 0}.result{padding:18px;background:var(--wash);border-left:5px solid var(--accent);margin-top:18px;white-space:pre-line;overflow-wrap:anywhere}.note{color:#465565;font-size:16px}.strip{padding:18px;background:var(--wash);border-radius:8px;margin-bottom:18px}table{border-collapse:collapse;width:100%;font-size:16px;table-layout:fixed}th,td{text-align:left;padding:10px 8px;border-bottom:1px solid #cbd0d1;overflow-wrap:anywhere;vertical-align:top}th{background:var(--wash)}ol,ul{padding-left:24px}li+li{margin-top:8px}pre{font-size:16px;white-space:pre-wrap;overflow-wrap:anywhere}code{font-size:16px}.grid{display:grid;gap:5px;max-width:440px}.grid button{padding:5px;min-width:0}.grid input{padding:5px!important;text-align:center;font-weight:750}blockquote{font:500 26px/1.5 Georgia,serif;margin:16px 0}footer{font-size:16px;color:#465565;margin-top:22px}[hidden]{display:none!important}svg{display:block;max-width:100%;height:auto}mark{background:#e0efad;color:var(--ink)}@media(max-width:560px){main{padding:18px 12px 28px}.panel{padding:20px 16px}.two{grid-template-columns:minmax(0,1fr)}h1{font-size:32px}.actions button{flex:1 1 135px}th,td{padding:8px 5px}.grid button{min-height:40px}blockquote{font-size:24px}}
</style></head><body><main><header><p class="kicker">TYPING PRACTICE · THREE SEPARATE METRICS</p><h1>Accuracy is not completion</h1><p>Reference passage: “We pack lunch.” · 14 characters, including spaces and punctuation. Printable ASCII only; no tabs or newlines.</p></header><section class="panel" id="practice" tabindex="0" aria-label="Typing practice region"><blockquote>We pack lunch.</blockquote><div class="actions"><button type="button" id="start">Start fresh attempt</button><button type="button" id="finish">Finish once</button><button type="button" id="reset">Reset</button></div><label for="typed">Type the reference passage</label><textarea id="typed" rows="3" disabled autocomplete="off" spellcheck="false"></textarea><div id="state" class="result" role="status" aria-live="polite">Ready</div><div id="metrics" class="result" role="status" aria-live="polite">No attempt yet.</div><div id="feedback" class="result" role="status" aria-live="polite">Use Start to begin.</div></section><footer>Original fictional example. Changes remain in this open page and are not saved.</footer><noscript>JavaScript is required for the local controls. The accompanying article contains worked examples.</noscript></main><script>
(()=>{'use strict';const $=id=>document.getElementById(id);
const reference='We pack lunch.';let phase='Ready',accepted='',began=0,elapsed=0,timer=null,generation=0,pasted=false,composing=false;function display(){if(phase==='Running')elapsed=(performance.now()-began)/1000;const tokens=accepted.trim()?accepted.trim().split(/\s+/):[],ref=reference.split(' '),matches=tokens.filter((t,i)=>t===ref[i]).length;const acc=tokens.length?100*matches/tokens.length:0,wpm=elapsed>0?(accepted.length/5)/(elapsed/60):null;$('state').textContent=phase+(pasted?' · Practice with pasted input':'');$('metrics').textContent='Elapsed: '+elapsed.toFixed(2)+' seconds / Characters: '+accepted.length+' / Gross WPM: '+(wpm===null?'N/A':wpm.toFixed(1))+' / Word accuracy: '+acc.toFixed(2)+'% ('+matches+'/'+tokens.length+') / '+(accepted===reference?'Exact passage complete':'Incomplete');}function stop(next){if(phase!=='Running')return;elapsed=(performance.now()-began)/1000;phase=next;clearInterval(timer);timer=null;$('typed').disabled=true;display();}function interrupt(){if(phase==='Running'){stop('Interrupted');$('feedback').textContent='Attempt interrupted. Start creates a new attempt.';}}function validate(){const v=$('typed').value;if(!/^[\x20-\x7e]*$/.test(v)){$('typed').value=accepted;$('feedback').textContent='Unsupported completed input rejected; previous accepted text retained.';return;}accepted=v;$('feedback').textContent='Current buffer recalculated.';display();}$('start').addEventListener('click',()=>{clearInterval(timer);const stamp=++generation;phase='Running';accepted='';elapsed=0;pasted=false;composing=false;$('typed').value='';$('typed').disabled=false;began=performance.now();timer=setInterval(()=>{if(stamp===generation&&phase==='Running')display();},100);$('feedback').textContent='All elapsed time counts until Finish.';$('typed').focus();display();});$('typed').addEventListener('input',e=>{if(phase!=='Running'){$('typed').value=accepted;return;}if(!composing&&!e.isComposing)validate();});$('typed').addEventListener('compositionstart',()=>{composing=true;});$('typed').addEventListener('compositionend',()=>{composing=false;if(phase==='Running')validate();});$('typed').addEventListener('paste',()=>{if(phase==='Running'){pasted=true;display();}});$('finish').addEventListener('click',()=>{if(composing){$('feedback').textContent='Finish the composition before ending the attempt.';return;}stop('Finished');});$('reset').addEventListener('click',()=>{generation++;clearInterval(timer);phase='Ready';accepted='';elapsed=0;pasted=false;composing=false;$('typed').value='';$('typed').disabled=true;$('state').textContent='Ready';$('metrics').textContent='No attempt yet.';$('feedback').textContent='Use Start to begin.';});window.addEventListener('blur',interrupt);document.addEventListener('visibilitychange',()=>{if(document.hidden)interrupt();});$('practice').addEventListener('focusout',e=>{if(!e.relatedTarget||!$('practice').contains(e.relatedTarget))interrupt();});
})();
</script></body></html>