feat(prompt-studio): enhance card tactile affordance and auto-snap drop dock
This commit is contained in:
+2
-1
@@ -153,7 +153,7 @@ DOM or live LiteGraph state.
|
||||
features compact vertical spacing with an inline topbar hosting the preset name input (`.anomalous-prompt-name-input`), direct `[💾 保存方案]` button, secondary action dropdown (`[··· 更多]` for new draft, preset tags, and JSON export), and window close button (`[✕]`), completely eliminating bulky standalone metadata strips;
|
||||
in docked sidebar mode (`#anomalous-container.anomalous-docked`) and narrow screen layouts (<860px), adopts a Unified Dual-Zone Flow (上下联动一体流): completely eliminates clumsy tab switching (`[词卡库 | 拼装台 | 全部]`), arranging the Assembler Stage on top (`order: 1`, max-height 54%) and Candidate Cards Deck on bottom (`order: 2`, max-height 50%), both with independent scroll containers to ensure candidate cards and assembled Lego blocks remain simultaneously visible;
|
||||
the Cards Deck hosts candidate prompt cards in a compact 2-column chip grid (`repeat(auto-fill, minmax(130px, 1fr))`) with 1-tap instant assembly (`cardEl.onclick` adds card to the active track with `@keyframes anomalous-just-added` animated feedback) alongside native HTML5 drag-and-drop,
|
||||
features restrained dark slate backgrounds (`#24262E`) with category-specific left accent borders (Base/Style/Subject/Trigger),
|
||||
features tactile glassmorphic card styling (dual-layer elevation shadows, top edge highlight, and category glow accents), a physical drag grip (`⠿`), a usage tip banner (`💡 点击词卡或拖拽至右侧拼装台`), monospace prompt snippet chips, and high-visibility `[+ 加入拼装台]` action buttons with instant click feedback,
|
||||
minimalist empty state container (`.anomalous-source-empty`), a streamlined col-header holding a unified action button group (`[🎯 提取]`, `[📥 导入]`, `[➕ 新建]`),
|
||||
one-click canvas node prompt extraction (`🎯 提取`, reading selected ComfyUI text nodes like `CLIPTextEncode` with downstream link connection traversal for accurate negative conditioning detection, auto-generating categorised cards) and one-click
|
||||
Material Library batch sync (`📥 导入`, cancellable fetch scoped to `category=prompts`), plus on-demand persistent card creation
|
||||
@@ -162,6 +162,7 @@ DOM or live LiteGraph state.
|
||||
the Assembler Stage hosts the sequential Lego block track (`anomalous-assembly-track`), compact modular blocks (~52px height) allowing generous top-to-bottom sequence stacking,
|
||||
supports bidirectional drag-and-drop reordering with ghost indicator lines, role-aware up/down swapping, instant A/B bypass toggles (greyscale dimming without deleting),
|
||||
interactive category pills, one-click Smart Sort (`🪄 按分类排序`, Base ➔ Style ➔ Subject ➔ Trigger),
|
||||
an interactive Auto-snap Dock (`.anomalous-assembly-snap-dock`) positioned at the bottom of the track that magnetically detects dragover across the empty lower track area to auto-snap dragged cards or blocks to the end with animated visual guidance,
|
||||
and a permanently visible sticky Action Dock (`.anomalous-prompt-action-dock`) at the bottom of the assembler stage: displays live synthesis statistics (`✨ X字 · Y块`), quick copy button (`[📋]`), expandable compiled text preview drawer (`[📄 最终文本 ▾]`), insertion position selector (`[在后 ▾] / [在前 ▾]`), and the ComfyUI canvas node direct injection bar (`[#ID 节点名称] [⬇️ 写入正向/负向]`), ensuring canvas node injection is always 1-click away and never buried inside collapsed drawers;
|
||||
`prompt_composition.js` provides bidirectional schema mapping (`planToWorkbenchDraft` and `workbenchDraftToSavedPlan`) ensuring
|
||||
100% roundtrip data integrity across `anomalous-prompt-plan-v1` and `version: 2`, lossless legacy dual-role splitting and trailing text retention,
|
||||
|
||||
@@ -444,6 +444,15 @@ 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');
|
||||
|
||||
@@ -474,6 +483,47 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
// Blocks Container & Dropzone
|
||||
const blocksContainer = text(rightPanel, 'div', '', 'anomalous-mixer-blocks-container anomalous-assembly-track');
|
||||
|
||||
blocksContainer.ondragover = (e) => {
|
||||
e.preventDefault();
|
||||
const snapDock = blocksContainer.querySelector('.anomalous-assembly-snap-dock');
|
||||
if (snapDock && (e.target === blocksContainer || e.target.closest('.anomalous-assembly-snap-dock'))) {
|
||||
snapDock.classList.add('is-drag-over');
|
||||
blocksContainer.classList.add('is-drag-over-end');
|
||||
}
|
||||
};
|
||||
blocksContainer.ondragleave = (e) => {
|
||||
if (!blocksContainer.contains(e.relatedTarget)) {
|
||||
const snapDock = blocksContainer.querySelector('.anomalous-assembly-snap-dock');
|
||||
snapDock?.classList.remove('is-drag-over');
|
||||
blocksContainer.classList.remove('is-drag-over-end');
|
||||
}
|
||||
};
|
||||
blocksContainer.ondrop = (e) => {
|
||||
if (e.target === blocksContainer || e.target.closest('.anomalous-assembly-snap-dock')) {
|
||||
e.preventDefault();
|
||||
const snapDock = blocksContainer.querySelector('.anomalous-assembly-snap-dock');
|
||||
snapDock?.classList.remove('is-drag-over');
|
||||
blocksContainer.classList.remove('is-drag-over-end');
|
||||
const jsonStr = e.dataTransfer.getData('application/json');
|
||||
if (jsonStr) {
|
||||
try {
|
||||
addSourceCardToMixer(JSON.parse(jsonStr));
|
||||
return;
|
||||
} catch (err) {}
|
||||
}
|
||||
if (draggedBlockId) {
|
||||
const fromIndex = draft.plan.parts.findIndex(p => p.id === draggedBlockId);
|
||||
if (fromIndex >= 0) {
|
||||
const [moved] = draft.plan.parts.splice(fromIndex, 1);
|
||||
draft.plan.parts.push(moved);
|
||||
syncDraftSynthesizedText(draft);
|
||||
renderBlocksList();
|
||||
updateOutputPreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Bottom Live Assembled Action Dock (Always visible sticky bar at bottom of assembler)
|
||||
const outputDeck = text(rightPanel, 'div', '', 'anomalous-mixer-deck-output anomalous-prompt-action-dock is-collapsed');
|
||||
|
||||
@@ -938,13 +988,7 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
filtered.forEach(card => {
|
||||
const cardEl = text(sourceCardsList, 'article', '', `anomalous-source-prompt-card is-cat-${card.category}`);
|
||||
cardEl.setAttribute('draggable', 'true');
|
||||
cardEl.title = window.anomalous_browser_lang === 'zh' ? '点击直接加入上方拼装台(也可拖拽)' : 'Click to add to mixer above (or drag)';
|
||||
|
||||
// Instant tap to add card to mixer
|
||||
cardEl.onclick = (e) => {
|
||||
if (e.target.closest('button') || e.target.closest('input')) return;
|
||||
addSourceCardToMixer(card);
|
||||
};
|
||||
cardEl.title = window.anomalous_browser_lang === 'zh' ? '点击直接加入右侧拼装台(也可按住拖拽)' : 'Click to add to stage (or drag)';
|
||||
|
||||
// Drag Start -> transfer prompt card payload
|
||||
cardEl.ondragstart = (e) => {
|
||||
@@ -970,6 +1014,9 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
const header = text(cardEl, 'div', '', 'anomalous-source-card-header');
|
||||
const meta = CATEGORY_META[card.category] || CATEGORY_META.subject;
|
||||
|
||||
const grip = text(header, 'span', '⠿', 'anomalous-source-card-grip');
|
||||
grip.title = window.anomalous_browser_lang === 'zh' ? '按住拖拽至拼装台' : 'Drag to assemble';
|
||||
|
||||
const badge = text(header, 'span', window.anomalous_browser_lang === 'zh' ? meta.zh : meta.en, 'anomalous-source-card-badge');
|
||||
badge.style.color = meta.color;
|
||||
badge.style.backgroundColor = meta.bg;
|
||||
@@ -994,6 +1041,9 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
|
||||
// Card Footer Actions
|
||||
const footer = text(cardEl, 'div', '', 'anomalous-source-card-footer');
|
||||
const hint = text(footer, 'span', '', 'anomalous-source-card-drag-hint');
|
||||
hint.innerHTML = `<svg style="width:10px;height:10px;vertical-align:-1px;margin-right:3px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 8v8M8 12h8"/></svg>${window.anomalous_browser_lang === 'zh' ? '点击或拖拽' : 'Click or Drag'}`;
|
||||
|
||||
const actions = text(footer, 'div', '', 'anomalous-source-card-actions');
|
||||
actions.style.marginLeft = 'auto';
|
||||
|
||||
@@ -1021,11 +1071,32 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
}
|
||||
|
||||
const dockBtn = text(actions, 'button', '', 'anomalous-source-action-btn is-dock');
|
||||
dockBtn.innerHTML = `<svg style="width:12px;height:12px;margin-right:4px;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' ? '加入组合' : 'Add to Plan'}`;
|
||||
dockBtn.title = window.anomalous_browser_lang === 'zh' ? '加入当前拼装组合' : 'Add into mixer track';
|
||||
dockBtn.innerHTML = `<svg style="width:11px;height:11px;margin-right:4px;vertical-align:-1px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>${window.anomalous_browser_lang === 'zh' ? '加入拼装台' : 'Add to Stage'}`;
|
||||
dockBtn.title = window.anomalous_browser_lang === 'zh' ? '点击加入当前拼装台(也可直接点击卡片)' : 'Add into mixer track';
|
||||
|
||||
const handleCardAdd = () => {
|
||||
cardEl.classList.add('is-clicked');
|
||||
setTimeout(() => cardEl.classList.remove('is-clicked'), 500);
|
||||
const originalHtml = dockBtn.innerHTML;
|
||||
dockBtn.innerHTML = `✓ ${window.anomalous_browser_lang === 'zh' ? '已加入' : 'Added'}`;
|
||||
dockBtn.classList.add('is-success');
|
||||
setTimeout(() => {
|
||||
if (dockBtn.isConnected) {
|
||||
dockBtn.innerHTML = originalHtml;
|
||||
dockBtn.classList.remove('is-success');
|
||||
}
|
||||
}, 700);
|
||||
addSourceCardToMixer(card);
|
||||
};
|
||||
|
||||
cardEl.onclick = (e) => {
|
||||
if (e.target.closest('button') || e.target.closest('input')) return;
|
||||
handleCardAdd();
|
||||
};
|
||||
|
||||
dockBtn.onclick = (e) => {
|
||||
e.stopPropagation();
|
||||
addSourceCardToMixer(card);
|
||||
handleCardAdd();
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -1310,6 +1381,22 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
updateOutputPreview();
|
||||
};
|
||||
});
|
||||
|
||||
// Interactive Auto-snap Dock at end of track
|
||||
const snapDock = text(blocksContainer, 'div', '', 'anomalous-assembly-snap-dock');
|
||||
snapDock.innerHTML = `
|
||||
<div class="anomalous-snap-dock-content">
|
||||
<svg class="anomalous-snap-icon" style="width:14px;height:14px;vertical-align:-2px;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
||||
<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
|
||||
</svg>
|
||||
<span class="anomalous-snap-dock-text">${window.anomalous_browser_lang === 'zh' ? '拖拽卡片至此自动贴合至末尾' : 'Drop card here to snap to bottom'}</span>
|
||||
</div>
|
||||
`;
|
||||
setupDropzoneListeners(snapDock);
|
||||
snapDock.onclick = () => {
|
||||
leftSearch?.focus?.();
|
||||
showWorkbenchToast(window.anomalous_browser_lang === 'zh' ? '点击左侧词卡即可直接加入此处' : 'Click any card on left to add here');
|
||||
};
|
||||
}
|
||||
|
||||
function setupDropzoneListeners(el) {
|
||||
@@ -1327,8 +1414,19 @@ function buildPromptComposer(owner, container, options = {}) {
|
||||
if (jsonStr) {
|
||||
try {
|
||||
addSourceCardToMixer(JSON.parse(jsonStr));
|
||||
return;
|
||||
} catch (err) {}
|
||||
}
|
||||
if (draggedBlockId) {
|
||||
const fromIndex = draft.plan.parts.findIndex(p => p.id === draggedBlockId);
|
||||
if (fromIndex >= 0) {
|
||||
const [moved] = draft.plan.parts.splice(fromIndex, 1);
|
||||
draft.plan.parts.push(moved);
|
||||
syncDraftSynthesizedText(draft);
|
||||
renderBlocksList();
|
||||
updateOutputPreview();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+168
-27
@@ -10836,49 +10836,86 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Individual Source Prompt Card (Restrained Dark Grey Base with Category Left Border) */
|
||||
.anomalous-source-prompt-card {
|
||||
/* Tip Banner for Prompt Studio Usage Guidance */
|
||||
.anomalous-workbench-tip-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 10px;
|
||||
margin: 2px 0 8px;
|
||||
background: rgba(56, 189, 248, 0.07);
|
||||
border: 1px solid rgba(56, 189, 248, 0.2);
|
||||
border-radius: var(--amb-radius-control, 6px);
|
||||
background: var(--amb-bg-card, #24262E);
|
||||
border: 1px solid var(--amb-border, rgba(255, 255, 255, 0.08));
|
||||
border-left: 3.5px solid #64748b;
|
||||
font-size: 0.72rem;
|
||||
color: #93c5fd;
|
||||
line-height: 1.35;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.anomalous-workbench-tip-banner .anomalous-tip-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
flex-shrink: 0;
|
||||
color: #38bdf8;
|
||||
}
|
||||
|
||||
/* Individual Source Prompt Card (Tactile Skewed Glassmorphic Card Aesthetics) */
|
||||
.anomalous-source-prompt-card {
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(180deg, #262935 0%, #1e2029 100%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.11);
|
||||
border-left: 4px solid #64748b;
|
||||
padding: 8px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
cursor: grab;
|
||||
user-select: none;
|
||||
transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card.is-cat-base {
|
||||
border-left-color: #38bdf8;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), -2px 0 8px -3px rgba(56, 189, 248, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.theme-abyssal-scarlet .anomalous-source-prompt-card.is-cat-base {
|
||||
border-left-color: #dc143c;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), -2px 0 8px -3px rgba(220, 20, 60, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card.is-cat-style {
|
||||
border-left-color: #c084fc;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), -2px 0 8px -3px rgba(192, 132, 252, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card.is-cat-subject {
|
||||
border-left-color: #4ade80;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), -2px 0 8px -3px rgba(74, 222, 128, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card.is-cat-trigger {
|
||||
border-left-color: #fb923c;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), -2px 0 8px -3px rgba(251, 146, 60, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card:hover {
|
||||
background: var(--amb-bg-card-hover, #2d303a);
|
||||
border-color: var(--amb-border-hover, rgba(255, 255, 255, 0.16));
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
||||
background: linear-gradient(180deg, #2e3242 0%, #232633 100%);
|
||||
border-color: rgba(255, 255, 255, 0.22);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card:active {
|
||||
cursor: grabbing;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card.is-clicked {
|
||||
transform: scale(0.97);
|
||||
border-color: #38bdf8 !important;
|
||||
box-shadow: 0 0 16px rgba(56, 189, 248, 0.45) !important;
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card.is-dragging-source {
|
||||
@@ -10892,9 +10929,25 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.anomalous-source-card-grip {
|
||||
color: #64748b;
|
||||
font-size: 11px;
|
||||
line-height: 1;
|
||||
margin-right: 1px;
|
||||
letter-spacing: -1px;
|
||||
cursor: grab;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.15s ease, color 0.15s ease;
|
||||
}
|
||||
|
||||
.anomalous-source-prompt-card:hover .anomalous-source-card-grip {
|
||||
opacity: 0.95;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.anomalous-source-card-badge {
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
padding: 2px 7px;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.66rem;
|
||||
font-weight: 600;
|
||||
border: 1px solid transparent;
|
||||
@@ -10902,8 +10955,9 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
}
|
||||
|
||||
.anomalous-source-card-title {
|
||||
font-size: 0.8rem;
|
||||
color: #e2e8f0;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
color: #f1f5f9;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -10911,16 +10965,18 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
}
|
||||
|
||||
.anomalous-source-card-snippet {
|
||||
font-size: 0.74rem;
|
||||
color: #94a3b8;
|
||||
line-height: 1.4;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
color: #cbd5e1;
|
||||
line-height: 1.45;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
padding: 4px 6px;
|
||||
border-radius: 4px;
|
||||
background: rgba(0, 0, 0, 0.32);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
padding: 5px 8px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.anomalous-source-card-footer {
|
||||
@@ -10934,7 +10990,10 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
|
||||
.anomalous-source-card-drag-hint {
|
||||
color: #64748b;
|
||||
font-size: 0.68rem;
|
||||
font-size: 0.66rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.anomalous-source-card-actions {
|
||||
@@ -10960,16 +11019,31 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
}
|
||||
|
||||
.anomalous-source-action-btn.is-dock {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: rgba(255, 255, 255, 0.14);
|
||||
color: var(--amb-text-main, #f1f5f9);
|
||||
font-weight: 500;
|
||||
background: rgba(56, 189, 248, 0.12);
|
||||
border-color: rgba(56, 189, 248, 0.35);
|
||||
color: #38bdf8;
|
||||
font-weight: 600;
|
||||
border-radius: 5px;
|
||||
padding: 3px 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
font-size: 0.7rem;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.anomalous-source-action-btn.is-dock:hover {
|
||||
background: var(--amb-bg-card-hover, rgba(255, 255, 255, 0.14));
|
||||
border-color: var(--amb-border-hover, rgba(255, 255, 255, 0.25));
|
||||
color: #ffffff;
|
||||
background: #38bdf8;
|
||||
color: #0b1329;
|
||||
border-color: #38bdf8;
|
||||
box-shadow: 0 0 12px rgba(56, 189, 248, 0.45);
|
||||
}
|
||||
|
||||
.anomalous-source-action-btn.is-dock.is-success {
|
||||
background: #22c55e !important;
|
||||
border-color: #22c55e !important;
|
||||
color: #ffffff !important;
|
||||
box-shadow: 0 0 12px rgba(34, 197, 94, 0.5) !important;
|
||||
}
|
||||
|
||||
.anomalous-source-action-btn.is-save-lib {
|
||||
@@ -11090,6 +11164,66 @@ dialog.anomalous-gallery-viewer::backdrop {
|
||||
background: rgba(45, 10, 20, 0.6);
|
||||
}
|
||||
|
||||
/* Interactive Auto-snap Dock at the bottom of Assembler blocks */
|
||||
.anomalous-assembly-snap-dock {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 44px;
|
||||
padding: 8px 14px;
|
||||
border: 1.5px dashed rgba(255, 255, 255, 0.14);
|
||||
border-radius: 8px;
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
margin-top: 6px;
|
||||
color: #94a3b8;
|
||||
font-size: 0.74rem;
|
||||
}
|
||||
|
||||
.anomalous-assembly-snap-dock:hover {
|
||||
border-color: rgba(255, 255, 255, 0.28);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.anomalous-assembly-snap-dock.is-drag-over,
|
||||
.anomalous-assembly-track.is-drag-over-end .anomalous-assembly-snap-dock {
|
||||
border-color: #38bdf8 !important;
|
||||
background: rgba(56, 189, 248, 0.12) !important;
|
||||
box-shadow: 0 0 18px rgba(56, 189, 248, 0.25), inset 0 0 10px rgba(56, 189, 248, 0.05) !important;
|
||||
color: #38bdf8 !important;
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
.theme-abyssal-scarlet .anomalous-assembly-snap-dock.is-drag-over,
|
||||
.theme-abyssal-scarlet .anomalous-assembly-track.is-drag-over-end .anomalous-assembly-snap-dock {
|
||||
border-color: #dc143c !important;
|
||||
background: rgba(220, 20, 60, 0.15) !important;
|
||||
box-shadow: 0 0 18px rgba(220, 20, 60, 0.3) !important;
|
||||
color: #ff6b81 !important;
|
||||
}
|
||||
|
||||
.anomalous-snap-dock-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: 500;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.anomalous-snap-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.anomalous-assembly-snap-dock.is-drag-over .anomalous-snap-icon,
|
||||
.anomalous-assembly-track.is-drag-over-end .anomalous-assembly-snap-dock .anomalous-snap-icon {
|
||||
transform: rotate(90deg) scale(1.15);
|
||||
}
|
||||
|
||||
.anomalous-workbench-sub-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -12290,3 +12424,10 @@ button:hover .anomalous-btn-icon {
|
||||
padding: 1px 4px !important;
|
||||
font-size: 0.68rem !important;
|
||||
}
|
||||
|
||||
#anomalous-container.anomalous-docked .anomalous-assembly-snap-dock {
|
||||
min-height: 32px !important;
|
||||
padding: 4px 8px !important;
|
||||
font-size: 0.68rem !important;
|
||||
margin-top: 3px !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user