Contesta — second origin

This page is served by the Vite dev server (npm run dev:site, port 5173 by default). The widget posts to the backend origin resolved from VITE_API_BASE_URL — http://localhost:8787 unless you override it. The two are different origins, so every message exercises CORS, the preflight, and the widget bundle.

Manual checklist — scenario 5 (host reset / empty-host theme)
  1. The widget is visible at all. If it is missing, `div:empty { display: none }` won.
  2. The widget's type is its own: not Comic Sans, not underlined, not 3x line-height.
  3. Type size is ~15px, not the 8px this page set on `html` (px, never rem).
  4. Nothing on this page changed appearance because the widget loaded.
Manual checklist — scenario 6 (cross-origin embedding)
  1. Open devtools. Send a message. The POST to the resolved API origin's `/api/chat` (default `http://localhost:8787/api/chat`) returns 200.
  2. The response carries `access-control-allow-origin` set to this page's own origin (`http://localhost:5173` by default).
  3. The answer renders in the widget as an assistant bubble.
  4. No console error mentions a blocked cross-origin request.
Manual checklist — CSP
  1. Re-serve with `style-src 'none'` (or a strict equivalent) and reload: the widget must stay styled, because it installs an adopted stylesheet and never depends on an inline `<style>` element.

Widget

The snippet below is a classic script tag. It must stay classic: inside a module script `document.currentScript` is always null, and the widget would never see the data-* configuration.