Compare two founder snapshots and trace proposed features to the problems they assume

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 returns · Lean Canvas assumptions</title><style>*{box-sizing:border-box}body{margin:0;background:#f3f0e9;color:#443e34;font:16px/1.55 system-ui,sans-serif}main{max-width:1040px;margin:auto;padding:24px}h1{font-size:34px;line-height:1.16}h2{font-size:24px}h3{font-size:19px}.eyebrow{letter-spacing:.06em;color:#82735f}.card{padding:20px;margin:18px 0;background:white;border:1px solid #d1c6b1;border-radius:6px}.canvas{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.canvas button{text-align:left;background:#fff}.canvas strong{display:block}.canvas span{display:block;margin-top:10px}.tabs{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0}button,textarea{font:inherit;color:inherit}button{min-height:44px;padding:12px;border:1px solid #93805c;border-radius:4px;background:white;cursor:pointer}button[aria-pressed=true]{background:#7b653d;color:white}button:focus-visible,textarea:focus-visible{outline:3px solid #ad6020;outline-offset:3px}.link{background:#eef5ea;border-left:6px solid #799462}.snapshot{background:#fff8e6;border-left:6px solid #b58b38}label{display:block;font-weight:650;margin:14px 0 6px}textarea{width:100%;min-width:0;max-width:100%;min-height:95px;padding:10px;border:1px solid #a29378;border-radius:4px;resize:vertical}.copy p{white-space:pre-wrap;overflow-wrap:anywhere}#status{font-weight:650;color:#7a531d}footer{margin:24px 0;color:#7a705d}[hidden]{display:none!important}@media(max-width:650px){main{padding:12px}h1{font-size:28px}.card{padding:14px}.canvas{grid-template-columns:1fr}}</style></head><body><main><p class="eyebrow">HYPOTHETICAL CLUB EQUIPMENT RETURNS · FOUNDER WORKING COPY</p><h1>Which problem would the next feature address?</h1><p>Lean Canvas method by Ash Maurya. This original snapshot contains assumptions, not customer findings, pricing or a product-viability result.</p><section class="card"><h2>Nine blocks · inspect an assumption</h2><div id="canvas" class="canvas"></div><section class="card" aria-live="polite"><h3 id="block-title"></h3><p id="block-detail"></p></section><h3>Current unfair advantage</h3><p id="current-advantage" aria-label="Current unfair advantage: blank"></p><p>Blank until a defensible advantage is supported.</p><button id="history" type="button" aria-expanded="false" aria-controls="history-view">Inspect earlier advantage wording</button><section id="history-view" class="card" hidden><h3>Earlier wording · retained</h3><p>“We work hard.”</p><p>Unsupported as an unfair advantage. Effort does not establish what makes this offer difficult to copy. The current advantage remains blank.</p></section></section><section class="card link"><h2>Trace a proposed solution to its problem</h2><div class="tabs"><button id="p1" type="button" aria-pressed="true">P1 · overdue status</button><button id="p2" type="button" aria-pressed="false">P2 · reminder receipt</button></div><h3 id="problem">P1 · Coordinator cannot tell which items are overdue.</h3><p><strong>Proposed solution:</strong> <span id="solution">S1 · Return-status view.</span></p><p><strong>Open question:</strong> <span id="open">What causes the records and returned equipment to disagree today?</span></p><p>These are hypotheses. S2 is an idea, not a functioning message service. Discovering a different cause could change the solution discussion.</p></section><section class="card snapshot"><h2>Independent founder snapshots</h2><div class="tabs"><button id="snapshot-a" type="button" aria-pressed="true">Snapshot A · more reminders</button><button id="snapshot-b" type="button" aria-pressed="false">Snapshot B · trustworthy status</button></div><h3 id="snapshot-title">A · more-reminders framing</h3><p id="snapshot-problem">Founder assumption: borrowers need more equipment-return reminders.</p><p id="snapshot-solution">Proposed response: more reminders. Check whether reminder receipt matters to the coordinator's next action.</p><p id="snapshot-question">Open question: how is receipt handled now, and is it an important problem?</p><p>Both independent framings are retained in this page. Reconciliation is a discussion about evidence, not a vote establishing truth.</p></section><button id="discovery" type="button" aria-expanded="false" aria-controls="discovery-view">Inspect the next discovery question</button><section id="discovery-view" class="card" hidden><h2>Seek a concrete account of P1</h2><p>Describe the last time your records disagreed with the equipment that had actually been returned. How did you find the difference, and what did you do next?</p><p>Follow the actual process and alternatives. If there is no such example, record that rather than persuading the person the problem exists.</p><p><strong>Actual customer response:</strong> not supplied.</p></section><section class="card"><h2>Your separate canvas and next question</h2><div id="fields"></div><div class="tabs"><button id="build" type="button">Build assumption review</button><button id="reset" type="button">Reset typed work</button></div><p id="status" role="status"></p><section id="confirm" hidden><h3>Clear all ten canvas fields?</h3><div class="tabs"><button id="keep" type="button">Keep my snapshot</button><button id="clear" type="button">Clear typed canvas</button></div></section><section id="review" class="card copy" hidden><h3>Your supplied assumption snapshot</h3><div id="copy"></div><p>Working assumptions only. No demand, viability, payment or customer validation has been inferred.</p></section></section><footer>Temporary notes only. No real messaging, payment, storage or saved research. Keep independent framings beside later actual evidence.</footer></main><script>'use strict';const $=id=>document.getElementById(id),blocks=[['problem-block','Problem','P1: uncertain overdue status. P2: uncertain reminder receipt.','Both are problem hypotheses. Shared sheets and manual messages are proposed existing alternatives to investigate, not interview findings.'],['customer-block','Customer segments','Proposed payer: coordinator. Users: borrowers.','Early-adopter hypothesis: coordinators manually reconciling multiple weekly loans. Payer and user are distinct.'],['value-block','Unique value proposition','Return records easy to reconcile before the next club meeting.','A proposed outcome, not a guarantee.'],['solution-block','Solution','S1: return-status view. S2: proposed acknowledgment mechanism.','S1 maps to P1 and S2 to P2. Need and usefulness are not established.'],['channels-block','Channels','Begin with direct coordinator conversations.','Later acquisition approaches remain to investigate.'],['revenue-block','Revenue streams','Subscription hypothesis.','Willingness to pay and amount are unknown.'],['costs-block','Cost structure','Maintenance and communication-handling costs.','Categories to investigate; no amounts supplied.'],['metrics-block','Key metrics','Completed loan reconciliations.','A proposed outcome measure, rather than a count of features built.'],['advantage-block','Unfair advantage','Not supplied; current field stays blank.','A complete-looking canvas does not establish a defensible advantage.']];for(const[id,title,summary,detail]of blocks){const b=document.createElement('button');b.type='button';b.id=id;b.setAttribute('aria-pressed',String(id==='problem-block'));const h=document.createElement('strong');h.textContent=title;const p=document.createElement('span');p.textContent=summary;b.append(h,p);b.addEventListener('click',()=>{for(const[key]of blocks)$(key).setAttribute('aria-pressed',String(key===id));$('block-title').textContent=title;$('block-detail').textContent=summary+' '+detail;});$('canvas').append(b);}$('block-title').textContent=blocks[0][1];$('block-detail').textContent=blocks[0][2]+' '+blocks[0][3];for(const id of ['p1','p2'])$(id).addEventListener('click',()=>{const first=id==='p1';$('p1').setAttribute('aria-pressed',String(first));$('p2').setAttribute('aria-pressed',String(!first));$('problem').textContent=first?'P1 · Coordinator cannot tell which items are overdue.':'P2 · Coordinator does not know whether a reminder reached a borrower.';$('solution').textContent=first?'S1 · Return-status view.':'S2 · Proposed acknowledgment mechanism.';$('open').textContent=first?'What causes the records and returned equipment to disagree today?':'Is knowing receipt important to the coordinator’s next action, and how is it handled now?';});for(const id of ['a','b'])$('snapshot-'+id).addEventListener('click',()=>{const a=id==='a';$('snapshot-a').setAttribute('aria-pressed',String(a));$('snapshot-b').setAttribute('aria-pressed',String(!a));$('snapshot-title').textContent=a?'A · more-reminders framing':'B · trustworthy-return-status framing';$('snapshot-problem').textContent=a?'Founder assumption: borrowers need more equipment-return reminders.':'Founder assumption: the coordinator needs trustworthy return records.';$('snapshot-solution').textContent=a?'Proposed response: more reminders. Check whether reminder receipt matters to the coordinator’s next action.':'Proposed response: a return-status view. Check what causes records and returned equipment to disagree.';$('snapshot-question').textContent=a?'Open question: how is receipt handled now, and is it an important problem?':'Open question: how was the last disagreement found, and what happened next?';});for(const[button,panel]of [['history','history-view'],['discovery','discovery-view']])$(button).addEventListener('click',()=>{const open=$(panel).hidden;$(panel).hidden=!open;$(button).setAttribute('aria-expanded',String(open));});const fields=[['own-customer','Paying customer, users and early-adopter scope · required'],['own-problem','Problem hypotheses and existing alternatives · required'],['own-value','Unique value proposition hypothesis'],['own-solution','Minimal solution ideas mapped to problems'],['own-channels','Channels'],['own-revenue','Revenue hypothesis and unknowns'],['own-costs','Cost categories and unknowns'],['own-metrics','Proposed outcome metrics'],['own-advantage','Supported unfair advantage, otherwise leave blank'],['own-question','Next discovery question and its hypothesis · required']];for(const[id,label]of fields){const l=document.createElement('label'),t=document.createElement('textarea');l.htmlFor=id;l.textContent=label;t.id=id;t.addEventListener('input',()=>{$('review').hidden=true;$('status').textContent='Assumptions changed. Build again to review current words.';});$('fields').append(l,t);}$('build').addEventListener('click',()=>{const missing=['own-customer','own-problem','own-question'].filter(id=>!$(id).value.trim());$('review').hidden=true;if(missing.length){$('status').textContent='Complete: '+missing.map(id=>({'own-customer':'customer/users','own-problem':'problem hypotheses','own-question':'next discovery question'})[id]).join(', ')+'.';return;}$('copy').replaceChildren();for(const[id,title]of fields){const h=document.createElement('h3'),p=document.createElement('p');h.textContent=title;p.textContent=$(id).value.trim()||'Not supplied.';$('copy').append(h,p);}$('review').hidden=false;$('status').textContent='Assumption review assembled from supplied words.';});$('reset').addEventListener('click',()=>{$('confirm').hidden=false;$('keep').focus();});$('keep').addEventListener('click',()=>{$('confirm').hidden=true;$('reset').focus();});$('clear').addEventListener('click',()=>{for(const[id]of fields)$(id).value='';$('review').hidden=true;$('confirm').hidden=true;$('status').textContent='Ten canvas fields cleared. Worked blocks and independent snapshot framing unchanged.';$('own-customer').focus();});</script></body></html>