Files
2026-11-10 03:00:46 +08:00

754 lines
28 KiB
CSS

/*
aimdo memory visualization — static styles.
JS still owns dynamic values (positions, widths, scale/zoom, drop-zone hover state).
All theme palettes live here, indexed by data-aimdo-theme on <html>. JS toggles
that attribute and reads computed CSS variables back into a small C palette
object — needed because <canvas> can't see CSS custom properties.
*/
/* ---------------- themes ----------------
:root holds the default theme. Other themes override only what differs from
default — JS toggles them by writing data-aimdo-theme on <html>.
fadeOutFrom / fadeOutTo are comma-separated RGB triplets parsed by JS for
the canvas fade animation; CSS itself doesn't consume them.
*/
:root {
--aimdo-bg: #181818;
--aimdo-rowBg: #1f1f1f;
--aimdo-headerBg: #202020;
--aimdo-border: #2a2a2a;
--aimdo-btn: #2a2a2a;
--aimdo-btnText: #888;
--aimdo-text: #b0b0b0;
--aimdo-textDim: #707070;
--aimdo-running: #b0b0b0;
--aimdo-vram: #e67e22;
--aimdo-torch: #2ecc71;
--aimdo-pinned: #4a9eff;
--aimdo-loadedRam: #0b3d66;
--aimdo-unloaded: #3a3a3a;
--aimdo-torchCache: #1a7a3a;
--aimdo-python: #9b59b6;
--aimdo-other: #505050;
--aimdo-graphBg: #0e0e0e;
--aimdo-gridLine: #1e1e1e;
--aimdo-totalLine: #d0d0d0;
--aimdo-gpuUtil: #c9a227;
--aimdo-gpuUtilHi: #e74c3c;
--aimdo-capLine: #555;
--aimdo-barBg: #222;
--aimdo-fadeOutFrom: 200, 60, 60;
--aimdo-fadeOutTo: 58, 58, 58;
/* model type colors (match LiteGraph slot colors) */
--aimdo-type-model: #B39DDB;
--aimdo-type-vae: #FF6E6E;
--aimdo-type-clip: #FFD500;
--aimdo-type-clip_vision: #A8DADC;
--aimdo-type-controlnet: #76B900;
--aimdo-type-style_model: #C2FFAE;
--aimdo-type-gligen: #9B59B6;
--aimdo-type-upscale_model: #7AB1FF;
}
[data-aimdo-theme="light"] {
--aimdo-bg: #f5f5f5; --aimdo-rowBg: #ebebeb; --aimdo-headerBg: #e2e2e2;
--aimdo-border: #a8a8a8; --aimdo-btn: #c8c8c8; --aimdo-btnText: #333;
--aimdo-text: #1a1a1a; --aimdo-textDim: #555;
--aimdo-graphBg: #fdfdfd; --aimdo-gridLine: #c8c8c8; --aimdo-barBg: #b8b8b8;
--aimdo-vram: #c2410c; --aimdo-torch: #15803d; --aimdo-pinned: #1d4ed8;
--aimdo-loadedRam: #7c9cc8;
--aimdo-unloaded: #888; --aimdo-torchCache: #166534; --aimdo-python: #6d28d9;
--aimdo-other: #666;
--aimdo-totalLine: #222; --aimdo-gpuUtil: #854d0e; --aimdo-gpuUtilHi: #b91c1c;
--aimdo-capLine: #555; --aimdo-running: #333;
--aimdo-fadeOutFrom: 180, 60, 60; --aimdo-fadeOutTo: 136, 136, 136;
--aimdo-type-model: #7c3aed; --aimdo-type-vae: #dc2626; --aimdo-type-clip: #ca8a04;
--aimdo-type-clip_vision: #0891b2; --aimdo-type-controlnet: #15803d;
--aimdo-type-style_model: #22c55e; --aimdo-type-gligen: #9333ea; --aimdo-type-upscale_model: #1e40af;
}
[data-aimdo-theme="sepia"] {
--aimdo-bg: #f4ecd8; --aimdo-rowBg: #ebe1c9; --aimdo-headerBg: #e0d4b6;
--aimdo-border: #b8a982; --aimdo-btn: #d6c89e; --aimdo-btnText: #6b5a3e;
--aimdo-text: #3a2f1e; --aimdo-textDim: #7a6a4e;
--aimdo-graphBg: #faf6e8; --aimdo-gridLine: #d8cba8; --aimdo-barBg: #c9b88a;
--aimdo-vram: #b8732e; --aimdo-torch: #6b8e23; --aimdo-pinned: #5a7a8c;
--aimdo-loadedRam: #3a5a6c;
--aimdo-unloaded: #c9b88a; --aimdo-torchCache: #4a6e23; --aimdo-python: #7a4a8a;
--aimdo-other: #8a7a5a;
--aimdo-totalLine: #4a3a2a; --aimdo-gpuUtil: #8a6818; --aimdo-gpuUtilHi: #a83a2a;
--aimdo-capLine: #8a7a5a; --aimdo-running: #5a4a3a;
--aimdo-fadeOutFrom: 168, 88, 68; --aimdo-fadeOutTo: 201, 184, 138;
--aimdo-type-model: #7a5e8a; --aimdo-type-vae: #b03030; --aimdo-type-clip: #a87818;
--aimdo-type-clip_vision: #5a8a8a; --aimdo-type-controlnet: #6b8e23;
--aimdo-type-style_model: #7a9a5a; --aimdo-type-gligen: #7a4a8a; --aimdo-type-upscale_model: #5a7a9a;
}
/* Pip-Boy CRT — green screen housed in metallic gray-brown chrome */
[data-aimdo-theme="fallout"] {
--aimdo-bg: #0a1a0a; --aimdo-rowBg: #0f2510; --aimdo-headerBg: #2a2520;
--aimdo-border: #5a4a3a; --aimdo-btn: #3a3530; --aimdo-btnText: #c8b89a;
--aimdo-text: #7fff7f; --aimdo-textDim: #3a8a3a;
--aimdo-graphBg: #051005; --aimdo-gridLine: #1a4a1a; --aimdo-barBg: #0f2510;
--aimdo-vram: #88ff66; --aimdo-torch: #ccff44; --aimdo-pinned: #44ffcc;
--aimdo-loadedRam: #2a7a5a;
--aimdo-unloaded: #1a4a1a; --aimdo-torchCache: #5a9a3a; --aimdo-python: #aaff88;
--aimdo-other: #2a4a2a;
--aimdo-totalLine: #7fff7f; --aimdo-gpuUtil: #ffcc44; --aimdo-gpuUtilHi: #ff5555;
--aimdo-capLine: #3a8a3a; --aimdo-running: #88ff66;
--aimdo-fadeOutFrom: 220, 80, 80; --aimdo-fadeOutTo: 26, 74, 26;
--aimdo-type-model: #aaff88; --aimdo-type-vae: #ff8866; --aimdo-type-clip: #ffdd44;
--aimdo-type-clip_vision: #88ffdd; --aimdo-type-controlnet: #aaff44;
--aimdo-type-style_model: #ccffaa; --aimdo-type-gligen: #ff88cc; --aimdo-type-upscale_model: #66ddff;
}
/* pastel pink with mint/lavender accents so data colors stay distinguishable */
[data-aimdo-theme="pink"] {
--aimdo-bg: #fff0f5; --aimdo-rowBg: #ffeaf2; --aimdo-headerBg: #ffd6e8;
--aimdo-border: #e8a4c4; --aimdo-btn: #ffc4d6; --aimdo-btnText: #7a3a5a;
--aimdo-text: #4a1f3a; --aimdo-textDim: #8a4a6a;
--aimdo-graphBg: #fff5fa; --aimdo-gridLine: #f5cadc; --aimdo-barBg: #f5c0d4;
--aimdo-vram: #e91e63; --aimdo-torch: #10a37f; --aimdo-pinned: #a78bfa;
--aimdo-loadedRam: #7a5ec0;
--aimdo-unloaded: #d8b4c0; --aimdo-torchCache: #0f8a6a; --aimdo-python: #7c3aed;
--aimdo-other: #a878a0;
--aimdo-totalLine: #4a1f3a; --aimdo-gpuUtil: #e0a04a; --aimdo-gpuUtilHi: #d32f5e;
--aimdo-capLine: #b67a8a; --aimdo-running: #5a2a4a;
--aimdo-fadeOutFrom: 220, 80, 110; --aimdo-fadeOutTo: 216, 180, 192;
--aimdo-type-model: #e91e63; --aimdo-type-vae: #ef4444; --aimdo-type-clip: #f59e0b;
--aimdo-type-clip_vision: #0ea5a4; --aimdo-type-controlnet: #65a30d;
--aimdo-type-style_model: #f472b6; --aimdo-type-gligen: #a855f7; --aimdo-type-upscale_model: #3b82f6;
}
/* Inherits ComfyUI's design tokens via var() so the panel adopts whatever
palette the host is in (light/dark mode is read live through the cascade).
--aimdo-type-* and --aimdo-fadeOut* are intentionally omitted — the
LiteGraph slot hues and fade RGB triplets from :root carry through. */
[data-aimdo-theme="comfy"] {
--aimdo-bg: var(--comfy-menu-bg);
--aimdo-rowBg: var(--comfy-menu-secondary-bg);
--aimdo-headerBg: var(--comfy-menu-bg);
--aimdo-border: var(--border-color);
--aimdo-btn: var(--comfy-input-bg);
--aimdo-btnText: var(--input-text);
--aimdo-text: var(--input-text);
--aimdo-textDim: var(--descrip-text);
--aimdo-running: var(--input-text);
--aimdo-graphBg: var(--comfy-menu-secondary-bg);
--aimdo-gridLine: var(--border-color);
--aimdo-barBg: var(--comfy-input-bg);
--aimdo-totalLine: var(--fg-color);
--aimdo-capLine: var(--border-color);
--aimdo-vram: var(--color-gold-500);
--aimdo-torch: var(--color-jade-600);
--aimdo-pinned: var(--color-azure-400);
--aimdo-loadedRam: var(--color-cobalt-800);
--aimdo-unloaded: var(--color-ash-800);
--aimdo-torchCache: var(--color-jade-600);
--aimdo-python: var(--color-magenta-700);
--aimdo-other: var(--color-neutral-550);
--aimdo-gpuUtil: var(--color-gold-500);
--aimdo-gpuUtilHi: var(--color-coral-500);
/* Neutral fade endpoints chosen to read OK against both light and dark
Comfy backgrounds — the dark-tuned :root defaults would streak black
on light mode. */
--aimdo-fadeOutFrom: 200, 100, 80;
--aimdo-fadeOutTo: 128, 128, 128;
}
/* CUSTOM THEME: Lucifer - Black and Red */
[data-aimdo-theme="lucifer"] {
--aimdo-bg: #000000;
--aimdo-rowBg: #050000;
--aimdo-headerBg: #000000;
--aimdo-border: #FF0000;
--aimdo-btn: #110000;
--aimdo-btnText: #FF0000;
--aimdo-text: #ffffff;
--aimdo-textDim: #880000;
--aimdo-running: #ffffff;
--aimdo-vram: #FF0000;
--aimdo-torch: #CC0000;
--aimdo-pinned: #880000;
--aimdo-loadedRam: #440000;
--aimdo-unloaded: #222222;
--aimdo-torchCache: #660000;
--aimdo-python: #FF0000;
--aimdo-other: #444444;
--aimdo-graphBg: #000000;
--aimdo-gridLine: #220000;
--aimdo-totalLine: #ffffff;
--aimdo-gpuUtil: #FF0000;
--aimdo-gpuUtilHi: #FF5555;
--aimdo-capLine: #FF0000;
--aimdo-barBg: #110000;
--aimdo-fadeOutFrom: 255, 0, 0;
--aimdo-fadeOutTo: 0, 0, 0;
/* model type colors — all red to match the Obsidian Redline aesthetic */
--aimdo-type-model: #FF0000;
--aimdo-type-vae: #FF0000;
--aimdo-type-clip: #FF0000;
--aimdo-type-clip_vision: #FF0000;
--aimdo-type-controlnet: #FF0000;
--aimdo-type-style_model: #FF0000;
--aimdo-type-gligen: #FF0000;
--aimdo-type-upscale_model: #FF0000;
}
/* ---------------- panel ---------------- */
#aimdo-viz-panel {
position: fixed;
background: var(--aimdo-bg);
color: var(--aimdo-text);
border: 1px solid var(--aimdo-border);
border-radius: 8px;
padding: 0;
font-family: monospace;
font-size: var(--aimdo-font-size, 12px);
z-index: 50;
min-width: 200px;
width: 340px;
max-width: 100vw;
box-shadow: 0 4px 12px rgba(0,0,0,0.7);
user-select: none;
display: flex;
flex-direction: column;
}
/* docked: flatten the panel into a horizontal row that fits the topbar actionbar */
#aimdo-viz-panel.aimdo-docked {
position: static !important;
left: auto !important; top: auto !important; right: auto !important; bottom: auto !important;
width: auto !important; height: auto !important;
min-width: 0 !important; max-width: none !important; max-height: none !important;
border: none !important; border-radius: 0 !important;
box-shadow: none !important; background: transparent !important;
flex-direction: row !important;
align-items: center;
zoom: 1 !important;
transform: none !important;
}
/* ---------------- header ---------------- */
.aimdo-header {
display: flex; justify-content: space-between; align-items: center;
padding: 6px 10px;
background: var(--aimdo-headerBg);
border-radius: 8px 8px 0 0;
cursor: move;
}
.aimdo-title {
font-weight: bold;
color: var(--aimdo-text);
white-space: nowrap;
}
/* 2x3 circular-dot drag handle — matches the grip icon on ComfyUI's docked actionbar.
Only shown when docked; floating mode lets the entire header act as the drag surface.
The shape is an SVG mask painted by background-color: border-radius can't anti-alias
a 2px circle reliably, and a radial-gradient ends up chunkier than what Chrome draws
for true SVG primitives. SVG renders the same crisp dots in both browsers. */
.aimdo-drag-handle {
display: none;
box-sizing: content-box;
width: 6px;
height: 10px;
padding: 0 4px;
background-color: var(--aimdo-textDim);
-webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 10'><circle cx='1' cy='1' r='0.8'/><circle cx='5' cy='1' r='0.8'/><circle cx='1' cy='5' r='0.8'/><circle cx='5' cy='5' r='0.8'/><circle cx='1' cy='9' r='0.8'/><circle cx='5' cy='9' r='0.8'/></svg>");
mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 10'><circle cx='1' cy='1' r='0.8'/><circle cx='5' cy='1' r='0.8'/><circle cx='1' cy='5' r='0.8'/><circle cx='5' cy='5' r='0.8'/><circle cx='1' cy='9' r='0.8'/><circle cx='5' cy='9' r='0.8'/></svg>");
-webkit-mask-size: 6px 10px;
mask-size: 6px 10px;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-origin: content-box;
mask-origin: content-box;
cursor: grab;
touch-action: none;
flex-shrink: 0;
align-self: center;
}
#aimdo-viz-panel.aimdo-docked .aimdo-drag-handle {
display: inline-block;
padding: 0 8px;
}
.aimdo-drag-handle:active { cursor: grabbing; }
.aimdo-drag-handle:hover { background-color: var(--aimdo-text); }
/* 关闭显示状态:隐藏全部内容,仅保留拖拽手柄 + 齿轮按钮 */
#aimdo-viz-panel.aimdo-hidden.aimdo-docked .aimdo-mini-bar,
#aimdo-viz-panel.aimdo-hidden .aimdo-mini-bar { display: none !important; }
#aimdo-viz-panel.aimdo-hidden .aimdo-title { display: none !important; }
#aimdo-viz-panel.aimdo-hidden .aimdo-header-right { display: none !important; }
#aimdo-viz-panel.aimdo-hidden .aimdo-header {
padding: 0 !important;
background: transparent !important;
}
#aimdo-viz-panel.aimdo-hidden .aimdo-drag-handle {
display: inline-block !important;
cursor: pointer;
width: auto;
height: 28px;
padding: 0 6px !important;
margin-right: 4px;
-webkit-mask-image: none !important;
mask-image: none !important;
position: relative;
}
#aimdo-viz-panel.aimdo-hidden .aimdo-drag-handle::after {
content: "⋮";
display: block;
color: var(--aimdo-btnText);
font-size: 20px;
line-height: 28px;
text-align: center;
}
#aimdo-viz-panel.aimdo-hidden .aimdo-drag-handle:hover::after {
color: var(--aimdo-vram);
}
#aimdo-viz-panel.aimdo-hidden .aimdo-drag-handle:hover::after {
color: var(--aimdo-vram);
}
#aimdo-viz-panel.aimdo-hidden #aimdo-viz-body { display: none !important; }
.aimdo-header-right {
display: flex; align-items: center; gap: 6px;
margin-left: auto;
}
#aimdo-viz-panel.aimdo-docked .aimdo-header {
padding: 2px 8px 2px 0 !important;
background: transparent !important;
border-radius: 0 !important;
flex-shrink: 0;
cursor: default;
}
/* ---------------- buttons ---------------- */
.aimdo-btn {
cursor: pointer;
font-size: 0.833em;
line-height: 1;
padding: 1px 6px;
background: var(--aimdo-btn);
border-radius: 3px;
color: var(--aimdo-btnText);
white-space: nowrap;
}
.aimdo-btn-icon {
cursor: pointer;
color: var(--aimdo-btnText);
padding: 0 4px;
}
/* 齿轮设置按钮 — 仿 ComfyUI 工具栏按钮风格 */
.aimdo-gear-btn {
display: none;
cursor: pointer;
padding: 3px 9px;
font-size: 17px;
line-height: 22px;
color: var(--aimdo-btnText);
background: var(--aimdo-btn);
border: 1px solid var(--aimdo-border);
border-radius: 5px;
transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.aimdo-gear-btn:hover {
color: var(--aimdo-text);
background: var(--aimdo-vram);
border-color: var(--aimdo-vram);
}
#aimdo-viz-panel.aimdo-docked .aimdo-gear-btn { display: inline-block; }
#aimdo-viz-panel.aimdo-hidden .aimdo-gear-btn { display: inline-block !important; }
}
#aimdo-viz-panel.aimdo-docked .aimdo-btn {
font-size: 0.917em;
padding: 3px 6px;
}
/* play / cancel-running button — same shape as other header buttons, but the icon
carries the state color (green play, red stop). Hover lifts the background. */
.aimdo-exec-btn {
cursor: pointer;
user-select: none;
display: inline-block;
text-align: center;
min-width: 1em; /* keeps width stable across » /   */
font-size: 0.833em;
line-height: 1;
padding: 2px 6px;
background: var(--aimdo-btn);
border-radius: 3px;
color: var(--aimdo-torch);
white-space: nowrap;
transition: filter 0.1s;
}
.aimdo-exec-btn:hover { filter: brightness(1.4); }
.aimdo-exec-btn.is-running { color: var(--aimdo-gpuUtilHi); }
#aimdo-viz-panel.aimdo-docked .aimdo-exec-btn {
font-size: 1em;
padding: 2.5px 10px;
}
/* ---------------- mini-bar ---------------- */
.aimdo-mini-bar {
display: none;
padding: 4px 10px 6px;
font-size: 0.833em;
color: var(--aimdo-textDim);
}
.aimdo-mini-row {
display: flex; justify-content: space-between; gap: 6px; margin-bottom: 2px;
}
.aimdo-mini-track {
background: var(--aimdo-barBg);
border-radius: 2px;
height: 8px;
overflow: hidden;
display: flex;
margin-bottom: 4px;
}
.aimdo-mini-track-last {
margin-bottom: 0;
}
/* GPU section: one row per metric — bar + value on the same line. The compact 8px
font + 6px bar kicks in only when temp/power are also visible (the .is-multibar
class); with only util showing, the row keeps the regular mini-bar styling so it
matches RAM/VRAM/CPU above. */
.aimdo-mini-inline {
display: flex;
align-items: center;
gap: 4px;
}
.mini-gpu-section.is-multibar .aimdo-mini-inline,
.mini-disk-section.is-multibar .aimdo-mini-inline {
line-height: 1;
font-size: 0.667em;
}
.mini-gpu-section.is-multibar .aimdo-mini-inline .aimdo-mini-track,
.mini-disk-section.is-multibar .aimdo-mini-inline .aimdo-mini-track { height: 6px; }
.aimdo-mini-inline .aimdo-mini-track {
flex: 1 1 0;
margin-bottom: 0;
}
/* Docked single-bar mode (only util visible): the inline track must keep the 4px
bottom margin that a standalone track has. Otherwise the GPU block is 4px shorter
than RAM/VRAM/CPU and, because the docked row centers its sections, the GPU bar
sits 2px lower than the others. Scoped to docked layout on purpose — in the
stacked (expanded) layout the offset does not occur and the section stays as-is. */
#aimdo-viz-panel.aimdo-docked .mini-gpu-section:not(.is-multibar) .aimdo-mini-inline .aimdo-mini-track {
margin-bottom: 4px;
}
.aimdo-mini-inline > .mini-gpu-usage,
.aimdo-mini-inline > .mini-temp-usage,
.aimdo-mini-inline > .mini-power-usage,
.aimdo-mini-inline > .mini-disk-read-usage,
.aimdo-mini-inline > .mini-disk-write-usage {
flex-shrink: 0;
text-align: right;
min-width: 32px;
}
/* push the header value to the right even when the GPU label is hidden */
.mini-gpu-header-value {
margin-left: auto;
}
/* single-bar mode: hide the inline value next to the bar — the value lives in
the title row instead so the layout matches RAM/VRAM/CPU above. */
.mini-gpu-section:not(.is-multibar) .aimdo-mini-inline > .mini-gpu-usage,
.mini-gpu-section:not(.is-multibar) .aimdo-mini-inline > .mini-temp-usage,
.mini-gpu-section:not(.is-multibar) .aimdo-mini-inline > .mini-power-usage {
display: none;
}
.aimdo-mini-fill {
height: 100%;
width: 0;
transition: width 0.35s ease-out, background 0.35s ease-out;
}
.mini-disk-read-fill { background: var(--aimdo-pinned); }
.mini-disk-write-fill { background: var(--aimdo-vram); }
.mini-faults-fill { background: var(--aimdo-gpuUtil); }
/* Optional group dividers: a thin line between logical groups (memory,
storage, compute). The .mini-group-start class marks the first section
of each non-leading group. Sections of the same group sit flush; if every
section in a group is hidden the divider still lands on the next visible
group-start (acceptable, matches the leading-edge quirk elsewhere). */
.aimdo-mini-bar.has-separators > .mini-group-start {
border-top: 1px solid var(--aimdo-border);
padding-top: 10px;
margin-top: 10px;
}
#aimdo-viz-panel.aimdo-docked .aimdo-mini-bar.has-separators > .mini-group-start {
border-top: 0;
padding-top: 0;
margin-top: 0;
border-left: 1px solid var(--aimdo-border);
padding-left: 16px;
margin-left: 6px;
/* content-box: the 16px indent + 1px divider must NOT eat into the declared
width. With the global border-box they shortened this section's bar by 17px,
so the group-start bar was visibly shorter than the others. */
box-sizing: content-box;
}
/* free disk space: one row per selected drive, mountpoint left, bar middle, "free" right.
Mountpoint column is fixed-width so multiple drives align vertically. */
.mini-diskspace-section.is-multibar .aimdo-mini-inline { line-height: 1; font-size: 0.667em; }
.mini-diskspace-section.is-multibar .aimdo-mini-inline .aimdo-mini-track { height: 6px; }
.mini-diskspace-drive-row > .mini-diskspace-mp {
flex-shrink: 0;
text-align: left;
min-width: 18px;
max-width: 36px;
overflow: hidden;
text-overflow: ellipsis;
}
.mini-diskspace-drive-row > .mini-diskspace-usage {
flex-shrink: 0;
text-align: right;
min-width: 32px;
}
.mini-diskspace-section.no-units .mini-diskspace-drive-row > .mini-diskspace-usage {
min-width: 18px;
}
/* docked mini-bar: horizontal, fixed-width sections. flex-end (not center) keeps
every bar on one horizontal line: all sections end with a bar plus the same 4px
trailing gap, so bottom-aligning the sections aligns the bars even when a label
row wraps to a second line and grows taller than the others. */
#aimdo-viz-panel.aimdo-docked .aimdo-mini-bar {
display: flex !important; flex-direction: row !important;
padding: 0 !important; gap: 12px; align-items: flex-end;
flex: 1 1 auto; min-width: 0;
font-size: 0.75em;
}
#aimdo-viz-panel.aimdo-docked .aimdo-mini-row {
flex-wrap: wrap;
justify-content: flex-start;
gap: 0;
margin-bottom: 3px;
}
/* "label|value" with no wasted space: the separator rides on the label so it
disappears together with a hidden label (miniShowType off) and never leaves a
stray leading "|"; :not(:only-child) skips single-span rows (e.g. disk space). */
#aimdo-viz-panel.aimdo-docked .aimdo-mini-row > span:first-child:not(:only-child)::after {
content: "|";
}
/* keep the GPU header value next to the label instead of pushed to the far right */
#aimdo-viz-panel.aimdo-docked .mini-gpu-header-value {
margin-left: 0;
}
#aimdo-viz-panel.aimdo-docked .aimdo-mini-row > span {
flex-shrink: 0;
white-space: nowrap;
}
#aimdo-viz-panel.aimdo-docked .aimdo-mini-bar > * {
width: var(--aimdo-dock-section-w, 70px);
min-width: var(--aimdo-dock-section-w, 70px);
flex: 0 0 auto;
overflow: hidden;
}
/* ---------------- body ---------------- */
#aimdo-viz-body {
padding: 8px 10px;
flex: 1 1 auto;
min-height: 120px;
display: flex;
flex-direction: column;
overflow: hidden;
}
#aimdo-viz-panel.aimdo-docked #aimdo-viz-body { display: none !important; }
#aimdo-viz-panel.aimdo-docked.aimdo-docked-expanded #aimdo-viz-body {
display: flex !important;
position: fixed !important;
z-index: 1500;
width: 420px;
max-height: 60vh;
background: var(--aimdo-bg);
color: var(--aimdo-text);
border: 1px solid var(--aimdo-border);
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0,0,0,0.7);
}
/* ---------------- bar segments (mini-bar + main content rows) ---------------- */
.aimdo-seg { height: 100%; }
.aimdo-seg-vram { background: var(--aimdo-vram); }
.aimdo-seg-torch { background: var(--aimdo-torch); }
.aimdo-seg-torchCache { background: var(--aimdo-torchCache); }
.aimdo-seg-pinned { background: var(--aimdo-pinned); }
.aimdo-seg-loadedRam { background: var(--aimdo-loadedRam); }
.aimdo-seg-python { background: var(--aimdo-python); }
.aimdo-seg-other { background: var(--aimdo-other); }
.aimdo-seg-unloaded { background: var(--aimdo-unloaded); }
/* ---------------- model rows (scroll area) ---------------- */
#aimdo-models { scrollbar-width: thin; scrollbar-color: var(--aimdo-btn) transparent; }
#aimdo-models::-webkit-scrollbar { width: 8px; }
#aimdo-models::-webkit-scrollbar-track { background: transparent; }
#aimdo-models::-webkit-scrollbar-thumb { background: var(--aimdo-btn); border-radius: 4px; }
#aimdo-models::-webkit-scrollbar-thumb:hover { background: var(--aimdo-textDim); }
.aimdo-model-row {
margin-top: 6px;
background: var(--aimdo-rowBg);
/* transparent border reserves space so the row height stays constant when the colored stroke toggles */
border: 1px solid transparent;
border-radius: 4px;
padding: 6px 8px;
}
.aimdo-model-head {
display: flex; justify-content: space-between; align-items: center;
margin-bottom: 2px;
}
.aimdo-model-name {
cursor: pointer; user-select: none;
padding: 1px 4px; margin: -1px -4px;
border-radius: 3px;
transition: background 0.1s;
}
.aimdo-model-name:hover { background: var(--aimdo-btn); }
.aimdo-model-chevron {
color: var(--aimdo-textDim);
margin-right: 4px;
font-size: 0.75em;
}
.aimdo-model-right {
display: flex; align-items: center; gap: 6px;
}
.aimdo-model-bar {
background: var(--aimdo-barBg);
border-radius: 3px;
height: 10px;
overflow: hidden;
display: flex;
}
.aimdo-model-legend {
display: flex; gap: 8px;
font-size: 0.833em;
color: var(--aimdo-textDim);
margin-top: 2px;
}
.aimdo-unload-btn, .aimdo-reset-wm-btn {
cursor: pointer;
font-size: 0.75em;
padding: 0px 4px;
background: var(--aimdo-btn);
border-radius: 2px;
color: var(--aimdo-btnText);
}
.aimdo-graph-canvas { cursor: crosshair; }
/* graph-height resize bar — highlights on hover and stays lit while dragging */
.aimdo-graph-resize {
height: 4px; cursor: ns-resize;
flex-shrink: 0; margin: 1px 0;
}
.aimdo-graph-resize:hover,
.aimdo-graph-resize.is-dragging { background: var(--aimdo-btn); }
/* ---------------- menus (root + submenus + unload menu) ---------------- */
.aimdo-menu {
display: none;
position: fixed;
z-index: 1500;
background: var(--aimdo-headerBg);
color: var(--aimdo-text);
border: 1px solid var(--aimdo-border);
border-radius: 4px;
padding: 2px 0;
min-width: 120px;
box-shadow: 0 4px 12px rgba(0,0,0,0.7);
font-family: monospace;
font-size: 0.833em;
}
.aimdo-menu-item {
padding: 4px 10px;
cursor: pointer;
white-space: nowrap;
}
.aimdo-menu-item:hover {
background: var(--aimdo-btn);
}
.aimdo-menu-item.is-disabled {
opacity: 0.4;
cursor: default;
}
.aimdo-menu-header {
padding: 4px 10px 2px;
color: var(--aimdo-textDim);
font-size: 0.75em;
text-transform: uppercase;
letter-spacing: 0.5px;
border-top: 1px solid var(--aimdo-border);
margin-top: 2px;
cursor: default;
}
.aimdo-menu-item.is-disabled:hover {
background: transparent;
}
.aimdo-menu-parent {
padding: 4px 10px; cursor: default; white-space: nowrap;
display: flex; justify-content: space-between; gap: 12px;
}
.aimdo-menu-parent:hover {
background: var(--aimdo-btn);
}
.aimdo-chevron { color: var(--aimdo-textDim); }
.aimdo-check {
display: inline-block;
width: 12px;
text-align: center;
}
/* ---------------- resize handles ---------------- */
.aimdo-edge-handle { position: absolute; z-index: 1; }
.aimdo-edge-left { top: 28px; bottom: 0; left: 0; width: 4px; cursor: ew-resize; }
.aimdo-edge-right { top: 28px; bottom: 0; right: 0; width: 4px; cursor: ew-resize; }
.aimdo-edge-bottom { left: 4px; right: 4px; bottom: 0; height: 4px; cursor: ns-resize; }
.aimdo-corner-handle {
position: absolute; right: 0; bottom: 0;
width: 8px; height: 8px; cursor: nwse-resize; z-index: 2;
background: linear-gradient(135deg,
transparent 50%,
var(--aimdo-textDim) 50%, var(--aimdo-textDim) 60%,
transparent 60%, transparent 75%,
var(--aimdo-textDim) 75%, var(--aimdo-textDim) 85%,
transparent 85%);
border-bottom-right-radius: 4px;
opacity: 0.55;
}
.aimdo-corner-handle:hover { opacity: 1; }
#aimdo-viz-panel.aimdo-docked .aimdo-edge-handle,
#aimdo-viz-panel.aimdo-docked .aimdo-corner-handle { display: none !important; }
/* ---------------- drop zone (shown during a drag toward the topbar) ---------------- */
.aimdo-dropzone {
position: relative; z-index: 1501;
align-self: stretch; margin: 6px;
padding: 0 12px;
display: flex; align-items: center; justify-content: center;
font-family: monospace; font-size: 0.917em;
border: 2px dashed #3b82f6; border-radius: 6px;
background: rgba(59,130,246,0.4); color: #fff;
pointer-events: auto; min-width: 160px;
opacity: 0.9;
transition: transform 0.12s, opacity 0.12s, box-shadow 0.12s, border-width 0.12s;
}
.aimdo-dropzone-left { order: -2; }
.aimdo-dropzone-right { order: 2; }
.aimdo-dropzone.is-hover {
opacity: 1; transform: scale(1.04);
border-width: 3px; box-shadow: 0 0 20px rgba(59,130,246,0.45);
}