diff --git a/config/custom.css b/config/custom.css index 191a058..0f8f275 100755 --- a/config/custom.css +++ b/config/custom.css @@ -1,6 +1,31 @@ -/* custom.css */ +/* ============================================================= + NETGRIMOIRE HOMEPAGE — custom.css + Aesthetic: Dark ops command center / arcane terminal + ============================================================= */ -/* Base background behavior */ +/* ── CSS Variables ── */ +:root { + --ng-teal: #00e5cc; + --ng-teal-dim: rgba(0, 229, 204, 0.15); + --ng-teal-border: rgba(0, 229, 204, 0.25); + --ng-teal-glow: rgba(0, 229, 204, 0.08); + --ng-amber: #ffaa00; + --ng-amber-dim: rgba(255, 170, 0, 0.15); + --ng-red: #ff4455; + --ng-green: #00ff88; + --ng-card-bg: rgba(12, 18, 24, 0.72); + --ng-card-border: rgba(255, 255, 255, 0.07); + --ng-blur: blur(6px); + --ng-radius: 10px; + --ng-transition: 0.2s ease; +} + + +/* ───────────────────────────────────────────── + BASE — Background behavior + ───────────────────────────────────────────── */ + +/* Prevent any wrapper div from painting over the body background */ html, body, body > div { @@ -14,94 +39,343 @@ body { } /* Per-tab backgrounds */ -body.tab-glance { - background-image: url("/images/bg-glance.jpg") !important; -} +body.tab-glance { background-image: url("/images/bg-glance.jpg") !important; } +body.tab-pncharris { background-image: url("/images/pncharris-bg.png") !important; } +body.tab-netgrimoire { background-image: url("/images/Netgrimoire-bg.png") !important; } +body.tab-wasted-bandwidth{ background-image: url("/images/Wasted-bandwidth-bg.png") !important; } +body.tab-nucking-futz { background-image: url("/images/Nucking-futz-bg.png") !important; } -body.tab-pncharris { - background-image: url("/images/pncharris-bg.png") !important; -} - -body.tab-netgrimoire { - background-image: url("/images/Netgrimoire-bg.png") !important; -} - -body.tab-wasted-bandwidth { - background-image: url("/images/Wasted-bandwidth-bg.png") !important; -} - -body.tab-nucking-futz { - background-image: url("/images/Nucking-futz-bg.png") !important; -} - -/* ----------------------------- */ -/* Readability / tone-down layer */ -/* ----------------------------- */ - -/* Let more background show through (was 0.55) */ +/* Page overlay — keep background visible but readable */ #page-wrapper { - background-color: rgba(0, 0, 0, 0.40); + background-color: rgba(0, 0, 0, 0.42); } -/* Make service cards and widgets pop (but more transparent than before) */ -.service-card, + +/* ───────────────────────────────────────────── + SERVICE CARDS + ───────────────────────────────────────────── */ + +.service-card { + background: var(--ng-card-bg) !important; + backdrop-filter: var(--ng-blur); + border: 1px solid var(--ng-card-border) !important; + border-radius: var(--ng-radius) !important; + transition: border-color var(--ng-transition), + box-shadow var(--ng-transition), + transform var(--ng-transition); +} + +.service-card:hover { + border-color: var(--ng-teal-border) !important; + box-shadow: 0 0 14px var(--ng-teal-glow), + 0 4px 16px rgba(0, 0, 0, 0.4) !important; + transform: translateY(-2px); +} + +/* Service name */ +.service-card .service-name, +.service-card a { + color: rgba(255, 255, 255, 0.90) !important; + transition: color var(--ng-transition); +} + +.service-card:hover .service-name, +.service-card:hover a { + color: var(--ng-teal) !important; +} + +/* Description text */ +.service-card .service-description { + color: rgba(200, 210, 220, 0.55) !important; + font-size: 0.78rem; +} + + +/* ───────────────────────────────────────────── + WIDGETS + ───────────────────────────────────────────── */ + .widget { - background: rgba(20, 20, 20, 0.70) !important; /* was 0.85 */ - backdrop-filter: blur(2px); - border-radius: 10px; + background: var(--ng-card-bg) !important; + backdrop-filter: var(--ng-blur); + border: 1px solid var(--ng-card-border) !important; + border-radius: var(--ng-radius) !important; + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35); } -/* ----------------------------- */ -/* PNCHarris: narrow centered column */ -/* ----------------------------- */ +/* Monitoring / stats widget — teal accent */ +.widget[class*="uptimekuma"], +.widget[class*="portainer"], +.widget[class*="resources"] { + border-color: var(--ng-teal-border) !important; + box-shadow: 0 0 18px var(--ng-teal-glow), + 0 2px 12px rgba(0, 0, 0, 0.35) !important; +} + +/* Mailcow widget — amber accent (mail = caution) */ +.widget[class*="mailcow"] { + border-color: rgba(255, 170, 0, 0.25) !important; + box-shadow: 0 0 14px var(--ng-amber-dim), + 0 2px 12px rgba(0, 0, 0, 0.35) !important; +} + +/* Widget stat values */ +.widget .widget-value, +.widget [class*="value"] { + color: var(--ng-teal) !important; + font-variant-numeric: tabular-nums; +} + +/* Widget labels */ +.widget .widget-label, +.widget [class*="label"] { + color: rgba(180, 200, 210, 0.60) !important; + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.05em; +} + + +/* ───────────────────────────────────────────── + GROUP HEADERS + ───────────────────────────────────────────── */ + +/* Group title bar */ +.services-group > div:first-child, +[class*="group-name"], +[class*="group-title"] { + color: var(--ng-teal) !important; + font-size: 0.70rem !important; + font-weight: 600 !important; + letter-spacing: 0.12em !important; + text-transform: uppercase !important; + border-bottom: 1px solid var(--ng-teal-border) !important; + padding-bottom: 4px !important; + margin-bottom: 8px !important; + opacity: 0.85; +} + + +/* ───────────────────────────────────────────── + STATUS INDICATORS (used in widgets) + ───────────────────────────────────────────── */ + +.status-ok, [class*="status-up"], [class*="status-ok"] { color: var(--ng-green) !important; } +.status-warn, [class*="status-warn"], [class*="status-pend"] { color: var(--ng-amber) !important; } +.status-crit, [class*="status-down"], [class*="status-err"] { color: var(--ng-red) !important; } + + +/* ───────────────────────────────────────────── + GLOBAL WIDGETS BAR (top of page) + widgets.yaml renders here + ───────────────────────────────────────────── */ + +/* Resource widget nodes */ +#information-widgets .resources-widget { + background: rgba(12, 18, 24, 0.78) !important; + backdrop-filter: var(--ng-blur); + border: 1px solid var(--ng-teal-border) !important; + border-radius: var(--ng-radius) !important; + box-shadow: 0 0 20px var(--ng-teal-glow); +} + +/* Search bar */ +#information-widgets .search-widget input { + background: rgba(12, 18, 24, 0.80) !important; + border: 1px solid var(--ng-teal-border) !important; + border-radius: 6px !important; + color: #e0f0f0 !important; + transition: box-shadow var(--ng-transition), + border-color var(--ng-transition); +} + +#information-widgets .search-widget input:focus { + outline: none !important; + border-color: var(--ng-teal) !important; + box-shadow: 0 0 12px var(--ng-teal-dim) !important; +} + +/* Datetime / greeting */ +#information-widgets .datetime-widget, +#information-widgets .greeting-widget { + color: rgba(220, 240, 245, 0.85) !important; + text-shadow: 0 0 20px rgba(0, 229, 204, 0.25); +} + + +/* ───────────────────────────────────────────── + SCROLLBAR — match the aesthetic + ───────────────────────────────────────────── */ + +::-webkit-scrollbar { width: 6px; height: 6px; } +::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.2); } +::-webkit-scrollbar-thumb { background: var(--ng-teal-border); border-radius: 3px; } +::-webkit-scrollbar-thumb:hover { background: rgba(0, 229, 204, 0.45); } + + +/* ───────────────────────────────────────────── + TAB NAV + ───────────────────────────────────────────── */ + +/* Tab bar background */ +nav, [class*="topnav"], [class*="navbar"] { + background: rgba(6, 10, 14, 0.82) !important; + backdrop-filter: blur(10px) !important; + border-bottom: 1px solid rgba(0, 229, 204, 0.12) !important; +} + +/* Individual tab items */ +nav a, [class*="tab-link"] { + color: rgba(200, 220, 225, 0.70) !important; + transition: color var(--ng-transition); +} + +nav a:hover, nav a.active, [class*="tab-link"]:hover { + color: var(--ng-teal) !important; +} + +/* Active tab underline */ +nav a.active { + border-bottom: 2px solid var(--ng-teal) !important; +} + + +/* ───────────────────────────────────────────── + NETGRIMOIRE TAB — subtle column dividers + ───────────────────────────────────────────── */ + +body.tab-netgrimoire .services-group { + border-left: 2px solid rgba(0, 229, 204, 0.08); + padding-left: 10px; +} + + +/* ───────────────────────────────────────────── + WASTED-BANDWIDTH TAB — amber/pirate tone + ───────────────────────────────────────────── */ + +body.tab-wasted-bandwidth .service-card:hover { + border-color: rgba(255, 170, 0, 0.35) !important; + box-shadow: 0 0 14px var(--ng-amber-dim), + 0 4px 16px rgba(0, 0, 0, 0.4) !important; +} + +body.tab-wasted-bandwidth .service-card:hover .service-name, +body.tab-wasted-bandwidth .service-card:hover a { + color: var(--ng-amber) !important; +} + +body.tab-wasted-bandwidth [class*="group-name"], +body.tab-wasted-bandwidth [class*="group-title"], +body.tab-wasted-bandwidth .services-group > div:first-child { + color: var(--ng-amber) !important; + border-color: rgba(255, 170, 0, 0.25) !important; +} + + +/* ───────────────────────────────────────────── + NUCKING-FUTZ TAB — red/danger tone + ───────────────────────────────────────────── */ + +body.tab-nucking-futz .service-card:hover { + border-color: rgba(255, 68, 85, 0.40) !important; + box-shadow: 0 0 14px rgba(255, 68, 85, 0.12), + 0 4px 16px rgba(0, 0, 0, 0.4) !important; +} + +body.tab-nucking-futz .service-card:hover .service-name, +body.tab-nucking-futz .service-card:hover a { + color: var(--ng-red) !important; +} + +body.tab-nucking-futz [class*="group-name"], +body.tab-nucking-futz [class*="group-title"], +body.tab-nucking-futz .services-group > div:first-child { + color: var(--ng-red) !important; + border-color: rgba(255, 68, 85, 0.25) !important; +} + + +/* ───────────────────────────────────────────── + PNCHARRIS TAB — narrow centered column + ───────────────────────────────────────────── */ -/* Constrain the real content container */ body.tab-pncharris main { - max-width: 900px; /* adjust: 760px narrower, 1100px wider */ - margin: 0 auto !important; - padding-left: 16px; + max-width: 900px; + margin: 0 auto !important; + padding-left: 16px; padding-right: 16px; } -/* Some builds wrap groups/sections full-width; constrain them too */ body.tab-pncharris section, body.tab-pncharris .group { - max-width: 900px; - margin-left: auto !important; + max-width: 900px; + margin-left: auto !important; margin-right: auto !important; } -/* If cards are being forced to stretch, relax that on PNCHarris */ body.tab-pncharris .service-card, body.tab-pncharris .widget { - width: auto !important; + width: auto !important; max-width: 100% !important; } -/* ========================================================= */ -/* GLANCE TAB: ONLY make the Glance iframe bigger (safe) */ -/* ========================================================= */ -/* Optional: make Glance tab use full width */ +/* ───────────────────────────────────────────── + GLANCE TAB — fullscreen iframe + ───────────────────────────────────────────── */ + body.tab-glance main { - max-width: none !important; - margin: 0 !important; - padding-left: 12px !important; + max-width: none !important; + margin: 0 !important; + padding-left: 12px !important; padding-right: 12px !important; } -/* Force a single wide column on the Glance tab */ body.tab-glance .service-grid, body.tab-glance .services { grid-template-columns: 1fr !important; } -/* Make ONLY the glance iframe tall. - This avoids touching parent wrappers that can blank the iframe on some builds. */ +/* Target both old and new Glance URL */ body.tab-glance iframe[name="glance"], -body.tab-glance iframe[src*="home.netgrimoire.com"] { - width: 100% !important; - height: calc(100vh - 170px) !important; /* tweak 140–220px if needed */ - border: 0 !important; +body.tab-glance iframe[src*="home.netgrimoire.com"], +body.tab-glance iframe[src*="glance.netgrimoire.com"] { + width: 100% !important; + height: calc(100vh - 170px) !important; + border: 0 !important; display: block !important; } + + +/* ───────────────────────────────────────────── + IFRAME WIDGETS (ntfy, Beszel, etc.) + ───────────────────────────────────────────── */ + +.widget iframe { + border-radius: 8px !important; + border: 0 !important; + overflow: hidden; +} + + +/* ───────────────────────────────────────────── + UTILITY — fade-in on load + ───────────────────────────────────────────── */ + +@keyframes ng-fadein { + from { opacity: 0; transform: translateY(6px); } + to { opacity: 1; transform: translateY(0); } +} + +.service-card { + animation: ng-fadein 0.35s ease both; +} + +/* Stagger cards in each group */ +.service-card:nth-child(1) { animation-delay: 0.00s; } +.service-card:nth-child(2) { animation-delay: 0.04s; } +.service-card:nth-child(3) { animation-delay: 0.08s; } +.service-card:nth-child(4) { animation-delay: 0.12s; } +.service-card:nth-child(5) { animation-delay: 0.16s; } +.service-card:nth-child(6) { animation-delay: 0.20s; } \ No newline at end of file