Resolve the promise before the handoff
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>Resolve the promise before the handoff</title><style>*{box-sizing:border-box}body{margin:0;background:#f3f4f2;color:#202c32;font:16px/1.5 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}main{max-width:1120px;margin:auto;padding:30px 28px 60px}header{margin-bottom:22px}.eyebrow{font-size:12px;letter-spacing:.14em;text-transform:uppercase;font-weight:750;color:#59676b}h1{font-size:clamp(25px,4vw,36px);line-height:1.15;letter-spacing:-.035em;margin:7px 0 10px}h2{font-size:21px;line-height:1.3;margin:0 0 16px}h3{font-size:17px;margin:0 0 10px}p{margin:8px 0 16px}label{display:block;font-size:14px;font-weight:650;margin:12px 0 5px}input,select,textarea,button{font:inherit}input,select,textarea{width:100%;min-width:0;border:1px solid #b6c0bf;border-radius:7px;background:#fff;color:#202c32;padding:10px 12px}textarea{resize:vertical;min-height:88px}input[type=checkbox]{width:18px;height:18px;vertical-align:middle;margin-right:8px}button{border:1px solid #b8c3c1;border-radius:7px;padding:10px 15px;background:#fff;color:#203632;font-weight:650;cursor:pointer}button.primary{background:#243f3c;color:white;border-color:#243f3c}button:hover{filter:brightness(.95)}button:disabled{opacity:.48;cursor:not-allowed}:focus-visible{outline:3px solid #b05814;outline-offset:3px}.buttons{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px}.panel{background:#fff;border:1px solid #d7ddda;border-radius:12px;padding:24px}.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:22px}.row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.result{background:#e4eee8;border:1px solid #c5d6ca;border-radius:12px;padding:28px}.big{font-size:clamp(32px,5vw,56px);font-weight:740;line-height:1.14;letter-spacing:-.04em;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.muted{color:#59686a;font-size:14px}.tag{display:inline-block;background:#edf0ed;border-radius:4px;padding:3px 8px;font-size:12px;font-weight:700}.error{color:#9d301b;font-weight:650;min-height:24px;margin-top:10px}.note{border-left:3px solid #9a794a;padding:10px 15px;background:#faf5e9;margin:18px 0}.below{margin-top:28px}.record{white-space:pre-wrap;overflow-wrap:anywhere;font:14px/1.65 ui-monospace,SFMono-Regular,Consolas,monospace;background:#f2f4f1;padding:18px;border-radius:8px}table{width:100%;border-collapse:collapse;font-size:14px}th,td{text-align:left;vertical-align:top;border-bottom:1px solid #dce1dd;padding:12px 10px;overflow-wrap:anywhere}th{color:#59686a;font-size:12px}a{color:#2c5a6a;overflow-wrap:anywhere}details{margin-top:20px}summary{cursor:pointer;font-weight:650}hr{border:0;border-top:1px solid #d6dcd6;margin:22px 0}[hidden]{display:none!important}ol,ul{padding-left:23px}.statline{display:flex;gap:20px;flex-wrap:wrap;margin:18px 0}.statline strong{display:block;font-size:24px}.inline{display:flex;align-items:center;gap:8px}.inline label{margin:0} .blank{min-height:36px;border-bottom:1px dashed #aebbb5;color:#66736d;font-size:13px;padding:8px 0}@media(max-width:720px){main{padding:22px 18px 45px}.split{grid-template-columns:1fr}.panel,.result{padding:20px}.row{gap:12px}th,td{padding:10px 6px}}@media(max-width:400px){main{padding:18px 14px 40px}.big{font-size:34px}button{padding:10px 12px}.row{grid-template-columns:1fr}.panel,.result{padding:17px}}.inline{flex-wrap:wrap}.metric{font-size:clamp(29px,4vw,44px);font-weight:750;line-height:1.2;letter-spacing:-.025em;font-variant-numeric:tabular-nums}.strip{display:flex;justify-content:space-between;align-items:center;gap:18px;flex-wrap:wrap}.caption{font-size:13px;color:#5d6b6f}.tag.warn{background:#f7e9ce;color:#795323}.tag.good{background:#e4ebe4;color:#344f3e}pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere}button[aria-pressed=true]{background:#304b51;color:white}.fieldNote{font-size:13px;color:#5e6a6d;margin:5px 0}.three{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}.docHeader{display:flex;gap:24px;justify-content:space-between;align-items:start;flex-wrap:wrap;border-bottom:2px solid #445a58;padding-bottom:20px}.docHeader h2{margin:0}.money{font-variant-numeric:tabular-nums;white-space:nowrap}.statusBand{padding:17px 22px;border-radius:8px;background:#f5ead5;color:#654c2c;font-weight:650}.statusBand p{font-size:14px;font-weight:400;margin:5px 0 0}.blankLine{border-bottom:1px dashed #b6bfb8;min-height:38px}.evidenceRow{display:grid;grid-template-columns:1fr 1fr;gap:18px;border-top:1px solid #dce1dc;padding:18px 0}.checklabel{font-weight:400;margin:10px 0}.subtle{background:#f4f6f3}.downloadStatus{font-size:13px;min-height:22px;color:#49645a}@media(max-width:650px){.three{grid-template-columns:1fr}.evidenceRow{grid-template-columns:1fr}.metric{font-size:32px}}.handoff{padding:25px;border:1px solid #dbcaa9;border-radius:12px;background:#f5ead7}.handoff h2{font-size:28px;margin:0}.promisePair{display:grid;grid-template-columns:1fr 1fr;gap:28px;margin-top:24px}.promisePair>div{border-top:2px solid #aa9066;padding-top:17px}.promisePair h3{font-size:23px;line-height:1.4;margin:8px 0}.handoff>p{margin:20px 0 0}@media(max-width:600px){.promisePair{grid-template-columns:1fr;gap:16px}.handoff{padding:20px}.promisePair h3{font-size:20px}}</style></head><body><main><header><div class="eyebrow">Cedar Design · D01 / H01 · Fictional internal packet</div><h1>Resolve the promise before the handoff</h1></header>
<section class="handoff"><div class="strip"><h2>Needs clarification</h2><span class="tag warn">Leo's acceptance not supplied</span></div><div class="promisePair"><div><span class="eyebrow">S01 · Maintained signed scope</span><h3>One landing-page draft<br>+ one revision round</h3></div><div><span class="eyebrow">N01 · Sales note</span><h3>Two revision rounds</h3></div></div><p><strong>E01:</strong> Preserve both statements and request an authorized source-record resolution.</p></section>
<section class="panel below"><div class="strip"><h2>Sender → receiver</h2><span>Mia → Leo</span></div><div class="buttons"><button id="sender" aria-pressed="false">Sender checklist</button><button id="receiver" aria-pressed="true">Receiver checklist</button></div><div id="checklist" class="below"></div><p class="muted">Approved trigger, actual customer goal, permitted contact route and delivery deadline are not supplied. A closed-won label, sent packet or introduction is not receiver acceptance.</p></section>
<section class="panel below"><h2>Unsent clarification request</h2><pre id="draft" class="record">Please resolve E01 for D01/H01. S01 lists one landing-page draft and one revision round; N01 lists two revision rounds. Please provide the authorized resolution and corrected source references. H01 remains Needs clarification pending review by Leo.</pre></section>
<form id="form" class="panel below" novalidate><h2>Prepare a separate corrected-packet recheck</h2><div class="row"><div><label for="packet">Corrected packet reference</label><input id="packet" placeholder="P02, only when supplied"></div><div><label for="resolutionRef">Authorized resolution / source reference</label><input id="resolutionRef"></div></div><label for="resolution">Supplied scope resolution</label><textarea id="resolution" placeholder="Retain the actual source statement; do not infer an amendment"></textarea><div class="row"><div><label for="trigger">Approved closed-sale trigger reference</label><input id="trigger"></div><div><label for="goal">Customer goal and source</label><input id="goal"></div><div><label for="contact">Permitted contact / introduction route reference</label><input id="contact"></div><div><label for="review">Leo's actual review date / evidence</label><input id="review"></div><div><label for="introduction">Actual introduction evidence</label><input id="introduction"></div><div><label for="decision">Actual receiver decision / acceptance reference</label><input id="decision"></div></div><label for="conditions">Remaining questions or conditions</label><textarea id="conditions"></textarea><div class="buttons"><button type="submit" class="primary">Prepare recheck record</button></div><p id="feedback" class="error" role="status"></p><pre class="record" id="recheck">No corrected packet supplied. Original E01 remains open.</pre></form>
<section class="panel below"><h2>Repeatable handoff procedure</h2><ol><li>Evidence the approved closed-sale trigger.</li><li>Collect scope, documented goal, interaction notes, questions and permitted contact route.</li><li>Reconcile promised work; retain missing or conflicting facts.</li><li>Identify the actual receiving owner.</li><li>Resolve exceptions with the authorized scope owner in maintained records.</li><li>Recheck corrected packet and introduce through the confirmed route.</li><li>Retain the receiver's actual decision and unresolved conditions.</li></ol><div class="row"><div><label for="sop">SOP owner / version / effective date</label><input id="sop" placeholder="TO CONFIRM"></div><div><label for="authority">Approving authority / acceptance criteria</label><input id="authority" placeholder="TO CONFIRM"></div></div><p class="muted">This review neither interprets a contract nor updates source scope, CRM or messages. Keep actual operational and approval records in the maintained workflow.</p><a href="https://blog.hubspot.com/service/sales-to-csm-handoff">Goal, interaction-note and question documentation reference</a></section><footer class="muted below">Local review copy · Edits last only while this page is open.</footer></main><script data-app>
(()=>{
const $=id=>document.getElementById(id);const text=(id,v)=>$(id).textContent=String(v);const on=(id,type,fn)=>$(id).addEventListener(type,fn);const escapeHTML=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));const money=n=>'$'+(n/100).toFixed(2);const quantity=(s,integer=false)=>{s=String(s).trim();if(!(integer?/^[0-9]+$/:/^[0-9]+(?:[.][0-9]{1,2})?$/).test(s)||!Number.isFinite(+s)||+s>100000)throw Error('Enter a nonnegative '+(integer?'whole number':'number with at most two decimals')+' up to 100,000. Blank is missing.');return +s};const cents=s=>Math.round(quantity(s)*100);const download=(filename,content,type='text/plain')=>{const url=URL.createObjectURL(new Blob([content],{type})),a=document.createElement('a');a.href=url;a.download=filename;document.body.append(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(url),1000)};
const sender=['Reference the approved closed-sale evidence.','Link the maintained scope version and relevant sales notes.','Source the customer goal and open questions.','Confirm the permitted contact and introduction route.','Identify Leo as the receiving owner; attach E01.'],receiver=['Compare S01 with N01; keep the one-versus-two-round discrepancy visible.','Review missing goal, contact and trigger evidence.','Confirm responsibilities and the actual introduction record.','Recheck a corrected packet against an authorized resolution.','Record an actual decision separately from sending and review.'];let record=null;
function view(role){if(!['sender','receiver'].includes(role))throw Error('Unknown handoff role');for(const id of ['sender','receiver'])$(id).setAttribute('aria-pressed',String(id===role));$('checklist').innerHTML='<ol>'+(role==='sender'?sender:receiver).map(s=>'<li>'+s+'</li>').join('')+'</ol>'}
function prepare(values){if(!values.packet.trim()||values.packet.trim()==='H01')throw Error('Use a distinct corrected-packet reference; preserve H01.');if(!values.resolutionRef.trim()||!values.resolution.trim())throw Error('A corrected packet needs a supplied authorized resolution and source reference.');const missing=['trigger','goal','contact','review','decision'].filter(key=>!values[key].trim());return {...values,missing,status:missing.length?'Pending supplied evidence: '+missing.join(', '):'Supplied decision reference requires source verification; no automatic acceptance.'}}
function clear(){text('recheck','Inputs changed. Prepare the recheck record again.');text('feedback','')}
function update(){try{const values=Object.fromEntries(['packet','resolutionRef','resolution','trigger','goal','contact','review','introduction','decision','conditions'].map(key=>[key,$(key).value]));record=prepare(values);text('recheck','D01 / H01 → '+record.packet+'\nOriginal E01: S01 one revision round; N01 two rounds.\nAuthorized resolution reference: '+record.resolutionRef+'\nSupplied resolution: '+record.resolution+'\nTrigger: '+(record.trigger||'NOT SUPPLIED')+'\nGoal/source: '+(record.goal||'NOT SUPPLIED')+'\nContact route: '+(record.contact||'NOT SUPPLIED')+'\nReceiver review: '+(record.review||'NOT SUPPLIED')+'\nIntroduction: '+(record.introduction||'NOT SUPPLIED')+'\nReceiver decision/reference: '+(record.decision||'NOT SUPPLIED')+'\nRemaining conditions: '+(record.conditions||'Not supplied')+'\n'+record.status);text('feedback','Local recheck record prepared. Original H01/E01 statements are preserved.')}catch(e){record=null;text('recheck','No recheck record prepared. Original E01 remains open.');text('feedback',e.message)}}
on('sender','click',()=>view('sender'));on('receiver','click',()=>view('receiver'));on('form','submit',e=>{e.preventDefault();update()});['packet','resolutionRef','resolution','trigger','goal','contact','review','introduction','decision','conditions'].forEach(id=>on(id,'input',clear));window.app={prepare,view};view('receiver');
})();
</script>
<script>
// Local calculation controls: no native form submission or sandbox permissions required.
(()=>{const form=document.getElementById('form');if(!form)throw Error('Calculation form missing');const dispatch=()=>form.dispatchEvent(new Event('submit',{bubbles:true,cancelable:true}));const buttons=[...form.querySelectorAll('button')].filter(button=>button.type==='submit');if(buttons.length!==1)throw Error('Expected one calculation control');for(const button of buttons){button.type='button';button.addEventListener('click',dispatch);}form.addEventListener('keydown',event=>{if(event.key==='Enter'&&!event.isComposing&&['INPUT','SELECT'].includes(event.target.tagName)){event.preventDefault();dispatch();}});})();
</script>
</body></html>