Page transitions: on the phone, pages move like a native navigation stack, built on the View Transitions API (mobile/routeTransition.ts). A page opened from another slides in from the trailing edge, back slides it away, and switching between the dock's sections cross-fades while the dock stands still. Lazy routes do not flash their skeleton: the swap waits, behind the frozen snapshot, until the new page rendered. The edge-swipe back gesture already moves the page and skips the transition. RTL mirrors the motion, reduced motion and desktop get none. Pull-to-refresh on the mobile dashboard: the page follows the finger with resistance, ticks once past the threshold and re-reads trips and notifications quietly, without a loading state. Share: trip share and invite links and the journey link get a share button next to copy, opening the system share sheet (Capacitor Share in the apps, Web Share in browsers that have it). Haptics: a selection click for switches and segmented controls, a tick when a sheet is flung closed, and a firmer bump for the chat's long press. Theme lint: this branch's new screens use the type and z-index tokens, the Vacay company tint is a token, and the baseline is lowered to the new counts.
@trek/shared
Single source of truth for TREK's API contracts, expressed as Zod schemas and consumed by both the server (request validation + inferred DTO types) and the client (typed requests/responses).
This package is part of the incremental NestJS + React 19 migration (see the "Brownfield Rewrite" board). It is intentionally dormant until modules start importing it — adding it changes nothing for users.
Rules
- One folder per domain:
src/<domain>/<domain>.schema.ts(+.spec.ts). - Domain-agnostic building blocks live in
src/common/. - A route is only considered migrated once its contract lives here.
- Schemas are the source of truth; server DTOs and client types are inferred from them
(
z.infer<typeof schema>), never hand-duplicated.
Consumption (dev)
Both apps resolve @trek/shared to this package's TypeScript source:
- Server (
tsx): viapathsinserver/tsconfig.json. - Client (
vite): viaresolve.aliasinclient/vite.config.ts(+pathsfor the type-checker).
Production packaging (Docker / workspace wiring) is introduced in card F2, when the server first depends on this package at runtime. Until then prod builds are untouched.
Not yet here
The canonical error envelope is finalised in card F5 (it must match TREK's current Express error responses byte-for-byte), so it is deliberately not invented in F1.