Equipment return · course companion — Build a small slide-based learning module and distinguish slide progress, option interaction, submitted answer and container completion…

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>Equipment return · course companion</title><style>
*{box-sizing:border-box}body{margin:0;background:#edf1f8;color:#253551;font:16px/1.5 system-ui,sans-serif}main{max-width:1100px;margin:auto;padding:29px}h1{font-size:clamp(30px,4vw,43px);line-height:1.15;letter-spacing:-.04em;margin:5px 0 10px}h2{font-size:27px;line-height:1.2;margin:0 0 16px}p{margin:0 0 12px}.eyebrow{font-size:11px;text-transform:uppercase;letter-spacing:.13em;font-weight:750;color:#657a9c}.small{font-size:13px;color:#65728b}.deck{margin-top:24px;border-radius:14px;overflow:hidden;background:white;border:1px solid #cfdaec}.slide{padding:30px;min-height:360px;display:grid;grid-template-columns:1.2fr 1fr;gap:25px;align-items:center}.illustration{background:#e9effc;border-radius:12px;padding:20px;text-align:center}.locker{max-width:180px;height:240px;border-radius:8px;background:#4972b7;margin:auto;border:5px solid #254d89;position:relative;box-shadow:8px 8px 0 #b8caeb}.locker:before{content:'';position:absolute;left:18px;right:18px;top:22px;border-top:5px double #b7cbed;height:25px;border-bottom:5px double #b7cbed}.locker:after{content:'';position:absolute;right:15px;top:110px;height:45px;width:7px;border-radius:4px;background:#c7d8f4}.labelplate{position:absolute;left:28px;right:28px;top:75px;background:#fff9db;color:#183b69;font:800 34px system-ui;padding:9px;border-radius:4px}.equipment{font-size:66px;line-height:1;margin:25px 0;color:#3c65a0}.choices{display:flex;gap:10px;flex-wrap:wrap;margin:22px 0}.choices button{flex:1;font-size:24px;min-height:65px;background:#fff;color:#335b9a;border:2px solid #9fb8df}.choices button[aria-pressed=true]{background:#315d9e;color:white;border-color:#315d9e}.navigation{background:#f5f8ff;border-top:1px solid #d5e1f3;padding:17px 23px;display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}.tabs{display:flex;gap:7px;flex-wrap:wrap}button{font:700 14px system-ui;min-height:44px;border:1px solid #315d9e;border-radius:7px;background:#315d9e;color:white;padding:10px 16px;cursor:pointer}button.secondary{background:white;color:#315d9e}.tabs button[aria-pressed=true]{background:#315d9e;color:white}button:disabled{opacity:.45;cursor:default}:focus-visible{outline:3px solid #c8812c;outline-offset:3px}.feedback{background:#eff4fd;border-left:4px solid #6086c2;padding:14px;font-size:15px;min-height:60px}.ledger{margin-top:25px;background:white;border:1px solid #cfdaec;border-radius:12px;padding:24px}.ledger h2{font-size:22px}.logrow{display:grid;grid-template-columns:32px 100px 1fr;gap:10px;padding:12px 0;border-top:1px solid #e1e7f0;font-size:13px}.verb{font-weight:750;color:#315d9e}.badges{display:flex;gap:10px;flex-wrap:wrap;margin:15px 0}.badge{background:#e8effa;color:#365f99;border-radius:5px;padding:8px 12px;font-size:14px}.sum{background:#edf4fc;border-radius:9px;padding:22px}.sum strong{display:block;margin-bottom:9px;font-size:19px}.lower{font-size:13px;color:#65728b;margin:25px 0;max-width:100ch}[hidden]{display:none!important}@media(max-width:720px){main{padding:22px 16px}.slide{padding:22px;grid-template-columns:1fr;min-height:0}.illustration{max-width:320px;width:100%;margin:auto}.locker{height:180px;max-width:150px}.locker:after{top:100px}.labelplate{top:62px;font-size:29px}.navigation{padding:15px}.navigation>button{width:100%}.tabs{width:100%}.tabs button{flex:1}.logrow{grid-template-columns:24px 90px 1fr}.ledger{padding:20px}}@media(max-width:380px){main{padding:20px 12px}.tabs button{padding:10px;font-size:12px}.choices button{font-size:22px}}
</style></head><body><main><p class="eyebrow">Original learning sequence · HTML companion</p><h1>Return it to the matching locker.</h1><p>Inspect the supplied label, then choose the same identifier.</p><section class="deck"><div id="slide-1" class="slide"><div><p class="eyebrow">Authored slide 1 / 3 · context</p><h2>A place for the practice equipment</h2><p>Return the practice equipment to the locker whose ID matches its label.</p><p class="small">Next, inspect the fictional locker label. Then choose from L1, L2, and L3.</p><div class="equipment" aria-hidden="true">▣ → ▯</div></div><div class="illustration"><div class="locker" role="img" aria-label="An original unnumbered practice locker"></div></div></div><div id="slide-2" class="slide" hidden><div><p class="eyebrow">Authored slide 2 / 3 · evidence</p><h2>Read the label.</h2><p>The supplied fictional locker label reads <strong>L2</strong>.</p><p>Keep both the letter and the number when you choose the matching ID.</p></div><div class="illustration"><div class="locker" role="img" aria-label="Fictional locker with label L2"><span class="labelplate">L2</span></div></div></div><div id="slide-3" class="slide" hidden><div><p class="eyebrow">Authored slide 3 / 3 · response</p><h2>Which ID matches the label?</h2><p>Choose one, then press Check to submit it locally.</p><div class="choices"><button id="option-l1" type="button" aria-pressed="false">L1</button><button id="option-l2" type="button" aria-pressed="false">L2</button><button id="option-l3" type="button" aria-pressed="false">L3</button></div><button id="check" type="button">Check response</button><p id="selection-status" class="small" style="margin-top:12px">No option selected.</p></div><div class="feedback" id="feedback" role="status">A selection is not yet a submitted answer.</div></div><div id="sum-up" class="slide" hidden><div><p class="eyebrow">Local sum-up model · separate from authored slides</p><h2>You reached the review screen.</h2><p>Navigation and a submitted question response are different records.</p><div class="badges"><span class="badge">Navigation reached</span><span id="question-status" class="badge">Question not submitted</span></div></div><div class="sum"><strong id="question-outcome">No submitted answer · score unverified</strong><p id="summary-feedback">Reaching this screen does not supply a missing response or score.</p><p class="small">This is a local explanation of the native sum-up distinction, not an H5P container event.</p></div></div><div class="navigation"><div class="tabs"><button type="button" id="nav-1" class="secondary" aria-pressed="true">1 · Context</button><button type="button" id="nav-2" class="secondary" aria-pressed="false">2 · Label</button><button type="button" id="nav-3" class="secondary" aria-pressed="false">3 · Question</button></div><button id="next" type="button">Next slide</button></div></section><section class="ledger"><div style="display:flex;justify-content:space-between;gap:15px;align-items:center;flex-wrap:wrap"><h2>Local action trace</h2><button id="reset" type="button" class="secondary">Start a fresh local trace</button></div><p class="small">Local actions are paired with source-described native event concepts. Native payloads, object IDs, LMS/LRS storage, and versions are unverified.</p><div class="badges"><span class="badge" id="answer-count">0 local submissions</span><span class="badge" id="completion-count">0 local sum-up visits</span></div><p id="empty-trace" class="small">No local actions recorded yet.</p><div id="trace"></div></section><footer class="lower"><p>The target native module has three authored slides plus a configured native sum-up screen. This self-contained companion teaches the original locker task and models the action distinctions; it does not create an .h5p package, run H5P libraries, emit/capture native xAPI, collect learner identities, send grades, or establish LMS/LRS storage. Host settings may permit or block unchecked navigation and require their own actual test.</p><p>The only authored key is L2. A correct response to this task is not broader mastery. The trace lasts only in this open page. Package revision, content-type/library versions, host configuration, native object/context IDs, and actual native payload observations remain unsupplied.</p></footer></main><script>
'use strict';const $=id=>document.getElementById(id);let slide=1,selected=null,submitted=null,events=[];
function add(verb,scope,action,response=null,score=null){events.push({sequence:events.length+1,verb,scope,action,response,score});}
function outcome(answer){return answer==='L2'?{score:1,message:'The supplied label reads L2, so L2 matches this task.'}:{score:0,message:'The supplied label reads L2, not '+answer+'. Inspect the label, then try again.'};}
function render(){for(let i=1;i<=3;i++){$('slide-'+i).hidden=slide!==i;$('nav-'+i).setAttribute('aria-pressed',String(slide===i));}$('sum-up').hidden=slide!==4;$('next').disabled=slide===4;$('next').textContent=slide===3?'Review local sum-up':slide===4?'At local sum-up':'Next slide';for(const id of['L1','L2','L3'])$('option-'+id.toLowerCase()).setAttribute('aria-pressed',String(selected===id));$('selection-status').textContent=selected?'Selected '+selected+(submitted?' · checked locally':' · not submitted'):'No option selected.';$('question-status').textContent=submitted?'Question submitted locally':'Question not submitted';$('question-outcome').textContent=submitted?'Submitted '+submitted.response+' · '+submitted.score+'/1 for this task':'No submitted answer · score unverified';$('summary-feedback').textContent=submitted?outcome(submitted.response).message+' A checked response is distinct from navigation and does not establish mastery.':'Reaching this screen does not supply a missing response or score.';$('answer-count').textContent=events.filter(e=>e.verb==='answered').length+' local submissions';$('completion-count').textContent=events.filter(e=>e.verb==='completed').length+' local sum-up visits';$('trace').replaceChildren();$('empty-trace').hidden=events.length>0;for(const e of events){let row=document.createElement('div');row.className='logrow';for(const [text,cls]of[[e.sequence,''],[e.verb,'verb'],[e.scope+' · '+e.action+(e.response?' · response '+e.response:'')+(e.score!==null?' · score '+e.score+'/1':''),'']]){let span=document.createElement('span');span.textContent=text;span.className=cls;row.appendChild(span);}$('trace').appendChild(row);}}
function navigate(next){if(next===slide)return;slide=next;add(next===4?'completed':'progressed','presentation model',next===4?'Reached local sum-up; native trigger not captured':'Changed authored slide to '+next);render();}
for(let n=1;n<=3;n++)$('nav-'+n).addEventListener('click',()=>navigate(n));$('next').addEventListener('click',()=>{if(slide<4)navigate(slide+1);});for(const id of['L1','L2','L3'])$('option-'+id.toLowerCase()).addEventListener('click',()=>{selected=id;submitted=null;add('interacted','question model','Selected option',id);$('feedback').textContent='Selected '+id+'. Press Check to submit; this selection has no score yet.';render();});$('check').addEventListener('click',()=>{if(!selected){$('feedback').textContent='Incomplete: choose L1, L2, or L3 before checking.';return;}const r=outcome(selected);submitted={response:selected,score:r.score};add('answered','question model','Checked response',selected,r.score);$('feedback').textContent=r.message;render();});$('reset').addEventListener('click',()=>{slide=1;selected=null;submitted=null;events=[];$('feedback').textContent='A selection is not yet a submitted answer.';render();});render();
</script></body></html>