Buttons: the per-location Save changes / Delete location buttons had no icons, unlike the apps-config action buttons. Add a save (floppy) icon and a trash icon so they match the reference; colour comes from the nebula button groups they already belong to. Theme refactor: move the theme-specific [data-theme="nebula"] button/topbar/CTA rules out of the shared css/themes.css and into themes/nebula/theme.css, where the README says theme overrides belong. css/themes.css keeps only the generic, non-theme-scoped defaults (solid status/accent buttons, danger-zone, warning-banner) shared by dark-blue/light. No behaviour change: the nebula file loads after css/themes.css so the moved rules still win. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
313 lines
13 KiB
CSS
313 lines
13 KiB
CSS
/* Nebula — default theme. Matches the loading/login aurora gradient. */
|
|
[data-theme="nebula"] {
|
|
/* Gradient stops (shared by surface-bg and install/login screens).
|
|
Three deep cosmic stops: indigo -> violet-blue -> ocean. */
|
|
--gradient-from: #1a1442;
|
|
--gradient-mid: #1b2a5e;
|
|
--gradient-to: #0f3b6e;
|
|
|
|
/* Surfaces */
|
|
--surface-bg: linear-gradient(135deg, var(--gradient-from) 0%, var(--gradient-mid) 50%, var(--gradient-to) 100%);
|
|
--surface-bg-solid: #0f1729;
|
|
--surface-elevated: rgba(255, 255, 255, 0.07);
|
|
--surface-sunken: rgba(0, 0, 0, 0.22);
|
|
--surface-hover: rgba(255, 255, 255, 0.10);
|
|
--surface-selected: rgba(0, 212, 255, 0.18);
|
|
|
|
/* Borders — bright enough to read as glass edges */
|
|
--border: rgba(255, 255, 255, 0.16);
|
|
--border-strong: rgba(255, 255, 255, 0.26);
|
|
--border-subtle: rgba(255, 255, 255, 0.08);
|
|
|
|
/* Text */
|
|
--text-primary: #ffffff;
|
|
--text-secondary: rgba(255, 255, 255, 0.82);
|
|
--text-muted: rgba(255, 255, 255, 0.65);
|
|
--text-on-accent: #0a1426;
|
|
|
|
/* Accent (cyan from the loading screen) */
|
|
--accent: #00d4ff;
|
|
--accent-hover: #0099cc;
|
|
--accent-soft: rgba(0, 212, 255, 0.15);
|
|
--accent-rgb: 0, 212, 255;
|
|
|
|
/* Status colors — stable across themes */
|
|
--status-success: #28a745;
|
|
--status-success-hover: #218838;
|
|
--status-success-rgb: 40, 167, 69;
|
|
--status-danger: #dc3545;
|
|
--status-danger-hover: #c82333;
|
|
--status-danger-rgb: 220, 53, 69;
|
|
--status-warning: #ffc107;
|
|
--status-warning-rgb: 255, 193, 7;
|
|
--status-info: #17a2b8;
|
|
--status-info-rgb: 23, 162, 184;
|
|
|
|
/* Theme-aware foreground RGB triplets for overlays */
|
|
--text-rgb: 255, 255, 255;
|
|
--bg-rgb: 0, 0, 0;
|
|
|
|
/* Components — cards LIFT off the gradient with a light glassy tint
|
|
instead of darkening it. The cyan undertone keeps them on-theme. */
|
|
--card-bg: linear-gradient(155deg, rgba(255, 255, 255, 0.09) 0%, rgba(0, 212, 255, 0.05) 100%);
|
|
--card-border: rgba(255, 255, 255, 0.16);
|
|
--card-shadow: 0 4px 18px rgba(0, 0, 0, 0.30), inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
|
--card-shadow-hover: 0 10px 32px rgba(0, 212, 255, 0.18), 0 4px 18px rgba(0, 0, 0, 0.40), inset 0 1px 0 rgba(255, 255, 255, 0.10);
|
|
--input-bg: rgba(255, 255, 255, 0.06);
|
|
--input-border: rgba(255, 255, 255, 0.18);
|
|
--input-text: #ffffff;
|
|
--console-bg: rgba(0, 0, 0, 0.40);
|
|
--console-text: #00d4ff;
|
|
--code-bg: rgba(255, 255, 255, 0.06);
|
|
--code-text: #e6f3ff;
|
|
--tooltip-bg: rgba(10, 20, 38, 0.95);
|
|
--tooltip-text: #ffffff;
|
|
|
|
/* Chrome — translucent so the cosmic gradient bleeds through.
|
|
The backdrop-filter on .topbar/.sidebar frosts them into glass. */
|
|
--topbar-bg: rgba(15, 25, 50, 0.40);
|
|
--topbar-text: #ffffff;
|
|
--topbar-border: rgba(255, 255, 255, 0.12);
|
|
--sidebar-bg: rgba(15, 25, 50, 0.30);
|
|
--sidebar-text: #ffffff;
|
|
--sidebar-border: rgba(255, 255, 255, 0.10);
|
|
|
|
/* Legacy aliases — kept so older style.css var() refs resolve */
|
|
--bg-primary: var(--topbar-bg);
|
|
--bg-secondary: var(--surface-elevated);
|
|
--bg-tertiary: var(--surface-hover);
|
|
--text-color: var(--text-primary);
|
|
--primary-color: var(--accent);
|
|
--primary-hover: var(--accent-hover);
|
|
--primary-color-rgb: var(--accent-rgb);
|
|
--border-color: var(--border);
|
|
--content-bg: var(--surface-bg);
|
|
--hover-bg: var(--surface-hover);
|
|
--error-color: var(--status-danger);
|
|
--danger-color: var(--status-danger);
|
|
}
|
|
|
|
/* Every rule below must be prefixed with [data-theme="nebula"] — the
|
|
theme-registry loads every theme's CSS file at boot, so unscoped
|
|
selectors here would apply on light / dark-blue / example as well. */
|
|
|
|
/* Notifications float over arbitrary content (apps grid, task logs, etc.),
|
|
so the default --card-bg gradient — designed for cards inside a container
|
|
— bleeds the page through them. Use the sidebar's navy with a much higher
|
|
opacity so the toast reads as a solid panel without losing the glass feel. */
|
|
[data-theme="nebula"] .notification {
|
|
background: rgba(15, 25, 50, 0.88);
|
|
border-color: rgba(255, 255, 255, 0.14);
|
|
backdrop-filter: blur(12px);
|
|
-webkit-backdrop-filter: blur(12px);
|
|
}
|
|
|
|
/* App-page tab strips: anchor every tab bar to the same surface as
|
|
the sidebar so the chrome reads as one coherent navy surface.
|
|
Using var(--sidebar-bg) directly so any future sidebar tweak
|
|
carries through. Covers all three tab places on the apps page:
|
|
1. .tab-navigation — main app tabs (Config / Services / …) and
|
|
the Backup-location sub-tabs (Local / Remote 1 / Remote 2).
|
|
2. .tabs-list inside .tabs-wrapper — config sub-tabs that the
|
|
app-config form renders inside the Config tab. */
|
|
[data-theme="nebula"] .tab-navigation,
|
|
[data-theme="nebula"] .tabs-wrapper .tabs-list,
|
|
[data-theme="nebula"] .tabs-content {
|
|
background: var(--sidebar-bg);
|
|
}
|
|
|
|
[data-theme="nebula"] .login-btn {
|
|
color: #ffffff;
|
|
}
|
|
|
|
/* "Back to Apps" — same translucent design as Update Configuration (btn-manage),
|
|
but tinted with the warning amber so it reads as a distinct secondary action. */
|
|
[data-theme="nebula"] .config-actions .btn-secondary,
|
|
[data-theme="nebula"] .console-actions .btn-secondary {
|
|
background: rgba(var(--status-warning-rgb), 0.20) !important;
|
|
color: var(--text-primary) !important;
|
|
border: 1px solid rgba(var(--status-warning-rgb), 0.55) !important;
|
|
text-shadow: none;
|
|
font-weight: 600 !important;
|
|
transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .config-actions .btn-secondary:hover:not(:disabled),
|
|
[data-theme="nebula"] .console-actions .btn-secondary:hover:not(:disabled) {
|
|
background: rgba(var(--status-warning-rgb), 0.35) !important;
|
|
border-color: rgba(var(--status-warning-rgb), 0.80) !important;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
/* Advanced badge — bump the red to a brighter coral pink so it pops
|
|
on the cosmic gradient. The theme --status-danger (#dc3545) reads
|
|
as muddy maroon against nebula's blue/indigo, similar to how
|
|
--status-success needed a lift to #86efac for task pills. */
|
|
[data-theme="nebula"] .is-advanced .domains-header h3::after,
|
|
[data-theme="nebula"] .is-advanced .config-category h3::after {
|
|
background: rgba(252, 165, 165, 0.18);
|
|
border-color: rgba(252, 165, 165, 0.65);
|
|
color: #fca5a5;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------
|
|
Outline + tint buttons — copied from the .service-button "Welcome"
|
|
recipe (rgba(<colour>, 0.10) bg + rgba(<colour>, 0.30) border +
|
|
neutral text). Topbar pills use that exact alpha for the light feel;
|
|
in-content CTAs (Install/Manage/Uninstall) bump the alphas a bit and
|
|
add a subtle coloured outer glow so they feel weightier without
|
|
becoming solid.
|
|
------------------------------------------------------------------ */
|
|
|
|
/* --- Topbar pills (light, transparent) --------------------------- */
|
|
[data-theme="nebula"] .topbar .donate-btn {
|
|
background: rgba(var(--accent-rgb), 0.10) !important;
|
|
color: var(--text-primary) !important;
|
|
border: 1px solid rgba(var(--accent-rgb), 0.30) !important;
|
|
box-shadow: none !important;
|
|
text-shadow: none;
|
|
font-weight: 600;
|
|
transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease, box-shadow 0.2s ease !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .topbar .donate-btn:hover:not(:disabled) {
|
|
background: rgba(var(--accent-rgb), 0.20) !important;
|
|
border-color: rgba(var(--accent-rgb), 0.55) !important;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
[data-theme="nebula"] .topbar .logout-btn {
|
|
background: rgba(var(--status-danger-rgb), 0.10) !important;
|
|
color: var(--text-primary) !important;
|
|
border: 1px solid rgba(var(--status-danger-rgb), 0.30) !important;
|
|
box-shadow: none !important;
|
|
text-shadow: none;
|
|
font-weight: 600;
|
|
transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease, box-shadow 0.2s ease !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .topbar .logout-btn:hover:not(:disabled) {
|
|
background: rgba(var(--status-danger-rgb), 0.20) !important;
|
|
border-color: rgba(var(--status-danger-rgb), 0.55) !important;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
/* --- Topbar active nav (App Center / etc.) — translucent pill ----
|
|
Replaces the solid var(--primary-color) fill so the active page
|
|
indicator matches the Donate / Logout pill style. */
|
|
[data-theme="nebula"] .topbar-nav .nav-item.nav-active,
|
|
[data-theme="nebula"] .topbar-nav .nav-item.active {
|
|
background: rgba(var(--accent-rgb), 0.18) !important;
|
|
color: var(--text-primary) !important;
|
|
border-color: rgba(var(--accent-rgb), 0.50) !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .topbar-nav .nav-item.nav-active:hover,
|
|
[data-theme="nebula"] .topbar-nav .nav-item.active:hover {
|
|
background: rgba(var(--accent-rgb), 0.28) !important;
|
|
color: var(--text-primary) !important;
|
|
border-color: rgba(var(--accent-rgb), 0.70) !important;
|
|
}
|
|
|
|
/* --- In-content CTAs (more solid than the topbar but still
|
|
transparent — alpha set above the body's accent-glow so the
|
|
brand colour reads clearly against Nebula's gradient.) ------- */
|
|
[data-theme="nebula"] .install-btn,
|
|
[data-theme="nebula"] .btn-install,
|
|
[data-theme="nebula"] .app-card .install-btn {
|
|
background: rgba(var(--status-success-rgb), 0.55) !important;
|
|
color: var(--text-primary) !important;
|
|
border: 1px solid rgba(var(--status-success-rgb), 0.90) !important;
|
|
text-shadow: none;
|
|
font-weight: 600 !important;
|
|
transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .install-btn:hover:not(:disabled),
|
|
[data-theme="nebula"] .btn-install:hover:not(:disabled),
|
|
[data-theme="nebula"] .app-card .install-btn:hover:not(:disabled) {
|
|
background: rgba(var(--status-success-rgb), 0.70) !important;
|
|
border-color: rgba(var(--status-success-rgb), 1.00) !important;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
/* "Open" button on installed app cards — same success recipe. */
|
|
[data-theme="nebula"] .service-trigger-icon {
|
|
background: rgba(var(--status-success-rgb), 0.35) !important;
|
|
color: var(--text-primary) !important;
|
|
border: 1px solid rgba(var(--status-success-rgb), 0.65) !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .service-trigger:hover .service-trigger-icon,
|
|
[data-theme="nebula"] .service-trigger.open .service-trigger-icon {
|
|
background: rgba(var(--status-success-rgb), 0.50) !important;
|
|
border-color: rgba(var(--status-success-rgb), 0.85) !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .uninstall-btn,
|
|
[data-theme="nebula"] .btn-uninstall,
|
|
[data-theme="nebula"] .btn-danger,
|
|
[data-theme="nebula"] .backup-danger-btn {
|
|
background: rgba(var(--status-danger-rgb), 0.35) !important;
|
|
color: var(--text-primary) !important;
|
|
border: 1px solid rgba(var(--status-danger-rgb), 0.65) !important;
|
|
text-shadow: none;
|
|
font-weight: 600 !important;
|
|
transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .uninstall-btn:hover:not(:disabled),
|
|
[data-theme="nebula"] .btn-uninstall:hover:not(:disabled),
|
|
[data-theme="nebula"] .btn-danger:hover:not(:disabled),
|
|
[data-theme="nebula"] .backup-danger-btn:hover:not(:disabled) {
|
|
background: rgba(var(--status-danger-rgb), 0.50) !important;
|
|
border-color: rgba(var(--status-danger-rgb), 0.85) !important;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
[data-theme="nebula"] .manage-btn,
|
|
[data-theme="nebula"] .btn-manage,
|
|
[data-theme="nebula"] .btn-primary,
|
|
[data-theme="nebula"] .backup-primary-btn,
|
|
[data-theme="nebula"] .app-card .manage-btn,
|
|
[data-theme="nebula"] .app-card-actions .manage-btn {
|
|
background: rgba(var(--accent-rgb), 0.35) !important;
|
|
color: var(--text-primary) !important;
|
|
border: 1px solid rgba(var(--accent-rgb), 0.65) !important;
|
|
text-shadow: none;
|
|
font-weight: 600 !important;
|
|
transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease !important;
|
|
}
|
|
|
|
[data-theme="nebula"] .manage-btn:hover:not(:disabled),
|
|
[data-theme="nebula"] .btn-manage:hover:not(:disabled),
|
|
[data-theme="nebula"] .btn-primary:hover:not(:disabled),
|
|
[data-theme="nebula"] .backup-primary-btn:hover:not(:disabled),
|
|
[data-theme="nebula"] .app-card .manage-btn:hover:not(:disabled),
|
|
[data-theme="nebula"] .app-card-actions .manage-btn:hover:not(:disabled) {
|
|
background: rgba(var(--accent-rgb), 0.50) !important;
|
|
border-color: rgba(var(--accent-rgb), 0.85) !important;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
[data-theme="nebula"] .install-btn:disabled,
|
|
[data-theme="nebula"] .btn-install:disabled,
|
|
[data-theme="nebula"] .uninstall-btn:disabled,
|
|
[data-theme="nebula"] .btn-uninstall:disabled,
|
|
[data-theme="nebula"] .manage-btn:disabled,
|
|
[data-theme="nebula"] .btn-manage:disabled,
|
|
[data-theme="nebula"] .btn-primary:disabled,
|
|
[data-theme="nebula"] .btn-danger:disabled,
|
|
[data-theme="nebula"] .topbar .donate-btn:disabled,
|
|
[data-theme="nebula"] .topbar .logout-btn:disabled {
|
|
opacity: 0.50;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* The cyan accent is bright enough that a dark glyph (text-on-accent
|
|
= #0a1426) still reads, but white matches nebula's white-on-glass
|
|
system better. */
|
|
[data-theme="nebula"] .tooltip::after {
|
|
color: #ffffff;
|
|
}
|