Files
Varaverk/Plugin/unraid/css/varaverk.css
T

1064 lines
64 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Varaverk plugin styles — inherits unRAID theme, adds plugin-specific layout */
#varaverk-wrap { padding: 10px; font-family: inherit; }
/* Tab bar */
#vv-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 2px solid #444; align-items: flex-end; }
.vv-tab { padding: 6px 16px; text-decoration: none; color: #aaa; border-radius: 4px 4px 0 0; }
.vv-tab:hover { color: #fff; background: #333; }
.vv-tab.active { color: #fff; background: #555; border-bottom: 2px solid #fff; }
/* Expand toggle button */
#vv-expand-btn {
background: none; border: none; cursor: pointer;
color: #333; font-size: 15px; padding: 2px 8px 4px;
line-height: 1; border-radius: 3px; transition: color .15s;
margin-left: 6px; flex-shrink: 0;
}
#vv-expand-btn:hover { color: #888; }
#vv-expand-btn.active { color: #aaa; }
/* Fullscreen mode — hide Unraid chrome, reclaim the space */
body.vv-fullscreen #header { display: none !important; }
body.vv-fullscreen #menu { display: none !important; }
body.vv-fullscreen #displaybox { padding-left: 1rem !important; padding-top: .5rem !important; }
/* Cards / layout */
.vv-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.vv-card { flex: 1; min-width: 200px; background: #1e1e1e; border: 1px solid #444;
border-radius: 6px; padding: 12px; }
.vv-wide { flex: 100%; }
.vv-card h3 { margin: 0 0 10px; font-size: 13px; text-transform: uppercase;
color: #888; letter-spacing: 0.05em; white-space: normal;
overflow: hidden; min-width: 0;
display: flex; align-items: center; justify-content: space-between; }
/* Cog icon — links to related Unraid page. Hidden until card hovered. */
.vv-card-cog { color: #2a2a2a; font-size: 13px; line-height: 1; text-decoration: none;
padding: 1px 3px; border-radius: 3px; flex-shrink: 0;
transition: color 0.15s, background 0.15s;
font-style: normal; font-weight: normal; text-transform: none;
letter-spacing: 0; cursor: pointer; }
.vv-card:hover .vv-card-cog { color: #4a4a4a; }
.vv-card-cog:hover { color: #aaa !important; background: #333; }
/* Card header icon wrapper */
.vv-ico { display:inline-flex; align-items:center; opacity:0.38; flex-shrink:0; }
/* Status accent — left border colour for state-driven cards */
.vv-accent-ok { border-left-color: #2a5a2a !important; }
.vv-accent-warn { border-left-color: #5a4000 !important; }
.vv-accent-err { border-left-color: #5a1e1e !important; }
#vv-monitor .vv-card { transition: border-left-color 0.5s; }
/* Status banner — coloured strip at top of card body */
.vv-banner { border-radius: 4px; padding: 5px 10px; margin-bottom: 10px;
display: flex; align-items: center; justify-content: space-between;
font-size: 12px; font-weight: 600; }
.vv-banner-ok { background: #061306; border: 1px solid #1a401a; color: #4caf50; }
.vv-banner-warn { background: #130e00; border: 1px solid #3d2e00; color: #ff9800; }
.vv-banner-err { background: #140404; border: 1px solid #3d1010; color: #f44336; }
.vv-banner-off { background: #0d0d0d; border: 1px solid #252525; color: #555; }
/* System card — no h3, no top padding waste */
#vv-system { padding-top: 14px; }
/* System action buttons */
.vv-sys-btn { background: #2a2a2a; border: 1px solid #e65100; color: #ff9800; border-radius: 3px;
padding: 3px 0; font-size: 6px; cursor: pointer; line-height: 1;
width: 50px; min-width: 0; text-align: center; }
.vv-sys-btn:hover { background: #3a2000; color: #ffb74d; border-color: #ff9800; }
/* Fallback state badge */
.vv-state-badge { font-size: 20px; font-weight: bold; padding: 4px 0; margin-bottom: 2px; }
.vv-state-normal { color: #4caf50; }
.vv-state-failover { color: #f44336; }
.vv-state-no_internet { color: #ff9800; }
.vv-state-dark { color: #9e9e9e; }
.vv-state-unknown { color: #666; }
/* Docker table */
#vv-docker-table { width: 100%; border-collapse: collapse; font-size: 13px; }
#vv-docker-table th { text-align: left; padding: 4px 8px; color: #888;
border-bottom: 1px solid #444; }
#vv-docker-table td { padding: 4px 8px; border-bottom: 1px solid #2a2a2a; }
.vv-status-up { color: #4caf50; }
.vv-status-down { color: #f44336; }
/* Scheduler */
.vv-hint { color: #888; font-size: 13px; margin-bottom: 16px; }
.vv-sched-card { margin-bottom: 10px; }
.vv-script { background: #161616; border: 1px solid #333; border-radius: 4px;
padding: 6px 10px; margin: 4px 0; margin-left: 20px; }
.vv-job-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
transition: background 0.1s, box-shadow 0.1s; }
/* Orchestrator top row — clickable, show pointer + hover feedback */
.vv-orch-row { cursor: pointer; border-radius: 4px; }
.vv-orch-row:hover { background: rgba(255,255,255,0.04); }
.vv-job-label { flex: 1; font-size: 16px; font-weight: bold;
color: #6fcf97; min-width: 80px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vv-job-actions { display: flex; align-items: center; gap: 8px; padding-left: 44px; margin-top: 6px; }
.vv-job-desc { font-size: 14px; color: #777; margin: 3px 0 2px 0;
padding-left: 44px; box-sizing: border-box; width: 100%;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
cursor: default; }
.vv-cron { flex: 0 0 80px; width: 80px; background: #111; border: 1px solid #444; color: #ddd;
padding: 4px 6px; border-radius: 4px; font-family: monospace; font-size: 11px; }
.vv-event-badge { flex: 0 0 auto; padding: 3px 8px; border-radius: 4px; font-size: 12px;
background: #1a3a1a; border: 1px solid #2e6b2e; color: #6fcf6f;
white-space: nowrap; font-weight: 500; }
.vv-flag-badge { flex: 0 0 auto; padding: 2px 6px; border-radius: 3px; font-size: 11px;
background: #2e2200; border: 1px solid #6b4e00; color: #d4a017;
white-space: nowrap; font-family: monospace; }
.vv-log-label { display: flex; align-items: center; gap: 4px; font-size: 12px; color: #888;
cursor: pointer; white-space: nowrap; flex-shrink: 0; }
.vv-log-label input { cursor: pointer; accent-color: #4caf50; }
.vv-log-label:has(input:checked) { color: #4caf50; }
.vv-children { padding-top: 8px; border-top: 1px solid #333; margin-top: 8px; }
.vv-advanced-toggle { background: none; border: 1px solid #555; color: #aaa;
padding: 2px 8px; border-radius: 4px; cursor: pointer; font-size: 12px; }
.vv-advanced-toggle:hover { border-color: #888; color: #fff; }
.vv-btn-sm { padding: 3px 10px; background: #2a2a2a; border: 1px solid #555; color: #ccc;
border-radius: 4px; cursor: pointer; font-size: 12px; white-space: nowrap; }
.vv-btn-sm:hover { border-color: #888; color: #fff; }
.vv-btn-sm.active { border-color: #4caf50; color: #4caf50; }
/* Save checkmark */
.vv-save-check { color: #4caf50; font-size: 13px; width: 14px; flex-shrink: 0;
opacity: 0; text-align: center; }
@keyframes vv-check-fade { 0%,60% { opacity: 1; } 100% { opacity: 0; } }
.vv-save-check.vv-check-show { animation: vv-check-fade 2s forwards; }
/* Running dot */
.vv-job-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.vv-dot-running { background: #4caf50; animation: vv-pulse-dot 1s ease-in-out infinite; }
#vv-log-dot { animation: vv-pulse-dot 1s ease-in-out infinite; }
@keyframes vv-pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }
/* Selected job row — editor-style left accent + blue tint */
.vv-row-selected { background: rgba(100,149,237,0.1); border-radius: 4px;
outline: 1px solid rgba(100,149,237,0.35);
box-shadow: inset 3px 0 0 #6495ed; }
/* Two-panel layout */
#vv-sched-layout { display: flex; gap: 16px; align-items: stretch; }
#vv-sched-left { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-self: flex-start; }
#vv-sched-cards { flex: 1; }
#vv-sched-right { display: none; flex: 1 1 0; min-width: 0; flex-direction: column; overflow: hidden; align-self: flex-start; }
#vv-sched-right.vv-panel-visible { display: flex; }
.vv-log-card { flex: 1; display: flex; flex-direction: column; padding-bottom: 0; }
.vv-log-right-pre { max-height: none; overflow-y: auto; }
/* Scheduler stacked layout (narrow viewport) */
@media (max-width: 900px) {
#vv-sched-layout { flex-direction: column; align-items: stretch; }
#vv-sched-left { flex: none; width: 100%; }
#vv-sched-right { flex-direction: column; width: 100%; overflow: visible; }
.vv-log-right-pre { min-height: 520px; max-height: 680px; }
/* Toolbar: stack title row above buttons row, let buttons wrap */
.vv-log-toolbar { flex-direction: column; align-items: flex-start; gap: 6px; }
.vv-log-toolbar > div { flex-wrap: wrap; gap: 6px !important; }
/* Array-event rows: badge already shows the event, cron input is redundant */
.vv-job-row:has(.vv-event-badge) .vv-cron { display: none; }
}
/* Plugin settings row (Advanced mode) */
.vv-nb-settings { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
padding: 5px 10px; background: #101010; border-bottom: 1px solid #1a1a1a; }
/* ── Monitor: locked row height + scrollable cards ────────────────────────── */
/* Cards on the monitor grid are flex columns — h3 pins, body scrolls */
#vv-monitor .vv-card {
display: flex;
flex-direction: column;
overflow: hidden;
}
#vv-monitor .vv-card h3 { flex-shrink: 0; }
#vv-monitor .vv-card > div {
flex: 1;
min-height: 0;
overflow-y: auto;
-ms-overflow-style: none;
scrollbar-width: none;
}
#vv-monitor .vv-card > div::-webkit-scrollbar { display: none; }
/* Hide scrollbars on any nested scrollable div inside monitor cards */
#vv-monitor .vv-card div::-webkit-scrollbar { display: none; }
/* Dynamic row heights capped per screen tier — rows size to content, never exceed the cap.
minmax(0, Xpx): track is content-driven but capped; align-items:stretch makes all cards
in a row fill the track, so short cards (Pools, Watchdog) match tall ones (Array).
Breakpoints are viewport height (after browser chrome), not screen height. */
/* ~720p (viewport ≤ 700px) */
@media (min-width: 481px) and (max-height: 700px) {
#vv-monitor { grid-auto-rows: minmax(0, calc((100vh - 160px) / 4)); }
}
/* ~1080p (viewport 7011100px) */
@media (min-width: 481px) and (min-height: 701px) and (max-height: 1100px) {
#vv-monitor { grid-auto-rows: minmax(0, calc((100vh - 240px) / 4)); }
}
/* ~1440p (viewport 11011450px) — calibrated on 15" 1440p display */
@media (min-width: 481px) and (min-height: 1101px) and (max-height: 1450px) {
#vv-monitor { grid-auto-rows: minmax(0, calc((100vh - 335px) / 4)); }
}
/* ~4K (viewport > 1450px) */
@media (min-width: 481px) and (min-height: 1451px) {
#vv-monitor { grid-auto-rows: minmax(0, calc((100vh - 500px) / 4)); }
}
/* Mobile: natural heights, let page scroll */
@media (max-width: 480px) {
#vv-monitor { grid-auto-rows: auto !important; }
#vv-monitor .vv-card { overflow: visible !important; }
#vv-monitor .vv-card > div { overflow-y: visible; min-height: auto; }
}
/* Monitor responsive — 4-column grid at medium width */
@media (max-width: 1400px) {
/* CPU core bars — reduce gap/min-width at intermediate widths before cores get clipped */
.vv-cpu-cores { gap: 2px !important; }
.vv-cpu-core { min-width: 7px !important; }
}
@media (max-width: 1024px) {
#vv-monitor { grid-template-columns: repeat(4, 1fr) !important; }
#vv-docker { grid-column: span 4 !important; }
/* Reset explicit placements so cards reflow in the 4-col grid */
#vv-docker-folders { grid-column: span 4 !important; }
#vv-parity-card { grid-column: auto !important; }
#vv-storage-card { grid-column: auto !important; }
#vv-array-card { grid-column: auto !important; }
/* Streams header: hide right chip group entirely, keep server badges + media type */
.vv-stream-right { display: none; }
}
/* Containers+VMs: single column when viewport is narrow */
@media (max-width: 900px) {
.vv-df-cols { flex-direction: column; align-items: stretch; }
}
/* Phone layout — scheduler row/actions fixes + monitor single-column */
@media (max-width: 480px) {
/* Phone portrait — hint gone, cron stays inline but compact */
.vv-cron-hint { display: none !important; }
.vv-job-row .vv-cron { flex: 0 0 68px; width: 68px; font-size: 10px; margin-left: 30px; }
}
@media (max-width: 600px) {
/* Allow action buttons to wrap rather than overflow the card */
.vv-job-actions { flex-wrap: wrap; padding-left: 0; }
/* Kill the inline margin-left:auto that pushes Advanced off-screen */
.vv-advanced-toggle { margin-left: 0 !important; width: auto !important; }
/* Keep cron from growing — label owns remaining row space */
.vv-cron { flex: 0 0 75px; width: 75px; }
/* Slightly tighter label on narrow screens */
.vv-job-label { font-size: 14px; }
/* Footer buttons wrap instead of overflowing */
.vv-sched-footer { flex-wrap: wrap; }
/* Log toolbar search — narrow on small screens */
#vv-log-search { width: 80px; }
/* Snapshot footer — smaller on mobile */
.vv-snap-footer { gap: 10px !important; }
.vv-snap-item { gap: 4px; }
.vv-snap-label { font-size: 10px; }
.vv-snap-bar { width: 44px; height: 5px; }
.vv-snap-val { font-size: 11px; min-width: 26px; }
.vv-snap-div { font-size: 11px; }
.vv-snap-state { font-size: 11px; }
#vv-snap-partner { font-size: 11px; }
.vv-snap-media { font-size: 11px; }
/* CPU core bars — shrink gap and min-width so many cores don't overflow */
.vv-cpu-cores { gap: 2px !important; }
.vv-cpu-core { min-width: 6px !important; }
/* Monitor single-column — explicit placement cards need override too */
#vv-monitor { grid-template-columns: 1fr !important; }
#vv-monitor > .vv-card { grid-column: 1 / -1 !important; }
#vv-docker-folders { grid-column: 1 / -1 !important; }
}
/* Shared footer (Save Schedule left, info right) — same min-height so log card ends level with script cards */
.vv-sched-footer { display: flex; align-items: center; gap: 10px;
margin-top: 12px; padding: 10px 0; border-top: 1px solid #333;
flex-shrink: 0; min-height: 72px; box-sizing: border-box; }
.vv-sched-info { color: #666; font-size: 14px; display: flex; flex-direction: column; gap: 9px; }
.vv-save-btn { padding: 5px 18px; background: #4caf50; border: none; color: #fff;
border-radius: 4px; cursor: pointer; font-size: 13px; }
.vv-save-btn:hover { background: #388e3c; }
.vv-save-status { font-size: 12px; color: #aaa; }
.vv-run-btn { border-color: #2196f3 !important; color: #2196f3 !important; }
.vv-run-btn:hover { background: #0d47a1 !important; color: #fff !important;
border-color: #2196f3 !important; }
.vv-dry-btn { border-color: #ff9800 !important; color: #ff9800 !important; }
.vv-dry-btn:hover { background: #e65100 !important; color: #fff !important;
border-color: #ff9800 !important; }
.vv-log-btn { border-color: #555 !important; color: #666 !important; }
.vv-log-btn:hover { background: #333 !important; color: #aaa !important; border-color: #777 !important; }
.vv-log-btn.vv-has-log { border-color: #4caf50 !important; color: #4caf50 !important; }
.vv-log-btn.vv-has-log:hover { background: #1b5e20 !important; color: #fff !important;
border-color: #4caf50 !important; }
.vv-edit-btn { border-color: #7b1fa2 !important; color: #ce93d8 !important; }
.vv-edit-btn:hover { background: #4a148c !important; color: #fff !important; border-color: #7b1fa2 !important; }
.vv-add-script-btn { background: #1565c0 !important; border: none !important; color: #fff !important; margin-left: 8px; }
.vv-add-script-btn:hover { background: #0d47a1 !important; }
.vv-save-script-btn-style { background: #1565c0 !important; border: none !important; color: #fff !important; }
.vv-save-script-btn-style:hover { background: #0d47a1 !important; }
.vv-delete-btn { background: #b71c1c !important; border: none !important; color: #fff !important; margin-left: 4px; }
.vv-delete-btn:hover { background: #7f0000 !important; }
.vv-conf-btn { border-color: #00838f !important; color: #4dd0e1 !important; }
.vv-conf-btn:hover { background: #006064 !important; color: #fff !important; border-color: #00838f !important; }
/* Config form */
#vv-confform { padding: 2px 4px; }
.vv-cf-group { border-bottom: 1px solid #252525; padding-bottom: 14px; margin-bottom: 14px; }
.vv-cf-group:last-child { border-bottom: none; margin-bottom: 0; }
.vv-cf-group-header { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: bold;
color: #7a9eb5; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 10px; }
.vv-cf-file { font-size: 10px; color: #555; background: #1a1a1a; border: 1px solid #2e2e2e;
padding: 1px 6px; border-radius: 3px; font-weight: normal; text-transform: none;
letter-spacing: 0; }
/* One setting per striped row, numbered down the left. Previously these were separated only by
a 10px margin, which read as one continuous block once a script had more than a few. The
stripe is what actually does the separating; the number gives each one a handle to refer to. */
.vv-cf-field { display: flex; align-items: flex-start; gap: 10px;
padding: 8px 10px; border-radius: 3px; border-left: 2px solid transparent; }
.vv-cf-alt { background: #141414; }
.vv-cf-field:hover { border-left-color: #2d4a6a; }
.vv-cf-num { font-family: monospace; font-size: 10px; color: #3a3a3a; min-width: 20px;
text-align: right; padding-top: 2px; flex-shrink: 0; user-select: none; }
.vv-cf-field:hover .vv-cf-num { color: #6a6a6a; }
.vv-cf-body { flex: 1; min-width: 0; }
.vv-cf-key { font-family: monospace; font-size: 12px; color: #ccc; margin-bottom: 3px; }
.vv-cf-desc { font-size: 11px; color: #666; margin-bottom: 4px; font-style: italic; line-height: 1.4; }
.vv-cf-scalar { display: block; width: 100%; box-sizing: border-box; background: #111; border: 1px solid #333;
color: #ddd; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; }
.vv-cf-scalar:focus { border-color: #555; outline: none; }
/* Array fields: numbered gutter + striped rows. The wrap owns the border so the gutter and the
text read as one control. line-height is an exact 18px, not 1.6 — the stripes are a repeating
gradient and would drift out of register against the text on a fractional line box. */
.vv-cf-arraywrap { display: flex; border: 1px solid #333; border-radius: 4px; overflow: hidden;
background: #0d0d0d; }
.vv-cf-arraywrap:focus-within { border-color: #555; }
.vv-cf-lines { margin: 0; padding: 8px 6px 8px 0; width: 34px; min-width: 34px; flex-shrink: 0;
text-align: right; font-family: monospace; font-size: 11px; line-height: 18px;
color: #3a3a3a; background: #0a0a0a; border-right: 1px solid #1c1c1c;
overflow: hidden; user-select: none; white-space: pre; }
/* No soft wrap. A wrapped line takes two or three visual rows while the gutter prints one number
for it, so the numbers and the stripes drift further out of register with every long entry —
and the trailing comments in DAILY_MAINTENANCE_SCRIPTS are long. Scrolling sideways is the
same trade the main script editor already makes for the same reason. */
.vv-cf-array { display: block; width: 100%; box-sizing: border-box; background-color: transparent;
border: none; color: #ccc; padding: 8px; font-family: monospace; font-size: 11px;
line-height: 18px; resize: vertical; min-height: 60px;
white-space: pre; overflow-x: auto;
background-image: repeating-linear-gradient(rgba(255,255,255,0) 0 18px,
rgba(255,255,255,0.028) 18px 36px);
background-origin: content-box; background-attachment: local; }
.vv-cf-array:focus { outline: none; }
.vv-cf-empty { color: #555; font-size: 13px; font-style: italic; padding: 20px 4px; text-align: center; margin: 0; }
.vv-custom-empty { color: #666; font-size: 13px; padding: 8px 4px; margin: 0; font-style: italic; }
.vv-custom-count { font-size: 12px; color: #666; margin-left: 8px; flex-shrink: 0; }
.vv-section-sep { font-size: 11px; font-weight: bold; color: #666; text-transform: uppercase;
letter-spacing: 0.08em; padding: 10px 4px 4px; border-top: 1px solid #222; margin-top: 8px; }
#vv-editor { flex-direction: column; gap: 0; }
.vv-editor-body { font-family: monospace; font-size: 12px; background: #0d0d0d; color: #ccc;
border: 1px solid #333; border-radius: 4px; padding: 10px 12px; resize: none;
line-height: 1.5; scroll-behavior: auto; tab-size: 2; width: 100%; box-sizing: border-box;
white-space: pre; overflow-x: auto;
appearance: none; -moz-appearance: none; }
/* Editor layout: gutter + inner area — unified bordered block */
#vv-editor-wrap { display: flex; border: 1px solid #2e2e2e; border-radius: 4px 4px 0 0;
overflow: hidden; background: #0d0d0d; }
#vv-ln-gutter { width: 46px; min-width: 46px; flex-shrink: 0;
background: #0a0a0a; border-right: 1px solid #1c1c1c;
font-family: monospace; font-size: 12px; line-height: 1.5; tab-size: 2;
color: #3a3a3a; text-align: right; padding: 10px 8px 10px 0;
overflow: hidden; user-select: none; white-space: pre; }
.vv-gln-cur { color: #ccc; font-weight: bold; }
#vv-editor-inner { position: relative; flex: 1; overflow: hidden; background: #0d0d0d; }
/* Current line highlight — sits behind overlay */
#vv-cur-line { position: absolute; left: 0; right: 0; height: 18px;
background: rgba(255,255,255,0.04);
border-top: 1px solid rgba(255,255,255,0.03);
border-bottom: 1px solid rgba(255,255,255,0.03);
pointer-events: none; display: none; }
/* Syntax-highlight overlay — transparent bg so cur-line shows through */
#vv-hl-overlay { display: none; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
margin: 0; padding: 10px 12px; box-sizing: border-box;
font-family: monospace; font-size: 12px; line-height: 1.5; tab-size: 2;
white-space: pre; overflow: hidden;
pointer-events: none; user-select: none;
background: transparent; border: none; border-radius: 0; }
.vv-editor-hl #vv-hl-overlay { display: block; }
.vv-editor-hl #vv-editor-body { color: transparent; caret-color: #ddd; background: transparent;
border: none !important; border-radius: 0 !important; }
/* Visible selection — works even when text is transparent */
.vv-editor-hl #vv-editor-body::selection { background: rgba(100,149,237,0.35); color: transparent; }
.vv-editor-hl #vv-editor-body::-moz-selection{ background: rgba(100,149,237,0.35); color: transparent; }
/* Word match and search marks in the overlay */
.vv-word-mark { background: rgba(255,220,60,0.14); outline: 1px solid rgba(255,220,60,0.35); border-radius: 2px; }
.vv-search-mark { background: rgba(255,140,20,0.22); outline: 1px solid rgba(255,140,20,0.45); border-radius: 2px; }
.vv-search-mark-current{ background: rgba(255,90,0,0.40); outline: 2px solid rgba(255,100,0,0.7); border-radius: 2px; }
/* Slim scrollbar for editor */
#vv-editor-body::-webkit-scrollbar { width: 8px; height: 8px; }
#vv-editor-body::-webkit-scrollbar-track { background: #0a0a0a; }
#vv-editor-body::-webkit-scrollbar-thumb { background: #2a2a2a; border-radius: 4px; }
#vv-editor-body::-webkit-scrollbar-thumb:hover { background: #444; }
/* Editor find bar — two-row (find + optional replace) */
#vv-editor-find { display: none; flex-direction: column; gap: 0; padding: 5px 8px;
margin-bottom: 5px; background: #161616; border: 1px solid #333;
border-radius: 4px; font-size: 12px; }
#vv-editor-find.vv-find-open { display: flex; }
.vv-find-row { display: flex; align-items: center; gap: 6px; }
.vv-replace-row { display: none; align-items: center; gap: 6px;
margin-top: 4px; padding-top: 4px; border-top: 1px solid #222; }
.vv-replace-row.vv-repl-open { display: flex; }
.vv-find-expand { font-size: 10px; color: #555; cursor: pointer; flex-shrink: 0;
width: 14px; text-align: center; user-select: none;
transition: transform 0.15s; line-height: 1; }
.vv-find-expand:hover { color: #aaa; }
.vv-find-expand.open { transform: rotate(90deg); color: #888; }
#vv-find-input, #vv-replace-input {
flex: 1; min-width: 0; background: #0d0d0d; border: 1px solid #333;
color: #ddd; padding: 4px 8px; border-radius: 3px;
font-family: monospace; font-size: 12px; }
#vv-find-input:focus, #vv-replace-input:focus {
border-color: #6495ed; outline: none; box-shadow: 0 0 0 1px rgba(100,149,237,0.25); }
#vv-find-input.vv-find-no-match { border-color: #c62828; box-shadow: 0 0 0 1px rgba(198,40,40,0.3); }
.vv-find-count { font-size: 11px; color: #555; white-space: nowrap; flex-shrink: 0; min-width: 64px; text-align: right; }
.vv-find-nav-btn{ padding: 2px 8px !important; }
.vv-repl-btn { border-color: #444 !important; color: #777 !important; }
.vv-repl-btn:hover { border-color: #777 !important; color: #ddd !important; }
.vv-find-x { color: #555; cursor: pointer; font-size: 16px; line-height: 1;
padding: 0 2px; flex-shrink: 0; }
.vv-find-x:hover { color: #aaa; }
/* Editor status bar */
#vv-editor-status { display: none; align-items: center; gap: 10px; padding: 3px 10px;
background: #0e0e0e; border: 1px solid #2e2e2e; border-top: none;
border-radius: 0 0 4px 4px; font-family: monospace;
font-size: 10px; color: #444; user-select: none; flex-shrink: 0; }
#vv-editor-status.vv-ed-active { display: flex; }
.vv-es-pos { color: #666; }
.vv-es-sel { color: #555; }
.vv-es-lang { margin-left: auto; color: #4a6a7a; }
/* Status bar action buttons */
.vv-es-btn { background: none; border: none; cursor: pointer; color: #555;
font-size: 10px; padding: 1px 4px; border-radius: 2px; font-family: monospace; }
.vv-es-btn:hover { color: #aaa; background: rgba(255,255,255,0.05); }
.vv-es-btn.active { color: #6495ed; }
#vv-es-fontsize { color: #444; font-size: 10px; min-width: 26px; text-align: center; }
/* Word wrap mode — applied to #vv-editor-wrap when wrap is enabled */
#vv-editor-wrap.vv-ed-wrap .vv-editor-body { white-space: pre-wrap !important; overflow-x: hidden !important; }
#vv-editor-wrap.vv-ed-wrap #vv-hl-overlay { white-space: pre-wrap !important; word-break: break-word !important; }
#vv-editor-wrap.vv-ed-wrap #vv-ln-gutter { display: none; }
#vv-editor-wrap.vv-ed-wrap #vv-cur-line { display: none !important; }
/* Indent guides — 1px lines every 2 chars, starting at indent level 1 */
#vv-editor-inner {
position: relative; flex: 1; overflow: hidden;
background-color: #0d0d0d;
background-image: repeating-linear-gradient(
90deg,
rgba(255,255,255,0.045) 0 1px,
transparent 1px 2ch
);
background-position: calc(12px + 2ch) 0;
}
/* Go to line bar */
#vv-goto-bar { display: none; align-items: center; gap: 8px; padding: 5px 8px;
margin-bottom: 5px; background: #161616; border: 1px solid #333;
border-radius: 4px; font-size: 12px; }
#vv-goto-bar.vv-goto-open { display: flex; }
#vv-goto-input { width: 68px; background: #0d0d0d; border: 1px solid #333; color: #ddd;
padding: 4px 8px; border-radius: 3px; font-family: monospace; font-size: 12px; }
#vv-goto-input:focus { border-color: #6495ed; outline: none; }
.vv-goto-info { font-size: 11px; color: #555; white-space: nowrap; flex-shrink: 0; }
/* Undo / Redo buttons */
.vv-undo-redo-btn { border-color: #444 !important; color: #666 !important; }
.vv-undo-redo-btn:not([disabled]):hover { border-color: #777 !important; color: #ccc !important; background: #1e1e1e !important; }
.vv-undo-redo-btn[disabled] { opacity: 0.28 !important; cursor: default !important; pointer-events: none; }
.vv-undo-count { font-size: 10px; opacity: 0.7; margin-left: 2px; }
/* Suggestions panel — accordion */
#vv-suggestions { overflow-y: auto; }
.vv-sug-block { border-bottom: 1px solid #1e1e1e; }
.vv-sug-header { display: flex; align-items: center; gap: 8px; padding: 7px 4px;
cursor: pointer; user-select: none; flex-wrap: wrap; }
.vv-sug-header:hover { background: rgba(255,255,255,0.03); }
.vv-sug-chevron { color: #555; font-size: 11px; flex-shrink: 0; width: 10px; }
.vv-sug-title { color: #7a9eb5; font-weight: bold; font-size: 13px; flex: 1; min-width: 120px; }
.vv-sug-cron { color: #ddd; background: #111; border: 1px solid #333; padding: 1px 6px;
border-radius: 3px; font-size: 11px; font-family: monospace; white-space: nowrap; flex-shrink: 0; }
.vv-sug-label { color: #666; font-size: 12px; flex: 1; min-width: 0; white-space: nowrap;
overflow: hidden; text-overflow: ellipsis; }
.vv-sug-status { font-size: 11px; flex-shrink: 0; margin-left: auto; }
.vv-sug-on { color: #4caf50; }
.vv-sug-off { color: #777; }
.vv-sug-none { color: #444; }
.vv-sug-body { padding: 0 14px 10px; }
.vv-sug-desc { font-size: 12px; color: #888; white-space: pre-wrap; word-break: break-word;
background: none; border: none; margin: 4px 0 8px; padding: 0;
font-family: inherit; line-height: 1.6; }
.vv-sug-scripts { display: flex; flex-direction: column; gap: 4px; }
.vv-sug-script-row { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.vv-sug-inline-cron { color: #aaa; background: #111; padding: 1px 5px; border-radius: 3px;
font-size: 11px; white-space: nowrap; }
.vv-sug-path { color: #888; font-family: monospace; }
.vv-sug-configured { color: #4caf50; font-size: 11px; }
/* Info sections inside Scheduler Information panel */
/* ── Assistant dock (scheduler right panel) ────────────────────────────────────────────────── */
#vv-ai-dock { border: 1px solid #262626; border-radius: 6px; background: #0e0e0e;
margin-top: 6px; flex-shrink: 0; }
#vv-ai-dock-bar { display: flex; align-items: center; gap: 7px; padding: 6px 8px; }
#vv-ai-dock-chip { flex-shrink: 0; font-size: 10px; color: #5a7a8a; background: #12191d;
border: 1px solid #24343d; border-radius: 3px; padding: 2px 7px;
white-space: nowrap; max-width: 40%; overflow: hidden; text-overflow: ellipsis; }
.vv-ai-chip-flash { animation: vvAiChipFlash .9s ease-out 2; }
@keyframes vvAiChipFlash { 0%,100% { background:#12191d; color:#5a7a8a; }
50% { background:#2a2312; color:#d8b25a; } }
#vv-ai-dock-input { flex: 1; min-width: 0; background: #0a0a0a; border: 1px solid #262626;
border-radius: 4px; color: #c8c8c8; font-family: inherit; font-size: 12px;
padding: 5px 9px; }
#vv-ai-dock-input:focus { outline: none; border-color: #2d4a6a; }
#vv-ai-dock-body { border-bottom: 1px solid #1c1c1c; padding: 9px 10px; overflow-y: auto;
font-size: 12px; line-height: 1.55; }
/* Always present, unlike the collapse button next to it — the size of the conversation is worth
changing before there is one, when you already know the answer will be long. */
.vv-ai-dock-grow { flex-shrink: 0; min-width: 26px; }
.vv-ai-dock-grow-on { color: #8fb0c4; border-color: #2d4a6a; background: #12191d; }
.vv-ai-dock-q { color: #8fb0c4; margin: 0 0 5px; }
.vv-ai-dock-q::before { content: ' '; color: #3a5a6a; }
.vv-ai-dock-a { color: #b8b8b8; margin: 0 0 11px; white-space: normal; }
.vv-ai-dock-a code { background: #1a1a1a; border: 1px solid #333; border-radius: 2px;
padding: 0 4px; font-size: 11px; color: #9ab; }
.vv-ai-dock-a strong { color: #ddd; }
.vv-ai-dock-wait { color: #5a5a5a; font-style: italic; }
.vv-ai-dock-err { color: #e57; }
.vv-ai-dock-src { margin-top: 6px; padding-top: 5px; border-top: 1px solid #1c1c1c;
font-size: 10px; color: #4a4a4a; font-family: monospace; }
.vv-ai-dock-sep { margin: 4px 0 9px; font-size: 10px; color: #4a4a4a; text-align: center;
border-top: 1px solid #1c1c1c; padding-top: 6px; }
.vv-info-block .vv-sug-title { color: #9ab; }
/* Depth switch on the help header. Outlined rather than filled — it changes what you are
reading, it does not do anything to the machine, and every button on this page that does
is filled. */
.vv-more-btn { flex-shrink: 0; background: none; border: 1px solid #8a8a8a; color: #ccc;
font-size: 10px; letter-spacing: .04em; padding: 2px 9px; border-radius: 3px;
cursor: pointer; font-family: inherit; }
.vv-more-btn:hover { border-color: #fff; color: #fff; background: rgba(255,255,255,0.06); }
.vv-more-btn.vv-more-on { border-color: #2d4a6a; color: #7a9eb5; background: #14202c; }
.vv-info-body { padding: 2px 10px 10px; }
.vv-info-cols { margin: 0; padding-left: 16px; columns: 2; column-gap: 20px; column-fill: balance; }
.vv-info-cols li { font-size: 12px; color: #aaa; margin-bottom: 5px; break-inside: avoid; line-height: 1.5; }
.vv-info-cols .vv-info-sep { column-span: all; list-style: none; margin: 10px -4px 6px;
padding: 4px 8px; background: #161a1d; border-left: 2px solid #1e6fa5;
font-size: 10px; font-weight: bold; text-transform: uppercase;
letter-spacing: .08em; color: #4a8ab5; break-inside: avoid; }
.vv-info-cols li strong { color: #ccc; }
.vv-info-cols code { background: #1a1a1a; padding: 0 4px; border-radius: 2px;
font-size: 11px; color: #9ab; border: 1px solid #333; }
/* ── Rendered page docs (include/docs.php → pages/readme/*.md) ─────────────────────────────── */
/* Two columns so the reference tables and the task sections sit side by side rather than making
the panel a long scroll. Headings span both, which is what keeps a task and its steps together
instead of splitting across the gap. */
.vv-doc { columns: 320px 2; column-gap: 26px; font-size: 12px; color: #aaa; line-height: 1.55; }
.vv-doc > h1 { display: none; } /* the panel already has its own title */
.vv-doc h2 { column-span: all; margin: 12px -4px 7px; padding: 4px 8px; background: #161a1d;
border-left: 2px solid #1e6fa5; font-size: 10px; font-weight: bold;
text-transform: uppercase; letter-spacing: .08em; color: #4a8ab5; }
.vv-doc h2:first-child { margin-top: 2px; }
.vv-doc p { margin: 0 0 7px; break-inside: avoid; }
.vv-doc ul, .vv-doc ol { margin: 0 0 8px; padding-left: 16px; }
.vv-doc li { margin-bottom: 4px; break-inside: avoid; }
.vv-doc strong { color: #ccc; }
.vv-doc em { color: #9a9a9a; font-style: italic; }
.vv-doc hr { display: none; } /* h2 bars already separate the sections */
.vv-doc code { background: #1a1a1a; padding: 0 4px; border-radius: 2px; font-size: 11px;
color: #9ab; border: 1px solid #333; }
.vv-doc blockquote { margin: 0 0 8px; padding: 6px 9px; background: #16130d;
border-left: 2px solid #7a5a2a; color: #b39a72; break-inside: avoid; }
.vv-doc .vv-live-var { color: #8fc98f; border-color: #2e4a2e; }
.vv-doc .vv-unknown-var { color: #e57; border-color: #5a2a2a; }
.vv-doc-table { width: 100%; border-collapse: collapse; margin: 0 0 9px; break-inside: avoid; }
.vv-doc-table th { text-align: left; font-size: 9px; text-transform: uppercase; letter-spacing: .07em;
color: #4a4a4a; border-bottom: 1px solid #2a2a2a; padding: 3px 6px 3px 0; }
.vv-doc-table td { font-size: 11px; color: #999; border-bottom: 1px solid #1a1a1a;
padding: 4px 6px 4px 0; vertical-align: top; }
.vv-doc-code { background: #0d0d0d; border: 1px solid #222; border-radius: 3px; padding: 7px 9px;
font-size: 11px; color: #9ab; overflow-x: auto; break-inside: avoid; }
.vv-info-divider { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: #444;
padding: 10px 12px 4px; border-top: 1px solid #2a2a2a; margin-top: 2px; }
/* How do I use this — pinned at top of suggestions panel */
#vv-how-to-use {
position: sticky;
top: 0;
z-index: 3;
background: #1e1e1e;
border-bottom: 1px solid #333;
}
/* Run-status dot colours (tree + activity list) */
.vv-stat-ok { color: #4caf50; }
.vv-stat-warn { color: #ff9800; }
.vv-stat-error{ color: #f44336; }
.vv-stat-skip { color: #607d8b; }
.vv-stat-none { color: #444; }
/* Cron humanizer hint — left of cron input; first to collapse under space pressure */
.vv-cron-hint { font-size: 10px; color: #505050; white-space: nowrap;
flex: 0 10 auto; min-width: 0; max-width: 130px;
overflow: hidden; text-overflow: ellipsis;
pointer-events: none; user-select: none; }
/* Recent Activity list */
.vv-activity-list { display: flex; flex-direction: column; }
.vv-activity-row { display: flex; align-items: center; gap: 6px; padding: 4px 0;
border-bottom: 1px solid #1a1a1a; font-size: 11px; cursor: pointer; }
.vv-activity-row:last-child { border-bottom: none; }
.vv-activity-row:hover .vv-activity-label { color: #fff; }
.vv-activity-dot { flex-shrink: 0; font-size: 9px; }
.vv-activity-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
white-space: nowrap; color: #ccc; }
.vv-activity-ago { color: #555; font-size: 10px; white-space: nowrap; flex-shrink: 0; }
.vv-activity-dur { color: #444; font-size: 10px; white-space: nowrap; flex-shrink: 0;
min-width: 32px; text-align: right; }
/* Hands a run straight to the assistant. Hidden until the row is hovered — every row carries one
and shown always they read as the point of the list, which is the run history, not the AI. */
.vv-activity-ask { flex-shrink: 0; visibility: hidden; font: inherit; font-size: 10px;
color: #5a7a8a; background: #12191d; border: 1px solid #24343d;
border-radius: 3px; padding: 1px 6px; cursor: pointer; }
.vv-activity-row:hover .vv-activity-ask { visibility: visible; }
.vv-activity-ask:hover { color: #8fb0c4; border-color: #2d4a6a; }
.vv-activity-ask.vv-ask-bad { color: #c88; border-color: #4a2a2a; background: #1d1212; }
.vv-activity-row:focus-within .vv-activity-ask { visibility: visible; }
/* Log search */
#vv-log-search { width: 120px; font-size: 11px; padding: 2px 6px;
background: #111; border: 1px solid #333; color: #ccc;
border-radius: 3px; font-family: monospace; }
#vv-log-search:focus { border-color: #555; outline: none; }
mark { background: #5d4037; color: #ffcc80; border-radius: 2px; }
.vv-log-dim { opacity: 0.2; }
/* Cron Calculator */
.vv-calc-wrap { display: flex; flex-direction: column; gap: 8px; }
.vv-calc-in { width: 100%; background: #111; border: 1px solid #333; color: #ccc;
padding: 5px 8px; border-radius: 3px; font-family: monospace; font-size: 12px;
box-sizing: border-box; }
.vv-calc-in:focus { border-color: #555; outline: none; }
.vv-calc-expr { font-family: monospace; font-size: 13px; color: #7cb8e8;
background: #0d1117; padding: 4px 8px; border-radius: 3px; }
.vv-calc-desc { font-size: 12px; color: #aaa; padding: 2px 2px 0; }
.vv-calc-hint { font-size: 11px; color: #555; font-style: italic; }
.vv-calc-runs-lbl { font-size: 10px; color: #555; text-transform: uppercase;
letter-spacing: .05em; margin-top: 4px; }
.vv-calc-runs { display: flex; flex-direction: column; gap: 2px; }
.vv-calc-run-row { display: flex; gap: 8px; font-size: 11px; }
.vv-calc-run-in { color: #4caf50; white-space: nowrap; min-width: 56px; }
.vv-calc-run-at { color: #666; }
.vv-calc-apply-btn { align-self: flex-start; margin-top: 2px; }
/* Board blocks — Next Runs, Errors, Locks, Partner, Disabled */
.vv-board-placeholder { color: #555; font-size: 11px; padding: 3px 0; }
.vv-hdr-badge { display: inline-block; padding: 1px 7px; border-radius: 10px;
font-size: 10px; font-weight: bold; flex-shrink: 0; }
.vv-hdr-badge-red { background: #7f0000; color: #ef9a9a; }
.vv-hdr-badge-orange { background: #5d2000; color: #ffcc80; }
.vv-hdr-badge-gray { background: #2a2a2a; color: #aaa; }
/* Next Runs */
.vv-nextrun-list { display: flex; flex-direction: column; }
.vv-nextrun-row { display: flex; align-items: center; gap: 8px; padding: 4px 0;
border-bottom: 1px solid #1a1a1a; font-size: 12px; }
.vv-nextrun-row:last-child { border-bottom: none; }
.vv-nr-label { color: #ccc; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vv-nr-cron { color: #555; font-family: monospace; font-size: 10px; flex-shrink: 0; }
.vv-nr-in { color: #4caf50; font-size: 11px; white-space: nowrap; flex-shrink: 0; }
.vv-nr-at { color: #666; font-size: 11px; white-space: nowrap; flex-shrink: 0; }
/* Errors */
.vv-errors-list { display: flex; flex-direction: column; gap: 1px; }
.vv-err-row { padding: 5px 0; border-bottom: 1px solid #1a1a1a; }
.vv-err-row:last-child { border-bottom: none; }
.vv-err-top { display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px; }
.vv-err-script { color: #e07070; font-size: 11px; font-weight: bold; }
.vv-err-age { color: #555; font-size: 10px; flex: 1; padding-left: 6px; white-space: nowrap; }
.vv-ack-btn { margin-left: auto; font-size: 10px; padding: 1px 6px;
color: #555; border-color: #333; flex-shrink: 0; }
.vv-ack-btn:hover { color: #aaa; border-color: #555; }
.vv-err-line { color: #888; font-size: 11px; word-break: break-all; line-height: 1.4; }
/* The error text opens the log at that line. Underlined on hover only — a permanently decorated
line of log output is harder to read, and this block exists to be read first. */
.vv-err-line-open { cursor: pointer; }
.vv-err-line-open:hover { color: #ccc; text-decoration: underline; text-decoration-color: #4a4a4a; }
/* The line the operator was sent to. Left bar rather than a full highlight: the log is dense and
a filled background over one wrapped line reads as a block of colour, not a pointer. */
.vv-log-jump { background: #23303a; color: #dfe8ee; border-left: 3px solid #4a7ea0;
padding-left: 5px; margin-left: -8px; display: inline-block; width: calc(100% + 3px); }
/* Locks */
.vv-locks-list { display: flex; flex-direction: column; }
.vv-lock-row { display: flex; align-items: center; gap: 8px; padding: 4px 0;
border-bottom: 1px solid #1a1a1a; font-size: 12px; }
.vv-lock-row:last-child { border-bottom: none; }
.vv-lk-name { color: #e8a87c; flex: 1; }
.vv-lk-age { color: #777; font-size: 11px; white-space: nowrap; }
.vv-lock-clear { font-size: 11px !important; padding: 1px 7px !important;
border-color: #b71c1c !important; color: #ef9a9a !important; }
.vv-lock-clear:hover { background: #7f0000 !important; color: #fff !important; }
/* Partner */
.vv-partner-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 12px; }
.vv-partner-name { color: #ccc; }
.vv-partner-detail { color: #666; font-size: 11px; }
.vv-partner-down { color: #f44336 !important; }
/* Disabled scripts */
.vv-disabled-list { display: flex; flex-direction: column; gap: 1px; }
.vv-disabled-row { display: flex; align-items: center; gap: 8px; padding: 3px 0;
border-bottom: 1px solid #1a1a1a; font-size: 12px; }
.vv-disabled-row:last-child { border-bottom: none; }
.vv-disabled-name { color: #888; flex: 1; }
.vv-disabled-grp { color: #444; font-size: 10px; font-family: monospace; white-space: nowrap; }
/* Notification board */
.vv-nb-board { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
padding: 7px 10px; background: #141414; border-bottom: 1px solid #222;
font-size: 12px; min-height: 34px; }
.vv-nb-stat { color: #aaa; }
.vv-nb-sep { color: #444; }
.vv-nb-running { color: #f0a040; }
.vv-nb-conf-btns { display: flex; gap: 6px; margin-left: auto; }
.vv-nb-conf-btn { font-size: 11px; font-family: monospace; }
/* Advanced mode button */
.vv-adv-mode-btn { border: 1px solid #555; color: #999; transition: background 0.15s, color 0.15s, border-color 0.15s; }
.vv-adv-mode-btn:hover { border-color: #888; color: #fff; }
.vv-adv-mode-btn.vv-adv-mode-on { background: #1565c0; border-color: #1565c0; color: #fff; }
/* Script browser in suggestions panel */
.vv-sb-desc { font-size: 12px; color: #888; margin: 4px 0 6px; line-height: 1.5; }
.vv-sb-child-desc { margin-left: 16px; }
.vv-sb-hdr { font-family: monospace; font-size: 11px; color: #666; white-space: pre-wrap;
word-break: break-word; background: none; border: none; margin: 4px 0 8px;
padding: 0; line-height: 1.5; border-left: 2px solid #222; padding-left: 8px; }
.vv-sb-full { font-family: monospace; font-size: 11px; color: #888; white-space: pre-wrap;
word-break: break-word; background: #0a0a0a; border: 1px solid #222;
border-radius: 3px; margin: 6px 0 8px; padding: 8px 10px; line-height: 1.5;
max-height: 480px; overflow-y: auto; }
.vv-sb-child-block { border-top: 1px solid #1a1a1a; margin-top: 8px; padding-top: 8px; }
.vv-sb-child-name { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; flex-wrap: wrap; }
/* README content display */
.vv-readme-body { font-family: monospace; font-size: 11px; color: #777; white-space: pre-wrap;
word-break: break-word; background: none; border: none; margin: 0;
padding: 0 4px; line-height: 1.6; }
/* Script browser tree rows */
#vv-sb-tree { padding: 0; }
.vv-sb-entry { }
.vv-sb-row { display: flex; align-items: center; gap: 6px; padding: 5px 6px;
cursor: pointer; border-radius: 3px; user-select: none;
transition: background 0.1s, box-shadow 0.1s; }
.vv-sb-row:hover { background: rgba(255,255,255,0.04); }
.vv-sb-selected { background: rgba(100,149,237,0.14) !important;
outline: 1px solid rgba(100,149,237,0.4);
box-shadow: inset 3px 0 0 #6495ed; }
.vv-sb-orch-row { border-bottom: 1px solid #1c1c1c; }
.vv-sb-child-row { padding-left: 2px; }
.vv-sb-expand { width: 14px; flex-shrink: 0; color: #555; font-size: 10px; text-align: center; }
.vv-sb-expand:hover { color: #aaa; }
.vv-sb-leaf { cursor: default; pointer-events: none; }
.vv-sb-name { flex: 1; font-size: 13px; color: #b0c4d0; min-width: 0;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vv-sb-orch-row .vv-sb-name { font-weight: bold; color: #9ab; }
.vv-sb-children { padding-left: 10px; }
.vv-sb-child-indent { width: 14px; flex-shrink: 0; color: #333; font-size: 11px;
text-align: center; pointer-events: none; }
.vv-sb-badge { flex-shrink: 0; font-size: 11px; }
.vv-sb-cron { color: #555; background: #111; border: 1px solid #222;
padding: 0 4px; border-radius: 2px; font-size: 10px;
font-family: monospace; flex-shrink: 0; }
.vv-sb-status { font-size: 10px; flex-shrink: 0; }
/* Script info content area */
.vv-si-hdr { font-family: monospace; font-size: 12px; color: #4d894d; white-space: pre-wrap;
word-break: break-word; background: none; border: none; margin: 0;
padding: 8px 12px; line-height: 1.6; }
.vv-si-src { font-family: monospace; font-size: 11px; white-space: pre-wrap;
word-break: break-word; background: none; border: none; margin: 0;
padding: 8px 12px; line-height: 1.5; }
/* Cog settings button next to script name */
.vv-cog-btn { cursor:pointer; color:#444; font-size:.85em; margin-right:4px;
line-height:1; vertical-align:middle; user-select:none; }
.vv-cog-btn:hover { color:#aaa; }
/* Enriched script info blocks (advanced mode: header + docs + config) */
.vv-sinfo-block { border-top: 1px solid #222; padding: 0; }
.vv-sinfo-block:first-child { border-top: none; }
.vv-sinfo-lbl { font-size: 10px; font-weight: bold; text-transform: uppercase;
letter-spacing: .06em; color: #555; padding: 6px 12px 2px; }
/* Syntax highlight tokens — dark theme (VSCode-inspired) */
.vv-hl-sep { color: #2d2d2d; }
.vv-hl-shebang { color: #4a4a4a; }
.vv-hl-hash { color: #4a7340; }
.vv-hl-comment { color: #6a9955; }
.vv-hl-section { color: #9cdcfe; font-weight: bold; letter-spacing: 0.04em; }
.vv-hl-key { color: #9cdcfe; }
.vv-hl-value { color: #ce9178; }
.vv-hl-cron { color: #d7ba7d; font-weight: bold; }
.vv-hl-text { color: #4d894d; }
.vv-hl-keyword { color: #569cd6; }
.vv-hl-builtin { color: #4ec9b0; }
.vv-hl-string { color: #ce9178; }
.vv-hl-var { color: #d7ba7d; }
.vv-hl-number { color: #b5cea8; }
.vv-hl-op { color: #808080; }
/* Log panel */
.vv-log-panel { margin-top: 10px; border-top: 1px solid #333; padding-top: 8px; }
.vv-log-toolbar { display: flex; justify-content: space-between; align-items: center;
flex-wrap: wrap; gap: 4px; margin-bottom: 4px; }
.vv-log-ts { font-size: 11px; color: #666; }
.vv-log-pre { background: #0d0d0d; border: 1px solid #333; border-radius: 4px;
padding: 10px 12px; margin: 0; font-family: monospace; font-size: 12px;
color: #ccc; white-space: pre-wrap; word-break: break-all;
max-height: 340px; overflow-y: auto; line-height: 1.5;
scroll-behavior: auto; }
/* Toggle switch */
.vv-toggle { position: relative; display: inline-block; width: 36px; height: 20px; flex-shrink: 0; }
.vv-toggle input { opacity: 0; width: 0; height: 0; }
.vv-slider { position: absolute; inset: 0; background: #444; border-radius: 20px; cursor: pointer;
transition: 0.2s; }
.vv-slider:before { content: ''; position: absolute; width: 14px; height: 14px; left: 3px; bottom: 3px;
background: #fff; border-radius: 50%; transition: 0.2s; }
.vv-toggle input:checked + .vv-slider { background: #4caf50; }
.vv-toggle input:checked + .vv-slider:before { transform: translateX(16px); }
/* Config editor */
#vv-conf-tabs { display: flex; gap: 4px; margin-bottom: 8px; }
.vv-conf-tab { padding: 4px 12px; text-decoration: none; color: #aaa;
border: 1px solid #444; border-radius: 4px; font-size: 13px; }
.vv-conf-tab.active { color: #fff; background: #333; border-color: #666; }
#vv-conf-editor { width: 100%; min-height: 500px; background: #111; color: #ddd;
border: 1px solid #444; padding: 12px; font-family: monospace;
font-size: 13px; line-height: 1.5; border-radius: 4px; box-sizing: border-box; resize: vertical; }
#vv-conf-actions { margin-top: 8px; display: flex; align-items: center; gap: 10px; }
#vv-conf-actions button { padding: 6px 18px; background: #4caf50; border: none;
color: #fff; border-radius: 4px; cursor: pointer; font-size: 14px; }
#vv-conf-actions button:hover { background: #388e3c; }
#vv-conf-status { font-size: 13px; color: #aaa; }
/* Docs */
#vv-docs { display: flex; gap: 16px; }
#vv-docs-sidebar { width: 220px; flex-shrink: 0; }
#vv-docs-sidebar h3 { font-size: 12px; text-transform: uppercase; color: #888; margin: 0 0 8px; }
#vv-docs-sidebar ul { list-style: none; padding: 0; margin: 0; }
#vv-docs-sidebar li { margin: 2px 0; }
#vv-docs-sidebar a { display: block; padding: 3px 8px; font-size: 12px; color: #aaa;
text-decoration: none; border-radius: 3px; }
#vv-docs-sidebar a:hover { background: #222; color: #fff; }
#vv-docs-sidebar a.active { background: #333; color: #fff; }
#vv-docs-content { flex: 1; min-width: 0; }
.vv-doc-body { background: #1a1a1a; border: 1px solid #444; border-radius: 6px;
padding: 20px; line-height: 1.7; }
.vv-doc-body h1, .vv-doc-body h2, .vv-doc-body h3 { color: #ddd; }
.vv-doc-body code { background: #111; padding: 1px 5px; border-radius: 3px; font-size: 12px; }
.vv-doc-body pre { background: #111; padding: 12px; border-radius: 4px; overflow-x: auto; }
.vv-doc-hint { font-size: 12px; color: #666; margin-top: 8px; }
/* Media stream sessions */
.vv-stream-servers { display: flex; justify-content: space-between; align-items: center;
flex-wrap: nowrap; gap: 8px; margin-bottom: 10px; }
/* Left side: server badges + media type */
.vv-stream-left { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; flex-shrink: 0; }
/* Right side: device / resolution / codec chip groups */
.vv-stream-right { display: flex; align-items: center; gap: 0; flex-wrap: nowrap; flex-shrink: 0; }
.vv-server-badge { background: #333; border: 1px solid #555; color: #aaa;
font-size: 10px; padding: 1px 7px; border-radius: 10px; }
.vv-server-badge-sm { font-size: 9px; padding: 1px 6px; flex-shrink: 0; }
/* Chip groups — server badge row */
.vv-device-sep { color: #2a2a2a; font-size: 12px; margin: 0 2px; user-select: none; }
/* shared chip geometry */
.vv-device-chip,
.vv-chip-device, .vv-chip-res, .vv-chip-codec, .vv-chip-mtype {
font-size: 10px; padding: 1px 7px; border-radius: 10px;
white-space: nowrap; border: 1px solid; }
/* media type — purple */
.vv-chip-mtype { color: #9a6abf; background: #1a0d2e; border-color: #3a1e55; }
/* device — blue */
.vv-chip-device { color: #5a9ec8; background: #0d1e2e; border-color: #1c3f5c; }
/* resolution — teal */
.vv-chip-res { color: #4aaa9a; background: #0b1e1c; border-color: #1a4540; }
/* codec — amber */
.vv-chip-codec { color: #b38820; background: #201500; border-color: #483300; }
/* legacy fallback */
.vv-device-chip { color: #666; background: #181818; border-color: #252525; }
/* chip group wrappers — inline so they flow with the badge row */
.vv-chip-group-device, .vv-chip-group-res, .vv-chip-group-codec { display: contents; }
.vv-stream-empty { color: #555; font-style: italic; font-size: 12px; margin: 4px 0; }
.vv-stream-empty span { font-size: 11px; color: #444; }
.vv-stream-row { margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #282828; }
.vv-stream-row:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
.vv-stream-top { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.vv-stream-icon { font-size: 10px; color: #888; flex-shrink: 0; }
.vv-stream-title { flex: 1; font-size: 12px; color: #ddd; font-weight: 500;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vv-stream-meta { display: flex; gap: 10px; flex-wrap: wrap; font-size: 10px;
color: #666; margin-bottom: 5px; }
.vv-stream-user { color: #888; }
.vv-stream-client { color: #555; }
.vv-stream-method { font-weight: 500; }
.vv-stream-time { color: #555; margin-left: auto; }
.vv-stream-bar { height: 3px; background: #1a1a1a; border-radius: 2px; overflow: hidden; }
.vv-stream-bar div { height: 100%; border-radius: 2px; transition: width 0.4s; }
/* Live var substitution colours */
code.vv-live-var { color: #4caf50; background: #0d1f0d; }
code.vv-unknown-var { color: #ff9800; background: #1f130d; }
/* ── Arrange mode ─────────────────────────────────────────────────────────── */
.vv-drag-handle { cursor: grab; color: #555; font-size: 14px; padding: 0 5px 0 0; user-select: none; flex-shrink: 0; }
.vv-drag-handle:hover { color: #888; }
.vv-drag-handle:active { cursor: grabbing; color: #aaa; }
/* Dragged item: semi-transparent with a dashed ring so you still see what you grabbed */
.vv-drag-ghost { opacity: 0.4; outline: 1px dashed #555; border-radius: 4px; }
/* Drop insertion line: blue glow to match selection accent */
.vv-drop-line { height: 2px; background: #6495ed; border-radius: 2px; margin: 2px 0;
pointer-events: none; box-shadow: 0 0 6px rgba(100,149,237,0.7); }
.vv-arrange-active .vv-children { min-height: 28px; border: 1px dashed #2a2a2a; border-radius: 4px;
padding: 4px 2px; transition: border-color 0.12s, background 0.12s; }
/* Drop targets use blue to match selection theme */
.vv-arrange-active .vv-children.vv-drop-target { border-color: #6495ed; background: rgba(100,149,237,0.07); }
.vv-arrange-btn-active { background: #1a3a1e !important; color: #4caf50 !important; border-color: #2d5c33 !important; }
/* Grabbing cursor while dragging anything */
.vv-is-dragging, .vv-is-dragging * { cursor: grabbing !important; }
.vv-arrange-save-btn { background: #1a3a1e; border-color: #2d5c33; color: #4caf50; }
.vv-arrange-save-btn:hover { background: #22502a; }
#vv-arrange-btn { background: #7b1fa2; border-color: #7b1fa2; }
#vv-arrange-btn:hover { background: #4a148c; border-color: #4a148c; }
/* ── Arrange workspace panel ─────────────────────────────────────────────── */
.vv-arrange-ws-hdr { font-size: 11px; font-weight: bold; color: #888; text-transform: uppercase;
letter-spacing: 0.6px; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; }
#vv-pending-badge { background: #ff9800; color: #000; font-size: 10px; padding: 1px 7px;
border-radius: 10px; font-weight: bold; }
.vv-arrange-pending-hdr { font-size: 10px; color: #555; text-transform: uppercase; letter-spacing: 0.5px;
margin-bottom: 5px; }
.vv-pending-row { display: flex; align-items: center; gap: 8px; padding: 3px 0;
font-size: 11px; border-bottom: 1px solid #1e1e1e; }
.vv-pending-script { color: #ddd; font-weight: 500; }
.vv-pending-arrow { color: #555; font-size: 10px; }
.vv-library-zone { border: 1px dashed #2a2a2a; border-radius: 4px; padding: 6px;
min-height: 60px; transition: border-color 0.12s, background 0.12s; }
.vv-library-zone.vv-drop-target { border-color: #ef5350; background: rgba(239,83,80,0.09);
box-shadow: inset 0 0 8px rgba(239,83,80,0.08); }
.vv-arrange-drop-hint { font-size: 10px; color: #444; text-align: center; padding: 2px 0 7px; }
.vv-lib-card { background: #1c1c1c; border: 1px solid #2e2e2e; border-radius: 3px;
padding: 4px 8px; margin-bottom: 4px; cursor: grab; display: flex;
align-items: center; justify-content: space-between; gap: 8px; }
.vv-lib-card:hover { border-color: #444; }
.vv-lib-card.vv-drag-ghost { opacity: 0.35; }
.vv-lib-card-name { font-size: 16px; color: #ccc; font-weight: bold; }
.vv-lib-card-path { font-size: 10px; color: #444; font-family: monospace; }
/* ── Custom script folders ────────────────────────────────────────────────── */
.vv-folder-group { margin-bottom: 1px; }
.vv-folder-row { display: flex; align-items: center; gap: 6px; padding: 3px 6px;
cursor: pointer; border-radius: 3px; color: #888; font-size: 12px; user-select: none; }
.vv-folder-row:hover { background: #1e1e1e; }
.vv-folder-chevron { font-size: 10px; color: #555; width: 10px; flex-shrink: 0; }
.vv-folder-name { flex: 1; font-weight: 500; color: #aaa; }
.vv-folder-count { font-size: 10px; color: #555; background: #1c1c1c;
padding: 0 5px; border-radius: 8px; border: 1px solid #2a2a2a; }
.vv-folder-children { padding-left: 12px; min-height: 4px; }
.vv-folder-children.vv-drop-target { background: rgba(100,149,237,0.07); border-radius: 4px;
outline: 1px dashed rgba(100,149,237,0.4); }
.vv-folder-new-row { display: flex; align-items: center; gap: 6px; padding: 4px 6px; }
.vv-new-folder-btn { background: #0277bd !important; border: none !important; color: #fff !important; }
.vv-new-folder-btn:hover { background: #01579b !important; }
/* ── Snapshot footer (right panel status bar) ────────────────────────────── */
.vv-snap-footer { display: flex !important; flex-direction: row !important;
align-items: center !important; justify-content: center; gap: 20px; flex-wrap: wrap; }
.vv-snap-item { display: flex; align-items: center; gap: 7px; }
.vv-snap-label { font-size: 12px; color: #555; text-transform: uppercase; letter-spacing: 0.05em; }
.vv-snap-bar { width: 90px; height: 8px; background: #222; border-radius: 4px; overflow: hidden; flex-shrink: 0; }
.vv-snap-bar span { display: block; height: 100%; border-radius: 4px; width: 0;
transition: width 0.5s, background-color 0.5s; }
.vv-snap-val { font-size: 15px; color: #aaa; font-family: monospace; min-width: 36px; }
.vv-snap-div { color: #333; font-size: 15px; }
.vv-snap-state { font-size: 15px; font-weight: bold; }
#vv-snap-partner { font-size: 15px; color: #666; }
.vv-snap-media { font-size: 15px; color: #666; }
/* ── Containers and VMs card ──────────────────────────────────────────────── */
.vv-df-section-hdr { font-size: 10px; font-weight: bold; color: #555; text-transform: uppercase;
letter-spacing: 0.08em; padding: 4px 2px 5px; border-bottom: 1px solid #222;
margin-bottom: 4px; }
.vv-df-empty { font-size: 12px; color: #555; font-style: italic; padding: 4px 2px 8px; }
.vv-df-vm-row { display: flex; align-items: center; gap: 8px; padding: 5px 2px;
border-bottom: 1px solid #1a1a1a; }
.vv-df-vm-row:last-of-type { border-bottom: none; }
.vv-df-vm-icon { font-size: 15px; line-height: 1; flex-shrink: 0; }
.vv-df-vm-meta { font-size: 10px; color: #555; }
.vv-df-cols { display: flex; gap: 10px; align-items: flex-start; }
.vv-df-col { flex: 1; min-width: 0; }
#vv-docker-folders-body { overflow-x: hidden; }
.vv-df-folder { border-bottom: 1px solid #1a1a1a; }
.vv-df-folder:last-child { border-bottom: none; }
.vv-df-folder-hdr { display: flex; align-items: center; gap: 6px; padding: 5px 4px;
cursor: pointer; user-select: none; border-radius: 3px; }
.vv-df-folder-hdr:hover { background: rgba(255,255,255,0.03); }
.vv-df-chevron { color: #555; font-size: 10px; width: 10px; flex-shrink: 0; }
.vv-df-fname { flex: 1; font-size: 12px; color: #aaa; font-weight: 500;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vv-df-folder-body { padding-left: 10px; padding-bottom: 3px; }
.vv-df-container { display: flex; align-items: center; gap: 7px; padding: 3px 6px;
cursor: pointer; border-radius: 3px; user-select: none; }
.vv-df-container:hover { background: rgba(255,255,255,0.04); }
.vv-df-active { background: rgba(100,149,237,0.1) !important;
outline: 1px solid rgba(100,149,237,0.35);
box-shadow: inset 3px 0 0 #6495ed; }
.vv-df-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.vv-df-cname { flex: 1; font-size: 12px; color: #ccc;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vv-df-status { font-size: 10px; color: #555; flex-shrink: 0; white-space: nowrap; }
.vv-df-actions { display: flex; gap: 6px; padding: 3px 6px 5px 24px; flex-wrap: wrap; }
/* ── Rsync standalone controls ────────────────────────────────────────────── */
.vv-rsync-location { width: 120px; flex-shrink: 1; min-width: 60px; font-size: 11px; font-family: monospace;
background: #111; border: 1px solid #333; color: #aaa;
padding: 2px 6px; border-radius: 3px; }
.vv-rsync-location:focus { border-color: #555; outline: none; }
.vv-rsync-location::placeholder { color: #444; }
.vv-script-args { flex: 1 1 0; min-width: 60px; max-width: 180px; font-size: 11px; font-family: monospace;
background: #111; border: 1px solid #2a2a2a; color: #aaa;
padding: 2px 6px; border-radius: 3px;
opacity: 0.3; transition: opacity 0.15s; }
.vv-script-args:hover, .vv-script-args:focus { opacity: 1; border-color: #555; outline: none; }
.vv-script-args::placeholder { color: #3a3a3a; }
.vv-rsync-save-btn { background: #1a2e1a; border-color: #2a4a2a; color: #6aaa6a; }
.vv-rsync-save-btn:hover { background: #22382a; }