glirastes 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -1
- package/README.md +32 -47
- package/dist/cjs/embed/chat-styles.generated.d.ts +1 -1
- package/dist/cjs/embed/chat-styles.generated.js +1 -1
- package/dist/cjs/react/components/approval-card.js +20 -1
- package/dist/cjs/react/locale-de.js +3 -0
- package/dist/cjs/react/provider/ai-chat-provider.js +3 -0
- package/dist/cjs/react/styles.css +26 -0
- package/dist/cjs/react/types.d.ts +5 -0
- package/dist/cjs/react/utils/create-approval-description.js +12 -6
- package/dist/cjs/runtime/glirastes.d.ts +5 -4
- package/dist/cjs/runtime/glirastes.js +4 -2
- package/dist/cjs/runtime/index.d.ts +1 -0
- package/dist/cjs/runtime/index.js +4 -1
- package/dist/cjs/runtime/local-limits.d.ts +6 -0
- package/dist/cjs/runtime/local-limits.js +26 -0
- package/dist/cjs/runtime/runtime-mode.d.ts +1 -1
- package/dist/cjs/runtime/runtime-mode.js +1 -1
- package/dist/cjs/runtime/sdk-version.d.ts +2 -0
- package/dist/cjs/runtime/sdk-version.js +5 -0
- package/dist/cjs/server/lancer/client.js +2 -1
- package/dist/cli/commands/connect.js +6 -6
- package/dist/cli/commands/connect.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/embed/chat-styles.generated.d.ts +1 -1
- package/dist/embed/chat-styles.generated.js +1 -1
- package/dist/embed/chat-styles.generated.js.map +1 -1
- package/dist/react/components/approval-card.js +20 -1
- package/dist/react/components/approval-card.js.map +1 -1
- package/dist/react/locale-de.js +3 -0
- package/dist/react/locale-de.js.map +1 -1
- package/dist/react/provider/ai-chat-provider.js +3 -0
- package/dist/react/provider/ai-chat-provider.js.map +1 -1
- package/dist/react/styles.css +26 -0
- package/dist/react/types.d.ts +5 -0
- package/dist/react/utils/create-approval-description.js +12 -6
- package/dist/react/utils/create-approval-description.js.map +1 -1
- package/dist/runtime/glirastes.d.ts +5 -4
- package/dist/runtime/glirastes.js +4 -2
- package/dist/runtime/glirastes.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/local-limits.d.ts +6 -0
- package/dist/runtime/local-limits.js +23 -0
- package/dist/runtime/local-limits.js.map +1 -0
- package/dist/runtime/runtime-mode.d.ts +1 -1
- package/dist/runtime/runtime-mode.js +1 -1
- package/dist/runtime/runtime-mode.js.map +1 -1
- package/dist/runtime/sdk-version.d.ts +2 -0
- package/dist/runtime/sdk-version.js +3 -0
- package/dist/runtime/sdk-version.js.map +1 -0
- package/dist/server/lancer/client.js +2 -1
- package/dist/server/lancer/client.js.map +1 -1
- package/package.json +1 -1
- package/skills/integrating-glirastes-nextjs/SKILL.md +2 -9
- package/skills/setting-up-glirastes/SKILL.md +40 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.1] - 2026-11-12
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- README quickstart leads with the two-command coding-agent path; the chat route security details moved to `docs/chat-route-security.md`.
|
|
15
|
+
- `glirastes connect` needs no `--base-url`: flag, then `GLIRASTES_CONTROL_PLANE_URL`, then `https://api.glirastes.io`. `glirastes sync` already reads the paired connection and needs none.
|
|
16
|
+
- `createGlirastes({ localLimits })` is optional and each field falls back to `DEFAULT_LOCAL_LIMITS` (6 steps, 8 tool calls, 60 s, 40k/4k tokens, 0.5 USD); partial overrides merge onto it. The init skill and README drop the full limits block.
|
|
17
|
+
- `setting-up-glirastes` asks once whether the app runs Standalone or with the Platform, records it, and lists the values both modes need (`GLIRASTES_APPROVAL_SECRET`).
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- The runner registers with `GLIRASTES_BUILD_ID`, else `glirastes@<sdk version>`, instead of `0.0.0` when `createGlirastes` gets no `version`.
|
|
22
|
+
- The default Platform URL is now `https://api.glirastes.io`; the previous `api.glirastes.chainmatics.io` host did not resolve, so connected apps without `GLIRASTES_CONTROL_PLANE_URL` never reached the Platform.
|
|
23
|
+
- The approval card no longer hides what you approve: array values show the first two items plus "+N weitere" with an expandable one-item-per-line list, and long text expands to wrap fully (`aria-expanded`, German and English locale strings).
|
|
24
|
+
|
|
10
25
|
## [0.5.0] - 2026-11-11
|
|
11
26
|
|
|
12
27
|
The Foundation release. Its surface differs from 0.4.0; read **Breaking** before
|
|
@@ -546,7 +561,8 @@ No code changes — patch-level docs release.
|
|
|
546
561
|
these libraries on install. `react-markdown` is loaded via `React.lazy`
|
|
547
562
|
with a plain-text fallback when the peer dep is not installed.
|
|
548
563
|
|
|
549
|
-
[Unreleased]: https://github.com/chainmatics/glirastes/compare/v0.5.
|
|
564
|
+
[Unreleased]: https://github.com/chainmatics/glirastes/compare/v0.5.1...HEAD
|
|
565
|
+
[0.5.1]: https://github.com/chainmatics/glirastes/compare/v0.5.0...v0.5.1
|
|
550
566
|
[0.5.0]: https://github.com/chainmatics/glirastes/compare/v0.4.0...v0.5.0
|
|
551
567
|
[0.4.0]: https://github.com/chainmatics/glirastes/compare/v0.3.2...v0.4.0
|
|
552
568
|
[0.2.1]: https://github.com/chainmatics/glirastes/compare/v0.2.0...v0.2.1
|
package/README.md
CHANGED
|
@@ -43,6 +43,20 @@ or business data.
|
|
|
43
43
|
|
|
44
44
|
## Quickstart (Next.js App Router)
|
|
45
45
|
|
|
46
|
+
### With a coding agent (recommended)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install glirastes @ai-sdk/openai @ai-sdk/react react-markdown
|
|
50
|
+
npx --no-install glirastes init
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Run `init` inside Claude Code or Codex (Node >= 20.6). Your agent then derives
|
|
54
|
+
the tools from your routes, adds the chat route and the chat UI, and asks once
|
|
55
|
+
whether the app runs Standalone or with the Platform. Existing files are never
|
|
56
|
+
replaced; `--dry-run --json` previews without writing anything.
|
|
57
|
+
|
|
58
|
+
### By hand
|
|
59
|
+
|
|
46
60
|
**1. Install** the SDK and the chat peers (Node >= 20.6):
|
|
47
61
|
|
|
48
62
|
```bash
|
|
@@ -60,7 +74,6 @@ npx --no-install glirastes init
|
|
|
60
74
|
`predev` / `prebuild` scripts (`glirastes tools refresh`) and a short hint in
|
|
61
75
|
`AGENTS.md` / `CLAUDE.md`, installs the [agent skills](#agent-skills) and hands
|
|
62
76
|
the integration to your coding agent. Existing files are never replaced.
|
|
63
|
-
`--dry-run --json` previews without writing anything.
|
|
64
77
|
|
|
65
78
|
**3. Derive the tools** from your routes, pages, URL filters and client actions:
|
|
66
79
|
|
|
@@ -82,15 +95,7 @@ import { createAiChatHandler } from 'glirastes/server/nextjs';
|
|
|
82
95
|
import * as generated from '@/generated/glirastes/tools.generated';
|
|
83
96
|
import { resolvePrincipal } from '@/lib/glirastes-principal'; // your session lookup
|
|
84
97
|
|
|
85
|
-
const glirastes = createGlirastes({
|
|
86
|
-
generated,
|
|
87
|
-
localLimits: {
|
|
88
|
-
maxModelSteps: 6, maxToolCalls: 8, totalTimeoutMs: 60_000, toolTimeoutMs: 15_000,
|
|
89
|
-
maxInputTokens: 40_000, maxOutputTokens: 4_000, maxEstimatedCostUsd: 0.5,
|
|
90
|
-
maxRepeatedFingerprint: 3, maxConsecutiveErrors: 3,
|
|
91
|
-
delegation: { maxDepth: 1, maxBreadth: 1, sharedBudget: true },
|
|
92
|
-
},
|
|
93
|
-
});
|
|
98
|
+
const glirastes = createGlirastes({ generated });
|
|
94
99
|
const openrouter = createOpenAI({ baseURL: 'https://openrouter.ai/api/v1', apiKey: process.env.OPENROUTER_API_KEY });
|
|
95
100
|
|
|
96
101
|
export const runtime = 'nodejs';
|
|
@@ -107,38 +112,12 @@ export async function POST(request: Request) {
|
|
|
107
112
|
}
|
|
108
113
|
```
|
|
109
114
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
call runs only when every check passed in that request; any other approved
|
|
117
|
-
call without a result in the history is denied. With the default in-process store, each
|
|
118
|
-
approval runs at most once per process within its lifetime, and each caller
|
|
119
|
-
holds at most 200 live approvals. Without a managed runtime or
|
|
120
|
-
`approvalScope`, the caller is told apart by a keyed hash of the request's
|
|
121
|
-
`Authorization` or `Cookie` header (only requests without credentials share
|
|
122
|
-
one quota); `approvalScope` also binds each approval to its user. With several instances, pass a
|
|
123
|
-
shared `approvalStore` (e.g. Redis), or a replayed history can run once more
|
|
124
|
-
on another instance. The handler also answers 415 to a body that is not
|
|
125
|
-
`application/json`, 403 to a browser request from another origin (list yours
|
|
126
|
-
in `allowedOrigins`), 413 above `maxBodyBytes` (1 MB), and 400 to a body that
|
|
127
|
-
is not JSON (`invalid_json`), to a history that repeats a tool call id or an
|
|
128
|
-
approval id (`duplicate_tool_call_id`, `duplicate_approval_id`), to a
|
|
129
|
-
malformed tool part or approval (`tool_part_malformed`, `approval_malformed`)
|
|
130
|
-
and to more than 32 approved calls in one request (`too_many_approvals`).
|
|
131
|
-
|
|
132
|
-
Endpoint tools call the origin of the chat request's URL, the address your
|
|
133
|
-
Next.js server listens on, so they reach the app's own route handlers. If your
|
|
134
|
-
API runs in another process, even under the same public origin behind a
|
|
135
|
-
proxy, pass `endpointCaller: (request) => createHttpEndpointCaller({ baseUrl,
|
|
136
|
-
request })` with its origin; `trustForwardedHeaders: true` is the alternative
|
|
137
|
-
only when every request comes through a proxy that sets `x-forwarded-host`
|
|
138
|
-
(otherwise a client can aim the calls, with the user's cookie, at any host).
|
|
139
|
-
|
|
140
|
-
`executeTool` and routes built from `glirastes/runtime/ai-sdk` alone run a tool
|
|
141
|
-
without these approval checks; give them only input your server has authorized.
|
|
115
|
+
Budgets default to safe values; pass `localLimits: { maxToolCalls: 4 }` to override single fields.
|
|
116
|
+
|
|
117
|
+
Before production set `GLIRASTES_APPROVAL_SECRET` (at least 16 characters, the
|
|
118
|
+
same on every instance): it signs each approval so a forged or edited chat
|
|
119
|
+
history runs nothing. Request limits, multi-instance setups and the rest are in
|
|
120
|
+
[docs/chat-route-security.md](docs/chat-route-security.md).
|
|
142
121
|
|
|
143
122
|
**5. Mount the chat** and the navigation bridge (client components):
|
|
144
123
|
|
|
@@ -274,15 +253,20 @@ See the skill [`building-glirastes-chat-ui`](skills/building-glirastes-chat-ui/S
|
|
|
274
253
|
`createGlirastes` from `glirastes/runtime` handles both. Connected, it falls
|
|
275
254
|
back to the local code whenever the Platform is unreachable and reports errors
|
|
276
255
|
to `onError` (operation and status only). `GLIRASTES_CONTROL_PLANE_URL` is
|
|
277
|
-
optional and defaults to `https://api.glirastes.
|
|
256
|
+
optional and defaults to `https://api.glirastes.io`; set it only
|
|
278
257
|
for a self-hosted or local Platform.
|
|
279
258
|
|
|
280
259
|
```bash
|
|
281
|
-
npx glirastes connect
|
|
282
|
-
npx glirastes sync
|
|
283
|
-
npx glirastes doctor
|
|
260
|
+
npx glirastes connect # pair the app with the hosted Platform, writes GLIRASTES_API_KEY
|
|
261
|
+
npx glirastes sync # upload the current local setup
|
|
262
|
+
npx glirastes doctor # local checks, no network
|
|
284
263
|
```
|
|
285
264
|
|
|
265
|
+
Pass `--base-url <platform-url>` to `connect` only for a self-hosted or local
|
|
266
|
+
Platform. For a production server or CI where nobody runs `connect`, create a
|
|
267
|
+
key in the Platform dashboard under **Settings → API keys → "Keys for servers
|
|
268
|
+
and CI"** and set it as `GLIRASTES_API_KEY`.
|
|
269
|
+
|
|
286
270
|
The **Glirastes Platform** is the optional control plane: reviewed tool
|
|
287
271
|
configuration, signed immutable revisions, staged rollouts, approvals and
|
|
288
272
|
content-free health. **Free** covers the local SDK, the local skill workflow
|
|
@@ -327,7 +311,7 @@ and a connected app; **Pro** adds the managed CI tool agent. Details:
|
|
|
327
311
|
| `glirastes tools enrich --managed [--first-run] [--base <branch>]` | Pro, CI only: run the managed tool agent |
|
|
328
312
|
| `glirastes setup [--dry-run] [--managed]` | Validate and install the local setup artifacts |
|
|
329
313
|
| `glirastes setup inspect` | Inspect project manifests before integration |
|
|
330
|
-
| `glirastes connect --base-url <url
|
|
314
|
+
| `glirastes connect [--base-url <url>]` | Pair the app with the Platform (`--base-url` only for self-hosted) |
|
|
331
315
|
| `glirastes sync` | Upload the current local setup |
|
|
332
316
|
| `glirastes doctor [--managed] [--verbose] [--json]` | Diagnose the local setup |
|
|
333
317
|
| `glirastes install [--host a,b]` | Install the agent skills only |
|
|
@@ -355,6 +339,7 @@ FastAPI are integrated and automatically checked. Exact levels and evidence:
|
|
|
355
339
|
|
|
356
340
|
- [Support matrix](docs/support-matrix.md)
|
|
357
341
|
- [Tool policy](docs/tool-policy.md)
|
|
342
|
+
- [Chat route security](docs/chat-route-security.md)
|
|
358
343
|
- [Chat interactions (`@` and `/`)](docs/chat-interactions.md)
|
|
359
344
|
- [Managed runtime sync](docs/managed-runtime-sync.md)
|
|
360
345
|
- [Runtime persistence](docs/runtime-persistence.md)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CHAT_STYLES = "/* glirastes \u2014 default chat panel styles.\n Auto-injected when you render <AiChat /> or <AiChatPanel />.\n Themes: every color / radius / font below is driven by CSS variables\n that can be overridden per-instance via the `theme` prop, which emits\n inline `--cm-*` vars on the root elements. The defaults below act as\n the fallback when no `theme` prop is given. */\n\n:where(\n [data-component=\"ai-chat-panel\"],\n [data-component=\"chat-window\"],\n [data-component=\"ai-trigger-button\"],\n [data-component=\"assistant-shell\"],\n [data-component=\"assistant-bubble\"],\n [data-component=\"assistant-toggle\"]\n):where(:not([data-unstyled], [data-unstyled] *)) {\n --cm-primary: #6366f1;\n --cm-primary-soft: #818cf8;\n --cm-primary-tint: rgba(99, 102, 241, 0.12);\n --cm-primary-ring: rgba(99, 102, 241, 0.18);\n --cm-bg: #ffffff;\n --cm-bg-muted: #f9fafb;\n --cm-bubble-user: #e0e7ff;\n --cm-bubble-assistant: #f3f4f6;\n --cm-border: #e5e7eb;\n --cm-text: #111827;\n --cm-text-muted: #6b7280;\n --cm-danger: #dc2626;\n --cm-radius: 0.875rem;\n --cm-radius-sm: 0.5rem;\n --cm-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 520px;\n max-height: 100%;\n background: var(--cm-bg);\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n overflow: hidden;\n font-family: var(--cm-font);\n font-size: 14px;\n line-height: 1.5;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.03);\n}\n\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) *,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) *::before,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) *::after {\n box-sizing: border-box;\n}\n\n/* ---------- Error banner ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"error-banner\"] {\n padding: 0.75rem 1rem;\n background: #fef2f2;\n color: #991b1b;\n border-bottom: 1px solid #fecaca;\n font-size: 13px;\n}\n\n/* ---------- Empty state ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"empty-state\"] {\n flex: 1;\n display: grid;\n place-items: center;\n padding: 2rem;\n color: var(--cm-text-muted);\n text-align: center;\n}\n\n/* ---------- Message list ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-list\"] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n scroll-behavior: smooth;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-list\"] > [data-action=\"load-more\"] {\n align-self: center;\n padding: 0.375rem 0.75rem;\n font: inherit;\n font-size: 12px;\n background: transparent;\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text-muted);\n cursor: pointer;\n}\n\n/* ---------- Message bubble ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"] {\n max-width: 85%;\n padding: 0.625rem 0.875rem;\n border-radius: var(--cm-radius);\n word-wrap: break-word;\n overflow-wrap: anywhere;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"][data-role=\"user\"] {\n align-self: flex-end;\n background: var(--cm-bubble-user);\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"][data-role=\"assistant\"] {\n align-self: flex-start;\n background: var(--cm-bubble-assistant);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"][data-role=\"system\"] {\n align-self: center;\n background: var(--cm-bg-muted);\n color: var(--cm-text-muted);\n font-style: italic;\n font-size: 13px;\n}\n\n/* ---------- Markdown content ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] p {\n margin: 0 0 0.5rem 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] p:last-child {\n margin: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] pre {\n background: rgba(0, 0, 0, 0.05);\n padding: 0.625rem 0.75rem;\n border-radius: var(--cm-radius-sm);\n overflow-x: auto;\n font-size: 12px;\n margin: 0.5rem 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] code {\n background: rgba(0, 0, 0, 0.06);\n padding: 0.125rem 0.25rem;\n border-radius: 3px;\n font-size: 0.9em;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] pre code {\n background: transparent;\n padding: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] ul,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] ol {\n margin: 0.25rem 0 0.5rem 1.25rem;\n padding: 0;\n}\n\n/* ---------- Chat input / mention input ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] {\n flex-shrink: 0;\n display: flex;\n gap: 0.5rem;\n align-items: flex-end;\n padding: 0.75rem 1rem;\n border-top: 1px solid var(--cm-border);\n background: var(--cm-bg);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"] textarea,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] textarea {\n flex: 1;\n min-height: 40px;\n max-height: 160px;\n resize: none;\n padding: 0.5rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"] textarea:focus,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] textarea:focus {\n border-color: var(--cm-primary);\n box-shadow: 0 0 0 3px var(--cm-primary-ring);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"] textarea::placeholder,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] textarea::placeholder {\n color: var(--cm-text-muted);\n}\n\n/* ---------- Send / stop buttons ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"] {\n padding: 0.5rem 1rem;\n background: var(--cm-primary);\n color: #fff;\n border: none;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-weight: 500;\n cursor: pointer;\n transition: opacity 0.15s, transform 0.05s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"]:hover:not(:disabled) {\n opacity: 0.92;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"]:active:not(:disabled) {\n transform: translateY(1px);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"stop\"] {\n padding: 0.5rem 0.875rem;\n background: transparent;\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n font: inherit;\n cursor: pointer;\n}\n\n/* ---------- Suggestion bar ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"suggestion-bar\"] {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n padding: 0.5rem 1rem 0.25rem 1rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"suggestion-chip\"] {\n padding: 0.375rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: 9999px;\n font: inherit;\n font-size: 12px;\n color: var(--cm-text);\n cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"suggestion-chip\"]:hover {\n background: var(--cm-bubble-user);\n border-color: var(--cm-primary);\n}\n\n/* ---------- Typing indicator ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] {\n display: flex;\n gap: 4px;\n padding: 0.5rem 1rem;\n align-items: center;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] [data-element=\"dot\"] {\n width: 6px;\n height: 6px;\n background: var(--cm-text-muted);\n border-radius: 50%;\n animation: cm-chat-typing 1.4s infinite ease-in-out both;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] [data-element=\"dot\"]:nth-child(2) {\n animation-delay: 0.16s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] [data-element=\"dot\"]:nth-child(3) {\n animation-delay: 0.32s;\n}\n@keyframes cm-chat-typing {\n 0%, 80%, 100% { transform: scale(0.7); opacity: 0.5; }\n 40% { transform: scale(1); opacity: 1; }\n}\n\n/* ---------- Truncation banner ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"truncation-banner\"] {\n padding: 0.75rem 1rem;\n background: #fef9c3;\n color: #713f12;\n border-top: 1px solid #fde047;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 1rem;\n font-size: 13px;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"truncation-banner\"] [data-element=\"actions\"] {\n display: flex;\n gap: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"truncation-banner\"] button {\n padding: 0.3125rem 0.625rem;\n background: #fff;\n border: 1px solid #d4a574;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n}\n\n/* ---------- Approval cards ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] {\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.875rem 1rem;\n background: #fffbeb;\n border: 1px solid #fcd34d;\n border-radius: var(--cm-radius);\n font-size: 13px;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"] [data-element=\"header\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] [data-element=\"header\"] {\n font-weight: 500;\n color: #713f12;\n margin-bottom: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"] [data-element=\"details\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] [data-element=\"details\"] {\n background: rgba(255, 255, 255, 0.6);\n border: 1px solid rgba(252, 211, 77, 0.6);\n border-radius: var(--cm-radius-sm);\n padding: 0.5rem 0.625rem;\n margin-bottom: 0.625rem;\n font-size: 12px;\n color: #78350f;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-line\"] {\n display: flex;\n gap: 0.5rem;\n line-height: 1.5;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-label\"] {\n flex: 0 0 auto;\n min-width: 5.5rem;\n opacity: 0.75;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-label\"]::after {\n content: \":\";\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-value\"] {\n min-width: 0;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"] [data-element=\"actions\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] [data-element=\"actions\"] {\n display: flex;\n gap: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"approve\"] {\n padding: 0.375rem 0.875rem;\n background: #16a34a;\n color: #fff;\n border: none;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"approve\"]:hover:not(:disabled) {\n background: #15803d;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"reject\"] {\n padding: 0.375rem 0.875rem;\n background: #fff;\n color: #dc2626;\n border: 1px solid #fca5a5;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n}\n\n/* ---------- Mention chip ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-chip\"] {\n display: inline-flex;\n align-items: center;\n padding: 0.125rem 0.5rem;\n background: var(--cm-bubble-user);\n color: #3730a3;\n border-radius: 9999px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* ---------- Pipeline timeline ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"pipeline-timeline\"] {\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--cm-border);\n background: var(--cm-bg-muted);\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n\n/* ---------- Activity log and plan ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] {\n margin: 0 0 0.375rem;\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-summary\"] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n cursor: pointer;\n list-style: none;\n user-select: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-summary\"]::-webkit-details-marker {\n display: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"][data-state=\"running\"] [data-element=\"activity-summary\"] {\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-steps\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-items\"] {\n list-style: none;\n margin: 0.25rem 0 0;\n padding: 0 0 0 0.375rem;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-steps\"] {\n border-left: 1px solid var(--cm-border);\n margin-left: 0.375rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-step\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"] {\n display: flex;\n align-items: baseline;\n gap: 0.375rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"icon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"icon\"] {\n flex-shrink: 0;\n align-self: center;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-step\"][data-status=\"done\"] [data-element=\"icon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"][data-status=\"completed\"] [data-element=\"icon\"] {\n color: var(--cm-primary);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-step\"][data-status=\"error\"] [data-element=\"icon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"][data-state=\"error\"] [data-element=\"activity-summary\"] [data-element=\"icon\"] {\n color: #dc2626;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"detail\"] {\n opacity: 0.8;\n overflow-wrap: anywhere;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"detail\"]::before {\n content: \"\u00B7 \";\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-notice\"] {\n margin: 0.25rem 0 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"title\"] {\n font-weight: 600;\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"][data-status=\"in_progress\"] {\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"][data-status=\"pending\"] {\n opacity: 0.55;\n}\n\n/* ---------- Tool result ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"tool-result\"] {\n margin: 0.375rem 0;\n padding: 0.5rem 0.75rem;\n background: rgba(0, 0, 0, 0.03);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n\n/* ---------- Provider composer, '/' and '@' list ---------- */\n/* The wrapper above is flex, but the editor, mic and Send sit inside a bare\n <form> (classNames.input is empty by default). Without this rule the form\n shrink-wraps its contents and the editor and its list collapse to ~111px. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] > form {\n display: flex;\n flex: 1;\n min-width: 0;\n gap: 0.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-element=\"editor\"] {\n box-sizing: border-box;\n min-height: 40px;\n max-height: 160px;\n overflow-y: auto;\n overflow-wrap: anywhere;\n padding: 0.5rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n outline: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-element=\"editor\"]:focus {\n border-color: var(--cm-primary);\n box-shadow: 0 0 0 3px var(--cm-primary-ring);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-element=\"placeholder\"] {\n position: absolute;\n top: 0.5rem;\n left: 0.75rem;\n color: var(--cm-text-muted);\n pointer-events: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-component=\"mention-dropdown\"] {\n position: absolute;\n left: 0;\n right: 0;\n bottom: calc(100% + 0.25rem);\n z-index: 20;\n display: flex;\n flex-direction: column;\n max-height: min(40vh, 16rem);\n overflow-y: auto;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown-item\"] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.125rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n background: transparent;\n border: none;\n color: var(--cm-text);\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown-item\"][data-selected=\"true\"] {\n background: var(--cm-primary-tint);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown-item\"] [data-element=\"description\"] {\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n\n/* ---------- Chat interactions: entity actions and command arguments ---------- */\n/* The item keeps `width: 100%` from its own rule, so it gets a small flex basis here: with the full\n row as basis the shrink is shared by basis and squeezes the chips below their own width. The row\n wraps instead, which keeps the chips on one line beside the result and drops them below it only\n when the result cannot keep 8rem. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown\"] [data-element=\"result-row\"] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.25rem;\n padding-right: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"result-row\"] > [data-component=\"mention-dropdown-item\"] {\n flex: 1 1 8rem;\n min-width: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"entity-actions\"] {\n display: flex;\n flex: 0 0 auto;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: 0.25rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-action\"] {\n padding: 0.125rem 0.5rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: 999px;\n color: var(--cm-text);\n font: inherit;\n font-size: 12px;\n white-space: nowrap;\n cursor: pointer;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-action\"][data-selected=\"true\"] {\n background: var(--cm-primary-tint);\n border-color: var(--cm-primary);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"command-arguments\"] {\n box-sizing: border-box;\n display: flex;\n flex-wrap: wrap;\n align-items: flex-end;\n gap: 0.5rem;\n max-width: 100%;\n margin: 0 0 0.5rem;\n padding: 0.75rem;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n}\n/* The composer wrapper is one flex row and its `> form` rule (flex: 1) outranks the rule above,\n which would park the argument form beside the editor. The wrapper wraps and the form takes\n the full first row; the wrapper's gap supplies the space below it. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] {\n flex-wrap: wrap;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] > form[data-component=\"command-arguments\"] {\n flex: 1 1 100%;\n margin: 0;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n flex: 1 1 100%;\n margin: 0;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"error\"] {\n flex: 1 1 100%;\n margin: 0;\n color: var(--cm-danger);\n font-size: 12px;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"field\"] {\n position: relative;\n display: flex;\n flex: 1 1 10rem;\n flex-direction: column;\n gap: 0.25rem;\n min-width: 0;\n color: var(--cm-text-muted);\n font-size: 12px;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) input,\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) select {\n box-sizing: border-box;\n width: 100%;\n padding: 0.375rem 0.5rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n font-size: 14px;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) input:focus,\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) select:focus {\n outline: none;\n border-color: var(--cm-primary);\n box-shadow: 0 0 0 3px var(--cm-primary-ring);\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] {\n position: absolute;\n left: 0;\n right: 0;\n bottom: calc(100% + 0.25rem);\n z-index: 20;\n max-height: 12rem;\n margin: 0;\n padding: 0;\n overflow-y: auto;\n list-style: none;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] [role=\"option\"] {\n padding: 0.375rem 0.5rem;\n color: var(--cm-text);\n cursor: pointer;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] [role=\"option\"][data-selected=\"true\"] {\n background: var(--cm-primary-tint);\n}\n/* The dropdown rule for descriptions is scoped to the mention items; without this one the span runs\n on after the label (`Alice Examplealice@example.com`). */\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] [data-element=\"description\"] {\n display: block;\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] {\n display: flex;\n gap: 0.375rem;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"run\"],\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"cancel\"] {\n padding: 0.375rem 0.75rem;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 14px;\n cursor: pointer;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"run\"] {\n background: var(--cm-primary);\n border: 1px solid var(--cm-primary);\n color: #ffffff;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"cancel\"] {\n background: transparent;\n border: 1px solid var(--cm-border);\n color: var(--cm-text);\n}\n\n/* ---------- Structured clarification ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"clarification-card\"] {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n max-width: 100%;\n margin: 0.375rem 0;\n padding: 0.75rem;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"question\"] {\n margin: 0;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] {\n display: flex;\n flex-wrap: wrap;\n gap: 0.375rem;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-option\"] {\n display: inline-flex;\n flex-direction: column;\n align-items: flex-start;\n max-width: 100%;\n padding: 0.375rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: 9999px;\n color: var(--cm-text);\n font: inherit;\n font-size: 13px;\n text-align: left;\n overflow-wrap: anywhere;\n cursor: pointer;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-option\"]:disabled {\n opacity: 0.6;\n cursor: default;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"description\"] {\n font-size: 11px;\n color: var(--cm-text-muted);\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"free-text\"] {\n display: flex;\n gap: 0.375rem;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"free-text\"] input {\n flex: 1;\n min-width: 0;\n padding: 0.375rem 0.625rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-free-text\"] {\n padding: 0.375rem 0.75rem;\n background: var(--cm-primary);\n border: none;\n border-radius: var(--cm-radius-sm);\n color: #fff;\n font: inherit;\n cursor: pointer;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-free-text\"]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ---------- Voice: mic, push-to-talk, retry, recording bar ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"voice-input-addon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"retry-recording\"] {\n flex-shrink: 0;\n min-width: 40px;\n min-height: 40px;\n padding: 0 0.625rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n cursor: pointer;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n -webkit-touch-callout: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"voice-input-addon\"][data-state=\"recording\"] {\n border-color: var(--cm-danger);\n color: var(--cm-danger);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"recording-bar\"] {\n min-width: 0;\n}\n/* The inline bar is `width: 100%` (inline style). Next to the editor, mic and\n Send it would get ~100px at 375px wide, too little for the live words. A\n non-auto flex-basis beats that width, so the bar takes a row of its own\n below them (form wraps; `order` moves it behind Send, which stays beside\n the editor). The row exists only while the bar is mounted. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] > form > [data-component=\"recording-bar\"] {\n flex: 1 1 100%;\n order: 1;\n}\n\n/* ===========================================================================\n Drop-in defaults for the floating trigger button and chat window.\n These exist so <LangGraphAiChat /> / <VercelAiChat /> \"just work\" with\n zero consumer styling. Override by passing className/buttonClassName.\n =========================================================================== */\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"] {\n background: linear-gradient(135deg, var(--cm-primary) 0%, var(--cm-primary-soft) 100%);\n color: #ffffff;\n box-shadow:\n 0 10px 25px -5px var(--cm-primary-tint),\n 0 4px 10px -3px var(--cm-primary-tint),\n 0 0 0 1px rgba(255, 255, 255, 0.12) inset;\n transition: transform 150ms ease, box-shadow 150ms ease;\n font-family: var(--cm-font);\n}\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"]:hover {\n transform: translateY(-1px);\n box-shadow:\n 0 14px 30px -5px var(--cm-primary-tint),\n 0 6px 12px -3px var(--cm-primary-tint),\n 0 0 0 1px rgba(255, 255, 255, 0.16) inset;\n}\n\n[data-component=\"ai-trigger-button\"][data-dragging=\"true\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"] {\n transform: scale(1.04);\n}\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"mic-trigger\"] {\n background: rgba(255, 255, 255, 0.22) !important;\n color: #ffffff;\n transition: background 150ms ease;\n}\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"mic-trigger\"]:hover {\n background: rgba(255, 255, 255, 0.34) !important;\n}\n\n/* ---------- Chat window shell ---------- */\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-sizing: border-box;\n background: var(--cm-bg);\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow:\n 0 25px 50px -12px rgba(0, 0, 0, 0.25),\n 0 0 0 1px rgba(0, 0, 0, 0.04);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n z-index: 10000;\n font-family: var(--cm-font);\n font-size: 14px;\n}\n\n[data-component=\"chat-window\"][data-mode=\"sidebar\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n border-radius: 0;\n box-shadow: none;\n}\n[data-component=\"chat-window\"][data-mode=\"sidebar\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-window-header\"] {\n cursor: default;\n}\n[data-component=\"chat-window-sidebar-resize\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: absolute;\n inset: 0 auto 0 0;\n width: 8px;\n z-index: 11;\n cursor: ew-resize;\n touch-action: none;\n}\n[data-component=\"chat-window-sidebar-resize\"]:hover:where(:not([data-unstyled], [data-unstyled] *)),\n[data-component=\"chat-window-sidebar-resize\"]:focus-visible:where(:not([data-unstyled], [data-unstyled] *)) {\n background: var(--cm-primary-tint);\n outline: 2px solid var(--cm-primary);\n outline-offset: -2px;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 8px 0;\n height: 100%;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) span {\n writing-mode: vertical-rl;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) button {\n appearance: none;\n border: 0;\n border-radius: var(--cm-radius-sm);\n width: 32px;\n min-height: 32px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font-size: 20px;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) button:hover {\n background: var(--cm-primary-tint);\n}\n\n/* ---------- Glassmorphism theme effect ----------\n Applied when the resolved theme sets `effect: 'glass'` (e.g. the\n `liquid-glass` preset). Adds a real backdrop blur so translucent\n backgrounds read as frosted glass instead of a flat wash. */\n[data-component=\"chat-window\"][data-theme-effect=\"glass\"]:where(:not([data-unstyled], [data-unstyled] *)),\n[data-component=\"ai-chat-panel\"][data-theme-effect=\"glass\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n backdrop-filter: blur(24px) saturate(180%);\n -webkit-backdrop-filter: blur(24px) saturate(180%);\n}\n[data-component=\"ai-trigger-button\"][data-theme-effect=\"glass\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"] {\n backdrop-filter: blur(16px) saturate(180%);\n -webkit-backdrop-filter: blur(16px) saturate(180%);\n}\n\n/* ---------- Mobile: take over the whole screen ----------\n Below 640px the floating window pattern breaks down \u2014 the\n window is too small to contain a useful conversation and\n edge-resize handles/drag headers don't map to touch gestures.\n Pin to the viewport, kill the radius, and disable edge handles. */\n@media (max-width: 640px) {\n [data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: fixed !important;\n left: 0 !important;\n top: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n width: 100vw !important;\n height: 100dvh !important;\n transform: none !important;\n border: none !important;\n border-radius: 0 !important;\n box-shadow: none !important;\n max-width: none !important;\n max-height: none !important;\n }\n [data-component=\"chat-window\"][data-collapsed=\"true\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n left: auto !important;\n width: 44px !important;\n }\n [data-component=\"chat-window-resize-handle\"]:where(:not([data-unstyled], [data-unstyled] *)),\n [data-component=\"chat-window-sidebar-resize\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: none !important;\n }\n [data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n cursor: default !important;\n padding-top: max(0.75rem, env(safe-area-inset-top));\n padding-left: max(1rem, env(safe-area-inset-left));\n padding-right: max(1rem, env(safe-area-inset-right));\n }\n [data-component=\"chat-window-body\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n padding-bottom: env(safe-area-inset-bottom);\n }\n /* Hide the pill while the chat is open \u2014 on mobile we own the\n whole viewport, so the pill would overlap the input bar. */\n [data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n z-index: 9998;\n }\n}\n\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) *,\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) *::before,\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) *::after {\n box-sizing: border-box;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--cm-border);\n background: var(--cm-bg-muted);\n cursor: grab;\n user-select: none;\n flex-shrink: 0;\n}\n\n[data-component=\"chat-window-header\"]:active:where(:not([data-unstyled], [data-unstyled] *)) {\n cursor: grabbing;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n font-size: 14px;\n font-weight: 600;\n color: var(--cm-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title-wrap\"] {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n align-items: center;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n flex-shrink: 0;\n margin-left: 0.5rem;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"close\"],\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"layout\"],\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"clear\"] {\n appearance: none;\n border: none;\n background: transparent;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: var(--cm-radius-sm);\n line-height: 1;\n color: var(--cm-text-muted);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 120ms ease, color 120ms ease;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"close\"]:hover,\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"layout\"]:hover,\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"clear\"]:hover:not(:disabled) {\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"clear\"]:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n/* ---------- Session switcher ---------- */\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n min-width: 0;\n font-family: var(--cm-font);\n pointer-events: none;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"],\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"popover\"] {\n pointer-events: auto;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"] {\n appearance: none;\n border: 1px solid transparent;\n background: transparent;\n padding: 0.25rem 0.5rem;\n border-radius: var(--cm-radius-sm);\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n max-width: 100%;\n color: var(--cm-text);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"]:hover {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"][data-open]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"] {\n background: var(--cm-primary-tint);\n border-color: var(--cm-primary);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger-title\"] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 14rem;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"popover\"] {\n position: absolute;\n top: calc(100% + 0.375rem);\n left: 0;\n min-width: 16rem;\n max-width: 22rem;\n max-height: 22rem;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(0, 0, 0, 0.04);\n z-index: 10001;\n font-weight: 400;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"new-session\"] {\n appearance: none;\n border: none;\n background: transparent;\n width: 100%;\n text-align: left;\n padding: 0.625rem 0.875rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 13px;\n font-weight: 600;\n color: var(--cm-primary);\n cursor: pointer;\n border-bottom: 1px solid var(--cm-border);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"new-session\"]:hover {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"new-session\"] [data-element=\"plus\"] {\n display: inline-flex;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: 9999px;\n align-items: center;\n justify-content: center;\n background: var(--cm-primary);\n color: #ffffff;\n font-size: 14px;\n line-height: 1;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-list\"] {\n flex: 1 1 auto;\n overflow-y: auto;\n padding: 0.25rem 0;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"empty\"] {\n padding: 1rem 0.875rem;\n color: var(--cm-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.875rem;\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"]:hover {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"][data-active] {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-main\"] {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-title\"] {\n font-size: 13px;\n font-weight: 600;\n color: var(--cm-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-subtitle\"] {\n font-size: 11px;\n color: var(--cm-text-muted);\n margin-top: 0.125rem;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-delete\"],\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-edit\"] {\n appearance: none;\n border: none;\n background: transparent;\n width: 1.5rem;\n height: 1.5rem;\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text-muted);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 120ms ease, background 120ms ease, color 120ms ease;\n flex-shrink: 0;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"]:hover [data-element=\"row-delete\"],\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"]:hover [data-element=\"row-edit\"] {\n opacity: 1;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-edit\"]:hover {\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-delete\"]:hover {\n background: rgba(220, 38, 38, 0.1);\n color: var(--cm-danger);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"][data-editing] {\n background: var(--cm-primary-tint);\n cursor: text;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-title-input\"] {\n width: 100%;\n appearance: none;\n background: transparent;\n border: none;\n outline: none;\n padding: 0;\n margin: 0;\n font: inherit;\n font-size: 13px;\n font-weight: 600;\n color: var(--cm-text);\n caret-color: var(--cm-primary);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-title-input\"]::placeholder {\n color: var(--cm-text-muted);\n}\n\n/* ---------- Confirm dialog ---------- */\n\n[data-component=\"confirm-dialog-backdrop\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: fixed;\n inset: 0;\n z-index: 10010;\n background: rgba(0, 0, 0, 0.55);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n font-family: var(--cm-font);\n animation: cm-confirm-fade 140ms ease-out;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n background: var(--cm-bg);\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow:\n 0 25px 50px -12px rgba(0, 0, 0, 0.6),\n 0 0 0 1px rgba(255, 255, 255, 0.04);\n padding: 1.25rem 1.25rem 1rem;\n min-width: min(22rem, calc(100vw - 2rem));\n max-width: 26rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n animation: cm-confirm-pop 160ms cubic-bezier(0.2, 0.9, 0.3, 1.1);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n font-size: 15px;\n font-weight: 600;\n color: var(--cm-text);\n line-height: 1.4;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"message\"] {\n font-size: 13px;\n color: var(--cm-text-muted);\n line-height: 1.5;\n margin-bottom: 0.25rem;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] {\n display: flex;\n justify-content: flex-end;\n gap: 0.5rem;\n margin-top: 0.75rem;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] button {\n appearance: none;\n border: 1px solid var(--cm-border);\n background: transparent;\n color: var(--cm-text);\n padding: 0.5rem 1rem;\n border-radius: var(--cm-radius-sm);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease, color 120ms ease, transform 120ms ease;\n font-family: inherit;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"cancel\"]:hover {\n background: var(--cm-primary-tint);\n border-color: var(--cm-primary);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"] {\n background: var(--cm-primary);\n border-color: var(--cm-primary);\n color: #ffffff;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"]:hover:not(:disabled) {\n filter: brightness(1.1);\n transform: translateY(-1px);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"][data-destructive] {\n background: var(--cm-danger);\n border-color: var(--cm-danger);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n@keyframes cm-confirm-fade {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes cm-confirm-pop {\n from { opacity: 0; transform: scale(0.95) translateY(6px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n[data-component=\"chat-window-body\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* When ai-chat-panel is a direct child of chat-window-body, drop its own\n border/radius/shadow so the window shell owns the framing. */\n[data-component=\"chat-window-body\"]:where(:not([data-unstyled], [data-unstyled] *)) > [data-component=\"ai-chat-panel\"] {\n border: none;\n border-radius: 0;\n box-shadow: none;\n min-height: 0;\n height: 100%;\n}\n\n/* ---------- Approval reminder ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-reminder\"] {\n margin: 0 1rem 0.5rem;\n padding: 0.5rem 0.75rem;\n border-radius: var(--cm-radius-sm);\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n font-size: 0.8125rem;\n}\n\n/* ---------------------------------------------------------------------------\n AssistantShell \u2014 docked sidebar or detached window. The handle geometry\n is inline, so it also works unstyled; these rules are only the look.\n --------------------------------------------------------------------------- */\n[data-component=\"assistant-shell\"][data-floating-gesture]:where(:not([data-unstyled], [data-unstyled] *)) { transition: none; will-change: transform, width, height; }\n@media (pointer: coarse) {\n [data-component=\"assistant-shell-window-handle\"]:where(:not([data-unstyled], [data-unstyled] *)):is([data-resize-edge=\"n\"], [data-resize-edge=\"s\"]) { height: 16px !important; }\n [data-component=\"assistant-shell-window-handle\"]:where(:not([data-unstyled], [data-unstyled] *)):is([data-resize-edge=\"e\"], [data-resize-edge=\"w\"]) { width: 16px !important; }\n [data-component=\"assistant-shell-window-handle\"]:where(:not([data-unstyled], [data-unstyled] *)):is([data-resize-edge=\"ne\"], [data-resize-edge=\"nw\"], [data-resize-edge=\"se\"], [data-resize-edge=\"sw\"]) { width: 28px !important; height: 28px !important; }\n}\n\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-sizing: border-box;\n z-index: 60;\n background: var(--cm-bg);\n color: var(--cm-text);\n font-family: var(--cm-font);\n border-left: 1px solid var(--cm-border);\n}\n[data-component=\"assistant-shell\"][data-mode=\"floating\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow: 0 12px 32px -12px rgba(17, 24, 39, 0.25);\n overflow: hidden;\n}\n[data-component=\"assistant-shell\"][data-floating-gesture=\"move\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-shadow: 0 16px 40px -12px rgba(17, 24, 39, 0.35);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"header\"] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n height: 2.75rem;\n flex-shrink: 0;\n padding: 0 0.75rem;\n border-bottom: 1px solid var(--cm-border);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"header\"] > [data-element=\"icon\"] {\n display: inline-flex;\n color: var(--cm-primary);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n flex: 1 1 0%;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 0.875rem;\n font-weight: 600;\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) :is(header[data-element=\"header\"], [data-element=\"rail\"]) > [data-action] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n border: 0;\n border-radius: var(--cm-radius-sm);\n background: transparent;\n color: var(--cm-text-muted);\n cursor: pointer;\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) :is(header[data-element=\"header\"], [data-element=\"rail\"]) > [data-action]:hover {\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"rail\"] {\n display: flex;\n flex-direction: column;\n align-items: center;\n height: 100%;\n padding: 0.5rem 0;\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"rail\"] > [data-action=\"expand\"] {\n flex: 1 1 0%;\n width: 100%;\n height: auto;\n flex-direction: column;\n justify-content: flex-start;\n gap: 1rem;\n padding-top: 0.25rem;\n font-size: 0.75rem;\n font-weight: 500;\n}\n[data-component=\"assistant-shell-resize\"]:where(:not([data-unstyled], [data-unstyled] *)):is(:hover, :focus-visible, [data-dragging]) {\n background: linear-gradient(to right, transparent 3px, var(--cm-primary) 3px, var(--cm-primary) 5px, transparent 5px);\n outline: none;\n}\n[data-component=\"assistant-bubble\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: fixed;\n right: 1rem;\n bottom: 1rem;\n z-index: 40;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n border: 0;\n border-radius: 9999px;\n background: var(--cm-primary);\n color: #fff;\n box-shadow: 0 8px 20px -8px rgba(17, 24, 39, 0.4);\n cursor: pointer;\n}\n[data-component=\"assistant-toggle\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 0;\n border-radius: var(--cm-radius-sm);\n background: transparent;\n color: var(--cm-text);\n font: inherit;\n font-size: 0.875rem;\n cursor: pointer;\n}\n[data-component=\"assistant-toggle\"]:where(:not([data-unstyled], [data-unstyled] *)):is(:hover, [aria-pressed=\"true\"]) {\n background: var(--cm-primary-tint);\n}\n";
|
|
1
|
+
export declare const CHAT_STYLES = "/* glirastes \u2014 default chat panel styles.\n Auto-injected when you render <AiChat /> or <AiChatPanel />.\n Themes: every color / radius / font below is driven by CSS variables\n that can be overridden per-instance via the `theme` prop, which emits\n inline `--cm-*` vars on the root elements. The defaults below act as\n the fallback when no `theme` prop is given. */\n\n:where(\n [data-component=\"ai-chat-panel\"],\n [data-component=\"chat-window\"],\n [data-component=\"ai-trigger-button\"],\n [data-component=\"assistant-shell\"],\n [data-component=\"assistant-bubble\"],\n [data-component=\"assistant-toggle\"]\n):where(:not([data-unstyled], [data-unstyled] *)) {\n --cm-primary: #6366f1;\n --cm-primary-soft: #818cf8;\n --cm-primary-tint: rgba(99, 102, 241, 0.12);\n --cm-primary-ring: rgba(99, 102, 241, 0.18);\n --cm-bg: #ffffff;\n --cm-bg-muted: #f9fafb;\n --cm-bubble-user: #e0e7ff;\n --cm-bubble-assistant: #f3f4f6;\n --cm-border: #e5e7eb;\n --cm-text: #111827;\n --cm-text-muted: #6b7280;\n --cm-danger: #dc2626;\n --cm-radius: 0.875rem;\n --cm-radius-sm: 0.5rem;\n --cm-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 520px;\n max-height: 100%;\n background: var(--cm-bg);\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n overflow: hidden;\n font-family: var(--cm-font);\n font-size: 14px;\n line-height: 1.5;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.03);\n}\n\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) *,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) *::before,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) *::after {\n box-sizing: border-box;\n}\n\n/* ---------- Error banner ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"error-banner\"] {\n padding: 0.75rem 1rem;\n background: #fef2f2;\n color: #991b1b;\n border-bottom: 1px solid #fecaca;\n font-size: 13px;\n}\n\n/* ---------- Empty state ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"empty-state\"] {\n flex: 1;\n display: grid;\n place-items: center;\n padding: 2rem;\n color: var(--cm-text-muted);\n text-align: center;\n}\n\n/* ---------- Message list ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-list\"] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n scroll-behavior: smooth;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-list\"] > [data-action=\"load-more\"] {\n align-self: center;\n padding: 0.375rem 0.75rem;\n font: inherit;\n font-size: 12px;\n background: transparent;\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text-muted);\n cursor: pointer;\n}\n\n/* ---------- Message bubble ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"] {\n max-width: 85%;\n padding: 0.625rem 0.875rem;\n border-radius: var(--cm-radius);\n word-wrap: break-word;\n overflow-wrap: anywhere;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"][data-role=\"user\"] {\n align-self: flex-end;\n background: var(--cm-bubble-user);\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"][data-role=\"assistant\"] {\n align-self: flex-start;\n background: var(--cm-bubble-assistant);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"message-bubble\"][data-role=\"system\"] {\n align-self: center;\n background: var(--cm-bg-muted);\n color: var(--cm-text-muted);\n font-style: italic;\n font-size: 13px;\n}\n\n/* ---------- Markdown content ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] p {\n margin: 0 0 0.5rem 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] p:last-child {\n margin: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] pre {\n background: rgba(0, 0, 0, 0.05);\n padding: 0.625rem 0.75rem;\n border-radius: var(--cm-radius-sm);\n overflow-x: auto;\n font-size: 12px;\n margin: 0.5rem 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] code {\n background: rgba(0, 0, 0, 0.06);\n padding: 0.125rem 0.25rem;\n border-radius: 3px;\n font-size: 0.9em;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] pre code {\n background: transparent;\n padding: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] ul,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"markdown\"] ol {\n margin: 0.25rem 0 0.5rem 1.25rem;\n padding: 0;\n}\n\n/* ---------- Chat input / mention input ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] {\n flex-shrink: 0;\n display: flex;\n gap: 0.5rem;\n align-items: flex-end;\n padding: 0.75rem 1rem;\n border-top: 1px solid var(--cm-border);\n background: var(--cm-bg);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"] textarea,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] textarea {\n flex: 1;\n min-height: 40px;\n max-height: 160px;\n resize: none;\n padding: 0.5rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"] textarea:focus,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] textarea:focus {\n border-color: var(--cm-primary);\n box-shadow: 0 0 0 3px var(--cm-primary-ring);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-input\"] textarea::placeholder,\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"] textarea::placeholder {\n color: var(--cm-text-muted);\n}\n\n/* ---------- Send / stop buttons ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"] {\n padding: 0.5rem 1rem;\n background: var(--cm-primary);\n color: #fff;\n border: none;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-weight: 500;\n cursor: pointer;\n transition: opacity 0.15s, transform 0.05s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"]:hover:not(:disabled) {\n opacity: 0.92;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"]:active:not(:disabled) {\n transform: translateY(1px);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"send\"]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"stop\"] {\n padding: 0.5rem 0.875rem;\n background: transparent;\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n font: inherit;\n cursor: pointer;\n}\n\n/* ---------- Suggestion bar ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"suggestion-bar\"] {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n padding: 0.5rem 1rem 0.25rem 1rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"suggestion-chip\"] {\n padding: 0.375rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: 9999px;\n font: inherit;\n font-size: 12px;\n color: var(--cm-text);\n cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"suggestion-chip\"]:hover {\n background: var(--cm-bubble-user);\n border-color: var(--cm-primary);\n}\n\n/* ---------- Typing indicator ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] {\n display: flex;\n gap: 4px;\n padding: 0.5rem 1rem;\n align-items: center;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] [data-element=\"dot\"] {\n width: 6px;\n height: 6px;\n background: var(--cm-text-muted);\n border-radius: 50%;\n animation: cm-chat-typing 1.4s infinite ease-in-out both;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] [data-element=\"dot\"]:nth-child(2) {\n animation-delay: 0.16s;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"typing-indicator\"] [data-element=\"dot\"]:nth-child(3) {\n animation-delay: 0.32s;\n}\n@keyframes cm-chat-typing {\n 0%, 80%, 100% { transform: scale(0.7); opacity: 0.5; }\n 40% { transform: scale(1); opacity: 1; }\n}\n\n/* ---------- Truncation banner ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"truncation-banner\"] {\n padding: 0.75rem 1rem;\n background: #fef9c3;\n color: #713f12;\n border-top: 1px solid #fde047;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 1rem;\n font-size: 13px;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"truncation-banner\"] [data-element=\"actions\"] {\n display: flex;\n gap: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"truncation-banner\"] button {\n padding: 0.3125rem 0.625rem;\n background: #fff;\n border: 1px solid #d4a574;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n}\n\n/* ---------- Approval cards ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] {\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.875rem 1rem;\n background: #fffbeb;\n border: 1px solid #fcd34d;\n border-radius: var(--cm-radius);\n font-size: 13px;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"] [data-element=\"header\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] [data-element=\"header\"] {\n font-weight: 500;\n color: #713f12;\n margin-bottom: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"] [data-element=\"details\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] [data-element=\"details\"] {\n background: rgba(255, 255, 255, 0.6);\n border: 1px solid rgba(252, 211, 77, 0.6);\n border-radius: var(--cm-radius-sm);\n padding: 0.5rem 0.625rem;\n margin-bottom: 0.625rem;\n font-size: 12px;\n color: #78350f;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-line\"] {\n display: flex;\n gap: 0.5rem;\n line-height: 1.5;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-label\"] {\n flex: 0 0 auto;\n min-width: 5.5rem;\n opacity: 0.75;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-label\"]::after {\n content: \":\";\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-value\"] {\n min-width: 0;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-items\"] {\n margin: 0;\n padding: 0 0 0 1.125rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-text\"][data-collapsed] {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow: hidden;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-toggle\"] {\n display: block;\n margin-top: 0.125rem;\n padding: 0;\n background: none;\n border: none;\n color: inherit;\n font: inherit;\n font-weight: 500;\n text-decoration: underline;\n cursor: pointer;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"detail-toggle\"]:focus-visible {\n outline: 2px solid var(--cm-primary);\n outline-offset: 2px;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-card\"] [data-element=\"actions\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"bulk-approval-card\"] [data-element=\"actions\"] {\n display: flex;\n gap: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"approve\"] {\n padding: 0.375rem 0.875rem;\n background: #16a34a;\n color: #fff;\n border: none;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"approve\"]:hover:not(:disabled) {\n background: #15803d;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"reject\"] {\n padding: 0.375rem 0.875rem;\n background: #fff;\n color: #dc2626;\n border: 1px solid #fca5a5;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n}\n\n/* ---------- Mention chip ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-chip\"] {\n display: inline-flex;\n align-items: center;\n padding: 0.125rem 0.5rem;\n background: var(--cm-bubble-user);\n color: #3730a3;\n border-radius: 9999px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* ---------- Pipeline timeline ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"pipeline-timeline\"] {\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--cm-border);\n background: var(--cm-bg-muted);\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n\n/* ---------- Activity log and plan ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] {\n margin: 0 0 0.375rem;\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-summary\"] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n cursor: pointer;\n list-style: none;\n user-select: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-summary\"]::-webkit-details-marker {\n display: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"][data-state=\"running\"] [data-element=\"activity-summary\"] {\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-steps\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-items\"] {\n list-style: none;\n margin: 0.25rem 0 0;\n padding: 0 0 0 0.375rem;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-steps\"] {\n border-left: 1px solid var(--cm-border);\n margin-left: 0.375rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-step\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"] {\n display: flex;\n align-items: baseline;\n gap: 0.375rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"icon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"icon\"] {\n flex-shrink: 0;\n align-self: center;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-step\"][data-status=\"done\"] [data-element=\"icon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"][data-status=\"completed\"] [data-element=\"icon\"] {\n color: var(--cm-primary);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-step\"][data-status=\"error\"] [data-element=\"icon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"][data-state=\"error\"] [data-element=\"activity-summary\"] [data-element=\"icon\"] {\n color: #dc2626;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"detail\"] {\n opacity: 0.8;\n overflow-wrap: anywhere;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"detail\"]::before {\n content: \"\u00B7 \";\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"activity-log\"] [data-element=\"activity-notice\"] {\n margin: 0.25rem 0 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"title\"] {\n font-weight: 600;\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"][data-status=\"in_progress\"] {\n color: var(--cm-text);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"plan-checklist\"] [data-element=\"plan-item\"][data-status=\"pending\"] {\n opacity: 0.55;\n}\n\n/* ---------- Tool result ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"tool-result\"] {\n margin: 0.375rem 0;\n padding: 0.5rem 0.75rem;\n background: rgba(0, 0, 0, 0.03);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n\n/* ---------- Provider composer, '/' and '@' list ---------- */\n/* The wrapper above is flex, but the editor, mic and Send sit inside a bare\n <form> (classNames.input is empty by default). Without this rule the form\n shrink-wraps its contents and the editor and its list collapse to ~111px. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] > form {\n display: flex;\n flex: 1;\n min-width: 0;\n gap: 0.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-element=\"editor\"] {\n box-sizing: border-box;\n min-height: 40px;\n max-height: 160px;\n overflow-y: auto;\n overflow-wrap: anywhere;\n padding: 0.5rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n outline: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-element=\"editor\"]:focus {\n border-color: var(--cm-primary);\n box-shadow: 0 0 0 3px var(--cm-primary-ring);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-element=\"placeholder\"] {\n position: absolute;\n top: 0.5rem;\n left: 0.75rem;\n color: var(--cm-text-muted);\n pointer-events: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"rich-mention-input\"] [data-component=\"mention-dropdown\"] {\n position: absolute;\n left: 0;\n right: 0;\n bottom: calc(100% + 0.25rem);\n z-index: 20;\n display: flex;\n flex-direction: column;\n max-height: min(40vh, 16rem);\n overflow-y: auto;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown-item\"] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.125rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n background: transparent;\n border: none;\n color: var(--cm-text);\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown-item\"][data-selected=\"true\"] {\n background: var(--cm-primary-tint);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown-item\"] [data-element=\"description\"] {\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n\n/* ---------- Chat interactions: entity actions and command arguments ---------- */\n/* The item keeps `width: 100%` from its own rule, so it gets a small flex basis here: with the full\n row as basis the shrink is shared by basis and squeezes the chips below their own width. The row\n wraps instead, which keeps the chips on one line beside the result and drops them below it only\n when the result cannot keep 8rem. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-dropdown\"] [data-element=\"result-row\"] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.25rem;\n padding-right: 0.5rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"result-row\"] > [data-component=\"mention-dropdown-item\"] {\n flex: 1 1 8rem;\n min-width: 0;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"entity-actions\"] {\n display: flex;\n flex: 0 0 auto;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: 0.25rem;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-action\"] {\n padding: 0.125rem 0.5rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: 999px;\n color: var(--cm-text);\n font: inherit;\n font-size: 12px;\n white-space: nowrap;\n cursor: pointer;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-action\"][data-selected=\"true\"] {\n background: var(--cm-primary-tint);\n border-color: var(--cm-primary);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"command-arguments\"] {\n box-sizing: border-box;\n display: flex;\n flex-wrap: wrap;\n align-items: flex-end;\n gap: 0.5rem;\n max-width: 100%;\n margin: 0 0 0.5rem;\n padding: 0.75rem;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n}\n/* The composer wrapper is one flex row and its `> form` rule (flex: 1) outranks the rule above,\n which would park the argument form beside the editor. The wrapper wraps and the form takes\n the full first row; the wrapper's gap supplies the space below it. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] {\n flex-wrap: wrap;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] > form[data-component=\"command-arguments\"] {\n flex: 1 1 100%;\n margin: 0;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n flex: 1 1 100%;\n margin: 0;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"error\"] {\n flex: 1 1 100%;\n margin: 0;\n color: var(--cm-danger);\n font-size: 12px;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"field\"] {\n position: relative;\n display: flex;\n flex: 1 1 10rem;\n flex-direction: column;\n gap: 0.25rem;\n min-width: 0;\n color: var(--cm-text-muted);\n font-size: 12px;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) input,\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) select {\n box-sizing: border-box;\n width: 100%;\n padding: 0.375rem 0.5rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n font-size: 14px;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) input:focus,\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) select:focus {\n outline: none;\n border-color: var(--cm-primary);\n box-shadow: 0 0 0 3px var(--cm-primary-ring);\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] {\n position: absolute;\n left: 0;\n right: 0;\n bottom: calc(100% + 0.25rem);\n z-index: 20;\n max-height: 12rem;\n margin: 0;\n padding: 0;\n overflow-y: auto;\n list-style: none;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] [role=\"option\"] {\n padding: 0.375rem 0.5rem;\n color: var(--cm-text);\n cursor: pointer;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] [role=\"option\"][data-selected=\"true\"] {\n background: var(--cm-primary-tint);\n}\n/* The dropdown rule for descriptions is scoped to the mention items; without this one the span runs\n on after the label (`Alice Examplealice@example.com`). */\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] [data-element=\"description\"] {\n display: block;\n font-size: 12px;\n color: var(--cm-text-muted);\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] {\n display: flex;\n gap: 0.375rem;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"run\"],\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"cancel\"] {\n padding: 0.375rem 0.75rem;\n border-radius: var(--cm-radius-sm);\n font: inherit;\n font-size: 14px;\n cursor: pointer;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"run\"] {\n background: var(--cm-primary);\n border: 1px solid var(--cm-primary);\n color: #ffffff;\n}\n[data-component=\"command-arguments\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"cancel\"] {\n background: transparent;\n border: 1px solid var(--cm-border);\n color: var(--cm-text);\n}\n\n/* ---------- Structured clarification ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"clarification-card\"] {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n max-width: 100%;\n margin: 0.375rem 0;\n padding: 0.75rem;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"question\"] {\n margin: 0;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"options\"] {\n display: flex;\n flex-wrap: wrap;\n gap: 0.375rem;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-option\"] {\n display: inline-flex;\n flex-direction: column;\n align-items: flex-start;\n max-width: 100%;\n padding: 0.375rem 0.75rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: 9999px;\n color: var(--cm-text);\n font: inherit;\n font-size: 13px;\n text-align: left;\n overflow-wrap: anywhere;\n cursor: pointer;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-option\"]:disabled {\n opacity: 0.6;\n cursor: default;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"description\"] {\n font-size: 11px;\n color: var(--cm-text-muted);\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"free-text\"] {\n display: flex;\n gap: 0.375rem;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"free-text\"] input {\n flex: 1;\n min-width: 0;\n padding: 0.375rem 0.625rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-free-text\"] {\n padding: 0.375rem 0.75rem;\n background: var(--cm-primary);\n border: none;\n border-radius: var(--cm-radius-sm);\n color: #fff;\n font: inherit;\n cursor: pointer;\n}\n[data-component=\"clarification-card\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"answer-free-text\"]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ---------- Voice: mic, push-to-talk, retry, recording bar ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"voice-input-addon\"],\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"retry-recording\"] {\n flex-shrink: 0;\n min-width: 40px;\n min-height: 40px;\n padding: 0 0.625rem;\n background: var(--cm-bg-muted);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text);\n font: inherit;\n cursor: pointer;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n -webkit-touch-callout: none;\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"voice-input-addon\"][data-state=\"recording\"] {\n border-color: var(--cm-danger);\n color: var(--cm-danger);\n}\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"recording-bar\"] {\n min-width: 0;\n}\n/* The inline bar is `width: 100%` (inline style). Next to the editor, mic and\n Send it would get ~100px at 375px wide, too little for the live words. A\n non-auto flex-basis beats that width, so the bar takes a row of its own\n below them (form wraps; `order` moves it behind Send, which stays beside\n the editor). The row exists only while the bar is mounted. */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"mention-input\"][data-mode=\"providers\"] > form > [data-component=\"recording-bar\"] {\n flex: 1 1 100%;\n order: 1;\n}\n\n/* ===========================================================================\n Drop-in defaults for the floating trigger button and chat window.\n These exist so <LangGraphAiChat /> / <VercelAiChat /> \"just work\" with\n zero consumer styling. Override by passing className/buttonClassName.\n =========================================================================== */\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"] {\n background: linear-gradient(135deg, var(--cm-primary) 0%, var(--cm-primary-soft) 100%);\n color: #ffffff;\n box-shadow:\n 0 10px 25px -5px var(--cm-primary-tint),\n 0 4px 10px -3px var(--cm-primary-tint),\n 0 0 0 1px rgba(255, 255, 255, 0.12) inset;\n transition: transform 150ms ease, box-shadow 150ms ease;\n font-family: var(--cm-font);\n}\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"]:hover {\n transform: translateY(-1px);\n box-shadow:\n 0 14px 30px -5px var(--cm-primary-tint),\n 0 6px 12px -3px var(--cm-primary-tint),\n 0 0 0 1px rgba(255, 255, 255, 0.16) inset;\n}\n\n[data-component=\"ai-trigger-button\"][data-dragging=\"true\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"] {\n transform: scale(1.04);\n}\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"mic-trigger\"] {\n background: rgba(255, 255, 255, 0.22) !important;\n color: #ffffff;\n transition: background 150ms ease;\n}\n\n[data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"mic-trigger\"]:hover {\n background: rgba(255, 255, 255, 0.34) !important;\n}\n\n/* ---------- Chat window shell ---------- */\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-sizing: border-box;\n background: var(--cm-bg);\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow:\n 0 25px 50px -12px rgba(0, 0, 0, 0.25),\n 0 0 0 1px rgba(0, 0, 0, 0.04);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n z-index: 10000;\n font-family: var(--cm-font);\n font-size: 14px;\n}\n\n[data-component=\"chat-window\"][data-mode=\"sidebar\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n border-radius: 0;\n box-shadow: none;\n}\n[data-component=\"chat-window\"][data-mode=\"sidebar\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"chat-window-header\"] {\n cursor: default;\n}\n[data-component=\"chat-window-sidebar-resize\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: absolute;\n inset: 0 auto 0 0;\n width: 8px;\n z-index: 11;\n cursor: ew-resize;\n touch-action: none;\n}\n[data-component=\"chat-window-sidebar-resize\"]:hover:where(:not([data-unstyled], [data-unstyled] *)),\n[data-component=\"chat-window-sidebar-resize\"]:focus-visible:where(:not([data-unstyled], [data-unstyled] *)) {\n background: var(--cm-primary-tint);\n outline: 2px solid var(--cm-primary);\n outline-offset: -2px;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 8px 0;\n height: 100%;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) span {\n writing-mode: vertical-rl;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) button {\n appearance: none;\n border: 0;\n border-radius: var(--cm-radius-sm);\n width: 32px;\n min-height: 32px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font-size: 20px;\n}\n[data-component=\"chat-window-rail\"]:where(:not([data-unstyled], [data-unstyled] *)) button:hover {\n background: var(--cm-primary-tint);\n}\n\n/* ---------- Glassmorphism theme effect ----------\n Applied when the resolved theme sets `effect: 'glass'` (e.g. the\n `liquid-glass` preset). Adds a real backdrop blur so translucent\n backgrounds read as frosted glass instead of a flat wash. */\n[data-component=\"chat-window\"][data-theme-effect=\"glass\"]:where(:not([data-unstyled], [data-unstyled] *)),\n[data-component=\"ai-chat-panel\"][data-theme-effect=\"glass\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n backdrop-filter: blur(24px) saturate(180%);\n -webkit-backdrop-filter: blur(24px) saturate(180%);\n}\n[data-component=\"ai-trigger-button\"][data-theme-effect=\"glass\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"button-pill\"] {\n backdrop-filter: blur(16px) saturate(180%);\n -webkit-backdrop-filter: blur(16px) saturate(180%);\n}\n\n/* ---------- Mobile: take over the whole screen ----------\n Below 640px the floating window pattern breaks down \u2014 the\n window is too small to contain a useful conversation and\n edge-resize handles/drag headers don't map to touch gestures.\n Pin to the viewport, kill the radius, and disable edge handles. */\n@media (max-width: 640px) {\n [data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: fixed !important;\n left: 0 !important;\n top: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n width: 100vw !important;\n height: 100dvh !important;\n transform: none !important;\n border: none !important;\n border-radius: 0 !important;\n box-shadow: none !important;\n max-width: none !important;\n max-height: none !important;\n }\n [data-component=\"chat-window\"][data-collapsed=\"true\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n left: auto !important;\n width: 44px !important;\n }\n [data-component=\"chat-window-resize-handle\"]:where(:not([data-unstyled], [data-unstyled] *)),\n [data-component=\"chat-window-sidebar-resize\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: none !important;\n }\n [data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n cursor: default !important;\n padding-top: max(0.75rem, env(safe-area-inset-top));\n padding-left: max(1rem, env(safe-area-inset-left));\n padding-right: max(1rem, env(safe-area-inset-right));\n }\n [data-component=\"chat-window-body\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n padding-bottom: env(safe-area-inset-bottom);\n }\n /* Hide the pill while the chat is open \u2014 on mobile we own the\n whole viewport, so the pill would overlap the input bar. */\n [data-component=\"ai-trigger-button\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n z-index: 9998;\n }\n}\n\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) *,\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) *::before,\n[data-component=\"chat-window\"]:where(:not([data-unstyled], [data-unstyled] *)) *::after {\n box-sizing: border-box;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--cm-border);\n background: var(--cm-bg-muted);\n cursor: grab;\n user-select: none;\n flex-shrink: 0;\n}\n\n[data-component=\"chat-window-header\"]:active:where(:not([data-unstyled], [data-unstyled] *)) {\n cursor: grabbing;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n font-size: 14px;\n font-weight: 600;\n color: var(--cm-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title-wrap\"] {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n align-items: center;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n flex-shrink: 0;\n margin-left: 0.5rem;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"close\"],\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"layout\"],\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"clear\"] {\n appearance: none;\n border: none;\n background: transparent;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: var(--cm-radius-sm);\n line-height: 1;\n color: var(--cm-text-muted);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 120ms ease, color 120ms ease;\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"close\"]:hover,\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"layout\"]:hover,\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"clear\"]:hover:not(:disabled) {\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n}\n\n[data-component=\"chat-window-header\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-action=\"clear\"]:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n/* ---------- Session switcher ---------- */\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n min-width: 0;\n font-family: var(--cm-font);\n pointer-events: none;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"],\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"popover\"] {\n pointer-events: auto;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"] {\n appearance: none;\n border: 1px solid transparent;\n background: transparent;\n padding: 0.25rem 0.5rem;\n border-radius: var(--cm-radius-sm);\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n max-width: 100%;\n color: var(--cm-text);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"]:hover {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"][data-open]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger\"] {\n background: var(--cm-primary-tint);\n border-color: var(--cm-primary);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"trigger-title\"] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 14rem;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"popover\"] {\n position: absolute;\n top: calc(100% + 0.375rem);\n left: 0;\n min-width: 16rem;\n max-width: 22rem;\n max-height: 22rem;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n background: var(--cm-bg);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(0, 0, 0, 0.04);\n z-index: 10001;\n font-weight: 400;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"new-session\"] {\n appearance: none;\n border: none;\n background: transparent;\n width: 100%;\n text-align: left;\n padding: 0.625rem 0.875rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 13px;\n font-weight: 600;\n color: var(--cm-primary);\n cursor: pointer;\n border-bottom: 1px solid var(--cm-border);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"new-session\"]:hover {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"new-session\"] [data-element=\"plus\"] {\n display: inline-flex;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: 9999px;\n align-items: center;\n justify-content: center;\n background: var(--cm-primary);\n color: #ffffff;\n font-size: 14px;\n line-height: 1;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-list\"] {\n flex: 1 1 auto;\n overflow-y: auto;\n padding: 0.25rem 0;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"empty\"] {\n padding: 1rem 0.875rem;\n color: var(--cm-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.875rem;\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"]:hover {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"][data-active] {\n background: var(--cm-primary-tint);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-main\"] {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-title\"] {\n font-size: 13px;\n font-weight: 600;\n color: var(--cm-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-subtitle\"] {\n font-size: 11px;\n color: var(--cm-text-muted);\n margin-top: 0.125rem;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-delete\"],\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-edit\"] {\n appearance: none;\n border: none;\n background: transparent;\n width: 1.5rem;\n height: 1.5rem;\n border-radius: var(--cm-radius-sm);\n color: var(--cm-text-muted);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 120ms ease, background 120ms ease, color 120ms ease;\n flex-shrink: 0;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"]:hover [data-element=\"row-delete\"],\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"]:hover [data-element=\"row-edit\"] {\n opacity: 1;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-edit\"]:hover {\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-delete\"]:hover {\n background: rgba(220, 38, 38, 0.1);\n color: var(--cm-danger);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"session-row\"][data-editing] {\n background: var(--cm-primary-tint);\n cursor: text;\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-title-input\"] {\n width: 100%;\n appearance: none;\n background: transparent;\n border: none;\n outline: none;\n padding: 0;\n margin: 0;\n font: inherit;\n font-size: 13px;\n font-weight: 600;\n color: var(--cm-text);\n caret-color: var(--cm-primary);\n}\n\n[data-component=\"session-switcher\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"row-title-input\"]::placeholder {\n color: var(--cm-text-muted);\n}\n\n/* ---------- Confirm dialog ---------- */\n\n[data-component=\"confirm-dialog-backdrop\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: fixed;\n inset: 0;\n z-index: 10010;\n background: rgba(0, 0, 0, 0.55);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n font-family: var(--cm-font);\n animation: cm-confirm-fade 140ms ease-out;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n background: var(--cm-bg);\n color: var(--cm-text);\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow:\n 0 25px 50px -12px rgba(0, 0, 0, 0.6),\n 0 0 0 1px rgba(255, 255, 255, 0.04);\n padding: 1.25rem 1.25rem 1rem;\n min-width: min(22rem, calc(100vw - 2rem));\n max-width: 26rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n animation: cm-confirm-pop 160ms cubic-bezier(0.2, 0.9, 0.3, 1.1);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n font-size: 15px;\n font-weight: 600;\n color: var(--cm-text);\n line-height: 1.4;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"message\"] {\n font-size: 13px;\n color: var(--cm-text-muted);\n line-height: 1.5;\n margin-bottom: 0.25rem;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] {\n display: flex;\n justify-content: flex-end;\n gap: 0.5rem;\n margin-top: 0.75rem;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"actions\"] button {\n appearance: none;\n border: 1px solid var(--cm-border);\n background: transparent;\n color: var(--cm-text);\n padding: 0.5rem 1rem;\n border-radius: var(--cm-radius-sm);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease, color 120ms ease, transform 120ms ease;\n font-family: inherit;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"cancel\"]:hover {\n background: var(--cm-primary-tint);\n border-color: var(--cm-primary);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"] {\n background: var(--cm-primary);\n border-color: var(--cm-primary);\n color: #ffffff;\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"]:hover:not(:disabled) {\n filter: brightness(1.1);\n transform: translateY(-1px);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"][data-destructive] {\n background: var(--cm-danger);\n border-color: var(--cm-danger);\n}\n\n[data-component=\"confirm-dialog\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"confirm\"]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n@keyframes cm-confirm-fade {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes cm-confirm-pop {\n from { opacity: 0; transform: scale(0.95) translateY(6px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n[data-component=\"chat-window-body\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* When ai-chat-panel is a direct child of chat-window-body, drop its own\n border/radius/shadow so the window shell owns the framing. */\n[data-component=\"chat-window-body\"]:where(:not([data-unstyled], [data-unstyled] *)) > [data-component=\"ai-chat-panel\"] {\n border: none;\n border-radius: 0;\n box-shadow: none;\n min-height: 0;\n height: 100%;\n}\n\n/* ---------- Approval reminder ---------- */\n[data-component=\"ai-chat-panel\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-component=\"approval-reminder\"] {\n margin: 0 1rem 0.5rem;\n padding: 0.5rem 0.75rem;\n border-radius: var(--cm-radius-sm);\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n font-size: 0.8125rem;\n}\n\n/* ---------------------------------------------------------------------------\n AssistantShell \u2014 docked sidebar or detached window. The handle geometry\n is inline, so it also works unstyled; these rules are only the look.\n --------------------------------------------------------------------------- */\n[data-component=\"assistant-shell\"][data-floating-gesture]:where(:not([data-unstyled], [data-unstyled] *)) { transition: none; will-change: transform, width, height; }\n@media (pointer: coarse) {\n [data-component=\"assistant-shell-window-handle\"]:where(:not([data-unstyled], [data-unstyled] *)):is([data-resize-edge=\"n\"], [data-resize-edge=\"s\"]) { height: 16px !important; }\n [data-component=\"assistant-shell-window-handle\"]:where(:not([data-unstyled], [data-unstyled] *)):is([data-resize-edge=\"e\"], [data-resize-edge=\"w\"]) { width: 16px !important; }\n [data-component=\"assistant-shell-window-handle\"]:where(:not([data-unstyled], [data-unstyled] *)):is([data-resize-edge=\"ne\"], [data-resize-edge=\"nw\"], [data-resize-edge=\"se\"], [data-resize-edge=\"sw\"]) { width: 28px !important; height: 28px !important; }\n}\n\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-sizing: border-box;\n z-index: 60;\n background: var(--cm-bg);\n color: var(--cm-text);\n font-family: var(--cm-font);\n border-left: 1px solid var(--cm-border);\n}\n[data-component=\"assistant-shell\"][data-mode=\"floating\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n border: 1px solid var(--cm-border);\n border-radius: var(--cm-radius);\n box-shadow: 0 12px 32px -12px rgba(17, 24, 39, 0.25);\n overflow: hidden;\n}\n[data-component=\"assistant-shell\"][data-floating-gesture=\"move\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n box-shadow: 0 16px 40px -12px rgba(17, 24, 39, 0.35);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"header\"] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n height: 2.75rem;\n flex-shrink: 0;\n padding: 0 0.75rem;\n border-bottom: 1px solid var(--cm-border);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"header\"] > [data-element=\"icon\"] {\n display: inline-flex;\n color: var(--cm-primary);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"title\"] {\n flex: 1 1 0%;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 0.875rem;\n font-weight: 600;\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) :is(header[data-element=\"header\"], [data-element=\"rail\"]) > [data-action] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n border: 0;\n border-radius: var(--cm-radius-sm);\n background: transparent;\n color: var(--cm-text-muted);\n cursor: pointer;\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) :is(header[data-element=\"header\"], [data-element=\"rail\"]) > [data-action]:hover {\n background: var(--cm-primary-tint);\n color: var(--cm-text);\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"rail\"] {\n display: flex;\n flex-direction: column;\n align-items: center;\n height: 100%;\n padding: 0.5rem 0;\n}\n[data-component=\"assistant-shell\"]:where(:not([data-unstyled], [data-unstyled] *)) [data-element=\"rail\"] > [data-action=\"expand\"] {\n flex: 1 1 0%;\n width: 100%;\n height: auto;\n flex-direction: column;\n justify-content: flex-start;\n gap: 1rem;\n padding-top: 0.25rem;\n font-size: 0.75rem;\n font-weight: 500;\n}\n[data-component=\"assistant-shell-resize\"]:where(:not([data-unstyled], [data-unstyled] *)):is(:hover, :focus-visible, [data-dragging]) {\n background: linear-gradient(to right, transparent 3px, var(--cm-primary) 3px, var(--cm-primary) 5px, transparent 5px);\n outline: none;\n}\n[data-component=\"assistant-bubble\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n position: fixed;\n right: 1rem;\n bottom: 1rem;\n z-index: 40;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n border: 0;\n border-radius: 9999px;\n background: var(--cm-primary);\n color: #fff;\n box-shadow: 0 8px 20px -8px rgba(17, 24, 39, 0.4);\n cursor: pointer;\n}\n[data-component=\"assistant-toggle\"]:where(:not([data-unstyled], [data-unstyled] *)) {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 0;\n border-radius: var(--cm-radius-sm);\n background: transparent;\n color: var(--cm-text);\n font: inherit;\n font-size: 0.875rem;\n cursor: pointer;\n}\n[data-component=\"assistant-toggle\"]:where(:not([data-unstyled], [data-unstyled] *)):is(:hover, [aria-pressed=\"true\"]) {\n background: var(--cm-primary-tint);\n}\n";
|