Adds a better diff design and removes the select and copy feature

This commit is contained in:
2026-09-10 08:36:42 +02:00
parent bb012702fe
commit 008adbfdb6
19 changed files with 582 additions and 2756 deletions

View File

@@ -0,0 +1,281 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Helder — 3b · in-pane diff (design reference)</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet">
<style>
body { margin: 0; background: #EFF0EE; padding: 40px; font-family: 'IBM Plex Sans', sans-serif; color: #171C22; }
@keyframes blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
</style>
</head>
<body>
<div data-screen-label="03b Diff in pane" style="width:1760px;height:1000px;background:#101720;border:1px solid #CDD1CD;border-radius:4px;overflow:hidden;display:flex;flex-direction:column;color:#E4E7E6">
<div style="height:44px;flex:none;background:#18202B;border-bottom:1px solid #232C39;display:flex;align-items:center;gap:18px;padding:0 14px">
<div style="display:flex;gap:8px;flex:none">
<span style="width:12px;height:12px;border-radius:9999px;background:#E8913A"></span>
<span style="width:12px;height:12px;border-radius:9999px;background:#6C7783"></span>
<span style="width:12px;height:12px;border-radius:9999px;background:#3A424C"></span>
</div>
<div style="display:flex;align-items:baseline;gap:10px;flex:none">
<span style="font:700 13px/1 'IBM Plex Mono',monospace;letter-spacing:.02em;color:#F4F5F4">helder<span style="color:#E8913A;animation:blink 1.1s steps(1,end) infinite">.</span></span>
<span style="font:400 12px/1 'IBM Plex Mono',monospace;color:#6C7783">bob</span>
<span style="font:400 12px/1 'IBM Plex Mono',monospace;color:#6C7783">·</span>
<span style="font:500 12px/1 'IBM Plex Mono',monospace;color:#E8913A">bob2</span>
</div>
<div style="display:flex;align-items:center;gap:7px;font:400 12px/1 'IBM Plex Mono',monospace;color:#6C7783;flex:1;min-width:0">
<span>agents</span><span></span><span>mail-checker</span><span></span>
<span style="color:#F4F5F4;font-weight:600">README.md</span>
</div>
<div style="display:flex;align-items:center;gap:4px;flex:none">
<span style="display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:2px;font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0">Search <span style="font:600 12px/1 'IBM Plex Mono',monospace;color:#E8913A;border:1px solid #232C39;border-radius:2px;padding:4px 6px">⌘F</span></span>
<span style="display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:2px;font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0">Fluid <span style="font:600 12px/1 'IBM Plex Mono',monospace;color:#E8913A;border:1px solid #232C39;border-radius:2px;padding:4px 6px">⌘L</span></span>
<span style="display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:2px;font:400 12px/1 'IBM Plex Sans',sans-serif;color:#6C7783">Hidden <span style="font:600 12px/1 'IBM Plex Mono',monospace;color:#6C7783;border:1px solid #232C39;border-radius:2px;padding:4px 6px">⌘.</span></span>
<span style="display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:2px;font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0">Note <span style="font:600 12px/1 'IBM Plex Mono',monospace;color:#E8913A;border:1px solid #232C39;border-radius:2px;padding:4px 6px">⌘N</span></span>
<span style="display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:2px;background:rgba(232,145,58,.10);font:500 12px/1 'IBM Plex Sans',sans-serif;color:#F4F5F4">Git <span style="font:600 12px/1 'IBM Plex Mono',monospace;color:#E8913A;border:1px solid rgba(232,145,58,.35);border-radius:2px;padding:4px 6px">⌘G</span></span>
<span style="width:26px;height:26px;margin-left:6px;border:1px solid #232C39;border-radius:2px;display:flex;align-items:center;justify-content:center;font:600 12px/1 'IBM Plex Mono',monospace;color:#6C7783">?</span>
</div>
</div>
<div style="flex:1;min-height:0;display:flex;position:relative">
<!-- source control -->
<div style="width:300px;flex:none;background:#18202B;border-right:1px solid #232C39;display:flex;flex-direction:column">
<div style="height:46px;flex:none;box-sizing:border-box;padding:0 12px;display:flex;gap:8px;align-items:center;border-bottom:1px solid #232C39">
<div style="flex:1;min-width:0;height:30px;background:#101720;border:1px solid #232C39;border-radius:2px;padding:0 9px;display:flex;align-items:center;font:400 12px/1 'IBM Plex Sans',sans-serif;color:#E4E7E6">runs mail check once an hour</div>
<div style="width:30px;height:30px;flex:none;border:1px solid #232C39;border-radius:2px;display:flex;align-items:center;justify-content:center;font:400 15px/1 'IBM Plex Mono',monospace;color:#BAC0C0"></div>
</div>
<div style="padding:14px 12px 6px;font:700 10px/1 'IBM Plex Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#6C7783;display:flex;justify-content:space-between">
<span>staged changes</span><span style="color:#E8913A">3</span>
</div>
<div style="display:flex;flex-direction:column">
<div style="height:22px;display:flex;align-items:center;gap:7px;padding:0 12px;font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783;overflow:hidden"><span style="flex:none"></span><span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">agents/mail-checker</span></div>
<div style="height:26px;display:flex;align-items:center;gap:8px;padding:0 12px 0 10px;background:#232C39;border-left:2px solid #E8913A"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4;width:12px">M</span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span style="font:500 12px/1 'IBM Plex Sans',sans-serif;color:#F4F5F4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">README.md</span></div>
<div style="height:22px;display:flex;align-items:center;gap:7px;padding:0 12px;font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783;overflow:hidden"><span style="flex:none"></span><span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">scheduler</span></div>
<div style="height:26px;display:flex;align-items:center;gap:8px;padding:0 12px 0 12px;border-left:2px solid transparent"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4;width:12px">M</span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#F8C793;border-radius:2px;padding:4px 5px">yml</span><span style="font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">scheduler.yaml</span></div>
<div style="height:22px;display:flex;align-items:center;gap:7px;padding:0 12px;font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783;overflow:hidden"><span style="flex:none"></span><span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">state</span></div>
<div style="height:26px;display:flex;align-items:center;gap:8px;padding:0 12px 0 12px;border-left:2px solid transparent"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4;width:12px">M</span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#A8D6CB;border-radius:2px;padding:4px 5px">tsv</span><span style="font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">skill-usage.tsv</span></div>
</div>
<div style="margin:16px 12px 0;border-top:1px solid #232C39"></div>
<div style="padding:14px 12px 6px;font:700 10px/1 'IBM Plex Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#6C7783;display:flex;justify-content:space-between">
<span>changes</span><span style="color:#E8913A">3</span>
</div>
<div style="display:flex;flex-direction:column">
<div style="height:22px;display:flex;align-items:center;gap:7px;padding:0 12px;font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783;overflow:hidden"><span style="flex:none"></span><span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">.</span></div>
<div style="height:26px;display:flex;align-items:center;gap:8px;padding:0 12px 0 12px;border-left:2px solid transparent"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#F0B476;width:12px">M</span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span style="font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">CLAUDE.md</span></div>
<div style="height:22px;display:flex;align-items:center;gap:7px;padding:0 12px;font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783;overflow:hidden"><span style="flex:none"></span><span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">scripts</span></div>
<div style="height:26px;display:flex;align-items:center;gap:8px;padding:0 12px 0 12px;border-left:2px solid transparent"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#F0B476;width:12px">M</span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span style="font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">README.md</span></div>
<div style="height:26px;display:flex;align-items:center;gap:8px;padding:0 12px 0 12px;border-left:2px solid transparent"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#F0B476;width:12px">M</span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#EFBCB0;border-radius:2px;padding:4px 5px">sh</span><span style="font:400 12px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">check-docs-rot.sh</span></div>
</div>
<div style="flex:1"></div>
<div style="padding:12px;border-top:1px solid #232C39;font:400 11px/1.5 'IBM Plex Mono',monospace;color:#6C7783">3 staged · 3 unstaged</div>
</div>
<!-- explorer -->
<div style="width:288px;flex:none;background:#18202B;border-right:1px solid #232C39;display:flex;flex-direction:column;overflow:hidden">
<div style="height:46px;flex:none;display:flex;align-items:center;justify-content:space-between;padding:0 12px;border-bottom:1px solid #232C39;font:700 10px/1 'IBM Plex Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#6C7783"><span>explorer</span><span>bob</span></div>
<div style="flex:1;min-height:0;padding:6px 0;display:flex;flex-direction:column;font:400 13px/1 'IBM Plex Sans',sans-serif;overflow:hidden">
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#F4F5F4"><span style="color:#E8913A;width:8px"></span><span style="color:#828D9A"></span>agents</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>knowledge-researcher</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>lead-agent</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#F4F5F4"><span style="color:#E8913A;width:8px"></span><span style="color:#828D9A"></span>mail-checker</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 60px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>PROMPT.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 58px;color:#F4F5F4;background:#232C39;border-left:2px solid #E8913A"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span style="font-weight:500">README.md</span><span style="flex:1"></span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4">M</span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 60px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>STATE.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>ok-monitor</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>sterrenkijker</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>tony</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>README.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>assets</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>data</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>docker</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>logs</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#F4F5F4"><span style="color:#E8913A;width:8px"></span><span style="color:#828D9A"></span>scheduler</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>prompts</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>README.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>runs-2026H2.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>runs.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#F8C793;border-radius:2px;padding:4px 5px">yml</span><span>scheduler.yaml</span><span style="flex:1"></span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4">M</span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#EFBCB0;border-radius:2px;padding:4px 5px">sh</span><span>test.sh</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#EFBCB0;border-radius:2px;padding:4px 5px">sh</span><span>tick.sh</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#BAC0C0"><span style="color:#6C7783;width:8px"></span><span style="color:#828D9A"></span>scripts</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 12px;color:#F4F5F4"><span style="color:#E8913A;width:8px"></span><span style="color:#828D9A"></span>state</div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#C3A6CE;border-radius:2px;padding:4px 5px">json</span><span>mail-state.json</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#C3A6CE;border-radius:2px;padding:4px 5px">json</span><span>read-counts.json</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>README.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 44px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#A8D6CB;border-radius:2px;padding:4px 5px">tsv</span><span>skill-usage.tsv</span><span style="flex:1"></span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4">M</span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>CLAUDE.md</span><span style="flex:1"></span><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4">M</span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>GUARDRAILS.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>LOOP.md</span><span style="flex:1"></span></div>
<div style="height:24px;display:flex;align-items:center;gap:7px;padding:0 12px 0 28px;color:#BAC0C0"><span style="font:600 10px/1 'IBM Plex Mono',monospace;color:#101720;background:#BAC0C0;border-radius:2px;padding:4px 5px">md</span><span>MEMORY.md</span><span style="flex:1"></span></div>
</div>
</div>
<!-- editor · diff -->
<div style="flex:1;min-width:0;background:#101720;display:flex;flex-direction:column;overflow:hidden">
<div style="height:46px;flex:none;display:flex;align-items:center;border-bottom:1px solid #232C39">
<span style="width:46px;flex:none;text-align:center;font:700 10px/1 'IBM Plex Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#6C7783">bob</span>
<div style="flex:1;min-width:0;display:flex;align-items:center;gap:12px;padding:0 12px">
<span style="font:700 10px/1 'IBM Plex Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#6C7783">modified</span>
<span style="font:500 12px/1 'IBM Plex Mono',monospace;color:#8FBFB4">+2</span>
<span style="font:500 12px/1 'IBM Plex Mono',monospace;color:#C4741F">2</span>
<span style="flex:1"></span>
<div style="display:flex;border:1px solid #232C39;border-radius:2px;overflow:hidden">
<span style="padding:5px 12px;font:500 11px/1 'IBM Plex Sans',sans-serif;color:#171C22;background:#E8913A">Actual</span>
<span style="padding:5px 12px;font:400 11px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;border-left:1px solid #232C39">Original</span>
<span style="padding:5px 12px;font:400 11px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;border-left:1px solid #232C39">Preview</span>
<span style="padding:5px 12px;font:400 11px/1 'IBM Plex Sans',sans-serif;color:#BAC0C0;border-left:1px solid #232C39">Diff</span>
</div>
</div>
</div>
<div style="flex:1;min-height:0;display:flex;overflow:hidden">
<div style="width:46px;flex:none;border-right:1px solid #232C39;display:flex;flex-direction:column;padding-top:8px;font:600 10px/1 'IBM Plex Mono',monospace;color:#8FBFB4">
<span style="height:110px"></span>
<span style="height:20px;display:flex;align-items:center;justify-content:center;background:#232C39">M</span>
<span style="height:340px"></span>
<span style="height:20px;display:flex;align-items:center;justify-content:center;color:#C4741F">M</span>
</div>
<div style="flex:1;min-width:0;display:grid;grid-template-columns:44px 1fr;align-content:start;font:400 13px/20px 'IBM Plex Mono',monospace;padding:8px 0">
<span style="text-align:right;padding-right:12px;color:#5A6472">1</span><span style="padding-right:18px;color:#F4F5F4;text-wrap:pretty"># mail-checker — how I dispatch it</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">2</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">3</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">This file is for me (Bob), the dispatcher. It says when to run this agent and how. The agent's own prompt is <span style="color:#A8D6CB">[`PROMPT.md`](PROMPT.md)</span>. I do not read that file myself.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">6</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">7</span><span style="padding-right:18px;color:#F4F5F4;text-wrap:pretty">## What it does</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">8</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">9</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">It works through imported mails that no AI has looked at yet. Per mail it does three things:</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">11</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">12</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">1. Judges whether Jonathan should actually read it.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">13</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">2. Cleans the body into readable Markdown.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">14</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">3. Makes a todo when the mail asks for a concrete action.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">15</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">16</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">New people it meets get a Vault note, so Blijnder remembers them.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">17</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">18</span><span style="padding-right:18px;color:#F4F5F4;text-wrap:pretty">## The hard boundary</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">19</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">20</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">It reads, cleans, classifies and records. It never replies to a mail, never deletes a mail, and never chooses a recipient. Nothing that it touches leaves Blijnder, and there is no exception to that.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">23</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">24</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">Between 2026-08-22 and 2026-08-27 there was one: an invoice went to the administration through a script of its own. Skynet does that job now (skynet#41), thus the workspace gave it up (bob#371). The agent is mute again, and the outbound gate refuses every command that would speak for it.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">28</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">29</span><span style="padding-right:18px;color:#F4F5F4;text-wrap:pretty">## When to dispatch</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">30</span><span></span>
<span style="text-align:right;padding-right:12px;color:#8FBFB4;background:rgba(143,191,180,.12);border-left:2px solid #8FBFB4">31</span><span id="changed-line" style="padding-right:18px;color:#F4F5F4;background:rgba(143,191,180,.12);text-wrap:pretty">- The scheduler fires it. Job <span style="color:#F0B476">`mail-checker-ronde`</span>, every hour, on the hour.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">32</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">- Jonathan asks for a mail sweep.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">33</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">- The mail step of my tick shows unchecked mail piling up.</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">34</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">35</span><span style="padding-right:18px;color:#F4F5F4;text-wrap:pretty">## How to dispatch</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">36</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">37</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">Send a subagent the <span style="color:#F4F5F4;font-weight:600">path</span>, not the content:</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">38</span><span></span>
<span style="text-align:right;padding-right:12px;color:#5A6472">39</span><span style="padding-right:18px;color:#6C7783;text-wrap:pretty">```</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">40</span><span style="padding-right:18px;color:#BAC0C0;text-wrap:pretty">Agent tool → "Read agents/mail-checker/PROMPT.md and follow it."</span>
<span style="text-align:right;padding-right:12px;color:#5A6472">41</span><span style="padding-right:18px;color:#6C7783;text-wrap:pretty">```</span>
</div>
<div style="width:16px;flex:none;border-left:1px solid #232C39;display:flex;flex-direction:column;align-items:center;padding-top:8px">
<span style="height:104px"></span>
<span style="width:4px;height:4px;background:#6C7783"></span>
<span style="height:64px"></span>
<span style="width:4px;height:4px;background:#8FBFB4"></span>
<span style="height:184px"></span>
<span style="width:4px;height:4px;background:#6C7783"></span>
<span style="height:118px"></span>
<span style="width:4px;height:4px;background:#C4741F"></span>
</div>
</div>
</div>
<!-- agent -->
<div style="width:480px;flex:none;background:#101720;border-left:1px solid #232C39;display:flex;flex-direction:column;overflow:hidden">
<div style="flex:1;min-height:0;padding:14px 16px;display:flex;flex-direction:column;gap:12px;overflow:hidden;font:400 13px/1.6 'IBM Plex Sans',sans-serif;color:#BAC0C0">
<div style="font:400 12px/1.6 'IBM Plex Mono',monospace;color:#6C7783;text-wrap:pretty">98:| <span style="color:#F0B476">[`check-docs-rot.sh`](check-docs-rot.sh)</span> | It checks my rule files for references that are not correct any more: a script or a flag that does not exist, a dead markdown link, an orphan script, an</div>
<div style="font:400 12px/1.6 'IBM Plex Mono',monospace;color:#6C7783">└ Allowed by auto mode classifier</div>
<div style="display:flex;gap:10px"><span style="color:#6C7783"></span><span style="text-wrap:pretty">The column is gone. <span style="color:#F0B476;font-family:'IBM Plex Mono',monospace">CLAUDE.md</span> now names which agents exist, and nothing about their clock.</span></div>
<div style="text-wrap:pretty"><span style="font-weight:600;color:#F4F5F4">Why it was there.</span> The table was written as one map with three columns, and <span style="color:#F0B476;font-family:'IBM Plex Mono',monospace">check-docs-rot.sh</span> section L then enforced the third against the cron lines. That made the coupling real: each change of a schedule broke the check until somebody opened a pull request on the root.</div>
<div style="text-wrap:pretty"><span style="font-weight:600;color:#F4F5F4">What changed.</span> The table is two columns. Below it stands one rule: when a job runs, and whether it runs at all, stands in <span style="color:#F0B476;font-family:'IBM Plex Mono',monospace">scheduler/scheduler.yaml</span> and only there. Section L still holds the table against <span style="color:#F0B476;font-family:'IBM Plex Mono',monospace">agents/</span> in both directions, and it no longer reads a clock.</div>
<div style="text-wrap:pretty"><span style="font-weight:600;color:#F4F5F4">The check is cleaner now.</span> It reported <span style="color:#F0B476;font-family:'IBM Plex Mono',monospace">knowledge-researcher</span> and <span style="color:#F0B476;font-family:'IBM Plex Mono',monospace">sterrenkijker</span> as wrong; both were this same duplication, and both are gone.</div>
<div style="text-wrap:pretty">Five files stand changed and uncommitted. <span style="color:#F0B476;font-family:'IBM Plex Mono',monospace">CLAUDE.md</span> is a root file, so it needs a pull request when you commit it.</div>
<div style="font:400 12px/1.6 'IBM Plex Mono',monospace;color:#6C7783">✳ Churned for 2m 49s · done 8:10 AM</div>
</div>
<div style="margin:0 16px 12px;height:44px;flex:none;background:#101720;border:2px solid #E8913A;box-shadow:0 0 0 2px rgba(232,145,58,.22);border-radius:2px;display:flex;align-items:center;gap:8px;padding:0 12px">
<span style="font:400 13px/1 'IBM Plex Mono',monospace;color:#E8913A"></span>
<span style="width:1px;height:16px;background:#E8913A;animation:blink 1.1s steps(1,end) infinite"></span>
<!-- hover: original of the whole file, same scroll -->
<!-- id added for the demo script -->
<div id="original-overlay" style="display:none;position:absolute;z-index:20;top:0;right:0;bottom:0;width:496px;background:#101720;border-left:2px solid #C4741F;box-shadow:0 4px 16px rgba(23,28,34,.10);flex-direction:column;overflow:hidden">
<div style="height:46px;flex:none;display:flex;align-items:center;gap:12px;padding:0 14px;border-bottom:1px solid #232C39;background:#18202B">
<span style="font:700 10px/1 'IBM Plex Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#C4741F">original</span>
<span style="font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783">before this change · same scroll</span>
<span style="flex:1"></span>
<span style="font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783">hold hover</span>
</div>
<div style="flex:1;min-height:0;display:grid;grid-template-columns:35px 1fr;align-content:start;font:400 10.3px/20px 'IBM Plex Mono',monospace;padding:8px 0;overflow:hidden">
<span style="text-align:right;padding-right:9px;color:#5A6472">1</span><span style="padding-right:11px;color:#F4F5F4;text-wrap:pretty"># mail-checker — how I dispatch it</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">2</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">3</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">This file is for me (Bob), the dispatcher. It says when to run this agent and how. The agent's own prompt is <span style="color:#A8D6CB">[`PROMPT.md`](PROMPT.md)</span>. I do not read that file myself.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">6</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">7</span><span style="padding-right:11px;color:#F4F5F4;text-wrap:pretty">## What it does</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">8</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">9</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">It works through imported mails that no AI has looked at yet. Per mail it does three things:</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">11</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">12</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">1. Judges whether Jonathan should actually read it.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">13</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">2. Cleans the body into readable Markdown.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">14</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">3. Makes a todo when the mail asks for a concrete action.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">15</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">16</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">New people it meets get a Vault note, so Blijnder remembers them.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">17</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">18</span><span style="padding-right:11px;color:#F4F5F4;text-wrap:pretty">## The hard boundary</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">19</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">20</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">It reads, cleans, classifies and records. It never replies to a mail, never deletes a mail, and never chooses a recipient. Nothing that it touches leaves Blijnder, and there is no exception to that.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">23</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">24</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">Between 2026-08-22 and 2026-08-27 there was one: an invoice went to the administration through a script of its own. Skynet does that job now (skynet#41), thus the workspace gave it up (bob#371). The agent is mute again, and the outbound gate refuses every command that would speak for it.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">28</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">29</span><span style="padding-right:11px;color:#F4F5F4;text-wrap:pretty">## When to dispatch</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">30</span><span></span>
<span style="text-align:right;padding-right:9px;color:#C4741F;background:rgba(196,116,31,.14);border-left:2px solid #C4741F">31</span><span style="padding-right:11px;color:#E4E7E6;background:rgba(196,116,31,.14);text-wrap:pretty">- The scheduler fires it. Job <span style="color:#F0B476">`mail-checker-ronde`</span>, every 15 minutes.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">32</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">- Jonathan asks for a mail sweep.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">33</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">- The mail step of my tick shows unchecked mail piling up.</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">34</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">35</span><span style="padding-right:11px;color:#F4F5F4;text-wrap:pretty">## How to dispatch</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">36</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">37</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">Send a subagent the <span style="color:#F4F5F4;font-weight:600">path</span>, not the content:</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">38</span><span></span>
<span style="text-align:right;padding-right:9px;color:#5A6472">39</span><span style="padding-right:11px;color:#6C7783;text-wrap:pretty">```</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">40</span><span style="padding-right:11px;color:#BAC0C0;text-wrap:pretty">Agent tool → "Read agents/mail-checker/PROMPT.md and follow it."</span>
<span style="text-align:right;padding-right:9px;color:#5A6472">41</span><span style="padding-right:11px;color:#6C7783;text-wrap:pretty">```</span>
</div>
</div>
</div>
<div style="padding:0 16px 12px;display:flex;flex-direction:column;gap:6px;font:400 11px/1.5 'IBM Plex Mono',monospace;color:#6C7783">
<div style="display:flex;align-items:center;gap:8px">
<span>[Opus 5 · 1M]</span>
<span style="color:#171C22;background:#E8913A;border-radius:2px;padding:3px 6px;font-weight:600">bob</span>
<span>|</span><span style="color:#A8D6CB">⑂ bob2</span>
<span style="flex:1"></span><span>/rc</span>
</div>
<div><span style="color:#E8913A">▸▸ auto mode on</span> (shift+tab to cycle) · ← for agents</div>
</div>
<div style="height:150px;flex:none;background:#101720;border-top:1px solid #232C39;padding:12px 16px;font:400 12px/1.7 'IBM Plex Mono',monospace;color:#BAC0C0">
<div><span style="color:#A8D6CB">[bob2]</span><span style="color:#828D9A">[~/code/bob]$</span> <span style="display:inline-block;width:7px;height:14px;background:#E8913A;vertical-align:-2px;animation:blink 1.1s steps(1,end) infinite"></span></div>
</div>
</div>
</div>
<div style="height:28px;flex:none;background:#18202B;border-top:1px solid #232C39;display:flex;align-items:center;gap:16px;padding:0 14px;font:400 11px/1 'IBM Plex Mono',monospace;color:#6C7783">
<span style="color:#E8913A">⑂ bob2</span>
<span style="color:#A8D6CB">+22</span><span style="color:#C4741F">66</span>
<span style="flex:1"></span>
<span>agents/mail-checker/README.md</span>
<span>·</span><span>Ln 1, Col 1</span><span>·</span><span>UTF-8</span><span>·</span><span>LF</span><span>·</span><span style="color:#D4D9D8">Markdown</span>
</div>
</div>
<script>
var row = document.getElementById('changed-line');
var overlay = document.getElementById('original-overlay');
row.addEventListener('mouseenter', function () { overlay.style.display = 'flex'; });
row.addEventListener('mouseleave', function () { overlay.style.display = 'none'; });
</script>
</body>
</html>

View File

@@ -0,0 +1,245 @@
# Handoff: Helder — in-pane diff (screen 3b)
## Overview
Helder is a desktop editor for working with Claude Code. This handoff covers **one screen**: the
workspace with a modified file open in the editor pane, in **Actual** view.
The idea behind the screen: the user always reads the **current** version of the file. A changed
line is marked in place with a teal rule and a teal tint — nothing else moves, no split view, no
`+`/`` line pairs. When the user hovers a changed line, the **whole original file** slides in over
the right-hand column (agent + terminal) at the **same scroll position**, so the two versions can be
compared line by line. The overlay disappears on mouse-out. There is no mode to enter and no mode to
leave.
## About the design files
`03b-in-pane-diff.html` in this folder is a **design reference created in HTML** — a prototype that
shows the intended look and behaviour. It is not production code to copy.
The task is to **recreate this design in the target codebase's own environment** (Electron + React,
Tauri, SwiftUI, whatever Helder already uses) with that codebase's established patterns, components
and styling layer. If no environment exists yet, choose the framework that fits the product and
implement the design there.
The HTML uses inline styles throughout because of how the design tool works. Do not treat that as a
styling instruction — move the values into the codebase's own token/theme layer.
## Fidelity
**High fidelity.** Colours, type, spacing, row heights and states below are final and exact.
Recreate the UI pixel-perfectly. The only intentionally loose part is the file-tree and
source-control content, which is sample data.
## Screen
**Name:** Workspace — file modified, Actual view
**Canvas:** 1760 × 1000 px (design size; the real window is resizable — see *Responsive behaviour*)
**Purpose:** read and edit a file that has uncommitted changes, while Claude Code works in the right
column; check what any changed line used to be without leaving the file.
### Column layout (left → right)
| Region | Width | Background | Divider |
|---|---|---|---|
| Source control | 300 px, fixed | `#18202B` | 1 px `#232C39` right |
| Explorer | 288 px, fixed | `#18202B` | 1 px `#232C39` right |
| Editor | flexible (692 px at 1760) | `#101720` | — |
| Agent + terminal | 480 px, fixed | `#101720` | 1 px `#232C39` left |
Vertical stack: title bar 44 px → body row (flex: 1) → status bar 28 px.
### Title bar — 44 px, `#18202B`, 1 px `#232C39` bottom
- Traffic lights: three 12 px circles, `#E8913A` / `#6C7783` / `#3A424C`, 8 px gap, 14 px from left.
- Wordmark `helder.` — IBM Plex Mono 700 13 px `#F4F5F4`; **the period is `#E8913A` and blinks**
(see *Animation*).
- Repo · worktree: `bob` `#6C7783` · `bob2` `#E8913A` 500, Plex Mono 12 px.
- Breadcrumb: Plex Mono 12 px `#6C7783`, `` separators, last crumb `#F4F5F4` 600.
- Right cluster, each 6 px 9 px padding, Plex Sans 12 px label + Plex Mono 12 px 600 shortcut chip
(1 px `#232C39`, radius 2, padding 4 px 6 px): Search ⌘F · Fluid ⌘L · Hidden ⌘. (label and chip
`#6C7783` — the off state) · Note ⌘N · **Git ⌘G active**: background `rgba(232,145,58,.10)`, label
`#F4F5F4`, chip border `rgba(232,145,58,.35)`. Then a 26 × 26 `?` button, 1 px `#232C39`.
### The 46 px header row
All three panel headers sit on **one 46 px row** with their 1 px `#232C39` bottom borders on the
same line. This alignment is deliberate — do not let any one of them grow.
1. **Source control commit row** — 46 px, padding 0 12 px, flex, 8 px gap, centred.
Commit field: flex 1, height 30 px, `#101720`, 1 px `#232C39`, radius 2, padding 0 9 px,
Plex Sans 12 px `#E4E7E6`. Sample value: `runs mail check once an hour`.
Push button: 30 × 30, 1 px `#232C39`, radius 2, glyph `↑` Plex Mono 15 px `#BAC0C0`.
2. **Explorer header** — 46 px, padding 0 12 px, space-between, Plex Mono 700 10 px, tracking
`.14em`, uppercase, `#6C7783`: `EXPLORER``BOB`.
3. **Editor header** — 46 px. A 46 px-wide agent-rail cell first (centred `BOB`, same label style),
then: `MODIFIED` (Plex Mono 700 10 px uppercase `#6C7783`), `+2` `#8FBFB4`, `2` `#C4741F` (both
Plex Mono 500 12 px), spacer, then the view switch.
**View switch** — a single bordered group, 1 px `#232C39`, radius 2, `overflow: hidden`, each item
5 px 12 px, Plex Sans 11 px, dividers 1 px `#232C39` between items:
`Actual` (**active**: `#E8913A` fill, `#171C22` text, weight 500) · `Original` · `Preview` · `Diff`
(inactive: `#BAC0C0`). Actual is the default and stays the default.
### Source control panel
Section header: padding 14 px 12 px 6 px, Plex Mono 700 10 px tracking `.14em` uppercase `#6C7783`,
count on the right in `#E8913A`.
Folder line: 22 px, `▤` + path, Plex Mono 11 px `#6C7783`, ellipsis on overflow.
File row: 26 px, 8 px gap — status letter (Plex Mono 600 10 px, 12 px wide; **staged `#8FBFB4`,
unstaged `#F0B476`**), file-type chip (Plex Mono 600 10 px, `#101720` text, radius 2, padding 4 px
5 px; `md` `#BAC0C0`, `yml` `#F8C793`, `tsv` `#A8D6CB`, `sh` `#EFBCB0`, `json`/`php` `#C3A6CE`,
`js` `#F0B476`), then the file name Plex Sans 12 px `#BAC0C0`.
**Selected row:** background `#232C39`, 2 px `#E8913A` left border, left padding reduced by 2 px so
the text does not shift, name `#F4F5F4` 500. Unselected rows carry `border-left: 2px solid
transparent` so nothing moves on selection.
Footer: 12 px padding, 1 px `#232C39` top, Plex Mono 11 px `#6C7783`, `3 staged · 3 unstaged`.
### Explorer
Rows are **24 px**. Folder: 8 px-wide chevron (`⌄` open `#E8913A`, `` closed `#6C7783`), `▤`
`#828D9A`, name Plex Sans 13 px (`#F4F5F4` when open, `#BAC0C0` when closed). Indent = 12 px + 16 px
per level. Files use the same type chips as source control; a modified file shows a trailing `M`
(Plex Mono 600 10 px `#8FBFB4`). Selected file: `#232C39`, 2 px `#E8913A` left border, name 500
`#F4F5F4`.
### Editor pane
- **Agent rail** — 46 px, 1 px `#232C39` right. Holds per-block `M` markers aligned to the changed
region: a marker is Plex Mono 600 10 px, 20 px tall, centred; the active block is `#8FBFB4` on
`#232C39`, an unstaged block is `#C4741F` on transparent.
- **Code grid** — `grid-template-columns: 44px 1fr`, `align-content: start`, padding 8 px 0,
Plex Mono 400 **13 px / 20 px**.
Line numbers: right-aligned, padding-right 12 px, `#5A6472`.
Line text: padding-right 18 px, `#BAC0C0`; markdown headings `#F4F5F4`; fenced-code markers
`#6C7783`; inline code and links `#F0B476`; a markdown link target `#A8D6CB`. Long lines **wrap**
(`text-wrap: pretty`) and keep their single line number — wrapped rows are how the pane behaves at
any width.
- **Changed line (the core of this screen)** — line number `#8FBFB4` on `rgba(143,191,180,.12)` with
a **2 px `#8FBFB4` left border**; the text cell has the same `rgba(143,191,180,.12)` tint and text
`#F4F5F4`. No `+` glyph, no second row, no strikethrough. This is the current content, simply
marked as changed.
- **Minimap strip** — 16 px, 1 px `#232C39` left, 4 × 4 px marks: `#6C7783` normal, `#8FBFB4` staged
change, `#C4741F` unstaged change.
### Agent + terminal column (480 px)
Conversation body: padding 14 px 16 px, 12 px gap, Plex Sans 13 px / 1.6 `#BAC0C0`; tool output and
metadata in Plex Mono 12 px / 1.6 `#6C7783`; file paths and identifiers inline in Plex Mono `#F0B476`;
lead-ins (`Why it was there.`) `#F4F5F4` 600.
Prompt field: 44 px, `#101720`, **2 px `#E8913A` border + `0 0 0 2px rgba(232,145,58,.22)` ring**
(the house focus state), radius 2, `` `#E8913A`, 1 × 16 px `#E8913A` caret that blinks.
Status lines: Plex Mono 11 px `#6C7783`; `bob` chip = `#E8913A` fill, `#171C22` text, radius 2;
`⑂ bob2` `#A8D6CB`; `▸▸ auto mode on` `#E8913A`.
Terminal: 150 px, 1 px `#232C39` top, Plex Mono 12 px / 1.7; prompt `[bob2]` `#A8D6CB`,
`[~/code/bob]$` `#828D9A`, 7 × 14 px `#E8913A` blinking block cursor.
### Status bar — 28 px, `#18202B`, 1 px `#232C39` top
Plex Mono 11 px `#6C7783`, 16 px gap, 0 14 px padding: `⑂ bob2` `#E8913A` · `+22` `#A8D6CB` ·
`66` `#C4741F` · spacer · file path · `·` · `Ln 1, Col 1` · `UTF-8` · `LF` · language `#D4D9D8`.
## Interactions & behaviour
### The hover reveal (the one behaviour to get right)
- **Trigger:** `mouseenter` anywhere on a changed line's text cell. **Dismiss:** `mouseleave`.
No click, no pin, no delay in the prototype. If you add a delay, keep it under 120 ms in and 0 ms
out — the gesture must feel like looking, not like opening something.
- **What appears:** a panel pinned to the **top, right and bottom of the body row**, 496 px wide, so
it covers the whole agent + terminal column and nothing else. `#101720`, **2 px `#C4741F` left
border**, `box-shadow: 0 4px 16px rgba(23,28,34,.10)`, `overflow: hidden`, `z-index` above the
agent column.
- **Panel header:** 46 px (the same 46 px as the editor header, so the first code line of both panes
starts at the same y), `#18202B`, 1 px `#232C39` bottom: `ORIGINAL` Plex Mono 700 10 px tracking
`.14em` `#C4741F`, then `before this change · same scroll` Plex Mono 11 px `#6C7783`, then
`hold hover` right-aligned in the same muted style.
- **Panel body:** the **whole original file**, not a hunk — same lines, same order, same wrap points
and **the same vertical position for every line as in the editor pane**. In the prototype this is
achieved by scaling the type to the narrower column: `grid-template-columns: 35px 1fr`, font
`400 10.3px/20px` Plex Mono, gutter padding-right 9 px, text padding-right 11 px. The line-height
stays 20 px, so line *n* sits at the same y in both panes.
**In the real implementation, do it properly:** render the original text into the same layout the
editor uses and synchronise scroll offsets, so line *n* of the original is always level with line
*n* of the current file. The rule to satisfy: *the changed line and its previous version are on the
same horizontal line of the screen*.
- **The old line inside the panel:** line number `#C4741F` on `rgba(196,116,31,.14)` with a 2 px
`#C4741F` left border; text cell same tint, text `#E4E7E6`. So: **teal = what is there now, amber
= what was there before.** Never green/red.
- The editor keeps its own scroll while the overlay is open; the overlay follows it.
### Other states
- Hover on any list row (source control, explorer, menus): fill deepens one step
(`#18202B``#232C39`). No lift, no shadow, no opacity change, no scale on press.
- Focus on a text field: 2 px `#E8913A` border + 2 px `rgba(232,145,58,.22)` ring.
- Disabled: 40 % opacity, `cursor: not-allowed`.
### Animation
Only two things move:
1. **The blinking period / caret**`@keyframes blink { 0%,49% { opacity:1 } 50%,100% { opacity:0 } }`,
`1.1s steps(1, end) infinite`. Used on the wordmark period, the prompt caret and the terminal
cursor. Freeze under `prefers-reduced-motion`.
2. **Colour transitions** — 160 ms `cubic-bezier(0.22, 1, 0.36, 1)`; 120 ms on small controls.
No entrance animation, no slide, no fade for the overlay — it is there or it is not. No scroll
reveal, no parallax.
### Responsive behaviour
Source control (300) and explorer (288) and the agent column (480) are fixed; the editor takes the
rest. Below roughly 1400 px the design has not been specified — ask before inventing collapse
behaviour. The hover panel is always 496 px and always anchored right.
## State
| State | Type | Notes |
|---|---|---|
| `activeView` | `'actual' \| 'original' \| 'preview' \| 'diff'` | Default `'actual'`. Persist per file. |
| `hoveredChangedLine` | `lineNumber \| null` | Drives the overlay. Cleared on mouse-out and on scroll-end if the pointer leaves. |
| `changedLines` | `Map<lineNumber, { current: string, previous: string, staged: boolean }>` | From the VCS diff of working tree vs HEAD/index. |
| `originalText` | `string` | Full HEAD/index version of the open file, needed for the overlay. |
| `editorScrollTop` | `number` | Mirrored into the overlay so the two panes stay in register. |
| `selectedFile`, `stagedFiles`, `unstagedFiles` | — | Source control and explorer content. |
Data needed: the file's working-tree content, its original content, and a line-level diff mapping
current line numbers to previous content. The overlay must be able to render the original file
immediately — pre-fetch it when a modified file is opened, not on hover.
## Design tokens
**Surfaces** `#101720` base · `#18202B` raised · `#232C39` selected/hover · `#3A424C` rule-strong
**Text** `#F4F5F4` strong · `#E4E7E6` body-strong · `#BAC0C0` body · `#828D9A` dim · `#6C7783` muted ·
`#5A6472` line numbers
**Accent** `#E8913A` amber · `#C4741F` amber-deep (previous state) · `#F0B476` amber-soft (inline code)
**Change** `#8FBFB4` current/changed, tint `rgba(143,191,180,.12)` · `#C4741F` previous, tint
`rgba(196,116,31,.14)`
**Syntax / chips** `#A8D6CB` string · `#F8C793` number-keyword · `#C3A6CE` structural · `#D8BEE4`
directive · `#EFBCB0` selector · `#D4D9D8` property
**Radius** 0 default · 2 px controls, chips, panels · 4 px window
**Borders** 1 px `#232C39` hairline · 2 px accent, used only for the selection marker, the changed-line
rule and a focused field
**Shadow** dropdown `0 4px 16px rgba(23,28,34,.10)`; modal `0 16px 48px rgba(23,28,34,.18)`. Nothing else
casts a shadow.
**Row heights** 22 px meta · 24 px explorer · 26 px source-control file · 28 px status bar · 30 px menu ·
34/38 px fields · 44 px title bar · 46 px panel headers
**Type** IBM Plex Mono 400/500/600/700 — code, labels, all numbers; IBM Plex Sans 400/500/600 — UI
text and prose. Code 13 px / 20 px. Labels 10 px, tracking `.14em`, uppercase. UI text 1213 px.
**Do not use** green or red for change, gradients, blur, emoji, white or pure black.
## Assets
None. No images, icons or fonts ship with this handoff. Both faces load from Google Fonts (IBM Plex
Mono, IBM Plex Sans) — swap in the licensed binaries in the app. Every glyph in the design is a
Unicode mark set in Plex Mono (`` `⌄` `▤` `↑` `⑂` `·` `→` `▸▸` `✳` `└`); if the app already uses
Lucide at stroke width 1.75, those are the sanctioned replacements for the folder and arrow marks.
## Files
- `03b-in-pane-diff.html` — the screen, standalone. Hover the teal line 31
(`- The scheduler fires it. Job \`mail-checker-ronde\`, every hour, on the hour.`) to see the
original overlay.
- Source of truth in the design project: `Helder IDE.dc.html`, section **[ 03 ] Diff**, screen
**3b**. Section 3a in the same file shows the older full-screen side-by-side diff, kept for
reference; 3b replaces it for in-pane use.