Specializes 00-shared/08 for this module. All motion tokens from
02_Design_Tokens.md §6 . The grid is the hero surface: drag-to-edit on desktop,
long-press on mobile (06 §S1 , 07 §A1 ).
Gesture Behaviour Screen
Tap empty cell Open S4 editor prefilled (class + day + time of cell) S1/S2 (coordinator)
Tap slot SlotDetailPopover: subject/teacher/room/time + actions (Duplicate, Edit/Delete (planned))S1/S2/S3
Long-press slot Same popover as tap (selectionClick haptic) — no drag on mobile ; edit happens in the editor, not by dragging S1
Long-press on TimetableSlotCard conflict badge Tooltip/semantics "Double-booked" detail (proposed) S1
Swipe left on slot Remove — (planned) (no DELETE endpoint; disabled until backend lands) S1/S2
Pull down Refresh grid (cache-bypass) S1/S2/S3
Tap FAB Scale-in (m-entrance) → S4 S1 (coordinator)
Tap ‹/› Week shift m-base cross-fade S1/S2/S3
Back gesture Editor sheet → grid (discard confirm if dirty (proposed)); grid → previous surface S4
Input Behaviour
Hover slot m-fast surface tint, e-2; tooltip after 500 ms (full label) (08 §2 )
Hover empty cell subtle fill; drop-target highlight primaryContainer when a slot is dragged over
Drag slot → cell Draggable<TimetableEntry> → DragTarget cell: drop opens S4 editor prefilled with new day/time + slot's subject/teacher/room. Creates a new entry — no PATCH exists; banner in editor: "This creates a new slot; the original stays until you delete it (planned)" (09 §5 )
Drag to invalid target (occupied non-empty cell) Rejected: cell shows errorContainer outline; slot returns (spring m-base)
Right-click slot Same popover as long-press
+ / NNew slot (S4) on grid screens (05_Global_Information_Architecture.md §7 )
← / →Week navigation (grid focused)
Ctrl+FFocus scope/class search (proposed)
EscClose editor sheet/dialog/popover
EnterSubmit focused editor; Tab logical order; visible focus ring primary 2 dp (09 §6 )
Delete keyOn focused slot → delete confirm (planned)
Event Haptic
Entry created (200) lightImpact()
Conflict (409 / pre-flight) mediumImpact() + banner
Slot long-press popover selectionClick()
Pull-to-refresh done lightImpact()
Rule disabled when system haptics off; none on web/desktop (08 §3 )
Screen Entrance Element motion
S1/S2 grid page fade+rise m-slow slot insert/remove: AnimatedList m-base; week shift cross-fade m-base; conflict border pulse once m-fast
S3 room view grid fade m-fast merge updates cross-fade m-fast
S4 editor sheet slide-up m-base, r-xl corners (phone) / dialog scale m-base (desktop) picker options m-fast; conflict banner slide-down m-base; Save spinner replaces label
S5 banner slide-down m-base dismiss slide-up m-fast
S6 week nav — offset label cross-fade m-fast
Reduced-motion: all collapse to fades ≤ m-instant, no stagger, no drag ghost
animation (08 §4 , 09 §8 ).
FAB hide/show on scroll (grid): hide on scroll-down, show on scroll-up (03 §D ).
Slot drag ghost (desktop): card lifts to e-4 + 0.95 scale while dragged;
drop snaps into cell (08 §2 ); drop → editor opens m-base (create semantics
per 09 §5 ).
Save button: label → spinner → check + snackbar "Slot added"; disabled while
pending (anti-double-submit 08 §6 ).
Week navigator: ‹/› + cross-fade; "Today" resets offset.
Scope switch: segmented control; grid cross-fades m-fast while refetching.
Conflict banner: auto-announce via live region; dismiss returns focus to
conflicting field.
Every interactive element responds ≤ 100 ms (08 §6 ).
Network-bound actions always pending-visible — never silent.
Submit double-tap prevented; destructive actions (planned) require explicit
confirm dialog (typed confirm not required — soft-delete is reversible server-side;
05_Global_Information_Architecture.md §5 applies to irreversible purge only).
Grid never blocks input during refetch: stale requests dropped via request
generation token (13 §5 ).