diff --git a/web/css/resolver-shell.css b/web/css/resolver-shell.css index 2a46bd0..98c8ae8 100644 --- a/web/css/resolver-shell.css +++ b/web/css/resolver-shell.css @@ -297,19 +297,12 @@ .mr-queue-header { display: flex; - justify-content: space-between; + justify-content: flex-end; align-items: center; - gap: var(--mr-spacing-10); - min-height: 44px; - margin-bottom: 0; - padding: 0 0 10px; -} - -.mr-queue-title { - color: var(--mr-text, #f3f3f3); - font-size: 14px; - font-weight: 700; - line-height: 1.25; + gap: var(--mr-spacing-6); + min-height: 36px; + margin: 0; + padding: 6px 0 8px; } .mr-queue-actions { @@ -317,46 +310,71 @@ gap: var(--mr-spacing-6); } -.mr-queue-tabs { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 4px; - margin-bottom: 8px; - padding: 3px; - background: rgba(255, 255, 255, 0.045); - border: 1px solid rgba(255, 255, 255, 0.075); - border-radius: 6px; +.mr-queue-tabs.mr-tabs { + align-self: stretch; + flex: 0 0 auto; + height: 34px; + margin: 0 0 -1px; + padding: 0 4px; + overflow: visible; + background: #1f1f1f; + --mr-tab-active-bg: #111; + --mr-tab-corner-size: 12px; } -.mr-queue-tab { +.mr-queue-tab.mr-tab { + flex: 1 1 0; min-width: 0; - height: 28px; - padding: 0 8px; - overflow: hidden; - color: var(--mr-text-muted, #b1b1b1); - font-size: 12px; + height: 32px; + min-height: 32px; + padding: 0 12px 5px; font-weight: 700; - line-height: 28px; - text-align: center; +} + +.mr-queue-tab.mr-tab .mr-tab-label { + min-width: 0; + overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - background: transparent; - border: 0; - border-radius: 4px; - cursor: pointer; } -.mr-queue-tab:hover, -.mr-queue-tab:focus-visible { - color: var(--mr-text, #f3f3f3); - background: rgba(255, 255, 255, 0.06); - outline: none; +.mr-queue-tab.mr-tab:not(.mr-tab-active):hover, +.mr-queue-tab.mr-tab:not(.mr-tab-active):focus, +.mr-queue-tab.mr-tab:not(.mr-tab-active):active { + padding: 0 12px 5px !important; } -.mr-queue-tab.is-active { - color: #f5fff6; - background: rgba(114, 211, 138, 0.18); - box-shadow: inset 0 0 0 1px rgba(114, 211, 138, 0.24); +.mr-queue-tab.mr-tab:not(.mr-tab-active)::after { + inset: 2px 5px 6px; +} + +.mr-queue-tab.mr-tab:not(.mr-tab-active) + .mr-queue-tab.mr-tab:not(.mr-tab-active)::before { + top: 8px; + bottom: 13px; +} + +.mr-queue-tab.mr-tab.mr-tab-active { + height: 32px; + min-height: 32px; + padding: 0 12px 5px; +} + +.mr-queue-tab.mr-tab.mr-tab-active::before, +.mr-queue-tab.mr-tab.mr-tab-active::after { + width: 12px; + height: 12px; +} + +.mr-queue-tab.mr-tab.mr-tab-active::before { + left: -10px; + -webkit-mask: radial-gradient(circle at 0 0, transparent 10px, #000 10px); + mask: radial-gradient(circle at 0 0, transparent 10px, #000 10px); +} + +.mr-queue-tab.mr-tab.mr-tab-active::after { + right: -10px; + -webkit-mask: radial-gradient(circle at 100% 0, transparent 10px, #000 10px); + mask: radial-gradient(circle at 100% 0, transparent 10px, #000 10px); } .mr-queue-list { diff --git a/web/resolver/actions/queue_methods.js b/web/resolver/actions/queue_methods.js index 45a83d0..7367265 100644 --- a/web/resolver/actions/queue_methods.js +++ b/web/resolver/actions/queue_methods.js @@ -70,13 +70,6 @@ export const queueMethods = { createQueuePanel() { this.queuePanelActiveTab = this.queuePanelActiveTab || 'queued'; - this.queueTitle = $el("div#queue-title.mr-queue-title", { textContent: "Queued Selections (0)" }); - this.queueToggleButton = $el("button", { - id: "queue-toggle", - className: "mr-btn mr-btn-secondary mr-btn-sm", - textContent: "Collapse", - onclick: () => this.toggleQueueCollapsed() - }); this.queueClearButton = $el("button", { id: "queue-clear", className: "mr-btn mr-btn-secondary mr-btn-sm", @@ -84,21 +77,19 @@ export const queueMethods = { onclick: () => this.clearAllQueued() }); - this.queueQueuedTabButton = $el("button.mr-queue-tab.is-active", { + this.queueQueuedTabButton = $el("button.mr-tab.mr-queue-tab.mr-tab-active", { type: "button", "data-tab": "queued", role: "tab", - textContent: "Queued (0)", onclick: () => this.setQueuePanelTab('queued') - }); - this.queueDownloadsTabButton = $el("button.mr-queue-tab", { + }, [$el("span.mr-tab-label", { textContent: "Queued (0)" })]); + this.queueDownloadsTabButton = $el("button.mr-tab.mr-queue-tab", { type: "button", "data-tab": "downloads", role: "tab", - textContent: "Downloads (0)", onclick: () => this.setQueuePanelTab('downloads') - }); - this.queueTabs = $el("div.mr-queue-tabs", { + }, [$el("span.mr-tab-label", { textContent: "Downloads (0)" })]); + this.queueTabs = $el("div.mr-tabs.mr-queue-tabs", { role: "tablist", "aria-label": "Queue panel views" }, [ @@ -106,20 +97,15 @@ export const queueMethods = { this.queueDownloadsTabButton ]); - // Header row with title and clear button this.queueHeader = $el("div.mr-queue-header", {}, [ - this.queueTitle, - $el("div.mr-queue-actions", {}, [ - this.queueToggleButton, - this.queueClearButton - ]) + this.queueClearButton ]); // Scrollable list this.queueList = $el("div#queue-list.mr-queue-list"); const panel = $el("div.mr-queue-panel", {}, [ - $el("div.mr-queue-stack", {}, [this.queueHeader, this.queueTabs, this.queueList]) + $el("div.mr-queue-stack", {}, [this.queueTabs, this.queueHeader, this.queueList]) ]); return panel; }, @@ -136,17 +122,10 @@ export const queueMethods = { const list = Array.isArray(this.pendingResolutions) ? this.pendingResolutions : []; const downloads = this.getActiveQueuePanelDownloads(); const activeTab = this.queuePanelActiveTab === 'downloads' ? 'downloads' : 'queued'; - // Update title count - const title = this.queueTitle || this.queueHeader.querySelector('#queue-title'); - if (title) { - title.textContent = activeTab === 'downloads' - ? `Downloads (${downloads.length})` - : `Queued Selections (${list.length})`; - } - const toggleBtn = this.queueToggleButton || this.queueHeader.querySelector('#queue-toggle'); - if (toggleBtn) toggleBtn.textContent = this.queueCollapsed ? 'Expand' : 'Collapse'; const clearBtn = this.queueClearButton || this.queueHeader.querySelector('#queue-clear'); - if (clearBtn) clearBtn.style.display = activeTab === 'queued' ? '' : 'none'; + const showActions = activeTab === 'queued'; + this.queueHeader.style.display = showActions ? '' : 'none'; + if (clearBtn) clearBtn.style.display = showActions ? '' : 'none'; this.updateQueuePanelTabs(list.length, downloads.length, activeTab); if (activeTab === 'downloads') { @@ -160,14 +139,22 @@ export const queueMethods = { updateQueuePanelTabs(queueCount, downloadCount, activeTab) { const queuedTab = this.queueQueuedTabButton || this.queueTabs?.querySelector?.('.mr-queue-tab[data-tab="queued"]'); const downloadsTab = this.queueDownloadsTabButton || this.queueTabs?.querySelector?.('.mr-queue-tab[data-tab="downloads"]'); + const setTabLabel = (tab, label) => { + const labelEl = tab?.querySelector?.('.mr-tab-label'); + if (labelEl) { + labelEl.textContent = label; + } else if (tab) { + tab.textContent = label; + } + }; if (queuedTab) { - queuedTab.textContent = `Queued (${queueCount})`; - queuedTab.classList.toggle('is-active', activeTab === 'queued'); + setTabLabel(queuedTab, `Queued (${queueCount})`); + queuedTab.classList.toggle('mr-tab-active', activeTab === 'queued'); queuedTab.setAttribute('aria-selected', activeTab === 'queued' ? 'true' : 'false'); } if (downloadsTab) { - downloadsTab.textContent = `Downloads (${downloadCount})`; - downloadsTab.classList.toggle('is-active', activeTab === 'downloads'); + setTabLabel(downloadsTab, `Downloads (${downloadCount})`); + downloadsTab.classList.toggle('mr-tab-active', activeTab === 'downloads'); downloadsTab.setAttribute('aria-selected', activeTab === 'downloads' ? 'true' : 'false'); } },