From d733e80881185d3f9f6353f84e0d74d5a03165a7 Mon Sep 17 00:00:00 2001 From: Towsty Date: Sat, 19 Sep 2026 08:19:36 -0500 Subject: [PATCH] Add a viewer-first mobile shell that swaps in under 768px without restyling desktop Bench. Co-authored-by: Cursor --- STUDIO2-MOBILE-PROMPT.md | 97 ++++++ assets/css/display.css | 4 + components/studio2/Bench.vue | 58 +++- components/studio2/Mobile.vue | 543 ++++++++++++++++++++++++++++++++++ composables/useIsMobile.ts | 29 ++ 5 files changed, 730 insertions(+), 1 deletion(-) create mode 100644 STUDIO2-MOBILE-PROMPT.md create mode 100644 components/studio2/Mobile.vue create mode 100644 composables/useIsMobile.ts diff --git a/STUDIO2-MOBILE-PROMPT.md b/STUDIO2-MOBILE-PROMPT.md new file mode 100644 index 0000000..a70b46b --- /dev/null +++ b/STUDIO2-MOBILE-PROMPT.md @@ -0,0 +1,97 @@ +# Cursor prompt — unique mobile portrait shell (new file) + +Do not edit `STUDIO2-DISPLAY-CURSOR-PROMPT.md`, `STUDIO2-DISPLAY-LAYOUT-SPEC.md`, `STUDIO2-LORA-DIALS-PROMPT.md`, or `STUDIO2-VIEWER-FIT-PROMPT.md`. + +Branch: **`studio-2`**. Push `origin/studio-2` only. Chrome only. Same `form`, queue, generate, locks, LoRAs, library. No graph/runner/extend/YuE2 changes. + +Desktop 3-column bench is **done**. Do not restyle desktop to make mobile work. Do not stack the three columns in a tall scroll and call it mobile. + +Breakpoint: `(max-width: 767px)` **and** coarse pointer. Use a **separate mobile shell** (`Studio2Mobile.vue` or `Bench` template `v-if="isMobile"`) that binds the **same** state as desktop Bench. + +Reference mock: `studio2-display-ux/mobile-mock.html` (open on a 390×844 viewport). + +--- + +## Why unique + +Portrait cannot show 260 | stage | 280. If you shrink that grid you lose Generate, LoRAs, and the still. + +Mobile is a **viewer-first phone app** with sheets for the inspector and the queue. Every desktop control still exists. It is just not on screen at once. + +--- + +## Chrome map (portrait) + +``` +┌ status / 48px header ─────────────────────────────────────┐ +│ AIGen Inbox ▾ GPU ☰ queue(n) │ +├ task chips (scroll-x) Generate Edit … Music ─────────────┤ +├ model chips Klein | Krea or H3 | LTX ───────┤ +├───────────────────────────────────────────────────────────┤ +│ │ +│ STAGE (contain, full remaining height) │ +│ │ +├ filmstrip scroll-x, tiles 72px ───────────────────────────┤ +├ [Slots] [Prompt] [Look] [Gen] Generate (amber, 48px) ─┤ +└───────────────────────────────────────────────────────────┘ +``` + +Bottom **dock** is 4 tabs that open sheets, plus Generate always visible: + +| Tab | Sheet contents (all desktop fields) | +|---|---| +| **Slots** | Hero, Start, End, Guides, Upload, Lock face, Lock outfit + Klein caption | +| **Prompt** | Prompt textarea, negative chips, style/render/quality/lighting chips | +| **Look** | LoRA stack (filename + Model/CLIP sliders + numbers), Seed + dice, Aspect, extra generation settings (steps/CFG only if that engine uses them) | +| **Gen** | Engine-specific video/music extras: duration/target length, fps, turbo, camera beats, YuE2 hints. Not a second Generate button. | + +**Generate** is the rightmost dock control — 48×48 or a 120px amber pill. Never labeled Queue. + +Header **☰** or badge **Queue (n)** opens a **right/bottom sheet** of job cards (same cards as desktop right column). + +Library and Settings stay header links (or a `…` menu). Do not drop them. + +--- + +## Stage + +- Same contain rule as desktop: `max-width/height 100%`, `object-fit: contain`, no inner max-width cap. +- Still / video / audio switch on `selected.kind`. No waveform on a still. +- Safe area: `padding-bottom: env(safe-area-inset-bottom)` on the dock. +- Filmstrip under stage, 72×48 tiles, amber ring on selected, horizontal scroll. Trash on selected tile only. + +--- + +## Sheets + +- One sheet at a time. Height `min(85vh, content)`. Drag handle + Done. +- Fields keep desktop order and payload keys. +- LoRA card = filename + two (or one) sliders + numeric `0.00–2.00`. No hashed meters. +- Krea disabled-on-Edit with the same one-line reason. +- LTX disabled on AIGen with `xAIGen only`. +- xAIGen hide defaults: eye on stage + each tile. No global hide checkbox required on mobile. + +--- + +## What you must not do + +- No desktop 3-column at `<768`. +- No “rotate device” dead end. +- No missing task (Iterate if desktop has it — add the chip). +- No second `form` object. +- Do not change Classic/Studio desktop tokens in this pass. + +`isMobile` from `window.matchMedia('(max-width: 767px)')` + resize listener. SSR: default desktop to avoid hydration flip, then switch on mount. + +--- + +## Done when + +390×844 portrait: + +- Stage fills the phone; dock + chips visible without page-zoom. +- Slots, Prompt, Look, Gen sheets each reachable; Generate queues a job. +- Queue sheet lists jobs. +- Rotate to ≥768: desktop 3-column returns, same job state. + +One or two present-tense commits. Screenshot 390 and 1440. diff --git a/assets/css/display.css b/assets/css/display.css index 71ad9d0..d159749 100644 --- a/assets/css/display.css +++ b/assets/css/display.css @@ -62,6 +62,10 @@ color: var(--text); } +.bench-root[data-mobile="1"] { + position: relative; +} + .bench-header { display: grid; grid-template-columns: 1fr auto 1fr; diff --git a/components/studio2/Bench.vue b/components/studio2/Bench.vue index f3204f4..1051676 100644 --- a/components/studio2/Bench.vue +++ b/components/studio2/Bench.vue @@ -1,5 +1,8 @@