Letter B · category review — Review whether an answer fits a stated category and letter, then separately compare accepted responses for uniqueness within that category.

HTML for this example

Select the code and use your copy shortcut. Changes in this preview are temporary.

<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Letter B · category review</title><style>*{box-sizing:border-box}body{margin:0;font:16px/1.5 Arial,sans-serif;color:var(--ink);background:var(--bg)}main{max-width:1180px;margin:auto;padding:26px 28px 50px}h1,h2,h3,p{margin:0}h1{font-size:34px;line-height:1.15;letter-spacing:-.025em}h2{font-size:23px;margin-bottom:12px}h3{font-size:17px}header{margin-bottom:22px}header p{margin-top:8px}button,input,select,textarea{font:inherit}button{cursor:pointer;min-height:44px;padding:9px 15px;border:1px solid var(--line);border-radius:7px;background:white;color:var(--ink)}button:hover{filter:brightness(.94)}button.active,.primary{background:var(--accent);color:white;border-color:var(--accent)}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid #117ec1;outline-offset:3px}input,select,textarea{max-width:100%;padding:9px;border:1px solid #8c9caa;border-radius:5px;background:white;color:var(--ink)}input{width:100%;min-width:0}textarea{width:100%;resize:vertical}label{display:block;font-size:14px;font-weight:bold;margin:12px 0 5px}.small,small{font-size:13px;color:var(--muted)}.eyebrow{font-size:12px;letter-spacing:.13em;text-transform:uppercase;margin-bottom:8px;font-weight:bold}.toolbar{display:flex;gap:8px;flex-wrap:wrap;margin:16px 0}.split{display:grid;grid-template-columns:1.5fr 1fr;gap:24px;align-items:start}.paper{background:white;border:1px solid var(--line);padding:25px;border-radius:10px}.fields{display:grid;grid-template-columns:1fr 1fr;gap:0 14px}.message{padding:12px 14px;border-left:4px solid var(--accent);background:var(--tint);margin:15px 0;overflow-wrap:anywhere}.big{font-size:40px;font-weight:700;line-height:1.2}table{border-collapse:collapse;width:100%;font-size:14px}th,td{text-align:left;padding:11px 8px;border-bottom:1px solid var(--line);vertical-align:top}th{font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}footer{margin-top:28px;padding-top:18px;border-top:1px solid var(--line);font-size:13px;color:var(--muted)}footer p+p{margin-top:8px}[hidden]{display:none!important}.stack{display:grid;gap:12px}.tag{font-size:12px;padding:4px 8px;border-radius:20px;background:var(--tint);display:inline-block}.section{margin-top:26px}.error{color:#a32727}svg{max-width:100%;height:auto;display:block}button[disabled]{opacity:.5;cursor:default}@media(max-width:800px){main{padding:22px 18px}.split{grid-template-columns:1fr}h1{font-size:30px}.paper{padding:20px}}@media(max-width:450px){main{padding:18px 12px}h1{font-size:27px}.fields{gap:0 10px}.paper{padding:16px}.big{font-size:34px}th,td{padding:9px 5px}.toolbar button{flex:1;padding:8px}}
:root{--bg:#fff7df;--ink:#30343d;--muted:#6d6b60;--accent:#7355a2;--line:#dfd4ad;--tint:#f2ebff}h1{font-family:Georgia,serif}.round-header{display:flex;align-items:center;gap:20px}.letter{font:bold 64px/1 Georgia;background:#f3cf4d;border-radius:20px;width:94px;height:94px;display:grid;place-items:center;transform:rotate(-5deg)}.scoreboard{display:flex;justify-content:space-between;gap:20px;background:#7355a2;color:white;padding:20px 24px;border-radius:14px;margin:20px 0}.scoreboard .big{font-size:38px}.review-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.category{background:#fff;border:1px solid var(--line);border-radius:14px;overflow:hidden}.category>h2{background:#f5dc7b;padding:14px 16px;font:22px Georgia;margin:0}.record{padding:16px;border-top:1px solid #e4dec9}.record label{margin-top:4px}.record input{font-size:21px}.record select{width:100%;font-size:14px}.outcome{margin-top:10px;font-size:14px;min-height:85px}.category small{display:block}.view-tabs{display:flex;gap:10px;margin:20px 0}.learner{max-width:760px;margin:auto}.learner textarea{background:#fffef7;min-height:340px}.record .small{margin:5px 0}.key-note{padding:12px 16px;color:#615c4e;font-size:13px}.policy{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}@media(max-width:720px){.review-grid{grid-template-columns:1fr}.policy{grid-template-columns:1fr}.outcome{min-height:0}.letter{width:76px;height:76px;font-size:53px}.scoreboard{padding:17px}.scoreboard .big{font-size:30px}}</style></head><body><main><header><div class="round-header"><div class="letter" aria-label="Round letter B">B</div><div><div class="eyebrow">One fictional round · teacher review</div><h1>A valid answer can be shared.</h1><p>Accept the category and letter first; compare uniqueness second.</p></div></div></header><div class="view-tabs"><button type="button" id="teacher-view" class="active">Prepared teacher review</button><button type="button" id="learner-view">Blank learner copy</button><button type="button" id="reset">Reset demonstration</button></div><section id="teacher-surface"><div class="scoreboard"><div><div class="small" style="color:white">Accepted unique cells · optional credit</div><div id="credits" class="big"></div></div><div id="review-summary"></div></div><div class="review-grid"><section class="category"><h2>Animal · B</h2><p class="key-note">Common animal name</p><div class="record"><label for="word-0-0">Fictional row A</label><input id="word-0-0" value="bear"><label for="decision-0-0" class="small">Teacher category decision</label><select id="decision-0-0"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-0-0" class="outcome"></div></div><div class="record"><label for="word-1-0">Fictional row B</label><input id="word-1-0" value="bear"><label for="decision-1-0" class="small">Teacher category decision</label><select id="decision-1-0"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-1-0" class="outcome"></div></div><div class="record"><label for="word-2-0">Fictional row C</label><input id="word-2-0" value="bird"><label for="decision-2-0" class="small">Teacher category decision</label><select id="decision-2-0"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-2-0" class="outcome"></div></div></section><section class="category"><h2>Object · B</h2><p class="key-note">Common classroom object; brush = art brush</p><div class="record"><label for="word-0-1">Fictional row A</label><input id="word-0-1" value="book"><label for="decision-0-1" class="small">Teacher category decision</label><select id="decision-0-1"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-0-1" class="outcome"></div></div><div class="record"><label for="word-1-1">Fictional row B</label><input id="word-1-1" value="brush"><label for="decision-1-1" class="small">Teacher category decision</label><select id="decision-1-1"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-1-1" class="outcome"></div></div><div class="record"><label for="word-2-1">Fictional row C</label><input id="word-2-1" value="desk"><label for="decision-2-1" class="small">Teacher category decision</label><select id="decision-2-1"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-2-1" class="outcome"></div></div></section><section class="category"><h2>Action · B</h2><p class="key-note">Base-form action verb</p><div class="record"><label for="word-0-2">Fictional row A</label><input id="word-0-2" value="build"><label for="decision-0-2" class="small">Teacher category decision</label><select id="decision-0-2"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-0-2" class="outcome"></div></div><div class="record"><label for="word-1-2">Fictional row B</label><input id="word-1-2" value="bounce"><label for="decision-1-2" class="small">Teacher category decision</label><select id="decision-1-2"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-1-2" class="outcome"></div></div><div class="record"><label for="word-2-2">Fictional row C</label><input id="word-2-2" value="bake"><label for="decision-2-2" class="small">Teacher category decision</label><select id="decision-2-2"><option value="accepted">Category fits</option><option value="pending">Needs teacher review</option><option value="rejected">Category does not fit</option></select><div id="outcome-2-2" class="outcome"></div></div></section></div><p class="message" id="scat-status" role="status">Fictional prepared rows A/B/C, not collected student records.</p></section><section id="learner-surface" class="paper learner" hidden><h2>Blank learner packet · B round</h2><p>Write one response and a short category explanation for each prompt.</p><label for="learner-copy">Student-only plain text · no worked answers</label><textarea id="learner-copy" readonly></textarea><div class="toolbar"><button type="button" id="select-learner">Select learner text</button></div><p id="select-status" class="small">Select the text, then use your device’s manual Copy command. This entire HTML file includes the teacher key; distribute only the blank text.</p></section><section class="paper section"><h2>Declared comparison policy</h2><div class="policy"><p><b>1. Category review</b><br>Teacher-authored decisions stay separate from the mechanical B check. New words wait for review.</p><p><b>2. Normalize narrowly</b><br>Trim outer spaces and ignore case only. Do not stem, merge synonyms or remove punctuation.</p><p><b>3. Compare locally</b><br>Count accepted answers in the same category and round. Hold the category’s final credit while any response is unresolved.</p></div></section><footer><p>Original fixed-letter activity, not the complete commercial rules, classwide collection or automatic semantic grading. These editable fictional rows demonstrate comparison; no actual student responses are requested or saved.</p><p>Teacher key and learner surface are visually separate; the HTML is not a secure student-only copy. The selectable learner text contains only blank prompts. Reset restores the original fictional data, not any native class records.</p></footer></main><script>'use strict';const $=id=>document.getElementById(id);const esc=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));const original=[["bear","book","build"],["bear","brush","bounce"],["bird","desk","bake"]],categories=["Animal","Object","Action"];const normalize=s=>s.trim().toLowerCase();const learnerText='LETTER B · BLANK LEARNER PACKET\nName: ____________________\nRound: B-01\n\nAnimal — common animal name beginning with B\nResponse: ____________________\nWhy it fits: ____________________\n\nObject — common classroom object name beginning with B\nResponse: ____________________\nWhy it fits: ____________________\n\nAction — base-form action verb beginning with B\nResponse: ____________________\nWhy it fits: ____________________\n\nTeacher feedback: ____________________';
function compare(records){return records.map(r=>{const normalized=normalize(r.word),letter=normalized.startsWith('b'),accepted=r.decision==='accepted'&&letter&&!!normalized,pending=r.decision==='pending'||!normalized,provisional=records.some(other=>other.category===r.category&&(other.decision==='pending'||!normalize(other.word)));const count=accepted?records.filter(other=>other.category===r.category&&other.decision==='accepted'&&normalize(other.word).startsWith('b')&&normalize(other.word)===normalized).length:0;return {...r,normalized,letter,accepted,pending,provisional,count,credit:accepted&&count===1&&!provisional?1:0};});}
function records(){return original.flatMap((row,i)=>row.map((_,j)=>({row:i,category:j,word:$('word-'+i+'-'+j).value,decision:$('decision-'+i+'-'+j).value})));}
function render(){const result=compare(records());let credit=0,pending=0;result.forEach(r=>{credit+=r.credit;if(r.pending)pending++;let message;if(!r.normalized)message='Blank response · Needs teacher review';else if(r.decision==='pending')message='Needs teacher review · no final credit';else if(r.decision==='rejected')message='Category does not fit · no credit';else if(!r.letter)message='Category fits; initial letter does not. No credit.';else message='Accepted · '+(r.count>1?'Shared ('+r.count+' occurrences), still valid':'Unique (1 occurrence)')+(r.provisional?' · provisional; category credit held':r.credit?' · 1 credit':' · 0 uniqueness credit');$('outcome-'+r.row+'-'+r.category).textContent=message+' | Compared word: '+(r.normalized||'—')+' | B check: '+(r.letter?'fits':'does not fit');});$('credits').textContent=credit+' '+(pending?'confirmed credits · provisional':'credits');$('review-summary').textContent=pending?pending+' responses need teacher review. Affected category credits held.':result.filter(r=>r.accepted).length+' accepted responses · '+result.filter(r=>r.decision==='accepted'&&!r.letter).length+' letter mismatches.';}
function reset(){original.forEach((row,i)=>row.forEach((word,j)=>{$('word-'+i+'-'+j).value=word;$('decision-'+i+'-'+j).value='accepted';}));$('learner-copy').value=learnerText;$('scat-status').textContent='Fictional prepared rows A/B/C, not collected student records.';view(false);render();}
function view(learner){$('teacher-surface').hidden=learner;$('learner-surface').hidden=!learner;$('teacher-view').className=learner?'':'active';$('learner-view').className=learner?'active':'';$('teacher-view').setAttribute('aria-pressed',String(!learner));$('learner-view').setAttribute('aria-pressed',String(learner));}
original.forEach((row,i)=>row.forEach((_,j)=>{$('word-'+i+'-'+j).addEventListener('input',()=>{$('decision-'+i+'-'+j).value='pending';$('scat-status').textContent='Response edited. Category acceptance reset to Needs teacher review; comparisons recomputed.';render();});$('decision-'+i+'-'+j).addEventListener('input',render);}));$('teacher-view').addEventListener('click',()=>view(false));$('learner-view').addEventListener('click',()=>view(true));$('select-learner').addEventListener('click',()=>{$('learner-copy').focus();$('learner-copy').select();$('select-status').textContent='Learner text selected. Use your device’s manual Copy command; no copy has been performed.';});$('reset').addEventListener('click',reset);reset();globalThis.App={normalize,compare,records,render,reset};</script></body></html>