/* ============================================================= NETGRIMOIRE HOMEPAGE — custom.css Aesthetic: Dark ops command center / arcane terminal ============================================================= */ /* ── 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 { background-color: transparent !important; } body { background-size: cover !important; background-position: center center !important; background-attachment: fixed !important; } /* Per-tab backgrounds */ 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; } /* Page overlay — keep background visible but readable */ #page-wrapper { background-color: rgba(0, 0, 0, 0.42); } /* ───────────────────────────────────────────── 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: 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); } /* 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 ───────────────────────────────────────────── */ body.tab-pncharris main { max-width: 900px; margin: 0 auto !important; padding-left: 16px; padding-right: 16px; } body.tab-pncharris section, body.tab-pncharris .group { max-width: 900px; margin-left: auto !important; margin-right: auto !important; } body.tab-pncharris .service-card, body.tab-pncharris .widget { width: auto !important; max-width: 100% !important; } /* ───────────────────────────────────────────── GLANCE TAB — fullscreen iframe ───────────────────────────────────────────── */ body.tab-glance main { max-width: none !important; margin: 0 !important; padding-left: 12px !important; padding-right: 12px !important; } body.tab-glance .service-grid, body.tab-glance .services { grid-template-columns: 1fr !important; } /* Target both old and new Glance URL */ body.tab-glance iframe[name="glance"], 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; }