/* 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: the board ─────────────────────────────────────────────────────── Only the half of the layout that is the same at every width lives here. Which cards exist, how wide each one is, what order they sit in, how many columns the board has at this width and how tall a row may be are all generated by include/monitor_board.php and arrive as --vv-cols, --vv-sp and --vv-rowdiv. Do not put a column count or a breakpoint in this file; they are arithmetic over the card floor, and that arithmetic has one home. minmax(0, 1fr), not 1fr: bare 1fr means minmax(auto, 1fr), and that auto floor resolves to the larger of min-content and min-width — one card holding an unbreakable string would push its column past its share and drag the grid out of the container. The row axis carried this guard for years; the column axis never did. min-width: 0 on the cards for the same reason, overriding the 200px .vv-card floor the flex layouts on other pages need. On this board the ladder is what guarantees a card's width, so a card defending its own floor can only overflow the track the ladder just sized for it. */ #vv-monitor { display: grid; grid-template-columns: repeat(var(--vv-cols, 8), minmax(0, 1fr)); gap: 12px; width: 100%; box-sizing: border-box; } #vv-monitor > .vv-card { grid-column: span var(--vv-sp, 1); min-width: 0; } /* 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; } /* System card: the Varaverk half is bounded, the host half is not. This card is the one with no