← back to Cncp Failures Mockups
public/v2-newspaper.html
83 lines
<!doctype html><html><head>
<meta charset="utf-8"><title>v2 — Newspaper / wire-service</title>
<style>
:root { --ink:#1a1a1a; --paper:#f3eedf; --rule:#2a2a2a; --accent:#8b0000; }
body { margin:0; background:var(--paper); color:var(--ink); font-family: Georgia,'Times New Roman',serif; line-height:1.5; min-height:100vh; }
.masthead { padding:24px 32px 14px; border-bottom:4px double var(--ink); }
.masthead h1 { font-family: 'Old English Text MT', 'Goudy Old Style', Georgia, serif; font-size:48px; line-height:1; margin:0; letter-spacing:0; }
.masthead .stamp { display:flex; justify-content:space-between; font-size:11px; text-transform:uppercase; letter-spacing:2px; margin-top:8px; color:#555; }
.masthead .subtitle { font-style:italic; font-size:13px; margin-top:4px; color:#444; }
.columns { display:grid; grid-template-columns: 2fr 1fr; gap:32px; padding:22px 32px; }
.lead { font-size:13px; }
.lead h2 { font-family:Georgia,serif; font-size:22px; letter-spacing:1px; margin:0 0 4px; text-transform:uppercase; }
.lead h2.sev-high { color:var(--accent); }
.lead .deck { font-style:italic; color:#444; margin-bottom:10px; }
.byline { font-size:11px; text-transform:uppercase; color:#777; letter-spacing:1px; margin-bottom:6px; }
.article { border-top:1px solid var(--rule); padding-top:12px; margin-top:14px; }
.article p { margin:0 0 6px; }
.article p.body { columns:2; column-gap:20px; column-rule:1px solid #c9c2af; font-size:12.5px; }
.lab { display:inline-block; font-size:10px; text-transform:uppercase; letter-spacing:2px; background:var(--ink); color:var(--paper); padding:2px 6px; margin-right:6px; }
.lab.high { background:var(--accent); }
.lab.med { background:#a06000; }
.lab.low { background:#3d6b2a; }
.sidebar { font-size:12px; }
.sidebar h3 { font-family:Georgia,serif; font-size:14px; text-transform:uppercase; letter-spacing:1.5px; border-top:3px solid var(--ink); border-bottom:1px solid var(--ink); padding:6px 0; margin:0 0 8px; }
.sidebar .stat { display:flex; justify-content:space-between; padding:3px 0; border-bottom:1px dotted #bbb; }
.sidebar .recent { font-family:Georgia,serif; font-size:11.5px; line-height:1.5; }
.sidebar .recent .item { padding:6px 0; border-bottom:1px dotted #bbb; }
.sidebar .recent .item .time { color:#888; font-size:10px; text-transform:uppercase; letter-spacing:1px; }
.pill { background:var(--ink); color:var(--paper); padding:1px 5px; font-size:10px; text-transform:uppercase; letter-spacing:1.5px; }
.pill.h{ background:var(--accent); }
.pill.m{ background:#a06000; }
.pill.l{ background:#3d6b2a; }
</style>
</head><body>
<div class="masthead">
<h1>The CNCP Dispatch</h1>
<div class="subtitle">All the failures fit to triage · A daily wire of process incidents · Vol. 1 No. 1</div>
<div class="stamp"><span id="dateStamp"></span><span>Edition: Wire Service</span><span>Hermes-3 desk on duty</span></div>
</div>
<div class="columns">
<div class="lead" id="lead"></div>
<div class="sidebar">
<h3>The Hermes Desk · 24h</h3>
<div id="stats"></div>
<h3 style="margin-top:18px;">Latest Filings</h3>
<div class="recent" id="recent"></div>
</div>
</div>
<script>
fetch('/data' + location.search).then(r=>r.json()).then(d => {
const date = new Date().toLocaleDateString('en-US', { weekday:'long', month:'long', day:'numeric', year:'numeric' });
document.getElementById('dateStamp').textContent = date.toUpperCase();
const lab = s => s==='high'?'<span class="lab high">crit</span>': s==='medium'?'<span class="lab med">warn</span>': s==='low'?'<span class="lab low">note</span>':'<span class="lab">unset</span>';
const lead = d.failures.map((f,i) => `
<div class="article">
<div class="byline">${lab(f.severity)} Filed ${new Date(f.lastSeen).toLocaleTimeString('en-US',{hour:'2-digit',minute:'2-digit'})} · from the ${f.source.toUpperCase()} desk</div>
<h2 class="${f.severity==='high'?'sev-high':''}">${f.processName} ${f.exitCode!=null?'reports exit '+f.exitCode:'flagged'} after ${f.eventCount} event${f.eventCount>1?'s':''}</h2>
<div class="deck">${f.suggestedAction || 'No action recommended.'}</div>
<p class="body">${(f.lastLines||'').split('\\n').filter(Boolean).slice(0,3).join(' ').slice(0,420)}…</p>
</div>
`).join('');
document.getElementById('lead').innerHTML = lead;
const h = d.hermes.last24h;
const sev = d.hermes.last24h.bySev;
document.getElementById('stats').innerHTML = `
<div class="stat"><span>Total calls</span><span>${h.total}</span></div>
<div class="stat"><span>Avg latency</span><span>${(h.avgLatencyMs/1000).toFixed(1)}s</span></div>
<div class="stat"><span>Classifications</span><span>${h.byType.classify}</span></div>
<div class="stat"><span>Refinements</span><span>${h.byType.chat}</span></div>
<div class="stat"><span>Ideas asked</span><span>${h.byType['idea-chat']}</span></div>
<div class="stat"><span>Severity</span><span><span class="pill h">H${sev.high}</span> <span class="pill m">M${sev.medium}</span> <span class="pill l">L${sev.low}</span></span></div>
<div class="stat"><span>Failed calls</span><span>${h.fail}</span></div>`;
document.getElementById('recent').innerHTML = d.hermes.recent.slice(0,6).map(c => `
<div class="item">
<div class="time">${new Date(c.ts).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit'})} · ${c.type}${c.severity?(' · '+lab(c.severity)):''}</div>
<div>${c.target}</div>
</div>`).join('');
});
</script>
</body></html>