Arrival ledger • promise and coverage — Separate dispatch from arrival, classify only deliveries with both promised and actual dates, and show missing-date and…
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>Arrival ledger • promise and coverage</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}} .metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:20px 0}.metric{padding:20px;background:white;border:1px solid var(--line,#d6e0e7);border-radius:9px}.metric h2{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#516272;margin:0}.metric .big{font-size:clamp(25px,4vw,39px);margin:8px 0}.metric small{font-size:12px;display:block}.badge{display:inline-block;padding:4px 10px;background:var(--tint,#e3f2f8);border-radius:20px;font-size:13px;font-weight:700}.paper{background:white;padding:26px;border:1px solid var(--line,#d6e0e7)}.feedback{padding:18px;background:var(--tint,#e3f2f8);border-left:4px solid var(--accent,#176783)}.preview{white-space:pre-wrap;overflow-wrap:anywhere}.fact-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}.fact-grid article{padding:20px;background:white;border:1px solid var(--line,#d6e0e7)}.record-row{display:grid;grid-template-columns:70px 1fr 1fr 1fr;gap:12px;align-items:start;padding:16px 0;border-bottom:1px solid var(--line,#d6e0e7)}.record-row small{display:block}.record-row b{display:block}.export textarea{min-height:170px}@media(max-width:720px){.metrics{grid-template-columns:1fr 1fr}.fact-grid{grid-template-columns:1fr}.record-row{grid-template-columns:55px 1fr 1fr}.record-row .row-extra{grid-column:2/4}}@media(max-width:400px){.metrics{gap:10px}.metric{padding:14px}.metric .big{font-size:29px}.metric h2{font-size:11px}.paper{padding:18px}.record-row{gap:9px;font-size:14px}}
body{--accent:#306552;--bg:#f2f6f3;--tint:#e2eee6;--ink:#243d32;--line:#ccddd1}.arrival-summary{display:grid;grid-template-columns:1fr 1fr;gap:16px}.rate{background:#306552;color:white;padding:24px;border-radius:8px}.rate .eyebrow{color:#edf5ef}.rate.coverage{background:#edf0e4;color:#33402d}.rate.coverage .eyebrow{color:#45563d}.rate p{margin-bottom:0}.rate .big{font-size:48px}.cohort-bar{display:flex;height:38px;border-radius:6px;overflow:hidden}.cohort-bar span{flex:1;text-align:center;line-height:38px;font-weight:700}.ontime{background:#d4e9d8;color:#285836}.late{background:#f6dbc5;color:#803d1a}.pending{background:#e3e8ee;color:#344c67}.unknown{background:#eee0f2;color:#694575}.order{display:grid;grid-template-columns:50px 1fr 1fr 1.2fr;gap:14px;border-bottom:1px solid #ccddd1;padding:18px 0;align-items:center}.order b,.order small{display:block}.order-id{font-weight:800}.order-state{padding:9px 12px;border-radius:6px;font-size:14px}#group-summary{font-weight:650}@media(max-width:720px){.order{grid-template-columns:40px 1fr 1fr;gap:10px;font-size:14px}.order-state{grid-column:2/4}.rate{padding:18px}.rate .eyebrow{font-size:11px}.rate p{font-size:14px}}@media(max-width:400px){.arrival-summary{gap:10px}.rate{padding:15px}.rate .big{font-size:36px}}</style></head><body><main>
<header><span class="eyebrow">Delivery review / original date-only ledger</span><h1>Arrived does not always mean classifiable.</h1><p class="intro">Compare actual arrival with its recorded promise; keep missing evidence visible.</p></header>
<section class="arrival-summary"><div class="rate"><span class="eyebrow">On-time rate among classifiable arrivals</span><div class="big" id="rate">50%</div><p id="rate-basis">1 on time ÷ 2 classifiable · D1 / D2</p></div><div class="rate coverage"><span class="eyebrow">Classification coverage of four-order cohort</span><div class="big" id="coverage">50%</div><p id="coverage-basis">2 classifiable ÷ 4 orders</p></div></section>
<section class="panel composition"><h2>One cohort, four evidence states</h2><div class="cohort-bar" id="cohort-bar" aria-label="One on-time, one late, one awaiting arrival, one arrived with no promise"><span class="ontime">D1</span><span class="late">D2</span><span class="pending">D3</span><span class="unknown">D4</span></div><p id="group-summary">Arrived: 3 · Classifiable arrivals: 2 · Overdue awaiting: 1 · Arrived with unknown promise: 1</p><p class="muted">D1 on time · D2 late · D3 awaiting arrival · D4 promise missing. “Arrived” includes both classifiable arrivals and D4.</p></section>
<nav class="controls" aria-label="Order scope"><button type="button" id="all" class="secondary">All orders</button><button type="button" id="arrived" class="secondary">Arrived</button><button type="button" id="awaiting" class="secondary">Awaiting arrival</button><button type="button" id="unknown" class="secondary">Missing promise</button><button type="button" id="classifiable" class="secondary">Classifiable arrivals</button></nav>
<section class="panel"><h2 id="scope-title">All orders · n = 4</h2><div id="orders"></div><p id="scope-note" class="muted"></p></section>
<section class="panel"><h2>As-of date scenario</h2><div class="grid"><div><label for="snapshot">Snapshot date (YYYY-MM-DD)</label><input id="snapshot" type="text" value="2026-10-13" ></div><div><div class="controls"><button type="button" id="recalculate">Recalculate date</button><button type="button" id="reset" class="secondary">Restore October 13</button></div><p id="snapshot-label"></p></div></div><p id="error" class="error" role="alert"></p></section>
<details><summary>Policy and source boundaries</summary><p>Date-only calendar rule: arrival on or before the promised date is on time; after is late. No early-arrival restriction or late tolerance. D2 is late by one calendar day. The on-time numerator is D1; the eligible denominator is D1 and D2. A 1/4 = 25% cohort share answers a different question.</p><p>Dispatch is a separate event; no departure details or quantities are supplied. D3 is not documented as delivered, and D4’s unknown promise is not a zero-day delay. Overall cohort rates remain visible while the record pane is filtered.</p></details>
<footer>Fictional HTML review snapshot, not a live tracking system, map, Excel file, on-time-in-full result, carrier grade, or prediction. No arrival is inferred from dispatch and no missing date is imputed. The maintained order ledger remains authoritative.</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()}
function clockMinute(s){if(!/^(?:[01]\d|2[0-3]):[0-5]\d$/.test(s))throw Error('Use a valid 24-hour time as HH:MM.');const [h,m]=s.split(':').map(Number);return h*60+m}
function whole(s,label){if(!/^\d+$/.test(String(s))||!Number.isSafeInteger(Number(s)))throw Error(label+' must be a nonnegative whole number.');return Number(s)}
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 deliveries=[{id:'D1',promise:'2026-10-12',arrival:'2026-10-12'},{id:'D2',promise:'2026-10-12',arrival:'2026-10-13'},{id:'D3',promise:'2026-10-12',arrival:null},{id:'D4',promise:null,arrival:'2026-10-13'}];let scope='all',current=null;
function deliveryStats(rows,snapshot){const now=isoDay(snapshot);const classified=rows.map(r=>{const p=r.promise?isoDay(r.promise):null,a=r.arrival?isoDay(r.arrival):null;if(a!==null&&a>now)throw Error('Snapshot precedes a supplied actual arrival; use a later date.');if(a!==null&&p!==null)return {...r,state:a<=p?'ontime':'late',late:Math.max(0,a-p)};if(a!==null)return {...r,state:'unknown'};return {...r,state:'awaiting',overdue:p===null?null:Math.max(0,now-p)}});const arrived=classified.filter(r=>r.arrival!==null),eligible=arrived.filter(r=>r.promise!==null),onTime=eligible.filter(r=>r.state==='ontime');return {rows:classified,arrived,eligible,onTime,awaiting:classified.filter(r=>r.state==='awaiting'),unknown:classified.filter(r=>r.state==='unknown'),rate:eligible.length?onTime.length/eligible.length:null,coverage:rows.length?eligible.length/rows.length:null}}
const pct=n=>n===null?'Not available':Number((n*100).toFixed(2))+'%';
function render(){if(!current)return;const rows=scope==='all'?current.rows:scope==='classifiable'?current.eligible:current[scope];txt('scope-title',{all:'All orders',arrived:'Arrived orders',awaiting:'Awaiting recorded arrival',unknown:'Arrived with missing promise',classifiable:'Classifiable arrivals'}[scope]+' · n = '+rows.length);$('orders').innerHTML=rows.map(r=>'<article class="order"><div class="order-id">'+r.id+'</div><div><small>Promised arrival</small><b>'+(r.promise||'Unknown')+'</b></div><div><small>Actual arrival</small><b>'+(r.arrival||'Not recorded')+'</b></div><div class="order-state '+r.state+'">'+(r.state==='ontime'?'Arrived · on time':r.state==='late'?'Arrived · late '+r.late+' calendar day'+(r.late===1?'':'s'):r.state==='unknown'?'Arrived · cannot classify timeliness':r.overdue>0?'Overdue '+r.overdue+' calendar day'+(r.overdue===1?'':'s')+' · awaiting arrival':'Awaiting arrival · not overdue')+'</div></article>').join('')||'<p>No orders in this scope.</p>';txt('scope-note',scope==='unknown'?'D4 has arrival evidence, but no promise for a timeliness comparison.':scope==='awaiting'?'An absent arrival remains absent; an overdue order is not a delivered outcome.':'The overall four-order rate and coverage above do not change when this record pane is filtered.');for(const s of ['all','arrived','awaiting','unknown','classifiable'])$(s).setAttribute('aria-pressed',String(scope===s))}
function pending(){current=null;txt('rate','Pending');txt('coverage','Pending');txt('rate-basis','');txt('coverage-basis','');txt('group-summary','Snapshot changed. Recalculate the current date.');$('orders').innerHTML='';$('cohort-bar').hidden=true;txt('scope-title','No current validated record view');txt('error','')}
function calculate(){try{current=deliveryStats(deliveries,$('snapshot').value);txt('rate',pct(current.rate));txt('coverage',pct(current.coverage));txt('rate-basis',current.onTime.length+' on time ÷ '+current.eligible.length+' classifiable · '+current.eligible.map(r=>r.id).join(', '));txt('coverage-basis',current.eligible.length+' classifiable ÷ '+current.rows.length+' orders');txt('group-summary','Arrived: '+current.arrived.length+' · Classifiable arrivals: '+current.eligible.length+' · Overdue awaiting: '+current.awaiting.filter(r=>r.overdue>0).length+' · Arrived with unknown promise: '+current.unknown.length);txt('snapshot-label','As of '+$('snapshot').value+' · calendar dates only');$('cohort-bar').hidden=false;txt('error','');render()}catch(e){pending();txt('scope-title','No accepted snapshot');txt('snapshot-label','Date not validated');txt('error',e.message)}}
for(const s of ['all','arrived','awaiting','unknown','classifiable'])on(s,'click',()=>{scope=s;render()});on('snapshot','input',pending);on('recalculate','click',calculate);enter('snapshot',calculate);on('reset','click',()=>{$('snapshot').value='2026-10-13';scope='all';calculate()});calculate();
</script></body></html>