feat(web): lamp-only header on the content width
Drops #master-verdict entirely - element, .rail-verdict rules and every line that wrote into it. The lamp is the only header signal; the unreachable detail moves onto the board's arr module so nothing is lost. Rail contents move into .rail-inner capped at the deck's 68rem and centred, leaving the panel full-bleed. Committed by the blitz orchestrator: the authoring session wedged with the work complete on disk and stopped accepting input.
This commit is contained in:
+32
-31
@@ -18,7 +18,7 @@
|
||||
fault red) with a soft glow, phosphor-cyan for the one interactive control.
|
||||
STORY: the operator opens the board, reads the master lamp, and knows in a
|
||||
second whether arr can do its job — and which upstream is down, by name.
|
||||
FIRST VIEWPORT: a top rail (wordmark + master lamp + verdict + version),
|
||||
FIRST VIEWPORT: a top rail (wordmark + master lamp + version),
|
||||
then the chain: TMDB and PROWLARR modules on the left feeding the central
|
||||
arr module, TRANSMISSION driven on the right, joined by bus hairlines with
|
||||
direction arrows. On a phone the chain stacks vertically.
|
||||
@@ -65,36 +65,37 @@
|
||||
interaction hue.
|
||||
-->
|
||||
<header class="rail">
|
||||
<div class="rail-id">
|
||||
<span class="lamp" id="master-lamp" data-state="probing" aria-hidden="true"></span>
|
||||
<h1 class="wordmark">arr</h1>
|
||||
</div>
|
||||
<nav class="rail-nav" aria-label="views">
|
||||
<button type="button" class="control" id="nav-library" aria-pressed="false">
|
||||
library
|
||||
</button>
|
||||
<button type="button" class="control" id="nav-queues" aria-pressed="false">
|
||||
queues<span class="nav-count readout" id="queues-count" hidden></span>
|
||||
</button>
|
||||
<button type="button" class="control" id="nav-settings" aria-pressed="false">
|
||||
settings
|
||||
</button>
|
||||
</nav>
|
||||
<div class="rail-search">
|
||||
<input
|
||||
id="search"
|
||||
class="search-input readout"
|
||||
type="text"
|
||||
spellcheck="false"
|
||||
autocomplete="off"
|
||||
placeholder="search · title / tmdb id / tt… / magnet"
|
||||
aria-label="unified search — titles, TMDB or IMDb ids, magnets and .torrent links"
|
||||
/>
|
||||
<span class="search-hint readout" id="search-hint" aria-hidden="true">/</span>
|
||||
</div>
|
||||
<p class="rail-verdict readout" id="master-verdict" role="status">probing chain…</p>
|
||||
<div class="rail-meta">
|
||||
<span class="readout dim" id="version" data-testid="version">v —</span>
|
||||
<div class="rail-inner">
|
||||
<div class="rail-id">
|
||||
<span class="lamp" id="master-lamp" data-state="probing" aria-hidden="true"></span>
|
||||
<h1 class="wordmark">arr</h1>
|
||||
</div>
|
||||
<nav class="rail-nav" aria-label="views">
|
||||
<button type="button" class="control" id="nav-library" aria-pressed="false">
|
||||
library
|
||||
</button>
|
||||
<button type="button" class="control" id="nav-queues" aria-pressed="false">
|
||||
queues<span class="nav-count readout" id="queues-count" hidden></span>
|
||||
</button>
|
||||
<button type="button" class="control" id="nav-settings" aria-pressed="false">
|
||||
settings
|
||||
</button>
|
||||
</nav>
|
||||
<div class="rail-search">
|
||||
<input
|
||||
id="search"
|
||||
class="search-input readout"
|
||||
type="text"
|
||||
spellcheck="false"
|
||||
autocomplete="off"
|
||||
placeholder="search · title / tmdb id / tt… / magnet"
|
||||
aria-label="unified search — titles, TMDB or IMDb ids, magnets and .torrent links"
|
||||
/>
|
||||
<span class="search-hint readout" id="search-hint" aria-hidden="true">/</span>
|
||||
</div>
|
||||
<div class="rail-meta">
|
||||
<span class="readout dim" id="version" data-testid="version">v —</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
+2
-6
@@ -148,7 +148,6 @@ function must<T extends Element>(selector: string): T {
|
||||
function main() {
|
||||
const board = must<HTMLElement>(".board");
|
||||
const masterLamp = must<HTMLElement>("#master-lamp");
|
||||
const verdict = must<HTMLElement>("#master-verdict");
|
||||
const version = must<HTMLElement>("#version");
|
||||
|
||||
const master = moduleRefs("master");
|
||||
@@ -193,10 +192,9 @@ function main() {
|
||||
|
||||
if (probe.kind === "unreachable") {
|
||||
masterLamp.dataset.state = "unreachable";
|
||||
verdict.dataset.tone = "fault";
|
||||
verdict.textContent = `daemon unreachable — ${probe.detail}`;
|
||||
version.textContent = "v —";
|
||||
setModule(master, "unreachable", "fault", "down");
|
||||
// the outage detail lives on the board's arr module — the header has no verdict line
|
||||
setModule(master, "unreachable", "fault", "down", probe.detail);
|
||||
for (const refs of Object.values(checks)) {
|
||||
setModule(refs, "off", "idle", "no signal");
|
||||
}
|
||||
@@ -210,8 +208,6 @@ function main() {
|
||||
const degraded = report.status === "degraded";
|
||||
|
||||
masterLamp.dataset.state = degraded ? "degraded" : "ok";
|
||||
verdict.dataset.tone = degraded ? "warn" : "ok";
|
||||
verdict.textContent = degraded ? "chain degraded" : "all signals nominal";
|
||||
version.textContent = `v${report.version}`;
|
||||
|
||||
setModule(master, degraded ? "degraded" : "ok", degraded ? "warn" : "ok", report.status);
|
||||
|
||||
+11
-27
@@ -136,15 +136,22 @@ body {
|
||||
/* ---- rails ---------------------------------------------------------- */
|
||||
|
||||
.rail {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-6);
|
||||
padding: var(--space-3) var(--space-6);
|
||||
border-bottom: 1px solid var(--line);
|
||||
background: var(--panel);
|
||||
box-shadow: inset 0 1px var(--highlight);
|
||||
}
|
||||
|
||||
/* contents share the deck's column; the panel itself stays full-bleed */
|
||||
.rail-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-6);
|
||||
width: 100%;
|
||||
max-width: 68rem;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.rail-id {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -160,24 +167,6 @@ body {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.rail-verdict {
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
|
||||
.rail-verdict[data-tone="ok"] {
|
||||
color: var(--signal-ok);
|
||||
}
|
||||
|
||||
.rail-verdict[data-tone="warn"] {
|
||||
color: var(--signal-warn);
|
||||
}
|
||||
|
||||
.rail-verdict[data-tone="fault"] {
|
||||
color: var(--signal-fault);
|
||||
}
|
||||
|
||||
.rail-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1770,7 +1759,7 @@ body {
|
||||
/* ---- small screens --------------------------------------------------- */
|
||||
|
||||
@media (max-width: 46rem) {
|
||||
.rail {
|
||||
.rail-inner {
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-3) var(--space-4);
|
||||
}
|
||||
@@ -1788,11 +1777,6 @@ body {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rail-verdict {
|
||||
flex-basis: 100%;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.rail-search {
|
||||
order: 4;
|
||||
flex-basis: 100%;
|
||||
|
||||
Reference in New Issue
Block a user