Family paths • whose relationship? — Trace named parent/sibling relationships from a stated person's viewpoint and select the corresponding aunt, cousin or niece word without…

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>Family paths • whose relationship?</title><style>*{box-sizing:border-box}body{margin:0;background:var(--bg,#f3f7fa);color:var(--ink,#203342);font:16px/1.55 system-ui,Segoe UI,sans-serif}main{max-width:1100px;margin:auto;padding:28px 30px 50px}h1{font-size:clamp(27px,3.5vw,40px);line-height:1.18;letter-spacing:-.035em;margin:8px 0 12px}h2{font-size:21px;line-height:1.35;margin:0 0 16px}h3{font-size:18px}.eyebrow{color:var(--accent,#176783);font-size:12px;letter-spacing:.12em;font-weight:800;text-transform:uppercase}.intro,.muted,small{color:#516272}.intro{margin:0 0 24px}.panel{padding:24px;border:1px solid var(--line,#d6e0e7);border-radius:12px;background:white;margin:18px 0}.grid{display:grid;grid-template-columns:1fr 1fr;gap:22px}.grid>*{min-width:0}.controls{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:16px 0}button,input,textarea,select{font:inherit}button{border:1px solid var(--accent,#176783);background:var(--accent,#176783);color:white;padding:10px 16px;min-height:44px;border-radius:7px;font-weight:700;cursor:pointer}button.secondary{background:white;color:var(--accent,#176783)}button[aria-pressed=true]{background:var(--tint,#e3f2f8);color:var(--ink,#203342);box-shadow:inset 0 0 0 2px var(--accent,#176783)}button:hover{filter:brightness(.96)}:focus-visible{outline:3px solid #d56b00;outline-offset:3px}label{display:block;margin:12px 0 5px;font-size:14px;font-weight:650}input:not([type=checkbox]),select,textarea{width:100%;padding:10px 12px;min-height:44px;border:1px solid #94a5b2;background:white;color:inherit;border-radius:7px}textarea{resize:vertical;min-height:120px}input[type=checkbox]{width:20px;height:20px;margin-right:9px}label.inline{display:flex;align-items:center;font-weight:500;gap:7px}.result{padding:24px;background:var(--tint,#e3f2f8);border:1px solid var(--line,#c8dce7);border-radius:12px}.big{font-size:clamp(30px,5vw,48px);font-weight:780;line-height:1.25;letter-spacing:-.035em;margin:10px 0}.trace{font:15px/1.7 ui-monospace,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}.error{color:#a12820;font-weight:650;min-height:24px}.table-wrap{overflow-x:auto}table{border-collapse:collapse;width:100%;font-size:15px}th,td{text-align:left;border-bottom:1px solid var(--line,#d6e0e7);padding:12px 9px;vertical-align:top}th{font-size:12px;text-transform:uppercase;letter-spacing:.03em;color:#516272}code,pre,.code{font:14px/1.65 ui-monospace,Consolas,monospace}pre{white-space:pre-wrap;overflow-wrap:anywhere;background:var(--tint,#eef3f7);padding:16px;border-radius:6px}details{border-top:1px solid var(--line,#d6e0e7);margin:24px 0;padding-top:16px}summary{cursor:pointer;font-weight:700;min-height:44px}footer{border-top:1px solid var(--line,#d6e0e7);margin-top:26px;padding-top:16px;font-size:13px;color:#516272}.bar{height:16px;background:#dce4ea;border-radius:20px;overflow:hidden;margin:12px 0}.bar span{display:block;height:100%;background:var(--accent,#176783)}[hidden]{display:none!important}@media(max-width:720px){main{padding:20px}.grid{grid-template-columns:1fr;gap:12px}.panel,.result{padding:20px}}@media(max-width:400px){main{padding:16px}.panel,.result{padding:16px}button{padding:10px 13px}} .sheet{background:white;border:1px solid var(--line,#d6e0e7);padding:26px}.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}.tiles>article{padding:20px;background:white;border:1px solid var(--line,#d6e0e7)}.badge{display:inline-block;border-radius:30px;padding:4px 11px;background:var(--tint,#e3f3fa);font-size:13px;font-weight:750}.preview{white-space:pre-wrap;overflow-wrap:anywhere}.schedule-row{display:grid;grid-template-columns:1fr 100px 100px;gap:15px;align-items:center;border-bottom:1px solid var(--line,#d6e0e7);padding:12px 0}.schedule-row label{margin:0}.schedule-row small{display:block}.schedule-row input{margin-top:6px}.export textarea{min-height:180px}.note{border-left:4px solid var(--accent,#176783);background:var(--tint,#e3f3fa);padding:16px}svg{max-width:100%;height:auto}button{overflow-wrap:anywhere}h2,h3,p{overflow-wrap:anywhere}@media(max-width:720px){.tiles{grid-template-columns:1fr}.schedule-row{grid-template-columns:1fr 80px}.schedule-row .range{grid-column:1/3}.sheet{padding:20px}}@media(max-width:400px){.sheet{padding:16px}}
body{--accent:#6d4d98;--tint:#f0eafa;--bg:#f7f5fb;--ink:#3d3152}.family-map{background:white;padding:25px;border-radius:20px;border:2px solid #dfd3ed}.parents{display:grid;grid-template-columns:1fr 100px 1fr;align-items:center;gap:14px}.person{display:block;padding:14px;background:#f8f5fc;border:2px solid #dbcee8;border-radius:12px}.person small{display:block}.person[data-path=true]{border-color:#6d4d98;background:#eee5fa;box-shadow:0 0 0 2px #6d4d9820}.branches{display:grid;grid-template-columns:1fr 1fr;gap:30px}.branches>div{border-top:3px solid #c4b3d7;margin-top:18px}.children{display:grid;grid-template-columns:1fr 1fr;gap:12px}.sibling{text-align:center;font-size:13px}.question-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}.question{background:#fff;padding:22px;border-radius:12px;border:1px solid #d9cce8}.question h3{margin:8px 0}.feedback{min-height:48px}@media(max-width:720px){.question-grid{grid-template-columns:1fr}.parents{grid-template-columns:1fr 72px 1fr;gap:7px}.family-map{padding:17px}.branches{gap:16px}.children{grid-template-columns:1fr}.person{padding:10px}.person small{font-size:12px}}</style></head><body><main>
<header><span class="eyebrow">Word paths / fictional family</span><h1>Whose relationship do you mean?</h1><p class="intro">Start with the named viewpoint, then follow only the supplied links.</p></header>
<section id="family-map" class="family-map"><div class="parents"><div id="person-leo" class="person"><b>Leo · P01</b><small>Maya’s brother</small></div><span class="sibling">siblings ↔</span><div id="person-maya" class="person"><b>Maya · P02</b><small>Leo’s sister</small></div></div><div class="branches"><div><p>Leo is parent of ↓</p><div class="children"><span id="person-nora" class="person"><b>Nora · P03</b><small>Leo’s daughter</small></span><span id="person-ivan" class="person"><b>Ivan · P04</b><small>Leo’s child</small></span></div></div><div><p>Maya is parent of ↓</p><span id="person-kai" class="person"><b>Kai · P05</b><small>Maya’s child</small></span></div></div><p id="path" class="note" aria-live="polite">Choose a question and trace its named people. The links stay the same.</p></section>
<div class="controls"><b id="score" aria-live="polite">0 correct / 4 · 0 checked</b><button type="button" id="reset" class="secondary">Reset all answers</button><button type="button" id="teacher" class="secondary">Teacher key</button></div>
<section id="learner" class="question-grid"><article class="question"><span class="eyebrow">Q1 / viewpoint: Nora</span><h3>Who is Maya to Nora?</h3><label for="answer-0">Relationship</label><select id="answer-0"><option value="">Choose a word</option><option>aunt</option><option>cousin</option><option>niece</option></select><div class="controls"><button type="button" id="check-0">Check Q1</button><button type="button" id="trace-0" class="secondary">Trace this question</button></div><p id="feedback-0" class="feedback" aria-live="polite">Not checked.</p></article><article class="question"><span class="eyebrow">Q2 / viewpoint: Nora</span><h3>Who is Kai to Nora?</h3><label for="answer-1">Relationship</label><select id="answer-1"><option value="">Choose a word</option><option>aunt</option><option>cousin</option><option>niece</option></select><div class="controls"><button type="button" id="check-1">Check Q2</button><button type="button" id="trace-1" class="secondary">Trace this question</button></div><p id="feedback-1" class="feedback" aria-live="polite">Not checked.</p></article><article class="question"><span class="eyebrow">Q3 / viewpoint: Kai</span><h3>Who is Nora to Kai?</h3><label for="answer-2">Relationship</label><select id="answer-2"><option value="">Choose a word</option><option>aunt</option><option>cousin</option><option>niece</option></select><div class="controls"><button type="button" id="check-2">Check Q3</button><button type="button" id="trace-2" class="secondary">Trace this question</button></div><p id="feedback-2" class="feedback" aria-live="polite">Not checked.</p></article><article class="question"><span class="eyebrow">Q4 / viewpoint: Maya</span><h3>Who is Nora to Maya?</h3><label for="answer-3">Relationship</label><select id="answer-3"><option value="">Choose a word</option><option>aunt</option><option>cousin</option><option>niece</option></select><div class="controls"><button type="button" id="check-3">Check Q4</button><button type="button" id="trace-3" class="secondary">Trace this question</button></div><p id="feedback-3" class="feedback" aria-live="polite">Not checked.</p></article></section>
<section id="teacher-key" class="panel" hidden><h2>Teacher reference · separate from learner work</h2><ol><li>Nora → parent Leo → sister Maya. Maya is Nora’s aunt.</li><li>Nora → parent Leo → sister Maya → child Kai. Kai is Nora’s cousin.</li><li>Kai → parent Maya → brother Leo → daughter Nora. Nora is Kai’s cousin.</li><li>Maya → brother Leo → daughter Nora. Nora is Maya’s niece.</li></ol><button type="button" id="student" class="secondary">Return to clean learner view</button><p>Returning clears revealed paths and all learner answers. No key is included in the learner text below.</p></section>
<details><summary>Clean learner text and supplied facts</summary><p>Leo and Maya are siblings. Leo is Maya’s brother; Maya is Leo’s sister. Nora is Leo’s daughter. Ivan is Leo’s child. Kai is Maya’s child. No gender is supplied for Ivan or Kai. No partner, household or other parent is supplied.</p><label for="learner-text">Manual-copy learner worksheet</label><textarea id="learner-text" readonly>Fictional people: Leo (P01), Maya (P02), Nora (P03), Ivan (P04), Kai (P05).
Leo is Maya’s brother; Maya is Leo’s sister. Leo is parent of Nora and Ivan. Nora is Leo’s daughter. Maya is parent of Kai. No gender supplied for Ivan or Kai.
Q1 Who is Maya to Nora? ______
Q2 Who is Kai to Nora? ______
Q3 Who is Nora to Kai? ______
Q4 Who is Nora to Maya? ______
Options for each question: aunt / cousin / niece.</textarea><button type="button" id="select-learner" class="secondary">Select learner text</button><small>Copy manually; no teacher answers in this text.</small></details>
<footer>This original fictional chart is a bounded English-vocabulary exercise, not a universal family model. Chart position adds no relationships. No real family information is requested; answers are local and are not saved or sent.</footer>
</main><script>const $=id=>document.getElementById(id);const on=(id,e,fn)=>$(id).addEventListener(e,fn);const txt=(id,v)=>$(id).textContent=v;const esc=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));const positive=x=>String(x).trim()!==''&&Number.isFinite(Number(x))&&Number(x)>0;const num=x=>Number(x.toPrecision(10)).toString();function enter(id,fn){on(id,'keydown',e=>{if(e.key==='Enter'&&!e.isComposing&&e.keyCode!==229){e.preventDefault();fn()}})}function selectText(id){$(id).focus();$(id).select()}
function isoDay(s){if(!/^\d{4}-\d{2}-\d{2}$/.test(s))throw Error('Use a real calendar date as YYYY-MM-DD.');const d=new Date(s+'T00:00:00Z');if(!Number.isFinite(d.getTime())||d.toISOString().slice(0,10)!==s)throw Error('Use a real calendar date as YYYY-MM-DD.');return d.getTime()/86400000}


const questions=[{view:'Nora',target:'Maya',answer:'aunt',people:['nora','leo','maya'],path:'Nora → parent Leo → sister Maya. Maya is Nora’s aunt.'},{view:'Nora',target:'Kai',answer:'cousin',people:['nora','leo','maya','kai'],path:'Nora → parent Leo → sister Maya → child Kai. Kai is Nora’s cousin.'},{view:'Kai',target:'Nora',answer:'cousin',people:['kai','maya','leo','nora'],path:'Kai → parent Maya → brother Leo → daughter Nora. Nora is Kai’s cousin.'},{view:'Maya',target:'Nora',answer:'niece',people:['maya','leo','nora'],path:'Maya → brother Leo → daughter Nora. Nora is Maya’s niece.'}];let evaluated=[null,null,null,null];
function score(){txt('score',evaluated.filter(x=>x===true).length+' correct / 4 · '+evaluated.filter(x=>x!==null).length+' checked')}
function trace(i,reveal){const q=questions[i];for(const n of ['leo','maya','nora','ivan','kai'])$('person-'+n).setAttribute('data-path',String(q.people.includes(n)));txt('path',reveal?q.path:'Viewpoint: '+q.view+'. Target: '+q.target+'. Follow the highlighted supplied links; choose the relationship in Q'+(i+1)+'.')}
function checkAnswer(i){const value=$('answer-'+i).value,q=questions[i];if(!['aunt','cousin','niece'].includes(value)){evaluated[i]=null;txt('feedback-'+i,'Choose aunt, cousin, or niece before checking.');score();return}evaluated[i]=value===q.answer;let f=evaluated[i]?'Correct. '+q.path:'Try again. '+q.path;if(i===0&&value==='niece')f='Direction reversed: the question asks Maya-to-Nora. Maya is Nora’s aunt; Nora is Maya’s niece.';if(i===3&&value==='aunt')f='Start from Maya. Nora is the daughter of Maya’s brother, so Nora is Maya’s niece.';txt('feedback-'+i,f);trace(i,true);score()}
function reset(){evaluated=[null,null,null,null];for(let i=0;i<4;i++){$('answer-'+i).value='';txt('feedback-'+i,'Not checked.')}for(const n of ['leo','maya','nora','ivan','kai'])$('person-'+n).setAttribute('data-path','false');txt('path','Choose a question and trace its named people. The links stay the same.');score()}
for(let i=0;i<4;i++){on('check-'+i,'click',()=>checkAnswer(i));on('trace-'+i,'click',()=>trace(i,false));on('answer-'+i,'change',()=>{evaluated[i]=null;txt('feedback-'+i,'Answer changed; check again.');score();trace(i,false)})}
on('reset','click',reset);on('teacher','click',()=>{$('learner').hidden=true;$('teacher-key').hidden=false;$('teacher').hidden=true});on('student','click',()=>{reset();$('learner').hidden=false;$('teacher-key').hidden=true;$('teacher').hidden=false});on('select-learner','click',()=>selectText('learner-text'));score();
</script></body></html>