web: the header wears the theme, and the rail says which build it is

Two things the studio could not say about itself.

The preset the header has open was painted in the dim text colour, the same grey
as the page name beside it — so the one label up there that changes with the look
read as chrome. It now takes the theme's own accent, the colour the brand mark
and the open tab already carry, which means it follows both the light/dark mode
and the accent group the reader picked, out of the CSS token and with no colour
written into the component.

And an image has no other mark on it: once the frontend tarball is loaded on the
NAS as `:latest`, nothing on the box says which revision came off. The rail now
names the build at its foot — quiet, mono, wrapping rather than widening the
column, and gone under 860px where the rail is the phone's scrolling tab bar
instead of a column.

The name is stamped into the bundle at build time: vite.config reads VERSION
from the environment (`docker compose build frontend --build-arg
VERSION=$(git rev-parse --short HEAD)`) and falls back to the package version
plus the minute it was built, so two builds of the same tree are never the same
name. `ARG VERSION=` in the Dockerfile is the knob; the bare `npm run build` —
dev server, check scripts — still stamps its own time, and the dev server passes
nothing at all, so the line only draws when there is something to say.

Verified:
  library-check.mjs — 37 steps, all passed, the two new ones reading the header
    off the running studio: the rail foot names the build (0.1.0+202609281504)
    and the preset chip's computed colour is the brand's accent, not a grey —
    rgb(206, 117, 9) amber, rgb(93, 24, 191) after switching to violet.
  scan-nav-check.mjs and roll-walk-check.mjs — all passed. frontend tsc --noEmit
    clean. Live 8090 on index-… matching dist/: /, /library and /app 200 with 0
    console errors.

ponytail: the name is the package version plus a caller-supplied tag, and nothing
bumps the package version, so the tag is the whole identity — have the release
job write it into package.json if the numbers ever need to mean something.
This commit is contained in:
2026-09-28 22:05:55 +07:00
parent 77729ad99a
commit 36cd711302
5 changed files with 66 additions and 1 deletions
+19 -1
View File
@@ -20,10 +20,13 @@
carry, so every screen says where the visitor is. */
.page-name { font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-dim); }
.header .spacer { flex: 1 1 auto; }
/* The preset the studio has open. It wears the theme's own accent rather than
the dim text colour: it is the one label up there that changes with the
look, and the same colour the open tab and the brand already carry. */
.recipe-name {
font-family: var(--mono);
font-size: 12px;
color: var(--text-dim);
color: var(--accent);
border: 1px solid var(--border-soft);
border-radius: 999px;
padding: 3px 10px;
@@ -65,6 +68,18 @@
.rail button .glyph { font-size: 17px; line-height: 1; }
.rail button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }
.rail button:hover { color: var(--text); }
/* The build behind the page. It sits at the foot of the column, quiet enough to
read past, and wraps rather than widening the rail when a name is long. */
.rail-version {
margin-top: auto;
padding: 8px 2px 2px;
font-family: var(--mono);
font-size: 9px;
letter-spacing: 0.02em;
color: var(--text-dim);
text-align: center;
overflow-wrap: anywhere;
}
/* --- panel columns ------------------------------------------------------- */
/* The panel is a cascade: the rail holds the tabs, then one column per open
@@ -1259,6 +1274,9 @@ input[type="range"] { width: 100%; accent-color: var(--accent); }
scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
/* The column is a row here, and the row is the tabs: a build name at its foot
would sit past the end of a line that already scrolls. It goes. */
.rail-version { display: none; }
.rail button {
flex: 0 0 auto;
flex-direction: row;