Fixes from a review of the mobile-UI branch.
- Guard the inspector size clamps so min<=max (f32::clamp panics otherwise) and set a
window min_inner_size; prevents a crash / degenerate layout at small sizes. Same
small-size guards for the piano-roll landscape toggle bar and the intent grid.
- Landscape 2->1 edge reveal: snap to fullscreen at frac>=0.5 (the preview's phase
boundary) instead of COLLAPSE_HI, so releasing mid-drag no longer jumps backward.
Both edges.
- Gate the double-tap-drag marquee to mobile so it can't hijack a desktop Brush/Draw
drag.
- Timeline mobile long-press: request a repaint while counting down so it fires even
when the finger is held perfectly still.
- Landscape folded top bar: lay the filename+search+overflow cluster out within a
reserved center span (gutters for the pane's own label/buttons) and elide the
filename, so it can't overlap or overflow the header.
- Node editor connect/disconnect: assert + document the top-level-graph assumption.
- Palette search field focuses only when unfocused (no per-frame focus stomp); reset
the inspector tap-anchor on orientation change; remove stale main.rs.backup.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the phone shell orientation-aware (portrait vs landscape). Orientation is
aspect-based (rotation = a resize the shell re-lays-out each frame); LB_MOBILE_UI=2
opens a landscape dev window. `SharedPaneState.is_portrait` is published to panes.
- Stack caps at 2 panes in landscape (max_panes through the R1–R6 drag ops), with a
per-frame clamp so rotating while 3 are open drops to 2.
- Edge drags are a continuous full-height reveal instead of stalling at the capped
trigger: 1-pane → split → next-pane-fullscreen, and (landscape 2-pane) a two-phase
slide-then-collapse to 1 pane. Both top and bottom edges, mirrored. Release snaps to
stay / split / fullscreen. Dividers resize and collapse-to-1 at the extremes.
- Inspector becomes a right-side vertical column in landscape (inspector_width_frac,
left-edge horizontal resize); portrait keeps the bottom sheet.
- Piano roll: vertical "Synthesia" view in portrait; landscape shows a Keys/Notes
segmented toggle over the conventional horizontal roll / full keyboard.
- Start screen reflows to 2 rows × 3 with the recent list beside it in landscape.
- Landscape headers are shorter (52→34px) and the top bar folds into the middle of the
top pane header (no separate band), reclaiming vertical space.
All gated to mobile; desktop unchanged (is_portrait defaults true).
The mobile Piano Roll becomes a unified, keyboard-primary instrument surface
(wireframe Plate 04/08): a playable keyboard as the base, revealing a
Synthesia-style falling-notes roll above it when the pane is tall enough.
- Shared keyboard geometry (panes/keyboard_layout.rs): width-driven, pan-aware
pitch->x, so the roll's note columns stay aligned with the Virtual Piano keys.
Shared keyboard_octave + keyboard_pan_x in SharedPaneState.
- Piano Roll vertical mode (is_mobile): notes as columns falling toward an amber
now-line by the keys, tempo-map converted (beats->seconds) so onsets cross the
line exactly when they sound. Vertical drag scrubs the timeline; horizontal
drag smoothly scrolls the keys (snaps to nearest key on release). Long-press
creates a note (drag to size) or resizes an existing one; pan suppresses it.
The keyboard is embedded (reuses Virtual Piano render + MIDI); the standalone
VirtualPiano stack slot is removed. show_roll is driven by the snapped pane
size-class so the keyboard<->roll reveal lands on a stack snap point.
- Virtual Piano: renders via the shared layout on mobile, colors playback_notes
like pressed keys, gates note-on/glissando to presses that start on the keys
(never gating release), and hides QWERTY hints on mobile.
- Transport formats by document.timeline_mode (Measures->bar.beat.tick,
Frames->MM:SS:FF, Seconds->MM:SS.mmm) — per project type, like desktop.
- In-pane instrument header (name + Presets + REC). Recording is driven from the
app each frame (not the Timeline pane's render) so REC works regardless of
visible panes, and stopping playback stops recording.
- Compose/Record intent opens Timeline + instrument pane; mobile central panel is
full-bleed (no inner margin) so panes sit flush.
- phone-ui-sketches.html: inst-bar moved to the top of the music surface.
Resolve all compiler warnings across daw-backend, lightningbeam-core, and
lightningbeam-editor:
- Delete dead code: the superseded CPU raster tools in raster_tool.rs
(EffectBrush/Smudge/Gradient/Transform/Warp/Liquify/Selection — replaced by
the GPU path), plus orphaned helpers and never-read struct fields.
- Mechanical fixes: drop unused imports/variables/mut, underscore unused params,
`drop(&x)` -> `let _ = x`, deprecated egui::Rounding -> CornerRadius, snake_case
rename, elided-lifetime Cow<'_, [u8]>.
- Keep the WIP CSS theming system (theme.rs/theme_render.rs) under
#[allow(dead_code)] rather than deleting it.
Editor checks warning-free; 293 core tests pass.