chore: archive design handoff bundle for toolbar refresh

Stores SethMux_4-24-26.zip + extracted design_handoff_sethmux_toolbar/
so the spec, mockups, and reference jsx components stay in-repo for
future reference. Not served in production — the only file that ships
is static/toolbar.js, which already matches the design's toolbar.js
byte-for-byte.
This commit is contained in:
Mortdecai
2026-04-24 19:51:48 -04:00
parent 2b375b0206
commit b8a7810bfd
8 changed files with 1340 additions and 0 deletions
@@ -0,0 +1,197 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>sethmux — desktop with tabs</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<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=Roboto:wght@400;500&family=Roboto+Mono:wght@400&display=swap" rel="stylesheet">
<style>
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
background:#0d0d10;
display:flex;align-items:center;justify-content:center;
font:12px/1.4 'Roboto','Helvetica Neue',Arial,sans-serif;
-webkit-font-smoothing:antialiased;
padding:24px;
overflow:auto;
}
/* ── App inside the browser ───────────────────────── */
.app{
background:#1a1a1d;
color:#e8eaed;
height:100%;
display:flex;flex-direction:column;
font:12px/1.4 'Roboto','Helvetica Neue',Arial,sans-serif;
}
/* sethmux own top chrome (matches Google-workspace dark) */
.top{
height:48px;flex-shrink:0;
background:#202124;border-bottom:1px solid #3c4043;
display:flex;align-items:center;padding:0 14px;gap:14px;
}
.brand{
color:#D35400;font-weight:500;font-size:14px;letter-spacing:.2px;
font-family:'Roboto',sans-serif;
}
.tabs{display:flex;gap:0;height:100%;align-items:stretch}
.tab{
display:flex;align-items:center;gap:8px;
padding:0 14px;height:100%;
color:#9aa0a6;font-size:12px;font-weight:500;
border-bottom:2px solid transparent;cursor:default;
}
.tab.active{color:#D35400;border-bottom-color:#D35400}
.tab .num{
font-family:'Roboto Mono',ui-monospace,monospace;font-size:10px;
color:#5f6368;
}
.tab.active .num{color:#D35400;opacity:.8}
.tab .dot{
width:6px;height:6px;border-radius:50%;background:#3c4043;
}
.tab.active .dot{background:#D35400}
.tab.alert .dot{background:#fdd663}
.spacer{flex:1}
.meta{
color:#9aa0a6;font-family:'Roboto Mono',ui-monospace,monospace;font-size:11px;
}
.meta b{color:#e8eaed;font-weight:400}
/* terminal */
.xterm{
flex:1;
padding:12px 14px;
overflow:hidden;
font-family:'Roboto Mono',ui-monospace,Menlo,Consolas,monospace;
font-size:13px;line-height:1.5;
color:#cfd2d6;background:#1a1a1d;
}
.ps1{color:#81c995}
.path{color:#8ab4f8}
.git{color:#fdd663}
.cmd{color:#e8eaed}
.dim{color:#5f6368}
.err{color:#f28b82}
.ok{color:#81c995}
.cursor{
display:inline-block;width:8px;height:15px;background:#e8eaed;
vertical-align:-2px;margin-left:1px;animation:blink 1.1s steps(1) infinite;
}
@keyframes blink{50%{opacity:0}}
/* status bar (above toolbar on desktop) */
.status{
height:24px;flex-shrink:0;
background:#202124;border-top:1px solid #3c4043;
display:flex;align-items:center;justify-content:space-between;
padding:0 14px;color:#9aa0a6;
font-family:'Roboto Mono',ui-monospace,monospace;font-size:11px;
}
.status .left,.status .right{display:flex;gap:14px;align-items:center}
.status b{color:#e8eaed;font-weight:400}
.status .ok{color:#81c995}
/* desktop hides the mobile toolbar — show it anyway in this preview
so reviewers can see what mobile users get */
#mb{display:flex !important;position:relative !important;
box-shadow:0 -1px 0 #3c4043 !important;flex-shrink:0;}
/* Chrome wrapper sets its own background */
</style>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
<script type="text/babel" src="browser-window.jsx"></script>
<script type="text/babel">
const { useEffect } = React;
function SethmuxApp() {
return (
<div className="app">
<div className="top">
<div className="brand">sethmux</div>
<div className="tabs">
<div className="tab"><span className="num">1</span><span className="dot"/>code</div>
<div className="tab active"><span className="num">2</span><span className="dot"/>git</div>
<div className="tab alert"><span className="num">3</span><span className="dot"/>run</div>
<div className="tab"><span className="num">4</span><span className="dot"/>logs</div>
<div className="tab"><span className="num">5</span><span className="dot"/>notes</div>
</div>
<div className="spacer"/>
<div className="meta">tmux <b>sethmux</b> · 1 client · 168×42</div>
</div>
<div className="xterm">
<div><span className="ps1">seth@mux</span> <span className="path">~/sethmux</span> <span className="git">(main)</span> <span className="dim">$</span> <span className="cmd">git status</span></div>
<div>On branch <span className="ok">main</span></div>
<div>Your branch is up to date with <span className="path">'origin/main'</span>.</div>
<div>&nbsp;</div>
<div>Changes not staged for commit:</div>
<div className="dim"> (use "git add &lt;file&gt;..." to update what will be committed)</div>
<div>&nbsp;</div>
<div> <span className="err">modified:</span> static/toolbar.js</div>
<div> <span className="err">modified:</span> README.md</div>
<div>&nbsp;</div>
<div>Untracked files:</div>
<div> <span className="err">static/compose-bar.js</span></div>
<div>&nbsp;</div>
<div><span className="ps1">seth@mux</span> <span className="path">~/sethmux</span> <span className="git">(main)</span> <span className="dim">$</span> <span className="cmd">git diff --stat static/toolbar.js</span></div>
<div> static/toolbar.js | <span className="ok">+138</span> <span className="err">-21</span></div>
<div>&nbsp;</div>
<div><span className="ps1">seth@mux</span> <span className="path">~/sethmux</span> <span className="git">(main)</span> <span className="dim">$</span> <span className="cursor"/></div>
</div>
<div className="status">
<div className="left">
<span><b>code</b> · <b>git</b> · run · logs · notes</span>
<span>pane <b>0</b>/1</span>
</div>
<div className="right">
<span className="ok"> connected</span>
<span><b>14:02</b></span>
</div>
</div>
{/* mobile toolbar mounts at body level via toolbar.js */}
</div>
);
}
function App() {
useEffect(() => {
// Load the real toolbar after render so it can find a place to mount.
if (window._toolbar) return;
const s = document.createElement('script');
s.src = 'toolbar.js';
document.body.appendChild(s);
}, []);
const tabs = [
{ title: 'sethmux — git' },
{ title: 'GitHub · sethmux' },
{ title: 'PR #42 · review' },
];
return (
<div style={{display:'flex',alignItems:'center',justifyContent:'center'}}>
<ChromeWindow tabs={tabs} activeIndex={0} url="mux.seth.dev" width={1180} height={760}>
<SethmuxApp/>
</ChromeWindow>
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
</script>
</body>
</html>