@adia-ai/web-modules 0.8.30 → 0.8.32

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 CHANGED
@@ -1,11 +1,32 @@
1
1
  # Changelog — @adia-ai/web-modules
2
2
 
3
+ ## [0.8.32] — 2026-08-09
4
+
5
+ ### Maintenance
6
+ - **Every `.d.ts` with a custom `events:` block regenerated — `addEventListener` overload order fixed at the generator** (gh#711 S1 review, `@adia-ai/web-components` CHANGELOG has the root-cause writeup). `scripts/build/dts-codegen.mjs` now emits event-specific overloads before the generic `HTMLElementEventMap` fallback instead of after, so TS overload resolution stops silently shadowing typed custom-event overloads (`change` chief among them, since it's also a literal `HTMLElementEventMap` key). Reordering only — `npm run typecheck` stays clean.
7
+ - **`dist/` bundles rebuilt** in this cut's window (4 file(s)) — regenerated from the source changes described above, not independent edits.
8
+ - **`editor/` touched in this release window** (2 file(s), e.g. `editor-sidebar/editor-sidebar.d.ts`) — carried by the entries above.
9
+ - **`runtime/` touched in this release window** (1 file(s), e.g. `a2ui-root/a2ui-root.d.ts`) — carried by the entries above.
10
+ - **`theme/` touched in this release window** (1 file(s), e.g. `theme-panel/theme-panel.d.ts`) — carried by the entries above.
11
+
12
+ ### Fixed
13
+ - **`chat-shell` message rows hosting a generated surface no longer inherit the prose reading-width cap (gh#719).** Every `[data-role]` row carried `max-width: var(--chat-message-max-width)` (85%) — right for conversational text bubbles, wrong for rows whose bubble hosts a mounted A2UI surface (a full structured card/form, e.g. a follow-up proposal or working differential). Two mount shapes carry a surface and both are now exempted: `[data-bubble][data-surface]` (a consumer's own attribute-on-bubble convention, e.g. patient-visit's `hydrate.js`) and `[data-bubble]:has(> [data-surface-root])` (`chat-shell`'s own registry mount — `chat-surfaces.js`'s `createSurfaceRegistry#route` appends an "island" div as a direct child of the bubble, with no attribute on the bubble itself; every `agent-chat`/`agent-admin` surface row rides this shape). Follows the file's own existing exemption precedent for `[data-role="error"]`.
14
+
15
+ ## [0.8.31] — 2026-08-07
16
+
17
+ ### Fixed
18
+ - **`chat-empty` is now registered** (gh#655). It had every sidecar (yaml/a2ui.json/examples) but no `defineIfFree('chat-empty', …)` anywhere — the tag never upgraded, so `customElements.whenDefined('chat-empty')` never resolved for any consumer awaiting it (light-DOM children still rendered; CSS tag-selectors still painted it, since neither cares about upgrade status — but the element itself stayed undefined). Added `chat-empty.js` with a minimal `UIElement` subclass (no reactive props, matching its CSS-only visibility contract) registered the way the sibling JS-bearing chat-cluster modules are (`chat-sidebar`, `chat-thread`, `chat-composer`); wired into `chat/index.js`'s barrel export.
19
+
20
+ ### Maintenance
21
+ - **`dist/` bundles rebuilt** in this cut's window (1 file(s)) — regenerated from the source changes described above, not independent edits.
22
+
3
23
  ## [0.8.30] — 2026-08-07
4
24
 
5
25
  ### Added
6
26
  - **`chatShell.setStreamedText(text)`** — replaces the streaming assistant message's text outright, the counterpart to `appendChunk` for a producer that revises what it already streamed.
7
27
 
8
28
  ### Fixed
29
+ - **`chat-composer` stops the inner `submit` event at its re-dispatch boundary (gh#676).** The re-emitted `composer-submit` was riding alongside the raw `submit` bubbling in from `chat-input-ui` unstopped — a host could receive both. `stopPropagation()` on the inner event before re-dispatching as `composer-submit` closes the second path.
9
30
  - **A rewritten or withheld turn now leaves the screen agreeing with the transcript (gh#665).** `wireAgentEvents` treated every `text` event as an append, so an `@adia-ai/agent` output guardrail's re-snapshot (`{ text: '', snapshot: <rewritten> }`) appended nothing and the ORIGINAL text stayed on screen while the session recorded the rewrite — a redaction that redacted nothing visible. An empty delta is now a replace from `snapshot` (an empty snapshot clears the bubble), which is safe for any text event since the snapshot is always the authoritative text.
10
31
 
11
32
  ### Maintenance
@@ -34,10 +34,10 @@ code. Propagated to the inner input element automatically.
34
34
  */
35
35
  disabled: boolean;
36
36
 
37
+ addEventListener(type: 'composer-submit', listener: (ev: ChatComposerComposerSubmitEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
37
38
  addEventListener<K extends keyof HTMLElementEventMap>(
38
39
  type: K,
39
40
  listener: (this: ChatComposer, ev: HTMLElementEventMap[K]) => unknown,
40
41
  options?: boolean | AddEventListenerOptions,
41
42
  ): void;
42
- addEventListener(type: 'composer-submit', listener: (ev: ChatComposerComposerSubmitEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
43
43
  }
@@ -49,6 +49,12 @@ class ChatComposer extends UIElement {
49
49
  this.#inputEl = this.querySelector('chat-input-ui') || this.querySelector('input-ui') || this.querySelector('textarea-ui');
50
50
 
51
51
  this.#onSubmit = (e) => {
52
+ // Stop the inner 'submit' event at this re-dispatch boundary too —
53
+ // this component re-emits it as 'composer-submit' below, so letting
54
+ // the raw 'submit' keep bubbling past chat-composer would let a
55
+ // host that (also) listens for raw 'submit' receive a duplicate
56
+ // (gh#676).
57
+ e.stopPropagation();
52
58
  // Re-emit as 'composer-submit' so host listens to one event
53
59
  // regardless of which inner input it is
54
60
  this.dispatchEvent(new CustomEvent('composer-submit', {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://adiaui.dev/a2ui/v0_9/components/ChatEmpty.json",
4
4
  "title": "ChatEmpty",
5
- "description": "Module-tier chat empty state. CSS-only no behavior, no JS. Sits\nas the first child of <chat-thread> as the empty state placeholder.\nVisibility is driven by <chat-thread>'s [empty] reflected attribute\nvia CSS (no JS toggling needed) when messages arrive, the parent\nthread loses [empty] and CSS hides this stub.\n\nReplaces the legacy <empty-state-ui data-chat-empty> child of the\nmessages container per ADR-0023. The legacy shape was retired in\nv0.4.0 per ADR-0024 and is no longer recognized.\n",
5
+ "description": "Module-tier chat empty state. No reactive props visibility is\ndriven by <chat-thread>'s [empty] reflected attribute via CSS (no\nJS toggling needed); when messages arrive, the parent thread loses\n[empty] and CSS hides this stub. Registered (defineIfFree) so the\ntag upgrades and resolves customElements.whenDefined('chat-empty')\n(gh#655) — sits as the first child of <chat-thread> as the empty\nstate placeholder.\n\nReplaces the legacy <empty-state-ui data-chat-empty> child of the\nmessages container per ADR-0023. The legacy shape was retired in\nv0.4.0 per ADR-0024 and is no longer recognized.\n",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `<chat-empty>` — Module-tier chat empty state. No reactive props — visibility is
3
+ driven by <chat-thread>'s [empty] reflected attribute via CSS (no
4
+ JS toggling needed); when messages arrive, the parent thread loses
5
+ [empty] and CSS hides this stub. Registered (defineIfFree) so the
6
+ tag upgrades and resolves customElements.whenDefined('chat-empty')
7
+ (gh#655) — sits as the first child of <chat-thread> as the empty
8
+ state placeholder.
9
+
10
+ Replaces the legacy <empty-state-ui data-chat-empty> child of the
11
+ messages container per ADR-0023. The legacy shape was retired in
12
+ v0.4.0 per ADR-0024 and is no longer recognized.
13
+
14
+ *
15
+ * @see https://ui-kit.exe.xyz/site/components/chat-empty
16
+ *
17
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
18
+ * the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
19
+ * run `npm run build:components`, then `npm run codegen:dts` to
20
+ * regenerate; or hand-author this file fully if rich event types are
21
+ * needed beyond what the yaml `events:` block can express.
22
+ */
23
+
24
+ import { UIElement } from '../../../web-components/core/element.js';
25
+
26
+ export class ChatEmpty extends UIElement {
27
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * <chat-empty>
3
+ * <empty-state-ui icon="chat-circle" heading="Hello!" description="Ask me anything."></empty-state-ui>
4
+ * </chat-empty>
5
+ *
6
+ * Module-tier chat empty state — the bespoke replacement for legacy
7
+ * `<empty-state-ui data-chat-empty>` per ADR-0023. Sits as the first
8
+ * child of <chat-thread>; visibility is driven entirely by CSS off
9
+ * <chat-thread>'s [empty] reflected attribute (see
10
+ * chat-shell/css/chat-shell.bespoke.css) — no JS toggling needed.
11
+ *
12
+ * Registered (gh#655) even though the element carries no reactive
13
+ * state: an unregistered custom element never resolves
14
+ * `customElements.whenDefined('chat-empty')` and never matches
15
+ * `:defined` — a host or test that waits on either hangs/mismatches
16
+ * forever, even though CSS tag-selectors keep painting it either way.
17
+ * Matches the sibling JS-bearing chat-cluster modules' own-file
18
+ * registration shape (chat-sidebar, chat-thread, chat-composer);
19
+ * chat-header/chat-status stay genuinely unregistered CSS-only markup
20
+ * wrappers — chat-empty is the one with a live tag reference in
21
+ * consumer surfaces (patient-visit), so it gets the class.
22
+ */
23
+
24
+ import { defineIfFree } from '../../../web-components/core/register.js';
25
+ import { UIElement } from '../../../web-components/core/element.js';
26
+
27
+ class ChatEmpty extends UIElement {
28
+ static properties = {};
29
+
30
+ static template = () => null;
31
+ }
32
+
33
+ defineIfFree('chat-empty', ChatEmpty);
34
+ export { ChatEmpty };
@@ -7,11 +7,13 @@ component: ChatEmpty
7
7
  category: feedback
8
8
  version: 1
9
9
  description: |
10
- Module-tier chat empty state. CSS-only no behavior, no JS. Sits
11
- as the first child of <chat-thread> as the empty state placeholder.
12
- Visibility is driven by <chat-thread>'s [empty] reflected attribute
13
- via CSS (no JS toggling needed) when messages arrive, the parent
14
- thread loses [empty] and CSS hides this stub.
10
+ Module-tier chat empty state. No reactive props visibility is
11
+ driven by <chat-thread>'s [empty] reflected attribute via CSS (no
12
+ JS toggling needed); when messages arrive, the parent thread loses
13
+ [empty] and CSS hides this stub. Registered (defineIfFree) so the
14
+ tag upgrades and resolves customElements.whenDefined('chat-empty')
15
+ (gh#655) — sits as the first child of <chat-thread> as the empty
16
+ state placeholder.
15
17
 
16
18
  Replaces the legacy <empty-state-ui data-chat-empty> child of the
17
19
  messages container per ADR-0023. The legacy shape was retired in
@@ -43,8 +45,8 @@ a2ui:
43
45
  <empty-state-ui data-chat-empty>. Place as the first child of
44
46
  <chat-thread>; visibility is automatic via the [empty]
45
47
  reflected attribute.
46
- - rule: 'CSS-only no JS module needed in shell HTML imports.'
47
- reason: 'CSS-only primitive.'
48
+ - rule: 'No reactive props — visibility is CSS-driven off the parent [empty] attribute, not a JS toggle.'
49
+ reason: 'State contract.'
48
50
  - rule: 'For non-chat empty states (lists, tables, canvas) use <empty-state-ui> primitive instead; chat-empty is chat-cluster-namespaced.'
49
51
  reason: 'Cluster vs primitive distinction.'
50
52
 
@@ -79,11 +79,6 @@ export class ChatShell extends UIElement {
79
79
  /** Enable Anthropic extended-thinking mode. */
80
80
  thinking: boolean;
81
81
 
82
- addEventListener<K extends keyof HTMLElementEventMap>(
83
- type: K,
84
- listener: (this: ChatShell, ev: HTMLElementEventMap[K]) => unknown,
85
- options?: boolean | AddEventListenerOptions,
86
- ): void;
87
82
  addEventListener(type: 'abort', listener: (ev: ChatShellAbortEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
88
83
  addEventListener(type: 'chunk', listener: (ev: ChatShellChunkEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
89
84
  addEventListener(type: 'clear', listener: (ev: ChatShellClearEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
@@ -92,4 +87,9 @@ export class ChatShell extends UIElement {
92
87
  addEventListener(type: 'message', listener: (ev: ChatShellMessageEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
93
88
  addEventListener(type: 'submit', listener: (ev: ChatShellSubmitEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
94
89
  addEventListener(type: 'thinking', listener: (ev: ChatShellThinkingEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
90
+ addEventListener<K extends keyof HTMLElementEventMap>(
91
+ type: K,
92
+ listener: (this: ChatShell, ev: HTMLElementEventMap[K]) => unknown,
93
+ options?: boolean | AddEventListenerOptions,
94
+ ): void;
95
95
  }
@@ -63,6 +63,24 @@ chat-shell [data-role="assistant"] [data-bubble] {
63
63
  border-bottom-left-radius: var(--chat-assistant-tail-radius);
64
64
  }
65
65
 
66
+ /* Generated-surface row — a mounted A2UI surface (structured card/form,
67
+ not conversational prose) shouldn't inherit the reading-width cap meant
68
+ for text bubbles. Mirrors the [data-role="error"] exemption below: "not
69
+ a conversational text bubble" already has precedent here.
70
+
71
+ Two mount shapes carry a surface, and neither is optional:
72
+ - [data-bubble][data-surface] — the attribute-on-bubble convention a
73
+ consumer (e.g. patient-visit's hydrate.js) applies to its own bubble.
74
+ - [data-bubble]:has(> [data-surface-root]) — chat-shell's OWN registry
75
+ mount (chat-surfaces.js's createSurfaceRegistry#route): an "island"
76
+ div appended as a direct child of the bubble, with no attribute on
77
+ the bubble itself. Every agent-chat / agent-admin surface row rides
78
+ this shape, not the patient-visit one. */
79
+ chat-shell [data-role]:has([data-bubble][data-surface]),
80
+ chat-shell [data-role]:has([data-bubble] > [data-surface-root]) {
81
+ max-width: none;
82
+ }
83
+
66
84
  /* Error message */
67
85
  chat-shell [data-role="error"] {
68
86
  align-self: center;
@@ -60,11 +60,11 @@ Useful for suppressing transitions while dragging.
60
60
  */
61
61
  resizing: boolean;
62
62
 
63
+ addEventListener(type: 'sidebar-resize', listener: (ev: ChatSidebarSidebarResizeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
64
+ addEventListener(type: 'sidebar-toggle', listener: (ev: ChatSidebarSidebarToggleEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
63
65
  addEventListener<K extends keyof HTMLElementEventMap>(
64
66
  type: K,
65
67
  listener: (this: ChatSidebar, ev: HTMLElementEventMap[K]) => unknown,
66
68
  options?: boolean | AddEventListenerOptions,
67
69
  ): void;
68
- addEventListener(type: 'sidebar-resize', listener: (ev: ChatSidebarSidebarResizeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
69
- addEventListener(type: 'sidebar-toggle', listener: (ev: ChatSidebarSidebarToggleEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
70
70
  }
package/chat/index.js CHANGED
@@ -2,4 +2,5 @@ export { ChatShell } from './chat-shell/chat-shell.js';
2
2
  export { ChatThread } from './chat-thread/chat-thread.js';
3
3
  export { ChatComposer } from './chat-composer/chat-composer.js';
4
4
  export { ChatSidebar } from './chat-sidebar/chat-sidebar.js';
5
+ export { ChatEmpty } from './chat-empty/chat-empty.js';
5
6
  export { createSurfaceRegistry, wireAgentEvents, PROGRESS_LABELS } from './chat-surfaces/chat-surfaces.js';
@@ -1 +1 @@
1
- :where(chat-shell){--chat-bg:var(--a-canvas-0);--chat-border:unset;--chat-radius:unset;--chat-header-height:var(--a-chrome-app-header-height);--chat-header-px:var(--a-space-4);--chat-header-gap:var(--a-space-2);--chat-header-border:1px solid var(--md-sys-color-neutral-outline-variant);--chat-messages-px:var(--a-space-4);--chat-messages-py:var(--a-space-4);--chat-messages-gap:var(--a-space-3);--chat-message-max-width:85%;--chat-user-bg:var(--md-sys-color-primary);--chat-user-fg:var(--md-sys-color-primary-on-primary);--chat-user-radius:var(--a-radius-md);--chat-user-tail-radius:var(--a-radius-sm);--chat-user-px:var(--a-space-3);--chat-user-py:var(--a-space-1);--chat-assistant-bg:var(--a-canvas-2);--chat-assistant-fg:var(--md-sys-color-neutral-on-surface);--chat-assistant-radius:var(--a-radius-lg);--chat-assistant-tail-radius:var(--a-radius-sm);--chat-assistant-px:var(--a-space-3);--chat-assistant-py:var(--a-space-1);--chat-avatar-size:1.75rem;--chat-avatar-bg:var(--chat-assistant-bg);--chat-avatar-fg:var(--chat-assistant-fg);--chat-avatar-font:var(--a-ui-sm);--chat-avatar-weight:var(--a-weight-semibold);--chat-cursor-width:2px;--chat-cursor-color:currentColor;--chat-cursor-speed:.8s;--chat-footer-px:var(--a-space-3);--chat-footer-py:var(--a-space-3);--chat-actions-gap:var(--a-space-1);--chat-code-bg:var(--a-canvas-2);--chat-code-radius:var(--a-radius-md);--chat-font-size:var(--a-ui-size);--chat-line-height:var(--a-leading-normal);--chat-weight-semibold:var(--a-weight-semibold);--chat-header-name-font:var(--a-ui-lg);--chat-header-status-font:var(--a-ui-md);--chat-header-status-fg:var(--a-fg-muted);--chat-error-gap:var(--a-space-2);--chat-error-fg:var(--a-danger-strong);--chat-error-font:var(--a-ui-sm);--chat-actions-duration:var(--a-duration-fast);--chat-actions-easing:var(--a-easing);--chat-avatar-radius:var(--a-radius-full);--chat-thinking-fg:var(--a-fg-muted);--chat-code-inline-radius:var(--a-radius-sm);--chat-code-inline-family:var(--a-font-family-code);--chat-code-block-px:var(--a-space-3);--chat-code-block-my:var(--a-space-2);--chat-code-block-font:var(--a-ui-sm)}chat-shell{box-sizing:border-box;border:var(--chat-border);border-radius:var(--chat-radius);background:var(--chat-bg);flex-direction:column;height:100%;display:flex;overflow:hidden}chat-shell>header{align-items:center;gap:var(--chat-header-gap);min-height:var(--chat-header-height);padding:0 var(--chat-header-px);border-bottom:var(--chat-header-border);flex-shrink:0;display:flex}chat-shell>header [data-chat-name]{font-weight:var(--chat-weight-semibold);font-size:var(--chat-header-name-font)}chat-shell>header chat-status{font-size:var(--chat-header-status-font);color:var(--chat-header-status-fg);margin-inline-start:auto}chat-shell>chat-thread,chat-shell>section{padding:var(--chat-messages-py) var(--chat-messages-px);gap:var(--chat-messages-gap);flex-direction:column;flex:1;min-height:0;display:flex;overflow-y:auto}chat-shell>footer{padding:var(--chat-footer-py) var(--chat-footer-px);flex-shrink:0;align-items:center;display:flex}chat-shell>footer chat-input-ui{flex:1}chat-shell [data-role]{gap:var(--chat-header-gap);max-width:var(--chat-message-max-width);align-items:flex-end;display:flex}chat-shell [data-role=user]{flex-direction:row-reverse;align-self:flex-end}chat-shell [data-role=assistant]{align-self:flex-start}chat-shell [data-role] [data-avatar]{width:var(--chat-avatar-size);height:var(--chat-avatar-size);border-radius:var(--chat-avatar-radius);background:var(--chat-avatar-bg);color:var(--chat-avatar-fg);font-size:var(--chat-avatar-font);font-weight:var(--chat-avatar-weight);flex-shrink:0;justify-content:center;align-items:center;display:flex}chat-shell [data-role] [data-bubble]{padding:var(--chat-assistant-py) var(--chat-assistant-px);border-radius:var(--chat-assistant-radius);font-size:var(--chat-font-size);line-height:var(--chat-line-height);white-space:pre-wrap;word-break:break-word}chat-shell [data-role] [data-bubble]>:first-child{margin-block-start:0}chat-shell [data-role] [data-bubble]>:last-child{margin-block-end:0}chat-shell [data-role=user] [data-bubble]{background:var(--chat-user-bg);color:var(--chat-user-fg);padding:var(--chat-user-py) var(--chat-user-px);border-radius:var(--chat-user-radius);border-bottom-right-radius:var(--chat-user-tail-radius)}chat-shell [data-role=assistant] [data-bubble]{background:var(--chat-assistant-bg);color:var(--chat-assistant-fg);border-bottom-left-radius:var(--chat-assistant-tail-radius)}chat-shell [data-role=error]{align-self:center;align-items:center;gap:var(--chat-error-gap);max-width:none;color:var(--chat-error-fg);font-size:var(--chat-error-font);display:flex}chat-shell [data-role] [data-actions]{gap:var(--chat-actions-gap);opacity:0;transition:opacity var(--chat-actions-duration) var(--chat-actions-easing);display:flex}chat-shell [data-role]:hover [data-actions]{opacity:1}chat-shell [data-cursor]{width:var(--chat-cursor-width);background:var(--chat-cursor-color);vertical-align:text-bottom;height:1em;animation:chat-shell-blink var(--chat-cursor-speed) step-end infinite;margin-inline-start:1px;display:inline-block}@keyframes chat-shell-blink{50%{opacity:0}}@media (prefers-reduced-motion:reduce){chat-shell [data-cursor]{opacity:.7;animation:none}}chat-shell [data-role=assistant][data-thinking] [data-bubble]{color:var(--chat-thinking-fg)}chat-shell [data-bubble] [data-content]{white-space:normal}chat-shell [data-bubble] [data-content] p{margin:0 0 .5em}chat-shell [data-bubble] [data-content] p:last-child{margin-bottom:0}chat-shell [data-bubble] [data-content] strong{font-weight:var(--chat-weight-semibold)}chat-shell [data-bubble] [data-content] code{background:var(--chat-code-bg);border-radius:var(--chat-code-inline-radius);font-family:var(--chat-code-inline-family);padding:.1em .15em;font-size:.875em}chat-shell [data-bubble] [data-content] pre{background:var(--chat-code-bg);border-radius:var(--chat-code-radius);padding:var(--chat-code-block-px);margin:var(--chat-code-block-my) 0;font-size:var(--chat-code-block-font);line-height:1.5;overflow-x:auto}chat-shell [data-bubble] [data-content] pre code{font-size:inherit;background:0 0;border-radius:0;padding:0}chat-shell [data-bubble] [data-content] ul,chat-shell [data-bubble] [data-content] ol{margin:.25em 0;padding-inline-start:1.25em}chat-shell [data-bubble] [data-content] li{margin-bottom:.15em}chat-shell [data-bubble] [data-content] a{color:inherit;text-underline-offset:2px;text-decoration:underline}chat-shell [data-bubble] [data-content] h1,chat-shell [data-bubble] [data-content] h2,chat-shell [data-bubble] [data-content] h3,chat-shell [data-bubble] [data-content] h4{font-weight:var(--chat-weight-semibold);margin:.75em 0 .25em}chat-shell [data-bubble] [data-content] h1:first-child,chat-shell [data-bubble] [data-content] h2:first-child,chat-shell [data-bubble] [data-content] h3:first-child{margin-top:0}chat-shell chat-empty{margin:auto}chat-shell[streaming] chat-empty,chat-shell:has([data-role]) chat-empty{display:none}chat-shell>chat-header,chat-sidebar>chat-header[slot=header],chat-sidebar>chat-header:first-child{align-items:center;gap:var(--chat-header-gap,var(--a-space-2));padding:0 var(--chat-header-px,var(--a-space-3));height:var(--chat-header-height,var(--a-size-lg));font-size:var(--chat-header-font,var(--a-ui-size));border-bottom:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant));background:var(--chat-bg,var(--md-sys-color-neutral-background));flex-shrink:0;display:flex}chat-header>[slot=name]{font-weight:var(--a-weight-medium,500);color:var(--md-sys-color-neutral-on-surface)}chat-header>[slot=status]{margin-inline-start:var(--a-space-2)}chat-header>[slot=action]:first-of-type{margin-inline-start:auto}chat-header>[slot=action-leading]{margin-inline-end:var(--a-space-2)}chat-status{align-items:center;gap:var(--a-space-1);font-size:var(--a-ui-sm);color:var(--a-fg-muted);display:inline-flex}chat-shell>chat-thread{overscroll-behavior:contain;gap:var(--chat-message-gap,var(--a-space-3));min-height:0;padding:var(--chat-thread-py,var(--a-space-4)) var(--chat-thread-px,var(--a-space-4));background:var(--chat-thread-bg,var(--md-sys-color-neutral-background));flex-direction:column;flex:1;display:flex;overflow-y:auto}chat-thread:not([empty])>chat-empty{display:none}chat-thread[empty]>chat-empty{padding:var(--a-space-6);flex:1;justify-content:center;align-items:center;display:flex}chat-shell>chat-composer{align-items:stretch;gap:var(--a-space-2);padding:var(--chat-composer-py,var(--a-space-3)) var(--chat-composer-px,var(--a-space-3));border-top:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant));background:var(--chat-bg,var(--md-sys-color-neutral-background));flex-shrink:0;display:flex}chat-composer>[slot=leading],chat-composer>[slot=attach],chat-composer>[slot=trailing]{align-items:center;gap:var(--a-space-1);flex-shrink:0;display:inline-flex}chat-composer>:is(chat-input-ui,input-ui,textarea-ui){flex:1;min-width:0}chat-composer[disabled]{opacity:.6;pointer-events:none}:is(chat-sidebar[slot=leading],chat-sidebar[slot=trailing]){min-width:var(--chat-sidebar-min-width,48px);max-width:var(--chat-sidebar-max-width,480px);min-height:0;font-size:var(--chat-sidebar-font,var(--a-ui-size));transition:width var(--chat-duration,var(--a-duration,.2s)) var(--chat-easing,var(--a-easing,ease));background:var(--chat-bg,var(--md-sys-color-neutral-background));flex-direction:column;flex-shrink:0;display:flex;position:relative;container:sidebar/inline-size}chat-sidebar[slot=leading]{width:var(--chat-sidebar-width-leading,240px);border-right:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant))}chat-sidebar[slot=trailing]{width:var(--chat-sidebar-width-trailing,320px);border-left:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant))}:is(chat-sidebar[slot=leading],chat-sidebar[slot=trailing])>[data-resize]{cursor:col-resize;z-index:1;-webkit-user-select:none;user-select:none;width:6px;position:absolute;top:0;bottom:0}chat-sidebar[slot=leading]>[data-resize]{right:-3px}chat-sidebar[slot=trailing]>[data-resize]{left:-3px}:is(chat-sidebar[slot=leading],chat-sidebar[slot=trailing])>[data-resize]:hover{background:var(--md-sys-color-primary);opacity:.5}chat-sidebar[resizing]{transition:none}chat-sidebar[resizing]>[data-resize]{background:var(--md-sys-color-primary);opacity:.8}chat-shell:has(>chat-sidebar){flex-direction:row;display:flex}chat-shell:has(>chat-sidebar)>:not(chat-sidebar){display:contents}
1
+ :where(chat-shell){--chat-bg:var(--a-canvas-0);--chat-border:unset;--chat-radius:unset;--chat-header-height:var(--a-chrome-app-header-height);--chat-header-px:var(--a-space-4);--chat-header-gap:var(--a-space-2);--chat-header-border:1px solid var(--md-sys-color-neutral-outline-variant);--chat-messages-px:var(--a-space-4);--chat-messages-py:var(--a-space-4);--chat-messages-gap:var(--a-space-3);--chat-message-max-width:85%;--chat-user-bg:var(--md-sys-color-primary);--chat-user-fg:var(--md-sys-color-primary-on-primary);--chat-user-radius:var(--a-radius-md);--chat-user-tail-radius:var(--a-radius-sm);--chat-user-px:var(--a-space-3);--chat-user-py:var(--a-space-1);--chat-assistant-bg:var(--a-canvas-2);--chat-assistant-fg:var(--md-sys-color-neutral-on-surface);--chat-assistant-radius:var(--a-radius-lg);--chat-assistant-tail-radius:var(--a-radius-sm);--chat-assistant-px:var(--a-space-3);--chat-assistant-py:var(--a-space-1);--chat-avatar-size:1.75rem;--chat-avatar-bg:var(--chat-assistant-bg);--chat-avatar-fg:var(--chat-assistant-fg);--chat-avatar-font:var(--a-ui-sm);--chat-avatar-weight:var(--a-weight-semibold);--chat-cursor-width:2px;--chat-cursor-color:currentColor;--chat-cursor-speed:.8s;--chat-footer-px:var(--a-space-3);--chat-footer-py:var(--a-space-3);--chat-actions-gap:var(--a-space-1);--chat-code-bg:var(--a-canvas-2);--chat-code-radius:var(--a-radius-md);--chat-font-size:var(--a-ui-size);--chat-line-height:var(--a-leading-normal);--chat-weight-semibold:var(--a-weight-semibold);--chat-header-name-font:var(--a-ui-lg);--chat-header-status-font:var(--a-ui-md);--chat-header-status-fg:var(--a-fg-muted);--chat-error-gap:var(--a-space-2);--chat-error-fg:var(--a-danger-strong);--chat-error-font:var(--a-ui-sm);--chat-actions-duration:var(--a-duration-fast);--chat-actions-easing:var(--a-easing);--chat-avatar-radius:var(--a-radius-full);--chat-thinking-fg:var(--a-fg-muted);--chat-code-inline-radius:var(--a-radius-sm);--chat-code-inline-family:var(--a-font-family-code);--chat-code-block-px:var(--a-space-3);--chat-code-block-my:var(--a-space-2);--chat-code-block-font:var(--a-ui-sm)}chat-shell{box-sizing:border-box;border:var(--chat-border);border-radius:var(--chat-radius);background:var(--chat-bg);flex-direction:column;height:100%;display:flex;overflow:hidden}chat-shell>header{align-items:center;gap:var(--chat-header-gap);min-height:var(--chat-header-height);padding:0 var(--chat-header-px);border-bottom:var(--chat-header-border);flex-shrink:0;display:flex}chat-shell>header [data-chat-name]{font-weight:var(--chat-weight-semibold);font-size:var(--chat-header-name-font)}chat-shell>header chat-status{font-size:var(--chat-header-status-font);color:var(--chat-header-status-fg);margin-inline-start:auto}chat-shell>chat-thread,chat-shell>section{padding:var(--chat-messages-py) var(--chat-messages-px);gap:var(--chat-messages-gap);flex-direction:column;flex:1;min-height:0;display:flex;overflow-y:auto}chat-shell>footer{padding:var(--chat-footer-py) var(--chat-footer-px);flex-shrink:0;align-items:center;display:flex}chat-shell>footer chat-input-ui{flex:1}chat-shell [data-role]{gap:var(--chat-header-gap);max-width:var(--chat-message-max-width);align-items:flex-end;display:flex}chat-shell [data-role=user]{flex-direction:row-reverse;align-self:flex-end}chat-shell [data-role=assistant]{align-self:flex-start}chat-shell [data-role] [data-avatar]{width:var(--chat-avatar-size);height:var(--chat-avatar-size);border-radius:var(--chat-avatar-radius);background:var(--chat-avatar-bg);color:var(--chat-avatar-fg);font-size:var(--chat-avatar-font);font-weight:var(--chat-avatar-weight);flex-shrink:0;justify-content:center;align-items:center;display:flex}chat-shell [data-role] [data-bubble]{padding:var(--chat-assistant-py) var(--chat-assistant-px);border-radius:var(--chat-assistant-radius);font-size:var(--chat-font-size);line-height:var(--chat-line-height);white-space:pre-wrap;word-break:break-word}chat-shell [data-role] [data-bubble]>:first-child{margin-block-start:0}chat-shell [data-role] [data-bubble]>:last-child{margin-block-end:0}chat-shell [data-role=user] [data-bubble]{background:var(--chat-user-bg);color:var(--chat-user-fg);padding:var(--chat-user-py) var(--chat-user-px);border-radius:var(--chat-user-radius);border-bottom-right-radius:var(--chat-user-tail-radius)}chat-shell [data-role=assistant] [data-bubble]{background:var(--chat-assistant-bg);color:var(--chat-assistant-fg);border-bottom-left-radius:var(--chat-assistant-tail-radius)}chat-shell [data-role]:has([data-bubble][data-surface]),chat-shell [data-role]:has([data-bubble]>[data-surface-root]){max-width:none}chat-shell [data-role=error]{align-self:center;align-items:center;gap:var(--chat-error-gap);max-width:none;color:var(--chat-error-fg);font-size:var(--chat-error-font);display:flex}chat-shell [data-role] [data-actions]{gap:var(--chat-actions-gap);opacity:0;transition:opacity var(--chat-actions-duration) var(--chat-actions-easing);display:flex}chat-shell [data-role]:hover [data-actions]{opacity:1}chat-shell [data-cursor]{width:var(--chat-cursor-width);background:var(--chat-cursor-color);vertical-align:text-bottom;height:1em;animation:chat-shell-blink var(--chat-cursor-speed) step-end infinite;margin-inline-start:1px;display:inline-block}@keyframes chat-shell-blink{50%{opacity:0}}@media (prefers-reduced-motion:reduce){chat-shell [data-cursor]{opacity:.7;animation:none}}chat-shell [data-role=assistant][data-thinking] [data-bubble]{color:var(--chat-thinking-fg)}chat-shell [data-bubble] [data-content]{white-space:normal}chat-shell [data-bubble] [data-content] p{margin:0 0 .5em}chat-shell [data-bubble] [data-content] p:last-child{margin-bottom:0}chat-shell [data-bubble] [data-content] strong{font-weight:var(--chat-weight-semibold)}chat-shell [data-bubble] [data-content] code{background:var(--chat-code-bg);border-radius:var(--chat-code-inline-radius);font-family:var(--chat-code-inline-family);padding:.1em .15em;font-size:.875em}chat-shell [data-bubble] [data-content] pre{background:var(--chat-code-bg);border-radius:var(--chat-code-radius);padding:var(--chat-code-block-px);margin:var(--chat-code-block-my) 0;font-size:var(--chat-code-block-font);line-height:1.5;overflow-x:auto}chat-shell [data-bubble] [data-content] pre code{font-size:inherit;background:0 0;border-radius:0;padding:0}chat-shell [data-bubble] [data-content] ul,chat-shell [data-bubble] [data-content] ol{margin:.25em 0;padding-inline-start:1.25em}chat-shell [data-bubble] [data-content] li{margin-bottom:.15em}chat-shell [data-bubble] [data-content] a{color:inherit;text-underline-offset:2px;text-decoration:underline}chat-shell [data-bubble] [data-content] h1,chat-shell [data-bubble] [data-content] h2,chat-shell [data-bubble] [data-content] h3,chat-shell [data-bubble] [data-content] h4{font-weight:var(--chat-weight-semibold);margin:.75em 0 .25em}chat-shell [data-bubble] [data-content] h1:first-child,chat-shell [data-bubble] [data-content] h2:first-child,chat-shell [data-bubble] [data-content] h3:first-child{margin-top:0}chat-shell chat-empty{margin:auto}chat-shell[streaming] chat-empty,chat-shell:has([data-role]) chat-empty{display:none}chat-shell>chat-header,chat-sidebar>chat-header[slot=header],chat-sidebar>chat-header:first-child{align-items:center;gap:var(--chat-header-gap,var(--a-space-2));padding:0 var(--chat-header-px,var(--a-space-3));height:var(--chat-header-height,var(--a-size-lg));font-size:var(--chat-header-font,var(--a-ui-size));border-bottom:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant));background:var(--chat-bg,var(--md-sys-color-neutral-background));flex-shrink:0;display:flex}chat-header>[slot=name]{font-weight:var(--a-weight-medium,500);color:var(--md-sys-color-neutral-on-surface)}chat-header>[slot=status]{margin-inline-start:var(--a-space-2)}chat-header>[slot=action]:first-of-type{margin-inline-start:auto}chat-header>[slot=action-leading]{margin-inline-end:var(--a-space-2)}chat-status{align-items:center;gap:var(--a-space-1);font-size:var(--a-ui-sm);color:var(--a-fg-muted);display:inline-flex}chat-shell>chat-thread{overscroll-behavior:contain;gap:var(--chat-message-gap,var(--a-space-3));min-height:0;padding:var(--chat-thread-py,var(--a-space-4)) var(--chat-thread-px,var(--a-space-4));background:var(--chat-thread-bg,var(--md-sys-color-neutral-background));flex-direction:column;flex:1;display:flex;overflow-y:auto}chat-thread:not([empty])>chat-empty{display:none}chat-thread[empty]>chat-empty{padding:var(--a-space-6);flex:1;justify-content:center;align-items:center;display:flex}chat-shell>chat-composer{align-items:stretch;gap:var(--a-space-2);padding:var(--chat-composer-py,var(--a-space-3)) var(--chat-composer-px,var(--a-space-3));border-top:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant));background:var(--chat-bg,var(--md-sys-color-neutral-background));flex-shrink:0;display:flex}chat-composer>[slot=leading],chat-composer>[slot=attach],chat-composer>[slot=trailing]{align-items:center;gap:var(--a-space-1);flex-shrink:0;display:inline-flex}chat-composer>:is(chat-input-ui,input-ui,textarea-ui){flex:1;min-width:0}chat-composer[disabled]{opacity:.6;pointer-events:none}:is(chat-sidebar[slot=leading],chat-sidebar[slot=trailing]){min-width:var(--chat-sidebar-min-width,48px);max-width:var(--chat-sidebar-max-width,480px);min-height:0;font-size:var(--chat-sidebar-font,var(--a-ui-size));transition:width var(--chat-duration,var(--a-duration,.2s)) var(--chat-easing,var(--a-easing,ease));background:var(--chat-bg,var(--md-sys-color-neutral-background));flex-direction:column;flex-shrink:0;display:flex;position:relative;container:sidebar/inline-size}chat-sidebar[slot=leading]{width:var(--chat-sidebar-width-leading,240px);border-right:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant))}chat-sidebar[slot=trailing]{width:var(--chat-sidebar-width-trailing,320px);border-left:var(--chat-border,1px solid var(--md-sys-color-neutral-outline-variant))}:is(chat-sidebar[slot=leading],chat-sidebar[slot=trailing])>[data-resize]{cursor:col-resize;z-index:1;-webkit-user-select:none;user-select:none;width:6px;position:absolute;top:0;bottom:0}chat-sidebar[slot=leading]>[data-resize]{right:-3px}chat-sidebar[slot=trailing]>[data-resize]{left:-3px}:is(chat-sidebar[slot=leading],chat-sidebar[slot=trailing])>[data-resize]:hover{background:var(--md-sys-color-primary);opacity:.5}chat-sidebar[resizing]{transition:none}chat-sidebar[resizing]>[data-resize]{background:var(--md-sys-color-primary);opacity:.8}chat-shell:has(>chat-sidebar){flex-direction:row;display:flex}chat-shell:has(>chat-sidebar)>:not(chat-sidebar){display:contents}