diff --git a/frontend/src/components/AppLayout.vue b/frontend/src/components/AppLayout.vue
index d8b0b69..a54d5e2 100644
--- a/frontend/src/components/AppLayout.vue
+++ b/frontend/src/components/AppLayout.vue
@@ -1,13 +1,26 @@
@@ -41,7 +54,10 @@ const activeTab = ref('submit')
:class="{ active: activeTab === 'queue' }"
@click="activeTab = 'queue'"
>
- ☰
+
+ ☰
+ {{ queueBadge > 9 ? '9+' : queueBadge }}
+
Queue
@@ -136,5 +152,26 @@ const activeTab = ref('submit')
text-transform: uppercase;
letter-spacing: 0.05em;
}
+
+ .nav-icon-wrap {
+ position: relative;
+ display: inline-flex;
+ }
+
+ .nav-badge {
+ position: absolute;
+ top: -6px;
+ right: -10px;
+ background: var(--color-accent);
+ color: var(--color-bg);
+ font-size: 0.6rem;
+ font-weight: 700;
+ min-width: 16px;
+ height: 16px;
+ line-height: 16px;
+ text-align: center;
+ border-radius: var(--radius-full);
+ padding: 0 3px;
+ }
}
diff --git a/frontend/src/components/UrlInput.vue b/frontend/src/components/UrlInput.vue
index 73ea1f3..643d1f4 100644
--- a/frontend/src/components/UrlInput.vue
+++ b/frontend/src/components/UrlInput.vue
@@ -184,10 +184,12 @@ function onFormatSelect(formatId: string | null): void {
}
function handlePaste(): void {
+ // Immediately signal that analysis is starting — prevents the Download
+ // button from being briefly clickable between paste and analysis.
+ isAnalyzing.value = true
// Auto-extract on paste — unified loading state
setTimeout(async () => {
if (url.value.trim()) {
- isAnalyzing.value = true
analyzeError.value = null
startAnalyzePhase()
try {
@@ -204,6 +206,9 @@ function handlePaste(): void {
isAnalyzing.value = false
stopAnalyzePhase()
}
+ } else {
+ // URL was cleared before timeout — cancel analysis state
+ isAnalyzing.value = false
}
}, 50)
}