diff --git a/docs/README-chat-widget.md b/docs/README-chat-widget.md
new file mode 100644
index 000000000..9ce09d6a8
--- /dev/null
+++ b/docs/README-chat-widget.md
@@ -0,0 +1,318 @@
+
RocketRide Chat Widget
+
+
+ Embed a brandable AI chat on any web page — one script tag, zero frameworks.
+
+
+
+
+
+
+
+
+
+`rocketride-chat-widget` is a framework-free chat UI for [RocketRide](https://rocketride.org) pipelines. One lean browser bundle (no React, no CSS frameworks) gives you two consumption modes:
+
+- **Floating chat bubble** — a single `
+```
+
+That is the whole integration: a launcher bubble appears in the chosen corner, clicking it opens the chat panel, and Escape closes it again. The loader reads its configuration from the script tag's own `data-*` attributes.
+
+> Use a **classic** script tag (`defer` is fine). With `type="module"` the browser leaves `document.currentScript` unset, so the loader cannot find its configuration and no bubble is mounted. Pin a version for production, e.g. `https://unpkg.com/rocketride-chat-widget@1.3.0/dist/rocketride-chat.js`.
+
+### Option 2 — inline web component
+
+The same bundle also registers the `` custom element (with a plain script tag, just omit `data-engine-url` if you don't want the bubble too):
+
+```html
+
+
+
+
+
+
+```
+
+The element fills its container (and keeps a 320px minimum height), so give it a sized parent.
+
+With a bundler, install the package and import it once — the import registers the element:
+
+```bash
+# NPM
+npm install rocketride-chat-widget
+# Yarn
+yarn add rocketride-chat-widget
+# PNPM
+pnpm add rocketride-chat-widget
+```
+
+```typescript
+import 'rocketride-chat-widget'; // registers
+```
+
+Don't have a pipeline yet? Visit [RocketRide on GitHub](https://github.com/rocketride-org/rocketride-server) or download the extension directly in your IDE.
+
+## What is RocketRide?
+
+[RocketRide](https://rocketride.org) is an open-source, developer-native AI pipeline platform.
+It lets you build, debug, and deploy production AI workflows without leaving your IDE -
+using a visual drag-and-drop canvas or code-first with TypeScript and Python SDKs.
+
+- **50+ ready-to-use nodes** - 13 LLM providers, 8 vector databases, OCR, NER, PII anonymization, and more
+- **High-performance C++ engine** - production-grade speed and reliability
+- **Deploy anywhere** - locally, on-premises, or self-hosted with Docker
+- **MIT licensed** - fully open source, OSI-compliant
+
+You build your `.pipe` - and the widget puts a chat UI on it, anywhere on the web.
+
+## Features
+
+- **Two modes, one bundle** - inline `` web component and script-tag launcher bubble
+- **Framework-free** - vanilla TypeScript web component; no React, no runtime dependencies
+- **Style isolation** - shadow DOM keeps host CSS out and widget CSS in
+- **Brandable** - accent color, title, welcome text, placeholder via attributes; full theming via CSS custom properties
+- **Light / dark / auto** - `auto` follows `prefers-color-scheme` and updates live
+- **Live status** - connecting / online / offline states, a "thinking" line with the pipeline's live status while it works, and an error banner with a Retry button
+- **Safe output rendering** - escape-first formatter for assistant text (paragraphs, code, bold, http(s) links only); raw model output is never injected as HTML
+- **Accessible** - `role="log"` with `aria-live="polite"`, labeled controls, keyboard support, focus management, reduced-motion support
+- **Public-key auth only** - designed so no private credential ever ships to the browser
+
+---
+
+## Security: public auth key only
+
+**The widget must only ever be configured with a pipeline's PUBLIC Authorization Key.**
+
+- **Where to find it:** when a pipeline with a chat source node is running, the node publishes a link of the form `{host}/chat?auth={public_auth}` along with the key itself (labeled _Public Authorization Key_, prefixed `pk_`). That `pk_…` value is what goes into the widget's `auth` / `data-auth`.
+- **What it grants:** the public key is scoped to that one running pipeline's chat interface. It both authenticates the connection and addresses the pipeline — the widget needs nothing else.
+- **What must never appear in a page:** the RocketRide engine API key (`ROCKETRIDE_APIKEY`) or any private task token (`tk_…`). Anything in an HTML attribute is readable by every visitor via _View Source_. The widget also never falls back to ambient environment credentials — the only credential it will ever send is the one you set explicitly.
+- **Treat it like a public endpoint:** anyone with the page (and therefore the key) can chat with that pipeline. Restarting the pipeline issues a new public key, so an old key can be retired by republishing. Apply the same rate limiting / abuse protection you would give any public form.
+
+### Exposing an engine to browsers (CORS and TLS)
+
+- **CORS.** By default the engine's web endpoints accept requests from any `localhost` / `127.0.0.1` origin (any port) — enough for local development. To embed the widget on a real site, set the `RR_CORS_ORIGINS` environment variable on the engine to a comma-separated list of allowed origins (e.g. `RR_CORS_ORIGINS=https://www.example.com`).
+- **TLS / mixed content.** Browsers block insecure connections from `https` pages. If the embedding page is served over `https`, the `engine-url` must be `https` too (the SDK upgrades it to a secure WebSocket automatically) — in practice, put the engine behind a TLS-terminating reverse proxy and use that URL.
+- **Don't expose more than you need.** The page only needs to reach the engine's chat endpoint; keep engine management interfaces off the public network.
+
+---
+
+## `` attributes
+
+All attributes are observed — changing them on a live element takes effect immediately. Changing `engine-url` or `auth` tears down the connection and reconnects.
+
+| Attribute | Required | Default | Description |
+| ------------- | -------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `engine-url` | Yes | - | RocketRide engine URL, e.g. `http://localhost:5565`. `http(s)` or `ws(s)` accepted; converted to WebSocket internally. |
+| `auth` | Yes | - | The pipeline's **PUBLIC** Authorization Key (`pk_…`). Never an engine API key or private token — see [Security](#security-public-auth-key-only). |
+| `title` | No | `RocketRide Assistant` | Header title. Note: `title` is also a global HTML attribute, so browsers additionally show it as a hover tooltip on the element. |
+| `accent` | No | `#5f2167` (RocketRide violet) | Brand accent color; any CSS color value. Shorthand for setting `--rr-accent`. |
+| `welcome` | No | (none) | Assistant-styled welcome bubble shown before the first exchange. Not sent to the pipeline as history. |
+| `placeholder` | No | `Type a message…` | Input placeholder text. |
+| `theme` | No | `auto` | `light` \| `dark` \| `auto`. `auto` follows `prefers-color-scheme` and updates live when the OS theme changes. |
+
+The element connects when both `engine-url` and `auth` are present and it is attached to the document. Until then it renders in the idle/offline state.
+
+## Script-tag loader (`data-*` attributes)
+
+The IIFE bundle auto-initializes the bubble when its own `
+```
+
+That is the whole integration: a launcher bubble appears in the chosen corner, clicking it opens the chat panel, and Escape closes it again. The loader reads its configuration from the script tag's own `data-*` attributes.
+
+> Use a **classic** script tag (`defer` is fine). With `type="module"` the browser leaves `document.currentScript` unset, so the loader cannot find its configuration and no bubble is mounted. Pin a version for production, e.g. `https://unpkg.com/rocketride-chat-widget@1.3.0/dist/rocketride-chat.js`.
+
+### Option 2 — inline web component
+
+The same bundle also registers the `` custom element (with a plain script tag, just omit `data-engine-url` if you don't want the bubble too):
+
+```html
+
+
+
+
+
+
+```
+
+The element fills its container (and keeps a 320px minimum height), so give it a sized parent.
+
+With a bundler, install the package and import it once — the import registers the element:
+
+```bash
+# NPM
+npm install rocketride-chat-widget
+# Yarn
+yarn add rocketride-chat-widget
+# PNPM
+pnpm add rocketride-chat-widget
+```
+
+```typescript
+import 'rocketride-chat-widget'; // registers
+```
+
+Don't have a pipeline yet? Visit [RocketRide on GitHub](https://github.com/rocketride-org/rocketride-server) or download the extension directly in your IDE.
+
+## What is RocketRide?
+
+[RocketRide](https://rocketride.org) is an open source, developer-native AI pipeline platform.
+It lets you build, debug, and deploy production AI workflows without leaving your IDE -
+using a visual drag-and-drop canvas or code-first with TypeScript and Python SDKs.
+
+- **50+ ready-to-use nodes** - 13 LLM providers, 8 vector databases, OCR, NER, PII anonymization, and more
+- **High-performance C++ engine** - production-grade speed and reliability
+- **Deploy anywhere** - locally, on-premises, or self-hosted with Docker
+- **MIT licensed** - fully open source, OSI-compliant
+
+You build your `.pipe` - and the widget puts a chat UI on it, anywhere on the web.
+
+## Features
+
+- **Two modes, one bundle** - inline `` web component and script-tag launcher bubble
+- **Framework-free** - vanilla TypeScript web component; no React, no runtime dependencies
+- **Style isolation** - shadow DOM keeps host CSS out and widget CSS in
+- **Brandable** - accent color, title, welcome text, placeholder via attributes; full theming via CSS custom properties
+- **Light / dark / auto** - `auto` follows `prefers-color-scheme` and updates live
+- **Live status** - connecting / online / offline states, a "thinking" line with the pipeline's live status while it works, and an error banner with a Retry button
+- **Safe output rendering** - escape-first formatter for assistant text (paragraphs, code, bold, http(s) links only); raw model output is never injected as HTML
+- **Accessible** - `role="log"` with `aria-live="polite"`, labeled controls, keyboard support, focus management, reduced-motion support
+- **Public-key auth only** - designed so no private credential ever ships to the browser
+
+---
+
+## Security: public auth key only
+
+**The widget must only ever be configured with a pipeline's PUBLIC Authorization Key.**
+
+- **Where to find it:** when a pipeline with a chat source node is running, the node publishes a link of the form `{host}/chat?auth={public_auth}` along with the key itself (labeled _Public Authorization Key_, prefixed `pk_`). That `pk_…` value is what goes into the widget's `auth` / `data-auth`.
+- **What it grants:** the public key is scoped to that one running pipeline's chat interface. It both authenticates the connection and addresses the pipeline — the widget needs nothing else.
+- **What must never appear in a page:** the RocketRide engine API key (`ROCKETRIDE_APIKEY`) or any private task token (`tk_…`). Anything in an HTML attribute is readable by every visitor via _View Source_. The widget also never falls back to ambient environment credentials — the only credential it will ever send is the one you set explicitly.
+- **Treat it like a public endpoint:** anyone with the page (and therefore the key) can chat with that pipeline. Restarting the pipeline issues a new public key, so an old key can be retired by republishing. Apply the same rate limiting / abuse protection you would give any public form.
+
+### Exposing an engine to browsers (CORS and TLS)
+
+- **CORS.** By default the engine's web endpoints accept requests from any `localhost` / `127.0.0.1` origin (any port) — enough for local development. To embed the widget on a real site, set the `RR_CORS_ORIGINS` environment variable on the engine to a comma-separated list of allowed origins (e.g. `RR_CORS_ORIGINS=https://www.example.com`).
+- **TLS / mixed content.** Browsers block insecure connections from `https` pages. If the embedding page is served over `https`, the `engine-url` must be `https` too (the SDK upgrades it to a secure WebSocket automatically) — in practice, put the engine behind a TLS-terminating reverse proxy and use that URL.
+- **Don't expose more than you need.** The page only needs to reach the engine's chat endpoint; keep engine management interfaces off the public network.
+
+---
+
+## `` attributes
+
+All attributes are observed — changing them on a live element takes effect immediately. Changing `engine-url` or `auth` tears down the connection and reconnects.
+
+| Attribute | Required | Default | Description |
+| ------------- | -------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `engine-url` | Yes | - | RocketRide engine URL, e.g. `http://localhost:5565`. `http(s)` or `ws(s)` accepted; converted to WebSocket internally. |
+| `auth` | Yes | - | The pipeline's **PUBLIC** Authorization Key (`pk_…`). Never an engine API key or private token — see [Security](#security-public-auth-key-only). |
+| `title` | No | `RocketRide Assistant` | Header title. Note: `title` is also a global HTML attribute, so browsers additionally show it as a hover tooltip on the element. |
+| `accent` | No | `#5f2167` (RocketRide violet) | Brand accent color; any CSS color value. Shorthand for setting `--rr-accent`. |
+| `welcome` | No | (none) | Assistant-styled welcome bubble shown before the first exchange. Not sent to the pipeline as history. |
+| `placeholder` | No | `Type a message…` | Input placeholder text. |
+| `theme` | No | `auto` | `light` \| `dark` \| `auto`. `auto` follows `prefers-color-scheme` and updates live when the OS theme changes. |
+
+The element connects when both `engine-url` and `auth` are present and it is attached to the document. Until then it renders in the idle/offline state.
+
+## Script-tag loader (`data-*` attributes)
+
+The IIFE bundle auto-initializes the bubble when its own `
+
+
+
+