The themed dialog component (modal.js: themedConfirm / themedPrompt / themedToast) is raised from common.js's data-async / data-confirm handler, which every page loads — but its .tc-* styles lived only in dashboard.css (the main tabbed dashboard's stylesheet). So on any standalone page (core/C0R3, settings, flow, logs) a dialog rendered completely unstyled: the build-queue rebuild-cancel confirm came up as raw text. Extract the .tc-* rules into a dedicated modal.css component (paired with modal.js) and @import it from common.css, so the styles load wherever a dialog can fire — not just the main dashboard. esbuild inlines the @import into the common.css bundle, so there's no extra request and the main dashboard is visually unchanged (it loads common.css too). The stale 'themedConfirm() in common.js' comment is gone with the move. Fixes #1910.
1301 lines
35 KiB
CSS
1301 lines
35 KiB
CSS
/* Dashboard-specific styles. common.css must be loaded first —
|
||
it defines the CSS custom properties, typography, and shared
|
||
component rules that this file depends on. */
|
||
|
||
/* SYST3M panel rules (rebuild queue / meta inputs / container load)
|
||
live in system-sections.css, shared with /core.html. A few are still
|
||
referenced from dashboard JS (the schedules view uses `.rqe-source*`),
|
||
so the dashboard pulls them in here. */
|
||
@import "./system-sections.css";
|
||
|
||
/* ─── tabbed dashboard chrome ──────────────────────────────────────
|
||
Top-of-page sticky header with banner + tab strip. SSE stays
|
||
alive across tab switches so count pills update live on inactive
|
||
tabs. See docs/web-ui.md::Chrome header + Tab strip for the
|
||
routing model. */
|
||
|
||
body.dashboard-shell {
|
||
/* Full-bleed body (no horizontal gutter). The 1.5em side gutter lives
|
||
on the inner `.page-content` wrapper (see common.css), so the sticky
|
||
chrome bar, the server-warnings banner, and the footer span the full
|
||
width edge-to-edge with no negative-margin breakout. `padding-bottom`
|
||
keeps a little breathing room above the viewport edge (overridden to
|
||
clear the selection bar via `.has-selection` below). No max-width cap
|
||
— wide screens use the full width rather than empty side margins. */
|
||
margin: 0;
|
||
padding-bottom: 1.5em;
|
||
}
|
||
|
||
.dashboard-chrome {
|
||
/* Home back-link + tab strip share one row (flex). The chrome owns the
|
||
horizontal gutter and the single full-width bottom divider; its
|
||
children drop their own side padding / border so they sit inline. */
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.75em;
|
||
/* Stickiness lives on the `.sticky-top` wrapper (common.css) that
|
||
common.js wraps this chrome in, alongside the server-warning banner,
|
||
so they stack in one sticky context instead of colliding. */
|
||
background: color-mix(in srgb, var(--bg) 86%, transparent);
|
||
-webkit-backdrop-filter: blur(8px) saturate(120%);
|
||
backdrop-filter: blur(8px) saturate(120%);
|
||
border-bottom: 1px solid var(--purple-dim);
|
||
padding: 0.3em 1em;
|
||
margin: 0 0 1em;
|
||
}
|
||
/* ← home back-link to the H0M3 hub. Small purple link top-left of the
|
||
chrome, mirroring the .page-back treatment the standalone pages use
|
||
(now shared from @hive/shared/chrome.css) so the navigation reads
|
||
consistently. The dashboard keeps this richer sticky chrome of its
|
||
own rather than folding into the simple page header. */
|
||
.dash-home-back {
|
||
flex: none;
|
||
color: var(--purple);
|
||
text-decoration: none;
|
||
font-size: 0.82em;
|
||
white-space: nowrap;
|
||
}
|
||
.dash-home-back:hover { text-decoration: underline; }
|
||
.banner-thin {
|
||
text-align: center;
|
||
margin: 0;
|
||
padding: 0 1em;
|
||
font-size: 0.78em;
|
||
color: var(--purple-dim);
|
||
letter-spacing: 0.15em;
|
||
white-space: pre;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.tabbar {
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
align-items: center;
|
||
gap: 0.2em;
|
||
/* On one row with the home link now; the chrome owns the gutter +
|
||
the bottom divider, so no outer padding / border here. */
|
||
}
|
||
/* Shares the flat-pill aesthetic of the shared `.hive-tab` (sub-tabs on
|
||
the standalone pages) so the chrome reads as one family. Kept a touch
|
||
weightier than bare `.hive-tab` — larger font, bold labels, count
|
||
pills — since this is the dashboard's primary nav, not a sub-strip. */
|
||
.tabbar .tab {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.5em;
|
||
flex-shrink: 0;
|
||
padding: 0.4em 0.95em;
|
||
color: var(--muted);
|
||
font-family: inherit;
|
||
font-size: 0.92em;
|
||
letter-spacing: 0.06em;
|
||
text-decoration: none;
|
||
border: 0;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
transition: color 0.15s ease, background 0.15s ease;
|
||
}
|
||
.tabbar .tab:hover {
|
||
color: var(--fg);
|
||
background: var(--border);
|
||
}
|
||
.tabbar .tab.hive-tab--active {
|
||
color: var(--purple);
|
||
background: var(--border);
|
||
}
|
||
.tab-label { font-weight: bold; white-space: nowrap; }
|
||
.tab-count {
|
||
display: inline-block;
|
||
background: var(--purple-dim);
|
||
color: var(--purple);
|
||
border-radius: 999px;
|
||
padding: 0 0.55em;
|
||
min-width: 1.6em;
|
||
text-align: center;
|
||
font-size: 0.82em;
|
||
font-variant-numeric: tabular-nums;
|
||
font-weight: bold;
|
||
}
|
||
.tab-count-attn {
|
||
/* Y3R C4LL — operator-action-required pill colour, harder to miss. */
|
||
background: color-mix(in srgb, var(--red) 22%, transparent);
|
||
color: var(--red);
|
||
}
|
||
|
||
|
||
/* Tab pane visibility — createTabStrip (@hive/shared/tabs.js) sets the
|
||
`hidden` attribute on every inactive pane (resolved from the URL hash;
|
||
default — no hash — is SW4RM). Only the active pane stays visible. */
|
||
.tab-pane[hidden] { display: none; }
|
||
|
||
/* FL0W is a separate page (`/flow.html`) — its full-viewport
|
||
styling lives in flow.css. */
|
||
.banner {
|
||
text-align: center;
|
||
margin: 0 0 1em 0;
|
||
font-size: 0.95em;
|
||
overflow-x: auto;
|
||
background: linear-gradient(
|
||
90deg,
|
||
var(--purple-dim) 0%,
|
||
var(--purple) 50%,
|
||
var(--purple-dim) 100%
|
||
);
|
||
background-size: 200% 100%;
|
||
background-position: 50% 0;
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
filter: drop-shadow(0 0 6px color-mix(in srgb, var(--purple) 45%, transparent));
|
||
}
|
||
.banner.active {
|
||
animation: banner-shimmer 1.8s linear infinite;
|
||
}
|
||
@keyframes banner-shimmer {
|
||
from { background-position: 200% 0; }
|
||
to { background-position: -100% 0; }
|
||
}
|
||
|
||
.role {
|
||
display: inline-block;
|
||
margin-left: 0.4em;
|
||
padding: 0.05em 0.5em;
|
||
border: 1px solid;
|
||
border-radius: 2px;
|
||
font-size: 0.8em;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
/* Container rows: a full-height square agent icon on the left, the
|
||
identity / actions / drill-in lines stacked in the card body on the
|
||
right. Pending rows dim everything except the pending indicator. */
|
||
.containers { display: flex; flex-direction: column; gap: 0.4em; }
|
||
.container-row {
|
||
padding: 0.6em 0.8em;
|
||
border: 1px solid var(--border);
|
||
border-radius: 4px;
|
||
background: color-mix(in srgb, var(--bg-elev) 55%, transparent);
|
||
transition: opacity 200ms ease, border-color 200ms ease;
|
||
}
|
||
/* Topology indent ladder. See docs/web-ui.md::Topology tree (Indent
|
||
+ lane geometry paragraph) for the 1.8em-per-depth-level
|
||
rationale + CSS-attr()-not-yet-portable caveat. */
|
||
.container-row[data-depth] { position: relative; }
|
||
.container-row[data-depth="1"] { margin-left: 1.8em; }
|
||
.container-row[data-depth="2"] { margin-left: 3.6em; }
|
||
.container-row[data-depth="3"] { margin-left: 5.4em; }
|
||
.container-row[data-depth="4"] { margin-left: 7.2em; }
|
||
.container-row[data-depth="5"] { margin-left: 9em; }
|
||
.container-row[data-depth="6"] { margin-left: 10.8em; }
|
||
/* Tree prefix lanes — DOM-painted, not text-glyph-painted. */
|
||
.container-row .tree-prefix {
|
||
position: absolute;
|
||
top: 0;
|
||
bottom: -0.4em;
|
||
display: flex;
|
||
flex-direction: row;
|
||
pointer-events: none;
|
||
user-select: none;
|
||
color: var(--purple-dim);
|
||
}
|
||
.container-row[data-depth="1"] .tree-prefix { left: -1.8em; }
|
||
.container-row[data-depth="2"] .tree-prefix { left: -3.6em; }
|
||
.container-row[data-depth="3"] .tree-prefix { left: -5.4em; }
|
||
.container-row[data-depth="4"] .tree-prefix { left: -7.2em; }
|
||
.container-row[data-depth="5"] .tree-prefix { left: -9em; }
|
||
.container-row[data-depth="6"] .tree-prefix { left: -10.8em; }
|
||
.tree-prefix .tree-lane {
|
||
flex: 0 0 1.8em;
|
||
position: relative;
|
||
}
|
||
.tree-prefix .lane-line::before,
|
||
.tree-prefix .lane-joint::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 0.6em;
|
||
top: 0;
|
||
bottom: 0;
|
||
border-left: 1px solid currentColor;
|
||
}
|
||
.tree-prefix .lane-joint-last::before {
|
||
bottom: auto;
|
||
height: 3.1em;
|
||
}
|
||
.tree-prefix .lane-joint::after {
|
||
content: '';
|
||
position: absolute;
|
||
left: 0.6em;
|
||
top: 3.1em;
|
||
width: 2em;
|
||
border-top: 1px solid currentColor;
|
||
}
|
||
.container-row:not(.tombstone) {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 0.7em;
|
||
}
|
||
.container-row:not(.tombstone) > .container-icon {
|
||
position: relative;
|
||
overflow: hidden;
|
||
flex: none;
|
||
width: 5em;
|
||
aspect-ratio: 1;
|
||
border-radius: 6px;
|
||
background-color: color-mix(in srgb, var(--crust) 60%, transparent);
|
||
cursor: pointer;
|
||
transition: box-shadow 120ms ease, transform 120ms ease;
|
||
}
|
||
.container-row:not(.tombstone) > .container-icon:hover {
|
||
box-shadow: 0 0 0 2px var(--purple);
|
||
}
|
||
.container-row:not(.tombstone) > .container-icon:focus-visible {
|
||
outline: 2px solid var(--purple);
|
||
outline-offset: 2px;
|
||
}
|
||
.container-row.selected {
|
||
border-color: var(--purple);
|
||
box-shadow: inset 0 0 0 1px var(--purple);
|
||
background: color-mix(in srgb, var(--purple) 6%, transparent);
|
||
}
|
||
.container-row.selected > .container-icon {
|
||
box-shadow: 0 0 0 2px var(--purple), 0 0 12px -4px var(--purple);
|
||
}
|
||
.container-row:not(.tombstone) > .container-icon > .container-icon-img {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: contain;
|
||
}
|
||
.container-row:not(.tombstone) > .container-icon.icon-unreachable {
|
||
filter: grayscale(1);
|
||
opacity: 0.4;
|
||
}
|
||
.container-row .card-body {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
/* ── per-agent three-dot context menu ─────────────────────────────────────
|
||
Positioned after .card-body in the flex row. */
|
||
.agent-menu {
|
||
flex: none;
|
||
position: relative;
|
||
align-self: flex-start;
|
||
margin-top: 0.3em;
|
||
}
|
||
.agent-menu-btn {
|
||
display: block;
|
||
background: none;
|
||
border: none;
|
||
color: var(--subtext0);
|
||
font-size: 1.1em;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
padding: 0.1em 0.4em;
|
||
border-radius: 4px;
|
||
opacity: 0;
|
||
transition: opacity 120ms, background 120ms, color 120ms;
|
||
}
|
||
.container-row:hover .agent-menu-btn,
|
||
.agent-menu.open .agent-menu-btn {
|
||
opacity: 1;
|
||
}
|
||
.agent-menu-btn:hover,
|
||
.agent-menu-btn:focus-visible {
|
||
background: color-mix(in srgb, var(--purple) 10%, transparent);
|
||
color: var(--purple);
|
||
outline: none;
|
||
}
|
||
.agent-menu-btn:focus-visible {
|
||
outline: 1px solid var(--purple);
|
||
}
|
||
.agent-menu-dropdown {
|
||
position: absolute;
|
||
right: 0;
|
||
top: calc(100% + 2px);
|
||
z-index: 50;
|
||
background: var(--bg-elev);
|
||
border: 1px solid var(--purple-dim);
|
||
border-radius: 6px;
|
||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 0.3em 0;
|
||
min-width: 10em;
|
||
white-space: nowrap;
|
||
}
|
||
.agent-menu-item {
|
||
display: block;
|
||
width: 100%;
|
||
background: none;
|
||
border: none;
|
||
color: var(--fg);
|
||
font-family: inherit;
|
||
font-size: 0.88em;
|
||
letter-spacing: 0.04em;
|
||
text-align: left;
|
||
padding: 0.4em 0.9em;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
box-sizing: border-box;
|
||
}
|
||
.agent-menu-item:hover {
|
||
background: var(--border);
|
||
color: var(--purple);
|
||
}
|
||
.agent-menu-sep {
|
||
height: 1px;
|
||
background: var(--purple-dim);
|
||
margin: 0.3em 0;
|
||
padding: 0;
|
||
}
|
||
/* Pending state splits queued vs running. */
|
||
.container-row.pending .actions { opacity: 0.4; pointer-events: none; }
|
||
.container-row.pending-running {
|
||
border-color: var(--amber);
|
||
background: color-mix(in srgb, var(--amber) 5%, transparent);
|
||
}
|
||
@keyframes container-icon-spin {
|
||
from { transform: rotate(0deg); }
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
.container-row.pending-running > .container-icon {
|
||
overflow: visible;
|
||
}
|
||
.container-row.pending-running > .container-icon::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: -5px;
|
||
border-radius: 50%;
|
||
border: 3px solid transparent;
|
||
border-top-color: var(--amber);
|
||
animation: container-icon-spin 0.9s linear infinite;
|
||
pointer-events: none;
|
||
}
|
||
.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 .head .meta { margin-left: auto; }
|
||
.container-row .head .nav-strip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
gap: 0.35em;
|
||
}
|
||
.nav-link {
|
||
color: var(--muted);
|
||
font-size: 0.95em;
|
||
line-height: 1;
|
||
padding: 0.15em 0.35em;
|
||
border-radius: 3px;
|
||
text-decoration: none;
|
||
transition: background 0.12s ease, color 0.12s ease;
|
||
}
|
||
.nav-link:hover {
|
||
background: color-mix(in srgb, var(--purple) 12%, transparent);
|
||
color: var(--cyan);
|
||
text-shadow: 0 0 6px color-mix(in srgb, var(--cyan) 50%, transparent);
|
||
}
|
||
.container-row .actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.4em;
|
||
}
|
||
.container-row .actions form.inline { display: inline-block; margin: 0; }
|
||
|
||
.agent-status {
|
||
font-size: 0.82em;
|
||
color: var(--subtext0);
|
||
padding: 0.1em 0.3em 0.25em;
|
||
/* Row layout: the message can wrap to two lines and clamp; the age
|
||
stamp is a non-shrinking sibling so it is always shown (it wraps to
|
||
the next line if there is no room, but is never clipped away). */
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: baseline;
|
||
column-gap: 0.3em;
|
||
}
|
||
.agent-status .status-msg {
|
||
flex: 0 1 auto;
|
||
min-width: 0;
|
||
/* Wrap to at most two lines, then ellipsize the overflow. */
|
||
display: -webkit-box;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 2;
|
||
line-clamp: 2;
|
||
overflow: hidden;
|
||
overflow-wrap: anywhere;
|
||
}
|
||
.agent-status .status-icon { opacity: 0.65; }
|
||
.agent-status .status-age {
|
||
flex: 0 0 auto;
|
||
opacity: 0.5;
|
||
font-size: 0.9em;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.container-row.tombstone {
|
||
border-style: dashed;
|
||
background: color-mix(in srgb, var(--bg-elev) 35%, transparent);
|
||
opacity: 0.85;
|
||
}
|
||
.container-row.tombstone .name { color: var(--muted); }
|
||
|
||
/* Notification controls — sit between the banner and the containers. */
|
||
.port-conflict {
|
||
background: color-mix(in srgb, var(--red) 8%, transparent);
|
||
border: 1px solid var(--red);
|
||
color: var(--red);
|
||
padding: 0.5em 0.8em;
|
||
margin-bottom: 0.6em;
|
||
border-radius: 4px;
|
||
text-shadow: 0 0 6px color-mix(in srgb, var(--red) 40%, transparent);
|
||
animation: questions-pulse 2.4s ease-in-out infinite;
|
||
}
|
||
.port-conflict strong { color: var(--red); }
|
||
|
||
/* Build-queue summary banner on the SW4RM tab: one compact line
|
||
when the rebuild queue has active work, with a link to the full queue on
|
||
the C0R3 page. Amber to match the in-progress / "rebuilding" card tint. */
|
||
.queue-summary {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.4em;
|
||
flex-wrap: wrap;
|
||
background: color-mix(in srgb, var(--amber) 8%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--amber) 55%, transparent);
|
||
color: var(--amber);
|
||
padding: 0.45em 0.8em;
|
||
margin-bottom: 0.6em;
|
||
border-radius: 4px;
|
||
}
|
||
.queue-summary strong { color: var(--amber); }
|
||
.queue-summary-link {
|
||
margin-left: auto;
|
||
color: var(--amber);
|
||
text-decoration: none;
|
||
font-weight: bold;
|
||
white-space: nowrap;
|
||
}
|
||
.queue-summary-link:hover { text-decoration: underline; }
|
||
|
||
/* .notif-row / .btn-notif moved to settings.css with the S3TT1NGS
|
||
page. */
|
||
|
||
.pending-state {
|
||
color: var(--amber);
|
||
font-size: 0.85em;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
text-shadow: 0 0 6px color-mix(in srgb, var(--amber) 55%, transparent);
|
||
animation: badge-pulse 1.6s ease-in-out infinite;
|
||
}
|
||
@keyframes badge-pulse {
|
||
0%, 100% { opacity: 1; }
|
||
50% { opacity: 0.7; }
|
||
}
|
||
@keyframes questions-pulse {
|
||
0%, 100% { box-shadow: 0 0 12px -4px color-mix(in srgb, var(--amber) 55%, transparent); }
|
||
50% { box-shadow: 0 0 22px -2px color-mix(in srgb, var(--amber) 95%, transparent); }
|
||
}
|
||
|
||
/* Pending approval: a card with three stacked sections — identity
|
||
header, what-changed body, decision actions. */
|
||
.approvals { list-style: none; padding: 0; margin: 0.4em 0 0; }
|
||
.approval-card {
|
||
background: var(--bg-elev);
|
||
border: 1px solid var(--border);
|
||
border-left: 3px solid var(--purple);
|
||
border-radius: 4px;
|
||
padding: 0.6em 0.8em;
|
||
margin-bottom: 0.6em;
|
||
}
|
||
.approval-head {
|
||
display: flex;
|
||
align-items: baseline;
|
||
flex-wrap: wrap;
|
||
gap: 0.3em;
|
||
}
|
||
.approval-ts {
|
||
margin-left: auto;
|
||
color: var(--muted);
|
||
font-size: 0.85em;
|
||
}
|
||
.approval-ts.stale {
|
||
color: var(--amber);
|
||
text-shadow: 0 0 6px color-mix(in srgb, var(--amber) 50%, transparent);
|
||
}
|
||
.approval-body {
|
||
margin: 0.45em 0;
|
||
padding-left: 1.3em;
|
||
}
|
||
.approval-description {
|
||
font-size: 0.9em;
|
||
color: var(--fg);
|
||
white-space: pre-wrap;
|
||
margin-bottom: 0.35em;
|
||
}
|
||
.approval-actions {
|
||
display: flex;
|
||
gap: 0.5em;
|
||
padding-top: 0.45em;
|
||
border-top: 1px solid var(--border);
|
||
}
|
||
.approval-actions form.inline { display: inline; }
|
||
/* Inline drill-in triggers (logs / config repo / view diff). */
|
||
.drill-ins {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.15em 1.1em;
|
||
margin-top: 0.4em;
|
||
}
|
||
.drill-ins .panel-trigger { margin-top: 0; }
|
||
|
||
.approval-tabs {
|
||
display: flex;
|
||
gap: 0.4em;
|
||
margin: 0.6em 0 0.4em;
|
||
}
|
||
.approval-tab {
|
||
background: transparent;
|
||
border: 1px solid var(--border);
|
||
color: var(--muted);
|
||
font: inherit;
|
||
font-size: 0.85em;
|
||
letter-spacing: 0.08em;
|
||
padding: 0.25em 0.9em;
|
||
cursor: pointer;
|
||
transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
|
||
}
|
||
.approval-tab:hover { color: var(--fg); }
|
||
.approval-tab.active {
|
||
color: var(--purple);
|
||
border-color: var(--purple);
|
||
background: color-mix(in srgb, var(--purple) 8%, transparent);
|
||
text-shadow: 0 0 4px currentColor;
|
||
}
|
||
.approvals-history .status { font-size: 0.85em; padding: 0 0.5em; }
|
||
.status-approved { color: var(--green); }
|
||
.status-denied { color: var(--red); }
|
||
.status-failed { color: var(--amber); }
|
||
.status-cancelled { color: var(--muted); }
|
||
.glyph-approved { color: var(--green); }
|
||
.glyph-denied { color: var(--red); }
|
||
.glyph-failed { color: var(--amber); }
|
||
.glyph-cancelled { color: var(--muted); }
|
||
|
||
.history-note {
|
||
margin-left: 1.8em;
|
||
margin-top: 0.2em;
|
||
color: var(--muted);
|
||
font-size: 0.85em;
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
}
|
||
ul form.inline { display: inline-block; }
|
||
|
||
.spawnform { display: flex; gap: 0.6em; align-items: stretch; margin: 0.5em 0; }
|
||
.spawnform input {
|
||
font-family: inherit;
|
||
font-size: 1em;
|
||
background: var(--bg-elev);
|
||
color: var(--fg);
|
||
border: 1px solid var(--border);
|
||
padding: 0.4em 0.6em;
|
||
flex: 1;
|
||
}
|
||
.spawnform input::placeholder { color: var(--muted); }
|
||
.spawnform input:focus { outline: 1px solid var(--purple); }
|
||
.role-pending { color: var(--amber); border-color: var(--amber); }
|
||
.btn-inline {
|
||
font-family: inherit;
|
||
background: transparent;
|
||
cursor: pointer;
|
||
margin-left: 0.4em;
|
||
}
|
||
/* Off-palette warm-amber hover tint: not an exact theme var (brighter than
|
||
--amber), left as a literal pending a dedicated named var. */
|
||
.btn-inline:hover { background: rgba(255, 184, 77, 0.1); }
|
||
.kind {
|
||
display: inline-block;
|
||
margin-left: 0.4em;
|
||
padding: 0.05em 0.5em;
|
||
border: 1px solid var(--purple-dim);
|
||
color: var(--purple-dim);
|
||
border-radius: 2px;
|
||
font-size: 0.75em;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
}
|
||
.kind-spawn { color: var(--amber); border-color: var(--amber); }
|
||
.spinner {
|
||
display: inline-block;
|
||
animation: spin 1s linear infinite;
|
||
color: var(--amber);
|
||
}
|
||
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
||
details { margin-top: 0.5em; }
|
||
summary {
|
||
cursor: pointer;
|
||
color: var(--muted);
|
||
font-size: 0.85em;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.1em;
|
||
}
|
||
summary:hover { color: var(--purple); }
|
||
.diff {
|
||
background: var(--bg-elev);
|
||
border: 1px solid var(--border);
|
||
padding: 0.8em;
|
||
margin-top: 0.4em;
|
||
overflow-x: auto;
|
||
font-size: 0.85em;
|
||
line-height: 1.4;
|
||
color: var(--muted);
|
||
white-space: pre;
|
||
}
|
||
.diff span { display: block; }
|
||
.diff .diff-add { color: var(--green); }
|
||
.diff .diff-del { color: var(--red); }
|
||
.diff .diff-hunk { color: var(--cyan); }
|
||
.diff .diff-file { color: var(--purple); font-weight: bold; }
|
||
.diff .diff-ctx { color: var(--fg); }
|
||
.questions {
|
||
background: var(--bg-elev);
|
||
border: 1px solid var(--amber);
|
||
box-shadow: 0 0 12px -4px var(--amber);
|
||
padding: 0.6em 0.9em;
|
||
animation: questions-pulse 2.4s ease-in-out infinite;
|
||
}
|
||
.reminders {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
.reminder-row {
|
||
padding: 0.4em 0;
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
.reminder-row:last-child { border-bottom: 0; }
|
||
.reminder-head { font-size: 0.9em; }
|
||
.reminder-body {
|
||
color: var(--fg);
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
margin: 0.3em 0;
|
||
}
|
||
.reminder-row.reminder-failed {
|
||
border-left: 2px solid var(--red);
|
||
padding-left: 0.5em;
|
||
}
|
||
.reminder-error {
|
||
color: var(--red);
|
||
background: color-mix(in srgb, var(--red) 6%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--red) 25%, transparent);
|
||
padding: 0.3em 0.5em;
|
||
font-size: 0.85em;
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
margin: 0.2em 0;
|
||
}
|
||
.reminder-actions {
|
||
display: flex;
|
||
gap: 0.4em;
|
||
margin-top: 0.3em;
|
||
}
|
||
|
||
.questions-filters {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.3em;
|
||
margin-bottom: 0.5em;
|
||
}
|
||
.q-filter-chip {
|
||
background: var(--bg);
|
||
color: var(--muted);
|
||
border: 1px solid var(--border);
|
||
border-radius: 999px;
|
||
padding: 0.15em 0.7em;
|
||
font: inherit;
|
||
font-size: 0.85em;
|
||
cursor: pointer;
|
||
}
|
||
.q-filter-chip:hover { color: var(--fg); }
|
||
.q-filter-chip.active {
|
||
color: var(--amber);
|
||
border-color: var(--amber);
|
||
}
|
||
.questions li.question-peer {
|
||
border-left: 2px solid var(--purple);
|
||
padding-left: 0.6em;
|
||
}
|
||
.questions .msg-to-peer { color: var(--purple); }
|
||
.btn-override { background: var(--purple) !important; color: var(--bg) !important; }
|
||
.questions li.question {
|
||
padding: 0.4em 0;
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
.questions li.question:last-child { border-bottom: 0; }
|
||
.questions .q-head { font-size: 0.9em; }
|
||
.questions .q-ttl {
|
||
color: var(--amber);
|
||
margin-left: 0.4em;
|
||
font-size: 0.95em;
|
||
letter-spacing: 0.05em;
|
||
}
|
||
.questions .q-body {
|
||
color: var(--fg);
|
||
margin: 0.3em 0;
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
}
|
||
.qform {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.5em;
|
||
margin-top: 0.4em;
|
||
}
|
||
.qform .q-options {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.25em;
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
border-radius: 4px;
|
||
padding: 0.4em 0.6em;
|
||
}
|
||
.qform .q-option label { cursor: pointer; user-select: none; }
|
||
.qform .q-option input { margin-right: 0.4em; accent-color: var(--amber); }
|
||
.qform .q-free { display: flex; }
|
||
.qform .q-free textarea {
|
||
flex: 1;
|
||
font-family: inherit;
|
||
font-size: 1em;
|
||
background: var(--bg);
|
||
color: var(--fg);
|
||
border: 1px solid var(--border);
|
||
padding: 0.4em 0.6em;
|
||
resize: vertical;
|
||
line-height: 1.4;
|
||
}
|
||
.qform .q-free textarea::placeholder { color: var(--muted); }
|
||
.qform .q-free textarea:focus { outline: 1px solid var(--amber); }
|
||
.qform button { align-self: flex-start; }
|
||
.qform-cancel { margin-top: 0.3em; }
|
||
.q-history {
|
||
margin-top: 0.8em;
|
||
border: 1px solid var(--border);
|
||
border-radius: 4px;
|
||
padding: 0.4em 0.7em;
|
||
}
|
||
.q-history summary { cursor: pointer; color: var(--muted); font-size: 0.9em; user-select: none; }
|
||
.questions-answered {
|
||
border: none;
|
||
box-shadow: none;
|
||
animation: none;
|
||
padding: 0;
|
||
margin-top: 0.5em;
|
||
}
|
||
.question-answered { opacity: 0.7; }
|
||
.question-answered .q-body { color: var(--muted); margin-bottom: 0.15em; }
|
||
.q-answer { font-size: 0.9em; color: var(--green); padding: 0.1em 0 0.4em 0; }
|
||
.q-answer-text { font-style: italic; }
|
||
|
||
footer {
|
||
margin-top: 4em;
|
||
text-align: center;
|
||
color: var(--muted);
|
||
font-size: 0.9em;
|
||
}
|
||
footer a { color: var(--purple); }
|
||
footer .banner-thin {
|
||
margin-bottom: 0.8em;
|
||
}
|
||
|
||
/* ─── capabilities (permissions) table ─────────────────────────────
|
||
Agents × capabilities matrix in the P3RM1SS10NS tab. Same layout
|
||
as the tool-groups table below. Horizontally scrollable on narrow
|
||
viewports. */
|
||
.cap-table-wrap { overflow-x: auto; margin-top: 0.5em; }
|
||
.cap-table { border-collapse: collapse; font-size: 0.82em; min-width: 100%; }
|
||
.cap-table th,
|
||
.cap-table td {
|
||
padding: 0.35em 0.6em;
|
||
border: 1px solid var(--border);
|
||
text-align: center;
|
||
vertical-align: middle;
|
||
}
|
||
.cap-table thead th {
|
||
background: var(--bg-elev);
|
||
color: var(--muted);
|
||
letter-spacing: 0.05em;
|
||
white-space: nowrap;
|
||
}
|
||
.cap-agent-col {
|
||
text-align: left !important;
|
||
min-width: 8em;
|
||
}
|
||
.cap-col {
|
||
min-width: 5em;
|
||
}
|
||
.cap-agent-name {
|
||
color: var(--fg);
|
||
font-weight: 600;
|
||
}
|
||
.cap-cb {
|
||
cursor: pointer;
|
||
width: 1em;
|
||
height: 1em;
|
||
accent-color: var(--purple);
|
||
}
|
||
.cap-row:hover td {
|
||
background: var(--bg-elev);
|
||
}
|
||
|
||
/* ─── tool-groups (permissions) table ──────────────────────────────
|
||
Agents × tool-groups matrix in the P3RM1SS10NS tab. Same layout
|
||
as the capabilities table above. Horizontally scrollable on narrow
|
||
viewports. */
|
||
.tg-table-wrap { overflow-x: auto; margin-top: 0.5em; }
|
||
.tg-table { border-collapse: collapse; font-size: 0.82em; min-width: 100%; }
|
||
.tg-table th,
|
||
.tg-table td { padding: 0.35em 0.6em; border: 1px solid var(--border); text-align: center; vertical-align: middle; }
|
||
.tg-table thead th { background: var(--bg-elev); color: var(--muted); letter-spacing: 0.05em; white-space: nowrap; }
|
||
.tg-agent-col { text-align: left !important; min-width: 8em; }
|
||
.tg-group-col { min-width: 5em; }
|
||
.tg-agent-name { color: var(--fg); font-weight: 600; }
|
||
.tg-cb { cursor: pointer; width: 1em; height: 1em; accent-color: var(--purple); }
|
||
.tg-row:hover td { background: var(--bg-elev); }
|
||
|
||
/* ─── permissions save bar (save-all) ──────────────────────────────
|
||
One page-level save button for the whole P3RM1SS10NS tab. Sticks to
|
||
the bottom of the pane so it stays reachable while scrolling a long
|
||
agent×perm matrix. Disabled (dim) until an edit makes the page dirty;
|
||
the (N agents) count in the label reflects how many agents will
|
||
rebuild. `#perm-save-note` carries the transient rebuilding/error
|
||
line beside it. */
|
||
.perm-save-bar {
|
||
position: sticky;
|
||
bottom: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.8em;
|
||
margin-top: 1em;
|
||
padding: 0.7em 0;
|
||
background: var(--bg);
|
||
border-top: 1px solid var(--border);
|
||
}
|
||
.perm-save-bar .btn:disabled {
|
||
opacity: 0.45;
|
||
cursor: not-allowed;
|
||
}
|
||
.perm-save-err { color: var(--red); }
|
||
|
||
/* ─── scheduled prompts tab ────────────────────────────────────────
|
||
Creation form at the top, list of queued schedule cards below. */
|
||
|
||
.schedule-edit-form {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.6em;
|
||
background: var(--bg-elev);
|
||
border: 1px solid var(--border);
|
||
border-radius: 4px;
|
||
padding: 0.8em 1em;
|
||
margin-bottom: 0.5em;
|
||
}
|
||
.schedule-edit-form-wrapper {
|
||
margin-top: 0.5em;
|
||
padding-left: 0.5em;
|
||
border-left: 2px solid var(--yellow);
|
||
}
|
||
.schedule-edit-targets-note {
|
||
color: var(--muted);
|
||
font-style: italic;
|
||
font-size: 0.85em;
|
||
margin: 0.2em 0 0 0;
|
||
}
|
||
.schedule-field {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.2em;
|
||
}
|
||
.schedule-field-label {
|
||
color: var(--muted);
|
||
font-size: 0.85em;
|
||
letter-spacing: 0.05em;
|
||
text-transform: uppercase;
|
||
}
|
||
.schedule-field input,
|
||
.schedule-field textarea {
|
||
font-family: inherit;
|
||
font-size: inherit;
|
||
background: var(--bg);
|
||
color: var(--fg);
|
||
border: 1px solid var(--border);
|
||
border-radius: 3px;
|
||
padding: 0.35em 0.5em;
|
||
}
|
||
.schedule-field textarea { resize: vertical; min-height: 4em; }
|
||
.schedule-targets {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.4em;
|
||
}
|
||
.schedule-target-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.4em;
|
||
padding: 0.2em 0.6em;
|
||
border: 1px solid var(--border);
|
||
border-radius: 999px;
|
||
font-size: 0.85em;
|
||
cursor: pointer;
|
||
background: color-mix(in srgb, var(--bg-elev) 40%, transparent);
|
||
}
|
||
.schedule-target-chip:hover { border-color: var(--purple-dim); }
|
||
.schedule-target-chip:has(input:checked) {
|
||
border-color: var(--purple);
|
||
color: var(--purple);
|
||
background: color-mix(in srgb, var(--purple) 8%, transparent);
|
||
}
|
||
.schedule-target-chip input { margin: 0; }
|
||
.schedule-actions {
|
||
display: flex;
|
||
gap: 0.5em;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.schedule-interval-presets {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.3em;
|
||
margin-top: 0.1em;
|
||
}
|
||
.btn-interval-preset {
|
||
color: var(--cyan);
|
||
border-color: var(--cyan);
|
||
font-size: 0.75em;
|
||
padding: 0.15em 0.55em;
|
||
letter-spacing: 0.05em;
|
||
}
|
||
.btn-interval-oneshot {
|
||
color: var(--muted);
|
||
border-color: var(--muted);
|
||
}
|
||
.schedule-interval-parts {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: 0.35em;
|
||
margin-top: 0.4em;
|
||
}
|
||
.schedule-interval-num {
|
||
width: 4em;
|
||
text-align: right;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.schedule-interval-unit {
|
||
color: var(--muted);
|
||
font-size: 0.85em;
|
||
margin-right: 0.2em;
|
||
}
|
||
.schedule-interval-preview {
|
||
margin-top: 0.4em;
|
||
color: var(--cyan);
|
||
font-size: 0.9em;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.schedule-interval-preview-oneshot { color: var(--muted); font-style: italic; }
|
||
|
||
.schedules-table-wrap { overflow-x: auto; margin-top: 0.5em; }
|
||
.schedules-table {
|
||
min-width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 0.82em;
|
||
}
|
||
.schedules-table th,
|
||
.schedules-table td {
|
||
padding: 0.35em 0.6em;
|
||
border: 1px solid var(--border);
|
||
vertical-align: middle;
|
||
}
|
||
.schedules-table thead th {
|
||
background: var(--bg-elev);
|
||
color: var(--muted);
|
||
font-weight: normal;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
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; }
|
||
.schedules-table-body-th { min-width: 12em; }
|
||
.schedules-table-actions-th { width: 7em; }
|
||
.schedules-table-agent-th {
|
||
width: 28px;
|
||
min-width: 28px;
|
||
height: 95px;
|
||
padding: 0 !important;
|
||
vertical-align: bottom;
|
||
white-space: nowrap;
|
||
text-transform: none !important;
|
||
letter-spacing: 0 !important;
|
||
position: relative;
|
||
}
|
||
.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;
|
||
color: var(--fg);
|
||
}
|
||
.schedules-table-agent-th > div > span {
|
||
display: inline-block;
|
||
padding: 0 4px 1px;
|
||
}
|
||
/* 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
|
||
can still see (and cancel) the stale entries rather than be surprised. */
|
||
.schedules-table-agent-th--gone > div {
|
||
color: var(--muted);
|
||
text-decoration: line-through;
|
||
opacity: 0.75;
|
||
}
|
||
.schedules-table-row-cancelled td { opacity: 0.55; }
|
||
.schedules-table-body-cell {
|
||
max-width: 30em;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||
font-size: 0.9em;
|
||
}
|
||
.schedules-table-check {
|
||
width: 28px;
|
||
text-align: center;
|
||
padding: 0.3em 0 !important;
|
||
}
|
||
.schedules-table-check-btn {
|
||
background: transparent;
|
||
border: 0;
|
||
color: var(--green);
|
||
cursor: pointer;
|
||
padding: 0.1em 0.3em;
|
||
font-family: inherit;
|
||
font-size: 1em;
|
||
}
|
||
.schedules-table-check-btn:hover:not(:disabled) {
|
||
color: var(--red);
|
||
}
|
||
.schedules-table-check-btn:disabled {
|
||
cursor: default;
|
||
}
|
||
.schedules-table-check-cancelled {
|
||
color: var(--muted);
|
||
font-size: 0.9em;
|
||
}
|
||
.schedules-table-actions {
|
||
text-align: right;
|
||
white-space: nowrap;
|
||
}
|
||
.schedules-table-actions .btn-inline-small {
|
||
margin-left: 0.3em;
|
||
}
|
||
.schedules-table-edit-row > td {
|
||
/* Off-palette dim-purple surface tint: not an exact theme var, left as a
|
||
literal pending a dedicated named var so a theme swap can recolour it. */
|
||
background: rgba(38, 32, 60, 0.35);
|
||
padding: 0.5em 0.6em;
|
||
}
|
||
.schedules-table-create-row td {
|
||
/* Off-palette dim-purple surface tint — see the edit-row note above. */
|
||
background: rgba(38, 32, 60, 0.25);
|
||
border-top: 2px solid var(--border);
|
||
vertical-align: top;
|
||
padding: 0.4em 0.5em;
|
||
}
|
||
.schedules-table-create-cell {
|
||
padding: 0.35em 0.4em;
|
||
}
|
||
.schedules-table-inline-input,
|
||
.schedules-table-inline-textarea,
|
||
.schedules-table-inline-num {
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
color: var(--fg);
|
||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||
font-size: 0.85em;
|
||
padding: 0.2em 0.4em;
|
||
border-radius: 2px;
|
||
}
|
||
.schedules-table-inline-input:focus,
|
||
.schedules-table-inline-textarea:focus,
|
||
.schedules-table-inline-num:focus {
|
||
border-color: var(--purple);
|
||
outline: none;
|
||
}
|
||
.schedules-table-inline-textarea {
|
||
display: block;
|
||
width: 100%;
|
||
min-height: 1.6em;
|
||
resize: vertical;
|
||
}
|
||
.schedules-table-create-body:focus-within .schedules-table-inline-textarea {
|
||
min-height: 4em;
|
||
}
|
||
.schedules-table-inline-desc {
|
||
display: block;
|
||
width: 100%;
|
||
margin-top: 0.25em;
|
||
}
|
||
.schedules-table-inline-datetime {
|
||
width: 100%;
|
||
font-size: 0.78em;
|
||
}
|
||
.schedules-table-inline-interval {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.1em;
|
||
white-space: nowrap;
|
||
}
|
||
.schedules-table-inline-num {
|
||
width: 2.4em;
|
||
text-align: right;
|
||
font-variant-numeric: tabular-nums;
|
||
-moz-appearance: textfield;
|
||
appearance: textfield;
|
||
}
|
||
.schedules-table-inline-num::-webkit-outer-spin-button,
|
||
.schedules-table-inline-num::-webkit-inner-spin-button {
|
||
-webkit-appearance: none;
|
||
margin: 0;
|
||
}
|
||
.schedules-table-inline-unit {
|
||
color: var(--muted);
|
||
font-size: 0.7em;
|
||
margin-right: 0.15em;
|
||
}
|
||
.schedules-table-inline-check {
|
||
width: 16px;
|
||
height: 16px;
|
||
cursor: pointer;
|
||
margin: 0;
|
||
}
|
||
.schedules-table-inline-check-lbl {
|
||
display: inline-flex;
|
||
cursor: pointer;
|
||
padding: 0.4em 0.6em;
|
||
}
|
||
.schedules-table-create-submit {
|
||
font-size: 1em;
|
||
padding: 0.15em 0.55em;
|
||
color: var(--green);
|
||
border-color: var(--green);
|
||
}
|
||
.schedules-table-create-reset {
|
||
font-size: 0.85em;
|
||
padding: 0.15em 0.45em;
|
||
color: var(--muted);
|
||
border-color: var(--border);
|
||
}
|
||
.btn-inline-small {
|
||
font-size: 0.7em;
|
||
padding: 0.1em 0.45em;
|
||
}
|
||
|
||
/* Selection bar — sticky-bottom strip for bulk actions. */
|
||
.selection-bar {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 40;
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
gap: 0.6em;
|
||
padding: 0.55em 1em;
|
||
background: var(--flow-frost-bg, color-mix(in srgb, var(--bg) 74%, transparent));
|
||
-webkit-backdrop-filter: blur(12px) saturate(140%);
|
||
backdrop-filter: blur(12px) saturate(140%);
|
||
border-top: 1px solid var(--purple);
|
||
box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.4);
|
||
}
|
||
.selection-bar[hidden] { display: none; }
|
||
.selection-count {
|
||
color: var(--purple);
|
||
font-weight: bold;
|
||
letter-spacing: 0.05em;
|
||
}
|
||
.selection-names {
|
||
color: var(--muted);
|
||
font-size: 0.85em;
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.selection-actions {
|
||
display: inline-flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.4em;
|
||
align-items: center;
|
||
}
|
||
.selection-actions .btn {
|
||
font-size: 0.75em;
|
||
padding: 0.2em 0.7em;
|
||
}
|
||
.selection-clear {
|
||
color: var(--muted);
|
||
border-color: var(--purple-dim);
|
||
font-size: 0.75em;
|
||
padding: 0.2em 0.7em;
|
||
}
|
||
/* Pad the dashboard body so the sticky bar doesn't cover the
|
||
bottom of the agent list. Only applies when bar is visible. */
|
||
body.dashboard-shell.has-selection { padding-bottom: 4.5em; }
|
||
|
||
.move-picker {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.3em;
|
||
margin-left: 0.6em;
|
||
}
|
||
.move-picker-select {
|
||
font-family: inherit;
|
||
font-size: 0.75em;
|
||
background: var(--bg);
|
||
color: var(--fg);
|
||
border: 1px solid var(--purple);
|
||
border-radius: 2px;
|
||
padding: 0.1em 0.3em;
|
||
max-width: 16em;
|
||
}
|
||
.move-picker-select:disabled {
|
||
opacity: 0.5;
|
||
cursor: default;
|
||
}
|
||
|
||
/* ST4TS moved to its own page (`/stats.html`): the
|
||
window selector / summary chips / bars live in stats.css, and the
|
||
shared `.hive-stats-table` moved to common.css (the SYST3M ›
|
||
C0NT41N3R L04D table in system-sections.css / on /core.html still
|
||
uses it). */
|
||
|