An ongoing migration is moving all business logic into `rust/`. Each app under `apps/` is a UI shell — it owns rendering, interaction, and platform-specific concerns, but never owns logic. The UI framework for any given app is a replaceable detail.
The single source of truth for all non-UI code. Everything platform-agnostic belongs here: no components, no hooks, no framework imports.
### `apps/`
Each app is a frontend that calls into Rust. Logic is never duplicated between apps — only UI is, because each platform may use an entirely different framework and language to build it.
Function signatures should make the call site readable and let the function evolve without breaking callers. Positional parameters fail both: `formatTime(30, 24)` hides which number is which, and adding, removing, or reordering an argument silently breaks every caller whose types happen to still line up. A single destructured object fixes both at once - each argument names itself at the call site, and the shape can grow without churn. So signatures default to one object parameter:
```tsx
// ❌ meaning depends on order; the shape can't evolve without touching every caller
The one real exception is type predicates (`element is VideoElement`) — the language requires a positional subject, so the reasoning above doesn't get to apply.