diff --git a/web/linker.js b/web/linker.js index 9b2692b..851e808 100644 --- a/web/linker.js +++ b/web/linker.js @@ -305,7 +305,7 @@ class LinkerManagerDialog extends ComfyDialog { html += `
`; html += this.getConfidenceBadge(match.confidence); html += `${formattedPath.display}`; - html += ``; html += `
`; @@ -313,18 +313,17 @@ class LinkerManagerDialog extends ComfyDialog { if (perfectMatches.length > 0 && otherMatches.length > 0) { const matchId = `more-matches-${missing.node_id}-${missing.widget_index}`; - html += `
${otherMatches.length} other match${otherMatches.length > 1 ? 'es' : ''} below 100%
`; + html += `
${otherMatches.length} other match${otherMatches.length > 1 ? 'es' : ''} below 100%
`; html += ``; @@ -1249,12 +1248,13 @@ class LinkerManagerDialog extends ComfyDialog { :root { --ml-bg: #1b1d20; --ml-bg-soft: #20242a; - --ml-card-bg: linear-gradient(180deg, #242930 0%, #1f2329 100%); - --ml-card-bg-alt: linear-gradient(180deg, #22272e 0%, #1d2127 100%); + --ml-card-bg: rgba(255, 255, 255, 0.028); + --ml-card-bg-alt: rgba(255, 255, 255, 0.04); --ml-panel-bg: rgba(255, 255, 255, 0.03); --ml-panel-bg-strong: rgba(255, 255, 255, 0.05); --ml-border: rgba(255, 255, 255, 0.09); --ml-border-strong: rgba(255, 255, 255, 0.14); + --ml-divider: rgba(255, 255, 255, 0.07); --ml-text: #eef2f7; --ml-text-muted: #a5afbd; --ml-text-dim: #748091; @@ -1304,20 +1304,22 @@ class LinkerManagerDialog extends ComfyDialog { /* Card Styles */ .ml-card { background: var(--ml-card-bg); - border: 1px solid var(--ml-border); + border: 1px solid transparent; border-radius: var(--ml-radius-lg); padding: 10px; margin-bottom: 8px; - transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease; - box-shadow: 0 4px 16px rgba(0,0,0,0.14); + transition: transform 0.18s ease, background 0.18s ease, box-shadow 0.18s ease; + box-shadow: inset 0 0 0 1px rgba(255,255,255,0.025); } .ml-card:nth-child(even) { background: var(--ml-card-bg-alt); } .ml-card:hover { transform: translateY(-1px); - border-color: var(--ml-border-strong); - box-shadow: 0 10px 28px rgba(0,0,0,0.2); + background: rgba(255,255,255,0.045); + box-shadow: + inset 0 0 0 1px rgba(255,255,255,0.04), + 0 10px 24px rgba(0,0,0,0.12); } /* Card Header */ @@ -1361,6 +1363,25 @@ class LinkerManagerDialog extends ComfyDialog { white-space: nowrap; flex-shrink: 0; } + .ml-node-chip.is-locatable { + cursor: pointer; + padding-right: 9px; + color: #b6c4d6; + background: rgba(78,161,255,0.08); + border-color: rgba(78,161,255,0.14); + transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease; + } + .ml-node-chip.is-locatable:hover { + background: rgba(78,161,255,0.14); + border-color: rgba(78,161,255,0.24); + color: #d7e7fb; + transform: translateY(-1px); + } + .ml-node-chip-icon { + font-size: 11px; + line-height: 1; + opacity: 0.95; + } .ml-category-chip { display: inline-flex; padding: 2px 7px; @@ -1415,9 +1436,10 @@ class LinkerManagerDialog extends ComfyDialog { .ml-column { min-width: 0; background: var(--ml-panel-bg); - border: 1px solid var(--ml-border); + border: 1px solid transparent; border-radius: var(--ml-radius-md); padding: 10px; + box-shadow: inset 0 0 0 1px rgba(255,255,255,0.03); } .ml-column-header { font-size: 10px; @@ -1427,17 +1449,24 @@ class LinkerManagerDialog extends ComfyDialog { letter-spacing: 0.08em; margin-bottom: 8px; padding-bottom: 6px; - border-bottom: 1px solid var(--ml-border); + border-bottom: 1px solid var(--ml-divider); } .ml-muted-note, .ml-no-matches { padding: 8px 10px; border-radius: var(--ml-radius-sm); - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.06); + background: rgba(255,255,255,0.02); + border: 1px solid transparent; color: var(--ml-text-muted); font-size: 11px; } + .ml-inline-note-action { + transition: color 0.15s ease, background 0.15s ease; + } + .ml-inline-note-action:hover { + color: var(--ml-text); + background: rgba(78,161,255,0.08); + } /* Filename Chips */ .ml-chip { @@ -1487,6 +1516,11 @@ class LinkerManagerDialog extends ComfyDialog { color: #f2a29d; border-color: rgba(244,67,54,0.22); } + .ml-badge-neutral { + background: rgba(165,175,189,0.1); + color: #c5ccd7; + border-color: rgba(165,175,189,0.16); + } /* Match Row */ .ml-match-row { @@ -1496,17 +1530,17 @@ class LinkerManagerDialog extends ComfyDialog { padding: 6px 8px; border-radius: var(--ml-radius-sm); margin-bottom: 4px; - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.05); - transition: background 0.15s ease, border-color 0.15s ease; + background: rgba(255,255,255,0.02); + border: 1px solid transparent; + transition: background 0.15s ease, box-shadow 0.15s ease; } .ml-match-row:hover { - background: rgba(255,255,255,0.05); - border-color: rgba(255,255,255,0.09); + background: rgba(255,255,255,0.045); + box-shadow: inset 0 0 0 1px rgba(255,255,255,0.035); } .ml-match-row.ml-best-match { - background: rgba(63,185,80,0.1); - border-color: rgba(63,185,80,0.26); + background: rgba(63,185,80,0.09); + box-shadow: inset 0 0 0 1px rgba(63,185,80,0.16); } .ml-match-filename { flex: 1; @@ -1525,14 +1559,17 @@ class LinkerManagerDialog extends ComfyDialog { align-items: center; justify-content: center; gap: 5px; - padding: 6px 10px; - border: none; - border-radius: 8px; + min-height: 30px; + padding: 6px 11px; + border: 1px solid transparent; + border-radius: 10px; font-size: 11px; font-weight: 600; cursor: pointer; - transition: all 0.15s ease; + transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease; white-space: nowrap; + text-decoration: none; + box-sizing: border-box; } .ml-btn:disabled { opacity: 0.5; @@ -1546,27 +1583,33 @@ class LinkerManagerDialog extends ComfyDialog { background: var(--ml-accent-hover); } .ml-btn-secondary { - background: rgba(255,255,255,0.03); + background: rgba(255,255,255,0.045); color: var(--ml-text); - border: 1px solid var(--ml-border); + border-color: rgba(255,255,255,0.08); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.025); } .ml-btn-secondary:hover:not(:disabled) { - background: rgba(255,255,255,0.05); - border-color: var(--ml-border-strong); + background: rgba(255,255,255,0.07); + border-color: rgba(255,255,255,0.13); + transform: translateY(-1px); } .ml-btn-link { background: var(--ml-accent-blue); color: white; + box-shadow: 0 8px 18px rgba(78,161,255,0.22); } .ml-btn-link:hover:not(:disabled) { background: #1976D2; + transform: translateY(-1px); } .ml-btn-download { background: var(--ml-accent); color: white; + box-shadow: 0 8px 18px rgba(63,185,80,0.2); } .ml-btn-download:hover:not(:disabled) { background: var(--ml-accent-hover); + transform: translateY(-1px); } .ml-btn-danger { background: #f44336; @@ -1576,19 +1619,32 @@ class LinkerManagerDialog extends ComfyDialog { background: #d32f2f; } .ml-btn-sm { - padding: 3px 7px; + min-height: 28px; + padding: 3px 8px; font-size: 10px; + border-radius: 9px; } .ml-btn-ghost { - background: transparent; + background: rgba(255,255,255,0.022); color: var(--ml-text-muted); - border: 1px solid rgba(255,255,255,0.08); + border-color: rgba(255,255,255,0.065); box-shadow: none; } .ml-btn-ghost:hover:not(:disabled) { - background: rgba(255,255,255,0.04); + background: rgba(255,255,255,0.055); color: var(--ml-text); - border-color: rgba(255,255,255,0.14); + border-color: rgba(255,255,255,0.12); + } + .ml-btn-utility { + padding-inline: 8px; + font-weight: 600; + letter-spacing: 0.01em; + } + .ml-btn-icon-only { + width: 28px; + min-width: 28px; + padding: 0; + aspect-ratio: 1; } .ml-btn-icon { font-size: 12px; @@ -1596,7 +1652,15 @@ class LinkerManagerDialog extends ComfyDialog { .ml-card-actions .ml-btn, .ml-match-row .ml-btn, .ml-combo-row .ml-btn { - min-height: 26px; + min-height: 28px; + } + .ml-search-source-btn { + border-radius: 999px; + padding-inline: 11px; + color: var(--ml-text-muted); + } + .ml-search-source-btn.ml-btn-primary { + box-shadow: 0 8px 18px rgba(63,185,80,0.18); } /* Download Section */ @@ -1606,7 +1670,14 @@ class LinkerManagerDialog extends ComfyDialog { padding: 9px; background: var(--ml-panel-bg-strong); border-radius: var(--ml-radius-md); - border: 1px solid var(--ml-border); + border: 1px solid transparent; + box-shadow: inset 0 0 0 1px rgba(255,255,255,0.03); + } + .ml-status-inline { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; } .ml-download-info { font-size: 11px; @@ -1636,7 +1707,7 @@ class LinkerManagerDialog extends ComfyDialog { position: relative; margin-top: 9px; padding-top: 9px; - border-top: 1px solid var(--ml-border); + border-top: 1px solid var(--ml-divider); } .ml-combo-row { display: flex; @@ -2616,6 +2687,10 @@ class LinkerManagerDialog extends ComfyDialog { } return `${confidence}%`; } + + getStatusBadge(label, variant = 'neutral') { + return `${label}`; + } /** * Format a filename with smart truncation @@ -4504,7 +4579,7 @@ class LinkerManagerDialog extends ComfyDialog { this.wireDownloadTargetAutocomplete(container, missing); - // Wire Locate button (only for top-level nodes) + // Wire locate chip (only for top-level nodes) const locateId = `locate-${missing.node_id}-${missing.widget_index}`; const locateBtn = container.querySelector(`#${locateId}`); if (locateBtn && missing.is_top_level !== false) { @@ -4667,19 +4742,20 @@ class LinkerManagerDialog extends ComfyDialog { } html += `

${titleHtml}

`; + const locateId = `locate-${missing.node_id}-${missing.widget_index}`; + const nodeChipClasses = missing.is_top_level !== false ? 'ml-node-chip is-locatable' : 'ml-node-chip'; + const nodeChipTitle = missing.is_top_level !== false ? 'Click to locate this node in the graph' : ''; + html += `
`; if (missing.category) { html += `${missing.category}`; } - html += `${nodeLabel} #${missing.node_id}`; - html += `
`; - html += ``; - html += `
`; - // Add Locate button for top-level nodes only + html += ``; if (missing.is_top_level !== false) { - const locateId = `locate-${missing.node_id}-${missing.widget_index}`; - html += ``; + html += `⌖`; } + html += `${nodeLabel} #${missing.node_id}`; + html += `
`; html += ``; html += ``; @@ -4703,7 +4779,7 @@ class LinkerManagerDialog extends ComfyDialog { html += `
`; html += ``; html += ``; - html += ``; + html += ``; html += `
`; html += `
`; html += ``; @@ -4720,7 +4796,12 @@ class LinkerManagerDialog extends ComfyDialog { if (perfectMatches.length > 0) { // Has perfect local match - download not needed - html += `
Not needed - exact local match available
`; + html += `
`; + html += `
`; + html += this.getStatusBadge('Not needed', 'neutral'); + html += `Exact local match available`; + html += `
`; + html += `
`; } else if (downloadSource && downloadSource.url) { html += this.renderDownloadSourceSection(missing, downloadSource); } else if (missing.is_urn) {