Same word, different meaning Classroom activity

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>Same word, different meaning | Classroom activity</title>
<style>
:root{color-scheme:light;--ink:#202c41;--muted:#4d596b;--paper:#fffdf7;--line:#d4d7d8;--accent:#974025;--lime:#e3f2b2}
*{box-sizing:border-box}
body{margin:0;background:#efede5;color:var(--ink);font:17px/1.6 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
main{max-width:1000px;margin:auto;padding:30px 24px 36px}
header{border-top:6px solid var(--ink);padding-top:18px;margin-bottom:24px}
.eyebrow{margin:0 0 8px;color:var(--accent);font-weight:750;letter-spacing:.045em}
h1{font:700 clamp(30px,5vw,44px)/1.12 Georgia,serif;max-width:660px;margin:0 0 12px}
header p:last-child{margin:0;max-width:700px;color:var(--muted)}
nav{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 22px}
button,input,textarea{font:inherit}
button{cursor:pointer;border:1px solid var(--line);border-radius:9px;background:var(--paper);color:var(--ink);padding:12px 16px;min-height:48px;font-weight:650}
nav button{flex:1 1 160px;text-align:left;border-bottom:4px solid var(--line)}
nav button[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
button:hover{border-color:var(--accent)}
:focus-visible{outline:3px solid #965225;outline-offset:4px}
.lesson{background:var(--paper);border:1px solid #d6d3c8;border-radius:14px;overflow:hidden;box-shadow:0 8px 24px #202c410a}
.context{padding:24px;border-bottom:1px solid var(--line);background:#f8f4e9}
.context p{margin:0}
#roundLabel{font-weight:750;color:var(--accent)}
blockquote{font:500 clamp(25px,4vw,33px)/1.4 Georgia,serif;margin:12px 0 16px}
mark{background:var(--lime);color:var(--ink);padding:0 .12em}
.workspace{padding:24px}
h2{font-size:21px;line-height:1.4;margin:0 0 10px}
.instruction{color:var(--muted);margin:0 0 18px}
.relation-guide{font-size:16px;color:var(--muted);padding:14px 16px;border-left:4px solid var(--accent);background:#f5f2eb;margin-bottom:20px}
.relation-guide p{margin:0}.relation-guide p+p{margin-top:4px}
fieldset{min-width:0;margin:0 0 20px;border:1px solid var(--line);border-radius:10px;padding:14px}
legend{font-size:22px;font-weight:750;padding:0 8px}
.choices{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.choices label{display:flex;align-items:flex-start;gap:9px;border:1px solid var(--line);border-radius:7px;padding:12px 10px;cursor:pointer;font-size:16px}
.choices label:has(input:checked){background:var(--lime);border-color:#526b26}
input[type=radio]{flex:0 0 auto;width:19px;height:19px;margin:4px 0 0;accent-color:#364d17}
.row-feedback{margin:8px 0 0;font-size:16px;color:var(--muted)}
.row-feedback:empty{display:none}
label[for=reason]{display:block;font-weight:750;margin-top:4px}
.help{color:var(--muted);font-size:16px;margin:4px 0 10px}
textarea{width:100%;min-height:112px;resize:vertical;border:1px solid #8994a3;border-radius:8px;background:white;color:var(--ink);padding:12px}
.actions{display:flex;flex-wrap:wrap;gap:10px;margin:18px 0}
#check{background:var(--accent);color:#fff;border-color:var(--accent)}
#feedback{padding:16px;border:1px solid #c8d3af;border-radius:8px;background:#f0f5e4;font-weight:650;min-height:62px}
#feedback[data-kind=error]{background:#fff0e8;border-color:#b66f4a}
.teacher{border-top:1px dashed #a5a7b1;padding-top:22px;margin-top:24px}
#teacherKey{padding:18px;background:#f1edf8;border-radius:8px;margin-top:14px}
#teacherKey h3{font-size:20px;margin:0 0 10px}
#teacherKey ul{padding-left:22px;margin:12px 0}
#teacherKey li+li{margin-top:10px}
#teacherKey p{margin:8px 0}
.closing{border-top:1px solid var(--line);padding:22px 24px;background:#f8f4e9}
.closing p{margin:0}.closing p+p{margin-top:10px}
footer{margin-top:20px;font-size:16px;color:var(--muted)}
[hidden]{display:none!important}
@media(max-width:540px){main{padding:18px 12px 24px}.context,.workspace,.closing{padding:20px 16px}nav{gap:8px}nav button{flex-basis:90px;padding:10px;font-size:16px}.choices{grid-template-columns:minmax(0,1fr)}.choices label{padding:10px 12px}.actions button{flex:1 1 150px}blockquote{font-size:27px}fieldset{padding:12px}}
</style>
</head>
<body>
<main>
<header>
<p class="eyebrow">WORD RELATIONS · PARTNER PRACTICE</p>
<h1>Same word,<br>different meaning.</h1>
<p>Keep the sentence beside the choices. Sort each word, then explain the clue that helped you decide.</p>
</header>
<nav aria-label="Choose a context card">
<button type="button" id="round1" aria-pressed="true">01 · Sound</button>
<button type="button" id="round2" aria-pressed="false">02 · Weight</button>
<button type="button" id="round3" aria-pressed="false">03 · Brightness</button>
</nav>
<article class="lesson" aria-label="Word relation activity">
<section class="context" aria-labelledby="roundLabel">
<p id="roundLabel">Round 1 of 3 · Sound</p>
<blockquote id="sentence">“The hallway was <mark>quiet</mark>; no one spoke.”</blockquote>
<p id="targetSense"><strong>Target:</strong> quiet · sound sense</p>
</section>
<section class="workspace" aria-labelledby="sortHeading">
<h2 id="sortHeading">How does each word relate?</h2>
<p class="instruction">Choose one relation for each word in this sentence.</p>
<div class="relation-guide" id="relationHelp">
<p>Synonym: same or nearly the same meaning. Antonym: opposite meaning.</p>
<p>Unrelated here: neither the same nor opposite <em>target meaning</em>.</p>
</div>
<fieldset aria-describedby="relationHelp"><legend id="word0">silent</legend>
<div class="choices">
<label><input id="r0-s" type="radio" name="relation0" value="s">Synonym / near synonym</label>
<label><input id="r0-a" type="radio" name="relation0" value="a">Antonym</label>
<label><input id="r0-u" type="radio" name="relation0" value="u">Unrelated here</label>
</div><p id="result0" class="row-feedback"></p></fieldset>
<fieldset aria-describedby="relationHelp"><legend id="word1">noisy</legend>
<div class="choices">
<label><input id="r1-s" type="radio" name="relation1" value="s">Synonym / near synonym</label>
<label><input id="r1-a" type="radio" name="relation1" value="a">Antonym</label>
<label><input id="r1-u" type="radio" name="relation1" value="u">Unrelated here</label>
</div><p id="result1" class="row-feedback"></p></fieldset>
<fieldset aria-describedby="relationHelp"><legend id="word2">circular</legend>
<div class="choices">
<label><input id="r2-s" type="radio" name="relation2" value="s">Synonym / near synonym</label>
<label><input id="r2-a" type="radio" name="relation2" value="a">Antonym</label>
<label><input id="r2-u" type="radio" name="relation2" value="u">Unrelated here</label>
</div><p id="result2" class="row-feedback"></p></fieldset>
<label for="reason">Sentence clue and your reason</label>
<p class="help" id="reasonHelp">Name words from the sentence and explain one relationship. Your teacher or partner reviews this explanation.</p>
<textarea id="reason" aria-describedby="reasonHelp" placeholder="The clue is… This tells me…"></textarea>
<div class="actions">
<button id="check" type="button">Check relations</button>
<button id="reset" type="button">Clear this round</button>
</div>
<p id="feedback" role="status" aria-live="polite">Choose three relations and add a clue and reason.</p>
<section class="teacher" aria-label="Separate teacher key">
<button id="reveal" type="button" aria-expanded="false" aria-controls="teacherKey">Reveal teacher key</button>
<div id="teacherKey" hidden>
<h3 id="keyTitle">Teacher key · Sound</h3>
<p id="keyClue"></p>
<ul><li id="key0"></li><li id="key1"></li><li id="key2"></li></ul>
<p id="keyNote"></p>
</div>
</section>
</section>
<aside class="closing">
<h2>Discuss the switch</h2>
<p>Compare the weight and brightness cards. Why does <strong>heavy</strong> oppose <strong>light</strong> in one sentence and miss its meaning in the other?</p>
<p>On paper, record the full sentence, target sense, candidate, relation, clue, and reason. Keep the teacher key separate.</p>
</aside>
</article>
<footer>Three invented classroom contexts. Checks cover only these fixed word choices. Responses stay in this open page; they are not saved. Repeats are practice, not a measure of mastery.</footer>
<noscript>This activity needs JavaScript for answer checks. Use the three classroom contexts and teacher answers in the accompanying article for paper practice.</noscript>
</main>
<script>
(() => {
  'use strict';
  const contextCards = [
    {title:'Sound', sentence:'“The hallway was <mark>quiet</mark>; no one spoke.”', target:'quiet · sound sense', words:['silent','noisy','circular'], key:['s','a','u'], clue:'Sentence clue: “no one spoke.”', explanations:['Silent is a synonym for the stated auditory sense: it fits the absence of speech.','Noisy is an antonym: it describes the opposite sound condition.','Circular is unrelated to this sense: it describes shape, not sound.'], note:'Discuss strength: quiet can allow a little noise; silent can suggest none. The match applies to this card, not every use of quiet.'},
    {title:'Weight', sentence:'“The crane lifted a <mark>light</mark> parcel, not a heavy one.”', target:'light · weight sense', words:['lightweight','heavy','purple'], key:['s','a','u'], clue:'Sentence clue: “not a heavy one.”', explanations:['Lightweight is a synonym: it expresses relatively low weight.','Heavy is an antonym: it gives the opposing weight description.','Purple is unrelated to this sense: it describes color, not weight.'], note:'A parcel could be purple. That does not make purple a synonym or antonym for its weight. The sentence gives no measured mass.'},
    {title:'Brightness', sentence:'“The lamp made the room <mark>light</mark>, not dark.”', target:'light · brightness sense', words:['bright','dark','heavy'], key:['s','a','u'], clue:'Sentence clues: “lamp” and “not dark.”', explanations:['Bright is a near synonym: it describes illumination here.','Dark is an antonym: it contrasts with the lit condition.','Heavy is unrelated to brightness: the weight contrast belongs to the parcel sentence.'], note:'Lightweight does not describe brightness, and bright does not describe the parcel’s weight. Keep the sentence with the answer.'}
  ];
  const get = (selector) => document.querySelector(selector);
  const radioChoices = Array.from(document.querySelectorAll('input[type="radio"]'));
  const roundButtons = [get('#round1'),get('#round2'),get('#round3')];
  const reasonField = get('#reason');
  const feedbackBox = get('#feedback');
  const revealButton = get('#reveal');
  const teacherKey = get('#teacherKey');
  let currentRound = 0;
  const relationNames = {s:'synonym / near synonym', a:'antonym', u:'unrelated here'};

  function clearFeedback() {
    feedbackBox.textContent = 'Choose three relations and add a clue and reason.';
    feedbackBox.removeAttribute('data-kind');
    for (let i = 0; i < 3; i++) get('#result'+i).textContent = '';
  }
  function hideKey() {
    teacherKey.hidden = true;
    revealButton.setAttribute('aria-expanded','false');
    revealButton.textContent = 'Reveal teacher key';
  }
  function resetRound() {
    radioChoices.forEach((choice) => { choice.checked = false; });
    reasonField.value = '';
    clearFeedback();
    hideKey();
  }
  function setRound(index) {
    currentRound = index;
    const card = contextCards[index];
    get('#roundLabel').textContent = 'Round '+(index+1)+' of 3 · '+card.title;
    get('#sentence').innerHTML = card.sentence;
    get('#targetSense').textContent = 'Target: '+card.target;
    get('#keyTitle').textContent = 'Teacher key · '+card.title;
    get('#keyClue').textContent = card.clue;
    get('#keyNote').textContent = card.note;
    for (let i = 0; i < 3; i++) {
      get('#word'+i).textContent = card.words[i];
      get('#key'+i).textContent = card.explanations[i];
    }
    roundButtons.forEach((button,i) => button.setAttribute('aria-pressed',String(i===index)));
    resetRound();
  }
  roundButtons.forEach((button,index) => button.addEventListener('click',() => setRound(index)));
  radioChoices.forEach((choice) => choice.addEventListener('change',clearFeedback));
  reasonField.addEventListener('input',clearFeedback);
  get('#reset').addEventListener('click',resetRound);
  revealButton.addEventListener('click',() => {
    const shouldOpen = teacherKey.hidden;
    teacherKey.hidden = !shouldOpen;
    revealButton.setAttribute('aria-expanded',String(shouldOpen));
    revealButton.textContent = shouldOpen ? 'Hide teacher key' : 'Reveal teacher key';
  });
  get('#check').addEventListener('click',() => {
    clearFeedback();
    const answers = [0,1,2].map((i) => get('input[name="relation'+i+'"]:checked'));
    if (answers.some((answer) => !answer) || !reasonField.value.trim()) {
      feedbackBox.textContent = 'Before checking, choose one relation for every word and add a sentence clue and reason.';
      feedbackBox.setAttribute('data-kind','error');
      return;
    }
    const card = contextCards[currentRound];
    let correctCount = 0;
    answers.forEach((answer,i) => {
      const correct = answer.value === card.key[i];
      if (correct) correctCount++;
      get('#result'+i).textContent = card.words[i]+': '+(correct ? 'Correct — '+relationNames[card.key[i]]+'.' : 'Try again. Recheck the '+card.title.toLowerCase()+' meaning.');
    });
    feedbackBox.textContent = correctCount+' of 3 relations correct. '+(correctCount===3 ? 'Discuss your explanation with a teacher or partner.' : 'Revisit the sentence clues, then try again.');
  });
  setRound(0);
})();
</script>
</body>
</html>