aboutsummaryrefslogtreecommitdiff
path: root/docs/prototypes/2026-07-07-maint-console-B-domain-tiles.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-07 18:24:12 -0500
committerCraig Jennings <c@cjennings.net>2026-07-07 18:24:12 -0500
commit7955be70ea7751c68d6a9b2ca3683ee697a38726 (patch)
treeb241c157d36238f9769660c0701ca24a2696abf2 /docs/prototypes/2026-07-07-maint-console-B-domain-tiles.html
parent96881fccae125c8803ac5c26b8ddb7ee77be363a (diff)
downloadarchsetup-7955be70ea7751c68d6a9b2ca3683ee697a38726.tar.gz
archsetup-7955be70ea7751c68d6a9b2ca3683ee697a38726.zip
docs: add maintenance console design + interactive prototypes
The design doc replaces the install-health framing in system-monitor-design-ideas.org with a maintenance console: dense metric subpanels behind a persistent selector, a doctor that streams into a results wall, determinate remedies only (guard-armed updates, curation lifecycles for noise, listeners, containers, and orphans), rotary band selectors on the tall subpanels, and a CLI-first build with a four-layer test strategy. Every decision is dated in the doc. Prototypes A-E5 keep the exploration path: five divergent layouts converging into E5, a fully interactive simulation whose GOOD/BAD snapshots become the build's test fixtures. todo.org gains the spec-create task, the panel keybinding-family task, and scope notes on the net/bt doctor retrofit.
Diffstat (limited to 'docs/prototypes/2026-07-07-maint-console-B-domain-tiles.html')
-rw-r--r--docs/prototypes/2026-07-07-maint-console-B-domain-tiles.html382
1 files changed, 382 insertions, 0 deletions
diff --git a/docs/prototypes/2026-07-07-maint-console-B-domain-tiles.html b/docs/prototypes/2026-07-07-maint-console-B-domain-tiles.html
new file mode 100644
index 0000000..ebc3acf
--- /dev/null
+++ b/docs/prototypes/2026-07-07-maint-console-B-domain-tiles.html
@@ -0,0 +1,382 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>MAINT · ratio — Approach B</title>
+<style>
+ :root{
+ --bg:#0a0c0d; --surface:#100f0f; --gold:#dab53d; --silver:#bfc4d0;
+ --dim:#7c838a; --cream:#f3e7c5; --slate:#424f5e; --slate-h:#54677d;
+ --ok:#74932f; --warn:#dab53d; --fail:#cb6b4d; --na:#7c838a;
+ --inset:#0a0c0d; --inset-bd:#2c2f32;
+ }
+ *{box-sizing:border-box}
+ body{
+ margin:0; padding:34px 16px; background:var(--bg);
+ font-family:"BerkeleyMono Nerd Font", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
+ color:var(--silver); font-size:13px; line-height:1.45;
+ display:flex; flex-direction:column; align-items:center; gap:20px;
+ }
+ .console{
+ width:1000px; max-width:100%; background:var(--surface);
+ border:1px solid var(--gold); border-radius:16px; padding:18px 20px 22px;
+ }
+ /* header */
+ .hdr{display:flex; align-items:baseline; justify-content:space-between; gap:16px;}
+ .hdr .title{color:var(--cream); font-size:16px; letter-spacing:.5px;}
+ .hdr .title b{color:var(--gold);}
+ .hdr .verdict{font-size:14px; color:var(--ok); font-weight:bold; letter-spacing:.5px;}
+ .sub{color:var(--dim); font-size:12px; margin-top:2px; margin-bottom:14px;}
+
+ /* global action bar */
+ .actionbar{
+ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
+ padding:11px 13px; margin-bottom:16px;
+ background:var(--inset); border:1px solid var(--inset-bd); border-radius:10px;
+ }
+ .actionbar .grp{display:flex; gap:8px;}
+ .actionbar .spacer{flex:1 1 auto;}
+ button{
+ font-family:inherit; font-size:12px; cursor:pointer;
+ background:var(--slate); color:var(--cream); border:1px solid #33404d;
+ border-radius:10px; padding:6px 12px;
+ }
+ button:hover{background:var(--slate-h);}
+ button.ghost{background:transparent; color:var(--silver); border-color:var(--inset-bd); padding:5px 10px;}
+ button.ghost:hover{background:#161a1d; color:var(--cream);}
+ button.tiny{font-size:11px; padding:3px 9px; border-radius:8px;}
+
+ /* updates chip */
+ .updates-chip{
+ display:flex; align-items:center; gap:12px; margin-left:auto;
+ padding:6px 12px; border:1px solid var(--fail); border-radius:999px;
+ background:rgba(203,107,77,.09);
+ }
+ .updates-chip .u-lamp{color:var(--fail);}
+ .updates-chip .u-txt{color:var(--cream); font-size:12px;}
+ .updates-chip .u-txt b{color:var(--warn);}
+
+ /* grid */
+ .grid{
+ display:grid; grid-template-columns:repeat(3, 1fr); gap:12px;
+ }
+ .tile{
+ background:var(--inset); border:1px solid var(--inset-bd); border-radius:10px;
+ padding:11px 12px 12px; display:flex; flex-direction:column; gap:8px;
+ cursor:pointer; transition:border-color .12s;
+ }
+ .tile:hover{border-color:#3c4a58;}
+ .tile.expanded{grid-column:1 / -1; cursor:default; border-color:var(--slate-h);}
+ .tile-top{display:flex; align-items:flex-start; gap:9px;}
+ .rollup{font-size:16px; line-height:1.1; margin-top:1px;}
+ .tile-head{flex:1 1 auto; min-width:0;}
+ .tile-name{color:var(--gold); font-weight:bold; letter-spacing:.3px;}
+ .tile-finding{color:var(--silver); font-size:12px; margin-top:2px;
+ white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
+ .tile-finding.warnt{color:var(--warn);}
+ .tile-finding.failt{color:var(--fail);}
+ .tile-foot{display:flex; align-items:center; gap:8px; justify-content:space-between;}
+ .counts{color:var(--dim); font-size:11px;}
+ .counts .fix{color:var(--silver);}
+ .expander{color:var(--dim); font-size:11px;}
+
+ /* lamps */
+ .lamp{font-size:13px;}
+ .l-ok{color:var(--ok);} .l-warn{color:var(--warn);} .l-fail{color:var(--fail);}
+ .l-na{color:var(--na);} .l-prog{color:var(--warn);}
+
+ /* expanded detail */
+ .detail{border-top:1px solid var(--inset-bd); padding-top:9px; margin-top:2px;}
+ .detail-hint{color:var(--dim); font-size:11px; margin-bottom:7px;}
+ .row{
+ display:grid; grid-template-columns:16px 1fr auto auto;
+ align-items:center; gap:10px; padding:4px 4px; border-radius:6px;
+ }
+ .row:hover{background:#141719;}
+ .row + .row{border-top:1px solid #17191b;}
+ .r-name{color:var(--silver);}
+ .r-val{color:var(--dim); font-size:12px; text-align:right; white-space:nowrap;}
+ .r-lever{justify-self:end; min-width:96px; text-align:right;}
+ .r-lever .none{color:#4d5358;}
+ .r-auto{font-size:10px; color:var(--dim); text-transform:uppercase; letter-spacing:.5px;
+ border:1px solid var(--inset-bd); border-radius:5px; padding:1px 5px; margin-left:6px;}
+
+ /* running capsule */
+ .capsule{
+ width:1000px; max-width:100%; background:var(--surface);
+ border:1px solid var(--gold); border-radius:16px; padding:14px 18px 16px;
+ }
+ .cap-hdr{display:flex; align-items:center; justify-content:space-between; margin-bottom:10px;}
+ .cap-hdr .title{color:var(--cream); font-size:14px; letter-spacing:.5px;}
+ .cap-hdr .title b{color:var(--gold);}
+ .cap-hdr .running{color:var(--warn); font-weight:bold;}
+ .wall{
+ background:var(--inset); border:1px solid var(--inset-bd); border-radius:10px;
+ padding:10px 12px; display:flex; flex-direction:column; gap:6px;
+ }
+ .wall .line{display:flex; align-items:center; gap:10px;}
+ .wall .line .glyph{width:14px; text-align:center;}
+ .wall .line .act{color:var(--silver); min-width:180px;}
+ .wall .line .st{color:var(--dim); font-size:12px;}
+ .wall .line .st b{color:var(--ok);}
+ .wall .line.done .act{color:var(--dim);}
+ .wall .line.queued .act{color:var(--dim);}
+ .cap-foot{display:flex; justify-content:flex-end; margin-top:11px;}
+ .legend{
+ width:1000px; max-width:100%; color:var(--dim); font-size:11px;
+ padding:0 6px; line-height:1.6;
+ }
+ .legend b{color:var(--silver); font-weight:normal;}
+</style>
+</head>
+<body>
+
+<div class="console">
+ <div class="hdr">
+ <div>
+ <div class="title">MAINT · <b>ratio</b></div>
+ </div>
+ <div class="verdict">● healthy</div>
+ </div>
+ <div class="sub">Approach B — Domain-tile grid</div>
+
+ <!-- global actions -->
+ <div class="actionbar">
+ <div class="grp">
+ <button>Clean up</button>
+ <button class="ghost">Review &amp; fix</button>
+ </div>
+ <div class="spacer"></div>
+ <div class="updates-chip">
+ <span class="u-lamp">●</span>
+ <span class="u-txt"><b>47 pending</b> · 3 CVE · mesa,linux-lts</span>
+ <button class="tiny">Run workflow</button>
+ </div>
+ </div>
+
+ <!-- domain grid -->
+ <div class="grid">
+
+ <!-- STORAGE (expanded) -->
+ <div class="tile expanded" id="t-storage">
+ <div class="tile-top">
+ <span class="rollup l-fail">●</span>
+ <div class="tile-head">
+ <div class="tile-name">Storage</div>
+ <div class="tile-finding failt">fstrim off · scrub 34d</div>
+ </div>
+ <div class="tile-foot" style="flex-direction:column; align-items:flex-end; gap:6px;">
+ <button class="tiny">Clean</button>
+ <span class="counts"><span class="fix">4 fix</span> · 6 watch</span>
+ </div>
+ </div>
+ <div class="detail">
+ <div class="detail-hint">10 checks — lever shown where the doctor can act</div>
+
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">cache<span class="r-auto">auto</span></span><span class="r-val">8.8 GB</span><span class="r-lever"><button class="tiny">Clean</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">deep-trim<span class="r-auto">confirm</span></span><span class="r-val">keep-3</span><span class="r-lever"><button class="tiny">Deep trim</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">disk</span><span class="r-val">69%</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">btrfs unalloc</span><span class="r-val">118 GiB</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">btrfs scrub<span class="r-auto">confirm</span></span><span class="r-val">34 d</span><span class="r-lever"><button class="tiny">Scrub</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">btrfs device-err</span><span class="r-val">0 / 0</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">SMART</span><span class="r-val">PASSED</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">SMART wear</span><span class="r-val">0%</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-fail">●</span><span class="r-name">fstrim.timer<span class="r-auto">confirm</span></span><span class="r-val">off</span><span class="r-lever"><button class="tiny">Enable</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">pacman integrity<span class="r-auto">workflow</span></span><span class="r-val">clean</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ <!-- SNAPSHOTS -->
+ <div class="tile" onclick="toggle('snap')" id="t-snap">
+ <div class="tile-top">
+ <span class="rollup l-ok">●</span>
+ <div class="tile-head">
+ <div class="tile-name">Snapshots</div>
+ <div class="tile-finding">42 snaps · timer active</div>
+ </div>
+ </div>
+ <div class="tile-foot">
+ <span class="counts"><span class="fix">1 fix</span> · 1 watch</span>
+ <span class="expander">▸ detail</span>
+ </div>
+ <div class="detail" id="d-snap" style="display:none;">
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">snapper count<span class="r-auto">confirm</span></span><span class="r-val">42</span><span class="r-lever"><button class="tiny">Prune</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">snapshot timer<span class="r-auto">confirm</span></span><span class="r-val">active</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ <!-- PACKAGES & SECURITY -->
+ <div class="tile" onclick="toggle('pkg')" id="t-pkg">
+ <div class="tile-top">
+ <span class="rollup l-fail">●</span>
+ <div class="tile-head">
+ <div class="tile-name">Packages &amp; Security</div>
+ <div class="tile-finding failt">3 CVE · 47 updates</div>
+ </div>
+ </div>
+ <div class="tile-foot">
+ <span class="counts"><span class="fix">3 fix</span> · 4 watch</span>
+ <span class="expander">▸ detail</span>
+ </div>
+ <div class="detail" id="d-pkg" style="display:none;">
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">orphans<span class="r-auto">confirm</span></span><span class="r-val">13</span><span class="r-lever"><button class="tiny">Review</button></span></div>
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">.pacnew<span class="r-auto">confirm</span></span><span class="r-val">2</span><span class="r-lever"><button class="tiny">Review</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">keyring<span class="r-auto">confirm</span></span><span class="r-val">12 d</span><span class="r-lever"><button class="tiny">Refresh</button></span></div>
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">pending updates<span class="r-auto">workflow</span></span><span class="r-val">47</span><span class="r-lever"><button class="tiny">Updates</button></span></div>
+ <div class="row"><span class="lamp l-fail">●</span><span class="r-name">arch-audit<span class="r-auto">workflow</span></span><span class="r-val">3 CVE</span><span class="r-lever"><button class="tiny">Updates</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">AUR staleness<span class="r-auto">workflow</span></span><span class="r-val">5</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">reboot-required<span class="r-auto">human</span></span><span class="r-val">no</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ <!-- SYSTEMD & BOOT -->
+ <div class="tile" onclick="toggle('sd')" id="t-sd">
+ <div class="tile-top">
+ <span class="rollup l-warn">●</span>
+ <div class="tile-head">
+ <div class="tile-name">systemd &amp; Boot</div>
+ <div class="tile-finding warnt">1 failed · timers 4/5</div>
+ </div>
+ </div>
+ <div class="tile-foot">
+ <span class="counts"><span class="fix">1 fix</span> · 3 watch</span>
+ <span class="expander">▸ detail</span>
+ </div>
+ <div class="detail" id="d-sd" style="display:none;">
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">is-system-running</span><span class="r-val">running</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">failed units<span class="r-auto">workflow</span></span><span class="r-val">1</span><span class="r-lever"><button class="tiny">Run workflow</button></span></div>
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">maintenance timers<span class="r-auto">confirm</span></span><span class="r-val">4 / 5</span><span class="r-lever"><button class="tiny">Enable</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">kernel taint</span><span class="r-val">0</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ <!-- LOGS & COREDUMPS -->
+ <div class="tile" onclick="toggle('log')" id="t-log">
+ <div class="tile-top">
+ <span class="rollup l-warn">●</span>
+ <div class="tile-head">
+ <div class="tile-name">Logs &amp; Coredumps</div>
+ <div class="tile-finding warnt">18 coredumps / 7d</div>
+ </div>
+ <div class="tile-foot" style="flex-direction:column; align-items:flex-end; gap:6px;">
+ <button class="tiny" onclick="event.stopPropagation()">Clean</button>
+ </div>
+ </div>
+ <div class="tile-foot">
+ <span class="counts"><span class="fix">3 fix</span> · 2 watch</span>
+ <span class="expander">▸ detail</span>
+ </div>
+ <div class="detail" id="d-log" style="display:none;">
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">coredumps<span class="r-auto">auto</span></span><span class="r-val">18 / 7d</span><span class="r-lever"><button class="tiny">Clear</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">journald<span class="r-auto">auto</span></span><span class="r-val">1.2 GB</span><span class="r-lever"><button class="tiny">Vacuum</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">app-log cleanup<span class="r-auto">auto</span></span><span class="r-val">ok</span><span class="r-lever"><button class="tiny">Run</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">journal errors<span class="r-auto">workflow</span></span><span class="r-val">12 real</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">kernel/hw events</span><span class="r-val">clean</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ <!-- MEMORY / THERMAL / POWER -->
+ <div class="tile" onclick="toggle('mem')" id="t-mem">
+ <div class="tile-top">
+ <span class="rollup l-warn">●</span>
+ <div class="tile-head">
+ <div class="tile-name">Memory / Thermal / Power</div>
+ <div class="tile-finding warnt">unclean-shutdown 75%</div>
+ </div>
+ </div>
+ <div class="tile-foot">
+ <span class="counts"><span class="fix">0 fix</span> · 6 watch</span>
+ <span class="expander">▸ detail</span>
+ </div>
+ <div class="detail" id="d-mem" style="display:none;">
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">memory<span class="r-auto">workflow</span></span><span class="r-val">104 GB free</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">swap / zram</span><span class="r-val">16 GiB</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">temps</span><span class="r-val">61° / 54°</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">thermal throttle</span><span class="r-val">no</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-na">○</span><span class="r-name">battery</span><span class="r-val">n/a</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">unclean-shutdown<span class="r-auto">workflow</span></span><span class="r-val">75%</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ <!-- NETWORK & POSTURE -->
+ <div class="tile" onclick="toggle('net')" id="t-net">
+ <div class="tile-top">
+ <span class="rollup l-ok">●</span>
+ <div class="tile-head">
+ <div class="tile-name">Network &amp; Posture</div>
+ <div class="tile-finding">all posture green</div>
+ </div>
+ </div>
+ <div class="tile-foot">
+ <span class="counts"><span class="fix">4 fix</span> · 2 watch</span>
+ <span class="expander">▸ detail</span>
+ </div>
+ <div class="detail" id="d-net" style="display:none;">
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">DNS / NM<span class="r-auto">workflow</span></span><span class="r-val">ok</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">firewall<span class="r-auto">confirm</span></span><span class="r-val">active</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">listeners</span><span class="r-val">3</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">tailscale<span class="r-auto">confirm</span></span><span class="r-val">4 / 4</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">fail2ban<span class="r-auto">confirm</span></span><span class="r-val">active</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">NTP<span class="r-auto">confirm</span></span><span class="r-val">synced</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ <!-- SERVICES / BACKUPS / VIRT -->
+ <div class="tile" onclick="toggle('svc')" id="t-svc">
+ <div class="tile-top">
+ <span class="rollup l-warn">●</span>
+ <div class="tile-head">
+ <div class="tile-name">Services &amp; Backups</div>
+ <div class="tile-finding warnt">docker reclaim 3 GB</div>
+ </div>
+ </div>
+ <div class="tile-foot">
+ <span class="counts"><span class="fix">2 fix</span> · 3 watch</span>
+ <span class="expander">▸ detail</span>
+ </div>
+ <div class="detail" id="d-svc" style="display:none;">
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">rsyncshot<span class="r-auto">workflow</span></span><span class="r-val">3h ago</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-warn">●</span><span class="r-name">docker reclaim<span class="r-auto">confirm</span></span><span class="r-val">3 GB</span><span class="r-lever"><button class="tiny">Prune</button></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">docker stopped</span><span class="r-val">2</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-na">○</span><span class="r-name">libvirt</span><span class="r-val">off</span><span class="r-lever"><span class="none">—</span></span></div>
+ <div class="row"><span class="lamp l-ok">●</span><span class="r-name">cron<span class="r-auto">confirm</span></span><span class="r-val">ok</span><span class="r-lever"><span class="none">—</span></span></div>
+ </div>
+ </div>
+
+ </div>
+</div>
+
+<!-- running / output-wall capsule -->
+<div class="capsule">
+ <div class="cap-hdr">
+ <div class="title">MAINT · <b>ratio</b> · <span class="running">CLEANING ◐</span></div>
+ <span style="color:var(--dim); font-size:12px;">4 Auto actions</span>
+ </div>
+ <div class="wall">
+ <div class="line"><span class="glyph l-prog">◐</span><span class="act">cache trim</span><span class="st">running…</span></div>
+ <div class="line done"><span class="glyph l-ok">●</span><span class="act">journal vacuum</span><span class="st">done · reclaimed <b>0.9 GB</b></span></div>
+ <div class="line done"><span class="glyph l-ok">●</span><span class="act">coredump clear</span><span class="st">done · <b>12 cleared</b></span></div>
+ <div class="line queued"><span class="glyph l-na">○</span><span class="act">app-log cleanup</span><span class="st">queued</span></div>
+ </div>
+ <div class="cap-foot"><button>Done</button></div>
+</div>
+
+<div class="legend">
+ Automation — <b>Auto</b> doctor cleans unattended · <b>Confirm</b> doctor previews then you click · <b>Human</b> panel nudges you to act · <b>Workflow</b> escalates to an agent workflow · <b>None</b> diagnostic only.
+</div>
+
+<script>
+ function toggle(id){
+ var t = document.getElementById('t-'+id);
+ var d = document.getElementById('d-'+id);
+ if(!d) return;
+ var open = d.style.display !== 'none';
+ d.style.display = open ? 'none' : 'block';
+ t.classList.toggle('expanded', !open);
+ var ex = t.querySelector('.expander');
+ if(ex) ex.textContent = open ? '▸ detail' : '▾ detail';
+ }
+</script>
+</body>
+</html>