diff --git a/themes/theme-theraiwy-dark.css b/themes/theme-theraiwy-dark.css index 662ee2e..0ef3398 100644 --- a/themes/theme-theraiwy-dark.css +++ b/themes/theme-theraiwy-dark.css @@ -1,1797 +1,80 @@ /*!TheRaiwy Dark*/ /* * ProxMorph Theme: TheRaiwy Dark - * Cyber aesthetic theme for Proxmox — dark, red-accented, grid-inspired + * Cyber aesthetic theme — dark, red-accented, grid background * Version: 1.0.0 + * Based on UniFi theme framework v5.94 * - * Based on ProxMorph v2.2.23 GitHub Dark theme framework. - * Replaces Primer colors with TheRaiwy's cyber dark palette: - * #080808 body / #0d0d0d surface / #dc2626 accent - * - * TheRaiwy Cyber Dark Mode Color Palette: - * - * CANVAS (Backgrounds): - * - canvas-default: #080808 - Main page background (deep black) - * - canvas-muted: #0d0d0d - Muted/card backgrounds - * - canvas-inset: #050505 - Header, inset areas - * - canvas-subtle: #111111 - Subtle backgrounds - * - * FOREGROUND (Text): - * - fg-default: #f0ede8 - Primary text (warm white) - * - fg-muted: #b0ada8 - Secondary/muted text - * - fg-subtle: #6b6966 - Tertiary text - * - fg-onEmphasis: #ffffff - Text on colored backgrounds - * - * BORDERS: - * - border-default: #2e2e31 - Default borders - * - border-muted: rgba(46, 46, 49, 0.7) - Muted borders - * - border-subtle: rgba(240, 237, 232, 0.1) - Subtle borders - * - * ACCENT (Red): - * - accent-fg: #dc2626 - Links, accent text - * - accent-emphasis: #c62222 - Active states - * - * SUCCESS (Green): - * - success-fg: #22c55e - Success text - * - success-emphasis: #16a34a - Primary buttons - * - * BORDER RADII (UniFi-aligned): - * - radius-sm: 4px - Form inputs, checkboxes - * - radius-md: 6px - Buttons - * - radius-lg: 8px - Windows, panels, cards + * TheRaiwy Cyber Dark Palette: + * - Body: #080808 / Surface: #0d0d0d / Elevated: #111111 + * - Accent: #dc2626 (red) / Hover: #e03434 / Active: #c62222 + * - Text: #f0ede8 (warm white) / Dim: #b0ada8 / Muted: #6b6966 + * - Borders: #2e2e31 / Strong: #3a3a3d + * - Success: #22c55e / Warning: #cc9903 / Danger: #dc2626 */ /* ===================================================== CSS VARIABLES ===================================================== */ :root { - /* TheRaiwy Cyber Dark Mode Tokens */ + --trw-color-primary: #dc2626; + --trw-color-danger: #dc2626; + --trw-color-warning: #cc9903; + --trw-color-success: #22c55e; - /* CANVAS (Backgrounds) */ - --trw-canvas-default: #080808; - --trw-canvas-muted: #0d0d0d; - --trw-canvas-inset: #050505; - --trw-canvas-subtle: #111111; + /* ProxMorph semantic variables */ + --pm-accent: #dc2626; + --pm-accent-hover: #e03434; + --pm-accent-active: #c62222; - /* FOREGROUND (Text) */ - --trw-fg-default: #f0ede8; - --trw-fg-muted: #b0ada8; - --trw-fg-subtle: #6b6966; - --trw-fg-on-emphasis: #ffffff; + --pm-success: #22c55e; + --pm-warning: var(--trw-color-warning); + --pm-error: var(--trw-color-danger); - /* BORDERS */ - --trw-border-default: #2e2e31; - --trw-border-muted: rgba(46, 46, 49, 0.7); - --trw-border-subtle: rgba(240, 237, 232, 0.1); + /* Base palette */ + --pm-bg-base: #080808; + --pm-bg-surface: #0d0d0d; + --pm-bg-elevated: #111111; - /* ACCENT (Red) */ - --trw-accent-fg: #dc2626; - --trw-accent-emphasis: #c62222; - --trw-accent-muted: rgba(220, 38, 38, 0.4); - --trw-accent-subtle: rgba(220, 38, 38, 0.15); + --pm-border: #2e2e31; + --pm-border-strong: #3a3a3d; - /* SUCCESS (Green) */ - --trw-success-fg: #22c55e; - --trw-success-emphasis: #16a34a; - --trw-success-hover: #1fb954; - --trw-success-active: #22c55e; + --pm-text: #f0ede8; + --pm-text-dim: #b0ada8; + --pm-text-muted: #6b6966; + --pm-text-disabled: #5b5956; + --pm-text-bright: #ffffff; - /* DANGER (Red) */ - --trw-danger-fg: #dc2626; - --trw-danger-emphasis: #b91c1c; + --pm-hover-subtle: rgba(240, 237, 232, 0.02); + --pm-hover-medium: rgba(240, 237, 232, 0.04); + --pm-hover-strong: rgba(240, 237, 232, 0.07); - /* ATTENTION (Yellow) */ - --trw-attention-fg: #cc9903; - --trw-attention-emphasis: #a37a02; + --pm-radius-sm: 4px; + --pm-radius-md: 6px; + --pm-radius-lg: 8px; + --pm-radius-xl: 12px; - /* Select menu active - red-tinted */ - --trw-selectmenu-active: #2a0808; + --pm-focus-ring-color: rgba(220, 38, 38, 0.15); - /* Border Radii - UniFi aligned */ - --trw-radius-sm: 4px; - --trw-radius-md: 6px; - --trw-radius-lg: 8px; - - /* Hover overlay */ - --trw-hover-overlay: rgba(240, 237, 232, 0.1); - - /* Map to Proxmox widget toolkit vars */ - --pwt-panel-background: var(--trw-canvas-default); - --pwt-text-color: var(--trw-fg-default); - --pwt-gauge-default: var(--trw-accent-emphasis); - --pwt-gauge-back: #1a1a1c; - --pwt-gauge-warn: var(--trw-attention-fg); - --pwt-gauge-crit: var(--trw-danger-emphasis); - --pwt-chart-primary: var(--trw-accent-emphasis); - --pwt-chart-grid-stroke: var(--trw-border-default); + /* Proxmox widget toolkit variables */ + --pwt-panel-background: var(--pm-bg-base); + --pwt-text-color: var(--pm-text-dim); + --pwt-gauge-default: var(--pm-accent-hover); + --pwt-gauge-back: var(--pm-bg-elevated); + --pwt-gauge-warn: var(--pm-warning); + --pwt-gauge-crit: var(--pm-error); + --pwt-chart-primary: var(--pm-accent); + --pwt-chart-grid-stroke: var(--pm-border); color-scheme: dark; } /* ===================================================== - BASE / BODY - ===================================================== */ -.x-body, -.x-viewport>.x-body, -body.x-border-layout-ct, -div.x-border-layout-ct { - background-color: var(--trw-canvas-default) !important; - color: var(--trw-fg-default) !important; -} - -/* ===================================================== - LAYOUT CONTAINER RESET (Prevent ExtJS clipping) - v2.1.5: Ported from UniFi theme for consistent border handling - ===================================================== */ - -/* Tool icons - no rounded corners */ -.x-tool, -.x-tool-tool-el, -.x-tool-default, -.x-tool-img { - border-radius: 0 !important; -} - -/* Form elements - exclude from global radius, apply 6px (GitHub style) */ -.x-form-item, -.x-form-item-default, -.x-form-item-body, -.x-form-item-body-default, -.x-form-text-field-body, -.x-form-text-field-body-default, -.x-form-fieldcontainer, -.x-field, -.x-field-default, -.x-form-type-text { - border-radius: 0 !important; -} - -/* Reset layout containers that clip elements with overflow:hidden + radius */ -.x-box-layout-ct, -.x-panel-bodyWrap, -.x-panel-bodyWrap-default, -.x-autocontainer-innerCt, -.x-autocontainer-outerCt, -.x-panel.x-tabpanel-child, -.x-panel.x-box-item, -.x-box-inner, -.x-box-target, -.x-container, -.x-container-default, -.x-window .x-panel-body, -.x-window .x-window-body, -.x-window .x-window-bodyWrap { - border-radius: 0 !important; -} - -/* Reset everything inside windows to 0 - then re-apply specific radii */ -.x-window *, -.x-window .x-autocontainer-innerCt, -.x-window .x-autocontainer-outerCt, -.x-window .x-form-layout-wrap, -.x-window .x-form-layout-auto-label, -.x-window .x-form-layout-colgroup, -.x-window .x-form-layout-column, -.x-window .x-field, -.x-window .x-form-item, -.x-window .x-form-item-body { - border-radius: 0 !important; -} - -/* v2.2.0: Dialog form content padding - vertical only (horizontal causes ExtJS layout overflow). - Root cause: ExtJS uses offsetWidth for layout → CSS horizontal padding shifts form items - rightward but doesn't narrow their computed width, causing trigger wraps to overflow 16px past - the column boundary where the adjacent column's opaque background covers them. */ -.x-window .x-tabpanel-child .x-autocontainer-innerCt { - padding: 12px 0 !important; -} - -/* v2.2.17: Allow column panel bodies to show overflowed form content (e.g. trigger wraps). - overflow:visible prevents the panel's own clipping from hiding elements that extend - slightly past the panel boundary during ExtJS layout calculation. */ -.x-window .x-panel-body:not(.x-scroller) { - overflow: visible !important; -} - -/* v2.2.17: 4px side padding on column panel bodies for visual breathing room. - ExtJS reads getPaddingInfo() on panel-body when sizing child form items, so this - correctly reduces item widths by 8px total without causing any overflow. */ -.x-window .x-panel.x-box-item .x-panel-body { - padding: 0 4px !important; -} - -/* Re-apply button styling inside windows (6px) */ -.x-window .x-btn { - border-radius: var(--trw-radius-md) !important; -} - -/* Re-apply checkbox styling inside windows */ -.x-window .x-form-checkbox { - border-radius: var(--trw-radius-sm) !important; -} - -/* Re-apply form inputs inside windows (4px with split corners - UniFi style) */ -.x-window .x-form-trigger-wrap, -.x-window .x-form-trigger-wrap-default { - border-radius: var(--trw-radius-sm) !important; -} - -.x-window .x-form-text-wrap, -.x-window .x-form-text { - border-radius: var(--trw-radius-sm) 0 0 var(--trw-radius-sm) !important; -} - -.x-window .x-form-arrow-trigger { - border-radius: 0 var(--trw-radius-sm) var(--trw-radius-sm) 0 !important; -} - -/* Form trigger/text wrap - reset and re-apply */ -.x-form-trigger-wrap, -.x-form-trigger-wrap *, -.x-form-text-wrap, -.x-form-text-wrap *, -.x-form-text, -.x-form-trigger { - border-radius: 0 !important; -} - -.x-form-trigger-wrap, -.x-form-trigger-wrap-default { - border-radius: var(--trw-radius-sm) !important; - overflow: hidden !important; -} - -.x-form-text-wrap, -.x-form-text-wrap-default { - border-radius: var(--trw-radius-sm) 0 0 var(--trw-radius-sm) !important; -} - -.x-form-text, -.x-form-text-default { - border-radius: var(--trw-radius-sm) 0 0 var(--trw-radius-sm) !important; -} - -.x-form-trigger, -.x-form-trigger-default, -.x-form-arrow-trigger, -.x-form-arrow-trigger-default { - border-radius: 0 var(--trw-radius-sm) var(--trw-radius-sm) 0 !important; -} - -/* Legend items - no rounded corners */ -.x-legend-container, -.x-legend-horizontal .x-legend-item, -.x-legend-item { - border-radius: 0 !important; -} - -/* Legend color marker (dot) - keep circular */ -.x-legend-item-marker { - border-radius: 50% !important; -} - -/* Boundlist - prevent clipping (applied to parent) */ -.x-boundlist { - border-radius: var(--trw-radius-lg) !important; - overflow: hidden !important; -} - -/* Chart canvas - no rounded corners on data area */ -.x-chart-grid, -.x-chart-axis, -canvas.x-surface, -.x-chart canvas { - border-radius: 0 !important; -} - -/* Constrain autocontainer width inside windows */ -.x-window .x-autocontainer-outerCt { - max-width: 100% !important; -} - -/* Fix window header/body width consistency */ -.x-window > .x-window-header, -.x-window > .x-window-body, -.x-window > .x-window-bodyWrap, -.x-window-bodyWrap > .x-window-body { - width: 100% !important; -} - -.x-window-header > .x-box-inner, -.x-window-header > .x-box-inner > .x-box-target { - width: 100% !important; -} - -.x-window-header-title { - width: auto !important; - flex: 1 !important; - max-width: calc(100% - 30px) !important; -} - -/* ===================================================== - MASKS & OVERLAYS - ===================================================== */ -.x-mask { - background-color: rgba(1, 4, 9, 0.5) !important; -} - -.x-tool .x-mask { - backdrop-filter: blur(4px); - background-color: var(--trw-canvas-muted); - opacity: 0.6; -} - -.x-css-shadow { - box-shadow: 0 8px 24px rgba(1, 4, 9, 0.5) !important; -} - -/* ===================================================== - ICONS - Using Proxmox default colors for dark mode - v2.1.1: Restored PVE base color scheme - ===================================================== */ - -/* General icon colors - visible gray for dark backgrounds */ -.x-tree-icon-custom, -.x-grid-icon-custom, -.fa-tags::before, -.fa-file-o::before, -.fa-building::before, -.x-action-col-icon::before, -.fa-shield::before, -.fa-file-text-o::before, -.fa-clock-o::before, -.x-tab-icon-el-default, -.pve-icon-verify-lettering::after, -.x-tree-icon-leaf:not(.x-tree-icon-custom)::before, -.x-tree-icon-parent:not(.x-tree-icon-custom)::before, -.x-tree-icon-parent-expanded:not(.x-tree-icon-custom)::before, -.x-grid-filters-filtered-column .x-column-header-text::after { - color: #aaaaaa !important; -} - -/* Folder icons - invert for dark mode */ -.x-tree-icon-parent:not(.x-tree-icon-custom)::before, -.x-tree-icon-parent-expanded:not(.x-tree-icon-custom)::before { - filter: invert(90%); -} - -/* Various image-based icons - invert for visibility */ -.fa-ceph::before, -.fa-sdn::before, -.fa-network-wired::before, -.pve-itype-treelist-item-icon-cdrom, -.fa-chevron-right::before, -.x-grid-row-console, -.x-box-scroller-toolbar-default.x-box-scroller, -.x-tree-elbow-img, -.pve-itype-icon-qemu, -.x-tree-node-computer, -.x-grid-tree-node-expanded .x-tree-node-computer, -.pbs-icon-tape, -.pbs-icon-tape-drive, -.x-tree-icon-leaf:not(.x-tree-icon-custom), -.x-tree-icon-parent:not(.x-tree-icon-custom), -.x-tree-icon-parent-expanded:not(.x-tree-icon-custom) { - filter: invert(90%); -} - -/* Hardware icons */ -.pve-itype-icon-cpu, -.pve-itype-icon-cdrom, -.pve-itype-icon-memory, -.pve-itype-icon-pci, -.pve-itype-icon-serial, -.pve-itype-icon-die, -.pmx-itype-icon-processor, -.pmx-itype-icon-memory, -.pve-itype-icon-storage, -.x-tree-node-harddisk, -.x-grid-tree-node-expanded .x-tree-node-harddisk { - filter: invert(100%); -} - -/* Hardware icons — counter-invert for non-SVG icon cells */ -td.pve-itype-icon-storage .x-grid-cell-inner, -td.x-tree-node-harddisk .x-grid-cell-inner { - filter: invert(100%) !important; -} - -/* Hardware icons — hide inverted borders for non-SVG icon cells */ -td.pve-itype-icon-storage, -td.x-tree-node-harddisk { - border-color: transparent !important; -} - -/* Hardware grid icons — mask-image renders SVG icons in theme text color - Replaces filter:invert approach for pve-itype-icon-* and pmx-itype-icon-* grid cells */ -td.pve-itype-icon-cpu, -td.pve-itype-icon-cdrom, -td.pve-itype-icon-memory, -td.pve-itype-icon-pci, -td.pve-itype-icon-serial, -td.pve-itype-icon-die, -td.pmx-itype-icon-processor, -td.pmx-itype-icon-memory { - filter: none !important; - background-image: none !important; - padding-left: 0 !important; - border-color: transparent !important; -} - -td.pve-itype-icon-cpu .x-grid-cell-inner, -td.pve-itype-icon-cdrom .x-grid-cell-inner, -td.pve-itype-icon-memory .x-grid-cell-inner, -td.pve-itype-icon-pci .x-grid-cell-inner, -td.pve-itype-icon-serial .x-grid-cell-inner, -td.pve-itype-icon-die .x-grid-cell-inner, -td.pmx-itype-icon-processor .x-grid-cell-inner, -td.pmx-itype-icon-memory .x-grid-cell-inner { - padding-left: 3px !important; -} - -td.pve-itype-icon-cpu .x-grid-cell-inner::before, -td.pve-itype-icon-cdrom .x-grid-cell-inner::before, -td.pve-itype-icon-memory .x-grid-cell-inner::before, -td.pve-itype-icon-pci .x-grid-cell-inner::before, -td.pve-itype-icon-serial .x-grid-cell-inner::before, -td.pve-itype-icon-die .x-grid-cell-inner::before, -td.pmx-itype-icon-processor .x-grid-cell-inner::before, -td.pmx-itype-icon-memory .x-grid-cell-inner::before { - content: '' !important; - display: inline-block !important; - width: 18px !important; - height: 14px !important; - vertical-align: middle !important; - margin-right: 10px !important; - background-color: currentColor !important; - -webkit-mask-size: contain !important; - mask-size: contain !important; - -webkit-mask-repeat: no-repeat !important; - mask-repeat: no-repeat !important; - -webkit-mask-position: center !important; - mask-position: center !important; -} - -td.pve-itype-icon-cpu .x-grid-cell-inner::before { - -webkit-mask-image: url('/pve2/images/icon-cpu.svg') !important; - mask-image: url('/pve2/images/icon-cpu.svg') !important; -} - -td.pve-itype-icon-memory .x-grid-cell-inner::before { - -webkit-mask-image: url('/pve2/images/icon-memory.svg') !important; - mask-image: url('/pve2/images/icon-memory.svg') !important; -} - -td.pve-itype-icon-cdrom .x-grid-cell-inner::before { - -webkit-mask-image: url('/pve2/images/icon-cd-drive.svg') !important; - mask-image: url('/pve2/images/icon-cd-drive.svg') !important; -} - -td.pve-itype-icon-pci .x-grid-cell-inner::before { - -webkit-mask-image: url('/pve2/images/icon-pci.svg') !important; - mask-image: url('/pve2/images/icon-pci.svg') !important; -} - -td.pve-itype-icon-serial .x-grid-cell-inner::before { - -webkit-mask-image: url('/pve2/images/icon-serial.svg') !important; - mask-image: url('/pve2/images/icon-serial.svg') !important; -} - -td.pve-itype-icon-die .x-grid-cell-inner::before { - -webkit-mask-image: url('/pve2/images/icon-die.svg') !important; - mask-image: url('/pve2/images/icon-die.svg') !important; -} - -td.pmx-itype-icon-processor .x-grid-cell-inner::before { - -webkit-mask-image: url('../images/icon-cpu.svg') !important; - mask-image: url('../images/icon-cpu.svg') !important; -} - -td.pmx-itype-icon-memory .x-grid-cell-inner::before { - -webkit-mask-image: url('../images/icon-ram.svg') !important; - mask-image: url('../images/icon-ram.svg') !important; -} - - -/* Icon overlays - default styling */ -.x-tree-icon-custom::after, -.x-grid-icon-custom::after { - color: #aaaaaa !important; - text-shadow: -1px 0 1px rgba(0, 0, 0, 0.5); -} - -/* RUNNING VMs/CTs - Green status indicator (PVE default) */ -.x-tree-icon-custom.running::after, -.x-grid-icon-custom.running::after, -.x-treelist-item-icon.running::after { - color: rgb(33, 191, 75) !important; - text-shadow: -1px 0 1px rgba(0, 0, 0, 0.5); -} - -/* ONLINE state - Green */ -.x-tree-icon-custom.online::after, -.x-grid-icon-custom.online::after { - color: rgb(33, 191, 75) !important; - text-shadow: -1px 0 1px rgba(0, 0, 0, 0.5); -} - -/* Stopped/offline - Muted gray */ -.x-tree-icon-custom.stopped, -.x-tree-icon-custom.offline, -.x-grid-icon-custom.stopped, -.x-grid-icon-custom.offline { - color: #888888 !important; -} - -/* Unknown state - Gray */ -.x-tree-icon-custom.unknown::after, -.x-grid-icon-custom.unknown::after { - color: #888888 !important; -} - -/* ERROR states - Red (PVE default) */ -.x-tree-icon-custom.error::after, -.x-tree-icon-custom.offline::after, -.x-tree-icon-custom.ha-error::after, -.x-grid-icon-custom.error::after, -.x-grid-icon-custom.offline::after, -.x-grid-icon-custom.ha-error::after { - color: rgb(204, 24, 0) !important; - text-shadow: -1px 0 1px rgba(0, 0, 0, 0.5); -} - -/* PAUSED/SUSPENDED - Amber (PVE default) */ -.x-tree-icon-custom.paused::after, -.x-tree-icon-custom.suspended::after, -.x-tree-icon-custom.lock-suspending::after, -.x-grid-icon-custom.paused::after, -.x-grid-icon-custom.suspended::after, -.x-grid-icon-custom.lock-suspending::after { - color: rgb(204, 142, 0) !important; - text-shadow: -1px 0 1px rgba(0, 0, 0, 0.5); -} - -/* PENDING/WARNING states - Yellow (PVE default) */ -.x-tree-icon-custom.pending::after, -.x-tree-icon-custom.io-error::after, -.x-tree-icon-custom.internal-error::after, -.x-tree-icon-custom.guest-panicked::after, -.x-grid-icon-custom.pending::after, -.x-grid-icon-custom.io-error::after, -.x-grid-icon-custom.internal-error::after, -.x-grid-icon-custom.guest-panicked::after { - color: rgb(255, 204, 0) !important; - text-shadow: -1px 0 1px rgba(0, 0, 0, 0.5); -} - -/* HA MAINTENANCE - Blue (PVE default) */ -.x-tree-icon-custom.ha-maintenance::after, -.x-grid-icon-custom.ha-maintenance::after { - color: rgb(56, 146, 212) !important; - text-shadow: -1px 0 1px rgba(0, 0, 0, 0.5); -} - -/* Locked icons */ -.x-tree-icon-custom.locked::after, -.x-tree-icon-custom.lock-backup::after, -.x-tree-icon-custom.lock-migrate::after, -.x-tree-icon-custom.lock-suspended::after, -.x-grid-icon-custom.locked::after, -.x-grid-icon-custom.lock-backup::after, -.x-grid-icon-custom.lock-migrate::after, -.x-grid-icon-custom.lock-suspended::after { - color: #aaaaaa !important; -} - -/* LXC/QEMU type indicators */ -.x-tree-icon-custom.lxc::after, -.x-tree-icon-custom.qemu::after, -.x-grid-icon-custom.lxc::after, -.x-grid-icon-custom.qemu::after { - background-color: transparent; - color: #888888 !important; -} - -.x-treelist-item-icon.lxc::after, -.x-treelist-item-icon.qemu::after { - background-color: transparent; - color: #888888 !important; -} - -/* Tree expander arrows */ -.x-tree-arrows .x-tree-expander { - filter: brightness(200%); -} - -/* v2.2.18: cancel old sprite-inversion; custom CSS controls handle appearance now */ -.x-form-checkbox-default, -.x-form-radio-default, -.x-column-header-checkbox .x-column-header-checkbox::after, -.x-grid-checkcolumn::after, -.x-menu-item-checked .x-menu-item-icon-default.x-menu-item-checkbox, -.x-menu-item-unchecked .x-menu-item-icon-default.x-menu-item-checkbox { - filter: none !important; -} - -/* ===================================================== - PANELS - UniFi base radius (8px) - ===================================================== */ -.x-panel, -.x-panel-default { - border-radius: var(--trw-radius-lg) !important; - padding: 0 !important; -} - -/* Column panels — native stacked layout (Issue #23 fix) */ -.x-panel.x-column { - padding: 5px !important; - margin: 0 !important; - max-width: none !important; - box-sizing: border-box !important; -} - -/* Column panel card styling — borders for summary + chart panels */ -.x-panel.x-panel-default.x-column { - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-lg) !important; - overflow: hidden !important; -} - -/* v2.2.1: Guest status panel and Notes panel borders */ -[id^="pveGuestStatusView-"].x-panel, -[id^="pveLxcStatusView-"].x-panel, -[id^="pveQemuStatusView-"].x-panel, -[id^="pmxNotesView-"].x-panel { - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-lg) !important; -} - -.x-panel-body, -.x-panel-body-default { - background-color: var(--trw-canvas-default) !important; - color: var(--trw-fg-default) !important; - border: none !important; -} - -/* Panel headers - only bottom border, flush with edges */ -.x-panel-header, -.x-panel-header-default { - background-color: var(--trw-canvas-muted) !important; - border: none !important; - border-bottom: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-lg) var(--trw-radius-lg) 0 0 !important; - margin: 0 !important; - padding: 8px 12px !important; - width: 100% !important; - box-sizing: border-box !important; - overflow: visible !important; -} - -/* Title text — prevent border-radius clipping */ -.x-title-text, -.x-title-text-default { - overflow: visible !important; -} - -.x-panel-bodyWrap, -.x-panel-bodyWrap-default { - margin: 0 !important; - padding: 0 !important; -} - -/* Remove borders from nested panels (like gauge widgets inside Resources) */ -.x-panel-body>.x-box-layout-ct, -.x-panel-body>.x-container, -.x-panel-body>.x-box-inner, -[id*="pmxGauge"] { - border: none !important; -} - -.x-panel-header-title-default, -.x-window-header-title-default { - color: var(--trw-fg-default) !important; -} - -.x-panel-header-default .x-tool-tool-el { - background-color: transparent; -} - -.x-tool-img { - filter: brightness(175%); -} - -.x-tool-over .x-tool-img { - filter: brightness(200%); -} - -div[id^="pveResourceTree-"][id$="-body"] { - border-color: var(--trw-canvas-default) !important; -} - -/* Resource tree: remove row separators/borders */ -[id^="pveResourceTree-"].x-tree-panel td.x-grid-cell, -[id^="pveResourceTree-"].x-tree-panel .x-grid-td, -[id^="pveResourceTree-"].x-tree-panel .x-grid-cell { - border-bottom: none !important; -} - -/* Resource tree: slightly increased row spacing */ -div[id^="pveResourceTree"] .x-grid-cell { - padding-top: 3px !important; - padding-bottom: 3px !important; -} - -.x-panel-bodyWrap { - overflow: visible !important; -} - -/* ===================================================== - SPLITTERS / SEPARATORS - v2.1.1: Fixed double border issue - ===================================================== */ -.x-splitter-vertical { - background-color: transparent !important; - border-left: 1px solid var(--trw-border-default) !important; - border-right: none !important; - width: 1px !important; -} - -.x-splitter-horizontal { - background-color: var(--trw-canvas-inset) !important; - border-top: 1px solid var(--trw-border-default) !important; -} - -/* Toolbox tree (pve-nav) right border - full height */ -/* Fix: border must be on .pve-toolbar-bg (the full-height docked toolbar), - not on .x-treelist which only stretches to cover its items. - z-index: 3 needed because content toolbar (z-index: 2, same as nav) renders - on top (later in DOM), covering the nav right border. */ -.pve-toolbar-bg { - border-right: 1px solid var(--trw-border-default) !important; - z-index: 3 !important; -} - -.x-treelist.x-treelist-pve-nav { - border-right: none !important; -} - -/* ===================================================== - TOOLBARS - ===================================================== */ -.x-toolbar, -.x-toolbar-default { - background-color: var(--trw-canvas-default) !important; - border-color: var(--trw-border-default) !important; -} - -.x-toolbar-default.x-docked-top { - border: none !important; - border-bottom: 1px solid var(--trw-border-default) !important; -} - -.x-toolbar-default .x-toolbar-separator { - border-color: var(--trw-border-default); -} - -.x-toolbar-text-default { - color: var(--trw-fg-muted); -} - -/* ===================================================== - PRIMARY BUTTONS - GitHub Green (6px radius) - ===================================================== */ -.x-btn-default-small { - background-color: var(--trw-success-emphasis) !important; - border: 1px solid rgba(255, 255, 255, 0.15) !important; - border-radius: var(--trw-radius-md) !important; -} - -.x-btn-default-small .x-btn-inner { - color: var(--trw-fg-on-emphasis) !important; -} - -.x-btn-default-small.x-btn-over, -.x-keyboard-mode .x-btn-default-small.x-btn-focus { - background-color: var(--trw-success-hover) !important; -} - -.x-btn-default-small.x-btn.x-btn-disabled { - background-color: var(--trw-success-emphasis) !important; - opacity: 0.5; -} - -.x-btn-default-small.x-btn.x-btn-pressed { - background-color: var(--trw-success-active) !important; -} - -/* ===================================================== - SECONDARY/TOOLBAR BUTTONS (4px radius) - ===================================================== */ -.x-btn-default-toolbar-small { - background-color: var(--trw-canvas-subtle) !important; - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-md) !important; -} - -.x-btn-default-toolbar-small .x-btn-inner-default-toolbar-small, -.x-btn-default-toolbar-small .x-btn-icon-el-default-toolbar-small { - color: var(--trw-fg-default) !important; -} - -.x-btn-default-toolbar-small .x-btn-wrap-default-toolbar-small.x-btn-arrow-right::after, -.x-btn-default-toolbar-small .x-btn-wrap-default-toolbar-small.x-btn-split-right::after { - filter: brightness(150%); -} - -.x-btn-default-toolbar-small.x-btn-over, -.x-keyboard-mode .x-btn-default-toolbar-small.x-btn-focus { - background-color: var(--trw-canvas-subtle) !important; - border-color: var(--trw-border-default) !important; -} - -.x-btn-default-toolbar-small.x-btn.x-btn-disabled { - background-color: var(--trw-canvas-subtle) !important; - opacity: 0.5; -} - -.x-btn-default-toolbar-small.x-btn.x-btn-menu-active, -.x-btn-default-toolbar-small.x-btn.x-btn-pressed { - background-color: var(--trw-accent-emphasis) !important; - border-color: var(--trw-accent-emphasis) !important; - padding: 4px 8px !important; /* Fix #30: prevent width change on dropdown */ -} - -.x-btn-default-toolbar-small.x-btn.x-btn-pressed .x-btn-inner-default-toolbar-small, -.x-btn-default-toolbar-small.x-btn.x-btn-pressed .x-btn-icon-el-default-toolbar-small { - color: var(--trw-fg-on-emphasis) !important; -} - -/* ===================================================== - FORM ELEMENTS (4px radius) - ===================================================== */ -.x-form-trigger-default { - background-color: var(--trw-canvas-muted) !important; -} - -.x-form-text-default { - background-color: var(--trw-canvas-muted) !important; - color: var(--trw-fg-default) !important; - border-radius: var(--trw-radius-sm) !important; -} - -.x-form-trigger-wrap, -.x-form-trigger-wrap-default { - border-color: var(--trw-border-default) !important; - background-color: var(--trw-canvas-muted) !important; - border-radius: var(--trw-radius-sm) !important; -} - -.x-form-trigger-wrap-default.x-form-trigger-wrap-focus { - border-color: var(--trw-accent-emphasis) !important; - box-shadow: 0 0 0 3px var(--trw-accent-subtle) !important; -} - -.x-form-item-label-default, -.x-form-cb-label-default { - color: var(--trw-fg-default) !important; -} - -.x-form-display-field-default { - color: var(--trw-fg-muted) !important; -} - -.x-form-spinner-default { - background-color: var(--trw-canvas-muted) !important; -} - -.x-fieldset, -.x-fieldset-default { - border-color: var(--trw-border-default) !important; - border-radius: var(--trw-radius-lg) !important; -} - -.x-fieldset-header-default>.x-fieldset-header-text { - color: var(--trw-fg-default) !important; -} - -/* ===================================================== - BOUNDLIST / DROPDOWNS (4px radius) - ===================================================== */ -.x-boundlist { - background-color: var(--trw-canvas-muted) !important; - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-lg) !important; - box-shadow: 0 8px 24px rgba(1, 4, 9, 0.5); - overflow: hidden !important; -} - -.x-boundlist-item { - background-color: transparent !important; - color: var(--trw-fg-default) !important; -} - -.x-boundlist-selected { - background-color: var(--trw-accent-subtle) !important; -} - -.x-boundlist-item-over { - background-color: var(--trw-hover-overlay) !important; -} - -/* ===================================================== - GRIDS / TABLES (square corners) - ===================================================== */ -.x-grid, -.x-grid-view { - border-radius: 0 !important; -} - -.x-column-header { - border-color: var(--trw-border-default) !important; - background-color: transparent !important; -} - -.x-column-header-inner, -.x-column-header-text { - color: var(--trw-fg-default) !important; - font-weight: 600 !important; -} - -.x-column-header-trigger { - border-color: var(--trw-border-muted) !important; -} - -.x-grid-item, -.x-column-header-default, -.x-grid-cell-row-numberer { - color: var(--trw-fg-default) !important; - background-color: var(--trw-canvas-default) !important; -} - -.x-grid-cell-special { - border-color: var(--trw-border-default) !important; -} - -.x-grid-group-hd { - background-color: var(--trw-canvas-default) !important; - border-color: var(--trw-border-default) !important; -} - -.x-grid-group-title { - color: var(--trw-fg-default) !important; -} - -.x-grid-header-ct { - background-color: var(--trw-canvas-muted) !important; - border: 1px solid var(--trw-border-muted) !important; - border-radius: var(--trw-radius-lg) var(--trw-radius-lg) 0 0 !important; -} - -.x-grid-item-alt { - background-color: #0c0c0c !important; -} - -.x-grid-with-row-lines .x-grid-item { - border-color: var(--trw-border-muted) !important; -} - -.x-grid-cell { - border-bottom: 1px solid var(--trw-border-subtle) !important; -} - -.x-grid-item-over, -.x-grid-with-row-lines .x-grid-item.x-grid-item-over { - background-color: var(--trw-hover-overlay) !important; -} - -.x-grid-item-selected, -.x-grid-with-row-lines .x-grid-item.x-grid-item-selected { - background-color: var(--trw-accent-subtle) !important; -} - -.x-column-header-over, -.x-column-header-open { - background-color: var(--trw-hover-overlay) !important; -} - -.x-column-header-sort-ASC, -.x-column-header-sort-DESC { - background-color: #1c0808 !important; -} - -.x-grid-row-summary .x-grid-cell, -.x-grid-row-summary .x-grid-rowwrap, -.x-grid-row-summary .x-grid-cell-rowbody { - background-color: var(--trw-canvas-default) !important; - border-color: var(--trw-border-default); -} - -.x-grid-with-col-lines .x-grid-cell, -.x-grid-with-col-lines .x-grid-item-over .x-grid-cell, -.x-grid-with-col-lines .x-grid-item-selected .x-grid-cell { - border-color: var(--trw-border-default) !important; -} - -.x-dd-drag-proxy { - background-color: var(--trw-canvas-muted); - border-color: var(--trw-border-default); - color: var(--trw-fg-default); -} - -.x-keyboard-mode .x-grid-item-focused { - background-color: var(--trw-hover-overlay) !important; - color: var(--trw-fg-on-emphasis) !important; -} - -/* v2.2.1: Remove blue outline from selected/focused items in resource tree */ -.x-keyboard-mode .x-grid-item-focused .x-grid-cell-inner::before, -.x-keyboard-mode .x-grid-item-selected .x-grid-cell-inner::before, -.x-grid-item-selected .x-grid-cell-inner::before, -.x-grid-item-focused .x-grid-cell-inner::before, -[id^="pveResourceTree"] .x-grid-item-selected .x-grid-cell-inner::before, -[id^="pveResourceTree"] .x-grid-item-focused .x-grid-cell-inner::before { - content: none !important; - display: none !important; - border: none !important; -} - -.x-grid-empty { - background-color: var(--trw-canvas-default) !important; - color: var(--trw-fg-muted) !important; -} - -/* ===================================================== -/* ===================================================== - MENUS (variable radius) - ===================================================== */ -.x-menu, -.x-menu-default { - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-lg) !important; - box-shadow: 0 8px 24px rgba(1, 4, 9, 0.5) !important; - overflow: hidden !important; -} - -.x-menu-body-default { - background-color: var(--trw-canvas-muted) !important; -} - -.x-menu-header { - background-color: var(--trw-accent-emphasis) !important; -} - -/* Menu Layout Fix (Flexbox reordering) */ -.x-menu-item-default > .x-menu-item-link { - display: flex !important; - align-items: center !important; - flex-direction: row !important; - padding: 6px 8px !important; - line-height: 20px !important; - text-decoration: none !important; -} - -.x-menu-item-text-default { - color: var(--trw-fg-default) !important; - font-size: 14px !important; - margin-left: 0 !important; -} - -.x-menu-item-icon-default { - color: var(--trw-fg-muted) !important; - order: -1 !important; /* Move icon to start */ - position: relative !important; - float: none !important; - margin-right: 8px !important; - margin-left: 0 !important; - left: auto !important; - top: auto !important; - width: 16px !important; - text-align: center !important; -} - -/* Remove the gutter/separator line */ -.x-menu-icon-separator-default { - display: none !important; -} - -.x-menu-item-default.x-menu-item-separator { - background-color: var(--trw-canvas-muted); - border-color: var(--trw-border-default); - margin: 4px 0 !important; -} - -.x-menu-item-default.x-menu-item-focus, -.x-menu-item-default.x-menu-item-active { - background-color: var(--trw-accent-emphasis) !important; - color: var(--trw-fg-on-emphasis) !important; -} - -.x-menu-item-active .x-menu-item-text-default, -.x-menu-item-focus .x-menu-item-text-default, -.x-menu-item-active .x-menu-item-icon-default, -.x-menu-item-focus .x-menu-item-icon-default { - color: var(--trw-fg-on-emphasis) !important; -} - -/* ===================================================== - PROGRESS BARS (5px radius) - ===================================================== */ -.x-progress, -.x-progress-default { - background-color: var(--trw-canvas-subtle) !important; - border-radius: var(--trw-radius-md) !important; -} - -.x-progress-default .x-progress-bar-default { - background-color: var(--trw-accent-emphasis) !important; - border-radius: var(--trw-radius-md) !important; -} - -.x-progress-default .x-progress-text { - color: var(--trw-fg-default) !important; -} - -.x-progress.warning .x-progress-bar { - background-color: var(--pwt-gauge-warn) !important; -} - -.x-progress.critical .x-progress-bar { - background-color: var(--pwt-gauge-crit) !important; -} - -/* ===================================================== - SPLITTERS - ===================================================== */ -.x-splitter { - background-color: var(--trw-canvas-inset) !important; -} - -.x-splitter-horizontal { - background-color: var(--trw-canvas-inset) !important; - border-top: 1px solid var(--trw-border-default) !important; -} - -.x-keyboard-mode .x-splitter-focus::after { - border-color: var(--trw-accent-emphasis) !important; -} - -.x-layout-split-bottom { - opacity: 0.7; -} - -/* ===================================================== - TABS — GitHub UnderlineNav style (v2.2.21) - Flat tabs, coral ::after underline on active tab. - Uses ::after (not border-bottom — ExtJS overrides it). - ===================================================== */ -.x-tab-bar, -.x-tab-bar-default { - background-color: var(--trw-canvas-default) !important; - border-radius: 0 !important; - border-bottom: 1px solid var(--trw-border-default) !important; - padding-bottom: 0 !important; -} - -/* v2.2.23: overflow visible on ALL containers within tab bar to prevent clipping */ -.x-tab-bar .x-box-inner, -.x-tab-bar .x-box-target, -.x-tab-bar-body, -.x-tab-bar-body-default { - overflow: visible !important; -} - -/* Base tab — no margin-bottom hack, position relative, no outlines */ -.x-tab, -.x-tab-default, -.x-tab-default-top { - background-color: transparent !important; - border: none !important; - border-radius: 0 !important; - padding: 8px 16px 8px !important; - overflow: visible !important; - margin-bottom: 0 !important; - transition: color .12s ease !important; - outline: none !important; - box-shadow: none !important; -} - -/* Remove ::after from inactive tabs */ -.x-tab::after { - display: none !important; -} - -.x-tab-inner-default { - color: var(--trw-fg-muted) !important; - font-size: 13px !important; -} - -.x-tab-default.x-tab-over { - background-color: transparent !important; -} -.x-tab-default.x-tab-over .x-tab-inner-default { - color: var(--trw-fg-default) !important; -} - -/* Active tab */ -.x-tab-default.x-tab.x-tab-active { - background-color: transparent !important; - border: none !important; - overflow: visible !important; - margin-bottom: 0 !important; - outline: none !important; - box-shadow: none !important; -} - -/* v2.2.23: coral underline INSIDE the tab at bottom:0 — immune to parent clipping */ -.x-tab-default.x-tab.x-tab-active::after { - content: '' !important; - display: block !important; - position: absolute !important; - bottom: 0 !important; - left: 0 !important; - right: 0 !important; - height: 2px !important; - background: var(--trw-accent-fg) !important; - z-index: 10 !important; - border-radius: 0 !important; - pointer-events: none !important; -} - -.x-tab-active .x-tab-inner-default { - color: var(--trw-fg-default) !important; - font-weight: 600 !important; -} - -.x-tab-default.x-tab.x-tab-disabled { - background-color: transparent !important; - border: none !important; - color: var(--trw-fg-subtle) !important; - margin-bottom: 0 !important; -} - -/* Keyboard mode focus: keep the same indicator, no outline */ -.x-keyboard-mode .x-tab-default.x-tab-focus, -.x-keyboard-mode .x-tab-default.x-tab-focus.x-tab-active { - background-color: transparent !important; - border: none !important; - outline: none !important; - box-shadow: none !important; - margin-bottom: 0 !important; -} -.x-keyboard-mode .x-tab-default.x-tab-focus.x-tab-active::after { - content: '' !important; - display: block !important; - position: absolute !important; - bottom: 0 !important; - left: 0 !important; - right: 0 !important; - height: 2px !important; - background: var(--trw-accent-fg) !important; - z-index: 10 !important; - pointer-events: none !important; -} - -/* Kill ALL interaction outlines/shadows — every possible state */ -.x-tab:focus, -.x-tab *:focus, -.x-tab-focus, -.x-tab-active.x-tab-focus, -.x-tab-inner-focus, -.x-tab-button-focus, -.x-tab-pressed, -.x-tab-active.x-tab-pressed, -.x-tab-over, -.x-tab:active, -.x-tab *:active { - outline: none !important; - box-shadow: none !important; -} - -.x-tabpanel-child { - border-radius: 0 0 var(--trw-radius-lg) var(--trw-radius-lg) !important; -} - -/* ===================================================== - TOOLTIPS (6px radius) - ===================================================== */ -.x-tip, -.x-tip-default { - background-color: var(--trw-canvas-muted) !important; - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-md) !important; - box-shadow: 0 4px 12px rgba(1, 4, 9, 0.4); -} - -.x-tip-body-default { - color: var(--trw-fg-default) !important; -} - -.x-tip-form-invalid { - background-color: var(--trw-canvas-muted) !important; - border-color: var(--trw-danger-emphasis) !important; -} - -.x-tip-body-form-invalid { - color: var(--trw-danger-fg) !important; -} - -/* ===================================================== - TREE NAVIGATION (4px radius) - ===================================================== */ -.x-treelist-item { - background-color: var(--trw-canvas-default) !important; - border-radius: var(--trw-radius-md) !important; -} - -/* v2.2.4: Pseudo-element approach for balanced hover/selected highlighting */ -.x-treelist-row { - border-radius: var(--trw-radius-md) !important; - background-color: transparent !important; - position: relative !important; - z-index: 0 !important; -} - -.x-treelist-row::before { - content: ""; - position: absolute; - top: 1px; - bottom: 1px; - left: 0; - right: 4px; - border-radius: var(--trw-radius-md); - background-color: transparent; - z-index: -1; - pointer-events: none; -} - -/* v2.1.4: Fix toolbox tree item text overlapping icons (icon is 24px absolute positioned) */ -.x-treelist-item-text { - margin-left: 28px !important; -} - -/* Toolbox tree items - increased visibility */ -.x-treelist-item-text, -.x-treelist-item-icon, -.x-treelist.x-treelist-pve-nav .x-treelist-item-text, -.x-treelist.x-treelist-pve-nav .x-treelist-item-icon { - color: var(--trw-fg-default) !important; -} - -/* Hover state - apply to pseudo-element */ -.x-treelist-row-over { - background-color: transparent !important; -} - -.x-treelist-row-over::before { - background-color: var(--trw-hover-overlay) !important; -} - -.x-treelist-row-over .x-treelist-item-icon, -.x-treelist-row-over .x-treelist-item-text { - background-color: transparent !important; - color: var(--trw-fg-default) !important; -} - -/* Toolbox tree - selected/active item uses GitHub green (pseudo-element) */ -.x-treelist-item-selected>.x-treelist-row { - background-color: transparent !important; -} - -.x-treelist-item-selected>.x-treelist-row::before, -.x-treelist-item-selected>.x-treelist-row:hover::before { - background-color: var(--trw-success-emphasis) !important; -} - -.x-treelist-item-selected .x-treelist-item-text, -.x-treelist-item-selected .x-treelist-item-icon { - color: var(--trw-fg-on-emphasis) !important; -} - -.x-treelist-pve-nav { - background-color: var(--trw-canvas-default) !important; - border-color: var(--trw-border-default) !important; -} - -/* ===================================================== - WINDOWS / MODALS (variable radius) - ===================================================== */ -.x-window, -.x-window-default { - background-color: var(--trw-canvas-inset) !important; - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-lg) !important; - box-shadow: 0 8px 24px rgba(1, 4, 9, 0.5) !important; - overflow: hidden !important; -} - -.x-window .x-window-header, -.x-window-header-default { - background-color: var(--trw-canvas-muted) !important; - border-color: transparent !important; - border-radius: var(--trw-radius-lg) var(--trw-radius-lg) 0 0 !important; -} - -.x-window-header-default .x-mask { - background-color: rgba(1, 4, 9, 0.7); -} - -.x-window .x-window-body, -.x-window-body-default { - background-color: var(--trw-canvas-default) !important; - border-color: var(--trw-border-default) !important; - color: var(--trw-fg-default) !important; - border-radius: 0 0 var(--trw-radius-lg) var(--trw-radius-lg) !important; -} - -.x-window-ghost { - background-color: var(--trw-canvas-default) !important; -} - -.x-window-header-default .x-tool-img { - background-color: transparent; -} - -.x-message-box .x-window-body { - background-color: var(--trw-canvas-muted) !important; -} - -/* ===================================================== - LEGEND / CHARTS - ===================================================== */ -.x-legend-container { - background-color: var(--trw-canvas-default) !important; -} - -.x-legend-horizontal .x-legend-item { - background-color: var(--trw-canvas-muted) !important; - color: var(--trw-fg-default) !important; - border: 1px solid var(--trw-border-muted) !important; -} - -/* ===================================================== - PROXMOX-SPECIFIC - ===================================================== */ -img[id^="proxmoxlogo-"][id$="-img"], -img[id^="proxmoxLogoSvg-"][id$="-img"] { - filter: invert(1) hue-rotate(180deg); -} - -.proxmox-invalid-row { - background-color: #521414 !important; -} - -.proxmox-warning-row { - background-color: #640 !important; -} - -.proxmox-disabled-row td { - color: var(--trw-fg-subtle) !important; -} - -.pmx-hint { - background-color: #640 !important; -} - -.pmx-hint a { - color: var(--trw-accent-fg) !important; -} - -.info-blue { - color: var(--trw-accent-fg) !important; -} - -.critical { - color: var(--trw-danger-fg) !important; -} - -/* Inline buttons (Documentation, Help) - GitHub Primer dark secondary button style */ -.proxmox-inline-button { - height: 28px !important; - min-height: 28px !important; - display: flex !important; - align-items: center !important; - padding: 3px 8px !important; - background-color: var(--trw-canvas-subtle) !important; - border: 1px solid var(--trw-border-default) !important; - border-radius: var(--trw-radius-md) !important; - color: var(--trw-fg-default) !important; - transition: background 0.08s cubic-bezier(0.33, 1, 0.68, 1) !important; -} - -.proxmox-inline-button:hover, -.proxmox-inline-button.x-btn-over { - background-color: var(--trw-canvas-muted) !important; - border-color: var(--trw-fg-muted) !important; -} - -.proxmox-inline-button:active, -.proxmox-inline-button.x-btn-pressed { - background-color: var(--trw-canvas-muted) !important; -} - -.proxmox-inline-button .x-btn-inner, -.proxmox-inline-button .x-btn-icon-el { - color: var(--trw-fg-default) !important; -} - -/* Loading states */ -.x-grid-row-loading, -.x-treelist-item-loading .x-treelist-item-icon, -.x-mask-msg-text, -.x-grid-tree-loading .x-tree-icon { - filter: invert(90%); -} - -.x-mask-msg { - background-color: var(--trw-canvas-muted) !important; - border: 1px solid var(--trw-border-default) !important; -} - -/* Markdown */ -.pmx-md code { - background-color: var(--trw-canvas-muted) !important; -} - -.pmx-md pre code { - border-color: var(--trw-border-default) !important; -} - -.pmx-md a { - color: var(--trw-accent-fg) !important; -} - -/* Tags */ -.pve-edit-tag.editable span { - background-color: var(--trw-canvas-muted) !important; - color: var(--trw-fg-default) !important; - border-color: var(--trw-border-default) !important; -} - -/* Datepicker */ -.x-datepicker, -.x-datepicker-column-header, -.x-monthpicker { - background-color: var(--trw-canvas-default) !important; - color: var(--trw-fg-default) !important; - border-color: transparent !important; -} - -.x-datepicker-header, -.x-datepicker-footer, -.x-monthpicker-buttons { - background-color: var(--trw-canvas-inset) !important; -} - -.x-datepicker-date, -.x-monthpicker-item-inner { - color: var(--trw-fg-default) !important; -} - -.x-datepicker-selected div.x-datepicker-date, -.x-monthpicker-item a.x-monthpicker-selected, -a.x-monthpicker-item-inner:hover, -div.x-datepicker-date:hover { - background-color: var(--trw-hover-overlay) !important; - color: var(--trw-fg-on-emphasis) !important; -} - -/* ===================================================== - SCROLLBARS - Cyber red-accented styling - ===================================================== */ -::-webkit-scrollbar { - width: 6px; - height: 6px; -} - -::-webkit-scrollbar-track { - background: var(--trw-canvas-default); -} - -::-webkit-scrollbar-thumb { - background: rgba(220, 38, 38, 0.25); - border-radius: 3px; - transition: background .3s; -} - -::-webkit-scrollbar-thumb:hover { - background: rgba(220, 38, 38, 0.5); -} - -::-webkit-scrollbar-corner { - background: var(--trw-canvas-default); -} - -/* Firefox scrollbar styling */ -* { - scrollbar-width: thin; - scrollbar-color: rgba(220, 38, 38, 0.25) var(--trw-canvas-default); -} - -/* ===================================================== - USAGE BARS (Vertical progress indicators) - v2.1.2: Using Proxmox dark theme default #e6e6e6 - ===================================================== */ -.usage { - background-color: #e6e6e6 !important; -} - -/* ===================================================== - DROPDOWNS - GitHub profile menu styling (dark) - ===================================================== */ -.x-menu, -.x-menu-default { - background-color: var(--trw-canvas-inset) !important; /* #050505 */ - border: 1px solid var(--trw-border-muted) !important; - border-radius: 6px !important; - box-shadow: 0 8px 24px rgba(1, 4, 9, 0.8) !important; - padding: 4px !important; -} - -.x-menu-body-default { - background-color: transparent !important; - padding: 4px !important; -} - -.x-menu-header { - background-color: transparent !important; - color: var(--trw-fg-default) !important; -} - -.x-menu-item-default > .x-menu-item-link { - display: flex !important; - align-items: center !important; - flex-direction: row !important; - gap: 8px !important; - justify-content: flex-start !important; - flex-wrap: nowrap !important; - min-height: 28px !important; - border-radius: 6px !important; - padding: 6px 8px !important; - line-height: 20px !important; - border: none !important; - cursor: pointer !important; - outline: none !important; - box-shadow: none !important; - white-space: nowrap !important; -} - -.x-menu-item-text-default { - color: var(--trw-fg-default) !important; - font-size: 13px !important; -} - -.x-menu-item-icon-default { - color: var(--trw-fg-muted) !important; - order: -1 !important; - margin-left: 0 !important; - margin-right: 8px !important; - position: relative !important; - left: 0 !important; - right: auto !important; - text-align: left !important; - display: inline-flex !important; - align-items: center !important; - justify-content: center !important; - height: 20px !important; - line-height: 20px !important; - vertical-align: middle !important; - top: 1px !important; - flex: 0 0 16px !important; - width: 16px !important; - align-self: center !important; - float: none !important; -} - -.x-menu-item-text-default { - order: 1 !important; - margin-left: 0 !important; - text-align: left !important; - line-height: 20px !important; - display: inline-flex !important; - align-items: center !important; - flex: 1 1 auto !important; - width: auto !important; - white-space: nowrap !important; -} - -.x-menu-item-default > .x-menu-item-link > .x-menu-item-icon-default, -.x-menu-item-default > .x-menu-item-link > .x-menu-item-text-default { - width: auto !important; - max-width: none !important; -} - -.x-menu-item-arrow, -.x-menu-item-arrow-default { - order: 2 !important; - margin-left: auto !important; -} - -.x-menu-item-default.x-menu-item-separator { - background-color: var(--trw-border-default) !important; - border: none !important; - height: 1px !important; - margin: 6px 4px !important; -} - -.x-menu-item-default.x-menu-item-focus, -.x-menu-item-default.x-menu-item-active, -.x-menu-item:hover { - background-color: var(--trw-canvas-muted) !important; - color: var(--trw-fg-default) !important; - border-radius: 6px !important; -} - -.x-menu-item-active .x-menu-item-text-default, -.x-menu-item-focus .x-menu-item-text-default { - color: var(--trw-fg-default) !important; -} - -/* Combo dropdowns (selects, boundlists) */ -.x-boundlist { - background-color: var(--trw-canvas-inset) !important; - border: 1px solid var(--trw-border-muted) !important; - border-radius: 6px !important; - box-shadow: 0 8px 24px rgba(1, 4, 9, 0.8) !important; - padding: 2px !important; - overflow: hidden !important; -} - -.x-boundlist-item { - border-radius: 6px !important; - padding: 2px 6px !important; - line-height: normal !important; - border: none !important; - cursor: pointer !important; - outline: none !important; - box-shadow: none !important; -} - -.x-boundlist-item-over { - background-color: var(--trw-canvas-muted) !important; -} - -.x-boundlist-selected { - background-color: var(--trw-selectmenu-active) !important; /* #2a0808 */ - color: var(--trw-fg-on-emphasis) !important; -} - -/* Floating grid pickers (storage/ISO selectors) */ -.x-layer.x-grid .x-grid-view, -.x-panel.x-layer.x-grid .x-grid-view, -.x-panel.x-layer.x-grid, -.x-layer.x-panel.x-grid { - border-radius: 6px !important; -} - -.x-layer.x-grid .x-grid-item-over, -.x-layer.x-grid .x-grid-item-selected, -.x-panel.x-layer.x-grid .x-grid-item-over, -.x-panel.x-layer.x-grid .x-grid-item-selected { - border-radius: 6px !important; - outline: none !important; - box-shadow: none !important; -} - -.x-layer.x-grid .x-grid-item-over td:first-child, -.x-layer.x-grid .x-grid-item-selected td:first-child, -.x-panel.x-layer.x-grid .x-grid-item-over td:first-child, -.x-panel.x-layer.x-grid .x-grid-item-selected td:first-child { - border-radius: 6px 0 0 6px !important; -} - -.x-layer.x-grid .x-grid-item-over td:last-child, -.x-layer.x-grid .x-grid-item-selected td:last-child, -.x-panel.x-layer.x-grid .x-grid-item-over td:last-child, -.x-panel.x-layer.x-grid .x-grid-item-selected td:last-child { - border-radius: 0 6px 6px 0 !important; -} - -/* ===================================================== - UNIFI BORDER-RADIUS PARITY (ported from theme-unifi.css) + GLOBAL BORDER-BOX ROUNDED CORNERS (UniFi style) ===================================================== */ .x-border-box, .x-border-box * { - border-radius: var(--trw-radius-lg); + border-radius: var(--pm-radius-lg); } /* Remove rounded corners from grids/tables/lists (Tasks, logs) */ @@ -1812,6 +95,7 @@ table *, tr, td, th, +/* Legend elements - no rounded corners */ .x-legend, .x-legend *, .x-legend-container, @@ -1823,6 +107,7 @@ th, .x-legend-horizontal .x-legend-item:last-child, .x-legend-vertical .x-legend-item:first-child, .x-legend-vertical .x-legend-item:last-child, +/* Tool icons - no rounded corners */ .x-tool, .x-tool-tool-el, .x-tool-default, @@ -1830,7 +115,8 @@ th, border-radius: 0 !important; } -/* Form elements - exclude from global radius */ +/* Form elements - exclude from global 8px, apply 4px (UniFi style) */ +/* Reset ALL form-related parent containers to prevent 8px inheritance */ .x-form-item, .x-form-item-default, .x-form-item-body, @@ -1844,7 +130,7 @@ th, border-radius: 0 !important; } -/* Reset layout containers that clip form elements */ +/* Reset layout containers that clip form elements with overflow:hidden + 8px radius */ .x-box-layout-ct, .x-panel-bodyWrap, .x-panel-bodyWrap-default, @@ -1856,13 +142,25 @@ th, .x-box-target, .x-container, .x-container-default, +/* Window/dialog inner bodies - prevent 8px clipping on form elements */ .x-window .x-panel-body, .x-window .x-window-body, .x-window .x-window-bodyWrap { border-radius: 0 !important; } -/* Reset everything inside windows to 0 - then re-apply specific radii */ +/* Restore right border for grids inside windows (fixed v5.4 over-reach) */ +.x-window .x-panel-body.x-grid-body { + border-right: 1px solid #34383D !important; +} + +/* ===================================================== + v5.73: WINDOW/MODAL BORDER-RADIUS CONSISTENCY + Reset all children to 0, then re-apply specific radii + to ensure consistent 8px corners on login/modals + ===================================================== */ + +/* 1. Reset everything inside windows to 0 - overrides global x-border-box rule */ .x-window *, .x-window .x-autocontainer-innerCt, .x-window .x-autocontainer-outerCt, @@ -1876,29 +174,54 @@ th, border-radius: 0 !important; } -.x-window, -.x-window-default { +/* 2. Window container - consistent 8px with overflow hidden */ +.x-window { border-radius: 8px !important; + overflow: hidden !important; + min-width: 295px !important; + /* v5.85: Match Proxmox default to prevent scrollbars */ } +/* v5.86: Fix dialog header/body not matching dialog width when min-width is applied + Root cause: ExtJS sets inline width on header/body that's smaller than min-width forces. + Solution: Force header/body to use 100% width so they inherit parent's computed width. */ +.x-window > .x-window-header, +.x-window > .x-window-body, +.x-window > .x-window-bodyWrap, +.x-window-bodyWrap > .x-window-body { + width: 100% !important; +} + +/* Ensure box containers inside header use full width */ +.x-window-header > .x-box-inner, +.x-window-header > .x-box-inner > .x-box-target { + width: 100% !important; +} + +/* Header title should expand appropriately */ +.x-window-header-title { + width: auto !important; + flex: 1 !important; + max-width: calc(100% - 30px) !important; +} + +/* 3. Window header - top corners only */ .x-window-header, .x-window-header-default { border-radius: 8px 8px 0 0 !important; } -.x-window .x-window-body, -.x-window-body-default { - border-radius: 0 !important; -} - +/* 4. Re-apply button styling inside windows (6px) */ .x-window .x-btn { border-radius: 6px !important; } +/* 5. Re-apply checkbox styling inside windows (4px) */ .x-window .x-form-checkbox { border-radius: 4px !important; } +/* 6. Re-apply form inputs inside windows (4px with split corners) */ .x-window .x-form-trigger-wrap, .x-window .x-form-trigger-wrap-default { border-radius: 4px !important; @@ -1922,21 +245,31 @@ th, border-radius: 0 !important; } +/* Form element containers - 4px radius (UniFi consistent) */ .x-form-trigger-wrap, .x-form-trigger-wrap-default { border-radius: 4px !important; + overflow: hidden !important; } +/* Constrain autocontainer width (Moved from L3450) */ +.x-window .x-autocontainer-outerCt { + max-width: 100% !important; +} + +/* Form text wrap - left side rounded */ .x-form-text-wrap, .x-form-text-wrap-default { border-radius: 4px 0 0 4px !important; } +/* Form input text - left side rounded */ .x-form-text, .x-form-text-default { border-radius: 4px 0 0 4px !important; } +/* Form trigger button - right side rounded */ .x-form-trigger, .x-form-trigger-default, .x-form-arrow-trigger, @@ -1944,143 +277,1593 @@ th, border-radius: 0 4px 4px 0 !important; } +/* Cursor styles for combobox/dropdown elements (pointer indicates clickable) */ +.x-form-trigger-wrap, +.x-form-text-wrap, +.x-form-field[role="combobox"], +input.x-form-text[readonly], +.x-form-trigger, +.x-form-arrow-trigger { + cursor: pointer !important; +} + +/* Cursor for dropdown list items */ +.x-boundlist-item, +.x-boundlist-item-over, +.x-boundlist-selected { + cursor: pointer !important; +} + +/* ===================================================== + BASE / BODY - Cyber dark background + grid pattern + ===================================================== */ +.x-body { + color: var(--pm-text); + background-color: var(--pm-bg-base); + background-image: + linear-gradient(rgba(255,255,255,0.008) 1px, transparent 1px), + linear-gradient(90deg, rgba(255,255,255,0.008) 1px, transparent 1px); + background-size: 56px 56px; +} + +.x-viewport>.x-body { + background-color: var(--pm-bg-base); +} + +body.x-border-layout-ct, +div.x-border-layout-ct { + background-color: var(--pm-bg-base); + background-image: + linear-gradient(rgba(255,255,255,0.008) 1px, transparent 1px), + linear-gradient(90deg, rgba(255,255,255,0.008) 1px, transparent 1px); + background-size: 56px 56px; +} + +/* Grid pan animation */ +@keyframes trw-grid-pan { + from { background-position: 0 0; } + to { background-position: 56px 56px; } +} + +.x-body, body.x-border-layout-ct, div.x-border-layout-ct { + animation: trw-grid-pan 30s linear infinite; +} + +/* ===================================================== + LEGEND / CHARTS - Ensure chart visibility + ===================================================== */ +.x-legend-container { + background-color: var(--pm-bg-base); + border-radius: 0 !important; +} + +.x-legend-horizontal .x-legend-item, +.x-legend-item { + background-color: var(--pm-bg-base); + color: var(--pm-text-muted); + border: none !important; + border-radius: 0 !important; +} + +/* Legend color marker (dot) - keep circular */ .x-legend-item-marker { border-radius: 50% !important; } +/* Chart canvas and SVG visibility */ +.x-chart, +.rrd-chart canvas, +canvas.x-surface { + opacity: 1 !important; +} + +/* Chart grid lines */ +.x-chart-grid-horizontal line, +.x-chart-grid-vertical line { + stroke: #34383D !important; + stroke-opacity: 1 !important; +} + +/* Chart axis text */ +.x-chart-axis-label { + fill: #B7BCC2 !important; +} + +/* RRDTool charts (Proxmox specific) - ensure PNG charts are visible */ +img.rrdimage, +.rrd-chart img, +div[class*="rrd"] img { + filter: none !important; + opacity: 1 !important; +} + /* ===================================================== - CHECKBOXES & RADIOS — GitHub Primer (v2.2.18) - ===================================================== */ + MASKS & OVERLAYS + ===================================================== */ +.x-mask { + /* v5.48: Background blur + 0.5 opacity */ + backdrop-filter: blur(4px) !important; + -webkit-backdrop-filter: blur(4px) !important; + background-color: rgba(0, 0, 0, 0.5) !important; +} -/* Base: remove sprite, styled as clean custom control */ -.x-form-checkbox, .x-form-checkbox-default, -.x-form-radio, .x-form-radio-default { +/* Disabled field-groups: keep the native "reduced opacity" look (no black mask overlay) */ +.x-item-disabled.x-masked-relative>.x-mask { + background-color: transparent !important; +} + +.x-tool .x-mask { + backdrop-filter: blur(4px); + background-color: #131416; + opacity: 0.6; +} + +/* v5.50: Hide ExtJS shadow element - use pure CSS shadow on window instead */ +.x-css-shadow { + display: none !important; +} + +/* ===================================================== + ICONS - Inverted for dark mode + ===================================================== */ +/* General icons - gray color */ +.fa-tags::before, +.fa-file-o::before, +.fa-building::before, +.x-action-col-icon::before, +.fa-shield::before, +.fa-file-text-o::before, +.fa-clock-o::before, +.x-tab-icon-el-default, +.pve-icon-verify-lettering::after, +.x-tree-icon-custom.lock-migrate::after, +.x-grid-icon-custom.lock-migrate::after, +.x-tree-icon-leaf:not(.x-tree-icon-custom)::before, +.x-tree-icon-parent:not(.x-tree-icon-custom)::before, +.x-tree-icon-parent-expanded:not(.x-tree-icon-custom)::before, +.x-grid-filters-filtered-column .x-column-header-text::after { + color: #B7BCC2; +} + +/* VM/CT icons - default gray, NOT green */ +.x-tree-icon-custom, +.x-grid-icon-custom { + color: #B7BCC2; +} + +.x-tree-icon-parent:not(.x-tree-icon-custom)::before, +.x-tree-icon-parent-expanded:not(.x-tree-icon-custom)::before { + filter: invert(90%); +} + +.fa-ceph::before, +.fa-sdn::before, +.fa-network-wired::before, +.pve-itype-treelist-item-icon-cdrom, +.fa-chevron-right::before, +.x-grid-row-console, +.x-box-scroller-toolbar-default.x-box-scroller, +.x-tree-elbow-img, +.pve-itype-icon-qemu, +.x-tree-node-computer, +.x-grid-tree-node-expanded .x-tree-node-computer, +.pbs-icon-tape, +.pbs-icon-tape-drive, +.x-tree-icon-leaf:not(.x-tree-icon-custom), +.x-tree-icon-parent:not(.x-tree-icon-custom), +.x-tree-icon-parent-expanded:not(.x-tree-icon-custom) { + filter: invert(90%); +} + +/* v5.37: Resource grid icon inversion - tree node icons only + Harddisk tree nodes are SVG background images that need inversion for dark themes */ +.x-tree-node-harddisk, +.x-grid-tree-node-expanded .x-tree-node-harddisk { + filter: invert(90%); +} + +/* Fix #27: Resource grid cells (td.pve-itype-icon-* / td.pmx-itype-icon-*) — remove + filter from TD so text is NOT inverted. Strip original background-image and reconstruct + icon via ::before pseudo-element on .x-grid-cell-inner with filter applied to icon only. + Includes pmx-itype-icon-processor/memory used by LXC Resources tab (PVE 9.x). */ +td.pve-itype-icon-cpu, +td.pve-itype-icon-memory, +td.pve-itype-icon-cdrom, +td.pve-itype-icon-pci, +td.pve-itype-icon-serial, +td.pve-itype-icon-die, +td.pmx-itype-icon-processor, +td.pmx-itype-icon-memory { + filter: none !important; background-image: none !important; - background-color: var(--trw-canvas-subtle) !important; - border: 1.5px solid var(--trw-fg-subtle) !important; - width: 16px !important; - height: 16px !important; + padding-left: 0px !important; +} + +/* Match FA row inner padding (4px) */ +td.pve-itype-icon-cpu > .x-grid-cell-inner, +td.pve-itype-icon-memory > .x-grid-cell-inner, +td.pve-itype-icon-cdrom > .x-grid-cell-inner, +td.pve-itype-icon-pci > .x-grid-cell-inner, +td.pve-itype-icon-serial > .x-grid-cell-inner, +td.pve-itype-icon-die > .x-grid-cell-inner, +td.pmx-itype-icon-processor > .x-grid-cell-inner, +td.pmx-itype-icon-memory > .x-grid-cell-inner { + padding-left: 4px !important; +} + +/* Inline-block pseudo-element icons — invert only the icon, not the text */ +td.pve-itype-icon-cpu > .x-grid-cell-inner::before, +td.pve-itype-icon-memory > .x-grid-cell-inner::before, +td.pve-itype-icon-cdrom > .x-grid-cell-inner::before, +td.pve-itype-icon-pci > .x-grid-cell-inner::before, +td.pve-itype-icon-serial > .x-grid-cell-inner::before, +td.pve-itype-icon-die > .x-grid-cell-inner::before, +td.pmx-itype-icon-processor > .x-grid-cell-inner::before, +td.pmx-itype-icon-memory > .x-grid-cell-inner::before { + content: '' !important; display: inline-block !important; - box-sizing: border-box !important; - cursor: pointer !important; - transition: border-color .12s ease, background-color .12s ease !important; + width: 14px !important; + height: 14px !important; + vertical-align: middle !important; + margin-right: 4px !important; + background-size: 14px 14px !important; + background-repeat: no-repeat !important; + background-position: center !important; + filter: invert(90%) !important; } -/* Checkbox: rounded square */ -.x-form-checkbox, .x-form-checkbox-default { - border-radius: 3px !important; +/* Individual icon URLs — pve-itype-icon-* classes are PVE-specific, so use /pve2/images/ + (icon-cpu.svg exists in /pwt/images/ too, but memory/cdrom/pci/serial/die do NOT) */ +td.pve-itype-icon-cpu > .x-grid-cell-inner::before { + background-image: url('/pve2/images/icon-cpu.svg') !important; +} +td.pve-itype-icon-memory > .x-grid-cell-inner::before { + background-image: url('/pve2/images/icon-memory.svg') !important; +} +td.pve-itype-icon-cdrom > .x-grid-cell-inner::before { + background-image: url('/pve2/images/icon-cd-drive.svg') !important; +} +td.pve-itype-icon-pci > .x-grid-cell-inner::before { + background-image: url('/pve2/images/icon-pci.svg') !important; +} +td.pve-itype-icon-serial > .x-grid-cell-inner::before { + background-image: url('/pve2/images/icon-serial.svg') !important; +} +td.pve-itype-icon-die > .x-grid-cell-inner::before { + background-image: url('/pve2/images/icon-die.svg') !important; +} +/* pmx-itype-icon-* use relative paths for PVE+PBS compatibility */ +td.pmx-itype-icon-processor > .x-grid-cell-inner::before { + background-image: url('../images/icon-cpu.svg') !important; +} +td.pmx-itype-icon-memory > .x-grid-cell-inner::before { + background-image: url('../images/icon-ram.svg') !important; } -/* Radio: circle + ::after inner dot */ -.x-form-radio, .x-form-radio-default { - border-radius: 50% !important; +/* v5.38: Summary panel icons (i elements) - reset to original Proxmox styling */ +i.pmx-itype-icon-processor, +i.pmx-itype-icon-memory, +.pmx-icon.pmx-itype-icon-processor, +.pmx-icon.pmx-itype-icon-memory { + filter: invert(90%) !important; + background-repeat: no-repeat !important; + background-position: 3px center !important; + background-size: 14px 14px !important; + padding-left: 18px !important; + position: static !important; +} + +/* v5.94: Use relative paths for PVE+PBS compatibility + PVE serves from /pwt/themes/ → ../images/ resolves to /pwt/images/ + PBS serves from /widgettoolkit/themes/ → ../images/ resolves to /widgettoolkit/images/ */ +i.pmx-itype-icon-processor, +.pmx-icon.pmx-itype-icon-processor { + background-image: url('../images/icon-cpu.svg') !important; +} + +i.pmx-itype-icon-memory, +.pmx-icon.pmx-itype-icon-memory { + background-image: url('../images/icon-ram.svg') !important; +} + +/* Disable ::before pseudo-elements on Summary panel icons */ +i.pmx-itype-icon-processor::before, +i.pmx-itype-icon-memory::before, +.pmx-icon.pmx-itype-icon-processor::before, +.pmx-icon.pmx-itype-icon-memory::before { + content: none !important; + display: none !important; +} + +/* v5.38: Summary panel SWAP and Bootdisk FontAwesome icons - consistent sizing */ +.left-aligned .fa.fa-refresh, +.left-aligned .fa.fa-hdd-o { + font-size: 14px !important; +} + +/* v5.88: Fix "More" button position in IPs section of Summary panel + Move button next to "IPs" label, vertically centered with IP addresses. + Parent containers need overflow:visible because transform moves button outside bounds. + + Key insight: ExtJS positions button at container's right edge (after IP addresses). + Solution: Anchor to top: 0, then use transform to shift button left to "IPs" label. + Value -242px moves button from right edge to just after the 35px "IPs" label. + NOTE: This value may need adjustment if Proxmox UI layout changes. */ +[id^="pveIPViewLXC-"] .x-box-inner, +[id^="pveIPViewLXC-"] > .x-box-inner { + overflow: visible !important; +} + +[id^="pveIPViewLXC-"] [id^="button-"].x-btn { + top: 0 !important; + transform: translate(-242px, 5px) !important; +} + +/* Cell inner content alignment — handled by Fix #27 td.pve-itype-icon-* rules above */ + +/* v5.37: FontAwesome icons in resource grid (Swap, Root Disk) */ +.pve-itype-fa .x-grid-cell-inner { + padding-left: 4px !important; +} + +.pve-itype-fa .pve-grid-fa, +.pve-itype-fa .pve-grid-fa.fa, +.x-grid-item .pve-itype-fa .fa { + color: #DEE0E3 !important; + margin-right: 4px !important; +} + +.x-tree-icon-custom, +.x-grid-icon-custom { + color: #B7BCC2; +} + +/* Running VMs/CTs - type icon neutral; status indicator handled separately */ +.x-tree-icon-custom.running, +.x-grid-icon-custom.running { + color: #B7BCC2; +} + +.x-tree-icon-custom::after, +.x-grid-icon-custom::after { + color: #B7BCC2; + text-shadow: none; +} + +.x-tree-icon-custom.stopped, +.x-tree-icon-custom.offline, +.x-grid-icon-custom.stopped, +.x-grid-icon-custom.offline { + color: #737C87; +} + +.x-tree-icon-custom.lxc::after, +.x-tree-icon-custom.qemu::after, +.x-grid-icon-custom.lxc::after, +.x-grid-icon-custom.qemu::after { + background-color: #131416; + color: #B7BCC2; +} + +/* v5.55: Fix LXC/QEMU icon ::after in treelist navigation */ +.x-treelist-item-icon.lxc::after, +.x-treelist-item-icon.qemu::after { + background-color: transparent !important; + color: #B7BCC2 !important; + margin-top: 4px !important; +} + +.x-tree-arrows .x-tree-expander { + filter: brightness(200%); +} + +/* ===================================================== + v5.6: Custom tree expander arrows (FontAwesome chevrons) + Replaces default sprite arrows with larger, animated icons + ===================================================== */ + +/* Base expander styling - replace sprite with FA icon */ +.x-tree-expander { + background-image: none !important; position: relative !important; - transform: translateZ(0) !important; - box-shadow: inset 0 0 0 0 transparent !important; + width: 18px !important; + height: 18px !important; + margin-right: 4px !important; + vertical-align: middle !important; } +/* Arrow icon using FontAwesome chevron-right */ +.x-tree-expander::before { + content: "\f054" !important; + /* FA chevron-right */ + font-family: "FontAwesome" !important; + font-size: 11px !important; + color: #737C87 !important; + /* UniFi tertiary/muted color */ + position: absolute !important; + top: -2px !important; + left: 3px !important; + transition: transform 0.2s ease, color 0.15s ease !important; +} + +/* Expanded state - arrow rotates 90 degrees */ +.x-grid-tree-node-expanded .x-tree-expander::before { + transform: rotate(90deg) !important; + color: #B7BCC2 !important; + /* UniFi secondary text */ +} + +/* Collapsed state - no rotation */ +tr:not(.x-grid-tree-node-expanded) .x-tree-expander::before { + transform: rotate(0deg) !important; +} + +/* Hover effect - UniFi blue accent */ +.x-tree-expander:hover::before { + color: var(--pm-accent) !important; +} + +/* Gap before node icon */ +.x-tree-icon-parent, +.x-tree-icon-leaf, +.x-tree-icon { + margin-left: 2px !important; +} + +/* Empty elbows - no extra margin */ +.x-tree-elbow-empty, +.x-tree-elbow { + margin-right: 0 !important; +} + +/* ===================================================== + v5.36: CHECKBOXES & RADIO BUTTONS - UniFi Authentic + Extracted from live UniFi Network Application + ===================================================== */ + +/* Remove the old filter-based styling */ +.x-form-checkbox-default, +.x-form-radio-default, +.x-column-header-checkbox .x-column-header-checkbox::after, +.x-grid-checkcolumn::after, +.x-menu-item-checked .x-menu-item-icon-default.x-menu-item-checkbox, +.x-menu-item-unchecked .x-menu-item-icon-default.x-menu-item-checkbox { + filter: none !important; +} + +/* The actual INPUT element that receives clicks - needs pointer cursor */ +.x-form-cb-input { + cursor: pointer !important; +} + +/* CHECKBOXES - Base styling (SPAN element - visual display) */ +.x-form-checkbox, +.x-form-checkbox-default { + display: inline-block !important; + width: 16px !important; + min-width: 16px !important; + height: 16px !important; + min-height: 16px !important; + border-radius: 4px !important; + border: 0.8px solid #737C87 !important; + background-color: rgba(0, 0, 0, 0.01) !important; + background-image: none !important; + cursor: pointer !important; + transition: border-color 0.2s linear, background-color 0.2s linear !important; + position: relative !important; + box-sizing: border-box !important; +} + +/* Checkbox - Checked state */ +.x-form-cb-checked .x-form-checkbox { + border-color: var(--pm-accent-hover) !important; + background-color: var(--pm-accent-hover) !important; + background-image: none !important; +} + +/* Checkbox checkmark using ::after pseudo-element */ +.x-form-cb-checked .x-form-checkbox::after { + content: '✓' !important; + position: absolute !important; + color: white !important; + font-size: 12px !important; + font-weight: bold !important; + top: 50% !important; + left: 50% !important; + transform: translate(-50%, -50%) !important; + pointer-events: none !important; +} + +/* Checkbox - Hover state */ +.x-form-checkbox:hover, +.x-form-cb:hover .x-form-checkbox, +.x-form-cb-wrap:hover .x-form-checkbox { + border-color: var(--pm-accent-hover) !important; +} + +/* RADIO BUTTONS - Base styling */ +.x-form-radio, +.x-form-radio-default { + display: inline-block !important; + width: 16px !important; + min-width: 16px !important; + height: 16px !important; + min-height: 16px !important; + border-radius: 50% !important; + border: 0.8px solid #737C87 !important; + background-color: rgba(0, 0, 0, 0.01) !important; + background-image: none !important; + cursor: pointer !important; + position: relative !important; + transition: border-color 0.2s linear !important; + box-sizing: border-box !important; +} + +/* Radio - Checked state border */ +.x-form-cb-checked .x-form-radio { + border-color: var(--pm-accent-hover) !important; + background-color: rgba(0, 0, 0, 0.01) !important; + background-image: none !important; +} + +/* Radio - Inner dot using ::after pseudo-element */ .x-form-radio::after { content: '' !important; position: absolute !important; top: 50% !important; left: 50% !important; - width: 7px !important; - height: 7px !important; + width: 6px !important; + height: 6px !important; border-radius: 50% !important; - background: transparent !important; + background-color: transparent !important; transform: translate(-50%, -50%) scale(0) !important; - transition: transform .15s ease, background .15s ease !important; + transition: transform 0.2s ease, background-color 0.2s ease !important; pointer-events: none !important; } -/* Hover */ -.x-form-checkbox:hover, .x-form-checkbox-default:hover, -.x-form-cb-wrap:hover .x-form-checkbox { - border-color: var(--trw-accent-fg) !important; -} - -.x-form-radio:hover, .x-form-radio-default:hover, -.x-form-cb-wrap:hover .x-form-radio { - border-color: var(--trw-accent-fg) !important; -} - -/* CHECKED checkbox — .x-form-cb-checked lives on the .x-form-item ancestor */ -.x-form-cb-checked .x-form-checkbox, -.x-form-cb-checked .x-form-checkbox-default { - background-color: var(--trw-accent-emphasis) !important; - border-color: var(--trw-accent-emphasis) !important; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 8'%3E%3Cpath d='M1 4l3 3 5-6' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important; - background-repeat: no-repeat !important; - background-position: center !important; - background-size: 9px 7px !important; -} - -/* SELECTED radio */ -.x-form-cb-checked .x-form-radio, -.x-form-cb-checked .x-form-radio-default { - border-color: var(--trw-accent-emphasis) !important; - background-color: var(--trw-canvas-muted) !important; -} - +/* Radio - Checked inner dot */ .x-form-cb-checked .x-form-radio::after { - background: var(--trw-accent-emphasis) !important; + background-color: var(--pm-accent-hover) !important; transform: translate(-50%, -50%) scale(1) !important; } -/* Buttons */ +/* Radio - Hover state */ +.x-form-radio:hover, +.x-form-cb-wrap:hover .x-form-radio { + border-color: var(--pm-accent-hover) !important; +} + +/* ===================================================== + BUTTONS - Clean, minimal style (UniFi authentic) + ===================================================== */ +/* v5.88: Respect inline display:none - Proxmox hides buttons dynamically and !important was overriding */ +.x-btn-default-small[style*="display: none"], +.x-btn-default-small[style*="display:none"] { + display: none !important; +} + .x-btn-default-small { - border-radius: 6px !important; + background-color: var(--pm-accent); + border: none; + border-radius: 6px; + padding: 5px 10px !important; + min-height: 26px !important; + /* v5.29: Header buttons (Create VM, Create CT, root@pam) - consistent 28px height with vertical centering */ + /* Exclude tag edit buttons (display:none when hidden, :has(.fa-check) for checkmark) */ + height: 28px !important; + min-height: 28px !important; + display: flex !important; + align-items: center !important; + padding: 3px 8px !important; } +.x-btn-default-small .x-btn-inner { + color: #ffffff; + padding: 2px 4px !important; + display: inline-flex !important; + align-items: center !important; +} + +/* Flex container logic (Merged from L3242) */ +.x-btn.x-btn-default-small .x-btn-button { + display: flex !important; + align-items: center !important; + justify-content: center !important; +} + +.x-btn.x-btn-default-small .x-btn-icon-el { + justify-content: center !important; +} + +.x-btn-default-small.x-btn-over, +.x-keyboard-mode .x-btn-default-small.x-btn-focus { + background-color: #338BFF; +} + +/* Pressed state */ +.x-btn-default-small.x-btn-pressed, +.x-btn-default-small.x-btn-menu-active { + background-color: #0056CC; +} + +/* Fix #29: Disabled buttons — explicit muted colors instead of opacity */ +.x-btn-default-small.x-btn.x-btn-disabled { + opacity: 1 !important; + background-color: #003A80 !important; + border-color: #002D66 !important; +} +.x-btn-default-small.x-btn.x-btn-disabled .x-btn-inner { + color: #8A9099 !important; +} + +/* Toolbar Buttons - Compact & Transparent */ .x-btn-default-toolbar-small { - border-radius: 4px !important; + background-color: transparent; + border: 1px solid #34383D !important; + padding: 4px 8px !important; + border-radius: 4px; } -.x-btn.x-btn-default-small:has(.fa-check) { - border-radius: 4px !important; +.x-btn-default-toolbar-small .x-btn-inner-default-toolbar-small { + color: #B7BCC2; } -/* Boundlist dropdowns */ +.x-btn-default-toolbar-small .x-btn-icon-el-default-toolbar-small { + color: #B7BCC2; +} + +/* v5.8: Toolbar button icon vertical centering fix */ +.x-btn-wrap.x-btn-wrap-default-toolbar-small { + align-items: center !important; +} + +.x-btn-icon-el.x-btn-icon-el-default-toolbar-small { + display: flex !important; + align-items: center !important; + justify-content: center !important; + line-height: 16px !important; + height: 16px !important; +} + +.x-btn-inner.x-btn-inner-default-toolbar-small { + display: flex !important; + align-items: center !important; +} + +.x-btn-default-toolbar-small .x-btn-wrap-default-toolbar-small.x-btn-arrow-right::after, +.x-btn-default-toolbar-small .x-btn-wrap-default-toolbar-small.x-btn-split-right::after { + filter: brightness(150%); +} + +.x-btn-default-toolbar-small.x-btn-over, +.x-keyboard-mode .x-btn-default-toolbar-small.x-btn-focus { + background-color: #34383D; +} + +.x-btn-default-toolbar-small.x-btn.x-btn-disabled { + opacity: 1 !important; + background-color: rgba(40, 43, 47, 0.5) !important; + border-color: #282B2F !important; +} +.x-btn-default-toolbar-small.x-btn.x-btn-disabled .x-btn-inner { + color: #555B63 !important; +} + +.x-btn-default-toolbar-small.x-btn.x-btn-menu-active, +.x-btn-default-toolbar-small.x-btn.x-btn-pressed { + background-color: var(--pm-accent); + padding: 4px 8px !important; /* Fix #30: prevent width change when dropdown opens */ +} + +.x-btn-default-toolbar-small.x-btn.x-btn-pressed .x-btn-inner-default-toolbar-small, +.x-btn-default-toolbar-small.x-btn.x-btn-pressed .x-btn-icon-el-default-toolbar-small { + color: #ffffff; +} + +/* Server View cogwheel button height - match adjacent combobox (28px) */ +.x-box-target:has(#view)>.x-btn { + height: 28px !important; + min-height: 28px !important; +} + +/* Header buttons (Create VM, Create CT, root@pam) - consistent 28px height with vertical centering */ +/* v5.29: Exclude tag edit buttons (display:none when hidden, :has(.fa-check) for checkmark) */ +.x-btn.x-btn-default-small:not(.x-btn-default-toolbar-small):not([style*="display: none"]):not([style*="display:none"]):not(:has(.fa-check)) { + height: 28px !important; + min-height: 28px !important; + display: flex !important; + align-items: center !important; + padding: 3px 8px !important; +} + +.x-btn.x-btn-default-small:not(.x-btn-default-toolbar-small):not([style*="display: none"]):not([style*="display:none"]):not(:has(.fa-check)) .x-btn-wrap { + display: flex !important; + align-items: center !important; +} + +.x-btn.x-btn-default-small:not(.x-btn-default-toolbar-small):not([style*="display: none"]):not([style*="display:none"]):not(:has(.fa-check)) .x-btn-inner { + display: flex !important; + align-items: center !important; +} + +/* Fix dropdown arrows on split/arrow buttons */ +.x-btn-wrap.x-btn-arrow-right::after, +.x-btn-wrap.x-btn-split-right::after { + height: 16px !important; + min-height: 16px !important; + width: 20px !important; + display: flex !important; + align-items: center !important; +} + +/* v5.27: Fix icon-only buttons - hide inner element when button has no text */ +/* ExtJS adds x-btn-no-text class to buttons with only an icon */ +.x-btn-no-text .x-btn-inner, +.x-btn-button.x-btn-no-text .x-btn-inner, +.x-btn-button-default-toolbar-small.x-btn-no-text .x-btn-inner-default-toolbar-small, +.x-btn-button-default-small.x-btn-no-text .x-btn-inner-default-small, +.x-btn-button-default-small.x-btn-no-text>.x-btn-inner-default-small { + display: none !important; +} + +/* ===================================================== + v5.8: TOOLBOX SCROLL ARROWS FIX + ExtJS behavior: + - Sets inline display:none when content NOT scrollable + - Adds x-box-scroller-disabled class at boundary + - No inline style when scrollable (show arrow) + ===================================================== */ + +/* Hide disabled scrollers (at boundary) */ +.x-box-scroller.x-box-scroller-disabled { + display: none !important; +} + +/* Hide scrollers when ExtJS sets inline display:none (not scrollable) */ +/* Note: ExtJS uses "display:none" without space, check both formats */ +.x-box-scroller.x-box-scroller-toolbar[style*="display:none"], +.x-box-scroller.x-box-scroller-toolbar[style*="display: none"] { + display: none !important; +} + +/* Show scrollers when content is scrollable (no inline display style, not disabled) */ +.x-toolbar-vertical .x-box-scroller-top:not(.x-box-scroller-disabled):not([style*="display"]), +.x-toolbar-vertical .x-box-scroller-bottom:not(.x-box-scroller-disabled):not([style*="display"]) { + display: flex !important; +} + +/* Style the vertical toolbar scrollers - arrow only, no background */ +.x-toolbar-vertical .x-box-scroller-top, +.x-toolbar-vertical .x-box-scroller-bottom { + width: 100% !important; + height: 16px !important; + left: 0 !important; + right: 0 !important; + background: transparent !important; + background-image: none !important; + filter: none !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; + cursor: pointer !important; + opacity: 1 !important; + z-index: 100 !important; + border: none !important; +} + +.x-toolbar-vertical .x-box-scroller-top { + top: 0 !important; +} + +.x-toolbar-vertical .x-box-scroller-bottom { + bottom: 0 !important; +} + +/* Arrow icons */ +.x-toolbar-vertical .x-box-scroller-top::before { + content: '▲' !important; + font-size: 10px !important; + color: #B7BCC2 !important; +} + +.x-toolbar-vertical .x-box-scroller-bottom::before { + content: '▼' !important; + font-size: 10px !important; + color: #B7BCC2 !important; +} + +/* Hover states */ +.x-toolbar-vertical .x-box-scroller-top:hover::before, +.x-toolbar-vertical .x-box-scroller-bottom:hover::before { + color: #F9FAFA !important; +} + +/* Re-hide disabled scrollers after styling */ +.x-toolbar-vertical .x-box-scroller.x-box-scroller-disabled { + display: none !important; +} + +/* ===================================================== + FORM ELEMENTS - Clean inputs (UniFi authentic) + ===================================================== */ +.x-form-trigger-default { + background-color: transparent; +} + +/* Boundlist dropdown popup - UniFi style 4px radius */ .x-boundlist { + background-color: #282B2F; + border: 1px solid #34383D; border-radius: 4px !important; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); + padding: 2px; } .x-boundlist-item { + background-color: transparent; + border: none; border-radius: 4px !important; + color: #DEE0E3; + padding: 2px 8px; } +.x-boundlist-selected { + background-color: rgba(249, 250, 250, 0.07); + color: #F9FAFA; +} + +.x-boundlist-item-over { + background-color: rgba(249, 250, 250, 0.04); + color: #DEE0E3; +} + +/* v5.38: Fix boundlist inner container inheriting 8px radius from global rule */ .x-boundlist-list-ct { border-radius: 4px !important; } -.x-boundlist-item-over, -.x-boundlist-selected { - border-radius: 4px !important; +/* Dropdown/floating grid pickers (e.g. ISO selector): readable column headers */ +.x-layer.x-grid .x-grid-header-ct, +.x-layer.x-grid .x-column-header, +.x-boundlist .x-grid-header-ct, +.x-boundlist .x-column-header { + background-color: var(--pm-bg-surface) !important; + border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important; } -/* Menus */ -.x-menu, +.x-layer.x-grid .x-column-header-inner, +.x-layer.x-grid .x-column-header-text, +.x-layer.x-grid .x-column-header-text-inner, +.x-layer.x-grid .x-column-header-text-default, +.x-boundlist .x-column-header-inner, +.x-boundlist .x-column-header-text, +.x-boundlist .x-column-header-text-inner, +.x-boundlist .x-column-header-text-default { + color: var(--pm-text-bright) !important; + font-weight: 700 !important; +} + +.x-layer.x-grid .x-column-header-trigger, +.x-boundlist .x-column-header-trigger { + border-left-color: rgba(255, 255, 255, 0.08) !important; +} + +.x-form-display-field-default { + color: #B7BCC2; +} + +.x-form-text-default { + background-color: transparent; + color: #F9FAFA; + border-radius: 4px 0 0 4px !important; + padding: 6px 10px !important; +} + +.x-form-trigger-wrap-default { + border-color: var(--pm-border); + border-radius: 4px !important; + background-color: var(--pm-hover-medium); +} + +.x-form-trigger-wrap-default.x-form-trigger-wrap-focus { + border-color: var(--pm-accent); + box-shadow: 0 0 0 3px var(--pm-focus-ring-color); +} + +.x-form-item-label-default { + color: #B7BCC2; +} + +.x-form-spinner-default { + background-color: #282B2F; +} + +/* v5.59: Make spinner buttons fill container with FontAwesome arrows */ +.x-form-spinner-up, +.x-form-spinner-down { + height: 13px !important; + background-image: none !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; + font-family: 'Font Awesome 6 Free', 'Font Awesome 5 Free', FontAwesome !important; + font-weight: 900 !important; + font-size: 7px !important; + color: #B7BCC2 !important; +} + +.x-form-spinner-up::before { + content: '\f077' !important; + display: block !important; +} + +.x-form-spinner-down::before { + content: '\f078' !important; + display: block !important; +} + +/* v5.64: Dialog form field alignment - let ExtJS handle natural sizing */ +.x-window .x-container .x-form-trigger-wrap, +.x-window .x-form-item-body .x-form-trigger-wrap { + width: 100% !important; + max-width: none !important; +} + +/* Ensure input fills the trigger wrap */ +.x-window .x-container .x-form-trigger-wrap input.x-form-field { + width: calc(100% - 2px) !important; +} + +/* v5.63: Removed v5.61 margin-left rule that caused form alignment issues */ + +.x-form-cb-label-default { + color: #B7BCC2; +} + +/* v5.41: Reduce gap between checkbox/radio and label */ +/* Label after checkbox - reduce left padding */ +.x-form-cb-label-after { + padding-left: 6px !important; +} + +/* Label before checkbox - reduce right padding */ +.x-form-cb-label-before { + padding-right: 6px !important; +} + +.x-fieldset-default { + border-color: #34383D; +} + +.x-fieldset-header-default>.x-fieldset-header-text { + color: #F9FAFA; +} + +/* ===================================================== + GRID / TABLE - UniFi authentic row hover + ===================================================== */ +.x-column-header { + border-color: transparent !important; + background-color: transparent !important; +} + +/* Header Text - Bright White */ +.x-column-header-inner, +.x-column-header-text { + color: #F9FAFA !important; + font-weight: 700 !important; + font-size: 13px !important; +} + +.x-grid-item, +.x-column-header-default, +.x-grid-cell-row-numberer { + color: #DEE0E3 !important; + background-color: transparent !important; + border-color: transparent !important; + font-size: 13px !important; +} + +.x-column-header-trigger { + border-color: transparent !important; +} + +.x-grid-cell-special { + border-color: transparent !important; +} + +.x-grid-group-hd { + background-color: transparent !important; + border-color: transparent !important; +} + +.x-grid-group-title { + color: #F9FAFA !important; + font-weight: 700 !important; +} + +.x-grid-header-ct { + border: none !important; + background-color: transparent !important; +} + +/* Row separators (use td borders; more reliable than box-shadow on