Add client-side icon replacement, Dashboard fixes, and Apps page styling
- Add JS icon replacement module to sidebar.js that swaps container icons with selfh.st CDN versions on Docker page and Dashboard via MutationObserver - Fix Dashboard container name extraction (Strategy 2: span.inner > span) for containers whose original icon was missing (question.png fallback) - Add CSS filter for Dashboard folder icons (folder-img-docker class) - Add icon mappings for containers without CDN matches (netdisco→networking-toolbox, urbackup→networking-toolbox, seekandwatch→databasement, unmarr→homarr, dockhand→docker) - Fix shadowed netdisco-web/netdisco-backend entries in update-icons.sh - Add Community Applications (Apps page) glass theme overrides Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
190
sidebar.js
190
sidebar.js
@@ -145,3 +145,193 @@
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// =============================================================
|
||||||
|
// Icon Replacement Module — selfh.st CDN icons for Docker/VMs
|
||||||
|
// =============================================================
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var CDN_PNG = 'https://cdn.jsdelivr.net/gh/selfhst/icons@main/png';
|
||||||
|
var CDN_SVG = 'https://cdn.jsdelivr.net/gh/selfhst/icons@main/svg';
|
||||||
|
|
||||||
|
// Container name → selfh.st icon name (lowercase)
|
||||||
|
// Only needed for names that don't auto-match.
|
||||||
|
// Add entries here or use the glass.icon Docker label.
|
||||||
|
var ICON_MAP = {
|
||||||
|
'autokuma': 'uptime-kuma',
|
||||||
|
'uptimekuma': 'uptime-kuma',
|
||||||
|
'uptime-kuma-api': 'uptime-kuma',
|
||||||
|
'homeassistant_inabox': 'home-assistant',
|
||||||
|
'dockersocket': 'docker',
|
||||||
|
'pgadmin4': 'pgadmin',
|
||||||
|
'postgresql17': 'postgresql',
|
||||||
|
'woodpecker-agent': 'woodpecker-ci',
|
||||||
|
'woodpecker-server': 'woodpecker-ci',
|
||||||
|
'rustdesk-hbbr': 'rustdesk',
|
||||||
|
'rustdesk-hbbs': 'rustdesk',
|
||||||
|
'rustfs': 'rustdesk',
|
||||||
|
'netbox-redis-cache': 'redis',
|
||||||
|
'netbox-worker': 'netbox',
|
||||||
|
'netdisco-backend': 'networking-toolbox',
|
||||||
|
'netdisco-web': 'networking-toolbox',
|
||||||
|
'diode-agent': 'netbox',
|
||||||
|
'diode-auth': 'netbox',
|
||||||
|
'diode-auth-bootstrap': 'netbox',
|
||||||
|
'diode-hydra': 'netbox',
|
||||||
|
'diode-hydra-migrate': 'netbox',
|
||||||
|
'diode-ingester': 'netbox',
|
||||||
|
'diode-ingress': 'netbox',
|
||||||
|
'diode-reconciler': 'netbox',
|
||||||
|
'authentik-worker': 'authentik',
|
||||||
|
'adguardhome': 'adguard-home',
|
||||||
|
'adguardhome-sync': 'adguard-home',
|
||||||
|
'timemachine': 'apple',
|
||||||
|
'libation': 'audible',
|
||||||
|
'netalertx': 'netalertx',
|
||||||
|
'actual-budget': 'actual-budget',
|
||||||
|
'speedtest-tracker': 'speedtest-tracker',
|
||||||
|
'open-webui': 'open-webui',
|
||||||
|
'urbackup': 'networking-toolbox',
|
||||||
|
'seekandwatch': 'databasement',
|
||||||
|
'unmarr': 'homarr',
|
||||||
|
'dockhand': 'docker'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resolve container name to selfh.st CDN URL
|
||||||
|
// mode: 'color' for expanded containers, 'light' for dashboard/folder-preview
|
||||||
|
function resolveIconUrl(name, mode) {
|
||||||
|
var key = name.toLowerCase();
|
||||||
|
var iconName = ICON_MAP[key] || key;
|
||||||
|
if (mode === 'light') {
|
||||||
|
return CDN_SVG + '/' + iconName + '-light.svg';
|
||||||
|
}
|
||||||
|
return CDN_PNG + '/' + iconName + '.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract container name from an <img> element by walking up the DOM
|
||||||
|
function getContainerName(img) {
|
||||||
|
// Strategy 1: sibling .inner > .appname text
|
||||||
|
var outer = img.closest('span.outer');
|
||||||
|
if (outer) {
|
||||||
|
var appname = outer.querySelector('span.appname');
|
||||||
|
if (appname) {
|
||||||
|
var a = appname.querySelector('a');
|
||||||
|
return (a ? a.textContent : appname.textContent).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 2: .inner > first non-state span (Dashboard view)
|
||||||
|
if (outer) {
|
||||||
|
var inner = outer.querySelector('span.inner');
|
||||||
|
if (inner) {
|
||||||
|
var nameSpan = inner.querySelector('span:not(.state)');
|
||||||
|
if (nameSpan && nameSpan.textContent.trim()) {
|
||||||
|
return nameSpan.textContent.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 3: .inner > a.exec text (FolderView uses this)
|
||||||
|
if (outer) {
|
||||||
|
var exec = outer.querySelector('a.exec');
|
||||||
|
if (exec) return exec.textContent.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 4: parent row ct-name
|
||||||
|
var row = img.closest('tr');
|
||||||
|
if (row) {
|
||||||
|
var ctName = row.querySelector('td.ct-name span.appname');
|
||||||
|
if (ctName) {
|
||||||
|
var a2 = ctName.querySelector('a');
|
||||||
|
return (a2 ? a2.textContent : ctName.textContent).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 4: extract from icon src path (fallback)
|
||||||
|
var src = img.getAttribute('src') || '';
|
||||||
|
var match = src.match(/images\/(.+?)-icon\.png/);
|
||||||
|
if (match) return match[1];
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine icon mode based on DOM context
|
||||||
|
function getIconMode(img) {
|
||||||
|
// Dashboard → light
|
||||||
|
if (img.closest('table.dashboard')) return 'light';
|
||||||
|
// Folder preview (collapsed row) → light
|
||||||
|
if (img.closest('div.folder-preview')) return 'light';
|
||||||
|
// Expanded container inside folder → color
|
||||||
|
if (img.closest('tr.folder-element')) return 'color';
|
||||||
|
// Regular container row → color
|
||||||
|
return 'color';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace all container icons on the page
|
||||||
|
function replaceIcons() {
|
||||||
|
var imgs = document.querySelectorAll('img.img');
|
||||||
|
imgs.forEach(function(img) {
|
||||||
|
// Skip sidebar logo and non-container icons
|
||||||
|
if (img.id === 'sidebar-logo') return;
|
||||||
|
// Skip folder category icons (SVGs managed by FolderView)
|
||||||
|
if (img.classList.contains('folder-img') && img.closest('td.folder-name')) return;
|
||||||
|
if (img.classList.contains('folder-img-docker')) return;
|
||||||
|
|
||||||
|
var name = getContainerName(img);
|
||||||
|
if (!name) return;
|
||||||
|
|
||||||
|
// Skip folder names (they start with "folder-")
|
||||||
|
if (name.indexOf('folder-') === 0) return;
|
||||||
|
|
||||||
|
var mode = getIconMode(img);
|
||||||
|
var url = resolveIconUrl(name, mode);
|
||||||
|
|
||||||
|
// Only replace if different (avoid infinite MutationObserver loop)
|
||||||
|
if (img.src !== url && img.getAttribute('src') !== url) {
|
||||||
|
img.src = url;
|
||||||
|
// Remove cache-busting onerror that resets to question mark
|
||||||
|
img.removeAttribute('onerror');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debounce to avoid excessive calls during DOM manipulation
|
||||||
|
var replaceTimer = null;
|
||||||
|
function debouncedReplace() {
|
||||||
|
if (replaceTimer) clearTimeout(replaceTimer);
|
||||||
|
replaceTimer = setTimeout(replaceIcons, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch for DOM changes (AJAX loads, FolderView manipulation)
|
||||||
|
function startObserver() {
|
||||||
|
var target = document.getElementById('displaybox') || document.body;
|
||||||
|
var observer = new MutationObserver(function(mutations) {
|
||||||
|
var dominated = false;
|
||||||
|
for (var i = 0; i < mutations.length; i++) {
|
||||||
|
if (mutations[i].addedNodes.length > 0) {
|
||||||
|
dominated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dominated) debouncedReplace();
|
||||||
|
});
|
||||||
|
observer.observe(target, { childList: true, subtree: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize when DOM is ready
|
||||||
|
function initIcons() {
|
||||||
|
// Initial replacement
|
||||||
|
setTimeout(replaceIcons, 500);
|
||||||
|
// Second pass after FolderView finishes its DOM work
|
||||||
|
setTimeout(replaceIcons, 2000);
|
||||||
|
// Start watching for future changes
|
||||||
|
startObserver();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', initIcons);
|
||||||
|
} else {
|
||||||
|
initIcons();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|||||||
389
style.css
389
style.css
@@ -1490,6 +1490,16 @@ span.folder-outer {
|
|||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Folder category icons (SVG on the folder row itself) — make white */
|
||||||
|
tr.folder > td.folder-name img.folder-img {
|
||||||
|
filter: brightness(0) invert(1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dashboard folder category icons — make white (same SVGs, different DOM) */
|
||||||
|
img.folder-img-docker {
|
||||||
|
filter: brightness(0) invert(1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Folder dropdown button */
|
/* Folder dropdown button */
|
||||||
button[class*="dropDown-"] {
|
button[class*="dropDown-"] {
|
||||||
background: rgba(255, 255, 255, 0.06) !important;
|
background: rgba(255, 255, 255, 0.06) !important;
|
||||||
@@ -1623,3 +1633,382 @@ div.clone-settings {
|
|||||||
background: rgba(126, 184, 218, 0.3);
|
background: rgba(126, 184, 218, 0.3);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
COMMUNITY APPLICATIONS (APPS PAGE) OVERRIDES
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
/* --- Override CA gray theme variables for glass look --- */
|
||||||
|
:root {
|
||||||
|
--template-background: rgba(255, 255, 255, 0.06);
|
||||||
|
--template-hover-background: rgba(255, 255, 255, 0.12);
|
||||||
|
--template-favourite: rgba(255, 255, 255, 0.10);
|
||||||
|
--border-color: rgba(255, 255, 255, 0.12);
|
||||||
|
--sidebar-background: rgba(255, 255, 255, 0.08);
|
||||||
|
--sidebar-text: var(--glass-text);
|
||||||
|
--ca-legacy-background-color: transparent;
|
||||||
|
--support-popup-text: var(--glass-text);
|
||||||
|
--support-popup-background: rgba(255, 255, 255, 0.10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Apps page left sidebar menu --- */
|
||||||
|
.menuItems {
|
||||||
|
background-color: transparent !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.caMenu,
|
||||||
|
ul.nonselectMenu {
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.caMenuItem,
|
||||||
|
a.caMenuItem {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caMenuItem:hover {
|
||||||
|
color: var(--glass-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedMenu {
|
||||||
|
color: var(--glass-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuItems hr {
|
||||||
|
border-color: rgba(255, 255, 255, 0.08) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Search area bar --- */
|
||||||
|
.searchArea {
|
||||||
|
background-color: transparent !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchAreaHolder {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchBox {
|
||||||
|
background: rgba(255, 255, 255, 0.08) !important;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.12) !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
backdrop-filter: blur(20px) !important;
|
||||||
|
-webkit-backdrop-filter: blur(20px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchBox::placeholder {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchSubmit {
|
||||||
|
background: rgba(255, 255, 255, 0.06) !important;
|
||||||
|
border: none !important;
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
border-radius: 0 10px 10px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- App cards (ca_holder) --- */
|
||||||
|
.ca_holder,
|
||||||
|
.dockerHubHolder {
|
||||||
|
background: rgba(255, 255, 255, 0.06) !important;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.10) !important;
|
||||||
|
border-radius: 16px !important;
|
||||||
|
backdrop-filter: blur(30px) saturate(1.3) !important;
|
||||||
|
-webkit-backdrop-filter: blur(30px) saturate(1.3) !important;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: background 0.2s, border-color 0.2s, box-shadow 0.2s !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ca_holder:hover,
|
||||||
|
.dockerHubHolder:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.12) !important;
|
||||||
|
border-color: rgba(255, 255, 255, 0.18) !important;
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ca_holderFav {
|
||||||
|
background: rgba(255, 255, 255, 0.10) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card text */
|
||||||
|
.ca_applicationName {
|
||||||
|
color: var(--glass-text-heading) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardDescription,
|
||||||
|
.cardDesc {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ca_author {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ca_categories,
|
||||||
|
a.ca_categories {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card description fade-out gradient — match glass bg */
|
||||||
|
.cardDesc::after {
|
||||||
|
background: linear-gradient(to right,
|
||||||
|
transparent 0%,
|
||||||
|
rgba(255, 255, 255, 0.03) 50%,
|
||||||
|
rgba(30, 30, 40, 0.6) 100%) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Buttons (caButton) --- */
|
||||||
|
.caButton,
|
||||||
|
.popupRepoDescription,
|
||||||
|
.popupDescription {
|
||||||
|
background: rgba(255, 255, 255, 0.10) !important;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.12) !important;
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
backdrop-filter: blur(15px) !important;
|
||||||
|
-webkit-backdrop-filter: blur(15px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caButton:hover {
|
||||||
|
background: var(--glass-accent) !important;
|
||||||
|
border-color: var(--glass-accent) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caButton:hover a,
|
||||||
|
a.caButton:hover {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caButton a {
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Home templates section headers --- */
|
||||||
|
.ca_homeTemplatesHeader {
|
||||||
|
color: var(--glass-text-heading) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ca_homeTemplatesLine2 {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Home templates horizontal scroll area --- */
|
||||||
|
.ca_homeTemplates {
|
||||||
|
scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Alternate view (app detail popup) --- */
|
||||||
|
#alternateView {
|
||||||
|
background-color: rgba(15, 15, 25, 0.92) !important;
|
||||||
|
backdrop-filter: blur(60px) saturate(1.5) !important;
|
||||||
|
-webkit-backdrop-filter: blur(60px) saturate(1.5) !important;
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
border-left: 1px solid rgba(255, 255, 255, 0.08) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alternateView table {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popupCloseArea {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popupName {
|
||||||
|
color: var(--glass-text-heading) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popupAuthor,
|
||||||
|
.popupAuthorMain {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popupInfoSection {
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Popup description box */
|
||||||
|
.popupDescription {
|
||||||
|
background: rgba(255, 255, 255, 0.06) !important;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.10) !important;
|
||||||
|
border-radius: 14px !important;
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popupRepoDescription {
|
||||||
|
background: rgba(255, 255, 255, 0.06) !important;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.10) !important;
|
||||||
|
border-radius: 14px !important;
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Sidebar detail panel (sidenav) --- */
|
||||||
|
.sidenav {
|
||||||
|
background-color: rgba(15, 15, 25, 0.90) !important;
|
||||||
|
backdrop-filter: blur(50px) saturate(1.5) !important;
|
||||||
|
-webkit-backdrop-filter: blur(50px) saturate(1.5) !important;
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Mobile overlay --- */
|
||||||
|
.mobileOverlay.menuShowing {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Multi-install bottom bar --- */
|
||||||
|
.multi_installDiv {
|
||||||
|
background-color: rgba(15, 15, 25, 0.85) !important;
|
||||||
|
backdrop-filter: blur(40px) !important;
|
||||||
|
-webkit-backdrop-filter: blur(40px) !important;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.08) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Card badge triangles — keep visible but soften --- */
|
||||||
|
.installedCardBackground {
|
||||||
|
background-color: rgba(50, 47, 255, 0.75) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.officialCardBackground,
|
||||||
|
.spotlightCardBackground {
|
||||||
|
background-color: rgba(133, 65, 83, 0.75) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.betaCardBackground {
|
||||||
|
background-color: rgba(255, 140, 47, 0.7) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warningCardBackground {
|
||||||
|
background-color: rgba(129, 0, 0, 0.75) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.greenCardBackground {
|
||||||
|
background-color: rgba(0, 129, 0, 0.75) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Links inside CA --- */
|
||||||
|
.popUpLink,
|
||||||
|
a.popUpLink {
|
||||||
|
color: var(--glass-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popUpLink:hover,
|
||||||
|
a.popUpLink:hover {
|
||||||
|
color: var(--glass-accent-hover) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Sort icons --- */
|
||||||
|
.sortIcons {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortIcons:hover {
|
||||||
|
color: var(--glass-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Page navigation --- */
|
||||||
|
.pageNumber {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pageNumber:hover {
|
||||||
|
color: var(--glass-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pageSelected {
|
||||||
|
color: var(--glass-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Template display area --- */
|
||||||
|
.ca_template {
|
||||||
|
background-color: rgba(255, 255, 255, 0.06) !important;
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
border-radius: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Statistics / no-apps-found text --- */
|
||||||
|
.ca_NoAppsFound,
|
||||||
|
.ca_NoDockerAppsFound {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Repo table --- */
|
||||||
|
.repoTable {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Screenshot borders --- */
|
||||||
|
.screen {
|
||||||
|
border-color: var(--glass-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Mod comment --- */
|
||||||
|
.modComment {
|
||||||
|
border-color: rgba(207, 49, 49, 0.5) !important;
|
||||||
|
background: rgba(207, 49, 49, 0.08) !important;
|
||||||
|
border-radius: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Category display --- */
|
||||||
|
#Category {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Docker card background (inside cards) --- */
|
||||||
|
.dockerCardBackground {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Favourite button styles --- */
|
||||||
|
.fav {
|
||||||
|
background: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent 0%,
|
||||||
|
rgba(0, 0, 0, 0.3) 100%
|
||||||
|
),
|
||||||
|
linear-gradient(
|
||||||
|
to right,
|
||||||
|
rgba(0, 153, 0, 0.7) 0%,
|
||||||
|
rgba(0, 153, 0, 0.85) 50%,
|
||||||
|
rgba(0, 153, 0, 0.7) 100%
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nonfav {
|
||||||
|
background-color: rgba(255, 255, 255, 0.10) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Icon display inside popup --- */
|
||||||
|
img.displayIcon,
|
||||||
|
img.popupIcon {
|
||||||
|
border-radius: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Spinner overlay --- */
|
||||||
|
.spinnerBackground {
|
||||||
|
background: rgba(0, 0, 0, 0.3) !important;
|
||||||
|
backdrop-filter: blur(5px) !important;
|
||||||
|
-webkit-backdrop-filter: blur(5px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Readmore gradient mask fix for dark theme --- */
|
||||||
|
.readmore-js-collapsed {
|
||||||
|
-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,1)), to(rgba(255,255,255,0.1))) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Credits page --- */
|
||||||
|
.credits {
|
||||||
|
color: var(--glass-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ca_creditTitle,
|
||||||
|
.ca_creditheader {
|
||||||
|
color: var(--glass-text-heading) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ca_credit {
|
||||||
|
color: var(--glass-text-muted) !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ auto_detect_icon() {
|
|||||||
rustfs) echo "rustdesk"; return 0 ;;
|
rustfs) echo "rustdesk"; return 0 ;;
|
||||||
netbox-redis-cache) echo "redis"; return 0 ;;
|
netbox-redis-cache) echo "redis"; return 0 ;;
|
||||||
netbox-worker) echo "netbox"; return 0 ;;
|
netbox-worker) echo "netbox"; return 0 ;;
|
||||||
netdisco-backend) echo "netdisco"; return 0 ;;
|
netdisco-backend) echo "networking-toolbox"; return 0 ;;
|
||||||
netdisco-web) echo "netdisco"; return 0 ;;
|
netdisco-web) echo "networking-toolbox"; return 0 ;;
|
||||||
libation) echo "audible"; return 0 ;;
|
libation) echo "audible"; return 0 ;;
|
||||||
diode-*) echo "netbox"; return 0 ;;
|
diode-*) echo "netbox"; return 0 ;;
|
||||||
authentik-worker) echo "authentik"; return 0 ;;
|
authentik-worker) echo "authentik"; return 0 ;;
|
||||||
@@ -95,8 +95,11 @@ auto_detect_icon() {
|
|||||||
speedtest-tracker) echo "speedtest-tracker"; return 0 ;;
|
speedtest-tracker) echo "speedtest-tracker"; return 0 ;;
|
||||||
timemachine) echo "apple"; return 0 ;;
|
timemachine) echo "apple"; return 0 ;;
|
||||||
open-webui) echo "open-webui"; return 0 ;;
|
open-webui) echo "open-webui"; return 0 ;;
|
||||||
urbackup) echo "urbackup"; return 0 ;;
|
urbackup) echo "networking-toolbox"; return 0 ;;
|
||||||
netalertx) echo "netalertx"; return 0 ;;
|
netalertx) echo "netalertx"; return 0 ;;
|
||||||
|
seekandwatch) echo "databasement"; return 0 ;;
|
||||||
|
unmarr) echo "homarr"; return 0 ;;
|
||||||
|
dockhand) echo "docker"; return 0 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Strategy 1: lowercase name directly
|
# Strategy 1: lowercase name directly
|
||||||
|
|||||||
Reference in New Issue
Block a user