@atelier-ui/angular 0.0.24 → 0.0.26

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.
@@ -38,7 +38,7 @@ class LlmButton {
38
38
  <span class="spinner" aria-hidden="true"></span>
39
39
  }
40
40
  <ng-content />
41
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--ui-spacing-2);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-medium);line-height:var(--ui-line-height-tight);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),color var(--ui-transition-fast),box-shadow var(--ui-transition-fast),transform var(--ui-transition-fast);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none}:host(:focus-visible){outline:none;box-shadow:var(--ui-focus-ring)}:host(.variant-primary){background-color:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary);box-shadow:var(--ui-shadow-xs)}:host(.variant-primary:hover:not(.is-disabled)){background-color:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-primary:active:not(.is-disabled)){background-color:var(--ui-color-primary-active);border-color:var(--ui-color-primary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-secondary){background-color:var(--ui-color-secondary);color:var(--ui-color-text-on-secondary);border-color:var(--ui-color-secondary);box-shadow:var(--ui-shadow-xs)}:host(.variant-secondary:hover:not(.is-disabled)){background-color:var(--ui-color-secondary-hover);border-color:var(--ui-color-secondary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-secondary:active:not(.is-disabled)){background-color:var(--ui-color-secondary-active);border-color:var(--ui-color-secondary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-outline){background-color:transparent;color:var(--ui-color-primary);border-color:var(--ui-color-border)}:host(.variant-outline:hover:not(.is-disabled)){background-color:var(--ui-color-primary-light);border-color:var(--ui-color-primary);transform:translateY(-1px)}:host(.variant-outline:active:not(.is-disabled)){background-color:color-mix(in srgb,var(--ui-color-primary) 12%,transparent);transform:scale(.97)}:host(.size-sm){padding:var(--ui-spacing-1) var(--ui-spacing-3);font-size:var(--ui-font-size-sm)}:host(.size-md){padding:var(--ui-spacing-2) var(--ui-spacing-4);font-size:var(--ui-font-size-md)}:host(.size-lg){padding:var(--ui-spacing-3) var(--ui-spacing-6);font-size:var(--ui-font-size-lg)}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed;pointer-events:none}.spinner{display:inline-block;width:1em;height:1em;border:1.5px solid currentColor;border-top-color:transparent;border-radius:var(--ui-radius-full);animation:llm-spin .7s linear infinite;flex-shrink:0}@keyframes llm-spin{to{transform:rotate(360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
41
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--ui-spacing-2);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-medium);line-height:var(--ui-line-height-tight);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),color var(--ui-transition-fast),box-shadow var(--ui-transition-fast),transform var(--ui-transition-fast);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none}:host(:focus-visible){outline:none;box-shadow:var(--ui-focus-ring)}:host(.variant-primary){background-color:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary);box-shadow:var(--ui-shadow-xs)}:host(.variant-primary:hover:not(.is-disabled)){background-color:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-primary:active:not(.is-disabled)){background-color:var(--ui-color-primary-active);border-color:var(--ui-color-primary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-secondary){background-color:var(--ui-color-secondary);color:var(--ui-color-text-on-secondary);border-color:var(--ui-color-secondary);box-shadow:var(--ui-shadow-xs)}:host(.variant-secondary:hover:not(.is-disabled)){background-color:var(--ui-color-secondary-hover);border-color:var(--ui-color-secondary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-secondary:active:not(.is-disabled)){background-color:var(--ui-color-secondary-active);border-color:var(--ui-color-secondary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-outline){background-color:transparent;color:var(--ui-color-primary);border-color:var(--ui-color-border)}:host(.variant-outline:hover:not(.is-disabled)){background-color:var(--ui-color-primary-light);border-color:var(--ui-color-primary);transform:translateY(-1px)}:host(.variant-outline:active:not(.is-disabled)){background-color:color-mix(in srgb,var(--ui-color-primary) 12%,transparent);transform:scale(.97)}:host(.variant-danger){background-color:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger);box-shadow:var(--ui-shadow-xs)}:host(.variant-danger:hover:not(.is-disabled)){background-color:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-danger:active:not(.is-disabled)){background-color:var(--ui-color-danger-active);border-color:var(--ui-color-danger-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.size-sm){padding:var(--ui-spacing-1) var(--ui-spacing-3);font-size:var(--ui-font-size-sm)}:host(.size-md){padding:var(--ui-spacing-2) var(--ui-spacing-4);font-size:var(--ui-font-size-md)}:host(.size-lg){padding:var(--ui-spacing-3) var(--ui-spacing-6);font-size:var(--ui-font-size-lg)}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed;pointer-events:none}.spinner{display:inline-block;width:1em;height:1em;border:1.5px solid currentColor;border-top-color:transparent;border-radius:var(--ui-radius-full);animation:llm-spin .7s linear infinite;flex-shrink:0}@keyframes llm-spin{to{transform:rotate(360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
42
42
  }
43
43
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmButton, decorators: [{
44
44
  type: Component,
@@ -52,7 +52,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
52
52
  '[class]': 'hostClasses()',
53
53
  '[attr.aria-disabled]': 'isDisabled()',
54
54
  '[attr.disabled]': 'isDisabled() ? true : null',
55
- }, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--ui-spacing-2);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-medium);line-height:var(--ui-line-height-tight);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),color var(--ui-transition-fast),box-shadow var(--ui-transition-fast),transform var(--ui-transition-fast);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none}:host(:focus-visible){outline:none;box-shadow:var(--ui-focus-ring)}:host(.variant-primary){background-color:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary);box-shadow:var(--ui-shadow-xs)}:host(.variant-primary:hover:not(.is-disabled)){background-color:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-primary:active:not(.is-disabled)){background-color:var(--ui-color-primary-active);border-color:var(--ui-color-primary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-secondary){background-color:var(--ui-color-secondary);color:var(--ui-color-text-on-secondary);border-color:var(--ui-color-secondary);box-shadow:var(--ui-shadow-xs)}:host(.variant-secondary:hover:not(.is-disabled)){background-color:var(--ui-color-secondary-hover);border-color:var(--ui-color-secondary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-secondary:active:not(.is-disabled)){background-color:var(--ui-color-secondary-active);border-color:var(--ui-color-secondary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-outline){background-color:transparent;color:var(--ui-color-primary);border-color:var(--ui-color-border)}:host(.variant-outline:hover:not(.is-disabled)){background-color:var(--ui-color-primary-light);border-color:var(--ui-color-primary);transform:translateY(-1px)}:host(.variant-outline:active:not(.is-disabled)){background-color:color-mix(in srgb,var(--ui-color-primary) 12%,transparent);transform:scale(.97)}:host(.size-sm){padding:var(--ui-spacing-1) var(--ui-spacing-3);font-size:var(--ui-font-size-sm)}:host(.size-md){padding:var(--ui-spacing-2) var(--ui-spacing-4);font-size:var(--ui-font-size-md)}:host(.size-lg){padding:var(--ui-spacing-3) var(--ui-spacing-6);font-size:var(--ui-font-size-lg)}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed;pointer-events:none}.spinner{display:inline-block;width:1em;height:1em;border:1.5px solid currentColor;border-top-color:transparent;border-radius:var(--ui-radius-full);animation:llm-spin .7s linear infinite;flex-shrink:0}@keyframes llm-spin{to{transform:rotate(360deg)}}\n"] }]
55
+ }, styles: [":host{display:inline-flex;align-items:center;justify-content:center;gap:var(--ui-spacing-2);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-medium);line-height:var(--ui-line-height-tight);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),color var(--ui-transition-fast),box-shadow var(--ui-transition-fast),transform var(--ui-transition-fast);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none}:host(:focus-visible){outline:none;box-shadow:var(--ui-focus-ring)}:host(.variant-primary){background-color:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary);box-shadow:var(--ui-shadow-xs)}:host(.variant-primary:hover:not(.is-disabled)){background-color:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-primary:active:not(.is-disabled)){background-color:var(--ui-color-primary-active);border-color:var(--ui-color-primary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-secondary){background-color:var(--ui-color-secondary);color:var(--ui-color-text-on-secondary);border-color:var(--ui-color-secondary);box-shadow:var(--ui-shadow-xs)}:host(.variant-secondary:hover:not(.is-disabled)){background-color:var(--ui-color-secondary-hover);border-color:var(--ui-color-secondary-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-secondary:active:not(.is-disabled)){background-color:var(--ui-color-secondary-active);border-color:var(--ui-color-secondary-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.variant-outline){background-color:transparent;color:var(--ui-color-primary);border-color:var(--ui-color-border)}:host(.variant-outline:hover:not(.is-disabled)){background-color:var(--ui-color-primary-light);border-color:var(--ui-color-primary);transform:translateY(-1px)}:host(.variant-outline:active:not(.is-disabled)){background-color:color-mix(in srgb,var(--ui-color-primary) 12%,transparent);transform:scale(.97)}:host(.variant-danger){background-color:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger);box-shadow:var(--ui-shadow-xs)}:host(.variant-danger:hover:not(.is-disabled)){background-color:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover);box-shadow:var(--ui-shadow-md);transform:translateY(-1px)}:host(.variant-danger:active:not(.is-disabled)){background-color:var(--ui-color-danger-active);border-color:var(--ui-color-danger-active);box-shadow:var(--ui-shadow-xs);transform:scale(.97)}:host(.size-sm){padding:var(--ui-spacing-1) var(--ui-spacing-3);font-size:var(--ui-font-size-sm)}:host(.size-md){padding:var(--ui-spacing-2) var(--ui-spacing-4);font-size:var(--ui-font-size-md)}:host(.size-lg){padding:var(--ui-spacing-3) var(--ui-spacing-6);font-size:var(--ui-font-size-lg)}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed;pointer-events:none}.spinner{display:inline-block;width:1em;height:1em;border:1.5px solid currentColor;border-top-color:transparent;border-radius:var(--ui-radius-full);animation:llm-spin .7s linear infinite;flex-shrink:0}@keyframes llm-spin{to{transform:rotate(360deg)}}\n"] }]
56
56
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
57
57
 
58
58
  /**
@@ -181,7 +181,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
181
181
  }, styles: [":host{display:inline-flex;align-items:center;justify-content:center;border-radius:var(--ui-radius-full);font-family:var(--ui-font-family);font-weight:var(--ui-font-weight-semibold);line-height:var(--ui-line-height-tight);white-space:nowrap;letter-spacing:.01em}:host(.size-sm){padding:.1875rem var(--ui-spacing-2);font-size:var(--ui-font-size-xs)}:host(.size-md){padding:.3125rem var(--ui-spacing-3);font-size:var(--ui-font-size-sm)}:host(.variant-default){background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text-muted);border:1px solid var(--ui-color-border)}:host(.variant-success){background-color:var(--ui-color-success-bg);color:var(--ui-color-success-text);border:1px solid color-mix(in srgb,var(--ui-color-success-text) 25%,transparent)}:host(.variant-warning){background-color:var(--ui-color-warning-bg);color:var(--ui-color-warning-text);border:1px solid color-mix(in srgb,var(--ui-color-warning-text) 25%,transparent)}:host(.variant-danger){background-color:var(--ui-color-danger-bg);color:var(--ui-color-danger-text);border:1px solid color-mix(in srgb,var(--ui-color-danger-text) 25%,transparent)}:host(.variant-info){background-color:var(--ui-color-info-bg);color:var(--ui-color-info-text);border:1px solid color-mix(in srgb,var(--ui-color-info-text) 25%,transparent)}.variant-icon{font-weight:700;margin-right:.3em;line-height:1}\n"] }]
182
182
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
183
183
 
184
- let nextId$c = 0;
184
+ let nextId$d = 0;
185
185
  /**
186
186
  * Accessible text input component for use with Angular Signal Forms.
187
187
  *
@@ -213,7 +213,7 @@ class LlmInput {
213
213
  /** The input's name attribute. Bound by [formField] directive. */
214
214
  name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
215
215
  /** @internal */
216
- errorId = `llm-input-errors-${nextId$c++}`;
216
+ errorId = `llm-input-errors-${nextId$d++}`;
217
217
  /** @internal */
218
218
  showErrors = computed(() => this.touched() && this.invalid() && this.errors().length > 0, ...(ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []));
219
219
  /** @internal */
@@ -290,7 +290,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
290
290
  }, styles: [":host{display:block;font-family:var(--ui-font-family);font-size:var(--ui-font-size-md)}input{display:block;width:100%;padding:.625rem var(--ui-spacing-3);font-size:inherit;font-family:inherit;line-height:var(--ui-line-height-normal);color:var(--ui-color-text);background-color:var(--ui-color-input-bg);border:1px solid var(--ui-color-input-border);border-radius:var(--ui-radius-md);box-shadow:inset 0 1px 2px #0000000a;transition:border-color var(--ui-transition-fast),box-shadow var(--ui-transition-fast),background-color var(--ui-transition-fast);outline:none;box-sizing:border-box}input::placeholder{color:var(--ui-color-placeholder)}input:hover:not(:disabled):not(:read-only){border-color:var(--ui-color-input-border-hover)}input:focus{border-color:var(--ui-color-input-border-focus);background-color:var(--ui-color-input-bg-focus);box-shadow:var(--ui-focus-ring)}.input-field{position:relative}:host(.is-invalid) input{border-color:var(--ui-color-input-border-invalid);padding-right:2rem}:host(.is-invalid) input:focus{border-color:var(--ui-color-input-border-invalid);box-shadow:0 0 0 2px var(--ui-color-surface),0 0 0 4px var(--ui-color-danger)}:host(.is-invalid) .input-field:before{content:\"\\2715\";position:absolute;top:.625rem;right:.75rem;color:var(--ui-color-danger);font-weight:700;line-height:1;pointer-events:none}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(.is-disabled) input{cursor:not-allowed}:host(.is-readonly) input{background-color:var(--ui-color-surface-sunken);cursor:default;box-shadow:none}.errors{margin-top:var(--ui-spacing-1)}.error-message{margin:0;font-size:var(--ui-font-size-sm);color:var(--ui-color-error-text);line-height:var(--ui-line-height-normal)}\n"] }]
291
291
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }] } });
292
292
 
293
- let nextId$b = 0;
293
+ let nextId$c = 0;
294
294
  /**
295
295
  * Accessible multiline text input component for use with Angular Signal Forms.
296
296
  *
@@ -324,7 +324,7 @@ class LlmTextarea {
324
324
  /** Whether to auto-resize the textarea height to fit its content. */
325
325
  autoResize = input(false, ...(ngDevMode ? [{ debugName: "autoResize" }] : /* istanbul ignore next */ []));
326
326
  /** @internal */
327
- errorId = `llm-textarea-errors-${nextId$b++}`;
327
+ errorId = `llm-textarea-errors-${nextId$c++}`;
328
328
  /** @internal */
329
329
  showErrors = computed(() => this.touched() && this.invalid() && this.errors().length > 0, ...(ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []));
330
330
  /** @internal */
@@ -407,7 +407,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
407
407
  }, styles: [":host{display:block;font-family:var(--ui-font-family);font-size:var(--ui-font-size-md)}textarea{display:block;width:100%;padding:.625rem var(--ui-spacing-3);font-size:inherit;font-family:inherit;line-height:var(--ui-line-height-normal);color:var(--ui-color-text);background-color:var(--ui-color-input-bg);border:1px solid var(--ui-color-input-border);border-radius:var(--ui-radius-md);box-shadow:inset 0 1px 2px #0000000a;transition:border-color var(--ui-transition-fast),box-shadow var(--ui-transition-fast),background-color var(--ui-transition-fast);outline:none;box-sizing:border-box;resize:vertical;min-height:80px}textarea::placeholder{color:var(--ui-color-placeholder)}textarea:hover:not(:disabled):not(:read-only){border-color:var(--ui-color-input-border-hover)}textarea:focus{border-color:var(--ui-color-input-border-focus);background-color:var(--ui-color-input-bg-focus);box-shadow:var(--ui-focus-ring)}.textarea-field{position:relative}:host(.is-invalid) textarea{border-color:var(--ui-color-input-border-invalid);padding-right:2rem}:host(.is-invalid) textarea:focus{border-color:var(--ui-color-input-border-invalid);box-shadow:0 0 0 2px var(--ui-color-surface),0 0 0 4px var(--ui-color-danger)}:host(.is-invalid) .textarea-field:before{content:\"\\2715\";position:absolute;top:.625rem;right:.75rem;color:var(--ui-color-danger);font-weight:700;line-height:1;pointer-events:none}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(.is-disabled) textarea{cursor:not-allowed}:host(.is-readonly) textarea{background-color:var(--ui-color-surface-sunken);cursor:default;box-shadow:none}:host(.is-auto-resize) textarea{resize:none;overflow:hidden}.errors{margin-top:var(--ui-spacing-1)}.error-message{margin:0;font-size:var(--ui-font-size-sm);color:var(--ui-color-error-text);line-height:var(--ui-line-height-normal)}\n"] }]
408
408
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], autoResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoResize", required: false }] }] } });
409
409
 
410
- let nextId$a = 0;
410
+ let nextId$b = 0;
411
411
  /**
412
412
  * Accessible checkbox component for use with Angular Signal Forms.
413
413
  *
@@ -435,9 +435,9 @@ class LlmCheckbox {
435
435
  /** Validation errors from the form system. Bound by [formField] directive. */
436
436
  errors = input([], ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
437
437
  /** @internal */
438
- inputId = `llm-checkbox-${nextId$a++}`;
438
+ inputId = `llm-checkbox-${nextId$b++}`;
439
439
  /** @internal */
440
- errorId = `llm-checkbox-errors-${nextId$a++}`;
440
+ errorId = `llm-checkbox-errors-${nextId$b++}`;
441
441
  /** @internal */
442
442
  nativeInput = viewChild('nativeInput', ...(ngDevMode ? [{ debugName: "nativeInput" }] : /* istanbul ignore next */ []));
443
443
  /** @internal */
@@ -528,7 +528,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
528
528
 
529
529
  const LLM_RADIO_GROUP = new InjectionToken('LLM_RADIO_GROUP');
530
530
 
531
- let nextId$9 = 0;
531
+ let nextId$a = 0;
532
532
  /**
533
533
  * Individual radio button. Must be placed inside an `llm-radio-group`.
534
534
  *
@@ -551,7 +551,7 @@ class LlmRadio {
551
551
  /** @internal */
552
552
  el = inject(ElementRef);
553
553
  /** @internal */
554
- inputId = `llm-radio-${nextId$9++}`;
554
+ inputId = `llm-radio-${nextId$a++}`;
555
555
  /** @internal */
556
556
  isChecked = computed(() => this.group?.value() === this.radioValue(), ...(ngDevMode ? [{ debugName: "isChecked" }] : /* istanbul ignore next */ []));
557
557
  /** @internal */
@@ -627,7 +627,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
627
627
  }, styles: [":host{display:block;font-family:var(--ui-font-family);font-size:var(--ui-font-size-md)}label{display:inline-flex;align-items:center;gap:var(--ui-spacing-2);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--ui-color-text);line-height:var(--ui-line-height-normal)}input[type=radio]{appearance:none;-webkit-appearance:none;flex-shrink:0;width:1.25rem;height:1.25rem;border:1.5px solid var(--ui-color-input-border);border-radius:50%;background-color:var(--ui-color-input-bg);cursor:pointer;position:relative;transition:border-color var(--ui-transition-fast),background-color var(--ui-transition-fast),box-shadow var(--ui-transition-fast);outline:none}input[type=radio]:hover:not(:disabled){border-color:var(--ui-color-input-border-hover);background-color:var(--ui-color-primary-light)}input[type=radio]:focus-visible{box-shadow:var(--ui-focus-ring);border-color:var(--ui-color-input-border-focus)}input[type=radio]:checked{background-color:var(--ui-color-primary);border-color:var(--ui-color-primary)}input[type=radio]:checked:after{content:\"\";position:absolute;inset:0;margin:auto;width:.45rem;height:.45rem;border-radius:50%;background-color:var(--ui-color-on-primary);animation:llm-radio-pop var(--ui-duration-normal) var(--ui-ease-spring)}:host-context(llm-radio-group.is-invalid) input[type=radio],:host(.is-invalid) input[type=radio]{border-color:var(--ui-color-input-border-invalid)}:host-context(llm-radio-group.is-invalid) input[type=radio]:focus-visible,:host(.is-invalid) input[type=radio]:focus-visible{border-color:var(--ui-color-input-border-invalid);box-shadow:0 0 0 2px var(--ui-color-surface),0 0 0 4px var(--ui-color-danger)}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(.is-disabled) label{cursor:not-allowed}:host(.is-disabled) input[type=radio]{cursor:not-allowed}@keyframes llm-radio-pop{0%{transform:scale(0)}60%{transform:scale(1.2)}to{transform:scale(1)}}\n"] }]
628
628
  }], propDecorators: { radioValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "radioValue", required: true }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
629
629
 
630
- let nextId$8 = 0;
630
+ let nextId$9 = 0;
631
631
  /**
632
632
  * Container for a group of radio buttons. Manages keyboard navigation, shared name,
633
633
  * and Signal Forms integration.
@@ -662,7 +662,7 @@ class LlmRadioGroup {
662
662
  /** Validation errors from the form system. Bound by [formField] directive. */
663
663
  errors = input([], ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
664
664
  /** @internal */
665
- errorId = `llm-radio-group-errors-${nextId$8++}`;
665
+ errorId = `llm-radio-group-errors-${nextId$9++}`;
666
666
  /** @internal */
667
667
  items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
668
668
  /** @internal */
@@ -751,7 +751,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
751
751
  }, providers: [{ provide: LLM_RADIO_GROUP, useExisting: LlmRadioGroup }], styles: [":host{display:block;font-family:var(--ui-font-family)}:host(.is-disabled){opacity:var(--ui-opacity-disabled);cursor:not-allowed}.errors{margin-top:var(--ui-spacing-1)}.error-message{margin:0;font-size:var(--ui-font-size-sm);color:var(--ui-color-error-text);line-height:var(--ui-line-height-normal)}\n"] }]
752
752
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }] } });
753
753
 
754
- let nextId$7 = 0;
754
+ let nextId$8 = 0;
755
755
  /**
756
756
  * Accessible toggle (switch) component for use with Angular Signal Forms.
757
757
  * Presents as a pill-shaped on/off slider instead of a checkbox box,
@@ -779,9 +779,9 @@ class LlmToggle {
779
779
  /** Validation errors from the form system. Bound by [formField] directive. */
780
780
  errors = input([], ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
781
781
  /** @internal */
782
- inputId = `llm-toggle-${nextId$7++}`;
782
+ inputId = `llm-toggle-${nextId$8++}`;
783
783
  /** @internal */
784
- errorId = `llm-toggle-errors-${nextId$7++}`;
784
+ errorId = `llm-toggle-errors-${nextId$8++}`;
785
785
  /** @internal */
786
786
  showErrors = computed(() => this.touched() && this.invalid() && this.errors().length > 0, ...(ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []));
787
787
  /** @internal */
@@ -973,7 +973,7 @@ class SelectOptionItem {
973
973
  // Handled by key manager — no-op here
974
974
  }
975
975
  }
976
- let nextId$6 = 0;
976
+ let nextId$7 = 0;
977
977
  /**
978
978
  * Accessible dropdown select component for use with Angular Signal Forms.
979
979
  * Uses the CDK Overlay for viewport-aware panel positioning.
@@ -1017,11 +1017,11 @@ class LlmSelect {
1017
1017
  /** @internal */
1018
1018
  panelRef = viewChild('panel', ...(ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []));
1019
1019
  /** @internal */
1020
- triggerId = `llm-select-trigger-${nextId$6}`;
1020
+ triggerId = `llm-select-trigger-${nextId$7}`;
1021
1021
  /** @internal */
1022
- panelId = `llm-select-panel-${nextId$6}`;
1022
+ panelId = `llm-select-panel-${nextId$7}`;
1023
1023
  /** @internal */
1024
- errorId = `llm-select-errors-${nextId$6++}`;
1024
+ errorId = `llm-select-errors-${nextId$7++}`;
1025
1025
  /** @internal */
1026
1026
  selectedLabel = computed(() => this.optionsList().find((o) => o.value === this.value())?.labelText ?? '', ...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
1027
1027
  /** @internal */
@@ -1362,7 +1362,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1362
1362
  }]
1363
1363
  }], propDecorators: { optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
1364
1364
 
1365
- let nextId$5 = 0;
1365
+ let nextId$6 = 0;
1366
1366
  /**
1367
1367
  * Filterable autocomplete combobox. Accepts an `options` array and emits the
1368
1368
  * selected option's `value`. The user types to narrow the list; selecting an
@@ -1410,11 +1410,11 @@ class LlmCombobox {
1410
1410
  /** @internal */
1411
1411
  inputEl = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
1412
1412
  /** @internal */
1413
- inputId = `llm-combobox-input-${nextId$5}`;
1413
+ inputId = `llm-combobox-input-${nextId$6}`;
1414
1414
  /** @internal */
1415
- panelId = `llm-combobox-panel-${nextId$5}`;
1415
+ panelId = `llm-combobox-panel-${nextId$6}`;
1416
1416
  /** @internal */
1417
- errorId = `llm-combobox-errors-${nextId$5++}`;
1417
+ errorId = `llm-combobox-errors-${nextId$6++}`;
1418
1418
  /** @internal */
1419
1419
  filteredOptions = computed(() => {
1420
1420
  const q = this.query().toLowerCase();
@@ -1713,7 +1713,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1713
1713
 
1714
1714
  const LLM_DIALOG = new InjectionToken('LLM_DIALOG');
1715
1715
 
1716
- let nextId$4 = 0;
1716
+ let nextId$5 = 0;
1717
1717
  /**
1718
1718
  * Accessible modal dialog using the native `<dialog>` element.
1719
1719
  * Includes focus trap, Escape to close, backdrop click to close, and animation.
@@ -1742,8 +1742,8 @@ class LlmDialog {
1742
1742
  /** ID of the element that labels the dialog (defaults to the llm-dialog-header id). */
1743
1743
  ariaLabelledby = input('', { ...(ngDevMode ? { debugName: "ariaLabelledby" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
1744
1744
  /** @internal — referenced by LlmDialogHeader via LLM_DIALOG token */
1745
- headerId = `llm-dialog-header-${nextId$4}`;
1746
- dialogId = `llm-dialog-${nextId$4++}`;
1745
+ headerId = `llm-dialog-header-${nextId$5}`;
1746
+ dialogId = `llm-dialog-${nextId$5++}`;
1747
1747
  dialogRef = viewChild('dialogEl', ...(ngDevMode ? [{ debugName: "dialogRef" }] : /* istanbul ignore next */ []));
1748
1748
  triggerEl = signal(null, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
1749
1749
  panelClass = computed(() => `panel size-${this.size()}`, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
@@ -1921,7 +1921,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1921
1921
 
1922
1922
  const LLM_TAB_GROUP = new InjectionToken('LLM_TAB_GROUP');
1923
1923
 
1924
- let nextId$3 = 0;
1924
+ let nextId$4 = 0;
1925
1925
  /**
1926
1926
  * Accessible tabbed interface container. Renders a tab list and manages
1927
1927
  * keyboard navigation with roving tabindex.
@@ -2058,11 +2058,11 @@ class LlmTab {
2058
2058
  /** Whether this tab is disabled. */
2059
2059
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
2060
2060
  /** @internal */
2061
- tabId = `llm-tab-${nextId$3}`;
2061
+ tabId = `llm-tab-${nextId$4}`;
2062
2062
  /** @internal */
2063
- panelId = `llm-tab-panel-${nextId$3}`;
2063
+ panelId = `llm-tab-panel-${nextId$4}`;
2064
2064
  /** @internal */
2065
- id = `llm-tab-instance-${nextId$3++}`;
2065
+ id = `llm-tab-instance-${nextId$4++}`;
2066
2066
  /** @internal */
2067
2067
  context = inject(LLM_TAB_GROUP);
2068
2068
  /** @internal */
@@ -2114,7 +2114,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
2114
2114
 
2115
2115
  const LLM_ACCORDION_GROUP = new InjectionToken('LLM_ACCORDION_GROUP');
2116
2116
 
2117
- let nextId$2 = 0;
2117
+ let nextId$3 = 0;
2118
2118
  /**
2119
2119
  * Container that manages accordion items. Controls single vs multi expansion
2120
2120
  * and provides keyboard navigation across items.
@@ -2220,7 +2220,7 @@ class LlmAccordionItem {
2220
2220
  return this.disabledInput();
2221
2221
  }
2222
2222
  /** @internal */
2223
- id = `llm-accordion-item-${nextId$2++}`;
2223
+ id = `llm-accordion-item-${nextId$3++}`;
2224
2224
  /** @internal */
2225
2225
  triggerId = `${this.id}-trigger`;
2226
2226
  /** @internal */
@@ -3374,7 +3374,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
3374
3374
 
3375
3375
  const LLM_DRAWER = new InjectionToken('LLM_DRAWER');
3376
3376
 
3377
- let nextId$1 = 0;
3377
+ let nextId$2 = 0;
3378
3378
  /**
3379
3379
  * Slide-in drawer panel using the native `<dialog>` element.
3380
3380
  * Supports left, right, top, and bottom positions with focus trap,
@@ -3403,8 +3403,8 @@ class LlmDrawer {
3403
3403
  /** Whether clicking the backdrop closes the drawer. */
3404
3404
  closeOnBackdrop = input(true, ...(ngDevMode ? [{ debugName: "closeOnBackdrop" }] : /* istanbul ignore next */ []));
3405
3405
  /** @internal — referenced by LlmDrawerHeader via LLM_DRAWER token */
3406
- headerId = `llm-drawer-header-${nextId$1}`;
3407
- drawerId = `llm-drawer-${nextId$1++}`;
3406
+ headerId = `llm-drawer-header-${nextId$2}`;
3407
+ drawerId = `llm-drawer-${nextId$2++}`;
3408
3408
  dialogRef = viewChild('dialogEl', ...(ngDevMode ? [{ debugName: "dialogRef" }] : /* istanbul ignore next */ []));
3409
3409
  triggerEl = signal(null, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
3410
3410
  hostClasses = computed(() => `position-${this.position()} size-${this.size()}${this.open() ? ' is-open' : ''}`, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
@@ -3921,7 +3921,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
3921
3921
 
3922
3922
  const LLM_STEPPER = new InjectionToken('LLM_STEPPER');
3923
3923
 
3924
- let nextId = 0;
3924
+ let nextId$1 = 0;
3925
3925
  /**
3926
3926
  * Multi-step wizard container.
3927
3927
  *
@@ -4132,7 +4132,7 @@ class LlmStep {
4132
4132
  /** Whether this step is disabled. */
4133
4133
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
4134
4134
  /** @internal */
4135
- id = `llm-step-instance-${nextId++}`;
4135
+ id = `llm-step-instance-${nextId$1++}`;
4136
4136
  /** @internal */
4137
4137
  context = inject(LLM_STEPPER);
4138
4138
  /** @internal */
@@ -4312,6 +4312,476 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
4312
4312
  }, styles: [":host{display:block;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-md);overflow:hidden;font-family:var(--ui-font-family)}.code-block-header{display:flex;align-items:center;justify-content:space-between;padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-raised);border-bottom:1px solid var(--ui-color-border);min-height:2.25rem}.code-block-label{font-family:var(--ui-font-mono, \"Menlo\", \"Monaco\", \"Courier New\", monospace);font-size:.72rem;font-weight:600;letter-spacing:.03em;color:var(--ui-color-text-muted);text-transform:lowercase;-webkit-user-select:none;user-select:none}.code-block-copy{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem .55rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);background:transparent;color:var(--ui-color-text-muted);font-family:inherit;font-size:.72rem;font-weight:500;cursor:pointer;transition:color var(--ui-transition-fast),background var(--ui-transition-fast),border-color var(--ui-transition-fast);white-space:nowrap}.code-block-copy:hover{color:var(--ui-color-text);background:var(--ui-color-surface);border-color:var(--ui-color-input-border)}.code-block-copy:focus-visible{outline:var(--ui-focus-ring);outline-offset:2px}.code-block-body{background:var(--ui-color-surface);overflow-x:auto}.code-block-pre{margin:0;padding:var(--ui-spacing-4);font-family:var(--ui-font-mono, \"Menlo\", \"Monaco\", \"Courier New\", monospace);font-size:var(--ui-font-size-sm);line-height:1.65;color:var(--ui-color-text);white-space:pre;tab-size:2}.code-line{display:flex}.code-line-number{display:inline-block;min-width:2rem;padding-right:var(--ui-spacing-3);color:var(--ui-color-text-muted);text-align:right;-webkit-user-select:none;user-select:none;border-right:1px solid var(--ui-color-border);margin-right:var(--ui-spacing-3);flex-shrink:0;opacity:.6}.code-line-text{flex:1}\n"] }]
4313
4313
  }], propDecorators: { code: [{ type: i0.Input, args: [{ isSignal: true, alias: "code", required: false }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], filename: [{ type: i0.Input, args: [{ isSignal: true, alias: "filename", required: false }] }], copyable: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyable", required: false }] }], showLineNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLineNumbers", required: false }] }] } });
4314
4314
 
4315
+ const LLM_CHAT = new InjectionToken('LLM_CHAT');
4316
+
4317
+ let nextId = 0;
4318
+ /**
4319
+ * AI assistant surface. Three layout variants share the same content slots
4320
+ * and can be swapped without changing the children.
4321
+ *
4322
+ * Variants:
4323
+ * - `drawer`: Right-anchored slide-in panel, full viewport height.
4324
+ * - `popup`: Floating bubble (bottom-right) + compact chat window.
4325
+ * - `inline`: Embedded card, sits inline with page content.
4326
+ *
4327
+ * Compose with `llm-chat-header`, `llm-chat-messages`, `llm-chat-input`.
4328
+ *
4329
+ * Usage:
4330
+ * ```html
4331
+ * <llm-chat variant="drawer" [(open)]="isOpen" status="idle">
4332
+ * <llm-chat-header>AI Assistant</llm-chat-header>
4333
+ * <llm-chat-messages>
4334
+ * <llm-chat-message role="assistant">Hi! How can I help?</llm-chat-message>
4335
+ * <llm-chat-message role="user">Show me a sorting function.</llm-chat-message>
4336
+ * </llm-chat-messages>
4337
+ * <llm-chat-input placeholder="Ask anything…" (send)="onSend($event)" />
4338
+ * </llm-chat>
4339
+ * ```
4340
+ */
4341
+ class LlmChat {
4342
+ /** Layout variant. */
4343
+ variant = input('drawer', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
4344
+ /** Whether the chat is open. Used by drawer/popup; ignored by inline. Two-way bindable via [(open)]. */
4345
+ open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
4346
+ /** Connection / response status. Drives badge color in header and disables input while streaming. */
4347
+ status = input('idle', ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
4348
+ /** @internal — referenced by LlmChatHeader via LLM_CHAT token for aria-labelledby. */
4349
+ headerId = `llm-chat-header-${nextId++}`;
4350
+ dialogRef = viewChild('dialogEl', ...(ngDevMode ? [{ debugName: "dialogRef" }] : /* istanbul ignore next */ []));
4351
+ triggerEl = signal(null, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
4352
+ hostClasses = computed(() => `variant-${this.variant()} status-${this.status()}${this.open() ? ' is-open' : ''}`, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
4353
+ constructor() {
4354
+ // Drawer variant uses native <dialog> open/close lifecycle.
4355
+ effect(() => {
4356
+ if (this.variant() !== 'drawer')
4357
+ return;
4358
+ const dialog = this.dialogRef()?.nativeElement;
4359
+ if (!dialog)
4360
+ return;
4361
+ if (this.open()) {
4362
+ this.triggerEl.set(document.activeElement);
4363
+ dialog.showModal();
4364
+ }
4365
+ else {
4366
+ if (dialog.open)
4367
+ dialog.close();
4368
+ this.triggerEl()?.focus();
4369
+ this.triggerEl.set(null);
4370
+ }
4371
+ });
4372
+ }
4373
+ onCancel(event) {
4374
+ event.preventDefault();
4375
+ this.open.set(false);
4376
+ }
4377
+ onBackdropClick(event) {
4378
+ if (event.target === this.dialogRef()?.nativeElement) {
4379
+ this.open.set(false);
4380
+ }
4381
+ }
4382
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChat, deps: [], target: i0.ɵɵFactoryTarget.Component });
4383
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: LlmChat, isStandalone: true, selector: "llm-chat", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { properties: { "class": "hostClasses()" } }, providers: [
4384
+ {
4385
+ provide: LLM_CHAT,
4386
+ useFactory: (chat) => ({
4387
+ headerId: chat.headerId,
4388
+ status: chat.status,
4389
+ close: () => chat.open.set(false),
4390
+ toggle: () => chat.open.set(!chat.open()),
4391
+ }),
4392
+ deps: [LlmChat],
4393
+ },
4394
+ ], viewQueries: [{ propertyName: "dialogRef", first: true, predicate: ["dialogEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
4395
+ @switch (variant()) {
4396
+ @case ('drawer') {
4397
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
4398
+ <dialog
4399
+ #dialogEl
4400
+ [attr.aria-labelledby]="headerId"
4401
+ aria-modal="true"
4402
+ [cdkTrapFocus]="open()"
4403
+ (cancel)="onCancel($event)"
4404
+ (close)="open.set(false)"
4405
+ (click)="onBackdropClick($event)"
4406
+ >
4407
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
4408
+ <div class="surface drawer-surface" (click)="$event.stopPropagation()">
4409
+ <ng-content />
4410
+ </div>
4411
+ </dialog>
4412
+ }
4413
+ @case ('popup') {
4414
+ @if (open()) {
4415
+ <div class="surface popup-surface" [attr.aria-labelledby]="headerId" role="dialog">
4416
+ <ng-content />
4417
+ </div>
4418
+ }
4419
+ <button
4420
+ type="button"
4421
+ class="fab-bubble"
4422
+ [attr.aria-label]="open() ? 'Close AI assistant' : 'Open AI assistant'"
4423
+ [attr.aria-expanded]="open()"
4424
+ (click)="open.set(!open())"
4425
+ >
4426
+ <span aria-hidden="true">AI</span>
4427
+ </button>
4428
+ }
4429
+ @default {
4430
+ <section class="surface inline-surface" [attr.aria-labelledby]="headerId">
4431
+ <ng-content />
4432
+ </section>
4433
+ }
4434
+ }
4435
+ `, isInline: true, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1$1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4436
+ }
4437
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChat, decorators: [{
4438
+ type: Component,
4439
+ args: [{ selector: 'llm-chat', standalone: true, imports: [A11yModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
4440
+ {
4441
+ provide: LLM_CHAT,
4442
+ useFactory: (chat) => ({
4443
+ headerId: chat.headerId,
4444
+ status: chat.status,
4445
+ close: () => chat.open.set(false),
4446
+ toggle: () => chat.open.set(!chat.open()),
4447
+ }),
4448
+ deps: [LlmChat],
4449
+ },
4450
+ ], template: `
4451
+ @switch (variant()) {
4452
+ @case ('drawer') {
4453
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
4454
+ <dialog
4455
+ #dialogEl
4456
+ [attr.aria-labelledby]="headerId"
4457
+ aria-modal="true"
4458
+ [cdkTrapFocus]="open()"
4459
+ (cancel)="onCancel($event)"
4460
+ (close)="open.set(false)"
4461
+ (click)="onBackdropClick($event)"
4462
+ >
4463
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
4464
+ <div class="surface drawer-surface" (click)="$event.stopPropagation()">
4465
+ <ng-content />
4466
+ </div>
4467
+ </dialog>
4468
+ }
4469
+ @case ('popup') {
4470
+ @if (open()) {
4471
+ <div class="surface popup-surface" [attr.aria-labelledby]="headerId" role="dialog">
4472
+ <ng-content />
4473
+ </div>
4474
+ }
4475
+ <button
4476
+ type="button"
4477
+ class="fab-bubble"
4478
+ [attr.aria-label]="open() ? 'Close AI assistant' : 'Open AI assistant'"
4479
+ [attr.aria-expanded]="open()"
4480
+ (click)="open.set(!open())"
4481
+ >
4482
+ <span aria-hidden="true">AI</span>
4483
+ </button>
4484
+ }
4485
+ @default {
4486
+ <section class="surface inline-surface" [attr.aria-labelledby]="headerId">
4487
+ <ng-content />
4488
+ </section>
4489
+ }
4490
+ }
4491
+ `, host: {
4492
+ '[class]': 'hostClasses()',
4493
+ }, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"] }]
4494
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], dialogRef: [{ type: i0.ViewChild, args: ['dialogEl', { isSignal: true }] }] } });
4495
+ /**
4496
+ * Header slot for `llm-chat`. Holds the title, status indicator, and close button.
4497
+ * Children are projected into the title area; the close button is rendered automatically.
4498
+ */
4499
+ class LlmChatHeader {
4500
+ context = inject(LLM_CHAT);
4501
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
4502
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: LlmChatHeader, isStandalone: true, selector: "llm-chat-header", host: { properties: { "attr.id": "context.headerId" } }, ngImport: i0, template: `
4503
+ <div class="title-block">
4504
+ <ng-content />
4505
+ </div>
4506
+ <button
4507
+ type="button"
4508
+ class="close-btn"
4509
+ aria-label="Close chat"
4510
+ (click)="context.close()"
4511
+ >
4512
+ <svg
4513
+ xmlns="http://www.w3.org/2000/svg"
4514
+ width="14"
4515
+ height="14"
4516
+ viewBox="0 0 24 24"
4517
+ fill="none"
4518
+ stroke="currentColor"
4519
+ stroke-width="2.5"
4520
+ stroke-linecap="round"
4521
+ stroke-linejoin="round"
4522
+ aria-hidden="true"
4523
+ focusable="false"
4524
+ >
4525
+ <line x1="18" y1="6" x2="6" y2="18" />
4526
+ <line x1="6" y1="6" x2="18" y2="18" />
4527
+ </svg>
4528
+ </button>
4529
+ `, isInline: true, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4530
+ }
4531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatHeader, decorators: [{
4532
+ type: Component,
4533
+ args: [{ selector: 'llm-chat-header', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
4534
+ <div class="title-block">
4535
+ <ng-content />
4536
+ </div>
4537
+ <button
4538
+ type="button"
4539
+ class="close-btn"
4540
+ aria-label="Close chat"
4541
+ (click)="context.close()"
4542
+ >
4543
+ <svg
4544
+ xmlns="http://www.w3.org/2000/svg"
4545
+ width="14"
4546
+ height="14"
4547
+ viewBox="0 0 24 24"
4548
+ fill="none"
4549
+ stroke="currentColor"
4550
+ stroke-width="2.5"
4551
+ stroke-linecap="round"
4552
+ stroke-linejoin="round"
4553
+ aria-hidden="true"
4554
+ focusable="false"
4555
+ >
4556
+ <line x1="18" y1="6" x2="6" y2="18" />
4557
+ <line x1="6" y1="6" x2="18" y2="18" />
4558
+ </svg>
4559
+ </button>
4560
+ `, host: {
4561
+ '[attr.id]': 'context.headerId',
4562
+ }, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"] }]
4563
+ }] });
4564
+ /**
4565
+ * Scrollable message list for `llm-chat`. Project `llm-chat-message`,
4566
+ * `llm-chat-typing`, or `llm-chat-suggestion` children inside.
4567
+ */
4568
+ class LlmChatMessages {
4569
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatMessages, deps: [], target: i0.ɵɵFactoryTarget.Component });
4570
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: LlmChatMessages, isStandalone: true, selector: "llm-chat-messages", ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4571
+ }
4572
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatMessages, decorators: [{
4573
+ type: Component,
4574
+ args: [{ selector: 'llm-chat-messages', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `<ng-content />`, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"] }]
4575
+ }] });
4576
+ /**
4577
+ * A single chat message. Role drives bubble alignment and color.
4578
+ *
4579
+ * Usage:
4580
+ * ```html
4581
+ * <llm-chat-message role="assistant">Sure, here you go.</llm-chat-message>
4582
+ * <llm-chat-message role="user">Thanks!</llm-chat-message>
4583
+ * <llm-chat-message role="assistant" [failed]="true">Couldn't reach the assistant.</llm-chat-message>
4584
+ * ```
4585
+ */
4586
+ class LlmChatMessage {
4587
+ /** Sender of the message. Drives bubble alignment and color. */
4588
+ role = input('assistant', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
4589
+ /** Marks the message as failed (red dashed border, used in error state). */
4590
+ failed = input(false, ...(ngDevMode ? [{ debugName: "failed" }] : /* istanbul ignore next */ []));
4591
+ hostClasses = computed(() => `role-${this.role()}${this.failed() ? ' is-failed' : ''}`, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
4592
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatMessage, deps: [], target: i0.ɵɵFactoryTarget.Component });
4593
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: LlmChatMessage, isStandalone: true, selector: "llm-chat-message", inputs: { role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, failed: { classPropertyName: "failed", publicName: "failed", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.role": "\"listitem\"" } }, ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4594
+ }
4595
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatMessage, decorators: [{
4596
+ type: Component,
4597
+ args: [{ selector: 'llm-chat-message', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `<ng-content />`, host: {
4598
+ '[class]': 'hostClasses()',
4599
+ '[attr.role]': '"listitem"',
4600
+ }, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"] }]
4601
+ }], propDecorators: { role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], failed: [{ type: i0.Input, args: [{ isSignal: true, alias: "failed", required: false }] }] } });
4602
+ /**
4603
+ * Typing indicator (three animated dots). Render at the end of the message
4604
+ * list while the assistant is streaming a response.
4605
+ */
4606
+ class LlmChatTyping {
4607
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatTyping, deps: [], target: i0.ɵɵFactoryTarget.Component });
4608
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: LlmChatTyping, isStandalone: true, selector: "llm-chat-typing", host: { properties: { "attr.role": "\"status\"", "attr.aria-live": "\"polite\"" } }, ngImport: i0, template: `
4609
+ <span class="dot"></span>
4610
+ <span class="dot"></span>
4611
+ <span class="dot"></span>
4612
+ <span class="sr-only">Assistant is typing</span>
4613
+ `, isInline: true, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4614
+ }
4615
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatTyping, decorators: [{
4616
+ type: Component,
4617
+ args: [{ selector: 'llm-chat-typing', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
4618
+ <span class="dot"></span>
4619
+ <span class="dot"></span>
4620
+ <span class="dot"></span>
4621
+ <span class="sr-only">Assistant is typing</span>
4622
+ `, host: {
4623
+ '[attr.role]': '"status"',
4624
+ '[attr.aria-live]': '"polite"',
4625
+ }, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"] }]
4626
+ }] });
4627
+ /**
4628
+ * Tappable suggestion chip used in the empty state to seed a conversation.
4629
+ *
4630
+ * Usage:
4631
+ * ```html
4632
+ * <llm-chat-suggestion label="Explain a code snippet" hint="Tap to start →" (selected)="prompt.set($event)" />
4633
+ * ```
4634
+ */
4635
+ class LlmChatSuggestion {
4636
+ /** Primary label of the suggestion. */
4637
+ label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4638
+ /** Optional secondary hint text shown below the label. */
4639
+ hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
4640
+ /** Fires the label string when the chip is activated. */
4641
+ selected = output();
4642
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatSuggestion, deps: [], target: i0.ɵɵFactoryTarget.Component });
4643
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: LlmChatSuggestion, isStandalone: true, selector: "llm-chat-suggestion", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, ngImport: i0, template: `
4644
+ <button type="button" class="chip" (click)="selected.emit(label())">
4645
+ <span class="chip-label">{{ label() }}</span>
4646
+ @if (hint()) {
4647
+ <span class="chip-hint">{{ hint() }}</span>
4648
+ }
4649
+ </button>
4650
+ `, isInline: true, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4651
+ }
4652
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatSuggestion, decorators: [{
4653
+ type: Component,
4654
+ args: [{ selector: 'llm-chat-suggestion', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
4655
+ <button type="button" class="chip" (click)="selected.emit(label())">
4656
+ <span class="chip-label">{{ label() }}</span>
4657
+ @if (hint()) {
4658
+ <span class="chip-hint">{{ hint() }}</span>
4659
+ }
4660
+ </button>
4661
+ `, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"] }]
4662
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], selected: [{ type: i0.Output, args: ["selected"] }] } });
4663
+ /**
4664
+ * Composable input footer for `llm-chat`. Wraps a text field and emits
4665
+ * `send` (or `stop` while the assistant is streaming).
4666
+ *
4667
+ * The button automatically switches to a `danger` "Stop" button when the
4668
+ * parent chat's `status` is `'streaming'`.
4669
+ *
4670
+ * Usage:
4671
+ * ```html
4672
+ * <llm-chat-input placeholder="Ask anything…" (send)="onSend($event)" (stop)="onStop()" />
4673
+ * ```
4674
+ */
4675
+ class LlmChatInput {
4676
+ /** Placeholder shown in the empty input. Defaults change per parent status. */
4677
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
4678
+ /** Accessible label for the input field. */
4679
+ ariaLabel = input('Message your AI assistant', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
4680
+ /** Two-way bindable text content. */
4681
+ value = model('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
4682
+ /** Fires when Enter is pressed (without Shift) or the Send button is clicked. */
4683
+ send = output();
4684
+ /** Fires when the Stop button is clicked while the parent chat is streaming. */
4685
+ stop = output();
4686
+ context = inject(LLM_CHAT);
4687
+ isStreaming = computed(() => this.context.status() === 'streaming', ...(ngDevMode ? [{ debugName: "isStreaming" }] : /* istanbul ignore next */ []));
4688
+ effectivePlaceholder = computed(() => {
4689
+ const explicit = this.placeholder();
4690
+ if (explicit)
4691
+ return explicit;
4692
+ switch (this.context.status()) {
4693
+ case 'streaming':
4694
+ return 'Waiting for response…';
4695
+ case 'error':
4696
+ return 'Try again…';
4697
+ default:
4698
+ return 'Message your AI assistant…';
4699
+ }
4700
+ }, ...(ngDevMode ? [{ debugName: "effectivePlaceholder" }] : /* istanbul ignore next */ []));
4701
+ onInput(event) {
4702
+ const target = event.target;
4703
+ this.value.set(target.value);
4704
+ }
4705
+ onEnter(event) {
4706
+ const ke = event;
4707
+ if (ke.shiftKey)
4708
+ return;
4709
+ ke.preventDefault();
4710
+ this.emitSend();
4711
+ }
4712
+ emitSend() {
4713
+ const text = this.value().trim();
4714
+ if (!text || this.isStreaming())
4715
+ return;
4716
+ this.send.emit(text);
4717
+ this.value.set('');
4718
+ }
4719
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
4720
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: LlmChatInput, isStandalone: true, selector: "llm-chat-input", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", send: "send", stop: "stop" }, ngImport: i0, template: `
4721
+ <textarea
4722
+ class="field"
4723
+ [value]="value()"
4724
+ [placeholder]="effectivePlaceholder()"
4725
+ [disabled]="isStreaming()"
4726
+ [attr.aria-label]="ariaLabel()"
4727
+ (input)="onInput($event)"
4728
+ (keydown.enter)="onEnter($event)"
4729
+ rows="1"
4730
+ ></textarea>
4731
+ @if (isStreaming()) {
4732
+ <button
4733
+ type="button"
4734
+ class="action-btn variant-danger size-md"
4735
+ (click)="stop.emit()"
4736
+ >
4737
+ Stop
4738
+ </button>
4739
+ } @else {
4740
+ <button
4741
+ type="button"
4742
+ class="action-btn variant-primary size-md"
4743
+ [disabled]="!value().trim()"
4744
+ (click)="emitSend()"
4745
+ >
4746
+ Send
4747
+ </button>
4748
+ }
4749
+ `, isInline: true, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4750
+ }
4751
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LlmChatInput, decorators: [{
4752
+ type: Component,
4753
+ args: [{ selector: 'llm-chat-input', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
4754
+ <textarea
4755
+ class="field"
4756
+ [value]="value()"
4757
+ [placeholder]="effectivePlaceholder()"
4758
+ [disabled]="isStreaming()"
4759
+ [attr.aria-label]="ariaLabel()"
4760
+ (input)="onInput($event)"
4761
+ (keydown.enter)="onEnter($event)"
4762
+ rows="1"
4763
+ ></textarea>
4764
+ @if (isStreaming()) {
4765
+ <button
4766
+ type="button"
4767
+ class="action-btn variant-danger size-md"
4768
+ (click)="stop.emit()"
4769
+ >
4770
+ Stop
4771
+ </button>
4772
+ } @else {
4773
+ <button
4774
+ type="button"
4775
+ class="action-btn variant-primary size-md"
4776
+ [disabled]="!value().trim()"
4777
+ (click)="emitSend()"
4778
+ >
4779
+ Send
4780
+ </button>
4781
+ }
4782
+ `, styles: [":host(llm-chat){display:contents}.surface{display:flex;flex-direction:column;background:var(--ui-color-surface);color:var(--ui-color-text);overflow:hidden}:host(.variant-drawer) dialog{all:unset;position:fixed;inset:0 0 0 auto;height:100dvh;width:28rem;display:none;flex-direction:column;background:var(--ui-color-surface);box-shadow:var(--ui-shadow-xl, -8px 0 32px rgba(0, 0, 0, .12));color:var(--ui-color-text);overflow:hidden;transform:translate(100%);transition:transform var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) dialog[open]{display:flex;transform:translate(0)}@starting-style{:host(.variant-drawer) dialog[open]{transform:translate(100%)}}:host(.variant-drawer) dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity var(--ui-duration-slow) var(--ui-ease-out, ease-out),display var(--ui-duration-slow) allow-discrete,overlay var(--ui-duration-slow) allow-discrete}:host(.variant-drawer) .drawer-surface{width:100%;height:100%}:host(.variant-popup) .popup-surface{position:fixed;bottom:calc(var(--ui-spacing-6) + 3.5rem + var(--ui-spacing-4));right:var(--ui-spacing-6);width:23.75rem;height:35rem;border-radius:var(--ui-radius-xl);box-shadow:0 12px 32px #0000002e;z-index:100}:host(.variant-popup) .fab-bubble{position:fixed;bottom:var(--ui-spacing-6);right:var(--ui-spacing-6);width:3.5rem;height:3.5rem;border-radius:var(--ui-radius-full);background:var(--ui-color-brand-ai, #b5e61c);color:var(--ui-color-text);border:none;font-family:var(--ui-font-family);font-size:var(--ui-font-size-lg);font-weight:var(--ui-font-weight-semibold);cursor:pointer;box-shadow:0 6px 16px #0000002e;transition:transform var(--ui-transition-fast),box-shadow var(--ui-transition-fast);z-index:101}:host(.variant-popup) .fab-bubble:hover{transform:scale(1.05);box-shadow:0 8px 20px #00000038}:host(.variant-popup) .fab-bubble:focus-visible{outline:none;box-shadow:var(--ui-focus-ring),0 6px 16px #0000002e}:host(.variant-inline) .inline-surface{width:100%;height:100%;min-height:24rem;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-xl)}:host(.variant-inline) llm-chat-header .close-btn{display:none}:host(llm-chat-header){display:flex;align-items:center;justify-content:space-between;gap:var(--ui-spacing-3);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-bottom:1px solid var(--ui-color-border);flex-shrink:0}:host(llm-chat-header) .title-block{display:flex;align-items:center;gap:var(--ui-spacing-3);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-weight-semibold);color:var(--ui-color-text);letter-spacing:var(--ui-letter-spacing-tight);flex:1;min-width:0}:host(llm-chat-header) .close-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-sm);cursor:pointer;color:var(--ui-color-text-muted);transition:background-color var(--ui-transition-fast),color var(--ui-transition-fast)}:host(llm-chat-header) .close-btn:hover{background-color:var(--ui-color-surface-sunken);color:var(--ui-color-text)}:host(llm-chat-header) .close-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-messages){display:flex;flex-direction:column;gap:var(--ui-spacing-3);padding:var(--ui-spacing-4);overflow-y:auto;flex:1;background:var(--ui-color-surface)}:host(llm-chat-message){display:block;max-width:85%;padding:var(--ui-spacing-3) var(--ui-spacing-4);border-radius:var(--ui-radius-lg);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);word-wrap:break-word}:host(llm-chat-message.role-assistant),:host(llm-chat-message.role-system){background:var(--ui-color-surface-sunken);color:var(--ui-color-text);align-self:flex-start}:host(llm-chat-message.role-user){background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);align-self:flex-end}:host(llm-chat-message.role-system){font-style:italic;color:var(--ui-color-text-muted)}:host(llm-chat-message.is-failed){background:var(--ui-color-surface-sunken);border:1px dashed var(--ui-color-danger);color:var(--ui-color-text)}:host(llm-chat-typing){display:inline-flex;align-items:center;gap:var(--ui-spacing-1);padding:var(--ui-spacing-2) var(--ui-spacing-3);background:var(--ui-color-surface-sunken);border-radius:var(--ui-radius-lg);align-self:flex-start}:host(llm-chat-typing) .dot{width:.375rem;height:.375rem;border-radius:50%;background:var(--ui-color-text-muted);animation:llm-chat-typing 1.4s infinite ease-in-out}:host(llm-chat-typing) .dot:nth-child(2){animation-delay:.16s}:host(llm-chat-typing) .dot:nth-child(3){animation-delay:.32s}@keyframes llm-chat-typing{0%,60%,to{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){:host(llm-chat-typing) .dot{animation:none;opacity:.6}}:host(llm-chat-typing) .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host(llm-chat-suggestion){display:block}:host(llm-chat-suggestion) .chip{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ui-spacing-1);width:100%;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);color:var(--ui-color-text);border:1px solid var(--ui-color-border);border-radius:var(--ui-radius-lg);font-family:var(--ui-font-family);text-align:left;cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast)}:host(llm-chat-suggestion) .chip:hover{background-color:var(--ui-color-surface-sunken);border-color:var(--ui-color-border-hover)}:host(llm-chat-suggestion) .chip:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(llm-chat-suggestion) .chip-label{font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);color:var(--ui-color-text)}:host(llm-chat-suggestion) .chip-hint{font-size:var(--ui-font-size-xs);color:var(--ui-color-text-muted)}:host(llm-chat-input){display:flex;align-items:flex-end;gap:var(--ui-spacing-2);padding:var(--ui-spacing-3) var(--ui-spacing-4);border-top:1px solid var(--ui-color-border);background:var(--ui-color-surface);flex-shrink:0}:host(llm-chat-input) .field{flex:1;min-width:0;padding:var(--ui-spacing-2) var(--ui-spacing-3);border:1px solid var(--ui-color-input-border, var(--ui-color-border));border-radius:var(--ui-radius-md);background:var(--ui-color-surface-sunken);color:var(--ui-color-text);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);line-height:var(--ui-line-height-normal);resize:none;transition:border-color var(--ui-transition-fast)}:host(llm-chat-input) .field::placeholder{color:var(--ui-color-text-muted)}:host(llm-chat-input) .field:hover:not(:disabled){border-color:var(--ui-color-input-border-hover, var(--ui-color-border-hover))}:host(llm-chat-input) .field:focus-visible{outline:none;border-color:var(--ui-color-primary);box-shadow:var(--ui-focus-ring)}:host(llm-chat-input) .field:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--ui-spacing-2) var(--ui-spacing-4);border:1px solid transparent;border-radius:var(--ui-radius-md);font-family:var(--ui-font-family);font-size:var(--ui-font-size-sm);font-weight:var(--ui-font-weight-medium);cursor:pointer;transition:background-color var(--ui-transition-fast),border-color var(--ui-transition-fast),transform var(--ui-transition-fast)}:host(llm-chat-input) .action-btn.variant-primary{background:var(--ui-color-primary);color:var(--ui-color-text-on-primary);border-color:var(--ui-color-primary)}:host(llm-chat-input) .action-btn.variant-primary:hover:not(:disabled){background:var(--ui-color-primary-hover);border-color:var(--ui-color-primary-hover)}:host(llm-chat-input) .action-btn.variant-danger{background:var(--ui-color-danger);color:var(--ui-color-text-on-danger);border-color:var(--ui-color-danger)}:host(llm-chat-input) .action-btn.variant-danger:hover{background:var(--ui-color-danger-hover);border-color:var(--ui-color-danger-hover)}:host(llm-chat-input) .action-btn:disabled{opacity:var(--ui-opacity-disabled);cursor:not-allowed}:host(llm-chat-input) .action-btn:focus-visible{outline:none;box-shadow:var(--ui-focus-ring)}:host(.status-streaming) llm-chat-input .field{cursor:wait}\n"] }]
4783
+ }], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], send: [{ type: i0.Output, args: ["send"] }], stop: [{ type: i0.Output, args: ["stop"] }] } });
4784
+
4315
4785
  // Design tokens stylesheet — consumers should import:
4316
4786
  // @import '@atelier-ui/angular/styles/tokens.css';
4317
4787
 
@@ -4319,5 +4789,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
4319
4789
  * Generated bundle index. Do not edit.
4320
4790
  */
4321
4791
 
4322
- export { LLM_ACCORDION_GROUP, LLM_BREADCRUMBS, LLM_DIALOG, LLM_DRAWER, LLM_RADIO_GROUP, LLM_SELECT, LLM_STEPPER, LLM_TABLE, LLM_TAB_GROUP, LlmAccordionGroup, LlmAccordionHeader, LlmAccordionItem, LlmAlert, LlmAvatar, LlmAvatarGroup, LlmBadge, LlmBreadcrumbItem, LlmBreadcrumbs, LlmButton, LlmCard, LlmCardContent, LlmCardFooter, LlmCardHeader, LlmCheckbox, LlmCodeBlock, LlmCombobox, LlmDialog, LlmDialogContent, LlmDialogFooter, LlmDialogHeader, LlmDrawer, LlmDrawerContent, LlmDrawerFooter, LlmDrawerHeader, LlmInput, LlmMenu, LlmMenuItem, LlmMenuSeparator, LlmMenuTrigger, LlmOption, LlmPagination, LlmProgress, LlmRadio, LlmRadioGroup, LlmSelect, LlmSkeleton, LlmStep, LlmStepper, LlmTab, LlmTabGroup, LlmTable, LlmTbody, LlmTd, LlmTextarea, LlmTh, LlmThead, LlmToast, LlmToastContainer, LlmToastService, LlmToggle, LlmTooltip, LlmTr };
4792
+ export { LLM_ACCORDION_GROUP, LLM_BREADCRUMBS, LLM_CHAT, LLM_DIALOG, LLM_DRAWER, LLM_RADIO_GROUP, LLM_SELECT, LLM_STEPPER, LLM_TABLE, LLM_TAB_GROUP, LlmAccordionGroup, LlmAccordionHeader, LlmAccordionItem, LlmAlert, LlmAvatar, LlmAvatarGroup, LlmBadge, LlmBreadcrumbItem, LlmBreadcrumbs, LlmButton, LlmCard, LlmCardContent, LlmCardFooter, LlmCardHeader, LlmChat, LlmChatHeader, LlmChatInput, LlmChatMessage, LlmChatMessages, LlmChatSuggestion, LlmChatTyping, LlmCheckbox, LlmCodeBlock, LlmCombobox, LlmDialog, LlmDialogContent, LlmDialogFooter, LlmDialogHeader, LlmDrawer, LlmDrawerContent, LlmDrawerFooter, LlmDrawerHeader, LlmInput, LlmMenu, LlmMenuItem, LlmMenuSeparator, LlmMenuTrigger, LlmOption, LlmPagination, LlmProgress, LlmRadio, LlmRadioGroup, LlmSelect, LlmSkeleton, LlmStep, LlmStepper, LlmTab, LlmTabGroup, LlmTable, LlmTbody, LlmTd, LlmTextarea, LlmTh, LlmThead, LlmToast, LlmToastContainer, LlmToastService, LlmToggle, LlmTooltip, LlmTr };
4323
4793
  //# sourceMappingURL=atelier-ui-angular.mjs.map