<pre><code>
<div id="govWatchContainer"></div>
<script>
(() => {
const container = document.getElementById('govWatchContainer');
const shadow = container.attachShadow({mode:'open'});
shadow.innerHTML = `
<style>
:host{all:initial;display:block;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;margin:0}
*{box-sizing:border-box}
input,select,button{all:unset;box-sizing:border-box;font:inherit;padding:8px;border:1px solid #d0d6e0;border-radius:6px;width:100%}
h1{font-size:1.4rem;margin-bottom:6px;font-weight:700}
p.lead{margin:0 0 12px;color:#444;display:block}
.controls{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0 18px}
.controls > *{flex:1 1 150px;min-width:120px}
.card-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px;}
.card-item{background:#fff;border-radius:8px;box-shadow:0 1px 4px rgba(0,0,0,0.04);padding:12px;display:flex;flex-direction:column;gap:6px;word-break:break-word;}
.card-item .tag{display:inline-block;padding:4px 8px;border-radius:999px;font-size:.75rem}
.status-Resolved{background:#e6fbf1;color:#006644}
.status-Unresolved{background:#fff4f4;color:#8a1d1d}
.status-Arrogance{background:#fff7e6;color:#8a5a00}
.status-Responsible{background:#eaf4ff;color:#054a91}
.actions{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
.small{font-size:.85rem;color:#666}
.link{color:#0b66ff;text-decoration:underline;cursor:pointer}
.summary{margin-top:16px;padding:12px;background:#fff; border-radius:8px;box-shadow:0 1px 4px rgba(0,0,0,0.04)}
.summary .row{display:flex;gap:12px;flex-wrap:wrap}
.card{padding:10px;border-radius:8px;background:#fbfdff;min-width:150px;flex:1 1 150px}
@media (max-width:600px){
h1{font-size:1.2rem}
p.lead{font-size:.85rem}
.card{min-width:100%;flex:1 1 100%}
}
</style>
<div>
<h1>Government Watch — Daily Major News Record</h1>
<p class="lead">Used to record major news daily, links to official responses, status, and classification. Works offline with CSV export, localStorage save, and four-year summaries.</p>
<div class="controls">
<input id="filterFrom" type="date" />
<input id="filterTo" type="date" />
<select id="filterStatus">
<option value="">-- Filter Status --</option>
<option value="Resolved">Resolved</option>
<option value="Unresolved">Unresolved</option>
<option value="Arrogance">Arrogance/Inaction/Incompetence</option>
<option value="Responsible">Responsible/Capable/Wise</option>
</select>
<button id="applyFilter">Apply Filter</button>
<button id="addRecord">Add Record</button>
<button id="clearAll" title="Clear all records (irreversible)">Clear All</button>
</div>
<div style="margin-bottom:12px">
<label class="small">Search / Notes:</label>
<input id="quickSearch" placeholder="Enter keyword then press Enter"/>
</div>
<div class="card-list" id="cardList"></div>
<div class="summary" id="summaryArea">
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap">
<div><strong>Loaded Records:</strong> <span id="totalCount">0</span></div>
<div class="small">Tip: Set the full term dates to generate a four-year summary.</div>
</div>
<div class="row" style="margin-top:10px;gap:12px">
<div class="card"><div class="small">Total Events</div><div id="cardTotal" style="font-weight:700">0</div></div>
<div class="card"><div class="small">Unresolved</div><div id="cardUnresolved">0</div></div>
<div class="card"><div class="small">Arrogance/Inaction/Incompetence</div><div id="cardArrogance">0</div></div>
<div class="card"><div class="small">Responsible/Capable/Wise</div><div id="cardResponsible">0</div></div>
</div>
<div style="margin-top:12px"><button id="computeSummary">Compute and Update Percentages</button></div>
</div>
</div>
`;
const s = shadow; let records = [];
const STORAGE_KEY = 'gov_watch_records_v2';
const $ = id => s.getElementById(id);
function escapeHtml(str){return str? String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"') : '';}
function renderCards(){
const container = $('cardList'); container.innerHTML='';
const from = $('filterFrom').value, to=$('filterTo').value, status=$('filterStatus').value, q=$('quickSearch').value.trim().toLowerCase();
const filtered = records.filter(r=>{
if(from && r.date<from) return false;
if(to && r.date>to) return false;
if(status && r.status!==status) return false;
if(q && !(r.title+' '+r.source+' '+r.govLink+' '+r.tags+' '+r.notes).toLowerCase().includes(q)) return false;
return true;
});
$('totalCount').textContent = filtered.length;
filtered.forEach(r=>{
const div = document.createElement('div'); div.className='card-item';
div.innerHTML = `
<strong>${escapeHtml(r.title)}</strong>
<div class="small">Date: ${escapeHtml(r.date)}</div>
<div class="small">Source: <a href="${escapeHtml(r.source)}" target="_blank" class="link">Link</a></div>
<div class="small">Gov Response: <a href="${escapeHtml(r.govLink)}" target="_blank" class="link">Link</a></div>
<div class="small">Severity: ${escapeHtml(r.severity)}</div>
<div class="small">Status: <span class="tag status-${escapeHtml(r.status)}">${escapeHtml(r.status)}</span></div>
<div class="small">Tags: ${escapeHtml(r.tags||'')}</div>
<div class="actions">
<button data-id="${r.id}" class="editBtn">Edit</button>
<button data-id="${r.id}" class="delBtn">Delete</button>
</div>
`;
container.appendChild(div);
});
}
function addRecord(obj){ const id=Date.now()+Math.floor(Math.random()*999); records.push(Object.assign({id}, obj)); renderCards();}
function editRecord(id){ const r=records.find(x=>x.id===id); if(!r) return alert('Record not found');
const title=prompt('Event title:',r.title); if(title===null) return;
const date=prompt('Date:',r.date); const source=prompt('Source URL:',r.source);
const govLink=prompt('Gov Response URL:',r.govLink); const severity=prompt('Severity:',r.severity);
const status=prompt('Status:',r.status); const tags=prompt('Tags:',r.tags); const notes=prompt('Notes:',r.notes);
Object.assign(r,{title,date,source,govLink,severity,status,tags,notes}); renderCards();
}
function deleteRecord(id){ if(!confirm('Delete this record?')) return; records=records.filter(r=>r.id!==id); renderCards(); }
function computeSummary(){
const total=records.length;
const unresolved=records.filter(r=> (r.status||'').toLowerCase().includes('unresolved')).length;
const arrogance=records.filter(r=> (r.status||'').toLowerCase().includes('arrogance')).length;
const responsible=records.filter(r=> (r.status||'').toLowerCase().includes('resolved') || (r.status||'').toLowerCase().includes('responsible')).length;
$('cardTotal').textContent=total; $('cardUnresolved').textContent=unresolved;
$('cardArrogance').textContent=arrogance; $('cardResponsible').textContent=responsible;
}
$('applyFilter').addEventListener('click',renderCards);
$('computeSummary').addEventListener('click',computeSummary);
$('addRecord').addEventListener('click',()=>{
const title=prompt('Event title'); if(!title) return;
const date=prompt('Date',new Date().toISOString().slice(0,10));
const source=prompt('Source URL'); const govLink=prompt('Gov Response URL');
const severity=prompt('Severity','Medium'); const status=prompt('Status','Unresolved');
const tags=prompt('Tags'); addRecord({date,title,source,govLink,severity,status,tags,notes:''});
});
$('quickSearch').addEventListener('keydown',e=>{ if(e.key==='Enter') renderCards(); });
$('clearAll').addEventListener('click',()=>{ if(confirm('Clear all?')){records=[]; renderCards();} });
shadow.addEventListener('click',e=>{
if(e.target.classList.contains('editBtn')) editRecord(Number(e.target.dataset.id));
if(e.target.classList.contains('delBtn')) deleteRecord(Number(e.target.dataset.id));
});
})();
</script>
</code></pre>
Love Pass — A platform where great ideas spark change. Share your creativity, actions, and stories, and connect with dreamers worldwide to make the world a better place.