Files
Bjorn/web/css/pages.css
Fabien POLLY eb20b168a6 Add RLUtils class for managing RL/AI dashboard endpoints
- Implemented methods for fetching AI stats, training history, and recent experiences.
- Added functionality to set operation mode (MANUAL, AUTO, AI) with appropriate handling.
- Included helper methods for querying the database and sending JSON responses.
- Integrated model metadata extraction for visualization purposes.
2026-02-18 22:36:10 +01:00

10646 lines
218 KiB
CSS

/* ==========================================================================
pages.css — Page-specific styles for all SPA page modules.
Each section is scoped under the page's wrapper class to avoid conflicts.
========================================================================== */
/* ===== Page-specific variables (extends global.css tokens) ===== */
:root {
/* Bridge aliases used by multiple pages (Credentials, Loot, Files, Attacks) */
--_bg: var(--bg);
--_panel: var(--c-panel-2);
--_panel-hi: color-mix(in oklab, var(--c-panel-2) 96%, transparent);
--_panel-lo: color-mix(in oklab, var(--c-panel-2) 86%, transparent);
--_border: var(--c-border);
--_ink: var(--ink);
--_muted: var(--muted);
--_acid: var(--acid);
--_acid2: var(--acid-2);
--_shadow: var(--shadow);
/* NetKB chip colors */
--kb-hostname-bg: color-mix(in oklab, var(--acid) 16%, transparent);
--kb-ip-bg: color-mix(in oklab, var(--acid-2) 18%, transparent);
--kb-mac-bg: color-mix(in oklab, var(--muted) 10%, transparent);
--kb-vendor-bg: color-mix(in oklab, #b18cff 16%, transparent);
--kb-ports-bg: color-mix(in oklab, #5fd1ff 16%, transparent);
--kb-essid-bg: color-mix(in oklab, #00e6c3 16%, transparent);
--kb-offline-bg: color-mix(in oklab, var(--bg-2) 88%, black 12%);
--kb-offline-brd: color-mix(in oklab, var(--c-border-strong) 60%, transparent);
--kb-offline-ring: color-mix(in oklab, #ff5b5b 30%, transparent);
--kb-badge-shimmer: linear-gradient(90deg, transparent, rgba(255, 255, 255, .22), transparent);
/* Attacks page */
--tile-min: 160px;
--ok-glow: rgba(34, 197, 94, .45);
--ko-glow: rgba(239, 68, 68, .45);
}
/* ===== Shared sidebar layout (SPA parity with web_old) ===== */
.page-with-sidebar {
--page-sidebar-w: 280px;
position: relative;
display: flex;
gap: 12px;
min-height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 56px) - 24px);
align-items: stretch;
}
.page-with-sidebar .page-sidebar {
width: var(--page-sidebar-w);
flex: 0 0 var(--page-sidebar-w);
position: sticky;
top: 0;
align-self: stretch;
min-height: 100%;
max-height: none;
min-width: 0;
display: flex;
flex-direction: column;
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-card);
box-shadow: var(--shadow);
overflow: auto;
}
.page-with-sidebar .page-main {
min-width: 0;
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.page-with-sidebar .sidebar-toggle-btn {
display: inline-flex;
margin-bottom: 0;
align-self: auto;
}
.page-with-sidebar .sidebar-fab {
position: fixed;
right: 14px;
bottom: calc(var(--h-bottombar, 56px) + 14px);
z-index: 82;
border-radius: 999px;
width: 38px;
height: 38px;
min-width: 38px;
min-height: 38px;
padding: 0;
font-size: 16px;
color: var(--ink);
background: color-mix(in oklab, var(--c-panel) 88%, transparent);
border: 1px solid var(--c-border-strong);
box-shadow: 0 6px 16px rgba(0, 0, 0, .28);
opacity: .88;
}
.page-with-sidebar .sidebar-fab:hover {
opacity: 1;
transform: translateY(-1px);
}
.page-with-sidebar .sidebar-fab:active {
transform: translateY(0);
}
.page-sidebar-backdrop {
display: none;
position: fixed;
left: 0;
right: 0;
top: var(--h-topbar, 56px);
bottom: var(--h-bottombar, 56px);
background: rgba(0, 0, 0, .52);
border: 0;
z-index: 79;
}
.page-with-sidebar .sidehead {
padding: 10px;
border-bottom: 1px dashed var(--c-border);
display: flex;
align-items: center;
gap: 8px;
}
.page-with-sidebar .sidetitle {
font-weight: 800;
color: var(--acid);
letter-spacing: .05em;
}
.page-with-sidebar .sidecontent {
padding: 10px;
overflow: auto;
min-height: 0;
flex: 1;
}
.page-with-sidebar.sidebar-collapsed .page-sidebar {
width: 0;
flex-basis: 0;
padding: 0;
border-width: 0;
overflow: hidden;
}
@media (max-width: 900px) {
.page-with-sidebar {
min-height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 56px) - 12px);
}
.page-with-sidebar .sidebar-fab {
right: 10px;
bottom: calc(var(--h-bottombar, 56px) + 10px);
}
.sidebar-fab-unified {
position: fixed;
z-index: 82;
border-radius: 999px;
width: 38px;
height: 38px;
min-width: 38px;
min-height: 38px;
padding: 0;
font-size: 16px;
color: var(--ink);
background: color-mix(in oklab, var(--c-panel) 88%, transparent);
border: 1px solid var(--c-border-strong);
box-shadow: 0 6px 16px rgba(0, 0, 0, .28);
opacity: .88;
}
.sidebar-fab-unified:hover {
opacity: 1;
transform: translateY(-1px);
}
.sidebar-fab-unified:active {
transform: translateY(0);
}
.page-with-sidebar .page-sidebar {
position: fixed;
top: var(--h-topbar, 56px);
bottom: var(--h-bottombar, 56px);
left: 0;
z-index: 80;
width: min(86vw, 320px);
flex-basis: auto;
transform: translateX(-105%);
transition: transform .2s ease;
}
.page-with-sidebar.sidebar-open .page-sidebar {
transform: translateX(0);
}
.page-with-sidebar.sidebar-open .page-sidebar-backdrop {
display: block;
}
}
/* ===== DASHBOARD ===== */
.dashboard-container {
--gap: 12px;
--radius: 14px;
--pad: 12px;
--fs-meta: 12px;
--fs-title: 22px;
--glow-weak: color-mix(in oklab, var(--_acid2) 30%, transparent);
--glow-mid: color-mix(in oklab, var(--_acid2) 70%, transparent);
}
@media (min-width:1024px) {
.dashboard-container {
--gap: 14px;
--radius: 16px;
--pad: 14px;
--fs-title: 24px;
}
}
.dashboard-container .card {
border: 1px solid var(--c-border, var(--_border));
background: color-mix(in oklab, var(--_panel) 92%, transparent);
border-radius: var(--radius);
box-shadow: var(--_shadow);
padding: var(--pad);
backdrop-filter: saturate(1.05) blur(3px);
}
.dashboard-container .head {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
}
.dashboard-container .head .title {
font-size: var(--fs-title);
line-height: 1.1;
margin: 0;
}
.dashboard-container .head .meta {
color: var(--_muted);
font-size: var(--fs-meta);
}
.dashboard-container .pill {
font-size: 12px;
color: var(--_muted);
}
.dashboard-container .hero-grid {
display: grid;
gap: var(--gap);
grid-template-columns: 1fr;
}
@media (min-width:1024px) {
.dashboard-container .hero-grid {
grid-template-columns: minmax(240px, 320px) 1fr minmax(220px, 300px);
}
}
/* Battery naked */
.dashboard-container .battery-card.naked {
border: none;
background: transparent;
box-shadow: none;
padding: 0;
display: grid;
place-items: center;
}
.dashboard-container .battery-wrap {
position: relative;
width: clamp(180px, 46vw, 260px);
aspect-ratio: 1/1;
height: auto;
display: grid;
place-items: center;
}
.dashboard-container .battery-ring {
position: absolute;
left: 50%;
top: 50%;
width: 100%;
height: 100%;
transform: translate(-50%, -50%) rotate(-90deg);
display: block;
}
.dashboard-container .batt-bg {
fill: none;
stroke: color-mix(in oklab, var(--_ink) 10%, transparent);
stroke-width: 16;
opacity: .35;
}
.dashboard-container .batt-fg {
fill: none;
stroke: url(#batt-grad);
stroke-width: 16;
stroke-linecap: round;
filter: url(#batt-glow);
stroke-dasharray: 100;
stroke-dashoffset: 100;
transition: stroke-dashoffset .9s ease;
}
.dashboard-container .batt-scan {
fill: none;
stroke: var(--glow-mid);
stroke-width: 16;
stroke-linecap: round;
stroke-dasharray: 8 280;
opacity: .14;
transform-origin: 50% 50%;
animation: db-battSweep 2.2s linear infinite;
}
@keyframes db-battSweep {
to {
transform: rotate(360deg);
}
}
.dashboard-container .batt-center {
position: absolute;
inset: 0;
display: grid;
grid-template-rows: auto auto auto;
align-content: center;
justify-items: center;
gap: 6px;
padding: 6px;
text-align: center;
}
.dashboard-container .bjorn-portrait {
position: relative;
width: 64px;
height: 64px;
display: grid;
place-items: center;
overflow: hidden;
}
.dashboard-container .bjorn-portrait img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
opacity: .95;
}
.dashboard-container .bjorn-lvl {
position: absolute;
right: -4px;
bottom: -4px;
font-size: 11px;
font-weight: 700;
padding: 2px 6px;
border-radius: 999px;
background: #0f1f18;
color: #d9ffe7;
border: 1px solid color-mix(in oklab, var(--ok) 40%, var(--_border));
box-shadow: 0 0 8px var(--glow-weak);
}
.dashboard-container .batt-val {
font-size: clamp(18px, 5vw, 24px);
font-weight: 800;
text-shadow: 0 0 14px var(--glow-weak);
}
.dashboard-container .batt-state {
color: var(--_muted);
font-size: 11px;
display: flex;
align-items: center;
gap: 6px;
}
.dashboard-container .batt-indicator {
width: 16px;
height: 16px;
display: inline-grid;
place-items: center;
}
.dashboard-container .batt-indicator svg {
width: 18px;
height: 18px;
stroke: currentColor;
fill: none;
stroke-width: 2;
}
.dashboard-container .pulse {
animation: db-pulseGlow 1.4s ease-in-out infinite;
}
@keyframes db-pulseGlow {
0%,
100% {
transform: scale(1);
opacity: .9;
}
50% {
transform: scale(1.1);
opacity: 1;
filter: drop-shadow(0 0 6px var(--glow-mid));
}
}
/* Connectivity */
.dashboard-container .net-card .globe {
position: relative;
width: 84px;
height: 84px;
display: grid;
place-items: center;
background: color-mix(in oklab, var(--_panel) 92%, transparent);
}
.dashboard-container .globe svg {
display: block;
}
.dashboard-container .globe-rim {
fill: none;
stroke: color-mix(in oklab, var(--_ink) 18%, transparent);
stroke-width: 3;
}
.dashboard-container .globe-lines {
fill: none;
stroke: var(--_acid2);
stroke-opacity: .85;
stroke-width: 2;
stroke-linecap: round;
stroke-dasharray: 4 5;
animation: db-globeSpin 12s linear infinite;
transform-origin: 32px 32px;
}
@keyframes db-globeSpin {
to {
transform: rotate(360deg);
}
}
.dashboard-container .net-badge {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
border-radius: 999px;
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 90%, transparent);
font-weight: 700;
}
.dashboard-container .net-on {
color: color-mix(in oklab, var(--_ink) 94%, white);
background: var(--ok);
border-color: color-mix(in oklab, var(--ok) 60%, transparent);
text-shadow: 0 1px 0 rgba(0, 0, 0, .25);
}
.dashboard-container .net-off {
background: color-mix(in oklab, var(--danger, #ff4d6d) 12%, var(--_panel));
color: var(--_ink);
border-color: color-mix(in oklab, var(--danger, #ff4d6d) 50%, transparent);
box-shadow: inset 0 0 10px color-mix(in oklab, var(--danger, #ff4d6d) 35%, transparent);
}
.dashboard-container .conn-card .row {
display: grid;
grid-template-columns: 22px 1fr auto;
gap: 10px;
align-items: center;
padding: 8px;
border: 1px solid var(--_border);
border-radius: 12px;
background: color-mix(in oklab, var(--_panel) 96%, transparent);
}
.dashboard-container .conn-card .row+.row {
margin-top: 8px;
}
.dashboard-container .conn-card .icon {
width: 22px;
height: 22px;
display: grid;
place-items: center;
}
.dashboard-container .conn-card .icon svg {
width: 20px;
height: 20px;
stroke: var(--_muted);
fill: none;
stroke-width: 2;
}
/* LED physical indicators */
.dashboard-container .conn-card #row-wifi,
.dashboard-container .conn-card #row-bt,
.dashboard-container .conn-card #row-eth,
.dashboard-container .conn-card #row-usb {
grid-template-columns: 14px 22px 1fr auto;
}
.dashboard-container .conn-card #row-wifi::before,
.dashboard-container .conn-card #row-bt::before,
.dashboard-container .conn-card #row-eth::before,
.dashboard-container .conn-card #row-usb::before {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
justify-self: center;
background: #4a4f50;
box-shadow: 0 0 0 2px var(--_border) inset, 0 0 6px rgba(0, 0, 0, .35);
opacity: .9;
}
.dashboard-container .conn-card #row-wifi[data-physon]::before,
.dashboard-container .conn-card #row-bt[data-physon]::before,
.dashboard-container .conn-card #row-eth[data-physon]::before,
.dashboard-container .conn-card #row-usb[data-physon]::before {
background: var(--ok);
box-shadow: 0 0 0 2px color-mix(in oklab, var(--ok) 40%, transparent) inset, 0 0 12px var(--ok);
}
.dashboard-container .conn-card #row-wifi.err::before,
.dashboard-container .conn-card #row-bt.err::before,
.dashboard-container .conn-card #row-eth.err::before,
.dashboard-container .conn-card #row-usb.err::before {
background: var(--danger, #ff4d6d);
box-shadow: 0 0 12px var(--danger, #ff4d6d);
}
.dashboard-container .state-pill {
padding: 3px 8px;
border-radius: 999px;
font-size: 12px;
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 90%, transparent);
color: var(--_muted);
}
.dashboard-container .on .state-pill {
color: #d9ffe7;
background: color-mix(in oklab, var(--ok) 15%, #0f1f18);
border-color: color-mix(in oklab, var(--ok) 40%, var(--_border));
}
.dashboard-container .off .state-pill {
opacity: .8;
}
.dashboard-container .err .state-pill {
color: #ffdadd;
background: color-mix(in oklab, var(--danger, #ff4d6d) 15%, #2a1a1a);
border-color: color-mix(in oklab, var(--danger, #ff4d6d) 40%, var(--_border));
}
.dashboard-container .details {
color: var(--_muted);
font-size: 12px;
}
.dashboard-container .details .key {
color: var(--_ink);
font-weight: 600;
}
.dashboard-container .details .dim {
opacity: .85;
}
/* KPI cards */
.dashboard-container .kpi-cards {
display: grid;
gap: var(--gap);
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
margin-top: var(--gap);
}
.dashboard-container .kpi {
border: 1px solid var(--_border);
border-radius: var(--radius);
background: color-mix(in oklab, var(--_panel) 92%, transparent);
padding: var(--pad);
display: grid;
gap: 6px;
}
.dashboard-container .kpi .label {
color: var(--_muted);
font-size: 12px;
}
.dashboard-container .kpi .val {
font-size: 20px;
font-weight: 800;
}
.dashboard-container .bar {
position: relative;
width: 100%;
height: 8px;
border-radius: 999px;
overflow: hidden;
background: color-mix(in oklab, var(--_ink) 8%, transparent);
border: 1px solid var(--_border);
}
.dashboard-container .bar>i {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 0%;
background: linear-gradient(90deg, var(--_acid), var(--_acid2));
transition: width .25s ease;
}
.dashboard-container .bar>i.warm {
background: linear-gradient(90deg, color-mix(in oklab, var(--warning, #ffd166) 85%, #ffbe55), var(--warning, #ffd166));
}
.dashboard-container .bar>i.hot {
background: linear-gradient(90deg, color-mix(in oklab, var(--danger, #ff4d6d) 85%, #ff6b6b), var(--danger, #ff4d6d));
}
.dashboard-container .delta {
display: inline-flex;
gap: 6px;
align-items: center;
padding: 2px 8px;
border-radius: 999px;
font-size: 12px;
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 92%, transparent);
color: var(--_muted);
}
.dashboard-container .delta.good {
color: #d9ffe7;
background: color-mix(in oklab, var(--ok) 15%, #0f1f18);
border-color: color-mix(in oklab, var(--ok) 40%, var(--_border));
}
.dashboard-container .delta.bad {
color: #ffdadd;
background: color-mix(in oklab, var(--danger, #ff4d6d) 15%, #2a1a1a);
border-color: color-mix(in oklab, var(--danger, #ff4d6d) 40%, var(--_border));
}
.dashboard-container .submeta {
color: var(--_muted);
font-size: 12px;
}
/* ===== CREDENTIALS ===== */
.credentials-container {
display: flex;
flex-direction: column;
gap: 12px;
scroll-padding-top: 56px;
}
.credentials-container .stats-bar {
display: flex;
gap: 12px;
flex-wrap: wrap;
padding: 12px;
background: color-mix(in oklab, var(--_panel) 88%, transparent);
border: 1px solid var(--_border);
border-radius: 12px;
box-shadow: var(--_shadow);
backdrop-filter: blur(16px);
}
.credentials-container .stat-item {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border: 1px solid var(--_border);
border-radius: 10px;
background: color-mix(in oklab, var(--_panel) 70%, transparent);
}
.credentials-container .stat-icon {
font-size: 1.1rem;
opacity: .9;
}
.credentials-container .stat-value {
font-weight: 800;
background: linear-gradient(135deg, var(--_acid), var(--_acid2));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.credentials-container .stat-label {
color: var(--_muted);
font-size: .8rem;
}
.credentials-container .global-search-container {
position: relative;
}
.credentials-container .global-search-input {
width: 100%;
padding: 10px 14px;
border-radius: 12px;
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 90%, transparent);
color: var(--_ink);
}
.credentials-container .global-search-input:focus {
outline: none;
border-color: color-mix(in oklab, var(--_acid2) 40%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 18%, transparent);
}
.credentials-container .clear-global-button {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: none;
border: 1px solid var(--_border);
color: #ef4444;
border-radius: 8px;
padding: 2px 6px;
display: none;
}
.credentials-container .clear-global-button.show {
display: block;
}
.credentials-container .tabs-container {
position: sticky;
top: 0;
z-index: 20;
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
min-height: 44px;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
background: color-mix(in oklab, var(--_panel) 92%, transparent);
border: 1px solid var(--_border);
border-radius: 12px;
box-shadow: var(--_shadow);
}
.credentials-container .tabs-container::-webkit-scrollbar {
height: 0;
}
.credentials-container .tab {
padding: 10px 18px;
border-radius: 10px;
cursor: pointer;
color: var(--_muted);
font-weight: 700;
font-size: .9rem;
border: 1px solid transparent;
white-space: nowrap;
flex: 0 0 auto;
}
.credentials-container .tab:hover {
background: rgba(255, 255, 255, .05);
color: var(--_ink);
border-color: var(--_border);
}
.credentials-container .tab.active {
color: var(--_ink);
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid2) 18%, transparent), color-mix(in oklab, var(--_acid) 14%, transparent));
border-color: color-mix(in oklab, var(--_acid2) 28%, var(--_border));
}
.credentials-container .tab-badge {
margin-left: 8px;
padding: 2px 6px;
border-radius: 999px;
background: rgba(255, 255, 255, .1);
border: 1px solid var(--_border);
font-size: .75rem;
}
.credentials-container .services-grid {
display: flex;
flex-direction: column;
gap: 12px;
}
.credentials-container .service-card {
background: color-mix(in oklab, var(--_panel) 88%, transparent);
border: 1px solid var(--_border);
border-radius: 16px;
overflow: hidden;
box-shadow: var(--_shadow);
}
.credentials-container .service-header {
display: flex;
align-items: center;
gap: 8px;
padding: 12px;
cursor: pointer;
user-select: none;
border-bottom: 1px solid color-mix(in oklab, var(--_border) 65%, transparent);
}
.credentials-container .service-header:hover {
background: rgba(255, 255, 255, .04);
}
.credentials-container .service-title {
flex: 1;
font-weight: 800;
letter-spacing: .2px;
font-size: .95rem;
text-transform: uppercase;
background: linear-gradient(135deg, var(--_acid), var(--_acid2));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.credentials-container .service-count {
font-weight: 800;
font-size: .8rem;
padding: 4px 8px;
border-radius: 10px;
background: rgba(255, 255, 255, .08);
color: var(--_ink);
border: 1px solid var(--_border);
}
.credentials-container .service-card[data-credentials]:not([data-credentials="0"]) .service-count {
background: linear-gradient(135deg, #2e2e2e, #4CAF50);
box-shadow: inset 0 0 0 1px rgba(76, 175, 80, .35);
}
.credentials-container .search-container {
position: relative;
}
.credentials-container .search-input {
padding: 6px 24px 6px 8px;
border: none;
border-radius: 10px;
background: rgba(255, 255, 255, .06);
color: var(--_ink);
font-size: .82rem;
}
.credentials-container .search-input:focus {
outline: none;
background: rgba(255, 255, 255, .1);
}
.credentials-container .clear-button {
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
border: none;
background: none;
color: #ef4444;
cursor: pointer;
display: none;
}
.credentials-container .clear-button.show {
display: block;
}
.credentials-container .download-button {
border: 1px solid var(--_border);
background: rgba(255, 255, 255, .04);
color: var(--_muted);
border-radius: 8px;
padding: 4px 8px;
cursor: pointer;
}
.credentials-container .download-button:hover {
color: #e99f00;
filter: brightness(1.06);
}
.credentials-container .collapse-indicator {
color: var(--_muted);
}
.credentials-container .service-card.collapsed .service-content {
max-height: 0;
overflow: hidden;
}
.credentials-container .service-content {
padding: 8px 12px;
}
.credentials-container .credential-item {
border: 1px solid var(--_border);
border-radius: 10px;
margin-bottom: 6px;
padding: 8px;
background: rgba(255, 255, 255, .02);
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 8px;
}
.credentials-container .credential-field {
display: flex;
align-items: center;
gap: 6px;
}
.credentials-container .field-label {
font-size: .78rem;
color: var(--_muted);
}
.credentials-container .field-value {
flex: 1;
padding: 2px 6px;
border-radius: 8px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border: 1px solid transparent;
}
.credentials-container .field-value:hover {
background: rgba(255, 255, 255, .06);
border-color: var(--_border);
}
.credentials-container .bubble-blue {
background: linear-gradient(135deg, #1d2a32, #00c4d6);
color: #fff;
}
.credentials-container .bubble-green {
background: linear-gradient(135deg, #1e2a24, #00b894);
color: #fff;
}
.credentials-container .bubble-orange {
background: linear-gradient(135deg, #3b2f1a, #e7951a);
color: #fff;
}
.credentials-container .copied-feedback {
position: fixed;
left: 50%;
bottom: 20px;
transform: translateX(-50%);
padding: 8px 12px;
background: #4CAF50;
color: #fff;
border-radius: 10px;
box-shadow: var(--_shadow);
opacity: 0;
transition: opacity .25s;
z-index: 9999;
}
.credentials-container .copied-feedback.show {
opacity: 1;
}
/* ===== NETKB ===== */
.netkb-container {
display: grid;
gap: 16px;
}
.netkb-container .hidden {
display: none !important;
}
.netkb-container .netkb-toolbar-wrap {
position: sticky;
top: 0;
z-index: 500;
backdrop-filter: saturate(1.1) blur(6px);
}
.netkb-container .netkb-toolbar {
position: relative;
display: flex;
gap: 12px;
align-items: center;
justify-content: flex-end;
margin-bottom: 12px;
border: 1px solid var(--c-border-strong);
padding: 8px 10px;
box-shadow: var(--shadow);
background: var(--panel);
border-radius: 16px;
}
/* .segmented styles now inherited from global.css */
.netkb-container .kb-switch {
display: inline-flex;
align-items: center;
gap: 10px;
font-weight: 700;
color: var(--muted);
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 999px;
padding: 6px 10px;
}
.netkb-container .kb-switch input {
display: none;
}
.netkb-container .kb-switch .track {
width: 44px;
height: 24px;
border-radius: 999px;
background: var(--c-panel-2);
position: relative;
border: 1px solid var(--c-border);
}
.netkb-container .kb-switch .thumb {
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--ink);
box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
transition: left .18s ease, background .18s ease;
}
.netkb-container .kb-switch input:checked~.track .thumb {
left: 22px;
background: var(--acid);
}
.netkb-container .kb-switch[data-on="true"] {
color: var(--ink);
}
.netkb-container .icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 12px;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
box-shadow: var(--shadow);
cursor: pointer;
transition: transform .12s ease, box-shadow .12s ease;
}
.netkb-container .icon-btn:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-hover);
}
.netkb-container .icon-btn svg {
width: 20px;
height: 20px;
fill: var(--ink);
}
.netkb-container .search-pop {
position: absolute;
right: 8px;
top: 54px;
display: none;
min-width: 260px;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
border-radius: 12px;
padding: 10px;
box-shadow: var(--shadow-hover);
}
.netkb-container .search-pop.show {
display: block;
}
.netkb-container .search-input-wrap {
position: relative;
display: flex;
align-items: center;
}
.netkb-container .search-pop input {
width: 100%;
padding: 10px 32px 10px 12px;
border-radius: 10px;
border: 1px solid var(--c-border);
background: var(--c-panel-2);
color: var(--ink);
font-weight: 700;
outline: none;
}
.netkb-container .search-clear {
position: absolute;
right: 6px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
color: var(--muted);
font-size: 14px;
cursor: pointer;
border-radius: 50%;
transition: background .15s;
}
.netkb-container .search-clear:hover {
background: var(--c-border-strong);
color: var(--ink);
}
.netkb-container .search-hint {
margin-top: 6px;
font-size: .85rem;
color: var(--muted);
}
.netkb-container .card-container {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: stretch;
justify-content: center;
}
.netkb-container .card {
background: var(--grad-card);
color: var(--ink);
border: 1px solid var(--c-border-strong);
border-radius: 18px;
box-shadow: var(--shadow);
width: min(380px, 100%);
padding: 12px;
display: flex;
flex-direction: column;
gap: 10px;
transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease, background .15s ease;
}
.netkb-container .card:hover {
box-shadow: var(--shadow-hover);
border-color: var(--c-border-hi);
transform: translateY(-1px);
}
.netkb-container .card.alive .card-title {
color: var(--ok);
}
.netkb-container .card.not-alive {
background: var(--kb-offline-bg);
border-color: var(--kb-offline-brd);
color: color-mix(in oklab, var(--muted) 90%, var(--ink) 10%);
box-shadow: 0 0 0 1px var(--kb-offline-brd), 0 0 0 2px color-mix(in oklab, var(--kb-offline-ring) 26%, transparent), var(--shadow);
}
.netkb-container .card.not-alive .card-title {
color: color-mix(in oklab, var(--muted) 85%, var(--ink) 15%);
}
.netkb-container .card-content {
display: flex;
flex-direction: column;
gap: 6px;
flex: 1;
}
.netkb-container .card-title {
font-size: 1.1rem;
font-weight: 800;
margin: 0;
}
.netkb-container .card-section {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.netkb-container .card.list {
width: 100%;
max-width: none;
flex-direction: row;
align-items: center;
}
.netkb-container .card.list .card-title {
font-size: 1rem;
}
.netkb-container .chip {
display: inline-block;
padding: .32rem .7rem;
border-radius: 999px;
border: 1px solid var(--c-border-strong);
background: var(--kb-chip);
color: var(--ink);
font-weight: 700;
font-size: .92rem;
}
.netkb-container .chip.host {
background: var(--kb-hostname-bg);
}
.netkb-container .chip.ip {
background: var(--kb-ip-bg);
}
.netkb-container .chip.mac {
background: var(--kb-mac-bg);
color: var(--muted);
}
.netkb-container .chip.vendor {
background: var(--kb-vendor-bg);
}
.netkb-container .chip.essid {
background: var(--kb-essid-bg);
}
.netkb-container .chip.port {
background: var(--kb-ports-bg);
border-color: var(--c-border-hi);
}
.netkb-container .port-bubbles {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.netkb-container .status-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: center;
}
.netkb-container .badge {
background: var(--c-panel-2);
color: var(--ink);
border: 1px solid var(--c-border);
border-radius: 14px;
padding: 8px 10px;
min-width: 160px;
text-align: center;
box-shadow: var(--shadow);
transition: transform .12s ease, box-shadow .12s ease, opacity .12s ease;
position: relative;
}
.netkb-container .badge .badge-header {
font-weight: 800;
opacity: .95;
}
.netkb-container .badge .badge-status {
font-weight: 900;
}
.netkb-container .badge .badge-timestamp {
font-size: .85em;
opacity: .9;
}
.netkb-container .badge.clickable {
cursor: pointer;
}
.netkb-container .badge:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-hover);
}
.netkb-container .badge.success {
background: linear-gradient(180deg, color-mix(in oklab, var(--ok) 12%, transparent), transparent);
}
.netkb-container .badge.failed {
background: linear-gradient(180deg, color-mix(in oklab, var(--danger) 18%, transparent), transparent);
}
.netkb-container .badge.pending {
background: linear-gradient(180deg, color-mix(in oklab, var(--muted) 12%, transparent), transparent);
}
.netkb-container .badge.expired {
background: linear-gradient(180deg, color-mix(in oklab, var(--warning) 18%, transparent), transparent);
}
.netkb-container .badge.cancelled {
background: linear-gradient(180deg, color-mix(in oklab, var(--c-panel) 18%, transparent), transparent);
}
.netkb-container .badge.running {
background: linear-gradient(180deg, color-mix(in oklab, #18f0ff 14%, transparent), transparent);
overflow: hidden;
animation: kb-badgePulse 1.6s ease-in-out infinite;
}
.netkb-container .badge.running::after {
content: "";
position: absolute;
inset: 0;
background: var(--kb-badge-shimmer);
animation: kb-shimmer 1.8s linear infinite;
}
.netkb-container .badge.running::before {
content: "";
position: absolute;
inset: -20%;
background: linear-gradient(130deg, transparent 40%, rgba(255, 255, 255, .06) 50%, transparent 60%);
animation: kb-sheen 2.2s ease-in-out infinite;
}
@keyframes kb-shimmer {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
@keyframes kb-sheen {
0% {
transform: translateX(-30%);
}
100% {
transform: translateX(30%);
}
}
@keyframes kb-badgePulse {
0%,
100% {
box-shadow: 0 0 0 0 rgba(24, 240, 255, .12);
}
50% {
box-shadow: 0 0 0 8px rgba(24, 240, 255, .04);
}
}
.netkb-container .table-wrap {
border: 1px solid var(--c-border-strong);
border-radius: 14px;
overflow: auto;
background: var(--panel);
box-shadow: var(--shadow);
}
.netkb-container .table-inner {
min-width: max-content;
}
.netkb-container table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
}
.netkb-container thead th {
position: sticky;
top: 0;
z-index: 2;
background: var(--c-panel);
color: var(--ink);
border-bottom: 1px solid var(--c-border-strong);
padding: 10px;
text-align: left;
white-space: nowrap;
cursor: pointer;
}
.netkb-container tbody td {
border-bottom: 1px solid var(--c-border);
padding: 10px;
white-space: nowrap;
text-align: center;
}
.netkb-container th:first-child,
.netkb-container td:first-child {
position: sticky;
left: 0;
background: var(--panel);
z-index: 3;
}
.netkb-container .filter-icon {
width: 16px;
height: 16px;
margin-left: 6px;
vertical-align: middle;
}
.netkb-container mark.hl {
background: color-mix(in oklab, var(--acid) 25%, transparent);
color: var(--ink);
padding: 0 .15em;
border-radius: 4px;
}
.netkb-container .segmented button:focus-visible,
.netkb-container .icon-btn:focus-visible,
.netkb-container .kb-switch:has(input:focus-visible) {
outline: 2px solid var(--acid);
outline-offset: 2px;
box-shadow: 0 0 0 3px color-mix(in oklab, var(--acid) 25%, transparent);
}
@media (max-width:720px) {
.netkb-container {
min-width: 0;
max-width: 100%;
overflow: hidden;
}
.netkb-container .card {
width: 100%;
}
.netkb-container .segmented button[data-view="grid"] {
display: none;
}
.netkb-container .netkb-toolbar-wrap {
position: relative;
top: auto;
}
.netkb-container .netkb-toolbar {
flex-wrap: wrap;
justify-content: center;
gap: 8px;
}
.netkb-container .table-wrap {
display: block;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
max-width: 100%;
width: 100%;
box-sizing: border-box;
}
.netkb-container .table-inner>table {
min-width: 760px;
width: max-content;
}
.netkb-container thead th,
.netkb-container tbody td {
min-width: 80px;
font-size: .85rem;
padding: 8px 6px;
white-space: nowrap;
}
.netkb-container .chip {
font-size: .8rem;
padding: .25rem .5rem;
}
.netkb-container .badge {
min-width: 120px;
padding: 6px 8px;
}
}
/* ===== NETWORK ===== */
.network-container {
padding: 12px;
position: relative;
z-index: 2;
display: flex;
flex-direction: column;
min-height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 56px) - 16px);
}
.network-container .nv-toolbar-wrap {
position: sticky;
top: 0;
margin: 0 0 10px 0;
z-index: 500;
backdrop-filter: saturate(1.1) blur(6px);
}
.network-container .nv-toolbar {
display: flex;
gap: 12px;
align-items: center;
justify-content: space-between;
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 16px;
padding: 8px 10px;
box-shadow: var(--shadow);
}
.network-container .nv-search {
display: flex;
align-items: center;
gap: 8px;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
border-radius: 12px;
padding: 6px 10px;
min-width: 240px;
box-shadow: var(--shadow);
}
.network-container .nv-search-icon {
font-size: 16px;
flex-shrink: 0;
opacity: .9;
}
.network-container .nv-search input {
border: none;
outline: none;
background: transparent;
color: var(--ink);
font-weight: 700;
width: 100%;
min-width: 0;
}
.network-container .nv-search-clear {
flex-shrink: 0;
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
color: var(--muted);
font-size: 13px;
cursor: pointer;
border-radius: 50%;
transition: background .15s;
}
.network-container .nv-search-clear:hover {
background: var(--c-border-strong);
color: var(--ink);
}
.network-container .segmented {
display: inline-flex;
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 999px;
padding: 4px;
box-shadow: var(--shadow);
}
.network-container .segmented button {
appearance: none;
border: 0;
background: transparent;
color: var(--muted);
font-weight: 700;
padding: 8px 14px;
border-radius: 999px;
cursor: pointer;
transition: background .15s ease, color .15s ease, transform .1s ease;
}
.network-container .segmented button[aria-pressed="true"] {
background: var(--grad-card);
color: var(--ink);
box-shadow: inset 0 0 0 1px var(--c-border-hi), 0 6px 24px var(--glow-weak);
transform: translateY(-1px);
}
.network-container .nv-switch {
display: inline-flex;
align-items: center;
gap: 10px;
font-weight: 700;
color: var(--muted);
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 999px;
padding: 6px 10px;
box-shadow: var(--shadow);
}
.network-container .nv-switch input {
display: none;
}
.network-container .nv-switch .track {
width: 44px;
height: 24px;
border-radius: 999px;
background: var(--c-panel-2);
position: relative;
border: 1px solid var(--c-border);
}
.network-container .nv-switch .thumb {
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--ink);
box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
transition: left .18s ease, background .18s ease;
}
.network-container .nv-switch input:checked~.track .thumb {
left: 22px;
background: var(--acid);
}
.network-container .nv-switch[data-on="true"] {
color: var(--ink);
}
.network-container .table-wrap {
border: 1px solid var(--c-border-strong);
border-radius: 14px;
overflow: auto;
-webkit-overflow-scrolling: touch;
background: var(--c-panel, #0b1218);
box-shadow: var(--shadow);
flex: 1;
min-height: 0;
}
.network-container table.network-table {
width: 100%;
min-width: 860px;
table-layout: auto;
border-collapse: separate;
border-spacing: 0 .5rem;
}
.network-container thead th {
position: sticky;
top: 0;
z-index: 3;
background: var(--c-panel, #0b1218);
color: var(--ink);
border-bottom: 1px solid var(--c-border-strong);
padding: 10px;
text-align: left;
white-space: nowrap;
cursor: pointer;
border-radius: 8px;
}
.network-container tbody tr {
background: color-mix(in oklab, var(--c-panel, #0b1218) 95%, var(--acid) 5%);
border: 1px solid var(--c-border-strong);
border-radius: 8px;
transition: .25s ease;
}
.network-container tbody tr:hover {
background: color-mix(in oklab, var(--c-panel, #0b1218) 88%, var(--acid) 12%);
box-shadow: var(--shadow);
transform: translateY(-2px);
}
.network-container td {
padding: 10px;
color: var(--ink, #fff);
background: color-mix(in oklab, var(--c-panel, #0b1218) 96%, var(--acid) 4%);
vertical-align: top;
white-space: normal;
}
.network-container th.hosts-header {
left: 0;
position: sticky;
z-index: 4;
}
.network-container td.hosts-cell {
position: sticky;
left: 0;
z-index: 2;
background: color-mix(in oklab, var(--c-panel, #0b1218) 92%, var(--acid) 8%);
}
.network-container thead th.sort-asc::after {
content: '\2191';
margin-left: 8px;
color: #00b894;
}
.network-container thead th.sort-desc::after {
content: '\2193';
margin-left: 8px;
color: #00b894;
}
.network-container .hosts-content {
display: flex;
align-items: center;
gap: .55rem;
flex-wrap: wrap;
min-width: 320px;
}
.network-container .bubble {
padding: .5rem 1rem;
border-radius: 6px;
font-size: .9rem;
display: inline-flex;
align-items: center;
gap: .5rem;
transition: .2s;
box-shadow: 0 2px 4px rgba(0, 0, 0, .1);
}
.network-container .bubble.essid {
background: linear-gradient(135deg, #272727, #2560a1);
color: #fff;
padding: 5px 10px;
border-radius: 5px;
font-size: .9em;
font-weight: bold;
white-space: nowrap;
display: inline-block;
}
.network-container .bubble.ip-address {
background: linear-gradient(135deg, #272727, #00cec9);
color: #fff;
font-weight: 600;
cursor: pointer;
}
.network-container .bubble.hostname {
background: linear-gradient(135deg, #5b5c5a, #e7951a);
color: #fff;
cursor: pointer;
}
.network-container .bubble.mac-address {
background: linear-gradient(135deg, #404041, #636e72);
color: #b2bec3;
font-family: monospace;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.network-container .bubble.vendor {
background: linear-gradient(135deg, #5b5c5a, #0a4952);
color: #fff;
font-weight: 600;
cursor: pointer;
white-space: nowrap;
}
.network-container .ports-container {
display: flex;
flex-wrap: wrap;
gap: .45rem;
align-items: center;
min-width: 220px;
}
.network-container .port-bubble {
background: linear-gradient(135deg, #1f2c33, #00b894);
color: #eafff8;
padding: .4rem .8rem;
border-radius: 20px;
font-size: .85rem;
border: 1px solid color-mix(in oklab, #00b894 40%, transparent);
max-width: fit-content;
transition: .2s;
}
.network-container .port-bubble:hover {
transform: scale(1.08);
box-shadow: 0 2px 8px rgba(9, 132, 227, .3);
}
.network-container .segmented button:focus-visible,
.network-container .nv-search input:focus-visible,
.network-container .nv-switch:has(input:focus-visible) {
outline: 2px solid var(--acid);
outline-offset: 2px;
box-shadow: 0 0 0 3px color-mix(in oklab, var(--acid) 25%, transparent);
}
/* Ocean / Map */
.network-container .ocean-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 0;
pointer-events: none;
background: radial-gradient(ellipse at center, #0a4b7a 0%, #01162e 60%, #00050a 100%);
}
.network-container .ocean-surface {
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
opacity: 0.3;
background-image: repeating-radial-gradient(circle at 50% 50%, transparent 0, transparent 20px, rgba(255, 255, 255, 0.02) 25px, transparent 40px);
animation: nv-oceanDrift 60s linear infinite alternate;
}
.network-container .ocean-caustics {
position: absolute;
top: -100%;
left: -100%;
width: 300%;
height: 300%;
opacity: 0.3;
mix-blend-mode: overlay;
animation: nv-causticFlow 30s linear infinite;
}
@keyframes nv-oceanDrift {
0% {
transform: translate(0, 0) rotate(0deg);
}
100% {
transform: translate(-40px, 20px) rotate(1deg);
}
}
@keyframes nv-causticFlow {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-100px, -50px);
}
}
.network-container #visualization-container {
display: none;
position: relative;
min-height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 56px) - 100px);
height: 100%;
flex: 1;
border-radius: 14px;
overflow: hidden;
border: 1px solid var(--c-border-strong);
box-shadow: var(--shadow);
background: transparent;
}
.network-container .link {
stroke: rgba(255, 255, 255, 0.15);
stroke-width: 1px;
}
.network-container .node {
cursor: pointer;
transition: opacity 0.5s;
}
.network-container .foam-ring {
fill: rgba(240, 248, 255, 0.3);
mix-blend-mode: screen;
animation: nv-foamPulse 4s ease-in-out infinite alternate;
}
.network-container .foam-ring:nth-child(2) {
animation-delay: -1s;
opacity: 0.3;
}
@keyframes nv-foamPulse {
0% {
transform: scale(0.9) rotate(0deg);
opacity: 0.4;
}
100% {
transform: scale(1.1) rotate(10deg);
opacity: 0.1;
}
}
.network-container .sonar-wave {
fill: none;
stroke: #ffb703;
stroke-width: 2px;
animation: nv-sonar 4s infinite ease-out;
opacity: 0;
pointer-events: none;
}
@keyframes nv-sonar {
0% {
r: 40px;
opacity: 0.6;
stroke-width: 3px;
}
100% {
r: 300px;
opacity: 0;
stroke-width: 1px;
}
}
.network-container .label-group {
transition: transform 0.1s;
}
.network-container .label-bg {
fill: rgba(0, 20, 40, 0.8);
rx: 4;
stroke: rgba(255, 255, 255, 0.1);
stroke-width: 0.5px;
}
.network-container .label-text {
font-size: 10px;
fill: #fff;
font-family: monospace;
text-shadow: 0 1px 2px #000;
pointer-events: none;
}
.network-container .d3-tooltip {
position: absolute;
pointer-events: none;
opacity: 0;
background: rgba(2, 16, 31, 0.95);
border: 1px solid #219ebc;
padding: 12px;
border-radius: 8px;
font-size: 0.85rem;
color: #fff;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5);
transform: translate(-50%, -110%);
transition: opacity 0.2s;
white-space: nowrap;
z-index: 1000;
}
@media (max-width: 900px) {
.network-container .nv-toolbar {
flex-wrap: wrap;
justify-content: flex-start;
gap: 8px;
}
.network-container .nv-search {
min-width: 0;
flex: 1 1 220px;
}
.network-container .segmented {
order: 3;
}
.network-container table.network-table {
min-width: 700px;
}
.network-container .hosts-content {
min-width: 260px;
}
}
@media (max-width: 720px) {
.network-container {
padding: 8px;
}
.network-container .nv-toolbar {
padding: 8px;
}
.network-container table.network-table {
min-width: 620px;
border-spacing: 0 .35rem;
}
.network-container .bubble {
font-size: .82rem;
padding: .35rem .65rem;
}
.network-container .port-bubble {
font-size: .8rem;
padding: .34rem .62rem;
}
}
/* ==========================================================================
VULNERABILITIES
========================================================================== */
.vuln-container {
padding: var(--gap-4);
min-height: calc(100vh - var(--h-topbar) - var(--h-bottombar));
animation: vuln-fadeIn 0.5s ease-in;
}
@keyframes vuln-fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.vuln-container .stats-header {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: var(--gap-4);
margin-bottom: var(--gap-3);
}
.vuln-container .stat-card {
background: var(--grad-card);
border-radius: var(--radius);
padding: var(--gap-4);
text-align: center;
border: 1px solid var(--c-border);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
box-shadow: var(--elev);
}
.vuln-container .stat-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
animation: vuln-pulse 2s infinite;
}
.vuln-container .stat-card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-hover);
}
.vuln-container .stat-number {
font-size: 28px;
font-weight: bold;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 5px 0;
}
.vuln-container .stat-label {
font-size: 12px;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 1px;
}
.vuln-container .control-bar {
background: var(--grad-card);
border-radius: var(--radius);
padding: var(--gap-4);
margin-bottom: var(--gap-3);
display: flex;
flex-wrap: wrap;
gap: var(--gap-3);
align-items: center;
border: 1px solid var(--c-border);
box-shadow: var(--elev);
}
.vuln-container .search-box {
flex: 1;
min-width: 200px;
position: relative;
}
.vuln-container .search-input {
width: 100%;
height: var(--control-h);
padding: 0 40px 0 var(--control-pad-x);
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
border-radius: var(--control-r);
color: var(--ink);
font-size: 14px;
transition: all 0.3s ease;
}
.vuln-container .search-input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--glow-weak);
}
.vuln-container .clear-search {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--danger);
cursor: pointer;
font-size: 18px;
display: none;
transition: color 0.3s ease;
}
.vuln-container .clear-search:hover {
color: var(--acid-2);
}
.vuln-container .clear-search.show {
display: block;
}
.vuln-container .filter-buttons {
display: flex;
gap: var(--gap-3);
}
.vuln-container .filter-btn.active {
background: linear-gradient(90deg, var(--accent), var(--accent-2));
border-color: var(--accent);
}
.vuln-container .severity-filter {
display: flex;
gap: var(--gap-2);
}
.vuln-container .severity-btn.critical.active {
background: var(--danger);
border-color: var(--danger);
color: var(--white);
}
.vuln-container .severity-btn.high.active {
background: var(--warning);
border-color: var(--warning);
color: var(--ink-invert);
}
.vuln-container .severity-btn.medium.active {
background: var(--accent-2);
border-color: var(--accent-2);
color: var(--ink-invert);
}
.vuln-container .severity-btn.low.active {
background: var(--ok);
border-color: var(--ok);
color: var(--ink-invert);
}
.vuln-container .vuln-grid {
display: grid;
gap: var(--gap-4);
max-height: calc(100vh - 250px);
overflow-y: auto;
}
.vuln-container .vuln-card {
background: var(--grad-card);
border-radius: var(--radius);
border: 1px solid var(--c-border);
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
animation: vuln-slideIn 0.4s ease-out;
box-shadow: var(--elev);
}
@keyframes vuln-slideIn {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.vuln-container .vuln-card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-hover);
border-color: var(--accent);
}
.vuln-container .vuln-card.inactive {
opacity: 0.6;
border-color: var(--muted-off);
}
.vuln-container .vuln-header {
padding: var(--gap-4);
background: var(--grad-quickpanel);
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
user-select: none;
border-bottom: 1px solid var(--c-border);
}
.vuln-container .vuln-title {
display: flex;
align-items: center;
gap: var(--gap-3);
flex: 1;
}
.vuln-container .vuln-id {
font-weight: bold;
font-size: 14px;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.vuln-container .severity-badge {
padding: 4px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.5px;
animation: vuln-pulse 2s infinite;
}
@keyframes vuln-pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.7;
}
100% {
opacity: 1;
}
}
.vuln-container .severity-critical {
background: var(--danger);
color: var(--white);
}
.vuln-container .severity-high {
background: var(--warning);
color: var(--ink-invert);
}
.vuln-container .severity-medium {
background: var(--accent-2);
color: var(--ink-invert);
}
.vuln-container .severity-low {
background: var(--ok);
color: var(--ink-invert);
}
.vuln-container .vuln-meta {
display: flex;
gap: var(--gap-4);
font-size: 12px;
color: var(--muted);
}
.vuln-container .meta-item {
display: flex;
align-items: center;
gap: var(--gap-2);
}
.vuln-container .expand-icon {
color: var(--muted);
transition: transform 0.3s ease;
font-size: 18px;
}
.vuln-container .vuln-card.expanded .expand-icon {
transform: rotate(180deg);
}
.vuln-container .vuln-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
}
.vuln-container .vuln-card.expanded .vuln-content {
max-height: 1000px;
}
.vuln-container .vuln-details {
padding: var(--gap-4);
border-top: 1px solid var(--c-border);
background: var(--c-panel);
}
.vuln-container .detail-section {
margin-bottom: var(--gap-4);
}
.vuln-container .detail-title {
font-size: 12px;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: var(--gap-2);
font-weight: 600;
}
.vuln-container .detail-content {
font-size: 14px;
line-height: 1.6;
color: var(--ink);
}
.vuln-container .tags-container {
display: flex;
flex-wrap: wrap;
gap: var(--gap-2);
}
.vuln-container .tag {
padding: 4px 8px;
background: var(--c-chip-bg);
border: 1px solid var(--c-border);
border-radius: var(--gap-2);
font-size: 11px;
color: var(--muted);
}
.vuln-container .action-buttons {
display: flex;
gap: var(--gap-3);
padding: var(--gap-4);
border-top: 1px solid var(--c-border);
background: var(--c-panel-2);
}
.vuln-container .action-btn {
flex: 1;
justify-content: center;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.vuln-container .btn-remediate {
background: var(--ok);
border-color: var(--ok);
color: var(--ink-invert);
}
.vuln-container .btn-details {
background: var(--accent-2);
border-color: var(--accent-2);
color: var(--ink-invert);
}
.vuln-container .btn-export {
background: linear-gradient(90deg, var(--accent), var(--accent-2));
border-color: var(--accent);
color: var(--white);
}
/* Host view */
.vuln-container .host-card {
background: var(--grad-card);
border-radius: var(--radius);
border: 1px solid var(--c-border);
margin-bottom: var(--gap-4);
overflow: hidden;
animation: vuln-slideIn 0.4s ease-out;
box-shadow: var(--elev);
}
.vuln-container .host-header {
background: var(--grad-quickpanel);
padding: var(--gap-4);
cursor: pointer;
user-select: none;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--c-border);
}
.vuln-container .host-header:hover {
background: var(--grad-modal);
}
.vuln-container .host-info {
display: flex;
flex-direction: column;
gap: var(--gap-2);
}
.vuln-container .host-name {
font-size: 16px;
font-weight: bold;
color: var(--ink);
display: flex;
align-items: center;
gap: var(--gap-3);
}
.vuln-container .host-details {
display: flex;
gap: var(--gap-4);
font-size: 12px;
color: var(--muted);
}
.vuln-container .host-stats {
display: flex;
gap: var(--gap-3);
align-items: center;
}
.vuln-container .host-stat-badge {
padding: 5px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: bold;
display: flex;
align-items: center;
gap: var(--gap-2);
}
.vuln-container .host-vulns {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
}
.vuln-container .host-card.expanded .host-vulns {
max-height: 2000px;
}
.vuln-container .host-vuln-list {
padding: var(--gap-4);
background: var(--c-panel);
}
.vuln-container .host-vuln-item {
background: var(--c-panel-2);
border: 1px solid var(--c-border);
border-radius: var(--control-r);
padding: var(--gap-3);
margin-bottom: var(--gap-3);
display: flex;
justify-content: space-between;
align-items: center;
transition: all 0.3s ease;
}
.vuln-container .host-vuln-item:hover {
background: var(--grad-card);
border-color: var(--accent);
transform: translateX(5px);
}
.vuln-container .host-summary {
background: var(--grad-quickpanel);
padding: var(--gap-3);
border-radius: var(--control-r);
margin-bottom: var(--gap-3);
display: flex;
justify-content: space-around;
text-align: center;
}
.vuln-container .host-summary-item {
display: flex;
flex-direction: column;
gap: var(--gap-2);
}
.vuln-container .host-summary-value {
font-size: 18px;
font-weight: bold;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.vuln-container .host-summary-label {
font-size: 10px;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* Badges */
.vuln-container .badge-kev {
background: var(--danger);
padding: 2px 6px;
border-radius: 10px;
font-size: 10px;
color: var(--white);
font-weight: bold;
}
.vuln-container .badge-exploit {
background: linear-gradient(135deg, #9c27b0, #e1bee7);
padding: 2px 6px;
border-radius: 10px;
font-size: 10px;
color: var(--white);
font-weight: bold;
}
.vuln-container .badge-epss-high {
background: linear-gradient(135deg, var(--danger), var(--warning));
padding: 2px 6px;
border-radius: 10px;
font-size: 10px;
color: var(--white);
font-weight: bold;
}
.vuln-container .badge-epss-medium {
background: linear-gradient(135deg, var(--warning), var(--accent-2));
padding: 2px 6px;
border-radius: 10px;
font-size: 10px;
color: var(--white);
font-weight: bold;
}
/* Pagination */
.vuln-container .pagination {
display: flex;
justify-content: center;
gap: var(--gap-3);
margin-top: var(--gap-4);
padding: var(--gap-3);
}
.vuln-container .page-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.vuln-container .page-btn.active {
background: linear-gradient(90deg, var(--accent), var(--accent-2));
border-color: var(--accent);
color: var(--white);
}
.vuln-container .page-info {
display: flex;
align-items: center;
color: var(--muted);
font-size: 13px;
}
/* Modal */
.vuln-container .modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--glass-8);
z-index: 1000;
animation: vuln-fadeIn 0.3s ease;
}
.vuln-container .modal.show {
display: flex;
align-items: center;
justify-content: center;
}
.vuln-container .modal-content {
background: var(--grad-modal);
border-radius: var(--radius);
max-width: 800px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
animation: vuln-slideUp 0.3s ease;
border: 1px solid var(--c-border-strong);
box-shadow: var(--shadow-hover);
}
@keyframes vuln-slideUp {
from {
transform: translateY(50px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.vuln-container .modal-header {
padding: var(--gap-4);
border-bottom: 1px solid var(--c-border);
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
background: var(--grad-quickpanel);
z-index: 1;
}
.vuln-container .modal-title {
font-size: 18px;
font-weight: bold;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.vuln-container .close-modal {
background: none;
border: none;
color: var(--muted);
font-size: 24px;
cursor: pointer;
transition: color 0.3s ease;
}
.vuln-container .close-modal:hover {
color: var(--ink);
}
.vuln-container .modal-body {
padding: var(--gap-4);
}
@media (max-width:768px) {
.vuln-container .stats-header {
grid-template-columns: repeat(2, 1fr);
}
.vuln-container .control-bar {
flex-direction: column;
}
.vuln-container .search-box {
width: 100%;
}
.vuln-container .filter-buttons {
width: 100%;
justify-content: space-between;
}
.vuln-container .severity-filter {
width: 100%;
justify-content: space-between;
}
.vuln-container .vuln-header {
flex-direction: column;
align-items: flex-start;
gap: var(--gap-3);
}
.vuln-container .vuln-meta {
flex-direction: column;
gap: var(--gap-2);
}
.vuln-container .modal-content {
width: 95%;
max-height: 90vh;
}
}
/* ==========================================================================
SCHEDULER
========================================================================== */
.scheduler-container .toolbar-top {
position: sticky;
top: calc(var(--h-topbar, 0px) + 5px);
z-index: 60;
}
.scheduler-container .controls {
position: sticky;
top: 1px;
z-index: 50;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .5rem;
padding: .6rem .8rem;
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 14px;
margin: .6rem .6rem 0 .6rem;
box-shadow: var(--shadow);
backdrop-filter: saturate(1.05) blur(6px);
}
.scheduler-container .pill {
background: var(--panel);
border: 1px solid var(--c-border-strong);
color: var(--ink);
border-radius: 999px;
padding: .45rem .8rem;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
font-weight: 700;
transition: transform .15s ease, box-shadow .2s ease, background .2s ease, color .2s ease;
box-shadow: var(--shadow);
}
.scheduler-container .pill:hover {
transform: translateY(-1px);
box-shadow: 0 10px 26px rgba(0, 0, 0, .35);
}
.scheduler-container .pill.active {
background: var(--grad-card, linear-gradient(135deg, color-mix(in oklab, var(--panel) 92%, transparent), color-mix(in oklab, var(--c-panel) 88%, transparent)));
box-shadow: inset 0 0 0 1px var(--c-border-strong), 0 6px 24px var(--glow-weak);
}
.scheduler-container .controls input[type="text"] {
flex: 1 1 260px;
min-width: 200px;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
color: var(--ink);
border-radius: 10px;
padding: .5rem .7rem;
box-shadow: var(--shadow);
font-weight: 700;
outline: none;
}
.scheduler-container .controls input[type="text"]:focus-visible,
.scheduler-container .pill:focus-visible {
outline: 2px solid var(--acid);
outline-offset: 2px;
box-shadow: 0 0 0 3px color-mix(in oklab, var(--acid) 25%, transparent);
}
.scheduler-container .stats {
flex-basis: 100%;
margin-left: 0;
text-align: center;
color: var(--muted);
}
/* Board */
.scheduler-container .boardWrap {
height: calc(100vh - (var(--h-topbar, 0px) + 5px) - 56px - 52px);
overflow: auto;
}
.scheduler-container .board {
display: flex;
gap: 14px;
padding: 14px;
min-width: 960px;
}
.scheduler-container .lane {
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 16px;
width: 340px;
display: flex;
flex-direction: column;
box-shadow: var(--shadow);
min-height: 0;
}
.scheduler-container .laneHeader {
display: flex;
align-items: center;
gap: .6rem;
padding: .6rem .75rem;
border-bottom: 1px solid var(--c-border-strong);
border-top-left-radius: 16px;
border-top-right-radius: 16px;
background: linear-gradient(180deg, color-mix(in oklab, var(--panel) 96%, transparent), color-mix(in oklab, var(--panel) 88%, transparent));
position: sticky;
top: 0;
z-index: 5;
}
.scheduler-container .laneHeader .dot {
width: 10px;
height: 10px;
border-radius: 999px;
box-shadow: 0 0 0 1px rgba(255, 255, 255, .08) inset;
}
.scheduler-container .laneHeader .count {
margin-left: auto;
color: var(--muted);
font-size: .9rem;
}
.scheduler-container .laneBody {
padding: .6rem;
display: flex;
flex-direction: column;
gap: .6rem;
overflow: auto;
min-height: 0;
}
/* Status dot colors */
.scheduler-container .status-upcoming .laneHeader .dot {
background: var(--c-upcoming);
animation: sched-dotPulse 1.6s ease-in-out infinite;
}
.scheduler-container .status-pending .laneHeader .dot {
background: var(--c-pending);
}
.scheduler-container .status-running .laneHeader .dot {
background: var(--c-running);
animation: sched-dotPulse 1.6s ease-in-out infinite;
}
.scheduler-container .status-success .laneHeader .dot {
background: var(--c-success);
}
.scheduler-container .status-failed .laneHeader .dot {
background: var(--c-failed);
}
.scheduler-container .status-expired .laneHeader .dot {
background: var(--c-expired);
}
.scheduler-container .status-cancelled .laneHeader .dot {
background: var(--c-cancel);
}
@keyframes sched-dotPulse {
0%,
100% {
box-shadow: 0 0 0 0 rgba(74, 168, 255, 0);
}
50% {
box-shadow: 0 0 12px 3px rgba(74, 168, 255, .65);
}
}
/* Cards */
.scheduler-container .card {
position: relative;
border: 1px solid var(--c-border-strong);
border-radius: 12px;
padding: .7rem .75rem;
box-shadow: var(--shadow);
display: flex;
flex-direction: column;
gap: .45rem;
overflow: hidden;
transition: transform .15s ease, box-shadow .25s ease, filter .2s ease, background .25s ease;
will-change: transform, box-shadow, filter;
background: var(--c-panel);
}
.scheduler-container .card:hover {
transform: translateY(-1px);
box-shadow: 0 16px 36px rgba(0, 0, 0, .4);
}
.scheduler-container .card .infoBtn {
position: absolute;
top: 6px;
right: 6px;
z-index: 3;
width: 22px;
height: 22px;
line-height: 20px;
font-weight: 800;
text-align: center;
border-radius: 999px;
border: 1px solid var(--c-border-strong);
background: var(--panel);
color: var(--c-upcoming);
cursor: pointer;
user-select: none;
-webkit-user-select: none;
}
.scheduler-container .card .infoBtn:hover {
filter: brightness(1.1);
}
/* Card status backgrounds */
.scheduler-container .card.status-upcoming {
background: color-mix(in oklab, var(--c-upcoming) 12%, var(--c-panel));
animation: sched-breathe 2.6s ease-in-out infinite, sched-halo 2.6s ease-in-out infinite;
}
.scheduler-container .card.status-pending {
background: color-mix(in oklab, var(--c-pending) 10%, var(--c-panel));
animation: sched-breathe 2.6s ease-in-out infinite, sched-haloGray 2.8s ease-in-out infinite;
}
.scheduler-container .card.status-running {
background: color-mix(in oklab, var(--c-running) 12%, var(--c-panel));
animation: sched-pulse 1.8s ease-in-out infinite, sched-haloBlue 2s ease-in-out infinite;
}
.scheduler-container .card.status-success {
background: color-mix(in oklab, var(--c-success) 10%, var(--c-panel));
}
.scheduler-container .card.status-failed {
background: color-mix(in oklab, var(--c-failed) 10%, var(--c-panel));
}
.scheduler-container .card.status-expired {
background: color-mix(in oklab, var(--c-expired) 10%, var(--c-panel));
}
.scheduler-container .card.status-cancelled {
background: color-mix(in oklab, var(--c-cancel) 10%, var(--c-panel));
}
.scheduler-container .badge {
margin-left: auto;
border-radius: 999px;
padding: .15rem .6rem;
font-size: .75rem;
font-weight: 800;
color: #0a0d10;
}
.scheduler-container .card.status-upcoming .badge {
background: var(--c-upcoming);
}
.scheduler-container .card.status-pending .badge {
background: var(--c-pending);
}
.scheduler-container .card.status-running .badge {
background: var(--c-running);
}
.scheduler-container .card.status-success .badge {
background: var(--c-success);
}
.scheduler-container .card.status-failed .badge {
background: var(--c-failed);
}
.scheduler-container .card.status-expired .badge {
background: var(--c-expired);
}
.scheduler-container .card.status-cancelled .badge {
background: var(--c-cancel);
}
/* Collapsed */
.scheduler-container .card.collapsed .kv,
.scheduler-container .card.collapsed .tags,
.scheduler-container .card.collapsed .timer,
.scheduler-container .card.collapsed .meta,
.scheduler-container .card.collapsed .btns,
.scheduler-container .card.collapsed .notice {
display: none !important;
}
.scheduler-container .card.collapsed {
gap: .25rem;
padding: .4rem .5rem;
}
.scheduler-container .card.collapsed .actionIcon {
width: 80px;
height: 80px;
}
.scheduler-container .cardHeader {
display: flex;
align-items: center;
gap: .6rem;
}
.scheduler-container .actionName {
font-weight: 800;
letter-spacing: .2px;
}
.scheduler-container .actionIconWrap {
display: flex;
align-items: center;
justify-content: center;
margin-right: 8px;
}
.scheduler-container .actionIcon {
width: 80px;
height: 80px;
object-fit: contain;
border-radius: 6px;
background: var(--panel);
border: 1px solid var(--c-border);
}
.scheduler-container .card.status-running .actionIcon {
animation: sched-pulseIcon 1.2s ease-in-out infinite;
}
.scheduler-container .card.status-pending .actionIcon {
animation: sched-swayIcon 1.8s ease-in-out infinite;
}
.scheduler-container .card.status-upcoming .actionIcon {
animation: sched-blinkIcon 2s ease-in-out infinite;
}
@keyframes sched-pulseIcon {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.25);
}
}
@keyframes sched-swayIcon {
0%,
100% {
transform: rotate(0deg);
}
25% {
transform: rotate(-5deg);
}
75% {
transform: rotate(5deg);
}
}
@keyframes sched-blinkIcon {
0%,
100% {
opacity: 1;
}
50% {
opacity: .4;
}
}
.scheduler-container .kv {
display: flex;
flex-wrap: wrap;
gap: .45rem .8rem;
font-size: .9rem;
}
.scheduler-container .kv .k {
color: var(--muted);
}
.scheduler-container .tags {
display: flex;
flex-wrap: wrap;
gap: .35rem;
}
.scheduler-container .tag {
background: var(--panel);
color: var(--ink);
border: 1px solid var(--c-border-strong);
padding: .15rem .45rem;
border-radius: 999px;
font-size: .74rem;
box-shadow: var(--shadow);
}
.scheduler-container .meta {
color: color-mix(in oklab, var(--ink) 76%, #9aa7b2);
font-size: .82rem;
display: flex;
flex-wrap: wrap;
gap: .5rem .8rem;
}
.scheduler-container .btns {
display: flex;
flex-wrap: wrap;
gap: .4rem;
margin-top: .2rem;
}
.scheduler-container .btn {
background: var(--panel);
border: 1px solid var(--c-border-strong);
color: var(--ink);
padding: .35rem .6rem;
border-radius: 8px;
cursor: pointer;
}
.scheduler-container .btn:hover {
filter: brightness(1.08);
}
.scheduler-container .btn.danger {
background: color-mix(in oklab, #9c2b2b 22%, var(--panel));
border-color: #4a1515;
color: #ffd0d0;
}
.scheduler-container .btn.warn {
background: color-mix(in oklab, #9c6a2b 22%, var(--panel));
border-color: #5c2c0c;
color: #ffd8a8;
}
.scheduler-container .empty {
color: var(--muted);
text-align: center;
padding: .6rem;
}
@keyframes sched-pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.02);
}
}
@keyframes sched-breathe {
0%,
100% {
filter: brightness(1);
}
50% {
filter: brightness(1.07);
}
}
@keyframes sched-halo {
0%,
100% {
box-shadow: 0 0 12px rgba(156, 194, 255, .25);
}
50% {
box-shadow: 0 0 22px rgba(156, 194, 255, .45);
}
}
@keyframes sched-haloGray {
0%,
100% {
box-shadow: 0 0 12px rgba(187, 187, 187, .15);
}
50% {
box-shadow: 0 0 22px rgba(187, 187, 187, .3);
}
}
@keyframes sched-haloBlue {
0%,
100% {
box-shadow: 0 0 12px rgba(74, 168, 255, .25);
}
50% {
box-shadow: 0 0 26px rgba(74, 168, 255, .5);
}
}
/* Timer / Progress */
.scheduler-container .timer {
font-size: .82rem;
color: color-mix(in oklab, var(--ink) 80%, #bcd7ff);
display: flex;
align-items: center;
gap: .4rem;
}
.scheduler-container .timer .cd {
font-variant-numeric: tabular-nums;
}
.scheduler-container .progress {
height: 6px;
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 999px;
overflow: hidden;
}
.scheduler-container .progress .bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, var(--c-running), #00d8ff);
}
/* More button */
.scheduler-container .moreWrap {
display: flex;
justify-content: center;
}
.scheduler-container .moreBtn {
background: var(--panel);
border: 1px solid var(--c-border-strong);
color: var(--ink);
border-radius: 10px;
padding: .45rem .8rem;
cursor: pointer;
transition: transform .15s;
margin: .25rem auto 0;
box-shadow: var(--shadow);
}
.scheduler-container .moreBtn:hover {
transform: translateY(-1px);
}
/* Notice */
.scheduler-container .notice {
padding: .6rem .8rem;
color: #ffd9d6;
background: color-mix(in oklab, #7a3838 55%, var(--panel));
border-bottom: 1px solid #7a3838;
display: none;
border-radius: 12px;
margin: .6rem;
}
/* Chips */
.scheduler-container .chips {
display: flex;
flex-wrap: wrap;
gap: .35rem;
margin: .1rem 0 .2rem;
justify-content: center;
}
.scheduler-container .chip {
--h: 200;
display: inline-flex;
align-items: center;
gap: .4rem;
padding: .25rem .55rem;
border-radius: 999px;
font-size: .82rem;
font-weight: 800;
color: #fff;
letter-spacing: .2px;
background: linear-gradient(135deg, rgba(255, 255, 255, .06), rgba(0, 0, 0, .12)), hsl(var(--h), 65%, 34%);
border: 1px solid hsla(var(--h), 70%, 60%, .35);
box-shadow: 0 6px 16px rgba(0, 0, 0, .22), inset 0 1px 0 rgba(255, 255, 255, .06);
transition: transform .15s ease, box-shadow .2s ease, filter .2s ease;
}
.scheduler-container .chip:hover {
transform: translateY(-1px);
box-shadow: 0 10px 22px rgba(0, 0, 0, .28);
}
.scheduler-container .chip .k {
opacity: .85;
font-weight: 700;
}
/* History modal */
.scheduler-container .modalOverlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, .5);
display: none;
align-items: center;
justify-content: center;
z-index: 1000;
}
.scheduler-container .modal {
width: min(860px, 92vw);
max-height: 80vh;
background: var(--panel);
border: 1px solid var(--c-border-strong);
border-radius: 14px;
box-shadow: 0 20px 56px rgba(0, 0, 0, .6);
display: flex;
flex-direction: column;
overflow: hidden;
}
.scheduler-container .modalHeader {
display: flex;
align-items: center;
gap: .6rem;
padding: .6rem .8rem;
border-bottom: 1px solid var(--c-border-strong);
background: linear-gradient(180deg, color-mix(in oklab, var(--panel) 96%, transparent), color-mix(in oklab, var(--panel) 88%, transparent));
}
.scheduler-container .modalHeader .title {
font-weight: 900;
}
.scheduler-container .modalHeader .spacer {
flex: 1;
}
.scheduler-container .modalBody {
padding: .6rem .8rem;
overflow: auto;
display: flex;
flex-direction: column;
gap: .35rem;
}
.scheduler-container .modalFooter {
padding: .5rem .8rem;
border-top: 1px solid var(--c-border-strong);
display: flex;
gap: .5rem;
justify-content: flex-end;
color: var(--muted);
}
.scheduler-container .xBtn,
.scheduler-container .miniToggle {
background: var(--panel);
color: var(--ink);
border: 1px solid var(--c-border-strong);
border-radius: 8px;
padding: .35rem .6rem;
cursor: pointer;
}
.scheduler-container .xBtn:hover,
.scheduler-container .miniToggle:hover {
filter: brightness(1.08);
}
.scheduler-container #searchBox {
width: 100%;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
color: var(--ink);
border-radius: 10px;
padding: .5rem .7rem;
box-shadow: var(--shadow);
font-weight: 700;
outline: none;
}
.scheduler-container .histRow {
display: flex;
align-items: center;
gap: .6rem;
padding: .45rem .6rem;
border-radius: 10px;
border: 1px solid var(--c-border-strong);
background: color-mix(in oklab, var(--ink) 2%, var(--panel));
}
.scheduler-container .histRow .ts {
color: var(--muted);
font-variant-numeric: tabular-nums;
}
.scheduler-container .histRow .st {
font-weight: 900;
margin-left: auto;
padding: .1rem .5rem;
border-radius: 999px;
font-size: .75rem;
color: #0a0d10;
}
.scheduler-container .hist-success {
background: color-mix(in oklab, var(--c-success) 8%, var(--panel));
border-left: 3px solid var(--c-success);
}
.scheduler-container .hist-failed {
background: color-mix(in oklab, var(--c-failed) 8%, var(--panel));
border-left: 3px solid var(--c-failed);
}
.scheduler-container .hist-running {
background: color-mix(in oklab, var(--c-running) 8%, var(--panel));
border-left: 3px solid var(--c-running);
}
.scheduler-container .hist-pending,
.scheduler-container .hist-scheduled {
background: color-mix(in oklab, var(--c-pending) 8%, var(--panel));
border-left: 3px solid var(--c-pending);
}
.scheduler-container .hist-expired {
background: color-mix(in oklab, var(--c-expired) 8%, var(--panel));
border-left: 3px solid var(--c-expired);
}
.scheduler-container .hist-cancelled {
background: color-mix(in oklab, var(--c-cancel) 8%, var(--panel));
border-left: 3px solid var(--c-cancel);
}
.scheduler-container .hist-superseded {
background: color-mix(in oklab, var(--c-super) 8%, var(--panel));
border-left: 3px solid var(--c-super);
}
@media (max-width:920px) {
.scheduler-container .board {
flex-direction: column;
min-width: 0;
}
.scheduler-container .lane {
width: auto;
}
.scheduler-container .stats {
width: 100%;
margin-left: 0;
}
.scheduler-container .boardWrap {
height: auto;
min-height: calc(100vh - (var(--h-topbar, 0px) + 5px));
}
}
@media (prefers-reduced-motion: reduce) {
.scheduler-container .card,
.scheduler-container .laneHeader .dot {
animation: none !important;
}
}
/* ==========================================================================
ATTACKS (Management)
========================================================================== */
.attacks-container .tabs-container {
display: flex;
gap: 4px;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid var(--_border);
}
.attacks-container .attacks-sidebar>.tabs-container {
margin: 10px 10px 8px;
}
.attacks-container .attacks-sidebar>.sidebar-page {
flex: 1;
min-height: 0;
overflow: auto;
padding: 0 10px 10px;
}
.attacks-container .tab-btn {
flex: 1;
padding: 10px 8px;
border: none;
cursor: pointer;
font-size: 14px;
font-weight: 700;
border-radius: 10px 10px 0 0;
color: var(--_ink);
background: var(--_panel-lo);
transition: .2s;
border: 1px solid var(--_border);
border-bottom: none;
}
.attacks-container .tab-btn:hover {
background: var(--_panel-hi);
transform: translateY(-1px);
}
.attacks-container .tab-btn.active {
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid) 18%, transparent), color-mix(in oklab, var(--_acid2) 12%, transparent));
color: var(--_ink);
border-color: color-mix(in oklab, var(--_acid2) 28%, var(--_border));
}
.attacks-container .unified-list {
list-style: none;
margin: 0;
padding: 0;
}
.attacks-container .unified-list .card {
display: flex;
align-items: center;
gap: 12px;
padding: 10px;
margin-bottom: 6px;
cursor: pointer;
border-radius: 12px;
background: var(--_panel-lo);
transition: .2s;
border: 1px solid var(--_border);
box-shadow: none;
}
.attacks-container .unified-list .card:hover {
background: var(--_panel-hi);
transform: translateY(-1px);
box-shadow: var(--_shadow);
}
.attacks-container .unified-list .card.selected {
background: color-mix(in oklab, var(--_acid2) 16%, var(--_panel-hi));
border-color: color-mix(in oklab, var(--_acid2) 35%, var(--_border));
}
.attacks-container .unified-list .card img {
height: 50px;
width: 50px;
border-radius: 10px;
object-fit: cover;
background: #0b0e13;
border: 1px solid var(--_border);
}
.attacks-container .unified-list .card span {
flex: 1;
font-weight: 700;
color: var(--_ink);
}
.attacks-container .enable-dot {
--size: 14px;
width: var(--size);
height: var(--size);
border-radius: 999px;
border: 1px solid var(--_border);
background: var(--ko);
box-shadow: 0 0 0 0 var(--ko-glow);
transition: .18s ease;
flex: 0 0 auto;
cursor: pointer;
}
.attacks-container .enable-dot.on {
background: var(--ok);
box-shadow: 0 0 0 4px var(--ok-glow);
border-color: color-mix(in oklab, var(--ok) 45%, var(--_border));
}
.attacks-container .enable-dot:focus-visible {
outline: none;
box-shadow: 0 0 0 4px color-mix(in oklab, var(--_acid2) 45%, transparent);
}
.attacks-container .page-content {
display: none;
overflow: auto;
height: -webkit-fill-available;
}
.attacks-container .page-content.active {
display: block;
}
.attacks-container .editor-textarea-container {
display: flex;
flex-direction: column;
height: 100%;
gap: 12px;
}
.attacks-container .editor-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.attacks-container .editor-buttons {
display: flex;
gap: 8px;
}
.attacks-container .editor-textarea {
flex: 1;
min-height: 400px;
resize: vertical;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 14px;
color: var(--_ink);
background: var(--_panel-lo);
border: 1px solid var(--_border);
border-radius: 12px;
padding: 14px;
box-shadow: inset 0 0 0 1px transparent;
transition: .2s;
}
.attacks-container .editor-textarea:focus {
outline: none;
border-color: color-mix(in oklab, var(--_acid2) 30%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 18%, transparent);
background: var(--_panel-hi);
}
.attacks-container .actions-bar {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 20px;
position: sticky;
top: 0;
z-index: 10;
background: var(--_panel);
padding: 10px;
border-radius: 12px;
border: 1px solid var(--_border);
backdrop-filter: blur(10px);
}
.attacks-container .actions-bar button,
.attacks-container .chip,
.attacks-container .select,
.attacks-container .sort-toggle {
border-radius: 10px;
border: 1px solid var(--_border);
color: var(--_ink);
background: var(--_panel-lo);
padding: 10px 12px;
cursor: pointer;
transition: .2s;
font-weight: 700;
}
.attacks-container .actions-bar button:hover,
.attacks-container .chip:hover,
.attacks-container .select:hover,
.attacks-container .sort-toggle:hover {
background: var(--_panel-hi);
transform: translateY(-1px);
}
.attacks-container .actions-bar button.danger {
background: color-mix(in oklab, var(--_acid) 12%, var(--_panel-lo));
}
.attacks-container .actions-bar button.danger:hover {
background: color-mix(in oklab, var(--_acid) 18%, var(--_panel-hi));
}
.attacks-container .chip {
border-radius: 999px;
}
.attacks-container .field {
position: relative;
min-width: 190px;
}
.attacks-container .input {
width: 100%;
padding: 10px 12px 10px 36px;
color: var(--_ink);
background: var(--_panel-lo);
border: 1px solid var(--_border);
border-radius: 10px;
outline: none;
transition: .2s;
}
.attacks-container .input:focus {
border-color: color-mix(in oklab, var(--_acid2) 28%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 14%, transparent);
background: var(--_panel-hi);
}
.attacks-container .field .icon {
position: absolute;
left: 10px;
top: 9px;
opacity: .7;
pointer-events: none;
}
.attacks-container .select {
appearance: none;
}
.attacks-container .sort-toggle {
min-width: 42px;
text-align: center;
}
.attacks-container .range-wrap {
display: flex;
align-items: center;
gap: 8px;
}
.attacks-container .range {
accent-color: var(--_acid);
}
.attacks-container .image-container {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(var(--tile-min), 1fr));
padding-bottom: 140px;
}
.attacks-container .image-item {
position: relative;
border-radius: 12px;
overflow: hidden;
cursor: pointer;
aspect-ratio: 1/1;
transition: .2s;
background: var(--_panel-lo);
border: 1px solid var(--_border);
}
.attacks-container .image-item:hover {
transform: translateY(-2px);
box-shadow: var(--_shadow);
background: var(--_panel-hi);
}
.attacks-container .image-item img {
width: 100%;
height: 100%;
display: block;
object-fit: contain;
background: #0b0e13;
image-rendering: pixelated;
}
.attacks-container .image-info {
position: absolute;
inset: auto 0 0 0;
padding: 6px 8px;
text-align: center;
font-size: 12px;
color: var(--_ink);
background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .75));
}
.attacks-container .select-ring {
position: absolute;
inset: 0;
pointer-events: none;
border: 3px solid transparent;
border-radius: 12px;
transition: .2s;
}
.attacks-container .image-item.selectable:hover .select-ring {
border-color: color-mix(in oklab, var(--_acid2) 35%, transparent);
}
.attacks-container .image-item.selected .select-ring {
border-color: var(--_acid2);
box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--_acid2) 35%, transparent);
}
.attacks-container .tick-overlay {
position: absolute;
top: 8px;
right: 8px;
width: 26px;
height: 26px;
border-radius: 50%;
background: color-mix(in oklab, var(--_acid) 80%, white);
color: #001;
font-weight: 900;
display: none;
align-items: center;
justify-content: center;
box-shadow: var(--_shadow);
}
.attacks-container .image-item.selected .tick-overlay {
display: flex;
}
.attacks-container .skeleton {
border-radius: 12px;
aspect-ratio: 1/1;
background: linear-gradient(90deg, rgba(255, 255, 255, .03) 25%, rgba(255, 255, 255, .08) 37%, rgba(255, 255, 255, .03) 63%);
background-size: 400% 100%;
animation: atk-shimmer 1.1s infinite;
border: 1px solid var(--_border);
}
@keyframes atk-shimmer {
0% {
background-position: 100% 0;
}
100% {
background-position: 0 0;
}
}
.attacks-container .edit-only {
display: none;
}
.attacks-container .edit-mode .edit-only {
display: inline-flex;
}
.attacks-container .status-only {
display: none;
}
.attacks-container .static-only {
display: none;
}
.attacks-container .status-mode .status-only {
display: inline-block;
}
.attacks-container .static-mode .static-only {
display: inline-block;
}
.attacks-container .web-only {
display: none;
}
.attacks-container .icons-only {
display: none;
}
.attacks-container .web-mode .web-only {
display: inline-block;
}
.attacks-container .icons-mode .icons-only {
display: inline-block;
}
.attacks-container .comments-container {
display: flex;
flex: 1 1 auto;
min-height: 0;
}
.attacks-container .buttons-container {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
margin-bottom: 10px;
flex-wrap: wrap;
}
.attacks-container .buttons-container h2 {
margin-right: auto;
}
.attacks-container .comments-editor {
flex: 1 1 auto;
min-width: 0;
min-height: 0;
overflow: auto;
white-space: pre;
word-wrap: normal;
background: var(--_panel-lo);
color: var(--_ink);
border: 1px solid var(--_border);
border-radius: 12px;
padding: 16px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 14px;
}
.attacks-container .comments-editor:focus {
outline: none;
border-color: color-mix(in oklab, var(--_acid2) 30%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 14%, transparent);
background: var(--_panel-hi);
}
.attacks-container .comments-editor.placeholder {
color: var(--_muted);
}
.attacks-container .comment-line {
display: block;
width: 100%;
}
.attacks-container .comment-line:nth-child(odd) {
color: var(--_ink);
}
.attacks-container .comment-line:nth-child(even) {
color: var(--_acid);
}
.attacks-container .modal-action {
display: none;
position: fixed;
inset: 0;
z-index: 1000;
padding: 10px;
background: rgba(0, 0, 0, .6);
justify-content: center;
align-items: center;
}
.attacks-container .modal-content {
position: relative;
width: 100%;
max-width: 520px;
max-height: 90vh;
overflow-y: auto;
background: var(--_panel-hi);
padding: 20px;
border-radius: 14px;
border: 1px solid var(--_border);
box-shadow: var(--_shadow);
}
.attacks-container .modal-header h3 {
margin: 0 0 10px 0;
color: var(--_ink);
}
.attacks-container .modal-body {
margin-bottom: 20px;
}
.attacks-container .modal-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
.attacks-container .close {
position: absolute;
right: 10px;
top: 10px;
font-size: 24px;
cursor: pointer;
color: var(--_muted);
}
.attacks-container .form-group {
margin-bottom: 15px;
}
.attacks-container .form-group label {
display: block;
margin-bottom: 6px;
color: var(--_muted);
font-weight: 700;
}
.attacks-container .form-group input[type="text"],
.attacks-container .form-group input[type="number"],
.attacks-container .form-group input[type="file"] {
width: 100%;
padding: 10px 12px;
color: var(--_ink);
background: var(--_panel-lo);
border: 1px solid var(--_border);
border-radius: 10px;
outline: none;
transition: .2s;
}
.attacks-container .form-group input:focus {
border-color: color-mix(in oklab, var(--_acid2) 28%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 14%, transparent);
background: var(--_panel-hi);
}
.attacks-container .action-btn-container {
padding: 2px;
gap: 2px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: center;
justify-content: center;
align-items: center;
}
.attacks-container .hero-btn {
border-radius: 16px;
background: var(--grid), var(--grad-hero);
position: sticky;
bottom: 0;
border: 1px solid var(--c-border);
box-shadow: var(--shadow);
display: grid;
align-items: center;
justify-items: center;
text-align: center;
padding: 6px;
}
@media (max-width:480px) {
.attacks-container .tabs-container {
gap: 2px;
}
.attacks-container .tab-btn {
font-size: 13px;
padding: 8px 6px;
}
.attacks-container .actions-bar {
gap: 8px;
}
}
/* ==========================================================================
DATABASE
========================================================================== */
.db-container {
--db-row-hover: rgba(0, 255, 154, .06);
--db-row-selected: rgba(0, 255, 154, .12);
--db-cell-edited: rgba(24, 240, 255, .18);
--db-cell-focus: rgba(0, 255, 154, .22);
--sidebar-w: 280px;
min-height: 100%;
display: flex;
flex-direction: column;
}
.db-container .db-header {
position: sticky;
top: 0;
z-index: 20;
background: var(--grad-topbar);
border: 1px solid var(--c-border);
border-radius: 12px;
padding: 12px;
box-shadow: var(--shadow);
margin-bottom: 12px;
}
.db-container .sticky-actions {
position: sticky;
bottom: 0;
z-index: 15;
display: flex;
gap: 8px;
justify-content: flex-end;
padding: 8px;
background: linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, .4));
border-top: 1px solid var(--c-border);
border-radius: 12px;
backdrop-filter: blur(4px);
}
.db-container .db-tree {
display: grid;
gap: 6px;
}
.db-container .tree-head {
display: flex;
gap: 8px;
align-items: center;
margin-bottom: 8px;
}
.db-container .tree-search {
display: flex;
gap: 6px;
align-items: center;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
border-radius: 10px;
padding: 6px 8px;
}
.db-container .tree-search input {
all: unset;
flex: 1;
color: var(--ink);
}
.db-container .tree-group {
margin-top: 10px;
}
.db-container .tree-item {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
border: 1px solid var(--c-border);
border-radius: 10px;
background: var(--c-panel-2);
cursor: pointer;
transition: .18s;
}
.db-container .tree-item:hover {
box-shadow: 0 0 0 1px var(--c-border-hi) inset, 0 8px 22px var(--glow-weak);
transform: translateX(2px);
}
.db-container .tree-item.active {
background: linear-gradient(180deg, #0b151c, #091219);
outline: 2px solid color-mix(in oklab, var(--acid) 55%, transparent);
}
.db-container .tree-item .count {
margin-left: auto;
padding: 2px 8px;
border-radius: 999px;
background: var(--c-chip-bg);
border: 1px solid var(--c-border-hi);
font-size: 11px;
color: var(--muted);
}
.db-container .db-title {
display: flex;
align-items: center;
gap: 10px;
font-weight: 700;
color: var(--acid);
letter-spacing: .08em;
}
.db-container .db-controls {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 10px;
}
.db-container .db-search {
display: flex;
align-items: center;
gap: 8px;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
border-radius: 10px;
padding: 0 10px;
min-width: 220px;
flex: 1;
}
.db-container .db-search input {
all: unset;
color: var(--ink);
height: 34px;
flex: 1;
}
.db-container .db-opts {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.db-container .hint {
color: var(--muted);
font-size: 12px;
}
.db-container .sep {
width: 1px;
height: 24px;
background: var(--c-border);
margin: 0 4px;
opacity: .6;
}
.db-container .db-wrap {
display: flex;
flex-direction: column;
gap: 12px;
min-height: 0;
flex: 1;
}
.db-container .db-table-wrap {
position: relative;
overflow: auto;
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-card);
box-shadow: var(--shadow);
flex: 1;
min-height: 0;
}
.db-container table.db {
width: 100%;
border-collapse: separate;
border-spacing: 0;
}
.db-container .db-table-wrap table.db thead th {
position: sticky;
top: 0;
z-index: 5;
background: var(--c-panel);
border-bottom: 1px solid var(--c-border-strong);
text-align: left;
padding: 10px;
font-weight: 700;
color: var(--acid);
user-select: none;
-webkit-user-select: none;
cursor: pointer;
white-space: nowrap;
}
.db-container .db tbody td {
padding: 8px 10px;
border-bottom: 1px dashed var(--c-border-muted);
vertical-align: middle;
background: var(--grad-card);
}
.db-container .db tbody tr:hover {
background: var(--db-row-hover);
}
.db-container .db tbody tr.selected {
background: var(--db-row-selected);
outline: 1px solid var(--c-border-hi);
}
.db-container .cell {
display: block;
min-width: 80px;
max-width: 520px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.db-container .cell[contenteditable="true"] {
outline: 0;
border-radius: 6px;
transition: .12s;
padding: 2px 6px;
}
.db-container .cell[contenteditable="true"]:focus {
background: var(--db-cell-focus);
box-shadow: 0 0 0 1px var(--c-border-hi) inset;
}
.db-container .cell.edited {
background: var(--db-cell-edited);
}
.db-container .pk {
color: var(--muted);
font-size: 12px;
}
.db-container .cols-drawer {
display: none;
}
.db-container .cols-drawer.open {
display: block;
}
.db-container .db-page {
display: grid;
grid-template-columns: 1fr;
}
.db-container .sticky-col-cell {
position: sticky;
z-index: 3;
background: var(--grad-card);
box-shadow: 1px 0 0 0 var(--c-border-strong), -1px 0 0 0 var(--c-border);
}
.db-container .sticky-col-head {
position: sticky;
z-index: 3;
background: var(--grad-card);
box-shadow: 1px 0 0 0 var(--c-border-strong), -1px 0 0 0 var(--c-border);
}
.db-container .sticky-check,
.db-container .sticky-col-head.sticky-check {
z-index: 4;
}
.db-container th.is-sticky .sticky-dot::after {
content: "\25CF";
margin-left: 6px;
font-size: 10px;
color: var(--acid);
opacity: .9;
}
@keyframes db-blinkChange {
from {
box-shadow: 0 0 0 0 var(--acid-22);
}
to {
box-shadow: 0 0 0 6px transparent;
}
}
.db-container .value-changed {
animation: db-blinkChange .66s ease;
}
@media (max-width:1100px) {
.db-container .db-controls {
gap: 6px;
}
.db-container .db-search {
min-width: 160px;
}
.db-container .cell {
max-width: 60vw;
}
}
/* ==========================================================================
BJORN
========================================================================== */
.bjorn-container .image-container {
display: flex;
justify-content: center;
align-items: center;
height: calc(100vh - 70px);
}
.bjorn-container .image-container img {
max-height: 100%;
max-width: 100%;
height: -webkit-fill-available;
cursor: pointer;
transition: transform 0.2s ease-in-out;
}
.bjorn-container .image-container img:active {
transform: scale(1.05);
}
.bjorn-container .image-container.fullscreen img {
height: 100vh;
width: auto;
}
@media (max-width:768px) {
.bjorn-container .image-container {
height: calc(100vh - 60px);
}
}
/* ==========================================================================
LOOT
========================================================================== */
.loot-container {
position: relative;
z-index: 2;
padding: 16px;
margin-top: 5px;
min-height: calc(100vh - 60px);
display: flex;
flex-direction: column;
gap: 16px;
animation: loot-fadeInUp .6s ease-out;
}
@keyframes loot-fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.loot-container .stats-bar {
display: flex;
gap: 12px;
flex-wrap: wrap;
padding: 12px;
background: color-mix(in oklab, var(--_panel) 88%, transparent);
border: 1px solid var(--_border);
border-radius: 12px;
box-shadow: var(--_shadow);
backdrop-filter: blur(16px);
}
.loot-container .stat-item {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: color-mix(in oklab, var(--_panel) 65%, transparent);
border: 1px solid var(--_border);
border-radius: 10px;
transition: .2s;
}
.loot-container .stat-item:hover {
background: color-mix(in oklab, var(--_panel) 78%, transparent);
transform: translateY(-2px);
}
.loot-container .stat-icon {
font-size: 1.2rem;
opacity: .95;
}
.loot-container .stat-value {
font-size: 1.05rem;
font-weight: 800;
background: linear-gradient(135deg, var(--_acid), var(--_acid2));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.loot-container .stat-label {
color: var(--_muted);
font-size: .75rem;
margin-left: 4px;
}
.loot-container .controls-bar {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.loot-container .search-container {
flex: 1;
min-width: 200px;
position: relative;
}
.loot-container .search-input {
width: 100%;
padding: 12px 16px 12px 44px;
background: color-mix(in oklab, var(--_panel) 90%, transparent);
border: 1px solid var(--_border);
border-radius: 12px;
color: var(--_ink);
font-size: .95rem;
backdrop-filter: blur(10px);
transition: .2s;
}
.loot-container .search-input:focus {
outline: none;
border-color: color-mix(in oklab, var(--_acid2) 40%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 18%, transparent);
background: color-mix(in oklab, var(--_panel) 96%, transparent);
}
.loot-container .search-icon {
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
color: var(--_muted);
pointer-events: none;
}
.loot-container .clear-search {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--_muted);
cursor: pointer;
font-size: 1rem;
display: none;
}
.loot-container .search-input:not(:placeholder-shown)~.clear-search {
display: block;
}
.loot-container .view-controls {
display: flex;
gap: 8px;
align-items: center;
}
.loot-container .view-btn,
.loot-container .sort-btn {
padding: 10px;
background: color-mix(in oklab, var(--_panel) 90%, transparent);
border: 1px solid var(--_border);
border-radius: 10px;
color: var(--_muted);
cursor: pointer;
transition: .2s;
backdrop-filter: blur(10px);
font-size: 1.1rem;
}
.loot-container .view-btn:hover,
.loot-container .sort-btn:hover {
background: color-mix(in oklab, var(--_panel) 96%, transparent);
color: var(--_ink);
transform: translateY(-2px);
}
.loot-container .view-btn.active {
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid) 20%, transparent), color-mix(in oklab, var(--_acid2) 12%, transparent));
color: var(--_ink);
border-color: color-mix(in oklab, var(--_acid2) 35%, var(--_border));
}
.loot-container .sort-dropdown {
position: relative;
}
.loot-container .sort-menu {
position: absolute;
top: calc(100% + 8px);
right: 0;
background: color-mix(in oklab, var(--_panel) 98%, transparent);
border: 1px solid var(--_border);
border-radius: 12px;
padding: 8px;
min-width: 150px;
backdrop-filter: blur(20px);
box-shadow: var(--_shadow);
opacity: 0;
pointer-events: none;
transform: translateY(-10px);
transition: .2s;
z-index: 10;
}
.loot-container .sort-dropdown.active .sort-menu {
opacity: 1;
pointer-events: auto;
transform: translateY(0);
}
.loot-container .sort-option {
padding: 10px 12px;
border-radius: 8px;
cursor: pointer;
transition: .2s;
font-size: .9rem;
color: var(--_ink);
}
.loot-container .sort-option:hover {
background: rgba(255, 255, 255, .05);
}
.loot-container .sort-option.active {
color: var(--_ink);
background: color-mix(in oklab, var(--_acid2) 14%, transparent);
}
.loot-container .tabs-container {
display: flex;
gap: 8px;
padding: 4px;
background: color-mix(in oklab, var(--_panel) 88%, transparent);
border-radius: 12px;
border: 1px solid var(--_border);
backdrop-filter: blur(10px);
overflow-x: auto;
scrollbar-width: none;
}
.loot-container .tabs-container::-webkit-scrollbar {
display: none;
}
.loot-container .tab {
padding: 10px 20px;
border-radius: 8px;
cursor: pointer;
transition: .2s;
white-space: nowrap;
font-size: .9rem;
font-weight: 700;
position: relative;
color: var(--_muted);
border: 1px solid transparent;
}
.loot-container .tab:hover {
background: rgba(255, 255, 255, .05);
color: var(--_ink);
}
.loot-container .tab.active {
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid) 16%, transparent), color-mix(in oklab, var(--_acid2) 10%, transparent));
color: var(--_ink);
border-color: color-mix(in oklab, var(--_acid2) 28%, var(--_border));
}
.loot-container .tab.active::after {
content: '';
position: absolute;
bottom: 0;
left: 10%;
right: 10%;
height: 2px;
background: linear-gradient(90deg, var(--_acid), var(--_acid2));
border-radius: 2px;
}
.loot-container .tab-badge {
display: inline-block;
padding: 2px 6px;
margin-left: 6px;
background: rgba(255, 255, 255, .08);
border: 1px solid var(--_border);
border-radius: 10px;
font-size: .75rem;
font-weight: 700;
color: var(--_ink);
}
.loot-container .explorer {
background: color-mix(in oklab, var(--_panel) 88%, transparent);
border-radius: 20px;
border: 1px solid var(--_border);
backdrop-filter: blur(20px);
box-shadow: var(--_shadow);
overflow: hidden;
flex: 1;
display: flex;
flex-direction: column;
animation: loot-slideIn .6s ease-out;
}
@keyframes loot-slideIn {
from {
opacity: 0;
transform: translateX(-16px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.loot-container .explorer-content {
padding: 20px;
overflow-y: auto;
flex: 1;
max-height: calc(100vh - 280px);
}
.loot-container .tree-view {
display: none;
}
.loot-container .tree-view.active {
display: block;
}
.loot-container .list-view {
display: none;
}
.loot-container .list-view.active {
display: grid;
gap: 8px;
}
.loot-container .tree-item {
margin-bottom: 4px;
animation: loot-itemSlide .3s ease-out backwards;
}
@keyframes loot-itemSlide {
from {
opacity: 0;
transform: translateX(-10px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.loot-container .tree-header {
display: flex;
align-items: center;
padding: 12px;
cursor: pointer;
border-radius: 10px;
transition: .2s;
position: relative;
overflow: hidden;
}
.loot-container .tree-header::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .05), transparent);
transform: translateX(-100%);
transition: transform .6s;
}
.loot-container .tree-header:hover::before {
transform: translateX(100%);
}
.loot-container .tree-header:hover {
background: rgba(255, 255, 255, .04);
}
.loot-container .tree-icon {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
margin-right: 12px;
font-size: 1.1rem;
flex-shrink: 0;
background: color-mix(in oklab, var(--_acid) 12%, transparent);
color: var(--_ink);
}
.loot-container .folder-icon {
background: color-mix(in oklab, var(--_acid) 10%, transparent);
color: var(--_ink);
}
.loot-container .tree-name {
flex: 1;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.loot-container .tree-chevron {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
color: var(--_muted);
transition: transform .3s cubic-bezier(.4, 0, .2, 1);
margin-left: 8px;
}
.loot-container .tree-item.expanded .tree-chevron {
transform: rotate(90deg);
}
.loot-container .tree-children {
max-height: 0;
overflow: hidden;
transition: max-height .3s cubic-bezier(.4, 0, .2, 1);
margin-left: 20px;
padding-left: 20px;
border-left: 1px solid var(--_border);
}
.loot-container .tree-item.expanded .tree-children {
max-height: 5000px;
}
.loot-container .file-item {
display: flex;
align-items: center;
padding: 10px 12px;
border-radius: 10px;
cursor: pointer;
transition: .2s;
margin-bottom: 4px;
}
.loot-container .file-item:hover {
background: rgba(255, 255, 255, .04);
transform: translateX(4px);
}
.loot-container .file-item:active {
transform: translateX(2px) scale(.98);
}
.loot-container .file-icon {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
margin-right: 12px;
font-size: .9rem;
flex-shrink: 0;
color: var(--_ink);
background: color-mix(in oklab, var(--_panel) 75%, transparent);
}
.loot-container .file-icon.ssh {
background: color-mix(in oklab, var(--_acid) 12%, transparent);
}
.loot-container .file-icon.sql {
background: color-mix(in oklab, var(--_acid2) 12%, transparent);
}
.loot-container .file-icon.smb {
background: color-mix(in oklab, var(--_acid2) 16%, transparent);
}
.loot-container .file-icon.other {
background: color-mix(in oklab, var(--_panel) 75%, transparent);
}
.loot-container .file-name {
flex: 1;
font-size: .9rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--_ink);
}
.loot-container .file-type {
padding: 3px 8px;
border-radius: 6px;
font-size: .7rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: .05em;
margin-left: 8px;
border: 1px solid var(--_border);
color: var(--_ink);
background: color-mix(in oklab, var(--_panel) 80%, transparent);
}
.loot-container .file-type.ssh {
background: color-mix(in oklab, var(--_acid) 12%, transparent);
}
.loot-container .file-type.sql {
background: color-mix(in oklab, var(--_acid2) 12%, transparent);
}
.loot-container .file-type.smb {
background: color-mix(in oklab, var(--_acid2) 16%, transparent);
}
.loot-container .no-results {
text-align: center;
color: var(--_muted);
padding: 40px;
font-size: .95rem;
}
.loot-container .no-results-icon {
font-size: 3rem;
margin-bottom: 16px;
opacity: .5;
}
.loot-container .loading {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
}
.loot-container .loading-spinner {
width: 40px;
height: 40px;
border: 3px solid var(--_border);
border-top-color: var(--_acid2);
border-radius: 50%;
animation: loot-spin 1s linear infinite;
}
@keyframes loot-spin {
to {
transform: rotate(360deg);
}
}
@media (max-width:768px) {
.loot-container {
padding: 12px;
gap: 12px;
}
.loot-container .controls-bar {
flex-direction: column;
align-items: stretch;
}
.loot-container .search-container {
width: 100%;
}
.loot-container .view-controls {
justify-content: center;
}
.loot-container .tabs-container {
padding: 2px;
}
.loot-container .tab {
padding: 8px 14px;
font-size: .85rem;
}
.loot-container .explorer-content {
padding: 12px;
max-height: calc(100vh - 320px);
}
.loot-container .tree-children {
margin-left: 12px;
padding-left: 12px;
}
.loot-container .stat-item {
padding: 6px 10px;
}
.loot-container .stat-value {
font-size: .95rem;
}
}
@media (hover:none) {
.loot-container .tree-header:active {
background: rgba(255, 255, 255, .06);
}
}
/* ==========================================================================
FILES EXPLORER
========================================================================== */
.files-container .loot-container {
display: flex;
flex-direction: column;
height: calc(100vh - 120px);
padding: 12px;
gap: 12px;
}
.files-container .file-explorer {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 10px;
color: var(--_ink);
background: color-mix(in oklab, var(--_panel) 92%, transparent);
border: 1px solid var(--_border);
border-radius: 14px;
backdrop-filter: blur(18px);
box-shadow: var(--_shadow);
}
.files-container .files-grid {
overflow-y: auto;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
gap: 8px;
padding: 8px;
border-radius: 8px;
}
.files-container .files-list {
overflow-y: auto;
padding: 4px;
}
.files-container .upload-container {
padding: 10px;
margin-bottom: 10px;
display: flex;
justify-content: center;
align-items: center;
}
.files-container .drop-zone {
width: 100%;
max-width: 800px;
padding: 16px;
border: 2px dashed var(--_border);
border-radius: 12px;
text-align: center;
font-size: 14px;
color: var(--_muted);
cursor: pointer;
transition: .25s ease;
background: color-mix(in oklab, var(--_panel) 88%, transparent);
backdrop-filter: blur(8px);
}
.files-container .drop-zone:hover {
background: color-mix(in oklab, var(--_panel) 96%, transparent);
}
.files-container .drop-zone.dragover {
border-color: color-mix(in oklab, var(--_acid) 50%, var(--_border));
background: color-mix(in oklab, var(--_acid) 12%, var(--_panel));
color: var(--_ink);
}
.files-container .grid-item,
.files-container .list-item {
border-radius: 10px;
padding: 8px;
cursor: pointer;
transition: .15s ease;
display: flex;
align-items: center;
position: relative;
border: 1px solid transparent;
background: color-mix(in oklab, var(--_panel) 86%, transparent);
}
.files-container .grid-item {
flex-direction: column;
text-align: center;
}
.files-container .list-item {
flex-direction: row;
gap: 12px;
}
.files-container .grid-item:hover,
.files-container .list-item:hover {
transform: translateY(-2px);
border-color: color-mix(in oklab, var(--_acid2) 35%, var(--_border));
box-shadow: 0 4px 14px rgba(0, 0, 0, .25);
background: color-mix(in oklab, var(--_panel) 96%, transparent);
}
.files-container .grid-item img,
.files-container .list-item img {
width: 28px;
height: 28px;
margin-bottom: 4px;
}
.files-container .list-item img {
margin-bottom: 0;
}
.files-container .item-name {
color: var(--_ink);
font-size: 14px;
line-height: 1.3;
word-break: break-word;
pointer-events: none;
}
.files-container .folder .item-name {
color: var(--_ink);
font-weight: 700;
}
.files-container .item-meta {
font-size: 11px;
color: var(--_muted);
margin-top: 4px;
pointer-events: none;
}
.files-container .multi-select-mode {
background: color-mix(in oklab, var(--_acid) 6%, transparent);
}
.files-container .item-selected {
background: color-mix(in oklab, var(--_acid) 18%, var(--_panel)) !important;
border: 2px solid color-mix(in oklab, var(--_acid) 55%, var(--_border)) !important;
}
.files-container .context-menu {
position: absolute;
z-index: 1000;
background: color-mix(in oklab, var(--_panel) 98%, transparent);
border: 1px solid var(--_border);
border-radius: 10px;
padding: 6px 8px;
min-width: 160px;
color: var(--_ink);
box-shadow: var(--_shadow);
}
.files-container .context-menu>div {
padding: 8px 10px;
border-radius: 8px;
cursor: pointer;
}
.files-container .context-menu>div:hover {
background: color-mix(in oklab, var(--_acid2) 12%, transparent);
}
.files-container .search-container {
position: relative;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.files-container .search-input {
width: 100%;
padding: 10px 40px 10px 12px;
font-size: 14px;
border-radius: 10px;
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 90%, transparent);
color: var(--_ink);
box-sizing: border-box;
transition: .2s;
}
.files-container .search-input:focus {
outline: none;
border-color: color-mix(in oklab, var(--_acid2) 35%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 18%, transparent);
background: color-mix(in oklab, var(--_panel) 96%, transparent);
}
.files-container .search-input::placeholder {
color: color-mix(in oklab, var(--_muted) 70%, transparent);
}
.files-container .clear-button {
position: absolute;
right: 12px;
background: none;
border: none;
color: color-mix(in oklab, var(--_acid) 55%, var(--_ink));
font-size: 16px;
cursor: pointer;
display: none;
}
.files-container .clear-button.show {
display: block;
}
.files-container .toolbar-buttons {
display: flex;
gap: 8px;
margin-bottom: 10px;
flex-wrap: wrap;
}
.files-container .action-button {
background: color-mix(in oklab, var(--_panel) 90%, transparent);
border: 1px solid var(--_border);
color: var(--_muted);
padding: 8px 10px;
border-radius: 10px;
cursor: pointer;
font-size: 14px;
font-weight: 700;
display: flex;
align-items: center;
gap: 6px;
transition: .2s;
backdrop-filter: blur(10px);
}
.files-container .action-button:hover {
background: color-mix(in oklab, var(--_panel) 96%, transparent);
color: var(--_ink);
transform: translateY(-2px);
}
.files-container .action-button.active {
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid) 18%, transparent), color-mix(in oklab, var(--_acid2) 10%, transparent));
color: var(--_ink);
border-color: color-mix(in oklab, var(--_acid2) 28%, var(--_border));
}
.files-container .action-button.delete {
background: color-mix(in oklab, var(--_acid) 14%, var(--_panel));
color: var(--_ink);
display: none;
border-color: color-mix(in oklab, var(--_acid) 40%, var(--_border));
}
.files-container .action-button.delete.show {
display: flex;
}
.files-container .modal {
display: block;
position: fixed;
inset: 0;
z-index: 1000;
background: rgba(0, 0, 0, .5);
}
.files-container .modal-content {
background: color-mix(in oklab, var(--_panel) 98%, transparent);
color: var(--_ink);
margin: 12vh auto;
padding: 20px;
width: min(500px, 92vw);
border: 1px solid var(--_border);
border-radius: 14px;
box-shadow: var(--_shadow);
}
.files-container .modal-buttons {
margin-top: 18px;
text-align: right;
display: flex;
gap: 8px;
justify-content: flex-end;
}
.files-container .modal-buttons button {
margin-left: 0;
padding: 8px 14px;
border-radius: 10px;
border: 1px solid var(--_border);
cursor: pointer;
background: color-mix(in oklab, var(--_panel) 92%, transparent);
color: var(--_ink);
}
.files-container .modal-buttons button:hover {
background: color-mix(in oklab, var(--_panel) 98%, transparent);
}
.files-container .modal-buttons .primary {
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid) 18%, transparent), color-mix(in oklab, var(--_acid2) 10%, transparent));
border-color: color-mix(in oklab, var(--_acid2) 35%, var(--_border));
color: var(--_ink);
}
.files-container #folder-tree {
border: 1px solid var(--_border);
border-radius: 10px;
padding: 8px;
margin: 10px 0;
max-height: 320px;
overflow-y: auto;
background: color-mix(in oklab, var(--_panel) 92%, transparent);
}
.files-container .folder-item {
padding: 8px 10px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
border-radius: 8px;
}
.files-container .folder-item:hover {
background: color-mix(in oklab, var(--_panel) 98%, transparent);
}
.files-container .folder-item.selected {
background: color-mix(in oklab, var(--_acid2) 16%, transparent);
outline: 1px solid color-mix(in oklab, var(--_acid2) 35%, var(--_border));
}
.files-container .folder-item i {
color: var(--_muted);
}
.files-container .path-navigator {
padding: 8px;
margin-bottom: 8px;
border-radius: 10px;
display: flex;
align-items: center;
gap: 8px;
background: color-mix(in oklab, var(--_panel) 90%, transparent);
border: 1px solid var(--_border);
}
.files-container .nav-buttons {
display: flex;
gap: 8px;
}
.files-container .back-button {
background: color-mix(in oklab, var(--_panel) 92%, transparent);
border: 1px solid var(--_border);
color: var(--_muted);
padding: 8px 12px;
border-radius: 10px;
cursor: pointer;
font-weight: 700;
display: flex;
align-items: center;
gap: 6px;
min-width: 40px;
min-height: 40px;
justify-content: center;
transition: .2s;
}
.files-container .back-button:hover {
background: color-mix(in oklab, var(--_panel) 98%, transparent);
color: var(--_ink);
}
.files-container .current-path {
display: flex;
align-items: center;
gap: 6px;
overflow: hidden;
flex-wrap: wrap;
}
.files-container .path-segment {
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid) 16%, transparent), color-mix(in oklab, var(--_acid2) 10%, transparent));
color: var(--_ink);
padding: 6px 10px;
border-radius: 10px;
cursor: pointer;
transition: .2s;
border: 1px solid color-mix(in oklab, var(--_acid2) 28%, var(--_border));
}
.files-container .path-segment:hover {
filter: brightness(1.08);
}
@media (max-width:420px) {
.files-container .loot-container {
height: 80vh;
}
.files-container .file-explorer {
max-height: 40vh;
}
.files-container .files-grid {
max-height: 40vh;
}
.files-container .drop-zone {
padding: 18px;
font-size: 15px;
}
.files-container .toolbar-buttons {
padding: 4px;
gap: 6px;
}
.files-container .search-container,
.files-container .path-navigator {
padding: 4px;
}
.files-container .grid-item {
min-height: 74px;
font-size: 12px;
}
.files-container .item-name {
font-size: 13px;
margin-top: 2px;
}
.files-container .item-meta {
font-size: 10px;
margin-top: 2px;
}
.files-container .grid-item img,
.files-container .list-item img {
width: 28px;
height: 28px;
}
}
@media (max-width:768px) {
.files-container .files-grid {
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
gap: 8px;
}
.files-container #file-list {
max-height: fit-content;
overflow-y: auto;
}
.files-container .toolbar-buttons {
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
}
.files-container .files-list {
padding: 8px;
max-height: 50vh;
overflow-y: auto;
}
.files-container .grid-item {
padding: 8px;
}
}
/* ═══════════════════════════════════════════════════════════════════════
BACKUP & UPDATE (.page-backup)
═══════════════════════════════════════════════════════════════════════ */
.page-backup .main-container {
display: flex;
height: calc(100vh - 60px);
width: 100%;
position: relative;
}
.page-backup .section-list {
list-style-type: none;
padding: 0;
margin: 0;
flex-grow: 1;
}
.page-backup .list-item {
display: flex;
align-items: center;
padding: 12px;
cursor: pointer;
border-radius: var(--radius);
margin-bottom: 12px;
transition: box-shadow .3s, background-color .3s, border-color .3s;
background: var(--grad-card);
border: 1px solid var(--c-border);
box-shadow: var(--shadow);
}
.page-backup .list-item:hover {
box-shadow: var(--shadow-hover);
}
.page-backup .list-item.selected {
border: 1px solid #00e764;
}
.page-backup .list-item img {
margin-right: 10px;
}
@keyframes bak-spin {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
.page-backup .right-panel {
flex: 1;
display: flex;
flex-direction: column;
padding: 20px;
overflow-y: auto;
box-sizing: border-box;
background-color: #1e1e1e;
}
.page-backup .content-section {
display: none;
}
.page-backup .content-section.active {
display: block;
}
.page-backup form {
margin-top: 20px;
}
.page-backup form label {
display: block;
margin-bottom: 5px;
color: white;
}
.page-backup form input[type="text"] {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #555;
border-radius: 4px;
background-color: #07422f40;
color: #fff;
cursor: text;
pointer-events: auto;
}
.page-backup form input[type="text"]:focus {
outline: none;
border-color: #007acc;
background-color: #3d3d3d;
}
.page-backup form input[type="text"]:hover {
border-color: #666;
}
.page-backup .default-badge {
display: inline-block;
padding: 2px 8px;
margin-left: 8px;
background-color: #007acc;
color: white;
border-radius: 12px;
font-size: .85em;
font-weight: 700;
}
.page-backup .bj-modal {
display: none;
position: fixed;
z-index: 1000;
inset: 0;
overflow: auto;
background-color: rgba(0, 0, 0, .5);
}
.page-backup .bj-modal__content {
background-color: #2d2d2d;
margin: 10% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: fit-content;
border-radius: 8px;
z-index: 1001;
color: #fff;
}
.page-backup .bj-modal__close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: 700;
cursor: pointer;
}
.page-backup .bj-modal__close:hover,
.page-backup .bj-modal__close:focus {
color: #fff;
text-decoration: none;
}
.page-backup .bj-loading-overlay {
display: none;
position: fixed;
z-index: 1100;
inset: 0;
background-color: rgba(0, 0, 0, .7);
justify-content: center;
align-items: center;
}
.page-backup .bj-rotating-arrow {
width: 50px;
height: 50px;
border: 5px solid transparent;
border-top: 5px solid #007acc;
border-right: 5px solid #007acc;
border-radius: 50%;
animation: bak-spin 1.5s linear infinite, bak-bjPulse 1.5s ease-in-out infinite;
}
@keyframes bak-bjPulse {
0% {
box-shadow: 0 0 0 0 rgba(0, 122, 204, .7);
}
70% {
box-shadow: 0 0 0 20px rgba(0, 122, 204, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(0, 122, 204, 0);
}
}
.page-backup #bj-update-message {
background-color: #28a745;
color: #fff;
padding: 12px 20px;
border-radius: 25px;
display: inline-block;
margin-bottom: 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, .1);
font-size: 16px;
max-width: 100%;
word-wrap: break-word;
}
.page-backup #bj-update-message.fade-in {
animation: bak-fadeIn .5s ease-in-out;
}
@keyframes bak-fadeIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width:768px) {
.page-backup .main-container {
flex-direction: column;
}
}
@media (min-width:769px) {
.page-backup .menu-icon {
display: none;
}
.page-backup .side-menu {
transform: translateX(0);
position: relative;
height: 98%;
z-index: 10000;
}
}
.page-backup .form-control {
cursor: text;
pointer-events: auto;
background-color: #2d2d2d;
color: #ffffff;
}
.page-backup .backups-table button.loading {
position: relative;
pointer-events: none;
opacity: .6;
background-color: #2d2d2d;
color: #fff;
border: #007acc;
}
/* ═══════════════════════════════════════════════════════════════════════
WEB ENUM (.webenum-container)
═══════════════════════════════════════════════════════════════════════ */
.webenum-container .container {
max-width: 1400px;
margin: 0 auto;
padding: 16px;
}
.webenum-container .header.card {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.webenum-container .header h1 {
margin: 0;
color: var(--acid);
}
.webenum-container .controls.card {
display: grid;
gap: 10px;
}
.webenum-container .controls-row {
display: flex;
flex-wrap: wrap;
gap: var(--gap-3);
align-items: center;
}
.webenum-container .search-box {
flex: 1;
min-width: 230px;
position: relative;
}
.webenum-container .search-box .input {
width: 100%;
padding-right: 36px;
}
.webenum-container .search-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: var(--acid);
}
.webenum-container .stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
margin: 10px 0 12px;
}
.webenum-container .stat-card {
background: var(--grad-card);
border: 1px solid var(--c-border);
border-radius: 14px;
padding: 12px 14px;
box-shadow: var(--shadow);
}
.webenum-container .stat-value {
font-weight: 700;
color: var(--acid);
}
.webenum-container .stat-label {
color: var(--muted);
}
.webenum-container .status-legend.card {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
}
.webenum-container .results-container.card {
overflow: hidden;
}
.webenum-container .results-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--c-border);
padding-bottom: 8px;
margin-bottom: 8px;
}
.webenum-container .results-count {
color: var(--accent-2);
font-weight: 600;
}
.webenum-container .table-container {
overflow: auto;
max-height: calc(100vh - 520px);
min-height: 400px;
}
.webenum-container table {
width: 100%;
border-collapse: collapse;
}
.webenum-container th {
position: sticky;
top: 0;
z-index: 1;
background: var(--c-panel-2);
color: var(--acid);
text-align: left;
padding: 10px 12px;
border-bottom: 1px solid var(--c-border);
user-select: none;
cursor: pointer;
font-weight: 700;
}
.webenum-container td {
padding: 8px 12px;
border-bottom: 1px dashed var(--c-border);
}
.webenum-container tr {
transition: background .15s ease;
}
.webenum-container tr:hover {
background: color-mix(in oklab, var(--acid) 8%, transparent);
cursor: pointer;
}
.webenum-container th.sortable::after {
content: ' \21C5';
opacity: .5;
}
.webenum-container th.sort-asc::after {
content: ' \2191';
color: var(--acid);
opacity: 1;
}
.webenum-container th.sort-desc::after {
content: ' \2193';
color: var(--acid);
opacity: 1;
}
.webenum-container .no-results {
text-align: center;
padding: 40px;
color: var(--muted);
font-style: italic;
}
.webenum-container .loading {
text-align: center;
padding: 40px;
color: var(--acid);
}
.webenum-container .host-badge {
background: var(--c-chip-bg);
color: var(--accent-2);
padding: 3px 8px;
border-radius: 8px;
border: 1px solid var(--c-border);
font-weight: 600;
font-size: .9rem;
}
.webenum-container .port-badge {
background: var(--c-chip-bg);
color: var(--acid);
padding: 3px 8px;
border-radius: 8px;
border: 1px solid var(--c-border);
font-weight: 700;
font-size: .9rem;
}
.webenum-container .url-link {
color: var(--acid-2);
text-decoration: none;
font-size: 1.1rem;
transition: .2s;
}
.webenum-container .url-link:hover {
color: var(--acid);
transform: scale(1.2);
display: inline-block;
}
.webenum-container .status {
display: inline-block;
min-width: 60px;
text-align: center;
padding: 5px 10px;
border-radius: 8px;
font-weight: 700;
font-size: .85rem;
border: 1px solid var(--c-border);
transition: .2s;
cursor: default;
}
.webenum-container .status:hover {
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
.webenum-container .status-2xx {
background: var(--ok);
color: var(--ink-invert);
}
.webenum-container .status-3xx {
background: var(--warning);
color: var(--ink-invert);
}
.webenum-container .status-4xx {
background: var(--danger);
color: var(--ink);
}
.webenum-container .status-5xx {
background: color-mix(in oklab, var(--danger) 65%, var(--lvl-crit-bg) 35%);
color: var(--ink);
}
.webenum-container .status-unknown {
background: var(--muted-off);
color: var(--ink);
}
.webenum-container .pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
padding: 10px;
background: var(--c-panel);
border-top: 1px dashed var(--c-border);
}
.webenum-container .page-btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 10px;
border-radius: var(--control-r);
background: var(--c-btn);
border: 1px solid var(--c-border-strong);
color: var(--ink);
cursor: pointer;
box-shadow: var(--shadow);
transition: .18s;
}
.webenum-container .page-btn:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-hover);
}
.webenum-container .page-btn.active {
outline: 2px solid color-mix(in oklab, var(--acid) 55%, transparent);
}
.webenum-container .page-btn:disabled {
opacity: .5;
cursor: not-allowed;
}
.webenum-container .btn-primary {
background: linear-gradient(180deg, color-mix(in oklab, var(--acid) 28%, var(--c-btn)), var(--c-btn));
border-color: color-mix(in oklab, var(--acid) 45%, var(--c-border));
color: var(--ink);
}
.webenum-container .webenum-modal-backdrop {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.85);
backdrop-filter: blur(4px);
z-index: 9999;
align-items: center;
justify-content: center;
animation: we-fadeIn 0.2s ease;
}
.webenum-container .webenum-modal-backdrop.show {
display: flex;
}
.webenum-container .webenum-modal-content {
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
width: min(720px, 96vw);
max-height: 86vh;
overflow: auto;
padding: 24px;
position: relative;
animation: we-slideUp 0.3s ease;
}
.webenum-container .webenum-modal-content h2 {
margin: 0 0 16px;
color: var(--acid);
font-size: 1.5rem;
}
.webenum-container .webenum-close {
position: absolute;
top: 16px;
right: 16px;
color: var(--muted);
font-size: 28px;
font-weight: 700;
cursor: pointer;
line-height: 1;
transition: .2s;
background: var(--c-btn);
border: 1px solid var(--c-border);
border-radius: 8px;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
}
.webenum-container .webenum-close:hover {
color: var(--acid);
transform: rotate(90deg);
}
@keyframes we-fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes we-slideUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@media (max-width:768px) {
.webenum-container .container {
padding: 10px;
}
.webenum-container .results-header {
flex-direction: column;
gap: 8px;
text-align: center;
}
.webenum-container th,
.webenum-container td {
padding: 8px 6px;
}
}
@media (max-width:480px) {
.webenum-container th,
.webenum-container td {
padding: 6px 4px;
font-size: .85rem;
}
.webenum-container .status {
font-size: .75rem;
}
}
/* ═══════════════════════════════════════════════════════════════════════
ZOMBIELAND C2C (.zombieland-container)
═══════════════════════════════════════════════════════════════════════ */
.zombieland-container .panel {
background: var(--panel);
border: 1px solid var(--c-border);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.zombieland-container .btn-icon {
padding: 8px;
min-width: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.zombieland-container .btn-primary {
background: linear-gradient(180deg, color-mix(in oklab, var(--accent) 22%, var(--btn-bg-solid)), var(--btn-bg-solid));
border-color: color-mix(in oklab, var(--accent) 55%, var(--border));
}
.zombieland-container .btn-danger {
background: linear-gradient(180deg, color-mix(in oklab, var(--danger) 20%, var(--btn-bg-solid)), var(--btn-bg-solid));
border-color: color-mix(in oklab, var(--danger) 55%, var(--border));
}
.zombieland-container .pill {
background: var(--c-pill-bg);
border: 1px solid var(--c-border);
color: var(--muted);
}
.zombieland-container .pill.online {
border-color: color-mix(in oklab, var(--ok) 60%, transparent);
color: var(--ok);
}
.zombieland-container .pill.offline {
border-color: color-mix(in oklab, var(--danger) 60%, transparent);
color: var(--danger);
}
.zombieland-container .pill.idle {
border-color: color-mix(in oklab, var(--warning) 60%, transparent);
color: var(--warning);
}
.zombieland-container .term {
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
border-radius: 10px;
}
.zombieland-container .console-output {
height: 400px;
overflow-y: auto;
padding: 12px;
font: var(--font-mono);
background: var(--grad-console);
border-radius: 8px;
}
.zombieland-container .console-line {
margin: 4px 0;
display: flex;
align-items: flex-start;
gap: 8px;
font: var(--font-mono);
}
.zombieland-container .console-time {
color: var(--muted);
font-size: 11px;
}
.zombieland-container .console-type {
padding: 2px 6px;
border-radius: 999px;
font-size: 11px;
font-weight: 700;
border: 1px solid var(--c-border);
background: var(--c-chip-bg);
}
.zombieland-container .console-type.tx {
background: var(--switch-on-bg);
color: var(--ok);
border-color: color-mix(in oklab, var(--ok) 60%, transparent);
}
.zombieland-container .console-type.rx {
background: color-mix(in oklab, var(--accent-2) 18%, var(--c-panel));
color: var(--accent-2);
border-color: color-mix(in oklab, var(--accent-2) 60%, transparent);
}
.zombieland-container .console-content {
flex: 1;
word-break: break-word;
}
.zombieland-container .console-content pre {
margin: 0;
white-space: pre-wrap;
}
.zombieland-container .agent-card {
transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
cursor: pointer;
position: relative;
border: 1px solid var(--c-border);
border-radius: var(--radius);
background: var(--grad-card);
box-shadow: var(--shadow);
}
.zombieland-container .agent-card:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-hover);
}
.zombieland-container .agent-card.selected {
border-color: color-mix(in oklab, var(--accent) 55%, transparent);
background: var(--grad-chip-selected);
}
.zombieland-container .os-icon {
width: 24px;
height: 24px;
}
.zombieland-container .toast.info {
border-color: color-mix(in oklab, var(--accent-2) 60%, transparent);
}
.zombieland-container .toast.success {
border-color: color-mix(in oklab, var(--ok) 60%, transparent);
}
.zombieland-container .toast.error {
border-color: color-mix(in oklab, var(--danger) 60%, transparent);
}
.zombieland-container .toast.warning {
border-color: color-mix(in oklab, var(--warning) 60%, transparent);
}
.zombieland-container .quick-cmd {
padding: 6px 12px;
background: var(--c-panel);
border: 1px dashed var(--c-border);
border-radius: 8px;
font-size: 12px;
cursor: pointer;
}
.zombieland-container .quick-cmd:hover {
box-shadow: 0 0 0 1px var(--c-border) inset, 0 8px 22px var(--glow-weak);
}
.zombieland-container .metric {
text-align: center;
}
.zombieland-container .metric-value {
font-size: 32px;
font-weight: 800;
color: var(--acid);
}
.zombieland-container .metric-label {
font-size: 12px;
color: var(--muted);
margin-top: 4px;
}
.zombieland-container .file-item {
padding: 8px;
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
border-radius: 10px;
}
.zombieland-container .file-item:hover {
background: var(--c-panel);
}
.zombieland-container .file-item.directory {
color: var(--accent-2);
}
.zombieland-container .modal_zombie {
background: var(--grad-modal);
border: 1px solid var(--c-border-strong);
border-radius: 16px;
box-shadow: 0 40px 120px var(--glow-strong), inset 0 0 0 1px var(--glow-strong);
}
.zombieland-container .modal-content {
background: transparent;
border: none;
border-radius: 12px;
padding: 24px;
max-width: 720px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
}
@keyframes zl-pulseGreen {
0% {
box-shadow: 0 0 0 0 var(--glow-strong);
}
70% {
box-shadow: 0 0 0 12px rgba(0, 0, 0, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
}
}
.zombieland-container .agent-card.pulse {
animation: zl-pulseGreen 1s ease;
}
.zombieland-container .agent-stale-yellow {
border-color: color-mix(in oklab, var(--warning) 75%, transparent) !important;
}
.zombieland-container .agent-stale-orange {
border-color: color-mix(in oklab, var(--warning) 95%, var(--danger) 10%);
}
.zombieland-container .agent-stale-red {
border-color: var(--danger) !important;
}
.zombieland-container .ecg {
position: relative;
width: 100%;
height: 42px;
overflow: hidden;
margin-top: 8px;
background: linear-gradient(transparent 23px, rgba(255, 255, 255, .04) 23px, transparent 24px);
}
.zombieland-container .ecg-wrapper {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 600px;
display: flex;
will-change: transform;
animation: zl-ecgScroll linear infinite;
}
@keyframes zl-ecgScroll {
from {
transform: translateX(0);
}
to {
transform: translateX(-200px);
}
}
.zombieland-container .ecg svg {
width: 200px;
height: 100%;
flex-shrink: 0;
}
.zombieland-container .ecg path {
fill: none;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
filter: drop-shadow(0 0 2px currentColor) drop-shadow(0 0 6px currentColor);
shape-rendering: geometricPrecision;
}
.zombieland-container .ecg.green {
color: var(--ok);
}
.zombieland-container .ecg.yellow {
color: var(--warning);
}
.zombieland-container .ecg.orange {
color: color-mix(in oklab, var(--warning) 70%, var(--danger) 20%);
}
.zombieland-container .ecg.red {
color: var(--danger);
}
.zombieland-container .ecg.flat .ecg-wrapper {
animation: none;
}
.zombieland-container .ecg:not(.flat)::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(0deg, transparent, rgba(255, 255, 255, .03), transparent);
animation: zl-ecgFlicker 2.3s ease-in-out infinite alternate;
pointer-events: none;
}
@keyframes zl-ecgFlicker {
from {
opacity: .2;
transform: translateY(0);
}
to {
opacity: .35;
transform: translateY(-0.5px);
}
}
.zombieland-container .console-line:has(.console-type.tx) .console-content {
color: var(--ok);
}
.zombieland-container .console-line:has(.console-type.rx) .console-content {
color: var(--accent-2);
}
.zombieland-container .console-output {
background: var(--grad-console);
border: 1px solid var(--c-border-strong);
}
.zombieland-container .toolbar {
flex-wrap: wrap;
gap: 8px;
}
.zombieland-container .quickbar {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
padding-bottom: 4px;
}
.zombieland-container .term-controls {
flex-wrap: wrap;
}
.zombieland-container .term-controls .input,
.zombieland-container .term-controls .select {
min-width: 140px;
}
@media (max-width: 768px) {
.zombieland-container .stats-grid {
grid-template-columns: 1fr !important;
}
.zombieland-container .term-controls {
gap: 8px;
}
.zombieland-container .term-controls .input {
flex: 1 1 100%;
}
.zombieland-container .term-controls .select {
flex: 1 1 45%;
}
.zombieland-container .term-controls .btn {
flex: 1 1 45%;
}
}
.zombieland-container .console-type.info {
background: color-mix(in oklab, var(--accent-2) 14%, var(--c-panel));
color: var(--accent-2);
border-color: color-mix(in oklab, var(--accent-2) 60%, transparent);
}
.zombieland-container .console-type.warning {
background: color-mix(in oklab, var(--warning) 12%, var(--c-panel));
color: var(--warning);
border-color: color-mix(in oklab, var(--warning) 60%, transparent);
}
.zombieland-container .console-type.error {
background: color-mix(in oklab, var(--danger) 12%, var(--c-panel));
color: var(--danger);
border-color: color-mix(in oklab, var(--danger) 60%, transparent);
}
.zombieland-container .console-type.success {
background: color-mix(in oklab, var(--ok) 12%, var(--c-panel));
color: var(--ok);
border-color: color-mix(in oklab, var(--ok) 60%, transparent);
}
.zombieland-container .console-line:has(.console-type.info) .console-content {
color: var(--accent-2);
}
.zombieland-container .console-line:has(.console-type.warning) .console-content {
color: var(--warning);
}
.zombieland-container .console-line:has(.console-type.error) .console-content {
color: var(--danger);
}
.zombieland-container .console-line:has(.console-type.success) .console-content {
color: var(--ok);
}
.zombieland-container #logsOutput {
background: var(--grad-console) !important;
border: 1px solid var(--c-border-strong);
border-radius: 10px;
color: var(--ink);
padding: 12px;
}
.zombieland-container #logsOutput .log-line {
display: flex;
align-items: flex-start;
gap: 8px;
font: var(--font-mono);
margin: 4px 0;
}
.zombieland-container #logsOutput .log-time {
color: var(--muted);
font-size: 11px;
}
.zombieland-container #logsOutput .log-text {
flex: 1;
word-break: break-word;
}
.zombieland-container #logsOutput .console-type {
padding: 2px 6px;
border-radius: 999px;
font-size: 11px;
font-weight: 700;
border: 1px solid var(--c-border);
background: var(--c-chip-bg);
}
.zombieland-container .stats-grid {
gap: 8px !important;
margin-bottom: 14px;
}
.zombieland-container .stats-grid .panel {
padding: 10px 12px;
}
.zombieland-container .stats-grid .metric-value {
font-size: 22px;
}
.zombieland-container .stats-grid .metric-label {
font-size: 11px;
margin-top: 2px;
}
@media (max-width:768px) {
.zombieland-container .stats-grid {
gap: 8px !important;
}
}
/* ═══════════════════════════════════════════════════════════════════════
ACTIONS LAUNCHER (.actions-container)
═══════════════════════════════════════════════════════════════════════ */
.actions-container #actionsLauncher {
min-height: 0;
height: 100%;
display: grid;
grid-template-columns: 1fr;
gap: var(--gap-3, 10px);
}
.actions-container .panel {
background: var(--grad-card, var(--c-panel));
border: 1px solid var(--c-border);
border-radius: var(--radius, 14px);
box-shadow: var(--elev, 0 10px 30px var(--acid-1a, #00ff9a1a), inset 0 0 0 1px var(--acid-22, #00ff9a22));
overflow: clip;
}
.actions-container .sideheader {
padding: 10px 10px 6px;
border-bottom: 1px dashed var(--c-border);
}
.actions-container .al-side-meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 8px;
}
.actions-container .al-side-meta .sidetitle {
color: var(--acid);
font-weight: 800;
letter-spacing: .05em;
}
.actions-container .tabs-container {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.actions-container .tab-btn {
all: unset;
cursor: pointer;
padding: 6px 10px;
border-radius: 10px;
background: var(--c-pill-bg);
border: 1px solid var(--c-border);
color: var(--muted);
}
.actions-container .tab-btn.active {
background: var(--grad-chip-selected);
outline: 2px solid color-mix(in oklab, var(--acid) 55%, transparent);
outline-offset: 0;
}
.actions-container .al-search {
display: flex;
gap: 10px;
padding: 10px;
}
.actions-container .al-input {
flex: 1;
background: var(--c-panel);
border: 1px solid var(--c-border-strong);
color: var(--ink);
padding: 10px 12px;
border-radius: var(--control-r, 10px);
font: inherit;
}
.actions-container .al-input:focus {
outline: none;
box-shadow: 0 0 0 2px color-mix(in oklab, var(--acid) 55%, transparent) inset;
}
.actions-container .sidecontent {
padding: 8px;
overflow: auto;
}
.actions-container .al-list {
display: flex;
flex-direction: column;
gap: 10px;
padding-right: 4px;
}
.actions-container .al-row {
position: relative;
display: grid;
grid-template-columns: 84px 1fr;
gap: 12px;
padding: 10px;
background: var(--c-panel-2);
border-radius: 12px;
cursor: pointer;
transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.actions-container .al-row:hover {
transform: translateY(-1px);
border-color: color-mix(in oklab, var(--accent) 25%, var(--c-border));
box-shadow: 0 10px 26px var(--glow-weak);
}
.actions-container .al-row.selected {
outline: 2px solid color-mix(in oklab, var(--acid) 35%, transparent);
box-shadow: 0 12px 30px color-mix(in oklab, var(--acid) 25%, transparent);
}
.actions-container .al-row .ic {
width: 84px;
height: 84px;
display: grid;
place-items: center;
border-radius: 12px;
background: var(--c-panel);
overflow: hidden;
}
.actions-container .ic-img {
width: 70px;
height: 70px;
object-fit: cover;
display: block;
}
.actions-container .al-row>div:nth-child(2) {
min-width: 0;
display: flex;
flex-direction: column;
gap: 4px;
}
.actions-container .name {
font-weight: 800;
color: var(--acid-2);
font-size: 14px;
line-height: 1.2;
}
.actions-container .desc {
color: var(--muted);
font-size: 13px;
line-height: 1.25;
}
.actions-container .al-row .chip {
position: absolute;
top: 6px;
left: calc(84px/2 + 10px);
transform: translateX(-50%);
padding: 2px 8px;
border-radius: 999px;
border: 1px solid var(--c-border);
background: var(--c-chip-bg);
color: var(--muted);
font-size: 11px;
line-height: 1;
pointer-events: none;
}
.actions-container .chip.ok {
color: var(--ok);
border-color: color-mix(in oklab, var(--ok) 60%, transparent);
}
.actions-container .chip.err {
color: var(--danger);
border-color: color-mix(in oklab, var(--danger) 60%, transparent);
}
.actions-container .chip.run {
color: var(--acid);
border-color: color-mix(in oklab, var(--acid) 60%, transparent);
}
.actions-container .center {
display: flex;
flex-direction: column;
min-height: 0;
height: 100%;
}
.actions-container .toolbar2 {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
border-bottom: 1px solid var(--c-border);
background: var(--c-panel);
flex-wrap: wrap;
}
.actions-container .seg {
display: flex;
border-radius: 10px;
overflow: hidden;
border: 1px solid var(--c-border);
}
.actions-container .seg button {
background: var(--c-panel);
color: var(--muted);
padding: 8px 10px;
border: none;
border-right: 1px solid var(--c-border);
cursor: pointer;
font: inherit;
}
.actions-container .seg button:last-child {
border-right: none;
}
.actions-container .seg button.active {
color: var(--ink-invert);
background: linear-gradient(90deg, var(--acid-2), color-mix(in oklab, var(--acid-2) 60%, white));
}
.actions-container .al-btn {
background: var(--c-btn);
color: var(--ink);
border: 1px solid var(--c-border-strong);
border-radius: var(--control-r, 10px);
padding: 8px 12px;
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
transition: .18s;
box-shadow: var(--elev);
font: inherit;
}
.actions-container .al-btn:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-hover);
}
.actions-container .al-btn.warn {
background: linear-gradient(180deg, color-mix(in oklab, var(--warning) 28%, var(--c-btn)), var(--c-btn));
color: var(--warning);
border-color: color-mix(in oklab, var(--warning) 55%, var(--c-border));
}
.actions-container .multiConsole {
flex: 1;
padding: 10px;
display: grid;
gap: 10px;
height: 100%;
grid-auto-flow: row;
grid-auto-rows: 1fr;
grid-template-rows: repeat(var(--rows, 1), 1fr);
}
.actions-container .split-1 {
grid-template-columns: 1fr;
}
.actions-container .split-2 {
grid-template-columns: 1fr 1fr;
}
.actions-container .split-3 {
grid-template-columns: 1fr 1fr 1fr;
}
.actions-container .split-4 {
grid-template-columns: 1fr 1fr;
}
.actions-container .pane {
position: relative;
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-console);
display: flex;
flex-direction: column;
box-shadow: inset 0 0 0 1px var(--c-border-muted);
}
.actions-container .paneHeader {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: 10px;
padding: 8px 10px;
border-bottom: 1px solid var(--c-border);
background: linear-gradient(180deg, color-mix(in oklab, var(--acid-2) 8%, transparent), transparent);
}
.actions-container .paneTitle {
display: grid;
grid-template-columns: auto auto 1fr;
align-items: center;
gap: 10px;
min-width: 0;
}
.actions-container .paneTitle .dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex: 0 0 auto;
}
.actions-container .paneIcon {
width: 70px;
height: 70px;
border-radius: 6px;
object-fit: cover;
opacity: .95;
}
.actions-container .titleBlock {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.actions-container .titleLine strong {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.actions-container .metaLine {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.actions-container .metaLine .chip {
border: 1px solid var(--c-border-strong);
background: var(--c-chip-bg);
color: var(--muted);
padding: 3px 8px;
border-radius: 999px;
}
.actions-container .paneBtns {
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: flex-end;
}
.actions-container .paneBtns .al-btn {
padding: 6px 8px;
font-size: .9rem;
}
.actions-container .paneLog {
flex: 1;
overflow: auto;
padding: 6px 8px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
font-size: .92rem;
}
.actions-container .logline {
white-space: pre-wrap;
word-break: break-word;
padding: 4px 6px;
line-height: 1.32;
color: var(--ink);
}
.actions-container .logline.info {
color: #bfefff;
}
.actions-container .logline.ok {
color: #9ff7c5;
}
.actions-container .logline.warn {
color: #ffd27a;
}
.actions-container .logline.err {
color: #ff99b3;
}
.actions-container .logline.dim {
color: #6a8596;
}
.actions-container .paneHighlight {
box-shadow: 0 0 0 2px var(--acid-2), 0 0 24px color-mix(in oklab, var(--acid-2) 55%, transparent) inset, 0 0 40px color-mix(in oklab, var(--acid-2) 35%, transparent);
animation: al-hi 900ms ease-out 1;
}
@keyframes al-hi {
0% {
transform: scale(1);
}
50% {
transform: scale(1.01);
}
100% {
transform: scale(1);
}
}
.actions-container .section {
padding: 12px;
border-bottom: 1px dashed var(--c-border);
}
.actions-container .h {
font-weight: 800;
letter-spacing: .5px;
color: var(--acid-2);
}
.actions-container .sub {
color: var(--muted);
font-size: .9rem;
}
.actions-container .builder {
padding: 12px;
display: grid;
gap: 12px;
}
.actions-container .field {
display: grid;
gap: 6px;
}
.actions-container .label {
font-size: .85rem;
color: var(--muted);
}
.actions-container .ctl,
.actions-container .select,
.actions-container .range {
background: var(--c-panel);
color: var(--ink);
border: 1px solid var(--c-border-strong);
border-radius: var(--control-r, 10px);
padding: 10px 12px;
font: inherit;
}
.actions-container .ctl:focus,
.actions-container .select:focus {
outline: none;
box-shadow: 0 0 0 2px color-mix(in oklab, var(--acid) 55%, transparent) inset;
}
.actions-container .chips {
display: flex;
gap: 8px;
flex-wrap: wrap;
padding: 10px;
}
.actions-container .chip2 {
padding: 6px 10px;
border-radius: 999px;
background: var(--c-chip-bg);
border: 1px solid var(--c-border-hi);
cursor: pointer;
transition: .18s;
}
.actions-container .chip2:hover {
box-shadow: 0 0 0 1px var(--c-border-hi) inset, 0 8px 22px var(--glow-weak);
}
@media (max-width: 860px) {
.actions-container #actionsLauncher {
grid-template-columns: 1fr;
}
.actions-container .toolbar2 {
display: none !important;
}
.actions-container .paneHeader {
grid-template-columns: 1fr;
row-gap: 8px;
}
.actions-container .paneBtns {
justify-content: flex-start;
}
.actions-container .paneBtns .al-btn {
padding: 5px 6px;
font-size: .85rem;
}
}
/* ═══════════════════════════════════════════════════════════════════════
ACTIONS STUDIO (.studio-container)
═══════════════════════════════════════════════════════════════════════ */
.studio-container {
--st-bg: #060c12;
--st-panel: #0a1520;
--st-card: #0b1c2a;
--st-card2: #0d2132;
--st-text: #e9f3ff;
--st-muted: #9fb4c9;
--st-border: #203448;
--st-neon: #66ffd1;
--st-neon2: #57c9ff;
--st-ok: #30db98;
--st-bad: #ff6b7c;
--st-warn: #ffd166;
--st-edge: #2a557a;
--st-global: #7040ff;
--st-host: #25be7b;
--st-tap: 44px;
--studio-header-h: 52px;
background: var(--st-bg);
color: var(--st-text);
font: 14px/1.35 Inter, system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
overflow: hidden;
height: 100%;
}
.studio-container #app {
display: grid;
grid-template-rows: auto 1fr auto;
height: 100%;
}
.studio-container header {
display: flex;
align-items: center;
gap: .5rem;
padding: .6rem .8rem;
min-height: var(--studio-header-h);
background: color-mix(in oklab, var(--st-panel) 95%, #050b12 5%);
border-bottom: 1px solid var(--st-border);
backdrop-filter: blur(8px);
z-index: 20;
}
.studio-container .logo {
width: 22px;
height: 22px;
border-radius: 6px;
background: conic-gradient(from 210deg, var(--st-neon), var(--st-neon2));
box-shadow: 0 0 32px rgba(90, 255, 200, .22);
}
.studio-container h1 {
font-size: 15px;
letter-spacing: .3px;
}
.studio-container .sp {
flex: 1;
}
.studio-container .btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: .45rem;
padding: .48rem .7rem;
border-radius: 12px;
background: #0c2132;
border: 1px solid var(--st-border);
color: var(--st-text);
cursor: pointer;
font-size: 13px;
transition: all .2s;
min-height: var(--st-tap);
}
.studio-container .btn:hover {
transform: translateY(-1px);
background: #0e2437;
}
.studio-container .btn:active {
transform: scale(.98);
}
.studio-container .btn.primary {
background: linear-gradient(180deg, #0e2f25, #0b241d);
border-color: #1d5a45;
color: var(--st-neon);
}
.studio-container .btn.icon {
width: var(--st-tap);
padding: 0;
}
.studio-container main {
display: grid;
grid-template-columns: 320px 1fr 360px;
gap: 8px;
padding: 8px;
min-height: 0;
height: 100%;
}
.studio-container .studio-side-backdrop {
display: none;
position: fixed;
inset: var(--h-topbar, 56px) 0 var(--h-bottombar, 56px) 0;
z-index: 2150;
border: 0;
margin: 0;
padding: 0;
background: rgba(0, 0, 0, .52);
}
@media (max-width:1100px) {
.studio-container {
--studio-header-h: 46px;
}
.studio-container header {
min-height: var(--studio-header-h);
padding: 6px 8px;
gap: 6px;
position: relative;
z-index: 2300;
}
.studio-container h1 {
font-size: 14px;
max-width: 34vw;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.studio-container .logo {
width: 18px;
height: 18px;
}
.studio-container main {
grid-template-columns: 1fr;
grid-template-rows: 1fr auto;
gap: 8px;
height: auto;
}
.studio-container #left,
.studio-container #right {
position: fixed;
z-index: 2200;
top: var(--h-topbar, 56px);
bottom: var(--h-bottombar, 56px);
width: min(90vw, 420px);
max-width: 420px;
transition: transform .25s ease, opacity .25s;
opacity: .98;
}
.studio-container #left {
left: 0;
transform: translateX(-120%);
}
.studio-container #left.open {
transform: translateX(0);
}
.studio-container #right {
right: 0;
transform: translateX(120%);
}
.studio-container #right.open {
transform: translateX(0);
}
.studio-container #btnPal,
.studio-container #btnIns {
position: fixed;
top: auto;
bottom: calc(var(--h-bottombar, 56px) + 14px);
z-index: 82;
width: 38px;
height: 38px;
min-width: 38px;
min-height: 38px;
padding: 0;
border-radius: 999px;
border: 1px solid var(--c-border-strong);
background: color-mix(in oklab, var(--c-panel) 94%, transparent);
color: var(--ink);
box-shadow: 0 6px 16px rgba(0, 0, 0, .28);
opacity: .88;
}
.studio-container #btnPal {
left: 10px;
}
.studio-container #btnIns {
right: 10px;
}
.studio-container #btnPal:hover,
.studio-container #btnIns:hover {
opacity: 1;
transform: translateY(-1px);
}
.studio-container #btnPal,
.studio-container #btnIns,
.studio-container #btnAutoLayout,
.studio-container #btnRepel,
.studio-container #btnHelp,
.studio-container #btnApply {
display: none;
}
.studio-mobile-dock {
display: flex;
}
.studio-container footer {
display: none;
}
.studio-toast {
bottom: calc(var(--h-bottombar, 56px) + 104px);
}
.studio-container .studio-side-backdrop.show {
display: block;
}
}
.studio-container #left {
background: var(--st-panel);
border: 1px solid var(--st-border);
border-radius: 12px;
display: flex;
flex-direction: column;
min-height: 0;
overflow: hidden;
}
.studio-container .tabs {
display: flex;
gap: 4px;
padding: 8px;
border-bottom: 1px solid var(--st-border);
}
.studio-container .tab {
padding: 6px 12px;
border-radius: 10px;
background: var(--st-card);
border: 1px solid transparent;
cursor: pointer;
font-size: 13px;
}
.studio-container .tab.active {
background: var(--st-card2);
border-color: var(--st-neon2);
color: var(--st-neon2);
}
.studio-container .tab-content {
flex: 1;
padding: 10px;
overflow: auto;
display: none;
}
.studio-container .tab-content.active {
display: block;
}
.studio-container h2 {
margin: .2rem 0 .6rem;
font-size: 12px;
color: var(--st-muted);
letter-spacing: .2px;
text-transform: uppercase;
}
.studio-container .search-row {
position: relative;
margin-bottom: 10px;
}
.studio-container input.search {
width: 100%;
background: #0a1f2e;
color: var(--st-text);
border: 1px solid var(--st-border);
border-radius: 12px;
padding: .6rem 2.1rem .6rem .7rem;
margin-bottom: 0;
font-size: 14px;
}
.studio-container .search-clear {
position: absolute;
right: 6px;
top: 50%;
transform: translateY(-50%);
width: 26px;
height: 26px;
border-radius: 999px;
border: 1px solid var(--st-border);
background: #0f2536;
color: var(--st-muted);
cursor: pointer;
display: none;
}
.studio-container .search-clear.show {
display: inline-flex;
align-items: center;
justify-content: center;
}
.studio-container .search-clear:hover {
color: var(--st-text);
border-color: color-mix(in oklab, var(--st-neon2) 45%, var(--st-border));
}
.studio-container .palette-meta {
display: flex;
gap: 6px;
flex-wrap: wrap;
margin-bottom: 10px;
}
.studio-container .palette-meta .pill {
font-size: 10px;
padding: .2rem .48rem;
}
.studio-container .pitem {
border: 1px solid var(--st-border);
background: #0a1b2a;
border-radius: 12px;
padding: 10px;
display: flex;
justify-content: space-between;
gap: 8px;
align-items: center;
user-select: none;
margin-bottom: 6px;
cursor: grab;
transition: all .2s;
}
.studio-container .pitem:active {
cursor: grabbing;
}
.studio-container .pitem:hover {
transform: translateX(2px);
background: #0c1e2d;
}
.studio-container .pitem.placed {
opacity: .55;
}
.studio-container .pmeta {
font-size: 12px;
color: var(--st-muted);
}
.studio-container .padd {
border: 1px solid var(--st-border);
background: #0b2437;
border-radius: 10px;
padding: .35rem .6rem;
font-size: 12px;
cursor: pointer;
}
.studio-container .padd:hover {
background: var(--st-neon2);
color: var(--st-bg);
transform: scale(1.05);
}
.studio-container .action-icon {
width: 24px;
height: 24px;
border-radius: 6px;
margin-right: 8px;
object-fit: cover;
}
.studio-container .host-card {
border: 1px solid var(--st-border);
background: linear-gradient(135deg, #0b1e2c, #0a1b2a);
border-radius: 12px;
padding: 10px;
margin-bottom: 6px;
cursor: grab;
}
.studio-container .host-card:active {
cursor: grabbing;
}
.studio-container .host-card.simulated {
border-color: var(--st-neon2);
background: linear-gradient(135deg, #0b2233, #0a1f2e);
}
.studio-container .host-card .row {
display: flex;
gap: 6px;
flex-wrap: wrap;
align-items: center;
font-size: 12px;
margin-top: 4px;
}
.studio-container .host-card .row .btn {
padding: .25rem .5rem;
font-size: 11px;
}
.studio-container #center {
position: relative;
border: 1px solid var(--st-border);
border-radius: 12px;
background: radial-gradient(1200px 800px at 0% 0%, #0a1827 0%, #060c12 60%), #060c12;
overflow: hidden;
touch-action: none;
}
.studio-container #bggrid {
position: absolute;
inset: 0;
background-image: linear-gradient(#0f2b3f 1px, transparent 1px), linear-gradient(90deg, #0f2b3f 1px, transparent 1px);
background-size: 40px 40px;
opacity: .18;
pointer-events: none;
}
.studio-container #canvas {
position: absolute;
left: 0;
top: 0;
transform-origin: 0 0;
}
.studio-container #nodes {
position: absolute;
left: 0;
top: 0;
width: 4000px;
height: 3000px;
}
.studio-container #links {
position: absolute;
left: 0;
top: 0;
width: 4000px;
height: 3000px;
overflow: visible;
pointer-events: auto;
}
.studio-container #controls {
position: absolute;
right: 10px;
bottom: 10px;
display: flex;
flex-direction: column;
gap: 6px;
z-index: 5;
}
.studio-container .canvas-hint {
position: absolute;
left: 10px;
right: 72px;
bottom: 10px;
z-index: 6;
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
border-radius: 12px;
border: 1px solid var(--st-border);
background: color-mix(in oklab, #07111a 78%, transparent);
color: var(--st-muted);
backdrop-filter: blur(8px);
box-shadow: 0 6px 18px rgba(0, 0, 0, .25);
}
.studio-container .canvas-hint strong {
color: var(--st-text);
font-size: 12px;
}
.studio-container .canvas-hint span {
font-size: 12px;
}
.studio-container .canvas-hint.hidden {
display: none;
}
.studio-container .canvas-hint .btn.icon {
margin-left: auto;
width: 28px;
min-height: 28px;
border-radius: 999px;
}
.studio-container .ctrl {
width: 44px;
height: 44px;
border-radius: 12px;
border: 1px solid var(--st-border);
background: #0a1f2e;
color: var(--st-text);
cursor: pointer;
transition: all .2s;
}
.studio-container .ctrl:hover {
background: #0c2437;
transform: scale(1.05);
}
.studio-container .ctrl:active {
transform: scale(.97);
}
.studio-container .node {
position: absolute;
min-width: 240px;
max-width: 320px;
color: var(--st-text);
background: linear-gradient(180deg, var(--st-card) 0%, var(--st-card2) 100%);
border: 2px solid var(--st-border);
border-radius: 12px;
box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
transition: transform .2s, box-shadow .2s, min-height .2s;
cursor: grab;
}
.studio-container .node:active {
cursor: grabbing;
}
.studio-container .node:hover {
transform: translateY(-2px);
box-shadow: 0 16px 40px rgba(0, 0, 0, .4);
}
.studio-container .node.sel {
outline: 2px solid var(--st-neon);
outline-offset: 2px;
}
.studio-container .nhdr {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
padding: 8px 10px;
border-bottom: 1px solid var(--st-border);
background: rgba(0, 0, 0, .2);
border-radius: 10px 10px 0 0;
}
.studio-container .nname {
font-weight: 700;
font-size: 13px;
letter-spacing: .2px;
display: flex;
align-items: center;
gap: 6px;
}
.studio-container .node-icon {
width: 20px;
height: 20px;
border-radius: 4px;
object-fit: cover;
}
.studio-container .badge {
font-size: 11px;
color: #97e8ff;
background: #0b2b3f;
border: 1px solid #214b67;
padding: .14rem .45rem;
border-radius: 999px;
}
.studio-container .nbody {
padding: 8px 10px;
display: grid;
gap: 6px;
font-size: 12px;
color: var(--st-muted);
}
.studio-container .row {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.studio-container .k {
color: #7fa6c4;
}
.studio-container .v {
color: var(--st-text);
}
.studio-container .nclose {
border: none;
background: transparent;
color: #9fb4c9;
font-size: 16px;
cursor: pointer;
opacity: 0;
transition: opacity .2s;
}
.studio-container .node:hover .nclose {
opacity: 1;
}
.studio-container .host .badge {
color: #9effc5;
background: #0f2a22;
border-color: #1f604b;
}
.studio-container .host {
background: linear-gradient(180deg, #0c241b, #0d2732);
border-color: var(--st-host);
}
.studio-container .global .badge {
color: #e6ddff;
background: #1b1335;
border-color: #4a3cb0;
}
.studio-container .global {
border-color: var(--st-global);
}
.studio-container .bjorn {
min-width: 120px;
max-width: 140px;
border-radius: 12px;
overflow: hidden;
}
.studio-container .bjorn .nhdr {
border-bottom: none;
background: linear-gradient(180deg, #1a1a2e, #16213e);
}
.studio-container .rail {
position: absolute;
top: 10px;
bottom: 10px;
width: 18px;
border-radius: 10px;
border: 1px solid var(--st-border);
background: #0a1f2e;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
padding: 6px;
cursor: crosshair;
z-index: 3;
}
.studio-container .rail.left {
left: -10px;
}
.studio-container .rail.right {
right: -10px;
background: #0f2a22;
border-color: #1f604b;
}
.studio-container .port {
width: 10px;
height: 10px;
border: 2px solid #0a1120;
border-radius: 50%;
background: var(--st-neon2);
box-shadow: 0 0 10px rgba(88, 201, 255, .5);
}
.studio-container .rail.right .port {
background: var(--st-neon);
}
.studio-container .port.add {
opacity: .5;
outline: 1px dashed #31597b;
}
.studio-container svg {
pointer-events: none;
}
.studio-container .path {
fill: none;
stroke: var(--st-edge);
stroke-width: 2.5;
opacity: .95;
pointer-events: stroke;
cursor: pointer;
transition: all .2s;
}
.studio-container .path:hover {
stroke-width: 3.5;
opacity: 1;
}
.studio-container .path.ok {
stroke: var(--st-ok);
}
.studio-container .path.bad {
stroke: var(--st-bad);
}
.studio-container .path.req {
stroke: var(--st-neon2);
}
.studio-container .path.flow {
stroke-dasharray: 6 9;
animation: as-flow 1.5s linear infinite;
}
@keyframes as-flow {
to {
stroke-dashoffset: -60;
}
}
.studio-container .edgelabel {
font-size: 11px;
fill: #d7ebff;
paint-order: stroke;
stroke: #0c1724;
stroke-width: 3px;
cursor: pointer;
pointer-events: all;
}
.studio-container .edgelabel.bad {
fill: #ffd4da;
}
.studio-container .edgelabel.ok {
fill: #c8ffe7;
}
.studio-container .edgelabel.req {
fill: #d7e2ff;
}
.studio-container #right {
background: var(--st-panel);
border: 1px solid var(--st-border);
border-radius: 12px;
padding: 10px;
display: flex;
flex-direction: column;
gap: 10px;
min-height: 0;
overflow: auto;
}
.studio-container .section {
background: #0b1d2b;
border: 1px solid var(--st-border);
border-radius: 12px;
padding: 10px;
}
.studio-container .section h3 {
margin: .2rem 0 .6rem;
font-size: 13px;
color: var(--st-muted);
}
.studio-container label {
display: flex;
flex-direction: column;
gap: .3rem;
margin: .45rem 0;
}
.studio-container label span {
font-size: 12px;
color: var(--st-muted);
}
.studio-container input,
.studio-container select,
.studio-container textarea {
background: #0a1f2e;
color: var(--st-text);
border: 1px solid var(--st-border);
border-radius: 10px;
padding: .6rem .65rem;
font: inherit;
outline: none;
transition: all .2s;
min-height: 40px;
}
.studio-container input:focus,
.studio-container select:focus,
.studio-container textarea:focus {
border-color: var(--st-neon2);
box-shadow: 0 0 0 2px rgba(87, 201, 255, 0.2);
}
.studio-container textarea {
min-height: 86px;
resize: vertical;
}
.studio-container .small {
font-size: 12px;
color: var(--st-muted);
}
.studio-container .pill {
display: inline-flex;
gap: 6px;
align-items: center;
padding: .14rem .5rem;
border-radius: 999px;
border: 1px solid var(--st-border);
background: #0b2233;
font-size: 11px;
}
.studio-container hr {
border: none;
border-top: 1px solid var(--st-border);
margin: .6rem 0;
}
.studio-container .form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
@media (max-width:600px) {
.studio-container .form-row {
grid-template-columns: 1fr;
}
}
.studio-container footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 8px;
border-top: 1px solid var(--st-border);
background: linear-gradient(90deg, rgba(10, 23, 34, .6), rgba(6, 16, 24, .8));
font-size: 12px;
color: var(--st-muted);
}
.studio-container footer {
flex-wrap: wrap;
justify-content: flex-start;
}
.studio-container .menu .item:hover {
background: color-mix(in oklab, var(--st-neon2) 16%, transparent);
}
.studio-container #mainMenu {
z-index: 2400 !important;
}
.studio-container .modal {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, .8);
z-index: 2500;
align-items: center;
justify-content: center;
}
.studio-container .modal.show {
display: flex;
}
.studio-container .modal-content {
background: var(--st-panel);
border: 1px solid var(--st-border);
border-radius: 16px;
padding: 20px;
max-width: 560px;
width: 92vw;
max-height: 90vh;
overflow: auto;
}
.studio-container .modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.studio-container .modal-title {
font-size: 18px;
font-weight: 600;
}
.studio-container .modal-close {
background: none;
border: none;
color: #fff;
font-size: 24px;
cursor: pointer;
}
.studio-container #helpModal .section {
margin-bottom: 10px;
}
.studio-container #helpModal .section .small {
display: block;
margin: 5px 0;
}
.studio-container .edge-menu {
position: fixed;
background: var(--st-card);
border: 1px solid var(--st-border);
border-radius: 12px;
padding: 6px;
box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
z-index: 2550;
display: none;
}
.studio-container .edge-menu.show {
display: block;
}
.studio-container .edge-menu-item {
padding: 10px 12px;
border-radius: 8px;
cursor: pointer;
font-size: 13px;
}
.studio-container .edge-menu-item:hover {
background: #0b2233;
}
.studio-container .edge-menu-item.danger {
color: var(--st-bad);
}
.studio-mobile-dock {
display: none;
position: fixed;
left: 10px;
right: 10px;
bottom: calc(var(--h-bottombar, 56px) + 8px);
z-index: 2250;
gap: 6px;
align-items: center;
justify-content: space-between;
padding: 8px;
border: 1px solid var(--st-border);
border-radius: 14px;
background: color-mix(in oklab, #08131d 90%, transparent);
box-shadow: 0 10px 24px rgba(0, 0, 0, .35);
backdrop-filter: blur(8px);
}
.studio-mobile-dock .btn {
min-height: 34px;
padding: .35rem .6rem;
font-size: 12px;
}
.studio-mobile-stats {
color: var(--st-muted);
font-size: 11px;
min-width: 56px;
text-align: center;
}
.studio-toast {
position: fixed;
right: 12px;
bottom: calc(var(--h-bottombar, 56px) + 74px);
z-index: 2800;
min-width: 180px;
max-width: min(92vw, 380px);
padding: 10px 14px;
border-radius: 10px;
border: 1px solid var(--st-border);
background: color-mix(in oklab, #0b1620 92%, transparent);
color: var(--st-text);
box-shadow: 0 8px 20px rgba(0, 0, 0, .32);
transition: opacity .25s ease;
opacity: 0;
}
.studio-toast.success {
border-color: color-mix(in oklab, var(--ok) 60%, transparent);
}
.studio-toast.error {
border-color: color-mix(in oklab, var(--danger) 60%, transparent);
}
.studio-toast.warn {
border-color: color-mix(in oklab, var(--warning) 60%, transparent);
}
@media (max-width:960px) {
.studio-container header {
flex-wrap: nowrap;
overflow: visible;
min-height: 44px;
padding: 6px 8px;
}
.studio-container h1 {
white-space: nowrap;
}
.studio-container .logo {
width: 18px;
height: 18px;
}
.studio-container .canvas-hint {
right: 10px;
bottom: calc(var(--h-bottombar, 56px) + 58px);
}
.studio-container #controls {
bottom: calc(var(--h-bottombar, 56px) + 58px);
}
.studio-toast {
bottom: calc(var(--h-bottombar, 56px) + 108px);
}
}
@media (max-width:640px) {
.studio-container footer {
display: none;
}
.studio-container footer .pill:nth-child(4),
.studio-container footer .pill:nth-child(5) {
display: none;
}
.studio-container .canvas-hint {
bottom: calc(var(--h-bottombar, 56px) + 58px);
}
.studio-container .canvas-hint span {
display: none;
}
.studio-mobile-dock .btn {
padding: .34rem .5rem;
min-width: 62px;
}
}
/* ==========================================================================
SPA runtime compatibility (module class names)
Keeps old visual language while matching current JS markup.
========================================================================== */
/* ---- Vulnerabilities module aliases ---- */
.vuln-container .stats-bar {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: var(--gap-4);
margin-bottom: var(--gap-3);
}
.vuln-container .stats-bar .stat-item {
background: var(--grad-card);
border-radius: var(--radius);
padding: var(--gap-4);
text-align: center;
border: 1px solid var(--c-border);
box-shadow: var(--elev);
display: grid;
gap: 6px;
justify-items: center;
}
.vuln-container .stats-bar .stat-value {
font-size: 28px;
font-weight: 800;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.vuln-container .vuln-controls {
background: var(--grad-card);
border-radius: var(--radius);
padding: var(--gap-4);
margin-bottom: var(--gap-3);
display: flex;
flex-wrap: wrap;
gap: var(--gap-3);
align-items: center;
border: 1px solid var(--c-border);
box-shadow: var(--elev);
}
.vuln-container .vuln-buttons {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.vuln-container .global-search-container {
flex: 1;
min-width: 220px;
position: relative;
}
.vuln-container .global-search-input {
width: 100%;
height: var(--control-h);
padding: 0 36px 0 var(--control-pad-x);
border: 1px solid var(--c-border-strong);
border-radius: var(--control-r);
background: var(--c-panel);
color: var(--ink);
}
.vuln-container .global-search-input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent) 28%, transparent);
}
.vuln-container .clear-global-button {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
border: none;
background: none;
color: var(--danger);
cursor: pointer;
display: none;
}
.vuln-container .clear-global-button.show {
display: inline-block;
}
.vuln-container .vuln-btn {
border: 1px solid var(--c-border);
background: var(--c-panel);
color: var(--ink);
border-radius: var(--control-r);
padding: 8px 12px;
cursor: pointer;
}
.vuln-container .vuln-btn.active {
background: linear-gradient(90deg, var(--accent), var(--accent-2));
border-color: var(--accent);
color: var(--white);
}
.vuln-container .vuln-severity-bar {
display: flex;
gap: var(--gap-2);
flex-wrap: wrap;
margin-bottom: var(--gap-3);
}
.vuln-container .vuln-severity-btn {
border: 1px solid var(--c-border);
background: var(--c-panel);
color: var(--ink);
border-radius: 999px;
padding: 5px 12px;
font-weight: 700;
cursor: pointer;
}
.vuln-container .vuln-severity-btn.active {
box-shadow: 0 0 0 1px var(--c-border-hi) inset;
}
.vuln-container .vuln-severity-btn.severity-critical.active {
background: var(--danger);
border-color: var(--danger);
color: var(--white);
}
.vuln-container .vuln-severity-btn.severity-high.active {
background: var(--warning);
border-color: var(--warning);
color: var(--ink-invert);
}
.vuln-container .vuln-severity-btn.severity-medium.active {
background: var(--accent-2);
border-color: var(--accent-2);
color: var(--ink-invert);
}
.vuln-container .vuln-severity-btn.severity-low.active {
background: var(--ok);
border-color: var(--ok);
color: var(--ink-invert);
}
.vuln-container .services-grid {
display: grid;
gap: var(--gap-4);
max-height: calc(100vh - 250px);
overflow-y: auto;
}
.vuln-container .vuln-card-header {
padding: var(--gap-4);
background: var(--grad-quickpanel);
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
cursor: pointer;
user-select: none;
border-bottom: 1px solid var(--c-border);
}
.vuln-container .vuln-card-title {
display: flex;
align-items: center;
gap: var(--gap-3);
flex-wrap: wrap;
flex: 1;
}
.vuln-container .collapse-indicator {
color: var(--muted);
transition: transform .3s ease;
font-size: 18px;
}
.vuln-container .vuln-card.expanded .collapse-indicator {
transform: rotate(180deg);
}
.vuln-container .vuln-content {
max-height: 0;
overflow: hidden;
transition: max-height .3s ease-out;
}
.vuln-container .vuln-card.expanded .vuln-content {
max-height: 2400px;
}
.vuln-container .vuln-detail-section {
margin-bottom: var(--gap-4);
padding: 0 var(--gap-4);
}
.vuln-container .detail-text {
color: var(--ink);
font-size: 14px;
line-height: 1.5;
}
.vuln-container .vuln-tag {
padding: 2px 8px;
border-radius: 999px;
font-size: 10px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: .3px;
border: 1px solid var(--c-border);
background: var(--c-chip-bg);
}
.vuln-container .vuln-tag.remediated {
background: color-mix(in oklab, var(--ok) 18%, var(--c-chip-bg));
border-color: color-mix(in oklab, var(--ok) 40%, var(--c-border));
}
.vuln-container .vuln-tag.kev {
background: color-mix(in oklab, var(--danger) 18%, var(--c-chip-bg));
border-color: color-mix(in oklab, var(--danger) 40%, var(--c-border));
}
.vuln-container .vuln-tag.exploit {
background: color-mix(in oklab, #9c27b0 18%, var(--c-chip-bg));
border-color: color-mix(in oklab, #9c27b0 40%, var(--c-border));
}
.vuln-container .vuln-tag.epss {
background: color-mix(in oklab, var(--warning) 18%, var(--c-chip-bg));
border-color: color-mix(in oklab, var(--warning) 40%, var(--c-border));
}
.vuln-container .vuln-pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
margin-top: var(--gap-4);
padding: var(--gap-3);
flex-wrap: wrap;
}
.vuln-container .vuln-page-btn {
border: 1px solid var(--c-border);
background: var(--c-panel);
color: var(--ink);
border-radius: 10px;
padding: 6px 10px;
cursor: pointer;
}
.vuln-container .vuln-page-btn.active {
background: linear-gradient(90deg, var(--accent), var(--accent-2));
border-color: var(--accent);
color: var(--white);
}
.vuln-container .vuln-page-btn.disabled {
opacity: .5;
cursor: not-allowed;
}
.vuln-container .vuln-page-info {
color: var(--muted);
font-size: 13px;
}
.vuln-container .vuln-modal {
display: none;
position: fixed;
inset: 0;
background: var(--glass-8);
z-index: 1000;
}
.vuln-container .vuln-modal.show {
display: flex;
align-items: center;
justify-content: center;
}
.vuln-container .vuln-modal-content {
background: var(--grad-modal);
border-radius: var(--radius);
max-width: 800px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
border: 1px solid var(--c-border-strong);
box-shadow: var(--shadow-hover);
}
.vuln-container .vuln-modal-header {
padding: var(--gap-4);
border-bottom: 1px solid var(--c-border);
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
background: var(--grad-quickpanel);
z-index: 1;
}
.vuln-container .vuln-modal-title {
font-size: 18px;
font-weight: 800;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.vuln-container .vuln-modal-close {
background: none;
border: none;
color: var(--muted);
font-size: 24px;
cursor: pointer;
}
.vuln-container .vuln-modal-body {
padding: var(--gap-4);
}
/* ---- Attacks module aliases ---- */
.attacks-container {
display: flex;
gap: 20px;
min-height: calc(100vh - var(--h-topbar) - var(--h-bottombar) - 8px);
align-items: stretch;
--page-sidebar-w: 320px;
}
.attacks-container .attacks-sidebar {
width: var(--page-sidebar-w);
flex: 0 0 var(--page-sidebar-w);
min-width: 0;
min-height: 100%;
display: flex;
flex-direction: column;
gap: 0;
padding: 0;
overflow: hidden;
}
.attacks-container .attacks-main {
width: auto;
flex: 1;
min-width: 0;
display: grid;
grid-template-rows: minmax(320px, auto) 1fr;
gap: 10px;
min-height: 0;
border: 1px solid var(--_border);
border-radius: 14px;
background: var(--grad-card);
box-shadow: var(--_shadow);
padding: 10px;
}
.attacks-container .attacks-main .page-content {
height: 100%;
overflow: auto;
}
.attacks-container .attacks-search-input {
width: 100%;
padding: 10px 12px;
border-radius: 10px;
border: 1px solid var(--_border);
background: var(--_panel-lo);
color: var(--_ink);
}
.attacks-container .attacks-categories {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.attacks-container .attacks-cat-pill {
border: 1px solid var(--_border);
background: var(--_panel-lo);
color: var(--_ink);
border-radius: 999px;
padding: 6px 10px;
cursor: pointer;
font-weight: 700;
display: inline-flex;
align-items: center;
gap: 6px;
}
.attacks-container .attacks-cat-pill.active {
background: linear-gradient(135deg, color-mix(in oklab, var(--_acid) 18%, transparent), color-mix(in oklab, var(--_acid2) 12%, transparent));
border-color: color-mix(in oklab, var(--_acid2) 28%, var(--_border));
}
.attacks-container .attacks-cat-pill .pill-count {
opacity: .8;
font-size: 12px;
}
.attacks-container .attacks-list {
overflow: auto;
min-height: 0;
display: grid;
gap: 8px;
}
.attacks-container .action-card {
display: grid;
grid-template-columns: auto 1fr auto;
gap: 10px;
align-items: center;
border: 1px solid var(--_border);
background: var(--_panel-lo);
border-radius: 12px;
padding: 8px;
cursor: pointer;
transition: .2s;
}
.attacks-container .action-card:hover {
transform: translateY(-1px);
box-shadow: var(--_shadow);
background: var(--_panel-hi);
}
.attacks-container .action-card.selected {
background: color-mix(in oklab, var(--_acid2) 16%, var(--_panel-hi));
border-color: color-mix(in oklab, var(--_acid2) 35%, var(--_border));
}
.attacks-container .action-card-img {
width: 56px;
height: 56px;
border-radius: 10px;
overflow: hidden;
border: 1px solid var(--_border);
background: #0b0e13;
display: grid;
place-items: center;
}
.attacks-container .action-card-icon {
width: 100%;
height: 100%;
object-fit: cover;
}
.attacks-container .action-card-name {
font-weight: 800;
color: var(--_ink);
}
.attacks-container .action-card-desc {
font-size: 12px;
color: var(--_muted);
}
.attacks-container .action-card-status {
font-size: 11px;
font-weight: 800;
border-radius: 999px;
padding: 3px 8px;
border: 1px solid var(--_border);
}
.attacks-container .action-card-status.status-running {
background: color-mix(in oklab, var(--warning) 18%, var(--_panel));
border-color: color-mix(in oklab, var(--warning) 40%, var(--_border));
}
.attacks-container .action-card-status.status-ok {
background: color-mix(in oklab, var(--ok) 18%, var(--_panel));
border-color: color-mix(in oklab, var(--ok) 40%, var(--_border));
}
.attacks-container .action-card-status.status-err {
background: color-mix(in oklab, var(--danger) 18%, var(--_panel));
border-color: color-mix(in oklab, var(--danger) 40%, var(--_border));
}
.attacks-container .attacks-detail {
overflow: auto;
}
.attacks-container .detail-top {
display: grid;
gap: 8px;
margin-bottom: 10px;
}
.attacks-container .detail-name {
font-size: 18px;
color: var(--_ink);
}
.attacks-container .detail-meta {
color: var(--_muted);
font-size: 12px;
margin-left: 8px;
}
.attacks-container .detail-desc {
color: var(--_muted);
font-size: 13px;
}
.attacks-container .detail-section-label {
color: var(--_muted);
font-size: 12px;
text-transform: uppercase;
letter-spacing: .5px;
font-weight: 700;
}
.attacks-container .detail-presets,
.attacks-container .detail-args,
.attacks-container .detail-free {
display: grid;
gap: 8px;
margin-bottom: 10px;
}
.attacks-container .preset-chips {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.attacks-container .preset-chip {
border: 1px solid var(--_border);
background: var(--_panel-lo);
color: var(--_ink);
border-radius: 999px;
padding: 5px 10px;
cursor: pointer;
}
.attacks-container .detail-fields {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 10px;
}
.attacks-container .arg-field {
display: grid;
gap: 6px;
}
.attacks-container .arg-label {
color: var(--_muted);
font-size: 12px;
}
.attacks-container .arg-ctl {
width: 100%;
padding: 8px 10px;
border-radius: 10px;
border: 1px solid var(--_border);
background: var(--_panel-lo);
color: var(--_ink);
}
.attacks-container .arg-range-wrap {
display: grid;
grid-template-columns: 1fr auto;
gap: 8px;
align-items: center;
}
.attacks-container .arg-range-val {
color: var(--_muted);
font-size: 12px;
min-width: 34px;
text-align: right;
}
.attacks-container .detail-free-input {
width: 100%;
padding: 8px 10px;
border-radius: 10px;
border: 1px solid var(--_border);
background: var(--_panel-lo);
color: var(--_ink);
}
.attacks-container .detail-actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.attacks-container .attacks-console {
display: grid;
grid-template-rows: auto 1fr;
min-height: 0;
}
.attacks-container .attacks-log {
overflow: auto;
min-height: 180px;
max-height: 48vh;
border: 1px solid var(--_border);
border-radius: 10px;
background: var(--grad-console);
padding: 10px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.attacks-container .log-line {
white-space: pre-wrap;
word-break: break-word;
font-size: 12px;
padding: 2px 0;
}
.attacks-container .log-ok {
color: #9ff7c5;
}
.attacks-container .log-warn {
color: #ffd27a;
}
.attacks-container .log-err {
color: #ff99b3;
}
.attacks-container .log-info {
color: #bfefff;
}
.attacks-container .log-dim {
color: #7f97a8;
}
@media (max-width: 1100px) {
.attacks-container.page-with-sidebar {
flex-direction: row;
}
.attacks-container.page-with-sidebar .attacks-main {
min-width: 0;
}
}
@media (max-width: 900px) {
.attacks-container.page-with-sidebar .attacks-main {
grid-template-rows: auto auto;
}
}
/* ==========================================================================
SPA class compatibility aliases (visual parity with web_old)
========================================================================== */
/* ---- Dashboard aliases ---- */
.dashboard-container .grid-stack {
display: grid;
gap: var(--gap);
}
.dashboard-container .state {
display: inline-flex;
align-items: center;
}
.dashboard-container .key {
color: var(--_ink);
font-weight: 600;
}
.dashboard-container .naked {
background: transparent;
box-shadow: none;
border: 0;
}
/* ---- NetKB aliases ---- */
.netkb-container .netkb-content {
min-height: 0;
}
.netkb-container .netkb-empty {
border: 1px dashed var(--c-border-strong);
border-radius: 12px;
padding: 16px;
color: var(--muted);
text-align: center;
background: var(--panel);
}
.netkb-container .badge-header {
display: block;
margin-bottom: 4px;
}
.netkb-container .badge-status {
display: block;
}
.netkb-container .badge-timestamp {
display: block;
margin-top: 4px;
}
/* ---- Files module aliases ---- */
.files-container .files-breadcrumb,
.files-container .files-toolbar {
border: 1px solid var(--_border);
border-radius: 12px;
background: color-mix(in oklab, var(--_panel) 90%, transparent);
box-shadow: var(--_shadow);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
.files-container .files-breadcrumb {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
padding: 8px 10px;
}
.files-container .files-bc-item {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
border-radius: 8px;
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 96%, transparent);
color: var(--_ink);
cursor: pointer;
}
.files-container .files-bc-item:hover {
filter: brightness(1.06);
}
.files-container .files-bc-sep {
color: var(--_muted);
}
.files-container .files-toolbar {
display: flex;
gap: 8px;
flex-wrap: wrap;
align-items: center;
padding: 8px;
}
.files-container .global-search-input {
flex: 1;
min-width: 220px;
padding: 10px 12px;
border-radius: 10px;
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 96%, transparent);
color: var(--_ink);
}
.files-container .global-search-input:focus {
outline: none;
border-color: color-mix(in oklab, var(--_acid2) 35%, var(--_border));
box-shadow: 0 0 0 3px color-mix(in oklab, var(--_acid2) 18%, transparent);
}
.files-container .vuln-btn {
border: 1px solid var(--_border);
background: color-mix(in oklab, var(--_panel) 92%, transparent);
color: var(--_ink);
border-radius: 10px;
padding: 8px 10px;
cursor: pointer;
font-weight: 700;
}
.files-container .vuln-btn:hover {
filter: brightness(1.06);
}
.files-container .btn-sm {
padding: 4px 6px;
font-size: 12px;
}
.files-container .btn-danger {
border-color: color-mix(in oklab, var(--danger) 40%, var(--_border));
color: color-mix(in oklab, var(--danger) 80%, var(--_ink));
}
.files-container .files-table-list {
border: 1px solid var(--_border);
border-radius: 12px;
overflow: auto;
background: color-mix(in oklab, var(--_panel) 90%, transparent);
box-shadow: var(--_shadow);
}
.files-container .files-row {
display: grid;
grid-template-columns: 40px minmax(180px, 1fr) 120px 170px 140px;
align-items: center;
gap: 8px;
padding: 8px 10px;
border-bottom: 1px solid var(--_border);
}
.files-container .files-header {
position: sticky;
top: 0;
z-index: 2;
font-weight: 800;
background: color-mix(in oklab, var(--_panel) 98%, transparent);
}
.files-container .files-row.files-dir:hover,
.files-container .files-row.files-file:hover {
background: color-mix(in oklab, var(--_acid2) 10%, transparent);
}
.files-container .files-cell {
min-width: 0;
}
.files-container .files-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.files-container .files-size,
.files-container .files-date {
color: var(--_muted);
}
.files-container .files-actions {
display: inline-flex;
gap: 6px;
justify-content: flex-end;
}
.files-container .sortable {
cursor: pointer;
user-select: none;
}
.files-container .db-status {
color: var(--_muted);
font-size: 12px;
padding: 4px 2px;
}
/* ==========================================================================
SPA runtime compatibility aliases (modules that use new class names)
========================================================================== */
.muted {
color: var(--muted);
}
/* ---- Actions Studio runtime aliases ---- */
.studio-container:not(.studio-runtime-host) {
display: grid;
grid-template-columns: minmax(300px, 340px) 1fr;
gap: 10px;
min-height: calc(100vh - var(--h-topbar) - var(--h-bottombar) - 12px);
}
.studio-container:not(.studio-runtime-host) .studio-sidebar {
border: 1px solid var(--st-border, var(--c-border));
border-radius: 12px;
background: var(--st-panel, var(--c-panel-2));
box-shadow: var(--shadow);
display: grid;
grid-template-rows: auto 1fr;
overflow: hidden;
min-height: 0;
}
.studio-container:not(.studio-runtime-host) .sidebar-header {
padding: 10px;
border-bottom: 1px dashed var(--st-border, var(--c-border));
display: grid;
gap: 8px;
}
.studio-container:not(.studio-runtime-host) .sidebar-list {
padding: 10px;
overflow: auto;
display: grid;
gap: 8px;
}
.studio-container:not(.studio-runtime-host) .sidebar-item {
border: 1px solid var(--st-border, var(--c-border));
border-radius: 10px;
background: var(--st-card, var(--c-panel));
padding: 8px;
cursor: pointer;
transition: .18s;
}
.studio-container:not(.studio-runtime-host) .sidebar-item:hover {
transform: translateX(2px);
box-shadow: var(--shadow);
}
.studio-container:not(.studio-runtime-host) .sidebar-item.active {
outline: 2px solid color-mix(in oklab, var(--accent-2, #18f0ff) 45%, transparent);
}
.studio-container:not(.studio-runtime-host) .sidebar-item-name {
font-weight: 700;
}
.studio-container:not(.studio-runtime-host) .sidebar-item-meta,
.studio-container:not(.studio-runtime-host) .sidebar-item-info,
.studio-container:not(.studio-runtime-host) .sidebar-empty {
color: var(--muted);
font-size: 12px;
}
.studio-container:not(.studio-runtime-host) .sidebar-delete-btn {
justify-self: end;
}
.studio-container:not(.studio-runtime-host) .studio-main {
border: 1px solid var(--st-border, var(--c-border));
border-radius: 12px;
background: var(--st-panel, var(--c-panel-2));
box-shadow: var(--shadow);
padding: 10px;
display: grid;
grid-template-rows: auto 1fr;
gap: 10px;
min-height: 0;
}
.studio-container:not(.studio-runtime-host) .studio-toolbar {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.studio-container:not(.studio-runtime-host) .toolbar-spacer {
flex: 1;
}
.studio-container:not(.studio-runtime-host) .studio-btn {
border: 1px solid var(--st-border, var(--c-border-strong));
background: var(--st-card, var(--c-panel));
color: var(--st-text, var(--ink));
border-radius: 10px;
padding: 8px 10px;
cursor: pointer;
font-weight: 700;
}
.studio-container:not(.studio-runtime-host) .studio-btn:hover {
transform: translateY(-1px);
box-shadow: var(--shadow);
}
.studio-container:not(.studio-runtime-host) .studio-panels {
display: grid;
grid-template-columns: 1.2fr .8fr;
gap: 10px;
min-height: 0;
}
.studio-container:not(.studio-runtime-host) .studio-editor,
.studio-container:not(.studio-runtime-host) .studio-preview {
border: 1px solid var(--st-border, var(--c-border));
border-radius: 12px;
background: var(--st-card, var(--c-panel));
padding: 10px;
overflow: auto;
min-height: 0;
}
.studio-container:not(.studio-runtime-host) .editor-form {
display: grid;
gap: 10px;
}
.studio-container:not(.studio-runtime-host) .editor-section {
border: 1px solid var(--st-border, var(--c-border));
border-radius: 10px;
padding: 10px;
background: var(--st-card2, var(--c-panel-2));
}
.studio-container:not(.studio-runtime-host) .section-title {
font-size: 12px;
text-transform: uppercase;
letter-spacing: .3px;
color: var(--muted);
margin-bottom: 8px;
font-weight: 700;
}
.studio-container:not(.studio-runtime-host) .form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.studio-container:not(.studio-runtime-host) .form-group {
display: grid;
gap: 6px;
}
.studio-container:not(.studio-runtime-host) .field-label {
color: var(--muted);
font-size: 12px;
}
.studio-container:not(.studio-runtime-host) .studio-input,
.studio-container:not(.studio-runtime-host) .studio-select,
.studio-container:not(.studio-runtime-host) .studio-textarea {
width: 100%;
border: 1px solid var(--st-border, var(--c-border-strong));
border-radius: 10px;
background: var(--st-bg, var(--c-panel));
color: var(--st-text, var(--ink));
padding: 8px 10px;
}
.studio-container:not(.studio-runtime-host) .studio-textarea {
min-height: 110px;
resize: vertical;
}
.studio-container:not(.studio-runtime-host) .studio-input:focus,
.studio-container:not(.studio-runtime-host) .studio-select:focus,
.studio-container:not(.studio-runtime-host) .studio-textarea:focus {
outline: none;
box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent-2, #18f0ff) 35%, transparent);
}
.studio-container:not(.studio-runtime-host) .args-list,
.studio-container:not(.studio-runtime-host) .req-list {
display: grid;
gap: 8px;
}
.studio-container:not(.studio-runtime-host) .arg-row,
.studio-container:not(.studio-runtime-host) .req-row {
border: 1px solid var(--st-border, var(--c-border));
border-radius: 10px;
padding: 8px;
background: var(--st-card, var(--c-panel));
}
.studio-container:not(.studio-runtime-host) .arg-row-header,
.studio-container:not(.studio-runtime-host) .req-row-header {
display: flex;
justify-content: space-between;
gap: 8px;
align-items: center;
margin-bottom: 6px;
}
.studio-container:not(.studio-runtime-host) .arg-row-title {
font-weight: 700;
}
.studio-container:not(.studio-runtime-host) .arg-row-body,
.studio-container:not(.studio-runtime-host) .req-p1,
.studio-container:not(.studio-runtime-host) .req-p2 {
display: grid;
gap: 8px;
}
.studio-container:not(.studio-runtime-host) .arg-name,
.studio-container:not(.studio-runtime-host) .arg-type,
.studio-container:not(.studio-runtime-host) .arg-default,
.studio-container:not(.studio-runtime-host) .arg-desc,
.studio-container:not(.studio-runtime-host) .arg-required,
.studio-container:not(.studio-runtime-host) .req-type {
width: 100%;
}
.studio-container:not(.studio-runtime-host) .full-width {
grid-column: 1 / -1;
}
.studio-container:not(.studio-runtime-host) .json-preview {
margin: 0;
border: 1px solid var(--st-border, var(--c-border));
border-radius: 10px;
background: var(--grad-console);
color: var(--ink);
padding: 10px;
min-height: 240px;
white-space: pre-wrap;
word-break: break-word;
}
.studio-container:not(.studio-runtime-host) .dirty-indicator {
color: var(--warning);
font-weight: 700;
}
@media (max-width: 1100px) {
.studio-container {
grid-template-columns: 1fr;
}
.studio-container .studio-panels {
grid-template-columns: 1fr;
}
}
/* ---- Web Enum runtime aliases ---- */
.webenum-container .webenum-controls {
display: grid;
gap: 10px;
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-card);
padding: 10px;
box-shadow: var(--shadow);
}
.webenum-container .stats-bar {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 10px;
}
.webenum-container .stats-bar .stat-item {
background: var(--grad-card);
border-radius: 12px;
padding: 10px 12px;
text-align: center;
border: 1px solid var(--c-border);
box-shadow: var(--elev);
display: grid;
gap: 6px;
justify-items: center;
}
.webenum-container .stats-bar .stat-value {
font-size: 26px;
font-weight: 800;
background: linear-gradient(90deg, var(--accent), var(--accent-2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.webenum-container .stats-bar .stat-label {
color: var(--muted);
font-size: 12px;
}
.webenum-container .global-search-container {
flex: 1;
min-width: 220px;
position: relative;
}
.webenum-container .global-search-input {
width: 100%;
height: var(--control-h);
padding: 0 36px 0 var(--control-pad-x);
border: 1px solid var(--c-border-strong);
border-radius: var(--control-r);
background: var(--c-panel);
color: var(--ink);
}
.webenum-container .global-search-input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent) 28%, transparent);
}
.webenum-container .clear-global-button {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
border: none;
background: none;
color: var(--danger);
cursor: pointer;
display: none;
}
.webenum-container .clear-global-button.show {
display: inline-block;
}
.webenum-container .webenum-filters {
display: flex;
gap: 8px;
flex-wrap: wrap;
align-items: center;
}
.webenum-container .webenum-main-actions {
display: flex;
gap: 8px;
align-items: center;
}
.webenum-container .webenum-filter-select,
.webenum-container .webenum-date-input {
border: 1px solid var(--c-border-strong);
border-radius: 10px;
background: var(--c-panel);
color: var(--ink);
padding: 8px 10px;
}
.webenum-container .webenum-export-btns {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.webenum-container .vuln-btn {
border: 1px solid var(--c-border);
background: var(--c-panel);
color: var(--ink);
border-radius: var(--control-r);
padding: 8px 12px;
cursor: pointer;
}
.webenum-container .vuln-btn:hover {
box-shadow: 0 0 0 1px var(--c-border-hi) inset, 0 8px 22px var(--glow-weak);
}
.webenum-container .webenum-status-legend {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 2px;
}
.webenum-container .webenum-table-wrap {
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-card);
box-shadow: var(--shadow);
overflow: auto;
}
.webenum-container .table-inner {
min-width: 100%;
}
.webenum-container .webenum-table {
width: 100%;
border-collapse: collapse;
}
.webenum-container .webenum-table th,
.webenum-container .webenum-table td {
padding: 8px 10px;
border-bottom: 1px dashed var(--c-border);
text-align: left;
}
.webenum-container .webenum-table th {
position: sticky;
top: 0;
background: var(--c-panel);
z-index: 2;
}
.webenum-container .webenum-row:hover {
background: color-mix(in oklab, var(--accent-2) 10%, transparent);
}
.webenum-container .webenum-link {
color: var(--accent-2);
text-decoration: none;
}
.webenum-container .webenum-link:hover {
text-decoration: underline;
}
.webenum-container .webenum-dir-cell {
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.webenum-container .webenum-pagination {
display: flex;
gap: 8px;
align-items: center;
justify-content: center;
flex-wrap: wrap;
margin-top: 8px;
}
.webenum-container .webenum-perpage-wrap {
display: inline-flex;
gap: 6px;
align-items: center;
}
.webenum-container .webenum-perpage {
border: 1px solid var(--c-border);
border-radius: 8px;
background: var(--c-panel);
color: var(--ink);
padding: 4px 8px;
}
.webenum-container .modal-detail-section {
margin-bottom: 12px;
}
.webenum-container .modal-section-title {
font-weight: 700;
margin-bottom: 4px;
color: var(--accent-2);
}
.webenum-container .modal-section-text {
color: var(--ink);
line-height: 1.45;
}
.webenum-container .webenum-modal-actions {
display: flex;
gap: 8px;
justify-content: flex-end;
margin-top: 8px;
flex-wrap: wrap;
}
.webenum-container .page-loading {
padding: 18px;
color: var(--muted);
text-align: center;
}
.webenum-container .vuln-modal {
display: none;
position: fixed;
inset: 0;
background: var(--glass-8);
z-index: 1000;
}
.webenum-container .vuln-modal.show {
display: flex;
align-items: center;
justify-content: center;
}
.webenum-container .vuln-modal-content {
background: var(--grad-modal);
border-radius: 12px;
max-width: 800px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
border: 1px solid var(--c-border-strong);
box-shadow: var(--shadow-hover);
}
.webenum-container .vuln-modal-header {
padding: 12px;
border-bottom: 1px solid var(--c-border);
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
background: var(--grad-quickpanel);
z-index: 1;
}
.webenum-container .vuln-modal-title {
font-size: 18px;
font-weight: 800;
}
.webenum-container .vuln-modal-close {
background: none;
border: none;
color: var(--muted);
font-size: 24px;
cursor: pointer;
}
.webenum-container .vuln-modal-body {
padding: 12px;
}
/* ---- Zombieland runtime aliases ---- */
.zombieland-container .zl-toolbar {
display: flex;
justify-content: space-between;
gap: 10px;
flex-wrap: wrap;
padding: 10px;
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-card);
box-shadow: var(--shadow);
}
.zombieland-container.page-with-sidebar {
--page-sidebar-w: 360px;
}
.zombieland-container.page-with-sidebar .zl-sidebar {
min-height: 0;
}
.zombieland-container.page-with-sidebar .zl-main {
min-width: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.zombieland-container.page-with-sidebar .zl-main .zl-main-grid {
min-height: 0;
}
.zombieland-container.page-with-sidebar .zl-main .zl-logs-panel {
min-height: 200px;
}
.zombieland-container .zl-toolbar-left {
display: flex;
gap: 8px;
align-items: center;
flex: 1;
min-width: 220px;
}
.zombieland-container .zl-toolbar-right {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.zombieland-container .zl-search-input,
.zombieland-container .zl-cmd-input,
.zombieland-container .zl-target-select,
.zombieland-container .zl-card-cmd-input {
border: 1px solid var(--_border);
border-radius: 10px;
background: color-mix(in oklab, var(--_panel) 95%, transparent);
color: var(--_ink);
padding: 8px 10px;
}
.zombieland-container .zl-search-input {
flex: 1;
}
.zombieland-container .zl-main-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 12px;
min-height: 0;
}
.zombieland-container .zl-console-panel,
.zombieland-container .zl-agents-panel,
.zombieland-container .zl-logs-panel {
border: 1px solid var(--_border);
border-radius: 12px;
background: color-mix(in oklab, var(--_panel) 90%, transparent);
box-shadow: var(--_shadow);
overflow: hidden;
}
.zombieland-container .zl-panel-header {
padding: 8px 10px;
border-bottom: 1px dashed var(--_border);
display: flex;
justify-content: space-between;
gap: 8px;
align-items: center;
}
.zombieland-container .zl-panel-title {
font-weight: 800;
color: var(--_ink);
}
.zombieland-container .zl-quickbar {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.zombieland-container .zl-quick-cmd,
.zombieland-container .zl-btn {
border: 1px solid var(--_border);
border-radius: 10px;
background: var(--_panel-lo);
color: var(--_ink);
padding: 6px 9px;
cursor: pointer;
}
.zombieland-container .zl-btn-sm {
border: 1px solid var(--_border);
border-radius: 8px;
background: var(--_panel-lo);
color: var(--_ink);
padding: 4px 7px;
cursor: pointer;
}
.zombieland-container .zl-btn-send {
border: 1px solid var(--_border);
border-radius: 10px;
background: color-mix(in oklab, var(--_acid2) 22%, var(--_panel-lo));
color: var(--_ink);
padding: 8px 10px;
cursor: pointer;
}
.zombieland-container .zl-console-output,
.zombieland-container .zl-logs-output {
min-height: 220px;
max-height: 42vh;
overflow: auto;
padding: 10px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
background: var(--grad-console);
}
.zombieland-container .zl-console-input-row {
display: grid;
grid-template-columns: minmax(120px, 220px) 1fr auto;
gap: 8px;
padding: 10px;
border-top: 1px dashed var(--_border);
}
.zombieland-container .zl-agents-list {
display: grid;
gap: 8px;
padding: 10px;
max-height: 56vh;
overflow: auto;
}
.zombieland-container .zl-agent-card {
border: 1px solid var(--_border);
border-radius: 12px;
background: var(--_panel-lo);
padding: 8px;
display: grid;
gap: 6px;
}
.zombieland-container .zl-agent-card.pulse {
box-shadow: 0 0 0 2px color-mix(in oklab, var(--_acid2) 35%, transparent);
}
.zombieland-container .zl-card-header {
display: flex;
justify-content: space-between;
gap: 8px;
align-items: center;
}
.zombieland-container .zl-card-identity {
display: flex;
gap: 6px;
align-items: center;
min-width: 0;
}
.zombieland-container .zl-card-id {
font-weight: 700;
}
.zombieland-container .zl-card-hostname {
color: var(--muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.zombieland-container .zl-card-info {
display: grid;
gap: 3px;
}
.zombieland-container .zl-info-row {
display: flex;
gap: 6px;
align-items: center;
}
.zombieland-container .zl-info-label {
color: var(--muted);
font-size: 12px;
min-width: 78px;
}
.zombieland-container .zl-card-actions,
.zombieland-container .zl-card-cmd-row {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.zombieland-container .zl-btn-card-send,
.zombieland-container .zl-btn-shell,
.zombieland-container .zl-btn-remove {
border: 1px solid var(--_border);
border-radius: 8px;
background: var(--_panel-hi);
color: var(--_ink);
padding: 5px 8px;
cursor: pointer;
}
.zombieland-container .zl-btn-remove {
color: color-mix(in oklab, var(--danger) 80%, var(--_ink));
}
.zombieland-container .zl-empty {
color: var(--muted);
text-align: center;
padding: 18px;
}
.zombieland-container .zl-empty-icon {
display: block;
font-size: 26px;
margin-bottom: 6px;
opacity: .8;
}
.zombieland-container .zl-ecg-row {
display: flex;
gap: 8px;
align-items: center;
}
.zombieland-container .zl-ecg-counter {
color: var(--muted);
font-size: 12px;
}
.zombieland-container .console-target {
color: var(--muted);
}
@media (max-width: 1100px) {
.zombieland-container .zl-main-grid {
grid-template-columns: 1fr;
}
}
/* ---- Database runtime aliases ---- */
.db-container .db-main {
display: grid;
grid-template-columns: minmax(240px, 300px) 1fr;
gap: 12px;
min-height: 0;
flex: 1;
}
.db-container .db-sidebar {
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-card);
box-shadow: var(--shadow);
padding: 10px;
overflow: auto;
}
.db-container .db-toolbar {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 10px;
}
.db-container .db-sidebar-filter,
.db-container .db-limit-select {
border: 1px solid var(--c-border);
border-radius: 8px;
background: var(--c-panel);
color: var(--ink);
padding: 6px 8px;
}
.db-container .db-actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.db-container .db-tree-group {
display: grid;
gap: 8px;
}
.db-container .db-tree-icon {
width: 16px;
display: inline-flex;
justify-content: center;
}
.db-container .db-tree-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.db-container .db-thead,
.db-container .db-tbody {
display: table-row-group;
}
.db-container .db-th,
.db-container .db-td {
display: table-cell;
}
.db-container .db-th-sel,
.db-container .db-td-sel {
width: 44px;
text-align: center;
}
.db-container .db-cell {
max-width: 420px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.db-container .db-live-label {
color: var(--muted);
font-size: 12px;
}
.db-container .db-danger {
color: var(--danger);
}
@media (max-width: 1100px) {
.db-container .db-main {
grid-template-columns: 1fr;
}
}
.db-container.page-with-sidebar {
--page-sidebar-w: 300px;
}
.db-container.page-with-sidebar .db-sidebar {
padding: 0;
display: flex;
flex-direction: column;
}
.db-container.page-with-sidebar .db-main {
display: flex;
flex-direction: column;
gap: 10px;
min-width: 0;
}
.db-container.page-with-sidebar .db-table-wrap {
min-height: 280px;
}
/* ---- Vulnerabilities runtime aliases ---- */
.vuln-container .page-loading {
padding: 16px;
color: var(--muted);
text-align: center;
}
.vuln-container .host-severity-pills {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.vuln-container .host-vuln-info {
display: grid;
gap: 4px;
}
.vuln-container .meta-label {
color: var(--muted);
font-size: 12px;
}
.vuln-container .meta-value {
color: var(--ink);
font-size: 13px;
}
.vuln-container .vuln-actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.vuln-container .vuln-affected-table {
width: 100%;
border-collapse: collapse;
}
.vuln-container .vuln-affected-table th,
.vuln-container .vuln-affected-table td {
padding: 8px;
border-bottom: 1px dashed var(--c-border);
text-align: left;
}
.vuln-container .vuln-affected-row:hover {
background: color-mix(in oklab, var(--accent-2) 10%, transparent);
}
.vuln-container .vuln-ref-link {
color: var(--accent-2);
text-decoration: none;
}
.vuln-container .vuln-ref-link:hover {
text-decoration: underline;
}
.vuln-container .modal-detail-section {
margin-bottom: 10px;
}
.vuln-container .modal-section-title {
font-weight: 700;
margin-bottom: 4px;
color: var(--accent-2);
}
.vuln-container .modal-section-text {
color: var(--ink);
line-height: 1.45;
}
/* ---- Misc runtime aliases ---- */
.backup-table {
width: 100%;
border-collapse: collapse;
}
.backup-table th,
.backup-table td {
padding: 8px;
border-bottom: 1px dashed var(--c-border);
text-align: left;
}
.backup-table th {
color: var(--muted);
}
.page-loading {
color: var(--muted);
text-align: center;
padding: 16px;
}
.network-container .network-empty {
padding: 14px;
text-align: center;
color: var(--muted);
border: 1px dashed var(--c-border);
border-radius: 10px;
background: var(--panel);
}
.network-container .table-inner {
min-width: max-content;
}
/* ---- Final parity aliases ---- */
.actions-container .sidebar-page {
display: block;
}
.vuln-container.page-with-sidebar {
--page-sidebar-w: 300px;
}
.vuln-container.page-with-sidebar .vuln-sidebar {
min-height: 0;
}
.vuln-container.page-with-sidebar .vuln-main {
min-width: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.vuln-container.page-with-sidebar .vuln-main .vuln-controls {
margin-bottom: 0;
}
.vuln-container.page-with-sidebar .vuln-main .vuln-severity-bar {
margin-bottom: 0;
}
.vuln-container.page-with-sidebar .vuln-main .services-grid {
max-height: none;
min-height: 280px;
}
.vuln-container.page-with-sidebar .stats-header {
display: grid;
gap: 10px;
}
.zombieland-container .zl-search-clear {
border: 1px solid var(--_border);
border-radius: 8px;
background: var(--_panel-lo);
color: var(--muted);
padding: 6px 8px;
cursor: pointer;
}
.zombieland-container .zl-search-clear:hover {
color: var(--_ink);
}
.zombieland-container .zl-btn-start {
color: color-mix(in oklab, var(--ok) 80%, var(--_ink));
}
.zombieland-container .zl-btn-stop {
color: color-mix(in oklab, var(--danger) 80%, var(--_ink));
}
.zombieland-container .zl-pill {
display: inline-flex;
align-items: center;
padding: 2px 8px;
border-radius: 999px;
border: 1px solid var(--_border);
background: var(--_panel-hi);
color: var(--muted);
font-size: 12px;
}
.zombieland-container .zl-info-value {
color: var(--_ink);
font-size: 12px;
}
.zombieland-container .zl-log-line {
display: grid;
grid-template-columns: auto auto 1fr;
gap: 8px;
margin-bottom: 6px;
font: var(--font-mono);
}
.zombieland-container .zl-log-text {
word-break: break-word;
}
.bjorn-container .bjorn-epd-img {
image-rendering: auto;
border-radius: 10px;
box-shadow: var(--shadow);
}
/* ===== BACKUP PAGE (NEW SPA LAYOUT) ===== */
.page-backup {
padding: 10px;
}
.page-backup .backup-layout {
display: grid;
grid-template-columns: minmax(240px, 300px) 1fr;
gap: 12px;
min-height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 60px) - 24px);
}
.page-backup .backup-sidebar,
.page-backup .backup-main {
border: 1px solid var(--c-border);
border-radius: 12px;
background: var(--grad-card);
box-shadow: var(--shadow);
}
.page-backup .backup-sidebar {
padding: 12px;
display: grid;
align-content: start;
gap: 10px;
}
.page-backup .backup-sidehead {
border-bottom: 1px dashed var(--c-border);
padding-bottom: 8px;
}
.page-backup .backup-side-title {
margin: 0;
color: var(--acid);
font-size: 14px;
letter-spacing: .04em;
text-transform: uppercase;
}
.page-backup .backup-nav-item {
width: 100%;
border: 1px solid var(--c-border);
border-radius: 12px;
background: color-mix(in oklab, var(--panel) 88%, transparent);
color: var(--ink);
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
cursor: pointer;
transition: .18s;
text-align: left;
}
.page-backup .backup-nav-item:hover {
transform: translateY(-1px);
box-shadow: var(--shadow);
}
.page-backup .backup-nav-item.active {
border-color: color-mix(in oklab, var(--acid) 45%, var(--c-border));
box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--acid-2) 30%, transparent);
}
.page-backup .backup-nav-icon {
width: 42px;
height: 42px;
object-fit: contain;
border-radius: 8px;
background: rgba(0, 0, 0, .2);
}
.page-backup .backup-nav-label {
font-weight: 700;
letter-spacing: .01em;
}
.page-backup .backup-main {
padding: 14px;
overflow: auto;
}
.page-backup .backup-title {
margin: 0 0 12px 0;
}
.page-backup .backup-form {
margin-bottom: 14px;
}
.page-backup .backup-label {
display: block;
margin-bottom: 8px;
color: var(--muted);
}
.page-backup .backup-form-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.page-backup .backup-input {
flex: 1;
min-width: 220px;
border: 1px solid var(--c-border);
border-radius: 10px;
background: var(--c-panel);
color: var(--ink);
padding: 10px 12px;
}
.page-backup .backup-subtitle {
margin: 10px 0;
color: var(--muted);
font-size: 13px;
text-transform: uppercase;
letter-spacing: .03em;
}
.page-backup .backup-table-wrap {
overflow: auto;
border: 1px solid var(--c-border);
border-radius: 12px;
}
.page-backup .backup-table {
width: 100%;
border-collapse: collapse;
}
.page-backup .backup-table th,
.page-backup .backup-table td {
padding: 10px;
border-bottom: 1px dashed var(--c-border);
text-align: left;
vertical-align: top;
}
.page-backup .backup-row-actions {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.page-backup .backup-default-pill {
margin-left: 8px;
}
.page-backup .backup-empty {
padding: 22px;
text-align: center;
color: var(--muted);
}
.page-backup .backup-update-message {
background: color-mix(in oklab, var(--ok) 18%, transparent);
border: 1px solid color-mix(in oklab, var(--ok) 40%, var(--c-border));
border-radius: 999px;
padding: 10px 14px;
display: inline-block;
margin-bottom: 12px;
}
.page-backup .backup-version-lines {
display: grid;
gap: 4px;
}
.page-backup .backup-update-available {
color: var(--acid);
font-weight: 700;
}
.page-backup .backup-update-ok {
color: var(--ok);
font-weight: 700;
}
.page-backup .backup-update-actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.page-backup .backup-modal-overlay {
position: fixed;
inset: 0;
z-index: 1200;
background: rgba(0, 0, 0, .6);
display: none;
align-items: center;
justify-content: center;
padding: 10px;
}
.page-backup .backup-modal {
width: min(480px, 95vw);
background: var(--grad-card);
border: 1px solid var(--c-border);
border-radius: 14px;
padding: 12px;
box-shadow: var(--shadow-hover);
}
.page-backup .backup-modal-head {
display: flex;
align-items: center;
gap: 8px;
justify-content: space-between;
}
.page-backup .backup-modal-title {
margin: 0;
}
.page-backup .backup-modal-help {
color: var(--muted);
margin: 8px 0 10px 0;
}
.page-backup .backup-keep {
display: flex;
gap: 8px;
align-items: center;
padding: 4px 0;
}
.page-backup .backup-modal-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 12px;
padding-top: 10px;
border-top: 1px dashed var(--c-border);
}
.page-backup .backup-loading-overlay {
position: fixed;
inset: 0;
z-index: 1300;
background: rgba(0, 0, 0, .6);
display: none;
align-items: center;
justify-content: center;
}
.page-backup .backup-spinner {
width: 52px;
height: 52px;
border: 4px solid transparent;
border-top-color: var(--accent-2);
border-right-color: var(--accent-2);
border-radius: 50%;
animation: bak-spin .9s linear infinite;
}
.page-backup.page-with-sidebar {
--page-sidebar-w: 300px;
min-height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 60px) - 24px);
}
.page-backup.page-with-sidebar .backup-sidebar {
padding: 12px;
display: grid;
align-content: start;
gap: 10px;
min-height: 0;
}
.page-backup.page-with-sidebar .backup-main {
min-width: 0;
min-height: 0;
}
/* ===== STUDIO RUNTIME HOST ===== */
.studio-container.studio-runtime-host {
min-height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 60px) - 12px);
height: calc(100vh - var(--h-topbar, 56px) - var(--h-bottombar, 60px) - 12px);
}
.studio-container.studio-runtime-host #app {
height: 100%;
min-height: 100%;
display: grid;
grid-template-rows: auto minmax(0, 1fr) auto;
}
.studio-container.studio-runtime-host main {
min-height: 0;
}
.studio-container.studio-runtime-host #left,
.studio-container.studio-runtime-host #center,
.studio-container.studio-runtime-host #right {
min-height: 0;
height: 100%;
}
@media (max-width:1100px) {
.studio-container.studio-runtime-host #left,
.studio-container.studio-runtime-host #right {
top: calc(var(--h-topbar, 56px) + var(--studio-header-h, 52px) + 8px);
}
}
.studio-container .studio-loading {
padding: 14px;
color: var(--muted);
text-align: center;
border: 1px dashed var(--c-border);
border-radius: 10px;
margin: 12px;
}
@media (max-width: 900px) {
.page-backup .backup-layout {
grid-template-columns: 1fr;
min-height: auto;
}
.page-backup .backup-sidebar {
grid-template-columns: 1fr 1fr;
}
.page-backup .backup-sidehead {
grid-column: 1 / -1;
}
.page-backup.page-with-sidebar .backup-sidebar {
grid-template-columns: 1fr 1fr;
}
.page-backup.page-with-sidebar .backup-sidehead {
grid-column: 1 / -1;
}
}