/* ====================================================================== Bjorn SPA — Global Design Tokens & Base Components Single source of truth for CSS variables, resets, and shared components. ====================================================================== */ /* ============================== 0) Design Tokens (CSS Vars) ============================== */ :root { /* ---- Base palette ------------------------------------------------- */ --black: #000000; --white: #ffffff; --bg: #050709; --bg-2: #0b0f14; --ink: #e6fff7; --muted: #8affc1cc; --acid: #00ff9a; --acid-2: #18f0ff; --danger: #ff3b3b; --warning: #ffd166; --ok: #2cff7e; --ink-invert: #001014; --critical: #ff3b3b; /* ---- Extended opacities ------------------------------------------- */ --black-00: rgba(0, 0, 0, 0); --black-10: rgba(0, 0, 0, .10); --black-50: rgba(0, 0, 0, .5); --white-05: rgba(255, 255, 255, .05); --white-06: rgba(255, 255, 255, .06); --white-10: rgba(255, 255, 255, .10); --white-12: rgba(255, 255, 255, .12); --white-20: rgba(255, 255, 255, .20); /* ---- Surfaces / panels -------------------------------------------- */ --panel: #0e1717; --panel-2: #101c1c; --border: #0f2b2b; --c-btn: #0d151c; --c-panel: #0b1218; --c-panel-2: #0a1118; --c-pill-bg: #0c141b; --c-chip-bg: #07121a; --c-slot: #0e1a22; --neutral-44: #444444; --muted-off: #666666; /* ---- Brand accents ------------------------------------------------ */ --accent: #22f0b4; --accent-2: #18d6ff; --ring: color-mix(in oklab, var(--accent) 60%, var(--white) 8%); /* ---- Borders (themed) --------------------------------------------- */ --c-border: #00ffff22; --c-border-strong: #00ffff33; --c-border-hi: #00ffff44; --c-border-muted: #00ffff11; /* ---- Overlays / glass --------------------------------------------- */ --overlay-bg: rgba(5, 9, 15, .55); --overlay-solid: rgba(7, 16, 24, .92); --glass-8: #00000088; --backdrop-dim: rgba(0, 0, 0, .55); /* ---- Scrollbars --------------------------------------------------- */ --sb-size: 10px; --sb-track: #07121a; --sb-thumb: #09372b; --sb-thumb-hi: var(--acid); --sb-outline: #00ff9a33; /* ---- Switch / toggles --------------------------------------------- */ --switch-track: #111111; --switch-on-bg: #022a1a; --switch-thumb: var(--acid); /* ---- Slider ------------------------------------------------------- */ --slider-h: 6px; --slider-thumb: var(--acid); --slider-thumb-size: 18px; --slider-track: color-mix(in oklab, var(--acid) 18%, var(--c-panel)); --slider-track-fill: color-mix(in oklab, var(--acid) 42%, var(--c-panel)); --slider-focus: color-mix(in oklab, var(--acid) 60%, transparent); /* ---- Effects / glows / shadows ------------------------------------ */ --acid-0f: #00ff9a0f; --acid-1a: #00ff9a1a; --acid-2a: #00ff9a2a; --acid-22: #00ff9a22; --acid-33: #00ff9a33; --glow-weak: var(--acid-0f); --glow-mid: #00ff9a22; --glow-strong: #00ff9a33; --shadow: 0 10px 30px var(--acid-1a), inset 0 0 0 1px var(--acid-22); --shadow-hover: 0 14px 34px var(--acid-2a), inset 0 0 0 1px var(--acid-33); --grid: repeating-linear-gradient(0deg, transparent 0 28px, var(--acid-0f) 28px 29px), repeating-linear-gradient(90deg, transparent 0 28px, var(--acid-0f) 28px 29px); --resize-stripe: linear-gradient(90deg, transparent 0 40%, var(--glow-strong) 40% 60%, transparent 60% 100%); --text-gradient: linear-gradient(180deg, transparent 0%, #00ff9a07 70%, #01180f8c 100%); --elev: var(--shadow); /* ---- Gradients ---------------------------------------------------- */ --grad-bg-1: radial-gradient(1000px 500px at 10% -5%, #0aff9922, transparent 60%); --grad-bg-2: radial-gradient(800px 400px at 110% 10%, #18f0ff22, transparent 60%); --grad-topbar: linear-gradient(#0c1118, #0a0e14); --grad-sidebar: linear-gradient(180deg, #0a1016, #05080c); --grad-card: linear-gradient(180deg, #0b1218, #070b10); --grad-bottombar: linear-gradient(#0a0e14, #091017); --grad-hero: radial-gradient(800px 200px at 80% -20%, #18f0ff22, transparent 60%), #071016; --grad-modal: linear-gradient(180deg, #0a1016, #05080c); --grad-console: linear-gradient(180deg, #071018, #05090f); --grad-chip-selected: linear-gradient(180deg, #0b151c, #091219); --grad-hero-base: #071016; --grad-quickpanel: linear-gradient(180deg, #09111a, #050a0f); --grad-dropdown: linear-gradient(180deg, #0a1116, #05090f); --grad-qprow: linear-gradient(180deg, #09121a, #080e14); /* ---- Console severities ------------------------------------------- */ --log-debug-ink: #c9d4df; --log-debug-bg: #2b3a48; --log-info-ink: #ffffff; --log-info-bg: #007b99; --log-warn-ink: #1a1200; --log-warn-bg: #ffc94d; --log-error-ink: #ffffff; --log-error-bg: #cc2b2b; --log-critical-ink: #ffffff; --log-critical-bg: #a00028; --log-success-ink: #002b14; --log-success-bg: var(--ok); --log-failed-ink: #ffffff; --log-failed-bg: var(--danger); --log-connected-ink: #00331a; --log-connected-bg: var(--acid); --log-critical-glow: #ff004444; /* ---- Log level badge tokens --------------------------------------- */ --lvl-debug-top: #24323a; --lvl-debug-bot: #1a262e; --lvl-debug-ink: #9bd3ff; --lvl-debug-bdr: #2a91ff44; --lvl-info-top: #12343a; --lvl-info-bot: #0e2a30; --lvl-info-ink: #7ee3ff; --lvl-info-bdr: #18f0ff55; --lvl-warn-top: #3a3312; --lvl-warn-bot: #2a240e; --lvl-warn-ink: #ffd166; --lvl-warn-bdr: #ffd16666; --lvl-error-top: #3a1616; --lvl-error-bot: #2a0e0e; --lvl-error-ink: #ff7b7b; --lvl-error-bdr: #ff3b3b66; --lvl-crit-top: #3a1226; --lvl-crit-bot: #2a0e1d; --lvl-crit-ink: #ff8ad6; --lvl-crit-bdr: #ff4fcf66; --lvl-succ-top: #123a22; --lvl-succ-bot: #0e2a1a; --lvl-succ-ink: #7dffb0; --lvl-succ-bdr: #2cff7e66; --lvl-fail-top: #3a1616; --lvl-fail-bot: #2a0e0e; --lvl-fail-ink: #ff7b7b; --lvl-fail-bdr: #ff3b3b66; --lvl-conn-top: #123a26; --lvl-conn-bot: #0e2a1a; --lvl-conn-ink: #7dffb0; --lvl-conn-bdr: #00ff9a66; --lvl-sse-top: #b68b00; --lvl-sse-bot: #6b4601; --lvl-sse-ink: #ac7000; --lvl-sse-bdr: #ca9b0055; /* ---- Layout / radii / sizes --------------------------------------- */ --radius: 14px; --h-topbar: 56px; --h-bottombar: 56px; --control-h: 38px; --control-r: 10px; --control-pad-x: 12px; --gap-1: 6px; --gap-2: 8px; --gap-3: 10px; --gap-4: 12px; /* ---- Typography --------------------------------------------------- */ --font-mono: 14px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; /* ---- QuickPanel sizes --------------------------------------------- */ --qp-h: 88vh; --qp-overshoot: 60px; /* ---- Console ------------------------------------------------------ */ --console-tab: 28px; /* ---- Backdrop ----------------------------------------------------- */ --backdrop-dim: rgba(0, 0, 0, .55); /* ---- Scanline helpers --------------------------------------------- */ --scanline-a: var(--black-00); --scanline-b: var(--black-10); /* ---- Component specials ------------------------------------------- */ --btn-bg-solid: #0f1919; --switch-alt-rail: #122121; --switch-alt-thumb: #1b2b2b; --pill-alt-bg: #122121; --pill-alt-bdr: #143030; color-scheme: dark; } /* ============================== 1) Resets & Base ============================== */ * { box-sizing: border-box } html, body { height: 100%; overflow: clip } body { background: var(--grad-bg-1), var(--grad-bg-2), var(--bg); color: var(--ink); font: var(--font-mono) } a { color: var(--acid); text-decoration: none } .spacer { flex: 1 } .icon { width: 16px; height: 16px; display: inline-block } .scanlines { position: fixed; inset: 0; pointer-events: none; opacity: .33; background-image: linear-gradient(var(--scanline-a) 50%, var(--scanline-b) 50%); background-size: 100% 2px; mix-blend-mode: overlay; z-index: 999 } /* ============================== 2) Enhanced Scrollbars ============================== */ *::-webkit-scrollbar { width: var(--sb-size); height: var(--sb-size) } *::-webkit-scrollbar-track { background: var(--sb-track); border-left: 1px solid var(--c-border); border-right: 1px solid var(--c-border) } *::-webkit-scrollbar-thumb { background: linear-gradient(180deg, color-mix(in oklab, var(--sb-thumb) 70%, transparent), var(--sb-thumb)); border: 2px solid var(--sb-track); border-radius: 12px; box-shadow: 0 0 14px var(--sb-outline) inset } *::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, color-mix(in oklab, var(--sb-thumb-hi) 70%, transparent), var(--sb-thumb-hi)) } *::-webkit-scrollbar-corner { background: var(--sb-track) } * { scrollbar-width: thin; scrollbar-color: var(--sb-thumb) var(--sb-track) } /* ============================== 2) Utility Classes ============================== */ .spacer { flex: 1 } .grid-stack { display: grid; gap: 14px } .grid-auto-260 { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px 16px } .grid-auto-320 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px } a { color: var(--acid); text-decoration: none } /* ============================== 3) Chips (full system) ============================== */ .chips { display: flex; flex-wrap: wrap; gap: 8px } .chip { display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 999px; background: var(--c-chip-bg); border: 1px solid var(--c-border-hi); cursor: pointer; -webkit-user-select: none; user-select: none; transition: .18s; font-size: 13px; font-weight: 600; color: var(--ink) } .chip:hover { box-shadow: 0 0 0 1px var(--c-border-hi) inset, 0 8px 22px var(--glow-weak) } .chip.is-selected, .chip[aria-selected="true"] { background: var(--grad-chip-selected); border-color: color-mix(in oklab, var(--acid) 55%, transparent) } .chip.sm { padding: 4px 8px; font-size: 12px } .chip.ok, .chip.run { border-color: color-mix(in oklab, var(--ok) 55%, transparent); color: var(--ok) } .chip.err, .chip.danger { border-color: color-mix(in oklab, var(--danger) 55%, transparent); color: var(--danger) } .chip.warn { border-color: color-mix(in oklab, var(--warning) 55%, transparent); color: var(--warning) } .chip.info { border-color: color-mix(in oklab, var(--acid-2) 55%, transparent); color: var(--acid-2) } .chip-link { text-decoration: none } .chip2 { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; background: var(--c-chip-bg); border: 1px solid var(--c-border); cursor: pointer; font-size: 12px; font-weight: 600; color: var(--ink); transition: .18s } .chip2:hover { border-color: var(--acid); box-shadow: 0 0 8px var(--glow-weak) } /* ============================== 4) Forms (inputs, selects, toggles) ============================== */ .input, .select, .ctl { height: var(--control-h); border-radius: var(--control-r); border: 1px solid var(--c-border-strong); background: var(--c-panel); color: var(--ink); padding: 0 var(--control-pad-x); font: inherit; outline: none; transition: border-color .2s, box-shadow .2s } .input:focus, .select:focus, .ctl:focus { border-color: var(--acid); box-shadow: 0 0 0 2px rgba(0, 255, 154, 0.15) } .ctl-check { accent-color: var(--acid) } .range { -webkit-appearance: none; appearance: none; width: 100%; height: var(--slider-h); background: var(--slider-track); border-radius: 999px; cursor: pointer; outline: none } .range::-webkit-slider-thumb { -webkit-appearance: none; width: var(--slider-thumb-size); height: var(--slider-thumb-size); border-radius: 50%; background: var(--slider-thumb); border: 1px solid var(--c-border-hi); box-shadow: 0 0 10px var(--acid); cursor: pointer } .range::-moz-range-thumb { width: var(--slider-thumb-size); height: var(--slider-thumb-size); border-radius: 50%; background: var(--slider-thumb); border: 1px solid var(--c-border-hi); box-shadow: 0 0 10px var(--acid); cursor: pointer } .toggle { position: relative; display: inline-block; width: 46px; height: 26px } .toggle input { opacity: 0; width: 0; height: 0 } .toggle .slider { position: absolute; inset: 0; cursor: pointer; background: var(--switch-track); border: 1px solid var(--c-border-hi); border-radius: 99px; transition: .18s } .toggle .slider::before { content: ""; position: absolute; left: 2px; top: 2px; width: 22px; height: 22px; border-radius: 50%; background: var(--switch-thumb); box-shadow: 0 0 10px var(--acid); transition: .18s } .toggle input:checked+.slider { background: var(--switch-on-bg) } .toggle input:checked+.slider::before { transform: translateX(20px) } /* ============================== 5) Modal / Sheet ============================== */ .modal-backdrop { position: fixed; inset: 0; background: var(--glass-8); display: none; align-items: center; justify-content: center; z-index: 60 } .modal-backdrop.show { display: flex } .modal { width: min(900px, 96vw); max-height: 86vh; background: var(--grad-modal); border: 1px solid var(--c-border-strong); border-radius: 16px; box-shadow: 0 40px 120px var(--glow-strong); overflow: hidden; display: flex; flex-direction: column } .modal.show { animation: pop .2s ease } @keyframes pop { from { transform: scale(.96); opacity: 0 } to { transform: scale(1); opacity: 1 } } .modal-header { display: flex; align-items: center; justify-content: space-between; padding: 16px; border-bottom: 1px solid var(--c-border) } .modal-body { flex: 1; overflow-y: auto; padding: 16px } .modal-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--c-border) } /* ============================== 6) State dots ============================== */ .state-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; background: var(--neutral-44) } .state-on { background: var(--ok); box-shadow: 0 0 10px var(--ok) } .state-off { background: var(--muted-off) } .state-err { background: var(--danger); box-shadow: 0 0 10px var(--danger) } /* ============================== 7) Badges ============================== */ .badge { padding: 3px 8px; border-radius: 999px; border: 1px solid var(--c-border-strong); background: var(--c-chip-bg); color: var(--muted); font-size: 12px; font-weight: 600 } /* ============================== 8) Tile ============================== */ .tile { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow) } /* ============================== 9) Log line severity classes ============================== */ .logline { white-space: pre-wrap; border-bottom: 1px dashed var(--c-border-muted); padding: 6px 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.5 } .logline.dim { color: var(--muted) } .logline.info { color: var(--acid-2) } .logline.ok { color: var(--ok) } .logline.warn { color: var(--warning) } .logline.err { color: var(--danger) } /* ============================== 10) Mark (search highlight) ============================== */ mark { background: rgba(0, 255, 154, 0.25); color: inherit; border-radius: 2px; padding: 0 1px } /* ============================== 11) Page Toolbar (unified sticky toolbar used across pages) ============================== */ .page-toolbar-wrap { position: sticky; top: 0; z-index: 500; -webkit-backdrop-filter: saturate(1.1) blur(6px); backdrop-filter: saturate(1.1) blur(6px) } .page-toolbar { display: flex; gap: 12px; align-items: center; justify-content: space-between; margin-bottom: 12px; border: 1px solid var(--c-border-strong); padding: 8px 10px; box-shadow: var(--shadow); background: color-mix(in oklab, var(--panel) 88%, transparent); border-radius: 16px } /* ============================== 12) Segmented control (Table/Map/Grid switcher) ============================== */ .segmented { display: inline-flex; background: var(--panel); border: 1px solid var(--c-border-strong); border-radius: 999px; padding: 4px; box-shadow: var(--shadow) } .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 } .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) } /* ============================== 13) Stats bar (horizontal KPI row) ============================== */ .stats-bar { display: flex; gap: 12px; flex-wrap: wrap; padding: 12px; background: color-mix(in oklab, var(--c-panel-2) 88%, transparent); border: 1px solid var(--c-border); border-radius: 12px; box-shadow: var(--shadow); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px) } .stat-item { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border: 1px solid var(--c-border); border-radius: 10px; background: color-mix(in oklab, var(--c-panel-2) 70%, transparent) } .stat-icon { font-size: 1.1rem; opacity: .9 } .stat-value { font-weight: 800; background: linear-gradient(135deg, var(--acid), var(--acid-2)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent } .stat-label { color: var(--muted); font-size: .8rem } /* Stat cards (grid variant) */ .stats-header { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--gap-4); margin-bottom: var(--gap-3) } .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 .3s cubic-bezier(.4, 0, .2, 1); position: relative; overflow: hidden; box-shadow: var(--shadow) } .stat-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, var(--accent), var(--accent-2)) } .stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover) } .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 } /* ============================== 14) Search box (shared pattern) ============================== */ .search-box { flex: 1; min-width: 200px; position: relative } .search-input { width: 100%; padding: 10px 14px; border-radius: 12px; border: 1px solid var(--c-border); background: color-mix(in oklab, var(--c-panel-2) 90%, transparent); color: var(--ink); font: inherit; outline: none; transition: border-color .2s, box-shadow .2s } .search-input:focus { border-color: color-mix(in oklab, var(--acid-2) 40%, var(--c-border)); box-shadow: 0 0 0 3px color-mix(in oklab, var(--acid-2) 18%, transparent) } .search-input::placeholder { color: var(--muted) } .icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 12px; background: var(--panel); border: 1px solid var(--c-border-strong); box-shadow: var(--shadow); cursor: pointer; transition: transform .12s ease, box-shadow .12s ease } .icon-btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-hover) } .icon-btn svg { width: 20px; height: 20px; fill: var(--ink) } /* ============================== 15) Control bar ============================== */ .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(--shadow) } /* ============================== 16) Data tables (shared DB/creds/vulns pattern) ============================== */ .data-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 } .data-table { width: 100%; border-collapse: separate; border-spacing: 0 } .data-table 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); -webkit-user-select: none; user-select: none; cursor: pointer; white-space: nowrap } .data-table tbody td { padding: 8px 10px; border-bottom: 1px dashed var(--c-border-muted); vertical-align: middle; background: var(--grad-card) } .data-table tbody tr:hover { background: rgba(0, 255, 154, .06) } .data-table tbody tr.selected { background: rgba(0, 255, 154, .12); outline: 1px solid var(--c-border-hi) } .data-table .cell { display: block; min-width: 80px; max-width: 520px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis } .data-table .cell[contenteditable="true"] { outline: 0; border-radius: 6px; transition: .12s; padding: 2px 6px } .data-table .cell[contenteditable="true"]:focus { background: rgba(0, 255, 154, .22); box-shadow: 0 0 0 1px var(--c-border-hi) inset } .data-table .cell.edited { background: rgba(24, 240, 255, .18) } .data-table .pk { color: var(--muted); font-size: 12px } /* ============================== 17) Tabs container (horizontal scrollable tabs) ============================== */ .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(--c-panel-2) 92%, transparent); border: 1px solid var(--c-border); border-radius: 12px; box-shadow: var(--shadow) } .tabs-container::-webkit-scrollbar { height: 0 } .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; transition: all .2s ease } .tab:hover { background: color-mix(in oklab, var(--c-panel-2) 90%, transparent) } .tab.active { background: var(--grad-chip-selected); border-color: color-mix(in oklab, var(--acid) 55%, transparent); color: var(--ink) } /* ============================== 18) Tree navigation (DB sidebar) ============================== */ .tree { display: grid; gap: 6px } .tree-head { display: flex; gap: 8px; align-items: center; margin-bottom: 8px } .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 } .tree-search input { all: unset; flex: 1; color: var(--ink) } .tree-group { margin-top: 10px } .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 } .tree-item:hover { box-shadow: 0 0 0 1px var(--c-border-hi) inset, 0 8px 22px var(--glow-weak); transform: translateX(2px) } .tree-item.active { background: var(--grad-chip-selected); outline: 2px solid color-mix(in oklab, var(--acid) 55%, transparent) } .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) } /* ============================== 19) Scheduler board / lanes ============================== */ .board-wrap { overflow: auto } .board { display: flex; gap: 14px; padding: 14px; min-width: 960px } .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 } .lane-header { 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 } .lane-body { flex: 1; overflow: auto; padding: 8px } .lane-count { padding: 2px 8px; border-radius: 999px; background: var(--c-chip-bg); border: 1px solid var(--c-border-hi); font-size: 11px; color: var(--muted); font-weight: 700 } /* ============================== 20) Agent / Zombie cards ============================== */ .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); padding: 12px } .agent-card:hover { transform: translateY(-1px); box-shadow: var(--shadow-hover) } .agent-card.selected { border-color: color-mix(in oklab, var(--accent) 55%, transparent); background: var(--grad-chip-selected) } .agent-card .pill.online { border-color: color-mix(in oklab, var(--ok) 60%, transparent); color: var(--ok) } .agent-card .pill.offline { border-color: color-mix(in oklab, var(--danger) 60%, transparent); color: var(--danger) } .agent-card .pill.idle { border-color: color-mix(in oklab, var(--warning) 60%, transparent); color: var(--warning) } /* ============================== 21) File explorer (grid + list modes) ============================== */ .file-explorer { flex: 1; display: flex; flex-direction: column; overflow: hidden; padding: 10px; color: var(--ink); background: color-mix(in oklab, var(--c-panel-2) 92%, transparent); border: 1px solid var(--c-border); border-radius: 14px; -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px); box-shadow: var(--shadow) } .files-grid { overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; padding: 8px; border-radius: 8px } .files-list { overflow-y: auto; display: flex; flex-direction: column; gap: 2px; padding: 4px } .file-item { padding: 8px; display: flex; align-items: center; gap: 8px; cursor: pointer; border-radius: 10px; transition: background .15s } .file-item:hover { background: var(--c-panel) } .file-item.directory { color: var(--accent-2) } .file-item .file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap } .file-item .file-size { color: var(--muted); font-size: 12px; white-space: nowrap } .file-item .file-date { color: var(--muted); font-size: 12px; white-space: nowrap } .breadcrumb { display: flex; align-items: center; gap: 4px; padding: 8px 0; flex-wrap: wrap; font-size: 13px } .breadcrumb span { cursor: pointer; color: var(--acid); transition: opacity .15s } .breadcrumb span:hover { opacity: .8 } .breadcrumb .sep { color: var(--muted); cursor: default } /* ============================== 22) Loot page ============================== */ .loot-container { position: relative; z-index: 2; padding: 16px; min-height: calc(100vh - 60px); display: flex; flex-direction: column; gap: 16px } /* ============================== 23) NetKB specific tokens ============================== */ .netkb-card { position: relative; border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--grad-card); padding: 12px; box-shadow: var(--shadow); transition: transform .16s ease, box-shadow .16s ease } .netkb-card:hover { transform: translateY(-1px); box-shadow: var(--shadow-hover) } .netkb-card.offline { opacity: .7; background: color-mix(in oklab, var(--bg-2) 88%, black 12%); border-color: color-mix(in oklab, var(--c-border-strong) 60%, transparent) } .kb-pill { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; border-radius: 999px; font-size: 12px; font-weight: 600 } .kb-pill.hostname { background: color-mix(in oklab, var(--acid) 16%, transparent); color: var(--acid) } .kb-pill.ip { background: color-mix(in oklab, var(--acid-2) 18%, transparent); color: var(--acid-2) } .kb-pill.mac { background: color-mix(in oklab, var(--muted) 10%, transparent); color: var(--muted) } .kb-pill.vendor { background: color-mix(in oklab, #b18cff 16%, transparent); color: #b18cff } .kb-pill.ports { background: color-mix(in oklab, #5fd1ff 16%, transparent); color: #5fd1ff } .kb-pill.essid { background: color-mix(in oklab, #00e6c3 16%, transparent); color: #00e6c3 } /* ============================== 24) Metric blocks (zombieland / dashboard) ============================== */ .metric { text-align: center } .metric-value { font-size: 32px; font-weight: 800; color: var(--acid) } .metric-label { font-size: 12px; color: var(--muted); margin-top: 4px } /* ============================== 25) Terminal block (zombieland console) ============================== */ .term { background: var(--c-panel); border: 1px solid var(--c-border-strong); border-radius: 10px } .console-output { height: 400px; overflow-y: auto; padding: 12px; font: var(--font-mono); background: var(--grad-console); border-radius: 8px } .console-line { margin: 4px 0; display: flex; align-items: flex-start; gap: 8px; font: var(--font-mono) } .console-time { color: var(--muted); font-size: 11px } .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) } .console-type.tx { color: var(--ok); border-color: color-mix(in oklab, var(--ok) 60%, transparent) } .console-type.rx { color: var(--accent-2); border-color: color-mix(in oklab, var(--accent-2) 60%, transparent) } .console-content { flex: 1; word-break: break-word } .console-content pre { margin: 0; white-space: pre-wrap } /* ============================== 26) Quick commands (zombieland) ============================== */ .quick-cmd { padding: 6px 12px; background: var(--c-panel); border: 1px dashed var(--c-border); border-radius: 8px; font-size: 12px; cursor: pointer; transition: .18s } .quick-cmd:hover { box-shadow: 0 0 0 1px var(--c-border) inset, 0 8px 22px var(--glow-weak) } /* ============================== 27) Heartbeat pulse animation ============================== */ @keyframes heartbeat { 0%, 100% { box-shadow: 0 0 0 0 rgba(0, 255, 154, .4) } 50% { box-shadow: 0 0 0 8px rgba(0, 255, 154, 0) } } .heartbeat { animation: heartbeat 2s ease-in-out infinite } /* ============================== 28) Switch (inline toggle in rows) ============================== */ .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 } .kb-switch input { display: none } .kb-switch .track { width: 44px; height: 24px; border-radius: 999px; background: var(--c-panel-2); position: relative; border: 1px solid var(--c-border) } .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 } .kb-switch input:checked~.track .thumb { left: 22px; background: var(--acid) } /* ============================== 29) Editor (shared code/text editor) ============================== */ .editor-textarea { width: 100%; min-height: 300px; resize: vertical; background: var(--c-panel); color: var(--ink); border: 1px solid var(--c-border-strong); border-radius: 10px; padding: 12px; font: var(--font-mono); line-height: 1.5; box-shadow: var(--shadow) } .editor-textarea:focus { outline: none; border-color: var(--acid); box-shadow: 0 0 12px var(--acid) } /* ============================== 30) EPD screen (bjorn page) ============================== */ .epd-frame { display: grid; place-items: center; padding: 20px; background: var(--grad-card); border: 1px solid var(--c-border); border-radius: var(--radius); box-shadow: var(--shadow) } .epd-frame img { max-width: 100%; height: auto; border-radius: 8px; image-rendering: pixelated } /* ============================== 31) Backup / Update sections ============================== */ .backup-section { display: flex; flex-direction: column; gap: 16px } .backup-card { background: var(--grad-card); border: 1px solid var(--c-border); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow) } .backup-card h3 { color: var(--acid); margin-bottom: 12px } /* ============================== 32) Vulnerability-specific ============================== */ .vuln-severity { display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; text-transform: uppercase } .vuln-severity.critical { background: rgba(255, 59, 59, .15); color: var(--danger); border: 1px solid rgba(255, 59, 59, .3) } .vuln-severity.high { background: rgba(255, 130, 0, .12); color: #ff8200; border: 1px solid rgba(255, 130, 0, .3) } .vuln-severity.medium { background: rgba(255, 209, 102, .1); color: var(--warning); border: 1px solid rgba(255, 209, 102, .3) } .vuln-severity.low { background: rgba(44, 255, 126, .1); color: var(--ok); border: 1px solid rgba(44, 255, 126, .3) } .vuln-severity.info { background: rgba(24, 240, 255, .1); color: var(--acid-2); border: 1px solid rgba(24, 240, 255, .3) } /* ============================== 33) Credential-specific ============================== */ .cred-row { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid var(--c-border); border-radius: 10px; background: var(--grad-card); margin-bottom: 6px; transition: all .2s } .cred-row:hover { box-shadow: var(--shadow-hover); transform: translateY(-1px) } .cred-field { display: flex; flex-direction: column; gap: 2px; overflow: hidden } .cred-field .label { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted) } .cred-field .value { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis } .cred-field .value.masked { filter: blur(4px); cursor: pointer; transition: filter .2s } .cred-field .value.masked:hover { filter: none } /* ============================== 34) Animations ============================== */ @keyframes fadeIn { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(30px) } to { opacity: 1; transform: translateY(0) } } @keyframes spin { to { transform: rotate(360deg) } } @keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .6 } } @keyframes blinkChange { from { box-shadow: 0 0 0 0 var(--acid-22) } to { box-shadow: 0 0 0 6px transparent } } .animate-fade { animation: fadeIn .4s ease } .animate-fadeup { animation: fadeInUp .6s ease-out } .value-changed { animation: blinkChange .66s ease } /* ============================== 35) Responsive helpers ============================== */ @media (max-width:1100px) { .data-table .cell { max-width: 60vw } } @media (max-width:700px) { .page-toolbar { flex-wrap: wrap } .stats-header { grid-template-columns: repeat(2, 1fr) } .board { min-width: 0; flex-direction: column } .lane { width: 100% } } /* ============================== 36) Unified Toggle Switch ============================== */ .toggle-switch { display: inline-flex; align-items: center; gap: 10px; font-weight: 700; color: var(--muted); background: var(--c-panel); border: 1px solid var(--c-border-strong); border-radius: 999px; padding: 6px 10px; cursor: pointer; transition: .2s } .toggle-switch:hover { background: var(--c-panel-2) } .toggle-switch input { display: none } .toggle-switch .track { width: 44px; height: 24px; border-radius: 999px; background: var(--c-panel-2); position: relative; border: 1px solid var(--c-border); flex-shrink: 0 } .toggle-switch .thumb { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--ink); box-shadow: 0 2px 8px rgba(0, 0, 0, .4); transition: left .18s ease, background .18s ease } .toggle-switch input:checked~.track .thumb { left: 22px; background: var(--acid) } .toggle-switch input:checked~.track { background: color-mix(in oklab, var(--acid) 22%, var(--c-panel-2)); border-color: color-mix(in oklab, var(--acid) 40%, var(--c-border)) } /* ============================== 37) Unified Status Colors ============================== */ .status-ok, .status-success { color: var(--ok) } .status-warn, .status-warning { color: var(--warning) } .status-err, .status-error, .status-danger, .status-failed { color: var(--danger) } .status-info { color: var(--acid-2) } .status-running { color: #4aa8ff } .status-pending { color: #bbbbbb } .status-upcoming { color: #9cc2ff } /* Status badge variants with background */ .badge-ok, .badge-success { background: color-mix(in oklab, var(--ok) 14%, var(--c-chip-bg)); border-color: color-mix(in oklab, var(--ok) 40%, var(--c-border)); color: var(--ok) } .badge-warn, .badge-warning { background: color-mix(in oklab, var(--warning) 14%, var(--c-chip-bg)); border-color: color-mix(in oklab, var(--warning) 40%, var(--c-border)); color: var(--warning) } .badge-err, .badge-error, .badge-danger { background: color-mix(in oklab, var(--danger) 14%, var(--c-chip-bg)); border-color: color-mix(in oklab, var(--danger) 40%, var(--c-border)); color: var(--danger) } .badge-info { background: color-mix(in oklab, var(--acid-2) 14%, var(--c-chip-bg)); border-color: color-mix(in oklab, var(--acid-2) 40%, var(--c-border)); color: var(--acid-2) } .badge-running { background: color-mix(in oklab, #4aa8ff 14%, var(--c-chip-bg)); border-color: color-mix(in oklab, #4aa8ff 40%, var(--c-border)); color: #4aa8ff } /* ============================== 38) Scheduler State Colors ============================== */ :root { --c-upcoming: #9cc2ff; --c-pending: #bbbbbb; --c-running: #4aa8ff; --c-success: var(--ok); --c-failed: var(--danger); --c-expired: #888888; --c-cancelled: #666666 } /* ============================== 39) Unified Segmented Control ============================== */ .segmented { display: inline-flex; background: var(--panel); border: 1px solid var(--c-border-strong); border-radius: 999px; padding: 4px; box-shadow: var(--shadow) } .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 } .segmented button:hover { color: var(--ink); background: rgba(255, 255, 255, .04) } .segmented button[aria-pressed="true"], .segmented button.active { 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) } /* ============================== 40) Unified Toolbar Pattern ============================== */ .page-toolbar { display: flex; gap: 12px; align-items: center; padding: 8px 10px; background: var(--panel); border: 1px solid var(--c-border-strong); border-radius: 16px; box-shadow: var(--shadow) } .page-toolbar-wrap { position: sticky; top: 0; z-index: 500; backdrop-filter: saturate(1.1) blur(6px); margin-bottom: 12px }