/* Varaverk plugin styles — inherits unRAID theme, adds plugin-specific layout */

#varaverk-wrap { padding: 10px; font-family: inherit; }

/* Tab bar
   Scrolls itself once the tabs stop fitting. Without this the row simply overflowed and the whole
   page went with it, so reaching the last tab on a phone meant dragging the entire layout
   sideways — every card, not just the bar.
   The scrollbar is hidden the way the log panes hide theirs: a visible one costs a row of height
   on a bar that is 30px tall, and the content is obviously draggable. overscroll-behavior stops a
   flick at either end of the bar from chaining out and scrolling the page instead. */
#vv-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 2px solid #444;
           align-items: flex-end; overflow-x: auto; overscroll-behavior-x: contain;
           -webkit-overflow-scrolling: touch; scrollbar-width: none; }
#vv-tabs::-webkit-scrollbar { display: none; }
/* Neither squashed nor broken across lines — a flex item's default is to shrink, which turned
   "Partnership" into three characters and an ellipsis before the bar ever decided to scroll. */
.vv-tab  { padding: 6px 16px; text-decoration: none; color: #aaa; border-radius: 4px 4px 0 0;
           flex-shrink: 0; white-space: nowrap; }
.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; }
/* One card surface for the whole plugin. #161616 on #2a2a2a was already what Settings, Watchdog,
   Arrs and Rsync drew — four pages agreeing under four different class names — while this shared
   one was still the older #1e1e1e on #444. Bringing it here is what makes them one look rather
   than two, and it is done on the appearance alone: flex and min-width stay, because the Monitor
   grid needs a 200px floor and the Arrs grid needs min-width:0, and merging those would change
   how both size their columns to fix a colour. */
.vv-card { flex: 1; min-width: 200px; background: #161616; border: 1px solid #2a2a2a;
           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; }
/* Flex items default to min-height:auto, which resolves to their content size — so a view with a
   long log in it refuses to shrink. The assistant below it is flex-shrink:0 and this panel is a
   fixed height with overflow:hidden, so whatever will not fit is not scrolled, it is clipped off
   the bottom: the assistant's own composer, which is the last thing in the panel. vvFitRight()
   sizes these explicitly and this is what lets that size actually take effect. */
#vv-sched-right > * { min-height: 0; }
#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 701–1100px) */
@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 1101–1450px) — 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: AI row ──────────────────────────────────────────────────────────
   Same eight columns and the same gap as #vv-monitor, and margin-top matches that grid's row
   gap, so the two containers read as one board. What differs is height, which is the whole
   reason it is a separate grid: no grid-auto-rows cap and no overflow:hidden on the cards, so
   the Assistant's expand control gives the transcript real room instead of growing it inside a
   box the row had already sized.

   align-items:start, not the stretch the grid above uses, so a card opts in to matching the
   Assistant rather than being dragged to its height. All three in this row opt in below; the
   default stays start so a card added later has to say so. */
#vv-monitor-ai {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 12px;
  margin-top: 12px;
  width: 100%;
  box-sizing: border-box;
  align-items: start;
}

/* Explicit placement, two rows. The left column carries AI over Tokens; Conversations and the
   Assistant span both rows, so the Assistant sets the height and the two stacked cards divide
   what it sets. This has to be written as row+column rather than the spans that were inline on
   the markup: a span says how wide, never which row, and auto-placement would drop Tokens into
   the first gap it found rather than under AI. */
/* AI fills its own row rather than sitting at the top of it. The Assistant spans both rows, and
   grid hands a spanning item's surplus height to the tracks it spans — so at Large, row 1 grows
   well past what the AI card's few lines need and the card left a gap above Tokens. Stretching is
   a no-op at the smaller sizes, where there is no surplus to take. */
#vv-ai-stats-card     { grid-column: 1 / span 1; grid-row: 1; align-self: stretch; }
#vv-ai-tokens-card    { grid-column: 1 / span 1; grid-row: 2; }
#vv-ai-chats-card     { grid-column: 2 / span 2; grid-row: 1 / span 2; }
#vv-ai-assistant-card { grid-column: 4 / span 5; grid-row: 1 / span 2; }

/* Conversations and Tokens take their height from the Assistant rather than setting their own.
   align-self overrides the row's align-items:start for these two, so they fill the track the
   Assistant defines — level at rest, and level again after expanding, since the track grows
   with it.

   They need their own scroll to do that, which Conversations did not need inside #vv-monitor:
   there it inherited a cap from `.vv-card > div { flex:1; overflow-y:auto }`. Out here both are
   content-driven, so forty saved chats — or a ledger with both hosts and a footer — would make
   the card the tallest thing in its column and set the height it is supposed to be following.
   The h3 pins and the body takes what is left, the same shape the monitor grid above uses.

   align-self alone does not finish the job, which is why vvAiRowSync() in monitor.php sets a
   max-height on both. A stretched item's own content still feeds grid track sizing — the track
   is sized from content first and stretched afterwards — so a card long enough grows the row it
   was meant to fit inside, and stretching to that row then changes nothing. The cap is measured
   from the Assistant, which is the one card here whose height is its own business. */
#vv-monitor-ai #vv-ai-chats-card,
#vv-monitor-ai #vv-ai-tokens-card {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#vv-monitor-ai #vv-ai-chats-card h3,
#vv-monitor-ai #vv-ai-tokens-card h3 { flex-shrink: 0; }
/* height:0 with flex:1 is the part that makes these follow rather than lead. flex-basis is
   already 0, so it changes nothing about the layout; what it changes is the height the body
   reports upward. Without it the card can still hand the auto-sized grid track a max-content
   height of its whole contents, and the track it was meant to fit inside grows to fit it
   instead. It grows back to fill the track through flex, then scrolls. */
#vv-monitor-ai #vv-ai-chats-card > div,
#vv-monitor-ai #vv-ai-tokens-card > div {
  flex: 1;
  height: 0;
  min-height: 0;
  overflow-y: auto;
  -ms-overflow-style: none;
  scrollbar-width: none;
}
#vv-monitor-ai #vv-ai-chats-card > div::-webkit-scrollbar,
#vv-monitor-ai #vv-ai-tokens-card > div::-webkit-scrollbar { display: none; }

/* ── AI token ledger — shared by the AI tab and the Monitor card ──────────────
   Moved out of pages/ai.php so both surfaces can draw the same rows. A tab's inline <style> is
   only present while that tab is, and the Monitor renders this ledger too. The AI panel's own
   chrome (.vv-ai-tok, the two-column split) stayed behind — it is that panel's frame, not part
   of the ledger. */
.vv-ai-hostrow { display:flex; align-items:center; gap:8px; font-size:11px; padding:4px 6px;
                 border-radius:4px; cursor:pointer; border:1px solid transparent; }
.vv-ai-hostrow:hover  { background:#141414; }
.vv-ai-hostrow.active { background:#14202c; border-color:#2d4a6a; }
.vv-ai-hostrow-n { color:#8a8a8a; }
.vv-ai-hostrow-h { color:#4a4a4a; font-family:monospace; font-size:10px; }
.vv-ai-hostrow-v { margin-left:auto; color:#c8c8c8; font-family:monospace; font-size:11px; flex-shrink:0; }
.vv-ai-hostrow-v.none { color:#3a3a3a; font-style:italic; font-family:inherit; font-size:10px; }
.vv-ai-tok-grid  { display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:12px; }
.vv-ai-tok-l { font-size:9px; letter-spacing:.08em; text-transform:uppercase; color:#4a4a4a; }
.vv-ai-tok-v { font-size:17px; font-weight:bold; color:#c8c8c8; font-family:monospace; line-height:1.3; }
.vv-ai-tok-s { font-size:10px; color:#5a5a5a; }
.vv-ai-tok-foot { margin-top:9px; padding-top:7px; border-top:1px solid #1a1a1a; font-size:10px;
                  color:#4a4a4a; display:flex; gap:14px; flex-wrap:wrap; }

/* The ledger in a 1-of-8 column. Every rule here is the same content given a sixth of the width
   it has on the AI tab: the tiles stop sitting side by side, the host id drops under its name
   instead of competing with the total for one line, and the footer stacks. */
/* Name and total keep the first line, the host id takes the second on its own. Ordered rather
   than reordered in the markup, because the AI tab wants all three on one line and this is the
   same HTML. flex-basis:100% on the id is what forces the break; without the explicit order the
   total would follow it onto a third line instead of staying beside the name. */
#vv-ai-tokens-card .vv-ai-hostrow   { flex-wrap: wrap; gap: 1px 6px; padding: 4px 5px; }
#vv-ai-tokens-card .vv-ai-hostrow-v { order: 1; }
#vv-ai-tokens-card .vv-ai-hostrow-h { order: 2; flex-basis: 100%; }
#vv-ai-tokens-card .vv-ai-tok-grid  { grid-template-columns: 1fr; gap: 9px; }
#vv-ai-tokens-card .vv-ai-tok-v     { font-size: 15px; }
#vv-ai-tokens-card .vv-ai-tok-foot  { flex-direction: column; gap: 3px; }
/* Section headings inside the card. .vv-ai-tok-l is already the 9px uppercase label this wants,
   so it is reused rather than restated — with room above it to separate the two halves. */
#vv-ai-tokens-card .vv-ai-tok-head  { margin: 11px 0 5px; }
#vv-ai-tokens-card .vv-ai-tok-head:first-child { margin-top: 0; }

/* Medium width — 4 columns, mirroring #vv-monitor's own breakpoint. The 1/2/5 spans do not
   survive the narrower grid: 5 of 4 would silently overflow the track. */
@media (max-width: 1024px) {
  #vv-monitor-ai { grid-template-columns: repeat(4, 1fr) !important; }
  #vv-ai-stats-card     { grid-column: 1 / span 1 !important; grid-row: 1 !important; }
  #vv-ai-tokens-card    { grid-column: 1 / span 1 !important; grid-row: 2 !important; }
  #vv-ai-chats-card     { grid-column: 2 / span 3 !important; grid-row: 1 / span 2 !important; }
  /* The Assistant drops to its own full-width row here. Five columns of eight is a readable
     transcript; three of four beside a list is not, and it is the card you sit and read. */
  #vv-ai-assistant-card { grid-column: 1 / span 4 !important; grid-row: 3 !important; }
}

/* Phone — single column, natural heights, page scrolls. Matching heights is meaningless once
   the cards are stacked, and the inner scroll has to go with it: on a page that already scrolls,
   a scroll region inside it is a trap for a thumb. */
@media (max-width: 480px) {
  #vv-monitor-ai { grid-template-columns: 1fr !important; }
  /* grid-row has to be released along with grid-column. The explicit rows above are the whole
     reason Tokens sits under AI, and left in place on a single-column grid they would stack
     cards into the same cell on top of each other rather than in sequence. */
  #vv-monitor-ai > .vv-card { grid-column: 1 / -1 !important; grid-row: auto !important; }
  #vv-monitor-ai #vv-ai-chats-card,
  #vv-monitor-ai #vv-ai-tokens-card { display: block; overflow: visible; }
  /* height:0 is only inert while these are flex items — as plain blocks it would collapse the
     body to nothing, so it goes back with the flex context that justified it. */
  #vv-monitor-ai #vv-ai-chats-card > div,
  #vv-monitor-ai #vv-ai-tokens-card > div { height: auto; min-height: auto; overflow-y: visible; }
}

/* 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; }
/* "No user adjustable settings" — a stated fact, not an empty region. Tagged rather than greyed
   out, because the thing being communicated is that nothing is missing. */
.vv-cf-none  { color: #9a8f6a; font-size: 12px; margin: 0; padding: 8px 10px;
               background: #1c1a12; border: 1px solid #33301f; border-left: 3px solid #7a6a3a;
               border-radius: 3px; }

/* ── Typed settings controls ──────────────────────────────────────────────────
   The controls the conf's own comments ask for: a switch for a boolean, a bounded number for a
   number, a list for a documented set of choices. Everything above renders a conf field as a
   text box, which is the honest default for a file of shell assignments and the wrong one for
   the seventy-two of them that hold true or false.

   Extensions of vv-cf-*, not a new family. The nine page-private settings vocabularies in this
   plugin exist because each page needed one control the shared set did not have and started a
   set of its own; adding the control here is what stops the tenth.

   Note vv-cf-num is already taken — it is the row-number gutter, not a number input. */
.vv-cf-ctl   { display: flex; align-items: center; gap: 8px; }
.vv-cf-ctl .vv-cf-scalar { flex: 1 1 auto; min-width: 0; }
/* Bounded, so it does not stretch to the width of a path field and invite a paragraph. */
.vv-cf-int   { max-width: 150px; flex: 0 0 auto !important; }
.vv-cf-unit  { font-size: 11px; color: #5a5a5a; flex-shrink: 0; }

/* Sliding switch, lifted from the settings page — the nicest of the six this plugin had grown,
   and the only one that reads as on or off from across a room rather than up close. */
.vv-cf-toggle { display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
                user-select: none; }
.vv-cf-track  { width: 32px; height: 18px; border-radius: 9px; background: #222; border: 1px solid #333;
                position: relative; transition: background .15s, border-color .15s; flex-shrink: 0; }
.vv-cf-track.on { background: #1a3a1a; border-color: #2d5a2d; }
.vv-cf-track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px;
                      border-radius: 50%; background: #555; transition: left .15s, background .15s; }
.vv-cf-track.on::after { left: 16px; background: #4caf50; }
/* States the value, not the setting's name — the key is already printed above it. Without this a
   switch mid-travel is the only thing saying which way it is pointing. */
.vv-cf-state  { font-size: 11px; color: #5a5a5a; font-family: monospace; }

.vv-cf-sel    { background: #111; border: 1px solid #333; color: #ddd; padding: 4px 8px;
                border-radius: 4px; font-family: monospace; font-size: 12px; max-width: 280px; }
.vv-cf-sel:focus { border-color: #555; outline: none; }
/* What the selected choice means, taken from the comment line that declared it. The confs
   already explain each option; repeating that in the page would be a second copy to drift. */
.vv-cf-opthint { font-size: 10px; color: #5a5a5a; font-style: italic; margin-top: 4px; }

/* A credential is editable and not readable. Masked rather than omitted, because a settings page
   that silently drops the fields it disapproves of is one you cannot trust to be complete. */
.vv-cf-secret { letter-spacing: .12em; }
.vv-cf-reveal { background: none; border: 1px solid #2e2e2e; color: #5a5a5a; font-size: 10px;
                padding: 3px 8px; border-radius: 3px; cursor: pointer; flex-shrink: 0; }
.vv-cf-reveal:hover { color: #aaa; border-color: #4a4a4a; }

/* ── The settings card ────────────────────────────────────────────────────────
   Emitted by vv_conf_ui_card(), so every page that shows settings shows the same object. Lives
   here rather than in each page's inline block for the reason nine page-private vocabularies
   existed in the first place: a card defined where it is used is a card that drifts. */
.vv-cf-card   { background:#161616; border:1px solid #2a2a2a; border-radius:6px;
                padding:12px 14px; margin-bottom:14px; }
.vv-cf-card-h { display:flex; align-items:center; gap:10px; cursor:pointer; user-select:none;
                flex-wrap:wrap; }
.vv-cf-card-c { color:#333; font-size:9px; transition:transform .12s; }
.vv-cf-card-h.open .vv-cf-card-c { transform:rotate(90deg); }
.vv-cf-card-l { font-size:11px; font-weight:700; color:#666; text-transform:uppercase;
                letter-spacing:.07em; }
.vv-cf-card-f { max-width:240px; cursor:text; background:#0d0d0d; border:1px solid #2a2a2a;
                border-radius:3px; color:#bbb; font-size:12px; padding:4px 8px; outline:none;
                font-family:inherit; }
.vv-cf-card-f:focus { border-color:#444; }
.vv-cf-card-s { margin-left:auto; font-size:10px; color:#444; font-family:monospace; }
.vv-cf-card-s.warn { color:#ffb74d; }
.vv-cf-card-s.ok   { color:#4caf50; }
.vv-cf-card-s.bad  { color:#ef5350; }
.vv-cf-card-save   { background:#1a2a1a; border:1px solid #2d4a2d; color:#4caf50; font-size:11px;
                     padding:5px 14px; border-radius:3px; cursor:pointer; font-family:inherit; }
.vv-cf-card-save:hover:not(:disabled) { background:#223a22; }
.vv-cf-card-save:disabled { opacity:.4; cursor:default; }
/* Scrolls itself rather than growing the page past the viewport, so Save stays reachable. */
.vv-cf-card [id$="-fields"] { max-height:60vh; overflow-y:auto; margin-top:10px; padding-right:4px; }
/* Hidden by the filter, not removed — see the note in VvConfCard. */
.vv-cf-group.vv-filtered { display:none; }

/* Touched but not yet saved. The row says so itself rather than relying on a Save button
   somewhere else having become enabled. */
.vv-cf-field.dirty { border-left-color: #6a5228; background: #14110a; }
.vv-cf-dot   { width: 5px; height: 5px; border-radius: 50%; background: #ffb74d; flex-shrink: 0;
               display: none; }
.vv-cf-field.dirty .vv-cf-dot { display: block; }
.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) ────────────────────────────────────────────────── */
/* The frame only. Everything the dock used to style for itself — its bar, input, transcript,
   question and answer rows, sources, separators, its own grow button — is the shared chat
   component's now, drawn from the same rules as the AI tab and the Monitor card. What is left is
   the box the panel puts it in. */
#vv-ai-dock { border: 1px solid #262626; border-radius: 6px; background: #0e0e0e;
              margin-top: 6px; flex-shrink: 0; padding: 6px 8px; }
/* The chip states profile and subject together here, and a long script name would otherwise push
   the action group off the end of a narrow panel. */
#vv-ai-dock .vv-ai-chip { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
/* Flashed when the subject moves under text already typed — see vvAiDockScope(). */
.vv-ai-chip-flash { animation: vvAiChipFlash .9s ease-out 2; }
@keyframes vvAiChipFlash { 0%,100% { background:#12191d; color:#5a7a8a; }
                           50%     { background:#2a2312; color:#d8b25a; } }

.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 directly beneath the notification board.
   top is the board's measured height, not a constant: the board wraps to a second line in
   Advanced mode, where the conf buttons and Git Pull join it. A hardcoded offset would let this
   slide underneath it at exactly the width where the wrap happens. vvFitRight() keeps the
   variable in step; the fallback is the board's own min-height. */
#vv-how-to-use {
  position: sticky;
  top: var(--vv-nb-h, 34px);
  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; }
/* Same size as Ack beside it, but not the same weight. Ack is the quiet, frequent action; asking
   what an error means is the rarer one and the one worth noticing on a row you do not understand,
   so it carries the assistant's blue rather than dissolving into the border. */
.vv-why-btn     { font-size: 10px; padding: 1px 6px; flex-shrink: 0;
                  color: #5c7cfa; border-color: #26324a; background: #0d1220; }
.vv-why-btn:hover { color: #8ba4ff; border-color: #3a4a6a; }
.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. Pinned above the help block: what is running and what is scheduled is the
   one thing on this panel worth seeing while reading anything else on it. Highest z-index of the
   two pinned rows because it is the topmost — #vv-how-to-use sticks directly beneath it. */
.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;
               position: sticky; top: 0; z-index: 4; }
.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; }

/* ── Profile picker ───────────────────────────────────────────────────────────
   Global rather than emitted with the chat component. It was shared out here when the Scheduler
   drew its own bar and loaded none of the component's stylesheet; that is no longer true — all
   three surfaces render the same markup now — but the picker is also used by the menus around it
   and reads more naturally beside them than inside the component's own block. */
.vv-ai-picker { position:relative; flex-shrink:0; }
.vv-ai-chip { display:inline-flex; align-items:center; gap:5px; font-size:10px; color:#5a7a8a;
              background:#12191d; border:1px solid #24343d; border-radius:3px; padding:3px 8px;
              cursor:pointer; font-family:inherit; white-space:nowrap; }
.vv-ai-chip:hover { color:#8fb0c4; border-color:#2d4a6a; }
.vv-ai-chip-c { color:#3a5a6a; font-size:8px; }
.vv-ai-picker.open .vv-ai-chip { color:#8fb0c4; border-color:#2d4a6a; }
.vv-ai-picker.open .vv-ai-chip-c { transform:rotate(180deg); }

/* Opens upward. Every picker in the plugin now sits on the composer's bottom row, so a menu
   dropping downward would fall out of the component — off the bottom of the Monitor card and
   over the help panel beneath it. Anchored to the trigger's top edge instead. */
.vv-ai-menu { display:none; position:absolute; bottom:calc(100% + 4px); left:0; z-index:60;
              min-width:250px; background:#0e0e0e; border:1px solid #2a2a2a; border-radius:5px;
              box-shadow:0 -6px 18px rgba(0,0,0,.55); overflow:hidden; }
/* Right-anchored variant for triggers near the right edge, where a left-anchored menu would run
   off the card. Used by the saved-conversations picker, whose list is unbounded — capped so a
   long history scrolls in place rather than running off the top of the viewport. */
.vv-ai-menu-r { left:auto; right:0; max-height:min(60vh,420px); overflow-y:auto; }
.vv-ai-picker.open .vv-ai-menu { display:block; }
.vv-ai-opt { display:block; width:100%; text-align:left; background:none; border:none;
             border-bottom:1px solid #1a1a1a; padding:7px 10px; cursor:pointer;
             font-family:inherit; }
.vv-ai-opt:last-child { border-bottom:none; }
.vv-ai-opt:hover { background:#152238; }
.vv-ai-opt.active { background:#12191d; }
.vv-ai-opt.active .vv-ai-opt-l { color:#9bd; }
.vv-ai-opt-l { display:block; font-size:11px; color:#b8b8b8; }
.vv-ai-opt-h { display:block; font-size:10px; color:#4a4a4a; line-height:1.4; margin-top:2px; }
/* Loading, empty and error in the saved-conversations menu: one line in the menu's own voice,
   styled so it does not read as a row you might try to click. */
.vv-ai-hist-msg { font-size:10px; color:#4a4a4a; font-style:italic; padding:9px 10px; }
