diff --git a/frontend/src/App.css b/frontend/src/App.css index 16b1f25f..47df9d9c 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -169,6 +169,23 @@ body { background: #252526; border-bottom: 1px solid #333; min-height: 38px; + /* Query container so every zone (view-mode toggle, editor toolbar, canvas + controls) can collapse based on the *shared bar's own width* — which is + what shrinks when the right-docked AI chat opens — instead of the viewport + width. Prevents the canvas controls (board selector, Serial, Scope) from + overlapping the editor Run/Compile buttons on a narrow bar. `layout` + containment (implied) does not clip: the overflow/run dropdowns still + render below the bar. */ + container-type: inline-size; + container-name: unified-toolbar; +} + +/* Collapse the Code/Both/Circuit labels to icon-only first (biggest fixed + block in the bar) as the shared bar narrows. */ +@container unified-toolbar (max-width: 1140px) { + .view-mode-toggle .vm-label { + display: none; + } } .unified-toolbar-explorer-toggle { @@ -177,7 +194,11 @@ body { .unified-toolbar-editor { flex: 1 1 auto; - min-width: 0; + /* Floor the editor zone at its fully-collapsed content width so it can never + shrink *under* its own buttons and paint them over the adjacent canvas + controls. Below this floor the (lower-priority) canvas controls get pushed + toward the right edge instead of overlapping — never the other way. */ + min-width: 280px; display: flex; } diff --git a/frontend/src/components/simulator/SimulatorCanvas.css b/frontend/src/components/simulator/SimulatorCanvas.css index e8ffdef8..53c52e67 100644 --- a/frontend/src/components/simulator/SimulatorCanvas.css +++ b/frontend/src/components/simulator/SimulatorCanvas.css @@ -398,6 +398,53 @@ } } +/* ── Narrow shared toolbar (desktop, AI chat open) ──────────────────────── + When the canvas header is portaled into the unified top toolbar, it shares + one row with the editor actions. As that *bar* narrows (mainly when the + right-docked AI chat opens), collapse the canvas controls the same way the + mobile block does — but keyed to the bar's own width via a container query, + not the viewport, so it triggers on a wide screen with the chat open too. + Priority: labels -> icons, then drop the non-interactive count, then the + zoom buttons (mouse-wheel zoom still works). Mirrors the thresholds the + editor toolbar and view-mode toggle collapse at, so the whole bar degrades + together and nothing overlaps. */ +@container unified-toolbar (max-width: 1010px) { + .canvas-serial-btn { + padding: 0 8px; + font-size: 0; /* hide "Serial" / "Scope" text, keep the icon */ + } + .canvas-serial-btn svg { + width: 18px; + height: 18px; + } + .add-component-btn { + padding: 0 9px; + font-size: 0; /* hide "Add" text, keep the icon */ + } + .add-component-btn svg { + width: 18px; + height: 18px; + } + .board-selector { + max-width: 120px; + text-overflow: ellipsis; + overflow: hidden; + } +} +@container unified-toolbar (max-width: 905px) { + .component-count { + display: none; + } + .board-selector { + max-width: 96px; + } +} +@container unified-toolbar (max-width: 835px) { + .zoom-controls { + display: none; /* mouse-wheel / trackpad zoom still available */ + } +} + /* ── WiFi / BLE status badges ─────────────────────────────────────────── */ .canvas-wifi-badge, .canvas-ble-badge { diff --git a/frontend/src/pages/EditorPage.tsx b/frontend/src/pages/EditorPage.tsx index 13b3bffe..106f03c9 100644 --- a/frontend/src/pages/EditorPage.tsx +++ b/frontend/src/pages/EditorPage.tsx @@ -480,7 +480,7 @@ export const EditorPage: React.FC = () => { > - {m.label} + {m.label} ))}