docs(adr): ADR-021 motion tokens + ADR-022 DomainError hierarchy
Unblocks Phase 0 Chunks 0.C (SDK motion module) and 0.D (SDK error system) in the YallaClient refactor plan. Both were parked pending SDK-side design decisions; these are those decisions.
ADR-021 — Motion tokens live inside `design`, not a standalone module
- `System.motion.*` sub-namespace added to the existing `design` module (not a new `uz.yalla.sdk:motion` artifact — BOM already has 12 members, resolution-cost vs. isolation-benefit trade favors co-location).
- Full token catalog: `duration` (Duration-typed), `easing` (CubicBezierEasing), `spring` (SpringSpec), `stagger` (Duration), `haptic` (HapticKind enum).
- First `expect`/`actual` surface in `design` — `HapticController` with Android (HapticFeedbackConstants + VibrationEffect.Composition, API 30+) and iOS (UIImpactFeedbackGenerator + CHHapticEngine) actuals.
ADR-022 — `DomainError` sealed hierarchy graduates into `core`
- One canonical error type; per-repository `Failure` types deprecate via typealias shims for one alpha cycle.
- Nested sealed `Network` (NoConnection / Timeout / ServerError) because "network layer failed" is a meaningful UI branching point distinct from per-subtype handling.
- `Unauthorized` / `Forbidden` / `Conflict` / `Validation(fields)` / `NotFound` at the top level.
- `Unknown(cause: Throwable?)` is the only place a raw Throwable crosses the error API — preserved for Sentry breadcrumbs.
- `SafeApiCall` in `data` rewritten to return `Either<DomainError, T>`.
Test plan
-
Docs-only change; `./gradlew apiCheck` unchanged -
Execution PRs (separate) will trigger BCV `apiDump` for the new public surface
CI note
Commit includes `[skip ci]` — YallaClient's runner budget is tight this week. Merge impact: zero code change, zero binary change, zero publish trigger.