155 lines
10 KiB
HTML
155 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1">
|
|
<title>Ops Timeline — Rhino Terminal</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
|
:root{--bg:#0d0f14;--surf:#141820;--card:#181c26;--border:#1e2332;
|
|
--amber:#ffb000;--amber-bright:#ffd866;--amber-dim:#665500;--amber-faint:#2a2200;
|
|
--green:#4caf7d;--red:#ef5350;--cyan:#7ae9ff;--muted:#3a3e4a;
|
|
--font:'JetBrains Mono','Fira Code','Cascadia Code',monospace
|
|
}
|
|
body{font-family:var(--font);background:var(--bg);color:var(--amber);min-height:100vh;padding:16px;line-height:1.7;font-size:14px}
|
|
.container{max-width:720px;margin:0 auto}
|
|
body::after{content:'';position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;background:radial-gradient(ellipse at center,rgba(255,176,0,0.015) 0%,transparent 70%);z-index:999}
|
|
|
|
.term-bar{border:1px solid var(--amber-faint);border-radius:4px 4px 0 0;background:var(--surf);overflow:hidden;margin-bottom:8px}
|
|
.term-title{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;background:var(--card);border-bottom:1px solid var(--amber-faint);font-size:11px;color:var(--amber-dim);user-select:none}
|
|
.term-title .dots{display:flex;gap:4px}
|
|
.term-title .dots .dot{width:10px;height:10px;border-radius:50%;margin:0}
|
|
.dot.r{background:#ff5f56}.dot.y{background:#ffbd2e}.dot.g{background:#27c93f}
|
|
.term-title .name{font-size:10px;text-transform:uppercase;letter-spacing:0.8px}
|
|
.term-body{padding:18px 16px 14px;min-height:200px}
|
|
|
|
.prompt-line{display:flex;align-items:center;gap:2px;margin-bottom:2px;font-size:13px;color:var(--amber-dim)}
|
|
.prompt-line .ps1{color:var(--amber-bright);font-weight:500}
|
|
.prompt-line .ps2{color:var(--muted)}
|
|
|
|
.sect{margin-bottom:12px}
|
|
.sect-head{display:flex;align-items:center;gap:8px;padding:10px 12px;cursor:pointer;user-select:none;border:1px solid var(--border);background:var(--surf);transition:all 0.2s}
|
|
.sect-head:hover{border-color:var(--amber-dim)}
|
|
.sect-head .arrow{transition:transform 0.25s;font-size:10px;color:var(--amber-dim)}
|
|
.sect-head.open .arrow{transform:rotate(90deg)}
|
|
.sect-head .label{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:0.6px;color:var(--amber-bright)}
|
|
.sect-head .badge{font-size:9px;padding:1px 6px;border-radius:3px;margin-left:auto;font-weight:500}
|
|
.badge-green{background:rgba(76,175,125,0.15);color:var(--green)}
|
|
.badge-amber{background:rgba(255,176,0,0.15);color:var(--amber)}
|
|
.badge-cyan{background:rgba(122,233,255,0.15);color:var(--cyan)}
|
|
.sect-body{display:none;padding:12px;background:var(--card);border:1px solid var(--border);border-top:none}
|
|
.sect-body.open{display:block}
|
|
|
|
.entry{display:flex;gap:12px;padding:8px 0;border-bottom:1px solid var(--amber-faint)}
|
|
.entry:last-child{border:none}
|
|
.entry .date{color:var(--amber-dim);font-size:11px;white-space:nowrap;min-width:75px;padding-top:2px}
|
|
.entry .desc{color:var(--txt);font-size:12px;line-height:1.6}
|
|
.entry .desc .tag{display:inline-block;font-size:9px;padding:0 5px;border-radius:2px;margin-right:4px;font-weight:500}
|
|
.tag-add{background:rgba(76,175,125,0.2);color:var(--green)}
|
|
.tag-fix{background:rgba(239,83,80,0.2);color:var(--red)}
|
|
.tag-chore{background:rgba(122,233,255,0.15);color:var(--cyan)}
|
|
.tag-upgrade{background:rgba(255,176,0,0.15);color:var(--amber)}
|
|
|
|
.status-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px}
|
|
.status-item{padding:8px 10px;background:var(--surf);border:1px solid var(--border);font-size:11px}
|
|
.status-item .key{color:var(--amber-dim)}
|
|
.status-item .val{color:var(--amber-bright);margin-top:2px}
|
|
.status-item .val.green{color:var(--green)}
|
|
.status-item .val.red{color:var(--red)}
|
|
|
|
.nav-links{display:flex;gap:12px;justify-content:center;padding:16px 0 8px}
|
|
.nav-links a{color:var(--amber-dim);text-decoration:none;font-size:11px;letter-spacing:0.4px}
|
|
.nav-links a:hover{color:var(--amber-bright)}
|
|
|
|
.rhino-ascii{text-align:center;padding:12px 0;color:var(--amber-dim);font-size:10px;line-height:1.3;opacity:0.6}
|
|
|
|
@media(max-width:600px){.status-grid{grid-template-columns:1fr}}
|
|
</style>
|
|
</head>
|
|
<body><div class="container">
|
|
|
|
<!-- Terminal Bar -->
|
|
<div class="term-bar">
|
|
<div class="term-title">
|
|
<div class="dots"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span></div>
|
|
<span class="name">ops-timeline · v2.0</span>
|
|
<span style="font-size:10px;color:var(--amber-dim)">~$ █</span>
|
|
</div>
|
|
<div class="term-body">
|
|
|
|
<div class="prompt-line"><span class="ps1">rhino@green-jacket</span><span class="ps2">:</span><span class="ps1">~</span><span class="ps2">$ cat /var/log/deployments</span></div>
|
|
<div style="height:8px"></div>
|
|
|
|
<!-- ======== Changelog ======== -->
|
|
<div class="sect">
|
|
<div class="sect-head open" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
|
|
<span class="arrow">▶</span><span class="label">Changelog</span><span class="badge badge-cyan">v2.0</span>
|
|
</div>
|
|
<div class="sect-body open" id="changelog">
|
|
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Ops Timeline page at <code>/ops</code></div></div>
|
|
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Market Intel API + dashboard tab with salary charts</div></div>
|
|
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Smart Match score column per job row</div></div>
|
|
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Evening Stand-Down briefing (6:45pm cron)</div></div>
|
|
<div class="entry"><span class="date">2026-07-20</span><div class="desc"><span class="tag tag-add">ADD</span> Backend backup to Gitea: Anthony/job-dashboard</div></div>
|
|
<div class="entry"><span class="date">2026-07-19</span><div class="desc"><span class="tag tag-add">ADD</span> Cover letter regeneration endpoint + docx export</div></div>
|
|
<div class="entry"><span class="date">2026-07-18</span><div class="desc"><span class="tag tag-add">ADD</span> Closing date urgency colours (past/urgent/warning)</div></div>
|
|
<div class="entry"><span class="date">2026-07-08</span><div class="desc"><span class="tag tag-chore">FIX</span> Stale job detection, bulk-edit, sorting</div></div>
|
|
<div class="entry"><span class="date">2026-07-03</span><div class="desc"><span class="tag tag-add">ADD</span> Initial job tracker dashboard — Notion sync + API</div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ======== System Status ======== -->
|
|
<div class="sect">
|
|
<div class="sect-head open" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
|
|
<span class="arrow">▶</span><span class="label">System Status</span><span class="badge badge-green">online</span>
|
|
</div>
|
|
<div class="sect-body open">
|
|
<div class="status-grid">
|
|
<div class="status-item"><div class="key">Dashboard Server</div><div class="val green">● Running</div><div class="key" style="margin-top:4px">port 9099</div></div>
|
|
<div class="status-item"><div class="key">Notion Sync</div><div class="val green">● Auto-refresh 5min</div><div class="key" style="margin-top:4px">jobs_cache.json</div></div>
|
|
<div class="status-item"><div class="key">Evening Stand-Down</div><div class="val green">● Cron active</div><div class="key" style="margin-top:4px">weekdays 18:45 AWST</div></div>
|
|
<div class="status-item"><div class="key">Gitea Backup</div><div class="val green">● Pushed</div><div class="key" style="margin-top:4px">Anthony/job-dashboard</div></div>
|
|
<div class="status-item"><div class="key">Cover Letter Engine</div><div class="val green">● OmniRoute</div><div class="key" style="margin-top:4px">cover-letter-writer combo</div></div>
|
|
<div class="status-item"><div class="key">Market Intel</div><div class="val green">● Live</div><div class="key" style="margin-top:4px">/api/market-intel</div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ======== Tech Stack ======== -->
|
|
<div class="sect">
|
|
<div class="sect-head" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
|
|
<span class="arrow">▶</span><span class="label">Tech Stack</span><span class="badge badge-cyan">built with</span>
|
|
</div>
|
|
<div class="sect-body">
|
|
<div class="status-grid">
|
|
<div class="status-item"><div class="key">Runtime</div><div class="val">Python 3 · HTTPServer</div></div>
|
|
<div class="status-item"><div class="key">Data</div><div class="val">Notion API · jobs_cache.json</div></div>
|
|
<div class="status-item"><div class="key">LLM</div><div class="val">OmniRoute · cover-letter-writer</div></div>
|
|
<div class="status-item"><div class="key">Infra</div><div class="val">Hermes CT460 · Tailscale</div></div>
|
|
<div class="status-item"><div class="key">Git</div><div class="val">Gitea · Anthony/job-dashboard</div></div>
|
|
<div class="status-item"><div class="key">CI</div><div class="val">Belongs to the rhino now</div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ======== Rhino Footer ======== -->
|
|
<div class="nav-links">
|
|
<a href="/">Dashboard</a>
|
|
<a href="/api/jobs">API</a>
|
|
<a href="/evening.html">Evening Briefing</a>
|
|
<a href="https://gitea.kangaroo-eel.ts.net/Anthony/job-dashboard" target="_blank">Source</a>
|
|
</div>
|
|
<div class="rhino-ascii">
|
|
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓<br>
|
|
┃ The Rhino in the Green Jacket ┃<br>
|
|
┃ "Keep the weird underneath the ┃<br>
|
|
┃ competent." ┃<br>
|
|
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
</div>
|
|
|
|
</div></div>
|
|
</div>
|
|
</body>
|
|
</html> |