style(prompt-studio): default to left dock, auto-orient track facing canvas, widen cards column to 190px and eliminate topbar wrapping
This commit is contained in:
+6
-5
@@ -193,11 +193,12 @@ DOM or live LiteGraph state.
|
||||
- **Floating Trigger Button & Anomalous Hypercube Core (悬浮入口魔晶重构)**:
|
||||
- 重绘旧版扁平纸箱立方体为 **「异象超维魔方核 (Anomalous Hypercube Core)」**:外层等轴测立体超维立方体轮廓,内嵌悬浮发光微晶棱镜(`--amb-accent` 随主题自适应为天青/猩红),核心凝聚一枚四芒星辉奇点(`✦`),兼具 3D 模型容器特征与魔法档案馆星辰意象。
|
||||
- 悬浮球体容器 (`#anomalous-trigger-btn`) 升级为亚克力磨砂深色毛玻璃材质 (`backdrop-filter: blur(16px)`),悬停微移提亮,图标伴随 12° 优雅微旋与天青/猩红柔和微光,保持高度克制的同时极具辨识度与高级质感。
|
||||
- **Prompt Studio Dual-Column Workbench (提示词工坊两行顶栏与容器自适应)**:
|
||||
- Topbar restructured into two clean rows: Row 1 hosts Back, shortened title ("提示词组合"), New, "更多 ▾" dropdown (containing Export), and primary Save Plan; Row 2 hosts expanded preset name and tag inputs.
|
||||
- Insert position ("添加到前面/后面") relocated into the target node write bar, adjacent to widget selection and write triggers where execution actually happens.
|
||||
- Left Column ("词卡库"): 280-320px width, clean cards with explicit text role badges (`[正向]` / `[负向]`), 2-line preview, single top drag hint, and secondary node/material extract buttons.
|
||||
- Responsive Container Query: Uses `@container prompt-workbench (max-width: 850px)` to smoothly stack panels vertically in narrow dock/floating windows without clipping or forced 100% heights.
|
||||
- **Prompt Studio Dual-Column Workbench (提示词工坊侧边抽屉与双向自适应停靠)**:
|
||||
- **Default Left Docking & Canvas-Facing Flow**: Defaults to left dock (`is-dock-left`), with Source Cards (190px) on the outer screen edge and Assembly Track on the inner side directly facing the ComfyUI canvas.
|
||||
- **Bidirectional Column Flipping**: When toggled to right dock, the layout seamlessly swaps column visual order (`order: 1` for Assembly Track facing canvas on left, `order: 2` for Source Cards along right screen edge) so that the Assembly Track is ALWAYS adjacent to the ComfyUI canvas regardless of docking side.
|
||||
- **Single-Line Unbroken Topbar**: Topbar strictly enforces `flex-wrap: nowrap`, keeping Title, Preset Name input (constrained max-width 140px), Node Extraction (`🎯`), Dock Toggle (`→`/`←`), More dropdown (`··· 更多`), and Close (`✕`) in a unified single row under any drawer width.
|
||||
- **De-cluttered Left Panel**: Expanded left column from 145px to 190px, purged redundant text buttons into compact 24x24 icon buttons (`[📥]` and `[+]`), shortened category filter pills to clean 2-character chips (`[全部]`, `[底模]`, `[风格]`, `[主体]`, `[触发]`) fitting into a single row, and removed bulky instructional tip banners.
|
||||
- **Dynamic Floating Action Dock & Popout Modal**: Floating Action Dock slides up only when blocks exist; provides single-click Node Direct Write and popout full-screen Prompt Inspector (`openPromptInspectorModal`) for deep multi-line tuning.
|
||||
- **Uniform Card Skeletons**: Recipe and material cards enforce "Preview -> 2-Line Clamped Title -> Key Specs -> Footer Action Bar" order, preventing Chinese title clipping; Model cards display titles and filenames at rest without `translateY` collapse and without `backdrop-filter: blur`, fading in action buttons on hover.
|
||||
- **Custom Tooltip System (`[data-tooltip]`)**: Solid dark capsules (`rgba(18, 20, 26, 0.98)`), 350ms standard hover delay, and keyboard focus-visible support.
|
||||
|
||||
|
||||
@@ -345,15 +345,15 @@ export async function openPromptStudio(owner = this) {
|
||||
activeStudioDrawer = drawer;
|
||||
overlay.appendChild(drawer);
|
||||
|
||||
// Dock side persistence
|
||||
const savedSide = localStorage.getItem('anomalous_studio_dock_side') || 'right';
|
||||
// Dock side persistence (default to left)
|
||||
const savedSide = localStorage.getItem('anomalous_studio_dock_side') || 'left';
|
||||
if (savedSide === 'left') {
|
||||
drawer.classList.add('is-dock-left');
|
||||
}
|
||||
|
||||
// Sidebar width persistence & resize handle
|
||||
const savedWidth = localStorage.getItem('anomalous_studio_sidebar_width') || '520';
|
||||
drawer.style.width = `${Math.max(400, Math.min(window.innerWidth * 0.85, parseInt(savedWidth, 10)))}px`;
|
||||
// Sidebar width persistence & resize handle (default to 580px)
|
||||
const savedWidth = localStorage.getItem('anomalous_studio_sidebar_width') || '580';
|
||||
drawer.style.width = `${Math.max(420, Math.min(window.innerWidth * 0.85, parseInt(savedWidth, 10)))}px`;
|
||||
|
||||
const resizeHandle = document.createElement('div');
|
||||
resizeHandle.className = 'anomalous-studio-resize-handle';
|
||||
@@ -403,8 +403,8 @@ export async function openPromptStudio(owner = this) {
|
||||
};
|
||||
|
||||
resizeHandle.ondblclick = () => {
|
||||
drawer.style.width = '520px';
|
||||
localStorage.setItem('anomalous_studio_sidebar_width', '520');
|
||||
drawer.style.width = '580px';
|
||||
localStorage.setItem('anomalous_studio_sidebar_width', '580');
|
||||
};
|
||||
|
||||
const onKeydown = (e) => {
|
||||
@@ -596,10 +596,12 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
const dockSideBtn = text(topActions, 'button', '', 'anomalous-btn-ghost anomalous-btn-sm');
|
||||
const isLeft = () => activeStudioDrawer?.classList.contains('is-dock-left');
|
||||
const updateDockBtn = () => {
|
||||
dockSideBtn.innerHTML = isLeft() ? '⇥' : '⇤';
|
||||
dockSideBtn.innerHTML = isLeft()
|
||||
? `<svg style="width:13px;height:13px;vertical-align:middle;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg>`
|
||||
: `<svg style="width:13px;height:13px;vertical-align:middle;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>`;
|
||||
dockSideBtn.title = isLeft()
|
||||
? (window.anomalous_browser_lang === 'zh' ? '停靠至右侧' : 'Dock Right')
|
||||
: (window.anomalous_browser_lang === 'zh' ? '停靠至左侧' : 'Dock Left');
|
||||
? (window.anomalous_browser_lang === 'zh' ? '停靠至右侧' : 'Dock to Right')
|
||||
: (window.anomalous_browser_lang === 'zh' ? '停靠至左侧' : 'Dock to Left');
|
||||
};
|
||||
updateDockBtn();
|
||||
dockSideBtn.onclick = () => {
|
||||
@@ -708,25 +710,20 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
// Action button group in leftHeader
|
||||
const leftHeaderActions = text(leftHeader, 'div', '', 'anomalous-workbench-header-actions');
|
||||
|
||||
// Button 1: Extract Prompts from Selected Canvas Node
|
||||
const extractNodeBtn = text(leftHeaderActions, 'button', '', 'anomalous-btn-ghost anomalous-btn-sm anomalous-btn-extract-node');
|
||||
extractNodeBtn.innerHTML = `<svg style="width:12px;height:12px;margin-right:3px;vertical-align:-1px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="3"/></svg>${window.anomalous_browser_lang === 'zh' ? '提取' : 'Extract'}`;
|
||||
extractNodeBtn.title = window.anomalous_browser_lang === 'zh' ? '从画布当前选中节点提取提示词并生成词卡' : 'Extract prompt text from selected canvas node into cards';
|
||||
// Button 1: One-click Sync / Import from Material Library
|
||||
const importMaterialsBtn = text(leftHeaderActions, 'button', '', 'anomalous-btn-ghost anomalous-btn-sm anomalous-icon-btn');
|
||||
importMaterialsBtn.innerHTML = `<svg style="width:13px;height:13px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>`;
|
||||
importMaterialsBtn.title = window.anomalous_browser_lang === 'zh' ? '从素材库同步提示词' : 'Sync prompts from Material Library';
|
||||
|
||||
// Button 2: One-click Sync / Import from Material Library
|
||||
const importMaterialsBtn = text(leftHeaderActions, 'button', '', 'anomalous-btn-ghost anomalous-btn-sm');
|
||||
importMaterialsBtn.innerHTML = `<svg style="width:12px;height:12px;margin-right:3px;vertical-align:-1px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>${window.anomalous_browser_lang === 'zh' ? '导入' : 'Import'}`;
|
||||
importMaterialsBtn.title = window.anomalous_browser_lang === 'zh' ? '读取素材库,一键把素材库里沉淀的提示词捞入当前工坊词库' : 'Read and import all prompts from Material Library into workbench';
|
||||
|
||||
// Button 3: Create New Custom Card (placed in header right, never wraps)
|
||||
const newCardTriggerBtn = text(leftHeaderActions, 'button', '', 'anomalous-btn-ghost anomalous-btn-sm');
|
||||
newCardTriggerBtn.innerHTML = `<svg style="width:12px;height:12px;margin-right:3px;vertical-align:-1px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>${window.anomalous_browser_lang === 'zh' ? '新建' : 'New'}`;
|
||||
newCardTriggerBtn.title = window.anomalous_browser_lang === 'zh' ? '新建并保存一张提示词卡片' : 'Create a new prompt card';
|
||||
// Button 2: Create New Custom Card
|
||||
const newCardTriggerBtn = text(leftHeaderActions, 'button', '', 'anomalous-btn-ghost anomalous-btn-sm anomalous-icon-btn');
|
||||
newCardTriggerBtn.innerHTML = `<svg style="width:13px;height:13px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>`;
|
||||
newCardTriggerBtn.title = window.anomalous_browser_lang === 'zh' ? '新建词卡' : 'Create new prompt card';
|
||||
|
||||
// Search and category filters bar
|
||||
const leftFilterBar = text(leftPanel, 'div', '', 'anomalous-workbench-filter-bar');
|
||||
const leftSearch = text(leftFilterBar, 'input', '', 'anomalous-workbench-search-input');
|
||||
leftSearch.placeholder = window.anomalous_browser_lang === 'zh' ? '搜索提示词或分类...' : 'Search prompt snippet...';
|
||||
leftSearch.placeholder = window.anomalous_browser_lang === 'zh' ? '搜索词卡...' : 'Search cards...';
|
||||
leftSearch.oninput = () => {
|
||||
sourceFilterKeyword = leftSearch.value.trim().toLowerCase();
|
||||
renderSourceCardsList();
|
||||
@@ -735,10 +732,10 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
const leftCategoryPills = text(leftPanel, 'div', '', 'anomalous-workbench-category-pills');
|
||||
const filterCats = [
|
||||
{ id: 'all', label: window.anomalous_browser_lang === 'zh' ? '全部' : 'All' },
|
||||
{ id: 'base', label: window.anomalous_browser_lang === 'zh' ? '通用底模' : 'Base' },
|
||||
{ id: 'style', label: window.anomalous_browser_lang === 'zh' ? '风格氛围' : 'Style' },
|
||||
{ id: 'subject', label: window.anomalous_browser_lang === 'zh' ? '主体内容' : 'Subject' },
|
||||
{ id: 'trigger', label: window.anomalous_browser_lang === 'zh' ? '触发词' : 'Trigger' },
|
||||
{ id: 'base', label: window.anomalous_browser_lang === 'zh' ? '底模' : 'Base' },
|
||||
{ id: 'style', label: window.anomalous_browser_lang === 'zh' ? '风格' : 'Style' },
|
||||
{ id: 'subject', label: window.anomalous_browser_lang === 'zh' ? '主体' : 'Subject' },
|
||||
{ id: 'trigger', label: window.anomalous_browser_lang === 'zh' ? '触发' : 'Trigger' },
|
||||
];
|
||||
filterCats.forEach(cat => {
|
||||
const pill = text(leftCategoryPills, 'button', cat.label, `anomalous-workbench-pill${sourceFilterCategory === cat.id ? ' is-active' : ''}`);
|
||||
@@ -754,15 +751,6 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
const newCardForm = text(leftPanel, 'div', '', 'anomalous-workbench-new-card-form');
|
||||
newCardForm.style.display = 'none';
|
||||
|
||||
// Usage Tip Banner
|
||||
const tipBanner = text(leftPanel, 'div', '', 'anomalous-workbench-tip-banner');
|
||||
tipBanner.innerHTML = `
|
||||
<svg class="anomalous-tip-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>
|
||||
</svg>
|
||||
<span>${window.anomalous_browser_lang === 'zh' ? '点击词卡或拖拽至右侧拼装台,自由调换顺序' : 'Click card or drag to right stage to assemble'}</span>
|
||||
`;
|
||||
|
||||
// Source Cards List
|
||||
const sourceCardsList = text(leftPanel, 'div', '', 'anomalous-source-cards-list');
|
||||
|
||||
@@ -1021,7 +1009,6 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
extractNodeBtn.onclick = () => extractPromptsFromSelectedNode(false);
|
||||
rightSuckNodeBtn.onclick = () => extractPromptsFromSelectedNode(true);
|
||||
|
||||
let materialSyncController = null;
|
||||
@@ -1034,7 +1021,7 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
materialSyncController = controller;
|
||||
|
||||
importMaterialsBtn.disabled = true;
|
||||
importMaterialsBtn.textContent = window.anomalous_browser_lang === 'zh' ? '正在同步素材...' : 'Syncing...';
|
||||
importMaterialsBtn.innerHTML = `<span style="font-size:11px;">⏳</span>`;
|
||||
|
||||
try {
|
||||
const res = await fetch('/anomalous/materials?category=prompts&limit=150', { signal: controller.signal });
|
||||
@@ -1084,7 +1071,7 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
if (materialSyncController === controller) {
|
||||
materialSyncController = null;
|
||||
importMaterialsBtn.disabled = false;
|
||||
importMaterialsBtn.innerHTML = `<svg style="width:12px;height:12px;margin-right:3px;vertical-align:-1px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>${window.anomalous_browser_lang === 'zh' ? '导入' : 'Import'}`;
|
||||
importMaterialsBtn.innerHTML = `<svg style="width:13px;height:13px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1428,15 +1415,13 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
if (!currentRoleParts.length) {
|
||||
const dropzoneNotice = text(blocksContainer, 'div', '', 'anomalous-assembly-dropzone');
|
||||
dropzoneNotice.innerHTML = `
|
||||
<div style="margin-bottom: 12px; opacity: 0.7;">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
<line x1="12" y1="15" x2="12" y2="3"/>
|
||||
<div style="margin-bottom: 12px; opacity: 0.65;">
|
||||
<svg width="38" height="38" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 3v12m0 0l-4-4m4 4l4-4M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div style="font-size: 0.92rem; font-weight: 600; color: #e2e8f0;">${window.anomalous_browser_lang === 'zh' ? '点击下方词卡或拖拽到这里拼装' : 'Click cards below or drop here to assemble'}</div>
|
||||
<div style="font-size: 0.76rem; color: #64748b; margin-top: 4px;">${window.anomalous_browser_lang === 'zh' ? '支持自由调换次序,点击【智能排序】自动理顺' : 'Drag to reorder anytime, or click Smart Sort.'}</div>
|
||||
<div style="font-size: 0.88rem; font-weight: 600; color: #f1f5f9;">${window.anomalous_browser_lang === 'zh' ? '点击词卡或拖拽到这里拼装' : 'Click cards or drag here to assemble'}</div>
|
||||
<div style="font-size: 0.74rem; color: #64748b; margin-top: 5px;">${window.anomalous_browser_lang === 'zh' ? '支持自由拖拽调换次序,点击【智能排序】一键理顺' : 'Reorder freely anytime, or click Smart Sort.'}</div>
|
||||
`;
|
||||
// Accept drops on empty dropzone
|
||||
setupDropzoneListeners(dropzoneNotice);
|
||||
|
||||
+218
-31
@@ -9541,31 +9541,40 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
flex-wrap: nowrap !important;
|
||||
gap: 8px;
|
||||
padding-bottom: 6px;
|
||||
height: 44px;
|
||||
padding: 0 12px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(20, 22, 27, 0.95);
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.anomalous-prompt-topbar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.anomalous-prompt-topbar-left h3 {
|
||||
margin: 0;
|
||||
font-size: 0.98rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.92rem;
|
||||
font-weight: 700;
|
||||
color: #f8fafc;
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.anomalous-prompt-topbar-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
.anomalous-prompt-close-btn {
|
||||
@@ -9585,16 +9594,16 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
background: var(--amb-bg-input, rgba(0, 0, 0, 0.35));
|
||||
border: 1px solid var(--amb-border, rgba(255, 255, 255, 0.14));
|
||||
border-radius: var(--amb-radius-control, 6px);
|
||||
padding: 3px 8px;
|
||||
padding: 2px 8px;
|
||||
height: 26px;
|
||||
color: var(--amb-text-main, #f1f5f9);
|
||||
font-size: 0.78rem;
|
||||
outline: none;
|
||||
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
||||
box-sizing: border-box;
|
||||
flex: 1 1 160px;
|
||||
min-width: 100px;
|
||||
max-width: 240px;
|
||||
flex: 0 1 130px;
|
||||
min-width: 60px;
|
||||
max-width: 140px;
|
||||
}
|
||||
|
||||
.anomalous-prompt-name-input:focus {
|
||||
@@ -12830,7 +12839,7 @@ button:hover .anomalous-btn-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 520px;
|
||||
width: 580px;
|
||||
max-width: 90vw;
|
||||
height: 100vh;
|
||||
background: var(--amb-bg-page, #121316);
|
||||
@@ -12874,7 +12883,7 @@ button:hover .anomalous-btn-icon {
|
||||
box-shadow: 0 0 10px rgba(56, 189, 248, 0.6);
|
||||
}
|
||||
|
||||
/* Drawer Workbench Grid */
|
||||
/* Drawer Workbench Base */
|
||||
.anomalous-prompt-studio-drawer .anomalous-prompt-workbench {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
@@ -12883,40 +12892,190 @@ button:hover .anomalous-btn-icon {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.anomalous-prompt-studio-drawer .anomalous-prompt-workbench-grid {
|
||||
/* Left Dock Mode (Default): Left Column = Cards (190px), Right Column = Assembly Track (faces canvas on right) */
|
||||
.anomalous-prompt-studio-drawer.is-dock-left .anomalous-prompt-workbench-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: 145px minmax(0, 1fr) !important;
|
||||
grid-template-columns: 190px minmax(0, 1fr) !important;
|
||||
flex-direction: row !important;
|
||||
gap: 8px !important;
|
||||
padding: 6px 8px 8px !important;
|
||||
gap: 0 !important;
|
||||
padding: 0 !important;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.anomalous-prompt-studio-drawer .anomalous-workbench-left-panel {
|
||||
.anomalous-prompt-studio-drawer.is-dock-left .anomalous-workbench-left-panel {
|
||||
order: 1 !important;
|
||||
flex: none !important;
|
||||
width: 145px !important;
|
||||
width: 190px !important;
|
||||
max-height: 100% !important;
|
||||
padding: 6px 6px 8px !important;
|
||||
padding: 8px 10px !important;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.08) !important;
|
||||
border-left: none !important;
|
||||
background: rgba(18, 20, 24, 0.7) !important;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.anomalous-prompt-studio-drawer .anomalous-workbench-right-panel {
|
||||
.anomalous-prompt-studio-drawer.is-dock-left .anomalous-workbench-right-panel {
|
||||
order: 2 !important;
|
||||
flex: 1 !important;
|
||||
max-height: 100% !important;
|
||||
padding: 6px 8px 48px !important; /* reserve bottom space for floating dock */
|
||||
padding: 8px 12px 52px !important; /* reserve bottom space for floating dock */
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
background: rgba(14, 15, 18, 0.5) !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Right Dock Mode: Right Column = Cards (190px), Left Column = Assembly Track (faces canvas on left) */
|
||||
.anomalous-prompt-studio-drawer:not(.is-dock-left) .anomalous-prompt-workbench-grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: minmax(0, 1fr) 190px !important;
|
||||
flex-direction: row !important;
|
||||
gap: 0 !important;
|
||||
padding: 0 !important;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.anomalous-prompt-studio-drawer:not(.is-dock-left) .anomalous-workbench-right-panel {
|
||||
order: 1 !important;
|
||||
flex: 1 !important;
|
||||
max-height: 100% !important;
|
||||
padding: 8px 12px 52px !important;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.08) !important;
|
||||
border-left: none !important;
|
||||
background: rgba(14, 15, 18, 0.5) !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.anomalous-prompt-studio-drawer:not(.is-dock-left) .anomalous-workbench-left-panel {
|
||||
order: 2 !important;
|
||||
flex: none !important;
|
||||
width: 190px !important;
|
||||
max-height: 100% !important;
|
||||
padding: 8px 10px !important;
|
||||
border-left: none !important;
|
||||
border-right: none !important;
|
||||
background: rgba(18, 20, 24, 0.7) !important;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Column Headers & Action Buttons */
|
||||
.anomalous-workbench-col-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
padding: 0 2px;
|
||||
margin-bottom: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.anomalous-workbench-col-title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 0.84rem;
|
||||
font-weight: 600;
|
||||
color: #f1f5f9;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.anomalous-workbench-col-title .anomalous-sub-counter {
|
||||
font-size: 0.72rem;
|
||||
color: #64748b;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.anomalous-workbench-header-actions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.anomalous-workbench-header-actions button.anomalous-icon-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
border-radius: 5px;
|
||||
color: #94a3b8;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.anomalous-workbench-header-actions button.anomalous-icon-btn:hover {
|
||||
color: #ffffff;
|
||||
background: rgba(56, 189, 248, 0.18);
|
||||
border-color: rgba(56, 189, 248, 0.4);
|
||||
}
|
||||
|
||||
/* Category Pills: 5 equal 2-char chips */
|
||||
.anomalous-workbench-category-pills {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
flex-wrap: nowrap;
|
||||
margin: 4px 0 8px;
|
||||
}
|
||||
|
||||
.anomalous-workbench-pill {
|
||||
flex: 1 1 0;
|
||||
text-align: center;
|
||||
padding: 3px 0;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
color: #94a3b8;
|
||||
font-size: 0.72rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.anomalous-workbench-pill:hover {
|
||||
color: #f1f5f9;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.anomalous-workbench-pill.is-active {
|
||||
color: #38bdf8;
|
||||
background: rgba(56, 189, 248, 0.15);
|
||||
border-color: rgba(56, 189, 248, 0.4);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Compact Source Cards in 190px */
|
||||
.anomalous-source-cards-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
/* Compact Source Cards */
|
||||
.anomalous-source-card-compact {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 8px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
padding: 5px 8px;
|
||||
background: rgba(255, 255, 255, 0.035);
|
||||
border: 1px solid rgba(255, 255, 255, 0.07);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
@@ -12926,27 +13085,31 @@ button:hover .anomalous-btn-icon {
|
||||
}
|
||||
|
||||
.anomalous-source-card-compact:hover {
|
||||
background: rgba(56, 189, 248, 0.15);
|
||||
border-color: rgba(56, 189, 248, 0.4);
|
||||
background: rgba(56, 189, 248, 0.12);
|
||||
border-color: rgba(56, 189, 248, 0.35);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
.anomalous-source-card-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.anomalous-source-card-name {
|
||||
font-size: 0.74rem;
|
||||
color: #e2e8f0;
|
||||
font-size: 0.75rem;
|
||||
color: #cbd5e1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.anomalous-source-card-compact:hover .anomalous-source-card-name {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.anomalous-source-card-add-icon {
|
||||
font-size: 0.72rem;
|
||||
color: #64748b;
|
||||
@@ -12960,6 +13123,30 @@ button:hover .anomalous-btn-icon {
|
||||
color: #38bdf8;
|
||||
}
|
||||
|
||||
/* Assembly Dropzone Notice */
|
||||
.anomalous-assembly-dropzone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
min-height: 260px;
|
||||
padding: 40px 20px;
|
||||
border: 1px dashed rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.015);
|
||||
color: #64748b;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.anomalous-assembly-dropzone:hover,
|
||||
.anomalous-assembly-dropzone.is-drag-over {
|
||||
border-color: rgba(56, 189, 248, 0.4);
|
||||
background: rgba(56, 189, 248, 0.04);
|
||||
}
|
||||
|
||||
/* Weight Wheel Pill in Assembled Blocks */
|
||||
.anomalous-block-weight-pill {
|
||||
display: inline-flex;
|
||||
|
||||
Reference in New Issue
Block a user