FallEstatePaper
v1 · prime 907
·
');w.document.close();w.print();} function renderDocuments(v){ const docs=state.documents.sort((a,b)=>b.createdAt-a.createdAt); v.innerHTML=`

Documents

${docs.length} total
${docs.length?`${docs.map(d=>``).join('')}
DateTemplateCodeStatusHash
${dateStr(d.createdAt)}${esc(d.templateName)}${esc(d.code)}${d.status}${esc(d.hash)}
`:'

No documents

Generate one from the Templates tab.

'}`; } function renderFirm(v){const f=state.firm||{}; v.innerHTML=`

Firm Setup

`; } async function saveFirmForm(){const f=state.firm||{id:uid('firm'),ts:now()};f.name=$('#fName').value.trim();f.email=$('#fEmail').value.trim();f.address=$('#fAddr').value.trim();f.phone=$('#fPhone').value.trim();f.hmrcAmlRef=$('#fAml').value.trim();f.updatedAt=now();state.firm=f;await idbPut('firms',f);await auditLog('firm.saved');toast('Firm saved');render();} function renderClients(v){ v.innerHTML=`

Clients

${state.clients.length}
${state.clients.length?`${state.clients.map(c=>``).join('')}
NameTypeProperty
${esc(((c.title||'')+' '+(c.firstName||'')+' '+(c.lastName||'')).trim()||c.id.slice(0,8))}${esc(c.clientType||'—')}${esc(c.propertyAddress||c.address||'—')}
`:'

No clients

Clients sync from fallestateonboard via BroadcastChannel.

'}`; } // Q&A const T0_QA=[ {q:/ast|shorthold|tenancy agreement/i,a:'An AST (Assured Shorthold Tenancy) is the default tenancy type in England under the Housing Act 1988. The agreement must include: parties, property address, rent amount and frequency, deposit amount and scheme, term dates, tenant and landlord obligations. Statutory requirements: gas safety cert, EPC (E+), EICR, How to Rent guide, deposit protection + prescribed info within 30 days.'}, {q:/s(ection)?.?21|form 6a|no.?fault/i,a:'Section 21 notice (Form 6A) requires possession with at least 2 months\' notice. Pre-requisites: deposit protected + prescribed info served, gas safety cert, EPC, EICR, and How to Rent guide provided. Cannot serve during first 4 months of the first tenancy. Valid for 6 months. Deregulation Act 2015 restrictions apply if improvement notice outstanding.'}, {q:/s(ection)?.?8|grounds|possession/i,a:'Section 8 notice specifies grounds for possession (Schedule 2, Housing Act 1988). Mandatory grounds (court must grant): Ground 8 (2+ months rent arrears). Discretionary grounds: Ground 10 (some rent arrears), Ground 11 (persistent delay), Ground 12 (breach of obligation), Ground 14 (nuisance). Notice periods vary by ground: 2 weeks to 2 months.'}, {q:/deposit|protect|prescribed/i,a:'Housing Act 2004: tenancy deposits must be protected in DPS, MyDeposits, or TDS within 30 days. Prescribed information (SI 2007/797) must be served within 30 days. Failure: 1-3x deposit penalty, cannot serve valid s.21. Deposit capped at 5 weeks\' rent for ASTs where annual rent

Q & A

T0 + T3 BYOK
${(state.ui.chat||[]).map(m=>`
${esc(m.text)}${m.source?`
${esc(m.source)}
`:''}
`).join('')}
`;const box=$('#chatBox');if(box)box.scrollTop=box.scrollHeight;} async function askQuestion(){const inp=$('#chatIn');if(!inp)return;const q=inp.value.trim();if(!q)return;inp.value='';if(!state.ui.chat)state.ui.chat=[];state.ui.chat.push({role:'user',text:q});render();let r=askT0(q);if(!r)r=await askT3(q);state.ui.chat.push(r?{role:'bot',text:r.answer,source:r.source}:{role:'bot',text:'No T0 match. Add BYOK key in Settings.',source:'system'});persistUI();render();} // Modal function openModal(type){const modal=$('#modal');const title=$('#modalTitle');const body=$('#modalBody');modal.classList.add('open'); if(type==='settings'){title.textContent='Settings';body.innerHTML=`
`;} } function closeModal(){$('#modal').classList.remove('open');} function saveSettings(){state.settings.anthropicKey=$('#sAnthro').value.trim();state.settings.auditChain=$('#sAudit').checked;$('#tierBadge').textContent=state.settings.anthropicKey?'T3':'T0';persistUI();closeModal();toast('Saved');render();} function exportAll(){const d={tool:TOOLNAME,v:VERSION,ts:now(),firm:state.firm,clients:state.clients,documents:state.documents};const b=new Blob([JSON.stringify(d,null,2)],{type:'application/json'});const u=URL.createObjectURL(b);const a=document.createElement('a');a.href=u;a.download='fallestatepaper-export.json';a.click();URL.revokeObjectURL(u);toast('Exported');} function importAll(){const inp=document.createElement('input');inp.type='file';inp.accept='.json';inp.onchange=async()=>{const f=inp.files[0];if(!f)return;try{const d=JSON.parse(await f.text());if(d.firm){state.firm=d.firm;await idbPut('firms',d.firm);}for(const k of['clients','documents']){if(Array.isArray(d[k]))for(const r of d[k]){state[k].push(r);await idbPut(k,r);}}persistUI();toast('Imported');render();}catch(e){toast('Failed');}};inp.click();} async function wipeAll(){if(!confirm('Wipe ALL data?'))return;for(const s of['firms','clients','documents','audit','state']){const tx=db.transaction(s,'readwrite');tx.objectStore(s).clear();await new Promise(r=>{tx.oncomplete=r;});}location.reload();} // Demo async function seedDemo(){if(state.clients.length||state.firm)return; const firm={id:uid('firm'),name:'Demo Estates & Lettings',address:'5 High Street, London SW1A 2AA',email:'info@demoestates.co.uk',phone:'020 7456 7890',hmrcAmlRef:'XMLR00012345',cmpScheme:'DPS',redressScheme:'PRS',updatedAt:now(),isDemo:true}; state.firm=firm;await idbPut('firms',firm); const t={id:uid('cl'),clientType:'tenant',title:'Ms',firstName:'Emma',lastName:'Clarke',address:'18 Oak Road, London',postcode:'SE1 4QR',propertyAddress:'Flat 3, 22 Elm Street, London SE1 5AB',rent:1400,email:'emma.clarke@email.co.uk',phone:'07700 900789',ts:now(),updatedAt:now(),isDemo:true}; const b={id:uid('cl'),clientType:'buyer',title:'Mr',firstName:'Richard',lastName:'Osei',address:'12 Maple Ave, London',postcode:'N1 2XY',propertyAddress:'',email:'r.osei@email.co.uk',phone:'07700 900456',ts:now(),updatedAt:now(),isDemo:true}; state.clients.push(t,b);await idbPut('clients',t);await idbPut('clients',b); await auditLog('demo.seeded',{reasoning:'first boot'});await persistUI(); } (async function boot(){try{await openDB();await loadAll();await seedDemo();initMesh();$('#tierBadge').textContent=state.settings.anthropicKey?'T3':'T0';render();}catch(e){console.error('[fallestatepaper] boot error:',e);document.getElementById('view').innerHTML='

Boot error

'+esc(e.message)+'

';}})();