PWA Bot Mode rail and sheet-up motion
Rail fixed in a branch. Sheet-up standard drafted, waiting on 3 picks.
Bot Mode on the phone now uses the Desktop rail component itself. Anything opened from a session, the top-right icons or the composer rises as one bottom sheet. It uses one spring and one dismiss gesture.
Rail: today vs fixed
| Today on m.allternit.com | Fixed (Desktop rail) |
|---|---|
![]() |
![]() |
![]() |
![]() |
- The phone had its own Grok-style rail (`PhoneBotsRail`, ai #783). It now renders the Desktop `ShellRail mode="bot"`: Home, big main bot tile with crown, Promote row, Projects, Bots, Group chats.
- Group chats are pinned above the floating footer. Before, they were hidden under it.
- Arrows bug (whole app): a rule in `src/design/theme.css` turned every caret inside an open drawer, sheet or popover upside down. Removed.
- Checks: typecheck clean, phone + bots vitest 478/478.
Today: four motions for the same job
| Opened from | Example | Today |
|---|---|---|
| Session | Artifact, file card, Thread inspector, Computer | |
| Session | Needs-you, agent canvas sheets | Arc BottomSheet |
| Top right | ⋯ menu, panes menu | fade-in dropdown |
| Top right | Switch thread | fake sheet, no motion, no drag |
| Top right | Overview, search, mini-app | instant overlay |
| Top right | Inbox | Arc BottomSheet |
| Composer | Model pill, Agent mode, Plugins, starters | popover, slide 4px |
| Composer | Artifacts ▾, Design system, bot + | popover / dropdown |
| Composer | Chat + | own sheet (useSheetGestures) |
Two spring systems run side by side: gestures/springs.ts (400/30) and Arc motion-tokens (smooth 0.4 s).
The standard: one sheet, three sizes
| Size | Height | Used for |
|---|---|---|
| Menu | content height, max 60% | ⋯, panes, Agent mode, Plugins, Design system, bot +, Artifacts ▾ |
| List | 55% → drag to 92% | model picker, switch thread, Inbox, Needs-you, canvas comments |
| Full | 94% with grabber + header | artifact, file, Thread inspector, Computer, overview, search, mini-app |
- Enter: rises from the bottom edge, Arc
spring.smooth(0.4 s, no bounce). The scrim fades with the sheet height. - Leave: drag down or flick (320 px/s), tap the scrim, or Back. Exit uses the same spring at 0.3 s.
- Reduced motion: 120 ms fade, no movement.
- Stays as is: ☰ rail slides from the left; Settings pages push from the right; the image lightbox zooms from the thumbnail; voice stays full screen.
- One primitive: Arc
BottomSheetgetssize="menu|list|full". QuietMenu, CascadeMenu and Popover render as a menu sheet on phone, so most composer and header menus change in one place.useSheetGesturessheets move onto it. Spring tokens become one set.
Feel it
Build order
- Arc
BottomSheetsizes, plus menu primitives as sheets on phone (covers B rows 3, 7, 8). - Full-size sheets for the instant overlays (artifact, pane host, overview, search, mini-app).
- Switch thread, model picker, Chat + onto the one sheet. Remove
useSheetGesturesduplicates. - One spring token set. Frame strips (
strip.mjs) of each size, interrupt and reduced motion. - Docs: phone motion guide in
surfaces/docs. One ai PR + one docs PR.



