diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index 498100f..e89ed6b 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -1475,11 +1475,13 @@ function syncOneLinerRunPolling() { function openOneLinerPanel() { ensureOneLinerUi(); + document.body.classList.add("oneliner-open"); document.querySelector(".oneliner-backdrop")?.classList.remove("hidden"); syncOneLinerRunPolling(); } function closeOneLinerPanel() { + document.body.classList.remove("oneliner-open"); document.querySelector(".oneliner-backdrop")?.classList.add("hidden"); clearOneLinerRunPollTimer(); } diff --git a/web/storyforge-web-v4/assets/styles.css b/web/storyforge-web-v4/assets/styles.css index 0c8b871..87d0c2a 100644 --- a/web/storyforge-web-v4/assets/styles.css +++ b/web/storyforge-web-v4/assets/styles.css @@ -1255,6 +1255,13 @@ select { box-shadow: var(--shadow); color: var(--text); cursor: pointer; + transition: transform 160ms ease, opacity 160ms ease; +} + +.oneliner-open .oneliner-fab { + opacity: 0; + pointer-events: none; + transform: translateY(16px) scale(0.96); } .oneliner-fab-mark { diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs index b98bc26..700eeb6 100644 --- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs +++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs @@ -97,7 +97,10 @@ test("mobile shell removes duplicated desktop topbar and collapses the main agen test("mobile action sheets and oneliner runtime behave like bottom sheets", () => { assert.match(APP, /class="sheet-handle"/); + assert.match(APP, /document\.body\.classList\.add\("oneliner-open"\)/); + assert.match(APP, /document\.body\.classList\.remove\("oneliner-open"\)/); assert.match(CSS, /\.sheet-handle\s*\{/); + assert.match(CSS, /\.oneliner-open \.oneliner-fab\s*\{[\s\S]*opacity:\s*0/); assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.auth-modal,\s*[\s\S]*\.action-modal,\s*[\s\S]*\.oneliner-panel\s*\{[\s\S]*border-radius:\s*24px 24px 0 0/); assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.auth-actions\s*\{[\s\S]*position:\s*sticky/); assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.oneliner-composer\s*\{[\s\S]*position:\s*sticky/);