quadraui 0.1.0

Cross-platform Rust UI toolkit: write one AppLogic and run it unmodified on TUI, GTK4 (Linux), macOS, and Windows backends
Documentation
# Architecture

**Workspace members:**

| Crate | Purpose |
|---|---|
| `quadraui/` | Core library: primitives, types, theme, backend traits, TUI, GTK, macOS, and Windows rasterisers. |
| `kubeui-core/` | Domain logic for a Kubernetes dashboard demo. No rendering deps — testable in isolation. |
| `kubeui/` | TUI Kubernetes dashboard. Real consumer of every TUI rasteriser. |
| `kubeui-gtk/` | GTK Kubernetes dashboard. Same domain logic as `kubeui`. |

**Two-layer split** inside `quadraui/`:

- `quadraui/src/primitives/` — backend-agnostic widget descriptions +
  layout functions + hit_test. **Must NOT depend on `ratatui`, `gtk4`,
  `cairo`, or any backend crate.** Tests live as inline `#[cfg(test)]
  mod tests` blocks at the bottom of each primitive file.
- `quadraui/src/tui/`, `quadraui/src/gtk/`, `quadraui/src/macos/`, and
  `quadraui/src/win/` — the four backend rasterisers (`tui`, `gtk`,
  `macos`, `win` feature-gated respectively). Each consumes the
  primitive's `layout()` and paints verbatim. **Must NOT contain layout
  decisions** that the primitive could express. See the root
  `README.md`'s *Status* section for how far each backend actually
  gets today.

**Compose helpers** in `quadraui/src/compose/` sit above primitives
and below apps. They own interaction state machines for common
multi-primitive compositions so consumers don't reimplement them:

- `FocusRing` — Tab/Shift+Tab cycling through widget IDs.
- `MenuSystem` — MenuBar + ContextMenu dropdown interaction.
- `SidebarSystem` — MSV + TreeView sidebar panel interaction.

**GTK hosting helpers** in `quadraui/src/gtk/`:

- `MenuOverlay` — encapsulates the DrawingArea boilerplate for
  MenuSystem dropdown popups when the menu bar lives in a separate
  titlebar widget. Handles the negative-y coordinate transform,
  `set_focusable(false)`, `can_target` toggling, surface clearing,
  and draw/click/motion wiring. Apps that use the single-DA runner
  don't need this — the dropdown paints on the same surface.

**Cross-backend runtime plumbing** sits at the top of `quadraui/src/`,
alongside `backend.rs` and `frame.rs`, shared by all four backends
instead of duplicated per-runner:

- `runtime.rs` — shared plumbing for the per-backend runners (`tui::run`,
  `gtk::run`, `macos::run`, `win::run`): the post-event `EventOutcome`
  enum and "apply this outcome to the live window", previously
  duplicated (or silently missing) across the four runners (#496/#813).
- `dispatch.rs` — cross-backend mouse + scroll dispatch. Backends call
  free functions (`dispatch_mouse_down`, `dispatch_mouse_drag`,
  `dispatch_mouse_up`, `dispatch_scroll`, `dispatch_click`) with raw,
  platform-translated events; a shared [`ModalStack`] decides whether an
  open modal — never a base-layer widget behind it — receives the event
  (issue #192).
- `shell.rs` — the `ShellApp` trait + `ShellConfig` for apps that want a
  full `AppShell` (activity bar + sidebar + main content) instead of
  implementing `AppLogic` directly. Each backend's `run_with_shell()`
  owns window creation, event wiring, and chrome rendering; the
  consumer renders only its own content. `shell_adapter.rs` is the
  shared `AppLogic` impl every backend's shell runner instantiates to
  avoid re-deriving that routing per backend.
- `paint_surface.rs` — `PaintSurface`, the low-level drawing-verb trait
  underneath the three pixel backends (GTK, macOS, Windows), factoring the
  "how the platform draws at all" half of `Backend` (frame lifecycle,
  measurement, fill/stroke/text primitives) out from the "what to
  paint" half — one `draw_*`/`*_layout` method per primitive (issue
  #807; `pub` since issue #1101, reached via `Backend::paint_surface`).

**Backend trait** in `quadraui/src/backend.rs` plumbs frame state, the
`set_theme` / `set_nerd_fonts` setters hosts call once per frame, *and*
one `draw_*` method per primitive (`docs/decisions/BACKEND_TRAIT_PROPOSAL.md` §4,
Decision 2 = B) — adding a primitive is a breaking change to the trait,
intentionally. Each backend's `draw_*` method is a thin wrapper around
that backend module's own internal `pub fn draw_*` free function (e.g.
`impl Backend for WinBackend { fn draw_tree(...) {
quadraui_win::draw_tree(...) } }`); the trait itself has no free-standing
"cross-cutting state" carve-out.

**`set_cell` / `cairo_rgb` / `ratatui_color` / etc.** are private
backend helpers — never call them from primitives.

**Frame composition** in `quadraui/src/frame.rs` sits above `Backend`:
`ScreenLayout` + `Surface` is the canonical way for a consumer to
assemble a top-level screen from multiple primitives — pushing
`Surface` entries and calling `ScreenLayout::draw` routes every backend
through one call site (rather than each backend calling
`Backend::draw_<name>` at its own, potentially divergent, call site)
and derives the click hit-map from the same data that was painted.
`Backend::draw_*` methods remain the public, low-level rasteriser entry
point underneath — `ScreenLayout::draw` calls them internally, and
they're the only path for primitives that don't have a `Surface`
variant yet. See `docs/decisions/DECISIONS.md` D-006 and
`docs/PRIMITIVE_RULES.md` "One primitive, one canonical paint path"
(issue #456).

**Audits.** `docs/audits/FRAMEWORK_AUDIT_2026-09-26.md` is the most recent
independent review of quadraui as an app framework: its verdict, the
measured numbers, and the severity-ranked roadmap behind epics #1095
(widget model) and #1096 (language bindings). The living, release-ordered
version of that roadmap is [`ROADMAP.md`](../../ROADMAP.md) at the repo root. `docs/SMELL_AUDIT_2026-07.md`
is the earlier code-smell audit.