/* The title bar: one row, fixed height, every slot a fixed or shared track so nothing in it moves when the host name or the agent's state changes length. Colours, type and space are tokens from tokens.css (the server's); the bar's height is this page's own. */ * { box-sizing: border-box; } :root { /* `TITLE_H` in src-tauri/src/lib.rs is this number: the app lays the bar out at it. */ --titlebar-h: 36px; } html, body { margin: 0; height: var(--titlebar-h); overflow: hidden; background: var(--bg); color: var(--ink); user-select: none; -webkit-user-select: none; cursor: default; } .bar { display: grid; /* leaf · name · host (takes the rest, and is the drag area) · update · agent · menu · sep · 3 controls */ grid-template-columns: var(--titlebar-h) auto minmax(0, 1fr) auto auto var(--titlebar-h) var(--border-w) repeat(3, 2.875rem); align-items: center; height: var(--titlebar-h); border-bottom: var(--border-w) solid var(--border); font: 600 var(--text-sm) / 1 var(--font-ui); } .bar__leaf { justify-self: center; width: 18px; height: 18px; image-rendering: pixelated; } .bar__name b { color: var(--leaf); font-weight: 700; } .bar__host { padding: 0 var(--sp-3); color: var(--ink-muted); font-weight: 400; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; align-self: stretch; display: flex; align-items: center; } button { height: var(--titlebar-h); margin: 0; padding: 0; font: inherit; color: var(--ink-muted); background: transparent; border: 0; border-radius: 0; cursor: pointer; } button:hover { color: var(--ink); background: var(--surface-hover); } button:focus-visible { outline: var(--outline-w) solid var(--accent); outline-offset: calc(-1 * var(--outline-w)); } .bar__agent { display: grid; grid-template-columns: var(--sp-2) auto; gap: var(--sp-2); align-items: center; padding: 0 var(--sp-3); font-weight: 400; } .dot { width: var(--sp-2); height: var(--sp-2); background: var(--ink-muted); } .bar__agent[data-state="running"] .dot, .bar__agent[data-state="elsewhere"] .dot { background: var(--leaf); } .bar__agent[data-state="starting"] .dot { background: var(--accent); } .bar__agent[data-state="failed"] .dot, .bar__agent[data-state="not_linked"] .dot, .bar__agent[data-state="no_folders"] .dot { background: var(--warning); } .bar__update { padding: 0 var(--sp-3); color: var(--accent-ink); background: var(--accent); } .bar__update:hover { color: var(--accent-ink); background: var(--accent-hover); } /* Hidden keeps its grid track (auto, so zero wide): the slots after it never move. */ .bar__update[hidden] { display: block; width: 0; padding: 0; overflow: hidden; } .bar__sep { width: var(--border-w); height: var(--sp-5); background: var(--border); } .bar__btn { display: grid; place-items: center; } .bar__btn svg { width: 16px; height: 16px; } .bar__btn--close:hover { color: var(--ink-inverse); background: var(--danger); } #maximize .i-restore { display: none; } #maximize[data-maximized] .i-max { display: none; } #maximize[data-maximized] .i-restore { display: block; } /* Narrow windows: the host goes first, then the agent's words (its dot stays). */ @media (max-width: 34rem) { .bar__host { visibility: hidden; } #agent-text { display: none; } }