Control Web Panel

WebPanel => CentOS-WebPanel GUI => Topic started by: Longhorn on October 31, 2026, 01:53:32 PM

Title: Bash script patch to enable dark mode in CWP
Post by: Longhorn on October 31, 2026, 01:53:32 PM
I've created this patch to have a CWP with dark mode, if anyone wants it:

#!/bin/bash

CSS_FILE="/usr/local/cwpsrv/htdocs/admin/design/img/login.css"
CSS_CUSTOM="/usr/local/cwpsrv/htdocs/admin/design/css/custom.css"

# Initial message (loading spinner, default color)
echo -e "\n🔄 Applying custom dark theme to the CWP panel..."

# Open padlock message (amber)
echo -e "\n     \e[33m🔓 CSS files unlocked for writing.\e[0m"
echo
chattr -i "$CSS_CUSTOM"
chattr -i "$CSS_FILE" 2>/dev/null

# Pencil message (amber)
echo -e "       \e[33m✏️  Writing custom CSS to the files...\e[0m"

CSS_BLOCK='

/* --- Custom dark theme --- */

.login, .about {
    filter: invert(1);
}
.login:before {
    background: rgb(241 241 241 / 50%);
}
.about {
    box-shadow: inset 0 1px rgb(255 255 255 / 30%), inset 0 0 0 1px rgb(255 255 255 / 10%), 0 0 6px rgb(255 255 255 / 20%) !important;
}
input[type=submit] {
    background: #cb6262 !important;
    color: #c5c5c5 !important;
    border-color: #555 !important;
    text-shadow: none !important;
    background-image: none !important;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
}
.login h1 {
    display: none !important;
}
body {
    background-color: #1c1c1c !important;
}'

# Check whether the block already exists
if ! grep -q 'Custom dark theme' "$CSS_FILE"; then
    echo -e "$CSS_BLOCK" >> "$CSS_FILE"
else
    echo -e "   \e[38;5;94m    ⚠️  The CSS block already exists in login.css; nothing was added.\e[0m"
    echo
fi

cat > "$CSS_CUSTOM" << 'EOF'

/* DARK THEME */

/* Do not invert html: the new CWP sidebar already has its own colors */
html {
    background: #000 !important;
}

/* Keep the background dark outside the filtered areas.
   Higher specificity ensures this rule takes precedence over cwp-shell.css, which loads later. */
html body {
    background: #1c1c1c !important;
}

html body #wrapper {
    background: #1c1c1c !important;
}

/* Preserve inversion in the content area, header and footer.
   The sidebar is excluded from these filters. */
#header,
#content,
#footer,
#right-sidebar {
    -webkit-filter: invert(1) hue-rotate(180deg) !important;
    -moz-filter: invert(1) hue-rotate(180deg) !important;
    filter: invert(1) hue-rotate(180deg) !important;
    -webkit-transition: 100ms ease all;
    transition: 100ms ease all;
}

/* Prevent double inversion if the footer or right sidebar
   is contained within #content. */
#content #footer,
#content #right-sidebar {
    -webkit-filter: none !important;
    -moz-filter: none !important;
    filter: none !important;
}

/* Preserve the original colors of images in the inverted areas.
   Do not apply this compensation to images in the sidebar. */
#header img,
#content img,
#footer img,
#right-sidebar img,
#header embed[flashvars],
#content embed[flashvars],
#footer embed[flashvars],
#right-sidebar embed[flashvars],
#header [type*="application/x-shockwave-flash"],
#content [type*="application/x-shockwave-flash"],
#footer [type*="application/x-shockwave-flash"],
#right-sidebar [type*="application/x-shockwave-flash"],
#header [type*="application/x-silverlight"],
#content [type*="application/x-silverlight"],
#footer [type*="application/x-silverlight"],
#right-sidebar [type*="application/x-silverlight"] {
    -webkit-filter: invert(1) hue-rotate(180deg) !important;
    -moz-filter: invert(1) hue-rotate(180deg) !important;
    filter: invert(1) hue-rotate(180deg) !important;
}

/* Preserve the styling of deleted elements */
.deleted {
    -webkit-filter: invert(1) hue-rotate(180deg) !important;
    -moz-filter: invert(1) hue-rotate(180deg) !important;
    filter: invert(1) hue-rotate(180deg) !important;
    transition: 100ms ease all;
}

tr > td > a > img,th > a > img {
    filter:url(\"data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'invert\'><feColorMatrix type=\'matrix\' values=\'-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0\$filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=0,xray=0,mirror=0,invert=0,opacity=1,rotation=2)!important
}

#header .navbar {
    background: #dfdfdf;
}

#header .navbar .navbar-brand {
    font-size: 0px!important;
    background-size: cover;
    background-repeat: no-repeat;
    width: 230px;
    margin-left: 0px !important;
    filter: invert(1);
}

#header .navbar .navbar-brand .slogan {
    display:none;
}

#footer {
    background-color: #ddd;
}

#sidebar .shortcuts .icon24.icomoon-icon-database {
    line-height:40px;
}

#sidebar .shortcuts ul li {
    color: green;
}

#sidebar .shortcuts ul li a {
    margin-right: 10px;
}

#sidebar .shortcuts .icomoon-icon-database {
    font-size: 27px;
    color: #00ff00;
}

#sidebar .shortcuts .icomoon-icon-database:before {
    content: "\e120";
}

#myTab li.active, #myTabService li.active {
    background: #83bfff !important;
}

#header .navbar .navbar-brand {
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

.panel .panel-body {
    border: none;
}
.column .panel:hover, .cwp-hs-card:hover {
    box-shadow: 0 10px 24px rgba(255, 255, 255, .5) !important;
}
.column .panel, .cwp-hs-card {
    box-shadow: 0 1px 2px rgba(216, 224, 240, .06), 0 1px 3px rgba(216, 224, 240, .04) !important;
}
.panel .panel-heading {
    border: 1px solid #f4f4f4;
}
.input-group-addon {
    border: none;
    background-color: transparent;
}
.stats-btn:hover {
    border-color: #f5f5f5;
}
.stats-btn {
    border: 1px solid #f4f4f4;
}
.panel.panel-primary .panel-heading {
    border-color: #ffffff;
}
#content .panel.panel-primary:not(.gradient) {
    box-shadow: none !important;
    border: none;
}
#content .panel.panel-primary:not(.gradient):hover {
    box-shadow: 0 10px 24px rgba(255, 255, 255, .5) !important;
}
.reminder ul li {
    padding: 15px 25px 27px;
    border-radius: 15px;
}
.reminder ul li:hover {
    background-image: none !important;
}
.reminder ul li {
    background-color: #ffffff;
}
.cwp-kpi-lbl {
    font-size: 13px !important;
    margin-top: 11px !important;
}
#footer {
    background-color: rgb(239 242 245);
    border-top: 1px solid #fffefe;
}
#header.header-fixed .navbar.navbar-default, #header.header-fixed .navbar {
    background: #dddddd !important;
    box-shadow: 0 4px 10px rgba(255, 255, 255, .6) !important;
}
#header .navbar .nav > li.active > a:after {
    opacity: .2;
}
#header .navbar .nav > li > a {
    line-height: 1em;
    border-color: #eee #eee #ccc;
    border-radius: 8px;
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
}
#header .navbar .nav > li > a:hover {
    border-color: #ccc #ccc #999;
    box-shadow: 0px 1px 2px rgb(255, 255, 255), 0px 0px 3px #ffffff inset;
}
/* ---- Sidebar: dark charcoal matching the content background ---- */
:root {
    --nav-bg: #090d12 !important;
    --nav-bg-2: #070a0e !important;
    --nav-ink: #d0d4d8 !important;
    --nav-ink-dim: #89939e !important;
    --nav-line: #202830 !important;
    --nav-active: #171f28 !important;
}

#sidebar {
    --accent: #b0b7bf !important;
    --accent-ink: #d0d4d8 !important;
}
EOF

# Set file permissions to 644
chmod 644 "$CSS_CUSTOM"
chmod 644 "$CSS_FILE"

# Closed padlock message (amber)
echo -e "       \e[33m🔒 The CSS files have been locked again.\e[0m"
chattr +i "$CSS_CUSTOM"
chattr +i "$CSS_FILE" 2>/dev/null

# Final success message (green)
echo -e "\n\e[32m✅ The custom dark theme has been successfully applied to CWP!\e[0m\n"