Umbrella issue for Phase 1 of the v2 UI overhaul: a coherent mobile-first pass — preview stays visible while editing, settings/batch become sheets on mobile, the batch table becomes touch-friendly, and we add the first new widget (Spacer) to validate the widget-add pipeline before Phase 2 leans on it.
Builds on Phase 0 (#27).
Slices
1.1 — Sticky preview + sticky print bar (M)
- Restructure
App.tsx so the preview stays visible while editing on mobile.
PrintButton becomes a sticky bottom action bar on mobile.
- Desktop two-column layout preserved via
lg: ordering.
- Done when: on 390×844 the live preview is visible while typing in any widget editor.
1.2 — Settings + Batch as bottom sheets (M)
- Replace inline
<details> with a bottom-sheet/drawer pattern below md:.
- Above
md: keep current inline behavior.
- Build one reusable
<Sheet> primitive (native <dialog> + ~50 LOC; no library).
- Settings sheet groups: Tape & layout / Colors / Printer (clearer than the 7-wide flex-wrap row).
- Done when: on mobile both Settings and Batch open as full-width sheets with a clear close affordance; desktop unchanged.
1.3 — Mobile-friendly Batch table (M)
- Below
md:, render each batch row as a stacked card (one input per variable per row) instead of a horizontal-scrolling table.
- Promote per-row delete + preview-eye to tappable icons.
- Above
md: keep the table.
- Done when: 390 px viewport with 3 variables × 4 rows has no horizontal scroll and no input overlap.
1.4 — New widget: Spacer / divider (M)
- New
SpacerWidget type with widthPx and style (blank / vertical-line / dotted).
- Tiny editor (slider + style toggle).
- Backend: render with a small new render engine — start with a 30-min spike to confirm labelle accepts a raw bitmap engine or we drop in a thin one.
- Validates the widget-add pipeline end-to-end as a stepping stone for Phase 2 widgets.
- Done when:
[Text][Spacer 20px][QR] shows a clear gap and round-trips through save/load.
1.5 — PWA polish (S)
- Maskable icon variants, mobile chrome theme match, dismissible "add to home screen" hint on first mobile visit.
- Honest offline state in
LabelPreview when the server is unreachable (NetworkFirst SW falls back gracefully).
- Done when: app installs to iOS/Android home screen, opens standalone, shows a recognisable offline state if the Pi is down.
Phase exit criteria
All slices merged, mobile smoke at 390×844 / 768×1024 / 1280×800 clean, hardware print test for the Spacer widget on hector passes.
Umbrella issue for Phase 1 of the v2 UI overhaul: a coherent mobile-first pass — preview stays visible while editing, settings/batch become sheets on mobile, the batch table becomes touch-friendly, and we add the first new widget (Spacer) to validate the widget-add pipeline before Phase 2 leans on it.
Builds on Phase 0 (#27).
Slices
1.1 — Sticky preview + sticky print bar (M)
App.tsxso the preview stays visible while editing on mobile.PrintButtonbecomes a sticky bottom action bar on mobile.lg:ordering.1.2 — Settings + Batch as bottom sheets (M)
<details>with a bottom-sheet/drawer pattern belowmd:.md:keep current inline behavior.<Sheet>primitive (native<dialog>+ ~50 LOC; no library).1.3 — Mobile-friendly Batch table (M)
md:, render each batch row as a stacked card (one input per variable per row) instead of a horizontal-scrolling table.md:keep the table.1.4 — New widget: Spacer / divider (M)
SpacerWidgettype withwidthPxandstyle(blank / vertical-line / dotted).[Text][Spacer 20px][QR]shows a clear gap and round-trips through save/load.1.5 — PWA polish (S)
LabelPreviewwhen the server is unreachable (NetworkFirst SW falls back gracefully).Phase exit criteria
All slices merged, mobile smoke at 390×844 / 768×1024 / 1280×800 clean, hardware print test for the Spacer widget on hector passes.