Rebuild the day, not the history
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>Rebuild the day, not the history</title>
<style>:root{color-scheme:light;--ink:#202b32;--muted:#52616a;--paper:#fff;--bg:#eaf0f3;--accent:#17485d;--soft:#edf5f8;--line:#cbd8de;--heading:Georgia,serif}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.65 system-ui,-apple-system,"Segoe UI",sans-serif}main{max-width:1040px;margin:28px auto;background:var(--paper);border:1px solid var(--line);border-radius:12px;overflow:hidden}header{padding:28px 32px;border-top:7px solid var(--accent);border-bottom:1px solid var(--line)}.kicker{color:var(--accent);margin:0 0 10px}h1{font:500 clamp(30px,5vw,46px)/1.15 var(--heading);letter-spacing:-.02em;margin:0 0 14px;max-width:850px}header p{margin:0;color:var(--muted)}.content{padding:0 32px 32px}h2{font:500 27px/1.25 var(--heading);margin:0 0 18px}h3{font-size:20px;line-height:1.35;margin:0 0 12px}p{margin:0 0 14px}p:last-child{margin-bottom:0}section{padding-top:28px;margin-top:28px;border-top:1px solid var(--line)}.hero{padding:24px;margin-top:24px;background:var(--soft);border-left:5px solid var(--accent);border-radius:4px}.hero p:first-child{font-size:21px;font-weight:650}.controls{display:flex;flex-wrap:wrap;gap:10px;margin:16px 0}button,.controls a{font:inherit;line-height:1.4;border:1px solid var(--accent);border-radius:6px;padding:12px 16px;background:var(--paper);color:var(--accent);cursor:pointer;text-decoration:none;max-width:100%}button:hover,.controls a:hover{background:var(--soft)}button[aria-pressed="true"],#check,#inspect,#rebuild,#apply{background:var(--accent);color:#fff}button:focus-visible,input:focus-visible,textarea:focus-visible,summary:focus-visible,a:focus-visible{outline:3px solid #c56412;outline-offset:3px}label{display:block;font-weight:650;margin:16px 0}input,textarea{display:block;font:inherit;line-height:1.55;color:var(--ink);background:var(--paper);border:1px solid #8297a2;border-radius:5px;padding:12px;width:100%;min-width:0;margin-top:8px}input[type="number"],input[type="date"]{max-width:320px}textarea{resize:vertical}.result{background:var(--soft);padding:18px 20px;border-left:4px solid var(--accent);font-weight:600;overflow-wrap:anywhere}.note{background:var(--soft);border:1px solid var(--line);padding:18px;border-radius:5px}.stage{padding:24px;background:var(--soft);border:1px solid var(--line);border-radius:8px}.record-list{display:grid;gap:14px;margin:20px 0}.record{padding:20px;border:1px solid var(--line);border-left:4px solid var(--accent);border-radius:4px}.record p{margin-bottom:8px}.two-col{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}.two-col>section{margin-top:0}.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:20px}.metrics p{font-size:16px!important;font-weight:400!important}.metrics strong{display:block;font-size:30px;font-weight:650;line-height:1.3;font-variant-numeric:tabular-nums;margin-top:8px}.timeline{list-style:none;padding:0;margin:0;counter-reset:phase}.timeline li{padding:14px 0 14px 20px;border-left:3px solid var(--accent);border-bottom:1px solid var(--line)}details{border:1px solid var(--line);border-radius:5px;padding:16px 18px;margin:20px 0}summary{cursor:pointer;font-weight:650}details[open] summary{margin-bottom:16px}dl{display:grid;grid-template-columns:1fr 1.5fr;gap:12px 20px}dt{font-weight:650}dd{margin:0}blockquote{margin:20px 0;padding:20px 24px;border-left:5px solid var(--accent);font:500 27px/1.5 var(--heading);background:var(--soft)}.expression{font-size:27px;font-weight:650;line-height:1.5;overflow-wrap:anywhere}.sample{padding:20px;background:var(--soft)}footer{padding:22px 32px;color:var(--muted);background:var(--soft);border-top:1px solid var(--line)}[hidden]{display:none!important}.sound-map{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-template-areas:". ahead ." "left center right" ". behind .";gap:8px;text-align:center;padding:20px 0;border:1px dashed var(--accent);background:radial-gradient(circle,transparent 35%,var(--line) 35.3%,transparent 35.7%)}.sound-map p{margin:0;padding:12px 4px;overflow-wrap:anywhere}.map-ahead{grid-area:ahead}.map-left{grid-area:left}.map-center{grid-area:center;font-weight:700}.map-right{grid-area:right}.map-behind{grid-area:behind}.partner{background:var(--soft);padding:24px;border-radius:12px}.partner blockquote:empty{display:none}.route-tree{border-left:3px solid var(--accent);padding-left:24px;display:grid;gap:20px}.route-tree article{padding:18px;background:var(--soft);border-radius:6px}.counters{display:flex;flex-wrap:wrap;gap:8px}.counter{display:inline-flex;align-items:center;justify-content:center;border:2px solid;border-radius:50%;width:56px;height:56px;font-size:16px;font-weight:650}.counter.red{color:#882f27;background:#ffebe7;border-color:#ba5145}.counter.blue{color:#18467a;background:#e2efff;border-color:#3f71a5}.counter-stage{padding:20px;border:1px dashed var(--accent);border-radius:8px}.facts{padding-left:24px}.facts li{margin-bottom:10px}
body.spanish{--bg:#f8e9df;--accent:#8b342a;--soft:#fff0e7;--line:#e5c7b6;--ink:#3c251e}body.asset{--bg:#142632;--accent:#154e69;--soft:#eaf4f8}body.sop{--bg:#e7e8e5;--accent:#484e3f;--soft:#f4f4ed;--heading:system-ui,sans-serif}body.fundraising{--bg:#f0e9f5;--accent:#65377b;--soft:#f7effb;--line:#d9c5e3}body.outdoor{--bg:#e2e9dd;--accent:#2e5b36;--soft:#edf4e9;--line:#bdcfb6}body.about{--bg:#eef0ff;--accent:#51439a;--soft:#f2f0ff;--line:#d4cee9}body.volunteer{--bg:#f1e3d6;--accent:#824128;--soft:#fbf0e5;--line:#ddc5ad}body.event{--bg:#222735;--accent:#303a65;--soft:#edf0fa;--line:#c8cfe2;--heading:system-ui,sans-serif}body.invoice{--bg:#dfece9;--accent:#176253;--soft:#eaf6f2;--line:#bed8d0;--heading:system-ui,sans-serif}body.backlog{--bg:#e6e3ee;--accent:#59447a;--soft:#f4f0fa;--line:#d5cbe5}body.sitemap{--bg:#e5edf2;--accent:#235574;--soft:#edf5fb;--heading:system-ui,sans-serif}body.cooperative{--bg:#f3ecd8;--accent:#795c16;--soft:#fbf5e5;--line:#ddce9f}body.factoring{--bg:#102d2b;--accent:#165d4d;--soft:#e7f6ef;--heading:system-ui,sans-serif}body.ratio{--bg:#fae8da;--accent:#883b2a;--soft:#fff3e8}body.fragments{--bg:#e7e1d7;--accent:#443c31;--soft:#f5f1e9;--line:#d0c6b7}body.nouns{--bg:#eee5f4;--accent:#67417d;--soft:#f8f0fc;--line:#dbc7e5}
@media(max-width:640px){main{margin:0;border-radius:0;border-left:0;border-right:0}header{padding:24px 20px}.content{padding:0 20px 24px}footer{padding:20px}.hero,.stage,.partner{padding:18px}h1{font-size:34px}h2{font-size:26px}.two-col{grid-template-columns:1fr;gap:16px}.controls button,.controls a{flex:1 1 135px}.metrics{grid-template-columns:1fr 1fr}.hero .metrics{gap:14px}.metrics strong{font-size:27px}.sound-map{font-size:16px}.sound-map p{padding:14px 2px}.route-tree{padding-left:16px}.expression{font-size:24px}dl{grid-template-columns:1fr}blockquote{padding:16px;font-size:24px}input[type="number"],input[type="date"]{max-width:100%}}</style>
</head>
<body class="invoice"><main><header><p class="kicker">Synthetic invoice and receipt ledger · USD · calendar dates in 2026</p><h1>Rebuild the day, not the history</h1></header><div class="content"><div class="hero"><p id="snapshotLabel">Snapshot: October 14, 2026</p><div class="metrics"><p>Positive open balance<strong id="total">$310</strong></p><p>Open invoices<strong id="openCount">3</strong></p><p>Unresolved invoices<strong id="unresolvedCount">0</strong></p></div><p id="totalScope">Confirmed positive balances; negative balances are separate.</p><p id="buckets">Current $250 · 1–30 days overdue $60 · Unclassified $0</p></div><section><h2>Select one date for every calculation</h2><label for="date">As-of date<input id="date" type="date" value="2026-10-14" ></label><div class="controls"><button type="button" id="rebuild" >Rebuild snapshot</button></div><p id="result" class="result" role="status" aria-live="polite">Snapshot loaded from the fictional baseline.</p><div class="controls"><button type="button" id="all" aria-pressed="true">All open</button><button type="button" id="current" aria-pressed="false">Current</button><button type="button" id="overdue" aria-pressed="false">Overdue</button><button type="button" id="unclassified" aria-pressed="false">Unclassified</button></div><p id="filtered"></p><div id="rows" class="record-list"></div></section><section><h2>Inspect receipt scope and edge cases</h2><p id="receipts"></p><div class="controls"><button type="button" id="duplicate" aria-pressed="false">Toggle identical R01 duplicate</button><button type="button" id="missing" aria-pressed="false">Toggle I03 missing due date</button></div><p id="scenario">Baseline records.</p><details><summary id="exceptionOptions">Explore receipt conflicts and an overpayment</summary><p>These controls change fictional source rows. Each R01 conflict retains source S1 and S1-conflict.</p><div class="controls"><button type="button" id="conflictAmount" aria-pressed="false">Model R01 amount conflict</button><button type="button" id="conflictDate" aria-pressed="false">Model R01 date conflict</button><button type="button" id="conflictInvoice" aria-pressed="false">Model R01 invoice conflict</button><button type="button" id="conflictCurrency" aria-pressed="false">Model R01 currency conflict</button><button type="button" id="overpay" aria-pressed="false">Model $100 extra receipt for I01</button></div></details><h3>Unresolved source rows</h3><p id="unresolved" class="note"></p><div id="heldRows" class="record-list"></div><h3>Credit and negative balances</h3><p id="credits" class="note"></p><details><summary>Source ledger and bucket rules</summary><p>I01 issued Oct 1, due Oct 13, $100. I02 issued Oct 1, due Oct 14, $200. I03 issued Oct 1, due Oct 20, $50.</p><p>R01: I01, Oct 12, $40. R02: I02, Oct 15, $200.</p><p>Current: due today or later. Positive calendar-day overdue ranges: 1–30, 31–60, 61–90, more than 90. Missing due date: Unclassified. Identical receipts count once. Conflicting source rows require owner review of the affected balance.</p></details></section></div><footer><p>Local example only. Controls send nothing and save no changes; reloading restores the sample. Keep the invoice and receipt ledger separately.</p></footer><noscript>Enable JavaScript to use this interactive example.</noscript></main>
<script>
(function invoiceApp(){
'use strict';
const q=s=>document.querySelector(s),put=(s,t)=>{q(s).textContent=t;},on=(s,fn,event='click')=>q(s).addEventListener(event,fn),esc=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])),mark=(ids,chosen)=>ids.forEach(id=>q(id).setAttribute('aria-pressed',String(id===chosen)));
let filter='all',duplicate=false,missing=false,conflict='',overpay=false,asof='2026-10-14',pending=false;
const invoices=[{id:'I01',issued:'2026-10-01',due:'2026-10-13',gross:100,currency:'USD'},{id:'I02',issued:'2026-10-01',due:'2026-10-14',gross:200,currency:'USD'},{id:'I03',issued:'2026-10-01',due:'2026-10-20',gross:50,currency:'USD'}];
const receipts=[{id:'R01',invoice:'I01',date:'2026-10-12',amount:40,currency:'USD',source:'S1'},{id:'R02',invoice:'I02',date:'2026-10-15',amount:200,currency:'USD',source:'S2'}];
const days=s=>Date.parse(s+'T00:00:00Z')/86400000,valid=s=>/^\d{4}-\d{2}-\d{2}$/.test(s)&&Number.isFinite(days(s))&&new Date(days(s)*86400000).toISOString().slice(0,10)===s,money=n=>n<0?'-$'+Math.abs(n):'$'+n;
function clear(){put('#total','Unavailable');put('#openCount','Unavailable');put('#unresolvedCount','Unavailable');put('#totalScope','Choose a valid date and rebuild.');put('#buckets','Awaiting a valid selected date.');put('#snapshotLabel','Snapshot: awaiting rebuild');put('#filtered','No current filtered result.');q('#rows').innerHTML='';put('#receipts','Receipt inclusion pending rebuild.');put('#unresolved','Unresolved records pending rebuild.');q('#heldRows').innerHTML='';put('#credits','Credit balances pending rebuild.');}
function render(){if(pending)return;
const source=receipts.map(v=>({...v}));if(duplicate)source.push({...receipts[0],source:'S1-copy'});
if(conflict){const row={...receipts[0],source:'S1-conflict'};if(conflict==='amount')row.amount=60;if(conflict==='date')row.date='2026-10-16';if(conflict==='association')row.invoice='I02';if(conflict==='currency')row.currency='EUR';source.push(row);}
if(overpay)source.push({id:'R03',invoice:'I01',date:'2026-10-14',amount:100,currency:'USD',source:'S4'});
const groups=new Map();for(const row of source){if(!groups.has(row.id))groups.set(row.id,[]);groups.get(row.id).push(row);}
const heldIds=new Set(),issues=[],unique=[];for(const [receiptId,versions]of groups){const signatures=new Set(versions.map(v=>JSON.stringify([v.invoice,v.date,v.amount,v.currency])));const invalid=versions.some(v=>!invoices.some(i=>i.id===v.invoice)||!valid(v.date)||!Number.isFinite(v.amount)||v.amount<0||v.currency!=='USD');if(signatures.size>1||invalid){for(const v of versions)if(invoices.some(i=>i.id===v.invoice))heldIds.add(v.invoice);issues.push({id:receiptId,versions,reason:signatures.size>1?'conflicting identity fields':'invalid receipt fields'});}else unique.push({...versions[0],sources:versions.map(v=>v.source)});}
const active=invoices.filter(i=>i.issued<=asof),held=active.filter(i=>heldIds.has(i.id)),included=unique.filter(v=>v.date<=asof),later=unique.filter(v=>v.date>asof);
const calculated=active.filter(i=>!heldIds.has(i.id)).map(i=>{const paid=included.filter(v=>v.invoice===i.id).reduce((n,v)=>n+v.amount,0),due=missing&&i.id==='I03'?null:i.due,age=due?days(asof)-days(due):null;return {...i,paid,open:i.gross-paid,due,age,bucket:age===null?'unclassified':age<=0?'current':'overdue'};});
const rows=calculated.filter(i=>i.open>0),credits=calculated.filter(i=>i.open<0),buckets={current:0,overdue:0,unclassified:0},aged={a:0,b:0,c:0,d:0};for(const row of rows){buckets[row.bucket]+=row.open;if(row.bucket==='overdue')aged[row.age<=30?'a':row.age<=60?'b':row.age<=90?'c':'d']+=row.open;}
put('#snapshotLabel','Snapshot: '+asof);put('#total',money(rows.reduce((n,i)=>n+i.open,0)));put('#openCount',String(rows.length));put('#unresolvedCount',String(held.length));put('#totalScope',held.length?held.length+' unresolved invoice(s): headline includes confirmed positive balances only. Held balances are unknown.':'Confirmed positive balances; credit/negative balances are shown separately below.');
put('#buckets','Current '+money(buckets.current)+' · 1–30 days overdue '+money(aged.a)+' · 31–60 '+money(aged.b)+' · 61–90 '+money(aged.c)+' · >90 '+money(aged.d)+' · Unclassified '+money(buckets.unclassified));
const shown=rows.filter(i=>filter==='all'||i.bucket===filter);put('#filtered',shown.length+' matching open invoices · subtotal '+money(shown.reduce((n,i)=>n+i.open,0)));q('#rows').innerHTML=shown.length?shown.map(i=>'<article class="record"><h3>'+i.id+' · open '+money(i.open)+'</h3><p>Gross '+money(i.gross)+' USD · due '+(i.due||'unknown')+'</p><p>'+(i.age===null?'Unclassified due date':i.age<=0?'Current':i.age+' days overdue')+'</p></article>').join(''):'<p>No confirmed positive invoices in this filter.</p>';
put('#receipts','Included: '+(included.map(v=>v.id+' '+money(v.amount)+' ['+v.sources.join(', ')+']').join(', ')||'none')+'. After as-of: '+(later.map(v=>v.id+' '+v.date).join(', ')||'none')+'. Conflicting or invalid receipt identities held: '+(issues.map(v=>v.id).join(', ')||'none')+'.');
put('#unresolved',held.length+' unresolved invoice'+(held.length===1?'':'s')+' · gross basis '+money(held.reduce((n,i)=>n+i.gross,0))+' held: '+(held.map(i=>i.id).join(', ')||'none')+'. '+(held.length?'Open balance unknown; a known gross amount is not the unresolved balance.':'No affected invoice calculation is held.'));
q('#heldRows').innerHTML=issues.map(issue=>'<article class="record"><h3>'+esc(issue.id)+' · '+esc(issue.reason)+'</h3>'+issue.versions.map(v=>'<p>'+esc(v.source)+': '+esc(v.invoice)+' · '+esc(v.date)+' · '+esc(v.currency)+' '+esc(v.amount)+'</p>').join('')+'<p>Retain both references and resolve the source before calculating the affected balance. No currency conversion is assumed.</p></article>').join('');
put('#credits',credits.length?credits.map(i=>i.id+' negative balance '+money(i.open)+' (gross '+money(i.gross)+', included receipts '+money(i.paid)+').').join(' ')+' Shown for review; no refund or write-off recorded.':'No negative balances in the resolved rows.');
put('#scenario',[duplicate?'Identical R01 copies count once; source references retained.':'',missing?'I03 due date missing; positive balance Unclassified.':'',conflict?'Modeled R01 '+conflict+' conflict.':'',overpay?'Modeled R03 adds $100 to I01 on October 14.':''].filter(Boolean).join(' ')||'Baseline records.');
}
on('#date',()=>{pending=true;clear();put('#result','Date changed. Rebuild the snapshot.');},'input');on('#rebuild',()=>{const value=q('#date').value;if(!valid(value)){pending=true;clear();put('#result','Enter a valid calendar date before rebuilding.');return;}asof=value;pending=false;render();put('#result','Snapshot rebuilt from eligible receipts on or before '+asof+'.');});
['all','current','overdue','unclassified'].forEach(f=>on('#'+f,()=>{filter=f;mark(['#all','#current','#overdue','#unclassified'],'#'+f);render();}));on('#duplicate',()=>{duplicate=!duplicate;q('#duplicate').setAttribute('aria-pressed',String(duplicate));render();});on('#missing',()=>{missing=!missing;q('#missing').setAttribute('aria-pressed',String(missing));render();});
const conflictButtons={amount:'#conflictAmount',date:'#conflictDate',association:'#conflictInvoice',currency:'#conflictCurrency'};for(const [name,selector]of Object.entries(conflictButtons))on(selector,()=>{conflict=conflict===name?'':name;mark(Object.values(conflictButtons),conflict?conflictButtons[conflict]:'');render();});on('#overpay',()=>{overpay=!overpay;q('#overpay').setAttribute('aria-pressed',String(overpay));render();});render();
})();
</script>
</body>
</html>