Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c08f47a035 | ||
|
|
234822e810 | ||
|
|
a58816d17e | ||
|
|
c8ed190ccc |
5 changed files with 132 additions and 27 deletions
|
|
@ -21,3 +21,51 @@ body.core-shell {
|
|||
/* createTabStrip toggles the native `hidden` attribute on inactive
|
||||
panes; ensure it wins over any inherited display. */
|
||||
.core-pane[hidden] { display: none; }
|
||||
|
||||
/* ─── K3PT ST4T3 + 1NFR4 container cards ────────────────────────────
|
||||
core.html doesn't load dashboard.css (that's the operator SPA),
|
||||
so the .container-row card styles aren't inherited. Redefine them
|
||||
here so tombstone and infra entries look like proper cards (similar
|
||||
to agent cards on the main dashboard) rather than bare list items. */
|
||||
.containers {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0.5em 0 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
}
|
||||
.container-row {
|
||||
background: var(--bg-elev);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
padding: 0.55em 0.8em 0.5em;
|
||||
}
|
||||
.container-row.tombstone {
|
||||
border-style: dashed;
|
||||
background: color-mix(in srgb, var(--bg-elev) 35%, transparent);
|
||||
opacity: 0.85;
|
||||
}
|
||||
.container-row .head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5em;
|
||||
margin-bottom: 0.4em;
|
||||
}
|
||||
.container-row .head .name {
|
||||
font-size: 1.05em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.container-row.tombstone .head .name { color: var(--muted); }
|
||||
.container-row .head .meta {
|
||||
margin-left: auto;
|
||||
font-size: 0.88em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.container-row .actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4em;
|
||||
}
|
||||
.container-row .actions form.inline { display: inline-block; margin: 0; }
|
||||
|
|
|
|||
|
|
@ -582,6 +582,20 @@ body.dashboard-shell {
|
|||
background: color-mix(in srgb, var(--purple) 8%, transparent);
|
||||
text-shadow: 0 0 4px currentColor;
|
||||
}
|
||||
/* History items: lighter card treatment so they're visually coherent with
|
||||
the pending .approval-card items above them. Left accent colour reflects
|
||||
the outcome via :has() on the per-status glyph span. */
|
||||
.approvals-history li {
|
||||
background: color-mix(in srgb, var(--bg-elev) 40%, transparent);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--subtext0);
|
||||
border-radius: 3px;
|
||||
padding: 0.35em 0.8em;
|
||||
margin-bottom: 0.4em;
|
||||
}
|
||||
.approvals-history li:has(.glyph-approved) { border-left-color: var(--green); }
|
||||
.approvals-history li:has(.glyph-denied) { border-left-color: var(--red); }
|
||||
.approvals-history li:has(.glyph-failed) { border-left-color: var(--amber); }
|
||||
.approvals-history .status { font-size: 0.85em; padding: 0 0.5em; }
|
||||
.status-approved { color: var(--green); }
|
||||
.status-denied { color: var(--red); }
|
||||
|
|
@ -1023,34 +1037,41 @@ footer .banner-thin {
|
|||
white-space: nowrap;
|
||||
}
|
||||
.schedules-table-id { width: 3em; text-align: center; }
|
||||
.schedules-table-next-col { width: 8em; white-space: nowrap; }
|
||||
.schedules-table-every-col { width: 7em; white-space: nowrap; }
|
||||
/* next / every columns: sized to typical content (short durations).
|
||||
Previous 8em / 7em wasted horizontal space. */
|
||||
.schedules-table-next-col { width: 5.5em; white-space: nowrap; }
|
||||
.schedules-table-every-col { width: 5em; white-space: nowrap; }
|
||||
.schedules-table-body-th { min-width: 12em; }
|
||||
.schedules-table-actions-th { width: 7em; }
|
||||
/* Agent-name columns: 90° vertical text (writing-mode) so names are fully
|
||||
readable without truncation. Previously used a -45° CSS transform which
|
||||
clipped names mid-glyph. writing-mode + rotate(180deg) is in-flow and
|
||||
needs no absolute positioning or overflow hacks. */
|
||||
.schedules-table-agent-th {
|
||||
width: 28px;
|
||||
min-width: 28px;
|
||||
height: 95px;
|
||||
padding: 0 !important;
|
||||
height: 8em;
|
||||
padding: 4px 2px !important;
|
||||
vertical-align: bottom;
|
||||
white-space: nowrap;
|
||||
text-transform: none !important;
|
||||
letter-spacing: 0 !important;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.schedules-table-agent-th > div {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
left: 14px;
|
||||
transform-origin: left bottom;
|
||||
transform: rotate(-45deg);
|
||||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||||
font-size: 0.9em;
|
||||
font-size: 0.85em;
|
||||
color: var(--fg);
|
||||
/* Rotate 90° bottom-to-top (conventional rotated column header). */
|
||||
writing-mode: vertical-rl;
|
||||
transform: rotate(180deg);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-height: 7.5em;
|
||||
}
|
||||
.schedules-table-agent-th > div > span {
|
||||
display: inline-block;
|
||||
padding: 0 4px 1px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
/* Column for an agent no longer in the live roster — its past schedules
|
||||
linger but the agent is gone. Greyed + struck through so the operator
|
||||
|
|
|
|||
|
|
@ -5,6 +5,14 @@
|
|||
body.logs-shell {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
/* Full-viewport flex column so the log pane can scroll internally
|
||||
instead of the whole page scrolling. The sticky-top wrapper and
|
||||
page-header shrink to their natural height; .logs-main takes the
|
||||
rest and each visible .logs-pane fills it. */
|
||||
height: 100dvh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Base tab styling now lives in @hive/shared/tabs.css (.hive-tab*). The
|
||||
|
|
@ -18,10 +26,28 @@ body.logs-shell {
|
|||
}
|
||||
|
||||
.logs-main {
|
||||
padding: 1.2em 1.5em 2em;
|
||||
padding: 1.2em 1.5em 0;
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.logs-pane[hidden] { display: none; }
|
||||
.logs-pane {
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 1.2em;
|
||||
}
|
||||
/* The AUDIT tab uses a <div> for its list instead of a <pre>, so give
|
||||
it the same flex-grow + internal scroll that .journal-output already has. */
|
||||
#audit-list {
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.logs-toolbar {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -16,14 +16,27 @@ body.stats-shell {
|
|||
padding: 1.2em 1.5em 2em;
|
||||
}
|
||||
|
||||
/* Window selector. Buttons keep the shared `.btn` pill look; the active
|
||||
one is flagged by createTabStrip via `.hive-tab--active` (was a bespoke
|
||||
`.active` toggle). */
|
||||
/* Window selector — now lives in the page-header (same row as ← home /
|
||||
ST4TS title). Fills the remaining header space and right-aligns the
|
||||
buttons. The shared `.btn` pill look is kept; createTabStrip flags the
|
||||
active one with `.hive-tab--active`. */
|
||||
.hive-stats-windows {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin: 12px 0;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
justify-content: flex-end;
|
||||
/* Smaller than the default .btn so the pills fit comfortably in the
|
||||
header without competing visually with the page title. */
|
||||
font-size: 0.82em;
|
||||
}
|
||||
/* Inactive buttons: slightly muted to distinguish from the active window,
|
||||
but readable even on low-contrast operator colour schemes. */
|
||||
.hive-stats-windows .btn {
|
||||
color: var(--subtext1, var(--muted));
|
||||
border-color: var(--border);
|
||||
font-size: 1em; /* relative to the .hive-stats-windows 0.82em */
|
||||
}
|
||||
.hive-stats-windows .btn.hive-tab--active {
|
||||
border-color: var(--amber);
|
||||
|
|
|
|||
|
|
@ -18,15 +18,8 @@
|
|||
<header class="page-header">
|
||||
<a class="page-back" href="/">← home</a>
|
||||
<span class="page-title">ST4TS</span>
|
||||
</header>
|
||||
|
||||
<main class="stats-main">
|
||||
<p class="meta">hive-wide turn statistics, aggregated across every agent over the selected window. <strong>cost is a rough estimate</strong> from approximate per-model list prices — it drifts and is a ballpark, not a bill.</p>
|
||||
|
||||
<!-- Window selector — a hash-routed createTabStrip (#1h / #24h / …),
|
||||
like the per-agent /stats page. Buttons keep the `.btn` pill
|
||||
look; createTabStrip toggles `.hive-tab--active` and the page
|
||||
re-fetches on change via onShow. -->
|
||||
<!-- Window selector lives in the header so it behaves like a tab strip
|
||||
(matches the pattern on /logs.html). Hash-routed via createTabStrip. -->
|
||||
<nav class="hive-stats-windows" id="hive-stats-windows" role="tablist">
|
||||
<button type="button" class="btn" data-tab="1h">1h</button>
|
||||
<button type="button" class="btn" data-tab="4h">4h</button>
|
||||
|
|
@ -36,6 +29,10 @@
|
|||
<button type="button" class="btn" data-tab="30d">30d</button>
|
||||
<button type="button" class="btn" data-tab="all">all</button>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="stats-main">
|
||||
<p class="meta">hive-wide turn statistics, aggregated across every agent over the selected window. <strong>cost is a rough estimate</strong> from approximate per-model list prices — it drifts and is a ballpark, not a bill.</p>
|
||||
|
||||
<div class="hive-stats-chips" id="hive-stats-summary"></div>
|
||||
<h3>◇ busiest agents</h3>
|
||||
|
|
|
|||
Loading…
Reference in a new issue