The product list, search and detail dialog run entirely in the client.
Every click fires a trigger with behavior: "INVOKE", whose handler
reads/mutates an in-memory product array (persisted to localStorage)
and returns a UiPage / UiPatch — exactly what a server
would otherwise send. No fetch, no Spring.