diff --git a/.agents/skills/impeccable/scripts/live-browser.js b/.agents/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.agents/skills/impeccable/scripts/live-browser.js
+++ b/.agents/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.claude/skills/impeccable/scripts/live-browser.js b/.claude/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.claude/skills/impeccable/scripts/live-browser.js
+++ b/.claude/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.cursor/skills/impeccable/scripts/live-browser.js b/.cursor/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.cursor/skills/impeccable/scripts/live-browser.js
+++ b/.cursor/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.gemini/skills/impeccable/scripts/live-browser.js b/.gemini/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.gemini/skills/impeccable/scripts/live-browser.js
+++ b/.gemini/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.github/skills/impeccable/scripts/live-browser.js b/.github/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.github/skills/impeccable/scripts/live-browser.js
+++ b/.github/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.kiro/skills/impeccable/scripts/live-browser.js b/.kiro/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.kiro/skills/impeccable/scripts/live-browser.js
+++ b/.kiro/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.opencode/skills/impeccable/scripts/live-browser.js b/.opencode/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.opencode/skills/impeccable/scripts/live-browser.js
+++ b/.opencode/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.pi/skills/impeccable/scripts/live-browser.js b/.pi/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.pi/skills/impeccable/scripts/live-browser.js
+++ b/.pi/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.qoder/skills/impeccable/scripts/live-browser.js b/.qoder/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.qoder/skills/impeccable/scripts/live-browser.js
+++ b/.qoder/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.rovodev/skills/impeccable/scripts/live-browser.js b/.rovodev/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.rovodev/skills/impeccable/scripts/live-browser.js
+++ b/.rovodev/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.trae-cn/skills/impeccable/scripts/live-browser.js b/.trae-cn/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.trae-cn/skills/impeccable/scripts/live-browser.js
+++ b/.trae-cn/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/.trae/skills/impeccable/scripts/live-browser.js b/.trae/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/.trae/skills/impeccable/scripts/live-browser.js
+++ b/.trae/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/plugin/skills/impeccable/scripts/live-browser.js b/plugin/skills/impeccable/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/plugin/skills/impeccable/scripts/live-browser.js
+++ b/plugin/skills/impeccable/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/site/styles/kinpaku-kit.css b/site/styles/kinpaku-kit.css
index 2b2e6085f..050e6c2d9 100644
--- a/site/styles/kinpaku-kit.css
+++ b/site/styles/kinpaku-kit.css
@@ -1194,7 +1194,7 @@
display: inline-flex;
align-items: center;
height: 28px;
- width: 88px;
+ width: 104px;
margin: 0 4px 0 6px;
border-radius: 5px;
background: var(--ks-graphite);
@@ -1202,12 +1202,12 @@
overflow: hidden;
cursor: pointer;
flex-shrink: 0;
- transition: width 0.18s ease, border-color 0.15s ease;
+ transition: border-color 0.15s ease;
}
.home-kinpaku .live-demo-gbar-chat.is-expanded,
.live-mode-kinpaku .live-demo-gbar-chat.is-expanded {
- width: min(220px, 42vw);
+ width: min(220px, 34vw);
cursor: text;
}
diff --git a/site/styles/live-mode.css b/site/styles/live-mode.css
index f883ad3ad..ae942d6f7 100644
--- a/site/styles/live-mode.css
+++ b/site/styles/live-mode.css
@@ -292,7 +292,8 @@
display: flex;
align-items: center;
gap: 2px;
- flex-shrink: 0;
+ flex: 1 1 auto;
+ min-width: 0;
padding: 4px 6px 4px 2px;
}
.live-demo-gbar-btn {
@@ -358,7 +359,7 @@
align-items: center;
justify-content: center;
box-sizing: border-box;
- flex-shrink: 0;
+ flex: 0 0 24px;
align-self: center;
width: 24px;
height: 24px;
diff --git a/skill/scripts/live-browser.js b/skill/scripts/live-browser.js
index ed9606409..1b8926333 100644
--- a/skill/scripts/live-browser.js
+++ b/skill/scripts/live-browser.js
@@ -8189,7 +8189,7 @@ void main() {
let voiceInterimBase = '';
/** @type {{ mode: 'steer'|'configure', input: HTMLInputElement, submit: () => void, beforeStart?: () => void } | null} */
let voiceCtx = null;
- const PAGE_CHAT_COLLAPSED_W = '88px';
+ const PAGE_CHAT_COLLAPSED_W = '104px';
const PAGE_CHAT_PROCESSING_W = '76px';
const PAGE_CHAT_PLACEHOLDER_COLLAPSED = 'Steer…';
const PAGE_CHAT_PLACEHOLDER_EXPANDED = 'Steer the page…';
@@ -8200,7 +8200,7 @@ void main() {
const GLOBAL_BAR_SECTION_GAP = 8;
const GLOBAL_BAR_INNER_GAP = 2;
const GLOBAL_BAR_INNER_PAD_LEFT = 2;
- const PAGE_CHAT_EXPANDED_W = 'min(280px, 38vw)';
+ const PAGE_CHAT_EXPANDED_MAX_W = 280;
const ICON_PAGE_CHAT =
'';
const ICON_PAGE_VOICE =
@@ -8280,6 +8280,43 @@ void main() {
return barPaletteForTheme(globalBarEl?.dataset.theme || detectPageTheme());
}
+ function globalBarModeToggles() {
+ return [
+ uiGetById(PREFIX + '-pick-toggle'),
+ uiGetById(PREFIX + '-insert-toggle'),
+ uiGetById(PREFIX + '-detect-toggle'),
+ uiGetById(PREFIX + '-design-toggle'),
+ ].filter(Boolean);
+ }
+
+ function syncGlobalBarExpandedLabels(expanded = globalBarEl?.matches(':hover')) {
+ globalBarModeToggles().forEach((toggle) => {
+ if (expanded && !pageChatExpanded) toggle._expandLabel?.();
+ else if (toggle.dataset.active === 'true') toggle._expandLabel?.();
+ else toggle._collapseLabel?.();
+ });
+ }
+
+ function pageChatCollapsedWidthPx() {
+ const parsed = parseFloat(PAGE_CHAT_COLLAPSED_W);
+ return Number.isFinite(parsed) ? parsed : 104;
+ }
+
+ function pageChatExpandedWidth() {
+ if (!pageChatEl || !globalBarEl) return PAGE_CHAT_EXPANDED_MAX_W + 'px';
+ const currentChatWidth = pageChatEl.getBoundingClientRect().width || pageChatCollapsedWidthPx();
+ const barWidth = globalBarEl.getBoundingClientRect().width || 0;
+ const nonChatWidth = Math.max(0, barWidth - currentChatWidth);
+ const available = window.innerWidth - 16 - nonChatWidth;
+ const next = Math.max(pageChatCollapsedWidthPx(), Math.min(PAGE_CHAT_EXPANDED_MAX_W, available));
+ return Math.round(next) + 'px';
+ }
+
+ function syncPageChatExpandedWidth() {
+ if (!pageChatEl || !pageChatExpanded) return;
+ pageChatEl.style.width = pageChatExpandedWidth();
+ }
+
function syncPageChatChrome() {
if (!pageChatEl) return;
const P = pageChatPalette();
@@ -8581,7 +8618,8 @@ void main() {
if (!pageChatEl || !pageChatInput) return false;
pageChatExpanded = true;
pageChatEl.dataset.expanded = 'true';
- pageChatEl.style.width = PAGE_CHAT_EXPANDED_W;
+ syncGlobalBarExpandedLabels(false);
+ pageChatEl.style.width = pageChatExpandedWidth();
pageChatEl.style.cursor = steerLocked ? 'default' : 'text';
pageChatInput.placeholder = PAGE_CHAT_PLACEHOLDER_EXPANDED;
if (pageChatHint) {
@@ -8676,7 +8714,7 @@ void main() {
pageChatEl.setAttribute('aria-label', 'Steer the page');
pageChatExpanded = keepExpanded;
pageChatEl.dataset.expanded = keepExpanded ? 'true' : 'false';
- pageChatEl.style.width = keepExpanded ? PAGE_CHAT_EXPANDED_W : PAGE_CHAT_COLLAPSED_W;
+ pageChatEl.style.width = keepExpanded ? pageChatExpandedWidth() : PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
if (pageChatInput) {
pageChatInput.disabled = false;
@@ -8990,6 +9028,7 @@ void main() {
pageChatEl.dataset.expanded = 'false';
pageChatEl.style.width = PAGE_CHAT_COLLAPSED_W;
pageChatEl.style.cursor = 'pointer';
+ syncGlobalBarExpandedLabels(globalBarEl?.matches(':hover'));
if (blur) {
pageChatInput.blur();
pageChatInput.style.pointerEvents = 'none';
@@ -9296,6 +9335,8 @@ void main() {
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
opacity: '0',
overflow: 'hidden', // clip the full-bleed brand mark to the bar radius
+ maxWidth: 'calc(100vw - 16px)',
+ boxSizing: 'border-box',
transition: 'opacity 0.3s ' + EASE + ', transform 0.3s ' + EASE,
});
globalBarEl.id = PREFIX + '-global-bar';
@@ -9344,6 +9385,8 @@ void main() {
const inner = el('div', {
display: 'flex', alignItems: 'center',
padding: '4px 5px 4px ' + GLOBAL_BAR_INNER_PAD_LEFT + 'px', gap: GLOBAL_BAR_INNER_GAP + 'px',
+ minWidth: '0',
+ flex: '1 1 auto',
});
inner.id = PREFIX + '-global-bar-inner';
globalBarEl.appendChild(inner);
@@ -9623,6 +9666,7 @@ void main() {
width: '1px', height: '18px',
background: P.hairline,
margin: '0 4px 0 2px',
+ flexShrink: '0',
});
inner.appendChild(divider);
@@ -9639,6 +9683,7 @@ void main() {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0', boxSizing: 'border-box',
width: '24px', height: '24px', borderRadius: '6px',
+ flexShrink: '0',
border: 'none', background: 'transparent',
color: P.textDim, fontFamily: FONT, fontSize: '0', lineHeight: '0',
cursor: 'pointer', transition: 'color 0.12s ease, background 0.12s ease',
@@ -9651,16 +9696,16 @@ void main() {
exitBtn.addEventListener('click', () => { sendEvent({ type: 'exit' }); teardown(); });
inner.appendChild(exitBtn);
- // Bar-level hover: expand every toggle's label at once; collapse on leave.
+ // Bar-level hover: expand mode labels unless Steer is using the space.
// Buttons with dataset.active="true" ignore collapse (their label stays).
- const toggles = [pickBtn, insertBtn, detectBtn, designBtn];
globalBarEl.addEventListener('mouseenter', () => {
- toggles.forEach((t) => t._expandLabel && t._expandLabel());
+ syncGlobalBarExpandedLabels(true);
+ syncPageChatExpandedWidth();
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
globalBarEl.addEventListener('mouseleave', () => {
- toggles.forEach((t) => t._collapseLabel && t._collapseLabel());
+ syncGlobalBarExpandedLabels(false);
schedulePendingDockPosition();
setTimeout(schedulePendingDockPosition, 260);
});
@@ -9678,6 +9723,7 @@ void main() {
pendingDockResizeObserver.observe(globalBarEl);
}
window.addEventListener('resize', positionPendingDock);
+ window.addEventListener('resize', syncPageChatExpandedWidth);
requestAnimationFrame(() => {
globalBarEl.style.opacity = '1';
@@ -9724,9 +9770,7 @@ void main() {
// If the bar is currently under the cursor, keep all labels expanded -
// otherwise clicking a toggle that deactivates (e.g. closing DESIGN.md)
// would collapse its label while the user's mouse is still on the bar.
- if (globalBarEl && globalBarEl.matches(':hover')) {
- [pickToggle, insertToggle, detectToggle, designToggle].forEach((t) => t?._expandLabel?.());
- }
+ syncGlobalBarExpandedLabels(globalBarEl && globalBarEl.matches(':hover'));
if (detectBadge) {
detectBadge.style.display = (detectActive && detectCount > 0) ? 'inline' : 'none';
diff --git a/tests/live-browser-regression.test.mjs b/tests/live-browser-regression.test.mjs
index 5b82a0491..d4ad8eebf 100644
--- a/tests/live-browser-regression.test.mjs
+++ b/tests/live-browser-regression.test.mjs
@@ -154,6 +154,29 @@ describe('live-browser.js regression guards', () => {
);
});
+ it('keeps the Steer pill from clipping its label or the global bar exit control', () => {
+ assert.match(
+ SOURCE,
+ /const PAGE_CHAT_COLLAPSED_W = '104px';/,
+ 'collapsed Steer pill should reserve enough room for icon, "Steer", and voice button',
+ );
+ assert.match(
+ SOURCE,
+ /function pageChatExpandedWidth\(\)[\s\S]{0,520}?window\.innerWidth - 16 - nonChatWidth[\s\S]{0,220}?Math\.max\(pageChatCollapsedWidthPx\(\), Math\.min\(PAGE_CHAT_EXPANDED_MAX_W, available\)\)/,
+ 'expanded Steer width should reserve viewport room for the rest of the global bar',
+ );
+ assert.match(
+ SOURCE,
+ /syncGlobalBarExpandedLabels\(false\);[\s\S]{0,80}?pageChatEl\.style\.width = pageChatExpandedWidth\(\);/,
+ 'opening Steer should collapse inactive mode labels before measuring input width',
+ );
+ assert.match(
+ SOURCE,
+ /maxWidth: 'calc\(100vw - 16px\)'[\s\S]{0,80}?boxSizing: 'border-box'/,
+ 'global bar should be constrained to the viewport instead of clipping the exit control offscreen',
+ );
+ });
+
it('does not autofocus the steering chat while a page editable is focused', () => {
assert.match(
SOURCE,