The look from the server's tokens, pinned; the frame and bar follow the page's theme

ui/tokens.css is no longer a hand copy that drifts: scripts/fetch-tokens.sh
takes the server's tokens.css at a git ref and tokens.lock.json pins it, as
fetch-cli.sh does for the CLI. build.rs reads the two themes' --bg and --border
out of it, so no colour is written in Rust. The content view reports the page's
theme by a navigation the app refuses (llembas-theme:<name>), and the window,
the title bar and the first-run page are painted in it and remember it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
HomerandClaude Fable 5.1 committed 2026-10-18 03:38:31 +02:00
1 parent 5028dd7ca1
commit 881a222f5f
12 files changed
+994 -59

No files matched your search

+14 -8
View File
@@ -1,7 +1,13 @@
/* 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. */
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);
@@ -16,10 +22,10 @@ html, body {
.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) 1px repeat(3, 2.875rem);
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: 1px solid var(--border);
border-bottom: var(--border-w) solid var(--border);
font: 600 var(--text-sm) / 1 var(--font-ui);
}
@@ -49,17 +55,17 @@ button {
cursor: pointer;
}
button:hover { color: var(--ink); background: var(--surface-hover); }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
button:focus-visible { outline: var(--outline-w) solid var(--accent); outline-offset: calc(-1 * var(--outline-w)); }
.bar__agent {
display: grid;
grid-template-columns: 0.5rem auto;
grid-template-columns: var(--sp-2) auto;
gap: var(--sp-2);
align-items: center;
padding: 0 var(--sp-3);
font-weight: 400;
}
.dot { width: 0.5rem; height: 0.5rem; background: var(--ink-muted); }
.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); }
@@ -76,11 +82,11 @@ button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* 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: 1px; height: 1.25rem; background: var(--border); }
.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: #fff; background: var(--danger); }
.bar__btn--close:hover { color: var(--ink-inverse); background: var(--danger); }
#maximize .i-restore { display: none; }
#maximize[data-maximized] .i-max { display: none; }