diff --git a/index.html b/index.html
index 7d0fe59..9c26a91 100644
--- a/index.html
+++ b/index.html
@@ -77,6 +77,7 @@
+
diff --git a/style.css b/style.css
index 52ae5a5..fbe7ac1 100644
--- a/style.css
+++ b/style.css
@@ -165,6 +165,7 @@ button.active { color: var(--accent-strong); background: var(--accent-soft); bor
.document-title:hover, .document-title:focus { border-color: var(--border); }
.toolbar-separator { width: 1px; height: 24px; margin: 0 2px; background: var(--border); }
.toolbar-spacer { flex: 1; min-width: 4px; }
+.toolbar-actions { display: flex; align-items: center; gap: 4px; min-width: 0; }
.tool-group { display: flex; align-items: center; gap: 1px; }
.toolbar button { font-size: 12px; }
.toolbar .dropdown { position: relative; }
@@ -588,7 +589,7 @@ kbd { padding: 3px 7px; color: var(--text); background: var(--panel-active); bor
@media (max-width: 840px) {
:root { --toolbar-height: 84px; }
#app { grid-template-columns: 1fr; grid-template-rows: var(--toolbar-height) 82px minmax(0, 1fr) 25px; }
- .toolbar { align-content: center; flex-wrap: wrap; overflow: hidden; }
+ .toolbar { align-content: center; flex-wrap: wrap; overflow: visible; }
.document-title { width: 155px; }
.toolbar-spacer { display: none; }
.shape-panel { grid-column: 1; grid-row: 2; border-right: 0; border-bottom: 1px solid var(--border); overflow-x: auto; overflow-y: hidden; }
@@ -603,13 +604,35 @@ kbd { padding: 3px 7px; color: var(--text); background: var(--panel-active); bor
}
@media (max-width: 540px) {
- :root { --toolbar-height: 116px; }
- .toolbar { align-items: flex-start; padding: 5px; }
+ :root { --toolbar-height: 118px; }
+ .toolbar {
+ display: grid;
+ grid-template-columns: auto minmax(0, 1fr) auto;
+ grid-template-rows: 32px 36px 32px;
+ align-items: center;
+ gap: 3px 5px;
+ padding: 5px;
+ }
.toolbar button { font-size: 11px; }
- .document-title { flex: 1; min-width: 140px; }
- .brand-mark span:last-child, .theme-toggle span { display: none; }
+ .brand-mark { grid-column: 1; grid-row: 1; }
+ .document-title { grid-column: 2; grid-row: 1; width: 100%; min-width: 0; }
+ .toolbar > .tool-group:not(.tool-pills) { grid-column: 3; grid-row: 1; }
+ .tool-pills { grid-column: 1 / -1; grid-row: 2; width: 100%; }
+ .tool-pills button { flex: 1 1 0; min-width: 0; min-height: 32px; padding-inline: 4px; }
+ .toolbar-actions {
+ display: grid;
+ grid-column: 1 / -1;
+ grid-row: 3;
+ grid-template-columns: 1fr 1fr .72fr 32px 32px 32px;
+ gap: 2px;
+ width: 100%;
+ }
+ .toolbar-actions > * { min-width: 0; }
+ .toolbar-actions .dropdown-toggle { width: 100%; min-height: 30px; padding-inline: 3px; white-space: nowrap; }
+ .toolbar-actions > .dropdown:nth-child(-n + 2) .dropdown-menu { right: auto; left: 0; }
+ .brand-mark span:last-child, #theme-label, .toolbar-actions .menu-caret { display: none; }
.dropdown-menu { max-width: calc(100vw - 12px); }
- .properties-panel { top: 123px; }
+ .properties-panel { top: 125px; }
#canvas-size-status { display: none; }
.settings-layout { grid-template-columns: 1fr; min-height: 0; }
.settings-tabs { flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--border-soft); }
diff --git a/tests/browser-smoke.mjs b/tests/browser-smoke.mjs
index f52d1c4..595bd36 100644
--- a/tests/browser-smoke.mjs
+++ b/tests/browser-smoke.mjs
@@ -359,6 +359,16 @@ try {
check();
}))()`);
assert(xmlImport.status.includes("Imported XML") && xmlImport.nodes === 10 && xmlImport.edges === 7, `XML round-trip failed: ${JSON.stringify(xmlImport)}`);
+
+ await client.send("Emulation.setDeviceMetricsOverride", { width: 390, height: 844, deviceScaleFactor: 1, mobile: true });
+ const mobileToolbar = await client.evaluate(`new Promise((resolve) => requestAnimationFrame(() => {
+ const controls = [...document.querySelectorAll('.toolbar [data-mode], #arrange-menu, #view-menu, #project-menu, #theme-toggle, .toolbar button[title="Settings"], .toolbar button[title="Keyboard shortcuts"]')];
+ resolve(controls.map((control) => {
+ const rect = control.getBoundingClientRect();
+ return { label: control.getAttribute('aria-label') || control.textContent.trim(), left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom, visible: getComputedStyle(control).display !== 'none' };
+ }));
+ }))`);
+ assert(mobileToolbar.every((control) => control.visible && control.left >= 0 && control.right <= 390 && control.top >= 0 && control.bottom <= 118), `Mobile toolbar controls are clipped: ${JSON.stringify(mobileToolbar)}`);
assert(client.errors.length === 0, `Browser errors: ${client.errors.join("; ")}`);
console.log("Browser smoke test passed: FlyonUI settings, commands, themes, locking, menus, modals, rendering, connectors, persistence, XML/JSON projects, and SVG/PNG export.");