Shape studio • look for the attributes — Help learners identify shapes by defining attributes across rotation and size changes, and explain why an open three-segment drawing is…
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>Shape studio • look for the attributes</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}}
body{--bg:#f5f7ff;--ink:#26325b;--accent:#574caa;--tint:#eeeafa;--line:#dbdef0}h1{max-width:740px;font-size:clamp(28px,4vw,43px)}.shape-board{display:grid;grid-template-columns:repeat(5,1fr);gap:14px}.shape{padding:12px;background:white;color:#26325b;border:2px solid #d6daed;display:flex;align-items:center;flex-direction:column;border-radius:18px}.shape:hover{border-color:#574caa}.shape svg{width:100%;max-width:180px;height:145px}.shape svg polygon,.shape svg rect{fill:#f3c86a;stroke:#58447d;stroke-width:4;stroke-linejoin:round}.shape svg path{fill:none;stroke:#58447d;stroke-width:4;stroke-linecap:round}.shape circle{fill:#58447d}.shape-label{align-self:flex-start;font-size:15px}.selection{font-size:14px}.feedback{padding:22px;background:#e9e4fb;border-radius:12px;margin:18px 0;font-size:17px;line-height:1.7}.square-stage{text-align:center}.square-stage svg{width:190px;max-width:100%;height:190px}.square-stage rect{fill:#84d2c6;stroke:#275b62;stroke-width:4}.square-stage path{fill:none;stroke:#275b62;stroke-width:2}@media(max-width:720px){.shape-board{grid-template-columns:repeat(3,1fr)}.shape svg{height:110px}}@media(max-width:400px){.shape-board{grid-template-columns:repeat(2,1fr);gap:10px}.shape svg{height:100px}}</style></head><body><main>
<header><span class="eyebrow">Shape studio / original 2D practice</span><h1>Select every closed three-sided shape.</h1><p class="intro">Tap a drawing to select it. You can choose more than one.</p></header>
<section class="shape-board" aria-label="Drawing choices"><button type="button" class="shape" id="shape-T1" aria-pressed="false" aria-label="T1. A closed scalene triangle with three straight sides. Select drawing."><span class="shape-label">T1</span><svg viewBox="0 0 160 140" aria-hidden="true"><polygon points="35,100 125,100 60,25" transform=""/></svg><span id="mark-T1" class="selection">Select</span></button><button type="button" class="shape" id="shape-T2" aria-pressed="false" aria-label="T2. A smaller, uniformly scaled and rotated copy of T1. Select drawing."><span class="shape-label">T2</span><svg viewBox="0 0 160 140" aria-hidden="true"><polygon points="35,100 125,100 60,25" transform="translate(80 70) rotate(65) scale(.65) translate(-80 -70)"/></svg><span id="mark-T2" class="selection">Select</span></button><button type="button" class="shape" id="shape-S1" aria-pressed="false" aria-label="S1. A square with four equal sides and four right angles. Select drawing."><span class="shape-label">S1</span><svg viewBox="0 0 160 140" aria-hidden="true"><rect x="40" y="30" width="80" height="80" transform=""/></svg><span id="mark-S1" class="selection">Select</span></button><button type="button" class="shape" id="shape-S2" aria-pressed="false" aria-label="S2. The same square rotated 45 degrees. Select drawing."><span class="shape-label">S2</span><svg viewBox="0 0 160 140" aria-hidden="true"><rect x="40" y="30" width="80" height="80" transform="rotate(45 80 70)"/></svg><span id="mark-S2" class="selection">Select</span></button><button type="button" class="shape" id="shape-O1" aria-pressed="false" aria-label="O1. Three consecutive sides of a square; endpoints do not meet. Select drawing."><span class="shape-label">O1</span><svg viewBox="0 0 160 140" aria-hidden="true"><path d="M 40 35 L 120 35 L 120 115 L 40 115"/><circle cx="40" cy="35" r="4"/><circle cx="40" cy="115" r="4"/></svg><span id="mark-O1" class="selection">Select</span></button></section><div class="controls"><button type="button" id="check">Check my choices</button><button type="button" id="reset" class="secondary">Start again</button></div><section id="feedback" class="feedback" aria-live="polite"><b>Your turn.</b> Look at the edges, corners, and whether the endpoints meet.</section>
<section class="panel"><div class="grid"><div><span class="eyebrow">Turn it and think</span><h2>Does turning S1 change its name?</h2><p>Follow the same drawing as it turns. Decide using its sides and angles.</p><div class="controls"><button type="button" id="rotate" class="secondary">Turn 45°</button><button type="button" id="square-yes">Still a square</button><button type="button" id="square-no" class="secondary">Different shape</button></div><p id="rotation-feedback" aria-live="polite">Choose an answer after inspecting the drawing.</p></div><div class="square-stage"><svg viewBox="0 0 180 180" aria-label="S1, the same square, currently rotated zero degrees" role="img" id="square-svg"><g id="square-turn"><rect x="45" y="45" width="90" height="90"/><path d="M45 60 L60 60 L60 45"/></g></svg><p id="angle">S1 • rotation 0°</p></div></div></section>
<details><summary>Text descriptions of the drawings</summary><ul><li><b>T1:</b> A closed scalene triangle with three straight sides.</li><li><b>T2:</b> A smaller, uniformly scaled and rotated copy of T1.</li><li><b>S1:</b> A square with four equal sides and four right angles.</li><li><b>S2:</b> The same square rotated 45 degrees.</li><li><b>O1:</b> Three consecutive sides of a square; endpoints do not meet.</li></ul></details>
<footer>Original schematic learning materials. Feedback appears after an attempt; this page collects no student data and saves no scores. Teachers should review the exercise for their own classroom context.</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=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[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()}
const chosen=new Set();let angle=0;
function shapeFeedback(selection){if(selection.length===0)return 'Unanswered: choose at least one drawing, then check.';const right=selection.length===2&&selection.includes('T1')&&selection.includes('T2');return (right?'Correct: T1 and T2 are the closed triangles.':'Try the attributes again. The closed triangles are T1 and T2.')+' T1 and T2 each have 3 straight sides, 3 corners, and no gap. Rotation and uniform size changes preserve those attributes. S1 and S2 each have 4 sides. O1 has 3 segments, but its endpoints do not meet; closing it would create a fourth side, not a triangle.'}
for(const id of ['T1','T2','S1','S2','O1'])on('shape-'+id,'click',()=>{if(chosen.has(id))chosen.delete(id);else chosen.add(id);$('shape-'+id).setAttribute('aria-pressed',String(chosen.has(id)));txt('mark-'+id,chosen.has(id)?'Selected ✓':'Select');txt('feedback','Choices changed. Check to see the attribute evidence.')});
on('check','click',()=>txt('feedback',shapeFeedback([...chosen])));
function turn(){$('square-turn').setAttribute('transform','rotate('+angle+' 90 90)');$('square-svg').setAttribute('aria-label','S1, the same square, currently rotated '+angle+' degrees');txt('angle','S1 • rotation '+angle+'°')}
on('rotate','click',()=>{angle=(angle+45)%360;turn();txt('rotation-feedback','Drawing turned. Does its classification change?')});on('square-yes','click',()=>txt('rotation-feedback','Correct. Its orientation changed; its square attributes did not: 4 equal sides and 4 right angles.'));on('square-no','click',()=>txt('rotation-feedback','Look again: it still has 4 equal sides and 4 right angles. Turning changes orientation, so S1 is still a square.'));
on('reset','click',()=>{chosen.clear();for(const id of ['T1','T2','S1','S2','O1']){$('shape-'+id).setAttribute('aria-pressed','false');txt('mark-'+id,'Select')}angle=0;turn();txt('feedback','Your turn. Look at the edges, corners, and whether the endpoints meet.');txt('rotation-feedback','Choose an answer after inspecting the drawing.')});
</script></body></html>