Module-specific interactions layered on shared 00-shared/08 . Covers every input
modality on phone/tablet/desktop.
Gesture Behaviour Where
Tap open parent/child, submit forms, toggle switches, open menus all
Tap on CTA submitting-aware disabled re-tap (00-shared/08 §6 ) forms, sheets
Long-press AppMenu on list rows / child cardsparents list, linked children
Double-tap none —
Swipe left/right no destructive swipe on links (irreversible server-side) — keep confirm—
Pull down refresh lists (bypasses cache) parents list, detail, my children
Pinch/drag none —
Hardware back pop sheet/dialog first; then previous screen; on root → shell all
Edge swipe drawer (shell) —
Haptics success lightImpact; link/unlink confirm heavyImpact; menu open selectionClick; error mediumImpact (08 §3 ) mutations
Input Behaviour
Tab form order = visual order; focus ring primary (2 dp)
Enter submits active form (create/edit/link); confirms focused dialog button
Esc closes sheet/dialog/menu; clears search; focus returns to trigger
N new guardian (parents list)
Ctrl/Cmd+Enter submit from text areas
Arrows navigate user/student picker results
Right-click context menu (same as long-press)
Hover row tint m-fast, tooltip after 500 ms; card elevation hint
Focus logical FocusTraversalGroup; modal sheets trap focus
Event Haptic
Guardian linked / profile saved lightImpact
Unlink confirm heavyImpact
Open row menu selectionClick
Validation error / 4xx mediumImpact
Rule off when system disabled; none on web/desktop (08 §3 )
Transition Duration/curve Used by
Route push list→detail m-base slideparents list, my children
Hero avatar list→detail m-slow flightparent/child cards
Link sheet m-base bottom slidelink guardian
Unlink row removal m-base fade-outdetail children list
Warning banner expand AnimatedSize m-baseduplicate/primary warnings
Child switcher change AnimatedSwitcher fade m-fastmy children
Skeleton→content cross-fade m-slow all loads
Reduced-motion: fades + instant only; no stagger, no hero (08 §4 ).
Interaction Detail
Submit pressed CTA loading swap m-base, double-tap locked
Switch toggle (pickup/primary) m-fast thumb + icon morph; warning banner slides in if conflict
Duplicate link attempt chip row shake (reduced-motion: none) + AppBanner(warning)
Unlink dialog scale+fade m-base; on confirm heavyImpact + row fade + snackbar
Children count badge scale pop m-fast on refresh change
Pull-to-refresh primary spinner; lightImpact on completion
All presses respond < 100 ms with m-fast ripple.
Every network action shows pending state (CTA spinner / skeleton).
Submit disabled while pending — no double-submit (double link rows are a real risk,
OQ-2).
Rate-limit → countdown, no auto-retry.
Errors persist until corrected/dismissed; never flash.
User picker sheet: debounced q search (300 ms, users.service.ts:90-115), Enter
selects first result, Esc closes.
Student picker in link sheet: search by admission number or name; selection replaces
field with chip; change reopens picker.
Deep links: studylyon://parents/:id → detail (admin); studylyon://students/:id
→ child if linked (forward-looking); studylyon://my/children → switcher.
Clipboard: none in this module (no codes/keys).
"Switch primary" never patches a link — no link PATCH endpoint
(student-parent-link.service.ts:16-41); the interaction performs delete+recreate and
its copy must not imply an update.
"Unlink" maps exactly to DELETE /parents/link/:linkId soft delete
(student-parent-link.service.ts:38-41); 404 → treat-as-removed.
Primary toggles warn but are not blocked client-side — the server permits
multi-primary (OQ-5); UI should never silently enforce what the server won't.
Search field on the parents list is client-side filtering only (server ignores q,
parent.service.ts:58-61) — interaction spec forbids pretending it queries the server.