Compare commits

..

2 Commits

Author SHA1 Message Date
Kaloyan Danchev
db5bd8c3b2 Phase 2 bug fixes: header, bars, checkboxes, icons, filter, cards
- Fix header double-offset (margin-left + padding-left) — use padding-left only
- Header text white with shadow for readability on light backgrounds
- Usage bars: 24px height, value text inside, left-aligned, color variants
- Dashboard bars: hide external span.load, use built-in span:last-child
- Dashboard CPU rows: 32px height, 36px line-height for alignment
- Glass checkbox/radio styling (appearance:none, custom check/dot)
- PanelIcon white for Settings/Tools/Plugins pages
- Plugin list FA icons white, tablesorter header transparent
- Shares Browse: lighter lock icon, glass tooltip, filter input refined
- File manager filter: reduced height, centered icon, toggle styling
- App cards: overflow:hidden for ribbon corner clipping
- Alternating table row backgrounds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:57:21 +02:00
Kaloyan Danchev
55ad7c66bc Fix 23 theme bugs across all pages: toggles, text visibility, icons, bars, shadows, layout
Phase 1: Fix toggle switch knob positioning (absolute + translateY centering)
Phase 2: Fix text visibility on Main/Shares thead td, Plugins descriptions, Settings/Tools PanelText labels
Phase 3: Fix icon coloring - JS replacement for Tailscale/ZFS Master with selfh.st light SVGs, CSS invert for remaining plugin imgs
Phase 4: Softer box-shadow on inner tables, stacked Panel rounding for Array Op
Phase 5: Browse table styling, form glass containers, Apps detail panel transparency
Phase 6: Main page usage bars (8px thin + gradient), plugin/VM button visibility
Phase 7: Header overflow fix, Docker folder-preview softening, Apps ribbon clipping, ZFS Master toggle spacing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:07:24 +02:00
3 changed files with 682 additions and 52 deletions

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 512 512"><path d="M-135.2 330c-5.4 5.4-14 5.4-19.4 0s-5.4-14.1 0-19.4c5.4-5.4 14-5.4 19.4 0 5.3 5.3 5.3 14 0 19.4m-3 383.6c-9.4 9.4-24.5 9.4-33.8 0-9.4-9.4-9.4-24.5 0-33.8 9.4-9.4 24.6-9.4 33.8 0 9.3 9.3 9.3 24.5 0 33.8m-80.1-46.2c-9.4-9.4-9.4-24.6 0-33.8 9.4-9.4 24.6-9.4 33.8 0 9.4 9.4 9.4 24.6 0 33.8-9.3 9.4-24.5 9.4-33.8 0m-12.2 46.2c-9.4 9.4-24.6 9.4-33.8 0-9.4-9.4-9.4-24.5 0-33.8 9.4-9.4 24.5-9.4 33.8 0 9.3 9.3 9.3 24.5 0 33.8m-80-46.2c-9.4-9.4-9.4-24.6 0-33.8 9.4-9.4 24.6-9.4 33.8 0 9.4 9.4 9.4 24.6 0 33.8-9.4 9.4-24.6 9.4-33.8 0m-12.3 46.2c-9.4 9.4-24.6 9.4-33.8 0-9.4-9.4-9.4-24.5 0-33.8 9.4-9.4 24.6-9.4 33.8 0 9.3 9.3 9.4 24.5 0 33.8m-80-46.2c-9.4-9.4-9.4-24.5 0-33.8 9.4-9.4 24.6-9.4 33.8 0 9.4 9.4 9.4 24.6 0 33.8-9.4 9.3-24.6 9.4-33.8 0m-12.3 46.2c-9.4 9.4-24.6 9.4-33.8 0-9.4-9.4-9.4-24.6 0-33.8 9.4-9.4 24.5-9.4 33.8 0 9.3 9.3 9.3 24.5 0 33.8M-452 312.3c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14.1 5.4-19.4 0s-5.4-14.1 0-19.4m29.8 29.8c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14.1 5.4-19.4 0-5.4-5.4-5.4-14.1 0-19.4m29.8 29.8c5.4-5.4 14.1-5.4 19.4 0 5.4 5.4 5.4 14.1 0 19.4-5.4 5.4-14 5.4-19.4 0s-5.4-14.1 0-19.4m0-59.6c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14 5.4-19.4 0-5.4-5.3-5.4-14.1 0-19.4m29.8 89.3c5.4-5.4 14.1-5.4 19.4 0 5.4 5.4 5.4 14.1 0 19.4-5.4 5.4-14 5.4-19.4 0-5.4-5.3-5.4-14 0-19.4m0-59.5c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14 5.4-19.4 0s-5.4-14.1 0-19.4m29.8-29.8c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14.1 5.4-19.4 0-5.4-5.3-5.4-14 0-19.4m29.7 89.3c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14 5.4-19.4 0-5.3-5.3-5.3-14 0-19.4m0-59.5c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14.1 5.4-19.4 0s-5.3-14.1 0-19.4m29.8-29.8c5.4-5.4 14.1-5.4 19.4 0 5.4 5.4 5.4 14.1 0 19.4-5.4 5.4-14 5.4-19.4 0-5.3-5.3-5.3-14 0-19.4m9.2 275.1c9.4-9.4 24.6-9.4 33.8 0 9.4 9.4 9.4 24.6 0 33.8-9.4 9.4-24.6 9.4-33.8 0-9.4-9.4-9.4-24.5 0-33.8m10.2-137.3c-5.4 5.4-14 5.4-19.4 0s-5.4-14.1 0-19.4c5.4-5.4 14.1-5.4 19.4 0 5.4 5.3 5.4 14 0 19.4m0-59.6c-5.4 5.4-14 5.4-19.4 0s-5.4-14.1 0-19.4c5.4-5.4 14.1-5.4 19.4 0 5.4 5.4 5.4 14.1 0 19.4m-49.2 70c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14 5.4-19.4 0-5.3-5.4-5.3-14.1 0-19.4m-7.2 80.7c9.4-9.4 24.6-9.4 33.8 0 9.4 9.4 9.4 24.5 0 33.8-9.4 9.4-24.6 9.4-33.8 0-9.4-9.3-9.4-24.5 0-33.8m-12.3 46.2c9.4 9.4 9.4 24.6 0 33.8-9.4 9.4-24.6 9.4-33.8 0-9.4-9.4-9.4-24.5 0-33.8 9.3-9.4 24.5-9.4 33.8 0m-10.2-216.3c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14 5.4-19.4 0-5.4-5.3-5.4-14 0-19.4m0 59.6c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.5-14.1 5.4-19.4 0c-5.4-5.5-5.4-14.2 0-19.5m89.3-29.8c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14 5.4-19.4 0-5.4-5.3-5.4-14 0-19.4m0-59.5c5.4-5.4 14-5.4 19.4 0s5.4 14.1 0 19.4c-5.4 5.4-14 5.4-19.4 0s-5.4-14.1 0-19.4m29.8 29.7c5.4-5.4 14.1-5.4 19.4 0 5.4 5.4 5.4 14.1 0 19.4-5.4 5.4-14 5.4-19.4 0-5.4-5.3-5.4-14 0-19.4m0-59.5c5.4-5.4 14.1-5.4 19.4 0 5.4 5.4 5.4 14 0 19.4s-14 5.4-19.4 0-5.4-14.1 0-19.4m29.8 29.7c5.4-5.4 14.1-5.4 19.4 0 5.4 5.4 5.4 14.1 0 19.4-5.4 5.4-14.1 5.4-19.4 0-5.4-5.3-5.4-14 0-19.4m148.4-45.1c0-21.7-17.6-39.4-39.4-39.4h-436.6c-21.7 0-39.4 17.6-39.4 39.4v149.9h58.6l-58.6 137V733c0 21.7 17.6 39.4 39.4 39.4h436.6c21.7 0 39.4-17.6 39.4-39.4V583.1h-58.6l58.6-137z" style="fill:#fff" transform="matrix(.989 0 0 .993 546 -255)"/></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -324,7 +324,10 @@
var replaceTimer = null;
function debouncedReplace() {
if (replaceTimer) clearTimeout(replaceTimer);
replaceTimer = setTimeout(replaceIcons, 200);
replaceTimer = setTimeout(function() {
replaceIcons();
replacePluginIcons();
}, 200);
}
// Watch for DOM changes (AJAX loads, FolderView manipulation)
@@ -343,14 +346,48 @@
observer.observe(target, { childList: true, subtree: true });
}
// Replace Tailscale sidebar icon with light SVG
function replaceTailscaleIcon() {
var imgs = document.querySelectorAll('img[alt="Tailscale"]');
// Plugin icon source → selfh.st light SVG replacement
// Maps partial src paths to icon names in /custom/assets/icons/
var PLUGIN_ICON_MAP = {
'/plugins/tailscale/': 'tailscale',
'/plugins/zfs.master/': 'openzfs',
// SNMP has no selfh.st icon — leave for CSS invert filter
};
// Replace plugin icons on Settings/Plugins/Tools pages with selfh.st light SVGs.
// Also replaces Tailscale sidebar icon (img[alt="Tailscale"]).
function replacePluginIcons() {
// Settings/Tools/Plugins grid icons
var imgs = document.querySelectorAll('#displaybox img, img[alt="Tailscale"]');
imgs.forEach(function(img) {
var url = CDN_SVG + '/tailscale-light.svg';
if (img.getAttribute('src') !== url) {
img.src = url;
img.removeAttribute('onerror');
// Skip container icons (handled by replaceIcons)
if (img.classList.contains('img')) return;
// Skip sidebar logo
if (img.id === 'sidebar-logo') return;
// Skip already replaced
if (img.getAttribute('data-glass-icon')) return;
var src = img.getAttribute('src') || '';
var keys = Object.keys(PLUGIN_ICON_MAP);
for (var i = 0; i < keys.length; i++) {
if (src.indexOf(keys[i]) !== -1) {
var iconName = PLUGIN_ICON_MAP[keys[i]];
var url = CDN_SVG + '/' + iconName + '-light.svg';
img.src = url;
img.setAttribute('data-glass-icon', iconName);
img.removeAttribute('onerror');
return;
}
}
// Also handle Tailscale by alt attribute (sidebar)
if (img.alt === 'Tailscale') {
var tsUrl = CDN_SVG + '/tailscale-light.svg';
if (src !== tsUrl) {
img.src = tsUrl;
img.setAttribute('data-glass-icon', 'tailscale');
img.removeAttribute('onerror');
}
}
});
}
@@ -359,10 +396,10 @@
function initIcons() {
// Initial replacement
setTimeout(replaceIcons, 500);
setTimeout(replaceTailscaleIcon, 500);
setTimeout(replacePluginIcons, 500);
// Second pass after FolderView finishes its DOM work
setTimeout(replaceIcons, 2000);
setTimeout(replaceTailscaleIcon, 2000);
setTimeout(replacePluginIcons, 2000);
// Start watching for future changes
startObserver();
}

676
style.css
View File

@@ -100,7 +100,8 @@ body::before {
#header i,
#header .fa,
#header [class*="icon"] {
color: rgba(50, 55, 65, 0.85) !important;
color: rgba(255, 255, 255, 0.9) !important;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5) !important;
}
@@ -387,7 +388,6 @@ html.sidebar-expanded.Theme--sidebar .nav-tile.right .nav-item a {
}
/* --- Content area shifts for sidebar (push, not overlap) --- */
#header,
#displaybox,
#footer,
#copyright {
@@ -395,13 +395,22 @@ html.sidebar-expanded.Theme--sidebar .nav-tile.right .nav-item a {
transition: margin-left 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
}
html.sidebar-expanded.Theme--sidebar #header,
html.sidebar-expanded.Theme--sidebar #displaybox,
html.sidebar-expanded.Theme--sidebar #footer,
html.sidebar-expanded.Theme--sidebar #copyright {
margin-left: var(--sidebar-expanded) !important;
}
/* Header already has padding-left from Unraid — override it instead of adding margin */
#header {
padding-left: var(--sidebar-collapsed) !important;
transition: padding-left 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
}
html.sidebar-expanded.Theme--sidebar #header {
padding-left: var(--sidebar-expanded) !important;
}
/* --- Search: click-triggered centered popup overlay --- */
.Theme--sidebar .nav-item.gui_search {
overflow: visible !important;
@@ -623,9 +632,14 @@ table thead th {
}
table tbody tr {
background: transparent !important;
transition: background 0.2s ease !important;
}
table tbody tr:nth-child(2n) {
background: rgba(255, 255, 255, 0.02) !important;
}
table tbody tr:hover {
background: rgba(255, 255, 255, 0.03) !important;
}
@@ -847,14 +861,38 @@ div.shade-black {
.usage-disk,
.usage-bar {
background: rgba(255, 255, 255, 0.06) !important;
border-radius: 8px !important;
border-radius: 12px !important;
overflow: hidden !important;
height: 24px !important;
position: relative !important;
}
.usage-disk > span,
.usage-bar > span {
border-radius: 8px !important;
.usage-disk > span:first-child,
.usage-bar > span:first-child {
border-radius: 12px !important;
background: linear-gradient(90deg, rgba(126, 184, 218, 0.6), var(--glass-accent)) !important;
height: 100% !important;
display: block !important;
}
/* Value text overlaid inside the bar */
.usage-disk > span:last-child,
.usage-bar > span:last-child {
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
display: flex !important;
align-items: center !important;
justify-content: flex-start !important;
padding-left: 8px !important;
font-size: 11px !important;
font-weight: 600 !important;
color: #fff !important;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) !important;
z-index: 1 !important;
pointer-events: none !important;
}
@@ -904,6 +942,7 @@ a:hover {
border-radius: var(--glass-radius-sm) !important;
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate)) !important;
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate)) !important;
overflow: hidden !important;
}
@@ -919,6 +958,7 @@ div.frame:has(> div.grid) {
-webkit-backdrop-filter: none !important;
border: none !important;
box-shadow: none !important;
overflow: visible !important;
}
div.frame:has(> div.grid)::before {
@@ -936,11 +976,11 @@ div.grid {
gap: 24px !important;
}
/* Tile columns — transparent + prevent overflow */
/* Tile columns — transparent */
div.tile {
background: transparent !important;
min-width: 0 !important;
overflow: hidden !important;
overflow: visible !important;
}
/* Dashboard tables → block layout, transparent, no stacking blur */
@@ -973,7 +1013,7 @@ table.dashboard > tbody.sortable {
-webkit-backdrop-filter: blur(30px) saturate(1.3) !important;
border: 1px solid var(--glass-border) !important;
border-radius: var(--glass-radius) !important;
box-shadow: var(--glass-shadow) !important;
box-shadow: none !important;
margin-bottom: 20px !important;
padding-bottom: 14px !important;
overflow: hidden !important;
@@ -984,7 +1024,7 @@ table.dashboard > tbody.sortable {
table.dashboard > tbody.sortable:hover {
background: rgba(255, 255, 255, 0.09) !important;
border-color: var(--glass-border-hover) !important;
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.30), inset 0 1px 0 rgba(255, 255, 255, 0.08) !important;
box-shadow: none !important;
}
/* visionOS inner glow on dashboard cards */
@@ -1013,6 +1053,12 @@ table.dashboard > tbody.sortable > tr:last-child {
border-bottom: none !important;
}
/* Hide compact Load: row in Processor card — Overall Load row shows same info.
Unraid's DashStats.css hides span.switch but the row keeps 33px of padding/gap */
table.dashboard > tbody.sortable > tr:has(.head_bar) {
display: none !important;
}
/* Dashboard card cells
NOTE: display must NOT use !important so Unraid's jQuery .hide() can override */
table.dashboard > tbody.sortable > tr > td {
@@ -1083,47 +1129,87 @@ table.dashboard > thead.stopgap {
table.dashboard .usage-disk,
table.dashboard .usage-bar {
background: rgba(255, 255, 255, 0.08) !important;
border-radius: 8px !important;
height: 8px !important;
border-radius: 12px !important;
height: 24px !important;
margin: 6px 0 !important;
overflow: hidden !important;
position: relative !important;
}
table.dashboard .usage-disk > span,
table.dashboard .usage-bar > span {
border-radius: 8px !important;
table.dashboard .usage-disk > span:first-child,
table.dashboard .usage-bar > span:first-child {
border-radius: 12px !important;
background: linear-gradient(90deg, rgba(126, 184, 218, 0.5), var(--glass-accent)) !important;
height: 100% !important;
display: block !important;
}
/* CPU bars — thin color-coded bars (higher specificity) */
#displaybox table.dashboard .usage-disk {
height: 10px !important;
border-radius: 5px !important;
/* Dashboard bar inner spans: normalize height/line-height */
.Theme--sidebar .usage-disk.sys > span {
line-height: normal !important;
height: 24px !important;
}
#displaybox table.dashboard .usage-disk > span {
border-radius: 5px !important;
/* Dashboard: hide the external span.load (Unraid JS fills the bar's inner span) */
table.dashboard span.head_bar > .load,
table.dashboard span.w72 > .load,
table.dashboard span.w36 > .load,
table.dashboard span.w18 > .load {
display: none !important;
}
#displaybox table.dashboard .usage-disk.greenbar > span {
/* Dashboard bar value text: left-aligned, vertically centered (inside bar) */
table.dashboard .usage-disk > span:last-child,
table.dashboard .usage-bar > span:last-child {
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
display: flex !important;
align-items: center !important;
justify-content: flex-start !important;
padding-left: 8px !important;
font-size: 11px !important;
font-weight: 600 !important;
color: #fff !important;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) !important;
z-index: 1 !important;
pointer-events: none !important;
}
/* Dashboard CPU rows: consistent height so borders don't clip bars */
table.dashboard > tbody.sortable > tr {
height: 32px !important;
}
/* Dashboard CPU core labels + bar wrappers: matching line-height */
table.dashboard > tbody.sortable > tr > td {
line-height: 36px !important;
vertical-align: middle !important;
}
/* Dashboard CPU show/hide link — parent flex container needs full width */
table.dashboard td > span.flex {
width: 100% !important;
}
/* Color variants for dashboard bars (class is on the fill span) */
table.dashboard .usage-disk > span.greenbar,
table.dashboard .usage-bar > span.greenbar {
background: linear-gradient(90deg, #22c55e, #4ade80) !important;
}
#displaybox table.dashboard .usage-disk.orangebar > span {
table.dashboard .usage-disk > span.orangebar,
table.dashboard .usage-bar > span.orangebar {
background: linear-gradient(90deg, #f97316, #fb923c) !important;
}
#displaybox table.dashboard .usage-disk.redbar > span {
table.dashboard .usage-disk > span.redbar,
table.dashboard .usage-bar > span.redbar {
background: linear-gradient(90deg, #ef4444, #f87171) !important;
}
/* Hide empty pill label text inside CPU bars */
#displaybox table.dashboard .usage-disk > span {
font-size: 0 !important;
color: transparent !important;
}
/* Docker container icons in dashboard */
table.dashboard img {
border-radius: 6px !important;
@@ -1199,8 +1285,14 @@ table.dashboard span.appname a:hover {
color: var(--glass-accent) !important;
}
/* CPU chart canvas — invert for dark background */
/* CPU chart — force block display (inline style sets table-row, breaking layout) */
#cpu_chart {
display: block !important;
}
/* CPU chart canvas — invert for dark background, block to prevent inline offset */
#cpuchart {
display: block !important;
filter: invert(1) hue-rotate(180deg) !important;
}
@@ -1254,12 +1346,21 @@ div.pie div {
}
.switch-button-button {
position: absolute !important;
top: 50% !important;
left: 2px !important;
transform: translateY(-50%) !important;
width: 18px !important;
height: 18px !important;
border-radius: 50% !important;
background: #fff !important;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !important;
transition: transform 0.25s ease !important;
transition: left 0.25s ease, transform 0.25s ease !important;
}
.switch-button-background.checked .switch-button-button {
left: calc(100% - 21px) !important;
top: calc(50% - 0.5px) !important;
}
@@ -1380,18 +1481,21 @@ div.tab[aria-selected="true"] {
-webkit-backdrop-filter: blur(30px) saturate(1.3) !important;
border: 1px solid var(--glass-border) !important;
border-radius: var(--glass-radius) !important;
box-shadow: var(--glass-shadow) !important;
box-shadow: none !important;
overflow: hidden !important;
border-collapse: separate !important;
border-spacing: 0 !important;
}
/* Table header row */
#displaybox table:not(.dashboard) thead {
#displaybox table:not(.dashboard) thead,
#displaybox table:not(.dashboard) thead tr {
background: rgba(255, 255, 255, 0.04) !important;
background-color: rgba(255, 255, 255, 0.04) !important;
}
#displaybox table:not(.dashboard) thead th {
#displaybox table:not(.dashboard) thead th,
#displaybox table:not(.dashboard) thead td {
color: var(--glass-text-muted) !important;
font-weight: 500 !important;
text-transform: uppercase !important;
@@ -1409,6 +1513,14 @@ div.tab[aria-selected="true"] {
background: transparent !important;
}
#displaybox table:not(.dashboard) tbody tr {
background: transparent !important;
}
#displaybox table:not(.dashboard) tbody tr:nth-child(2n) {
background: rgba(255, 255, 255, 0.02) !important;
}
#displaybox table:not(.dashboard) tbody tr:hover {
background: rgba(255, 255, 255, 0.04) !important;
}
@@ -1555,17 +1667,27 @@ table.tablesorter thead {
border-bottom: 1px solid rgba(255, 255, 255, 0.03) !important;
}
/* Docker/VM table rows — override Unraid dark theme background */
table.tablesorter tbody tr.sortable {
/* All tablesorter rows — override Unraid dark theme --dynamix-tablesorter-* variables */
table.tablesorter tbody tr {
background: transparent !important;
background-color: transparent !important;
}
table.tablesorter tbody tr.sortable:nth-child(even) {
table.tablesorter tbody tr:nth-child(2n) {
background: rgba(255, 255, 255, 0.02) !important;
background-color: rgba(255, 255, 255, 0.02) !important;
}
table.tablesorter tbody tr:hover,
table.tablesorter tbody tr.sortable:hover {
background: rgba(255, 255, 255, 0.05) !important;
background-color: rgba(255, 255, 255, 0.05) !important;
}
/* Tablesorter thead — override opaque header backgrounds */
table.tablesorter thead tr {
background: rgba(255, 255, 255, 0.04) !important;
background-color: rgba(255, 255, 255, 0.04) !important;
}
@@ -1689,9 +1811,22 @@ button[disabled] {
/* Checkbox and radio — subtle glass */
input[type="checkbox"],
input[type="radio"] {
border: 1px solid rgba(255, 255, 255, 0.20) !important;
-webkit-appearance: none !important;
appearance: none !important;
width: 16px !important;
min-width: 16px !important;
height: 16px !important;
min-height: 16px !important;
padding: 0 !important;
margin: 0 8px 0 0 !important;
box-sizing: border-box !important;
border: 1px solid rgba(255, 255, 255, 0.25) !important;
background: rgba(255, 255, 255, 0.06) !important;
border-radius: 4px !important;
cursor: pointer !important;
vertical-align: middle !important;
position: relative !important;
flex-shrink: 0 !important;
}
input[type="checkbox"]:checked,
@@ -1700,15 +1835,99 @@ input[type="radio"]:checked {
border-color: var(--glass-accent) !important;
}
/* Tooltip / title popups */
input[type="checkbox"]:checked::after {
content: '✓' !important;
position: absolute !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
font-size: 12px !important;
color: #fff !important;
line-height: 1 !important;
}
input[type="radio"] {
border-radius: 50% !important;
}
input[type="radio"]:checked::after {
content: '' !important;
position: absolute !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
width: 6px !important;
height: 6px !important;
background: #fff !important;
border-radius: 50% !important;
}
/* Disabled buttons — slightly more visible */
input[type="button"]:disabled,
button:disabled {
opacity: 0.65 !important;
}
/* Tooltip / title popups — glass style */
.tooltip,
[data-tooltip] {
[data-tooltip],
.ui-tooltip,
.tippy-box,
a.info > span {
background: rgba(255, 255, 255, 0.10) !important;
backdrop-filter: blur(40px) !important;
-webkit-backdrop-filter: blur(40px) !important;
border: 1px solid var(--glass-border) !important;
border-radius: 10px !important;
color: var(--glass-text) !important;
padding: 6px 12px !important;
}
.ui-tooltip-content {
color: var(--glass-text) !important;
}
/* Grey-text icons (lock, etc.) — lighter for dark background */
.grey-text,
.gray-text {
color: rgba(255, 255, 255, 0.45) !important;
}
/* File manager filter wrapper */
span.dfm_filter {
display: inline-flex !important;
align-items: center !important;
position: relative !important;
margin-right: 12px !important;
}
span.dfm_filter > i.fa-filter {
position: absolute !important;
left: 10px !important;
top: 50% !important;
transform: translateY(-50%) !important;
pointer-events: none !important;
font-size: 14px !important;
color: rgba(255, 255, 255, 0.5) !important;
}
span.dfm_filter > input.dfm_filter {
padding: 5px 12px 5px 30px !important;
}
/* File manager toggle (time/size) */
i.fa-toggle-off,
i.fa-toggle-on {
font-size: 20px !important;
cursor: pointer !important;
vertical-align: middle !important;
transition: color 0.2s ease !important;
}
i.fa-toggle-off {
color: rgba(255, 255, 255, 0.35) !important;
}
i.fa-toggle-on {
color: var(--glass-accent) !important;
}
/* Notification bar (parity check etc.) */
@@ -2151,3 +2370,376 @@ img.popupIcon {
.ca_credit {
color: var(--glass-text-muted) !important;
}
/* ============================================
BUG FIXES — Phase 2: Text & Label Visibility
============================================ */
/* Fix: Unraid tables use <td> in <thead>, not <th>.
Our existing rules only target thead th — add thead td. */
#displaybox table:not(.dashboard) thead td {
color: var(--glass-text-muted) !important;
font-weight: 500 !important;
text-transform: uppercase !important;
font-size: 0.72em !important;
letter-spacing: 0.6px !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
padding: 12px 16px !important;
background: transparent !important;
}
/* Also cover generic thead td (non-#displaybox context) */
table thead td {
color: var(--glass-text-muted) !important;
font-weight: 500 !important;
}
/* Plugins page: table header row has opaque dark bg from tablesorter.
The grid role table uses <th> which is fine, but ensure plugin
description text, author, version are clearly visible. */
#displaybox table.tablesorter tbody td,
#displaybox table.tablesorter tbody th,
#displaybox .plugin_list td,
#displaybox table[role="grid"] td,
#displaybox table[role="grid"] [role="gridcell"] {
color: var(--glass-text) !important;
}
/* Plugin name (h4/strong) and description (p) */
#displaybox table.tablesorter h4,
#displaybox table.tablesorter strong,
#displaybox table[role="grid"] h4,
#displaybox table[role="grid"] strong {
color: var(--glass-text-heading) !important;
}
#displaybox table.tablesorter p,
#displaybox table[role="grid"] p {
color: var(--glass-text-muted) !important;
}
/* Plugin status text */
#displaybox table.tablesorter .up-to-date,
#displaybox table[role="grid"] .up-to-date {
color: #4ade80 !important;
}
/* Settings/Tools/Plugins icon grid labels (.PanelText) —
currently inherits accent blue from <a>. Make labels white for readability. */
.PanelText {
color: var(--glass-text) !important;
}
/* Settings/Tools/Plugins font icons — make white */
.PanelIcon {
color: #fff !important;
}
/* Settings/Tools section headers (injected by Unraid as spans with inline styles) */
#displaybox .content > span[style],
#displaybox .content span[style*="font-size"] {
color: var(--glass-text-heading) !important;
}
/* ============================================
BUG FIXES — Phase 3: Icon Coloring
============================================ */
/* Plugin list large FA icons — white */
#displaybox i.fa.list,
#displaybox i[class*="icon-"].list {
color: #fff !important;
}
/* Table sorter headers — transparent bg, white text */
.tablesorter-header-inner {
background: transparent !important;
color: var(--glass-text-muted) !important;
}
/* Settings/Plugins/Tools icon grid: non-FA icons are PNG/SVG <img>.
Plugin icons that have selfh.st light SVG replacements get swapped via JS
(sidebar.js replacePluginIcons). For others, apply invert filter.
We scope this to only target icons inside the icon-grid span (not the
whole page) and exclude icons already replaced by JS (data-glass-icon). */
#displaybox .icon-setting img:not([data-glass-icon]),
#displaybox .page-setting img:not([data-glass-icon]),
#displaybox .icon-app img:not([data-glass-icon]),
#displaybox a[href*="/Settings/"] > span:first-child img:not([data-glass-icon]),
#displaybox a[href*="/Tools/"] > span:first-child img:not([data-glass-icon]),
#displaybox table[role="grid"] td:first-child img:not([data-glass-icon]) {
filter: brightness(0) invert(1) !important;
opacity: 0.85 !important;
}
/* Plugin list: first-cell icons (some are <img> not FA) */
#displaybox table.tablesorter td:first-child img:not([data-glass-icon]),
#displaybox table[role="grid"] [role="gridcell"]:first-child img:not([data-glass-icon]) {
filter: brightness(0) invert(1) !important;
opacity: 0.85 !important;
}
/* ============================================
BUG FIXES — Phase 4: Shadow & Rounding
============================================ */
/* Shadow removed from inner tables — parent glass card handles shadow */
/* Array Operation page: unify 4 stacked tables into one glass block.
Tables are: FORM>table, TABLE (direct), FORM>table, FORM>table.
Hidden P elements sit between them in the DOM. */
/* All ArrayOp tables: remove individual rounding, collapse spacing */
#displaybox table.ArrayOperation-Table {
border-radius: 0 !important;
margin-top: -1px !important;
margin-bottom: 0 !important;
}
/* Form wrappers: remove their margin so tables sit flush */
#displaybox .content > form:has(> table.ArrayOperation-Table) {
background: transparent !important;
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
border: none !important;
border-radius: 0 !important;
box-shadow: none !important;
padding: 0 !important;
margin-bottom: 0 !important;
}
/* Direct table child (Spin Up/Down): also remove bottom margin */
#displaybox .content > table.ArrayOperation-Table {
margin-bottom: 0 !important;
}
/* First table (inside first form): round top corners, restore top margin */
#displaybox .content > form:first-of-type > table.ArrayOperation-Table {
border-radius: var(--glass-radius) var(--glass-radius) 0 0 !important;
margin-top: 0 !important;
}
/* Last table (inside last form): round bottom corners */
#displaybox .content > form:last-of-type > table.ArrayOperation-Table {
border-radius: 0 0 var(--glass-radius) var(--glass-radius) !important;
}
/* Hide cell borders inside ArrayOp tables */
#displaybox table.ArrayOperation-Table td {
border-color: transparent !important;
}
/* ============================================
BUG FIXES — Phase 5: Table & Form Styling
============================================ */
/* Shares Browse page: file browser uses table.indexer.tablesorter.
Also covers any general tablesorter table with glass styling. */
table.tablesorter.indexer,
#displaybox table.tablesorter.indexer {
background: rgba(255, 255, 255, 0.06) !important;
border: 1px solid var(--glass-border) !important;
border-radius: var(--glass-radius) !important;
overflow: hidden !important;
}
table.tablesorter.indexer thead td,
table.tablesorter.indexer thead th {
background: rgba(255, 255, 255, 0.04) !important;
color: var(--glass-text-muted) !important;
}
table.tablesorter.indexer tbody tr:nth-child(even) {
background: rgba(255, 255, 255, 0.03) !important;
}
table.tablesorter.indexer tbody tr:hover {
background: rgba(255, 255, 255, 0.05) !important;
}
/* Share Settings form page: wrap form content in glass styling.
The form uses dl/dt/dd inside a content div. */
#displaybox .content > form,
#displaybox form[method],
#displaybox div.clone-settings,
#displaybox > .content > table:not(.dashboard):not(.tablesorter):not(.disk_status):not(.share_status):not(.ArrayOperation-Table) {
background: rgba(255, 255, 255, 0.06) !important;
backdrop-filter: blur(30px) saturate(1.3) !important;
-webkit-backdrop-filter: blur(30px) saturate(1.3) !important;
border: 1px solid var(--glass-border) !important;
border-radius: var(--glass-radius) !important;
padding: 16px !important;
margin-bottom: 16px !important;
}
/* Apps detail panel: ensure tags/buttons area has glass bg */
#alternateView .ca_template,
#alternateView table {
background: transparent !important;
border: none !important;
box-shadow: none !important;
}
/* ============================================
BUG FIXES — Phase 6: Bars & Button Visibility
============================================ */
/* Main page usage bars: 24px with value text inside */
#displaybox table:not(.dashboard) .usage-disk,
#displaybox table:not(.dashboard) .usage-bar {
height: 24px !important;
border-radius: 12px !important;
background: rgba(255, 255, 255, 0.08) !important;
overflow: hidden !important;
margin: 4px 0 !important;
position: relative !important;
}
#displaybox table:not(.dashboard) .usage-disk > span:first-child,
#displaybox table:not(.dashboard) .usage-bar > span:first-child {
height: 100% !important;
border-radius: 12px !important;
background: linear-gradient(90deg, rgba(126, 184, 218, 0.5), var(--glass-accent)) !important;
display: block !important;
}
/* Value text overlaid inside the bar */
#displaybox table:not(.dashboard) .usage-disk > span:last-child,
#displaybox table:not(.dashboard) .usage-bar > span:last-child {
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
display: flex !important;
align-items: center !important;
justify-content: flex-start !important;
padding-left: 8px !important;
font-size: 11px !important;
font-weight: 600 !important;
color: #fff !important;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) !important;
z-index: 1 !important;
pointer-events: none !important;
}
/* Color-coded bars on Main page (class is on the fill span) */
#displaybox table:not(.dashboard) .usage-disk > span.greenbar,
#displaybox table:not(.dashboard) .usage-bar > span.greenbar {
background: linear-gradient(90deg, #22c55e, #4ade80) !important;
}
#displaybox table:not(.dashboard) .usage-disk > span.orangebar,
#displaybox table:not(.dashboard) .usage-bar > span.orangebar {
background: linear-gradient(90deg, #f97316, #fb923c) !important;
}
#displaybox table:not(.dashboard) .usage-disk > span.redbar,
#displaybox table:not(.dashboard) .usage-bar > span.redbar {
background: linear-gradient(90deg, #ef4444, #f87171) !important;
}
/* Plugins Update: ensure update arrow buttons are visible */
#displaybox table.tablesorter input[type="button"],
#displaybox table[role="grid"] input[type="button"],
#displaybox table.tablesorter button:not([disabled]),
#displaybox table[role="grid"] button:not([disabled]) {
background: var(--glass-accent-subtle) !important;
color: var(--glass-accent) !important;
border: 1px solid rgba(126, 184, 218, 0.25) !important;
}
/* VM action buttons — ensure visibility */
#displaybox #vm_list button,
#displaybox #vm_list input[type="button"] {
background: var(--glass-accent-subtle) !important;
color: var(--glass-accent) !important;
border: 1px solid rgba(126, 184, 218, 0.25) !important;
}
/* ============================================
BUG FIXES — Phase 7: Page-Specific Layouts
============================================ */
/* Dashboard #3: header clipping — ensure UNRAID banner is fully visible */
#header {
overflow: visible !important;
z-index: 100 !important;
}
/* Ensure the Unraid logo/brand area doesn't clip */
#header > div:first-child,
#header .brand,
#header a[href*="unraid.net"] {
overflow: visible !important;
}
/* Docker #1: folder-preview wrapper has opaque glass bg.
Make it more subtle/transparent so container items
don't appear in a "tab-like" wrapper. */
.folder-preview,
div[class*="folder-preview"] {
background: rgba(255, 255, 255, 0.03) !important;
border: 1px solid rgba(255, 255, 255, 0.06) !important;
border-radius: 10px !important;
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
}
/* Docker folder-storage cell — reduce the wrapper appearance */
td.folder-storage {
background: transparent !important;
border: none !important;
padding: 4px 8px !important;
}
/* Apps #1: ribbon/badge corner rounding.
Ensure the card clips the ribbon properly. */
.ca_holder {
overflow: hidden !important;
border-radius: 16px !important;
}
/* Badge text positioning — ensure visible */
.ca_holder .installedCardBackground + span,
.ca_holder .betaCardBackground + span,
.ca_holder .officialCardBackground + span,
.ca_holder .warningCardBackground + span,
.ca_holder .greenCardBackground + span {
color: #fff !important;
font-size: 10px !important;
z-index: 2 !important;
}
/* ZFS Master: toggle icon gap fix.
The toggle/refresh area sits in a div that has excess margin.
Tighten the layout. */
#displaybox [id*="zfs"] .switch-button-background,
#displaybox [id*="ZFS"] .switch-button-background {
display: inline-block !important;
vertical-align: middle !important;
margin: 0 8px !important;
}
/* Fix stacked panels: don't apply to tabpanel children
which have their own panel structure */
[role="tabpanel"] div.Panel + div.Panel {
margin-top: 16px !important;
border-top: 1px solid var(--glass-border) !important;
border-radius: var(--glass-radius) !important;
}
[role="tabpanel"] div.Panel:not(:first-of-type):not(:last-of-type) {
border-radius: var(--glass-radius) !important;
}
[role="tabpanel"] div.Panel:first-of-type:has(+ div.Panel) {
border-radius: var(--glass-radius) !important;
margin-bottom: 16px !important;
}