max-agent-ui 0.0.39 → 0.0.41

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.
@@ -1,28 +1,32 @@
1
- import * as i13 from '@angular/common';
2
- import { CommonModule } from '@angular/common';
1
+ import * as i9 from '@angular/common';
2
+ import { NgTemplateOutlet, CommonModule } from '@angular/common';
3
3
  import * as i1 from '@angular/common/http';
4
4
  import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
5
5
  import * as i0 from '@angular/core';
6
- import { InjectionToken, Pipe, Input, Component, EventEmitter, Output, ChangeDetectionStrategy, isDevMode, Inject, Optional, Injectable, signal, HostListener, ViewChild, ViewEncapsulation } from '@angular/core';
6
+ import { InjectionToken, isDevMode, Inject, Optional, Injectable, Pipe, Input, Component, ChangeDetectionStrategy, EventEmitter, Output, inject, DestroyRef, signal, HostListener, ViewChild, ViewEncapsulation } from '@angular/core';
7
7
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
- import * as i5 from '@angular/forms';
8
+ import * as i1$2 from '@angular/forms';
9
9
  import { FormsModule } from '@angular/forms';
10
- import * as i6 from 'primeng/button';
10
+ import * as i2 from 'primeng/button';
11
11
  import { ButtonModule } from 'primeng/button';
12
- import * as i7 from 'primeng/chart';
12
+ import * as i3 from 'primeng/chart';
13
13
  import { ChartModule } from 'primeng/chart';
14
- import * as i8 from 'primeng/multiselect';
14
+ import * as i4 from 'primeng/multiselect';
15
15
  import { MultiSelectModule } from 'primeng/multiselect';
16
- import * as i9 from 'primeng/select';
16
+ import * as i5 from 'primeng/select';
17
17
  import { SelectModule } from 'primeng/select';
18
- import * as i10 from 'primeng/tag';
18
+ import * as i6 from 'primeng/tag';
19
19
  import { TagModule } from 'primeng/tag';
20
- import * as i11 from 'primeng/textarea';
20
+ import * as i7 from 'primeng/textarea';
21
21
  import { TextareaModule } from 'primeng/textarea';
22
- import * as i12 from 'primeng/tooltip';
22
+ import * as i8 from 'primeng/tooltip';
23
23
  import { TooltipModule } from 'primeng/tooltip';
24
24
  import { Subject, throwError, Observable, map, takeUntil, switchMap, of } from 'rxjs';
25
25
  import { marked } from 'marked';
26
+ import * as i2$1 from 'primeng/divider';
27
+ import { DividerModule } from 'primeng/divider';
28
+ import * as i1$1 from 'primeng/avatar';
29
+ import { AvatarModule } from 'primeng/avatar';
26
30
 
27
31
  /** Owned by one assistant component. Never persists, shares across tabs, or decodes signed state. */
28
32
  class AssistantConversationState {
@@ -106,156 +110,6 @@ const MAX_ASSISTANT_CONFIG = new InjectionToken('MAX_ASSISTANT_CONFIG', {
106
110
  factory: () => ({})
107
111
  });
108
112
 
109
- class MaxAssistantMarkdownPipe {
110
- transform(value, variant = 'default') {
111
- if (!value) {
112
- return '';
113
- }
114
- // Assistant responses may contain Markdown, but they must not be able to
115
- // inject raw HTML. Angular sanitises the generated HTML again when it is
116
- // assigned through [innerHTML].
117
- const escapedValue = value
118
- .replaceAll('&', '&')
119
- .replaceAll('<', '&lt;')
120
- .replaceAll('>', '&gt;');
121
- const rendered = marked.parse(escapedValue, {
122
- async: false,
123
- breaks: true,
124
- gfm: true
125
- });
126
- return variant === 'information'
127
- ? rendered.replaceAll('<li>', '<li><i class="fa-solid fa-arrow-right" aria-hidden="true"></i>')
128
- : rendered;
129
- }
130
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantMarkdownPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
131
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantMarkdownPipe, isStandalone: true, name: "maxAssistantMarkdown" });
132
- }
133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantMarkdownPipe, decorators: [{
134
- type: Pipe,
135
- args: [{
136
- name: 'maxAssistantMarkdown',
137
- standalone: true,
138
- pure: true
139
- }]
140
- }] });
141
-
142
- class MaxAgentShiftCardComponent {
143
- shift;
144
- variant = 'rota';
145
- get accentColor() {
146
- const color = this.shift.color?.trim();
147
- if (!color) {
148
- return '#64748b';
149
- }
150
- return /^(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color)
151
- ? `#${color}`
152
- : color;
153
- }
154
- get timeLabel() {
155
- const formatter = this.variant === 'rota'
156
- ? this.formatTimeToAmPm
157
- : this.formatTime;
158
- const start = formatter(this.shift.startTime);
159
- const end = formatter(this.shift.endTime);
160
- return start && end ? `${start} - ${end}` : start || end || 'All day';
161
- }
162
- get departmentLabel() {
163
- const count = this.shift.departments?.length ?? 0;
164
- return count
165
- ? `${count} department${count === 1 ? '' : 's'}`
166
- : 'All departments';
167
- }
168
- get taskLabel() {
169
- const count = this.shift.taskCount ?? 0;
170
- return `${count} task${count === 1 ? '' : 's'}`;
171
- }
172
- formatTime(value) {
173
- return value.match(/^\d{2}:\d{2}/)?.[0] ?? value;
174
- }
175
- formatTimeToAmPm(value) {
176
- const match = value.match(/^(\d{1,2}):(\d{2})/);
177
- if (!match) {
178
- return value;
179
- }
180
- const hour = Number(match[1]);
181
- const displayHour = ((hour + 11) % 12) + 1;
182
- return `${displayHour}.${match[2]} ${hour >= 12 ? 'PM' : 'AM'}`;
183
- }
184
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentShiftCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
185
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAgentShiftCardComponent, isStandalone: true, selector: "max-agent-shift-card", inputs: { shift: "shift", variant: "variant" }, ngImport: i0, template: "<article\n class=\"max-agent-shift-card\"\n [class.definition-card]=\"variant === 'definition'\"\n [class.rota-card]=\"variant === 'rota'\"\n [style.--max-agent-shift-accent]=\"accentColor\"\n [attr.aria-label]=\"(shift.description || shift.code || 'Shift') + ', ' + timeLabel\"\n>\n <header>\n <strong>{{ timeLabel }}</strong>\n @if(variant === 'definition' && shift.days) {\n <span>{{ shift.days }}</span>\n }\n </header>\n\n @if(variant === 'definition') {\n @if(shift.code) {\n <p><i class=\"pi pi-tag\" aria-hidden=\"true\"></i><span>{{ shift.code }}</span></p>\n }\n @if(shift.description) {\n <p><i class=\"pi pi-align-left\" aria-hidden=\"true\"></i><span>{{ shift.description }}</span></p>\n }\n <p><i class=\"pi pi-building\" aria-hidden=\"true\"></i><span>{{ departmentLabel }}</span></p>\n @if((shift.taskCount ?? 0) > 0) {\n <p><i class=\"pi pi-check-square\" aria-hidden=\"true\"></i><span>{{ taskLabel }}</span></p>\n }\n } @else {\n @if(shift.location) {\n <p><i class=\"pi pi-map-marker\" aria-hidden=\"true\"></i><span>{{ shift.location }}</span></p>\n }\n @if(shift.role) {\n <p><i class=\"pi pi-user\" aria-hidden=\"true\"></i><span>{{ shift.role }}</span></p>\n }\n }\n</article>\n", styles: [":host{display:block;width:100%;min-width:0}.max-agent-shift-card{--max-agent-shift-accent: #64748b;display:grid;gap:6px;box-sizing:border-box;width:100%;min-width:0;max-width:100%;padding:9px 10px 8px;overflow:hidden;border:1px solid var(--max-border, #dbe2ea);border-bottom:4px solid var(--max-agent-shift-accent);border-radius:8px;color:var(--max-text, #1e293b);background:var(--max-surface, #fff);box-shadow:0 1px 2px #0f172a14}.max-agent-shift-card header{display:flex;gap:8px;align-items:baseline;justify-content:space-between;min-width:0}.max-agent-shift-card header strong{flex:0 0 auto;color:var(--max-text, #1e293b);font-size:12px;line-height:1.3;white-space:nowrap}.max-agent-shift-card header span{overflow:hidden;color:var(--max-text, #1e293b);font-size:10px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.max-agent-shift-card p{display:grid;grid-template-columns:14px minmax(0,1fr);gap:6px;align-items:start;margin:0;color:var(--max-text, #334155);font-size:11px;line-height:1.3}.max-agent-shift-card p i{margin-top:1px;color:var(--max-text, #334155);font-size:11px}.max-agent-shift-card p span{min-width:0;overflow-wrap:anywhere}.definition-card{min-height:128px}.rota-card{min-height:54px}\n"] });
186
- }
187
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentShiftCardComponent, decorators: [{
188
- type: Component,
189
- args: [{ selector: 'max-agent-shift-card', template: "<article\n class=\"max-agent-shift-card\"\n [class.definition-card]=\"variant === 'definition'\"\n [class.rota-card]=\"variant === 'rota'\"\n [style.--max-agent-shift-accent]=\"accentColor\"\n [attr.aria-label]=\"(shift.description || shift.code || 'Shift') + ', ' + timeLabel\"\n>\n <header>\n <strong>{{ timeLabel }}</strong>\n @if(variant === 'definition' && shift.days) {\n <span>{{ shift.days }}</span>\n }\n </header>\n\n @if(variant === 'definition') {\n @if(shift.code) {\n <p><i class=\"pi pi-tag\" aria-hidden=\"true\"></i><span>{{ shift.code }}</span></p>\n }\n @if(shift.description) {\n <p><i class=\"pi pi-align-left\" aria-hidden=\"true\"></i><span>{{ shift.description }}</span></p>\n }\n <p><i class=\"pi pi-building\" aria-hidden=\"true\"></i><span>{{ departmentLabel }}</span></p>\n @if((shift.taskCount ?? 0) > 0) {\n <p><i class=\"pi pi-check-square\" aria-hidden=\"true\"></i><span>{{ taskLabel }}</span></p>\n }\n } @else {\n @if(shift.location) {\n <p><i class=\"pi pi-map-marker\" aria-hidden=\"true\"></i><span>{{ shift.location }}</span></p>\n }\n @if(shift.role) {\n <p><i class=\"pi pi-user\" aria-hidden=\"true\"></i><span>{{ shift.role }}</span></p>\n }\n }\n</article>\n", styles: [":host{display:block;width:100%;min-width:0}.max-agent-shift-card{--max-agent-shift-accent: #64748b;display:grid;gap:6px;box-sizing:border-box;width:100%;min-width:0;max-width:100%;padding:9px 10px 8px;overflow:hidden;border:1px solid var(--max-border, #dbe2ea);border-bottom:4px solid var(--max-agent-shift-accent);border-radius:8px;color:var(--max-text, #1e293b);background:var(--max-surface, #fff);box-shadow:0 1px 2px #0f172a14}.max-agent-shift-card header{display:flex;gap:8px;align-items:baseline;justify-content:space-between;min-width:0}.max-agent-shift-card header strong{flex:0 0 auto;color:var(--max-text, #1e293b);font-size:12px;line-height:1.3;white-space:nowrap}.max-agent-shift-card header span{overflow:hidden;color:var(--max-text, #1e293b);font-size:10px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.max-agent-shift-card p{display:grid;grid-template-columns:14px minmax(0,1fr);gap:6px;align-items:start;margin:0;color:var(--max-text, #334155);font-size:11px;line-height:1.3}.max-agent-shift-card p i{margin-top:1px;color:var(--max-text, #334155);font-size:11px}.max-agent-shift-card p span{min-width:0;overflow-wrap:anywhere}.definition-card{min-height:128px}.rota-card{min-height:54px}\n"] }]
190
- }], propDecorators: { shift: [{
191
- type: Input,
192
- args: [{ required: true }]
193
- }], variant: [{
194
- type: Input
195
- }] } });
196
-
197
- const ENTITY_ICONS = {
198
- team: 'pi pi-users',
199
- role: 'pi pi-id-card',
200
- location: 'pi pi-map-marker',
201
- position: 'pi pi-briefcase',
202
- department: 'pi pi-building',
203
- entity: 'pi pi-tag',
204
- };
205
- class MaxAgentEntityOptionComponent {
206
- entity;
207
- disabled = false;
208
- selected = new EventEmitter();
209
- get isPerson() {
210
- return this.entity.kind === 'person' || this.entity.kind === 'employee';
211
- }
212
- get displayCode() {
213
- return this.entity.code ?? this.entity.id;
214
- }
215
- get initials() {
216
- return this.entity.name
217
- .split(/\s+/u)
218
- .filter(Boolean)
219
- .slice(0, 2)
220
- .map((part) => part[0]?.toLocaleUpperCase())
221
- .join('');
222
- }
223
- get entityColor() {
224
- return this.normaliseColor(this.entity.color);
225
- }
226
- get entityTextColor() {
227
- return this.normaliseColor(this.entity.textColor);
228
- }
229
- get entityIcon() {
230
- return ENTITY_ICONS[this.entity.kind] ?? 'pi pi-tag';
231
- }
232
- choose() {
233
- if (!this.disabled) {
234
- this.selected.emit();
235
- }
236
- }
237
- normaliseColor(value) {
238
- const color = value?.trim();
239
- if (!color) {
240
- return undefined;
241
- }
242
- return /^[\da-f]{3,8}$/iu.test(color) ? `#${color}` : color;
243
- }
244
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentEntityOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
245
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAgentEntityOptionComponent, isStandalone: true, selector: "max-agent-entity-option", inputs: { entity: "entity", disabled: "disabled" }, outputs: { selected: "selected" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"entity-option\"\n [class.entity-option-person]=\"isPerson\"\n [class.entity-option-tag]=\"!isPerson\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'Choose ' + entity.name\"\n [style.--max-agent-entity-color]=\"entityColor\"\n [style.--max-agent-entity-text-color]=\"entityTextColor\"\n (click)=\"choose()\"\n>\n @if (isPerson) {\n <span class=\"person-photo\" aria-hidden=\"true\">\n @if (entity.photo) {\n <img [src]=\"entity.photo\" [alt]=\"''\" />\n } @else {\n <span>{{ initials }}</span>\n }\n </span>\n <span class=\"person-copy\">\n <span class=\"person-name\">{{ entity.name }}</span>\n @if (displayCode !== undefined && displayCode !== '') {\n <small>#{{ displayCode }}</small>\n }\n </span>\n <i class=\"pi pi-arrow-right option-arrow\" aria-hidden=\"true\"></i>\n } @else {\n <span class=\"entity-icon\" aria-hidden=\"true\">\n <i [class]=\"entityIcon\"></i>\n </span>\n <span class=\"entity-name\">{{ entity.name }}</span>\n }\n</button>\n", styles: [":host{display:block;min-width:0}.entity-option{align-items:center;border:0;color:var(--text-color, #1e293b);cursor:pointer;display:flex;font:inherit;min-width:0;text-align:left;border-radius:16px}.entity-option:disabled{cursor:default;opacity:.55}.entity-option-person{background:var(--surface-card, #fff);border:1px solid var(--border-color, #e2e8f0);gap:12px;padding:10px 12px;transition:background .16s ease,box-shadow .16s ease,transform .16s ease;width:100%}.entity-option-person:not(:disabled):hover{background:var(--surface-hover, #f8fafc);box-shadow:0 7px 18px #0f172a1a;transform:translateY(-1px)}.entity-option-person:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:2px}.person-photo{align-items:center;background:var(--surface-100, #f1f5f9);border-radius:50%;color:var(--primary-color, #2563eb);display:inline-flex;flex:0 0 40px;font-weight:600;height:40px;justify-content:center;overflow:hidden;width:40px}.person-photo img{height:100%;object-fit:cover;width:100%}.person-copy{display:grid;flex:1 1 auto;min-width:0}.person-name,.person-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.person-name{color:var(--primary-color, #2563eb);font-weight:600;font-size:14px}.person-copy small{color:var(--text-color-secondary, #64748b)}.option-arrow{color:var(--text-color-secondary, #64748b);flex:0 0 auto}.entity-option-tag{background:transparent;border-radius:var(--border-radius, 6px);gap:8px;padding:4px 8px 4px 4px}.entity-option-tag:not(:disabled):hover{background:var(--surface-hover, #f8fafc)}.entity-icon{align-items:center;background:var(--max-agent-entity-color, var(--surface-100, #f1f5f9));border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px);color:var(--max-agent-entity-text-color, var(--text-color, #1e293b));display:inline-flex;height:30px;justify-content:center;width:30px}.entity-name{font-weight:600}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
246
- }
247
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentEntityOptionComponent, decorators: [{
248
- type: Component,
249
- args: [{ selector: 'max-agent-entity-option', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n class=\"entity-option\"\n [class.entity-option-person]=\"isPerson\"\n [class.entity-option-tag]=\"!isPerson\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'Choose ' + entity.name\"\n [style.--max-agent-entity-color]=\"entityColor\"\n [style.--max-agent-entity-text-color]=\"entityTextColor\"\n (click)=\"choose()\"\n>\n @if (isPerson) {\n <span class=\"person-photo\" aria-hidden=\"true\">\n @if (entity.photo) {\n <img [src]=\"entity.photo\" [alt]=\"''\" />\n } @else {\n <span>{{ initials }}</span>\n }\n </span>\n <span class=\"person-copy\">\n <span class=\"person-name\">{{ entity.name }}</span>\n @if (displayCode !== undefined && displayCode !== '') {\n <small>#{{ displayCode }}</small>\n }\n </span>\n <i class=\"pi pi-arrow-right option-arrow\" aria-hidden=\"true\"></i>\n } @else {\n <span class=\"entity-icon\" aria-hidden=\"true\">\n <i [class]=\"entityIcon\"></i>\n </span>\n <span class=\"entity-name\">{{ entity.name }}</span>\n }\n</button>\n", styles: [":host{display:block;min-width:0}.entity-option{align-items:center;border:0;color:var(--text-color, #1e293b);cursor:pointer;display:flex;font:inherit;min-width:0;text-align:left;border-radius:16px}.entity-option:disabled{cursor:default;opacity:.55}.entity-option-person{background:var(--surface-card, #fff);border:1px solid var(--border-color, #e2e8f0);gap:12px;padding:10px 12px;transition:background .16s ease,box-shadow .16s ease,transform .16s ease;width:100%}.entity-option-person:not(:disabled):hover{background:var(--surface-hover, #f8fafc);box-shadow:0 7px 18px #0f172a1a;transform:translateY(-1px)}.entity-option-person:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:2px}.person-photo{align-items:center;background:var(--surface-100, #f1f5f9);border-radius:50%;color:var(--primary-color, #2563eb);display:inline-flex;flex:0 0 40px;font-weight:600;height:40px;justify-content:center;overflow:hidden;width:40px}.person-photo img{height:100%;object-fit:cover;width:100%}.person-copy{display:grid;flex:1 1 auto;min-width:0}.person-name,.person-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.person-name{color:var(--primary-color, #2563eb);font-weight:600;font-size:14px}.person-copy small{color:var(--text-color-secondary, #64748b)}.option-arrow{color:var(--text-color-secondary, #64748b);flex:0 0 auto}.entity-option-tag{background:transparent;border-radius:var(--border-radius, 6px);gap:8px;padding:4px 8px 4px 4px}.entity-option-tag:not(:disabled):hover{background:var(--surface-hover, #f8fafc)}.entity-icon{align-items:center;background:var(--max-agent-entity-color, var(--surface-100, #f1f5f9));border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px);color:var(--max-agent-entity-text-color, var(--text-color, #1e293b));display:inline-flex;height:30px;justify-content:center;width:30px}.entity-name{font-weight:600}\n"] }]
250
- }], propDecorators: { entity: [{
251
- type: Input,
252
- args: [{ required: true }]
253
- }], disabled: [{
254
- type: Input
255
- }], selected: [{
256
- type: Output
257
- }] } });
258
-
259
113
  const ASSISTANT_CHAT_ENDPOINTS = {
260
114
  development: '/agent-api/v1/chat',
261
115
  production: 'https://agent.maxtime.cloud/v1/chat'
@@ -550,6 +404,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
550
404
  type: Optional
551
405
  }] }] });
552
406
 
407
+ class MaxAssistantFeedbackService {
408
+ config;
409
+ http;
410
+ endpoint = getDefaultAssistantFeedbackUrl();
411
+ method = 'POST';
412
+ constructor(config, http) {
413
+ this.config = config;
414
+ this.http = http;
415
+ }
416
+ submitFeedback(feedback, config = {}) {
417
+ if (!this.http) {
418
+ return throwError(() => new Error('HttpClient is not available. Add provideHttpClient() to the host app.'));
419
+ }
420
+ const mergedConfig = this.mergeConfig(config);
421
+ return this.http.post(this.getFeedbackUrl(mergedConfig), feedback, { headers: this.getHeaders(mergedConfig) });
422
+ }
423
+ getFeedbackUrl(config) {
424
+ const configuredChatUrl = config.assistantApiUrl?.trim();
425
+ return configuredChatUrl
426
+ ? configuredChatUrl.replace(/\/chat\/?$/, '/feedback')
427
+ : getDefaultAssistantFeedbackUrl();
428
+ }
429
+ getHeaders(config) {
430
+ const user = this.getUser(config);
431
+ const configuredHeaders = typeof config.requestHeaders === 'function'
432
+ ? config.requestHeaders()
433
+ : config.requestHeaders ?? {};
434
+ let headers = new HttpHeaders({ 'Content-Type': 'application/json' });
435
+ for (const [name, value] of Object.entries(configuredHeaders)) {
436
+ if (name.trim() && value.trim()) {
437
+ headers = headers.set(name.trim(), value.trim());
438
+ }
439
+ }
440
+ if (user.token) {
441
+ headers = headers.set('x-auth-token', String(user.token));
442
+ }
443
+ if (user.version) {
444
+ headers = headers.set('x-version', String(user.version));
445
+ }
446
+ return headers;
447
+ }
448
+ getUser(config) {
449
+ return typeof config.user === 'function' ? config.user() : config.user ?? {};
450
+ }
451
+ mergeConfig(config) {
452
+ const merged = {
453
+ ...this.config,
454
+ ...Object.fromEntries(Object.entries(config).filter(([, value]) => value !== undefined))
455
+ };
456
+ if (config.user === undefined) {
457
+ return merged;
458
+ }
459
+ return {
460
+ ...merged,
461
+ user: {
462
+ ...this.getUser(this.config),
463
+ ...this.getUser(config)
464
+ }
465
+ };
466
+ }
467
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, deps: [{ token: MAX_ASSISTANT_CONFIG }, { token: i1.HttpClient, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
468
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, providedIn: 'root' });
469
+ }
470
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, decorators: [{
471
+ type: Injectable,
472
+ args: [{ providedIn: 'root' }]
473
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
474
+ type: Inject,
475
+ args: [MAX_ASSISTANT_CONFIG]
476
+ }] }, { type: i1.HttpClient, decorators: [{
477
+ type: Optional
478
+ }] }] });
479
+
553
480
  class MaxAssistantExportService {
554
481
  async exportTableToExcel(table) {
555
482
  const XLSX = await import('xlsx');
@@ -654,79 +581,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
654
581
  args: [{ providedIn: 'root' }]
655
582
  }] });
656
583
 
657
- class MaxAssistantFeedbackService {
658
- config;
659
- http;
660
- endpoint = getDefaultAssistantFeedbackUrl();
661
- method = 'POST';
662
- constructor(config, http) {
663
- this.config = config;
664
- this.http = http;
665
- }
666
- submitFeedback(feedback, config = {}) {
667
- if (!this.http) {
668
- return throwError(() => new Error('HttpClient is not available. Add provideHttpClient() to the host app.'));
669
- }
670
- const mergedConfig = this.mergeConfig(config);
671
- return this.http.post(this.getFeedbackUrl(mergedConfig), feedback, { headers: this.getHeaders(mergedConfig) });
672
- }
673
- getFeedbackUrl(config) {
674
- const configuredChatUrl = config.assistantApiUrl?.trim();
675
- return configuredChatUrl
676
- ? configuredChatUrl.replace(/\/chat\/?$/, '/feedback')
677
- : getDefaultAssistantFeedbackUrl();
678
- }
679
- getHeaders(config) {
680
- const user = this.getUser(config);
681
- const configuredHeaders = typeof config.requestHeaders === 'function'
682
- ? config.requestHeaders()
683
- : config.requestHeaders ?? {};
684
- let headers = new HttpHeaders({ 'Content-Type': 'application/json' });
685
- for (const [name, value] of Object.entries(configuredHeaders)) {
686
- if (name.trim() && value.trim()) {
687
- headers = headers.set(name.trim(), value.trim());
688
- }
689
- }
690
- if (user.token) {
691
- headers = headers.set('x-auth-token', String(user.token));
692
- }
693
- if (user.version) {
694
- headers = headers.set('x-version', String(user.version));
695
- }
696
- return headers;
697
- }
698
- getUser(config) {
699
- return typeof config.user === 'function' ? config.user() : config.user ?? {};
700
- }
701
- mergeConfig(config) {
702
- const merged = {
703
- ...this.config,
704
- ...Object.fromEntries(Object.entries(config).filter(([, value]) => value !== undefined))
705
- };
706
- if (config.user === undefined) {
707
- return merged;
708
- }
709
- return {
710
- ...merged,
711
- user: {
712
- ...this.getUser(this.config),
713
- ...this.getUser(config)
714
- }
715
- };
716
- }
717
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, deps: [{ token: MAX_ASSISTANT_CONFIG }, { token: i1.HttpClient, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
718
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, providedIn: 'root' });
719
- }
720
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, decorators: [{
721
- type: Injectable,
722
- args: [{ providedIn: 'root' }]
723
- }], ctorParameters: () => [{ type: undefined, decorators: [{
724
- type: Inject,
725
- args: [MAX_ASSISTANT_CONFIG]
726
- }] }, { type: i1.HttpClient, decorators: [{
727
- type: Optional
728
- }] }] });
729
-
730
584
  class MaxAssistantSupportService {
731
585
  config;
732
586
  http;
@@ -831,6 +685,247 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
831
685
  type: Optional
832
686
  }] }] });
833
687
 
688
+ class MaxAssistantMarkdownPipe {
689
+ transform(value, variant = 'default') {
690
+ if (!value) {
691
+ return '';
692
+ }
693
+ // Assistant responses may contain Markdown, but they must not be able to
694
+ // inject raw HTML. Angular sanitises the generated HTML again when it is
695
+ // assigned through [innerHTML].
696
+ const escapedValue = value
697
+ .replaceAll('&', '&amp;')
698
+ .replaceAll('<', '&lt;')
699
+ .replaceAll('>', '&gt;');
700
+ const rendered = marked.parse(escapedValue, {
701
+ async: false,
702
+ breaks: true,
703
+ gfm: true
704
+ });
705
+ return variant === 'information'
706
+ ? rendered.replaceAll('<li>', '<li><i class="fa-solid fa-arrow-right" aria-hidden="true"></i>')
707
+ : rendered;
708
+ }
709
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantMarkdownPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
710
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantMarkdownPipe, isStandalone: true, name: "maxAssistantMarkdown" });
711
+ }
712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantMarkdownPipe, decorators: [{
713
+ type: Pipe,
714
+ args: [{
715
+ name: 'maxAssistantMarkdown',
716
+ standalone: true,
717
+ pure: true
718
+ }]
719
+ }] });
720
+
721
+ class MaxAgentShiftCardComponent {
722
+ shift;
723
+ variant = 'rota';
724
+ icons = {};
725
+ get assignmentColor() {
726
+ return this.shift.color?.trim() ? this.accentColor : undefined;
727
+ }
728
+ get accentColor() {
729
+ const color = this.shift.color?.trim();
730
+ if (!color) {
731
+ return '#64748b';
732
+ }
733
+ return /^(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color)
734
+ ? `#${color}`
735
+ : color;
736
+ }
737
+ get timeLabel() {
738
+ const formatter = this.formatTimeToAmPm;
739
+ const start = formatter(this.shift.startTime);
740
+ const end = formatter(this.shift.endTime);
741
+ return start && end ? `${start} - ${end}` : start || end || 'All day';
742
+ }
743
+ get departmentLabel() {
744
+ const count = this.shift.departments?.length ?? 0;
745
+ return count
746
+ ? `${count} department${count === 1 ? '' : 's'}`
747
+ : 'All departments';
748
+ }
749
+ get taskLabel() {
750
+ const count = this.shift.taskCount ?? 0;
751
+ return `${count} task${count === 1 ? '' : 's'}`;
752
+ }
753
+ formatTimeToAmPm(value) {
754
+ const match = value.match(/^(\d{1,2}):(\d{2})/);
755
+ if (!match) {
756
+ return value;
757
+ }
758
+ const hour = Number(match[1]);
759
+ const displayHour = ((hour + 11) % 12) + 1;
760
+ return `${displayHour}:${match[2]} ${hour >= 12 ? 'PM' : 'AM'}`;
761
+ }
762
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentShiftCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
763
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAgentShiftCardComponent, isStandalone: true, selector: "max-agent-shift-card", inputs: { shift: "shift", variant: "variant", icons: "icons" }, ngImport: i0, template: "<article\n [class.max-agent-shift-card]=\"variant !== 'assignment'\"\n [class.app-shift-card]=\"variant === 'assignment'\"\n [class.app-shift-card--assignment]=\"variant === 'assignment'\"\n [class.app-shift-card--interactive]=\"variant === 'assignment'\"\n [class.p-2]=\"variant === 'assignment'\"\n [class.white-space-normal]=\"variant === 'assignment'\"\n [class.definition-card]=\"variant === 'definition'\"\n [class.rota-card]=\"variant === 'rota'\"\n [style.--max-agent-shift-accent]=\"accentColor\"\n [style.--scheduler-card-accent]=\"variant === 'assignment' ? assignmentColor : null\"\n [attr.aria-label]=\"(shift.description || shift.code || 'Shift') + ', ' + timeLabel\"\n>\n @if(variant === 'assignment') {\n <div class=\"app-shift-card__times\">{{ timeLabel }}</div>\n <div class=\"app-shift-card__meta card-text flex align-items-center\">@if(icons.team) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.team\" aria-hidden=\"true\"></i> }<span>{{ shift.team }}</span></div>\n <div class=\"app-shift-card__meta card-text flex align-items-center\">@if(icons.location) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.location\" aria-hidden=\"true\"></i> }<span>{{ shift.location }}</span></div>\n <div class=\"app-shift-card__meta card-text flex align-items-center\">@if(icons.role) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.role\" aria-hidden=\"true\"></i> }<span>{{ shift.role }}</span></div>\n } @else {\n <header>\n <strong>{{ timeLabel }}</strong>\n @if(variant === 'definition' && shift.days) {\n <span>{{ shift.days }}</span>\n }\n </header>\n\n @if(variant === 'definition') {\n @if(shift.code) {\n <p><i class=\"pi pi-tag\" aria-hidden=\"true\"></i><span>{{ shift.code }}</span></p>\n }\n @if(shift.description) {\n <p><i class=\"pi pi-align-left\" aria-hidden=\"true\"></i><span>{{ shift.description }}</span></p>\n }\n <p><i class=\"pi pi-building\" aria-hidden=\"true\"></i><span>{{ departmentLabel }}</span></p>\n @if((shift.taskCount ?? 0) > 0) {\n <p><i class=\"pi pi-check-square\" aria-hidden=\"true\"></i><span>{{ taskLabel }}</span></p>\n }\n } @else {\n @if(shift.location) {\n <p><i class=\"pi pi-map-marker\" aria-hidden=\"true\"></i><span>{{ shift.location }}</span></p>\n }\n @if(shift.role) {\n <p><i class=\"pi pi-user\" aria-hidden=\"true\"></i><span>{{ shift.role }}</span></p>\n }\n }\n }\n</article>\n", styles: [":host{display:block;width:100%;min-width:0}.max-agent-shift-card{--max-agent-shift-accent: #64748b;display:grid;gap:6px;box-sizing:border-box;width:100%;min-width:0;max-width:100%;padding:9px 10px 8px;overflow:hidden;border:1px solid var(--max-border, #dbe2ea);border-bottom:4px solid var(--max-agent-shift-accent);border-radius:8px;color:var(--max-text, #1e293b);background:var(--max-surface, #fff);box-shadow:0 1px 2px #0f172a14}.max-agent-shift-card header{display:flex;gap:8px;align-items:baseline;justify-content:space-between;min-width:0}.max-agent-shift-card header strong{flex:0 0 auto;color:var(--max-text, #1e293b);font-size:12px;line-height:1.3;white-space:nowrap}.max-agent-shift-card header span{overflow:hidden;color:var(--max-text, #1e293b);font-size:10px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.max-agent-shift-card p{display:grid;grid-template-columns:14px minmax(0,1fr);gap:6px;align-items:start;margin:0;color:var(--max-text, #334155);font-size:11px;line-height:1.3}.max-agent-shift-card p i{margin-top:1px;color:var(--max-text, #334155);font-size:11px}.max-agent-shift-card p span{min-width:0;overflow-wrap:anywhere}.definition-card{min-height:128px}.rota-card{min-height:54px}\n"] });
764
+ }
765
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentShiftCardComponent, decorators: [{
766
+ type: Component,
767
+ args: [{ selector: 'max-agent-shift-card', template: "<article\n [class.max-agent-shift-card]=\"variant !== 'assignment'\"\n [class.app-shift-card]=\"variant === 'assignment'\"\n [class.app-shift-card--assignment]=\"variant === 'assignment'\"\n [class.app-shift-card--interactive]=\"variant === 'assignment'\"\n [class.p-2]=\"variant === 'assignment'\"\n [class.white-space-normal]=\"variant === 'assignment'\"\n [class.definition-card]=\"variant === 'definition'\"\n [class.rota-card]=\"variant === 'rota'\"\n [style.--max-agent-shift-accent]=\"accentColor\"\n [style.--scheduler-card-accent]=\"variant === 'assignment' ? assignmentColor : null\"\n [attr.aria-label]=\"(shift.description || shift.code || 'Shift') + ', ' + timeLabel\"\n>\n @if(variant === 'assignment') {\n <div class=\"app-shift-card__times\">{{ timeLabel }}</div>\n <div class=\"app-shift-card__meta card-text flex align-items-center\">@if(icons.team) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.team\" aria-hidden=\"true\"></i> }<span>{{ shift.team }}</span></div>\n <div class=\"app-shift-card__meta card-text flex align-items-center\">@if(icons.location) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.location\" aria-hidden=\"true\"></i> }<span>{{ shift.location }}</span></div>\n <div class=\"app-shift-card__meta card-text flex align-items-center\">@if(icons.role) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.role\" aria-hidden=\"true\"></i> }<span>{{ shift.role }}</span></div>\n } @else {\n <header>\n <strong>{{ timeLabel }}</strong>\n @if(variant === 'definition' && shift.days) {\n <span>{{ shift.days }}</span>\n }\n </header>\n\n @if(variant === 'definition') {\n @if(shift.code) {\n <p><i class=\"pi pi-tag\" aria-hidden=\"true\"></i><span>{{ shift.code }}</span></p>\n }\n @if(shift.description) {\n <p><i class=\"pi pi-align-left\" aria-hidden=\"true\"></i><span>{{ shift.description }}</span></p>\n }\n <p><i class=\"pi pi-building\" aria-hidden=\"true\"></i><span>{{ departmentLabel }}</span></p>\n @if((shift.taskCount ?? 0) > 0) {\n <p><i class=\"pi pi-check-square\" aria-hidden=\"true\"></i><span>{{ taskLabel }}</span></p>\n }\n } @else {\n @if(shift.location) {\n <p><i class=\"pi pi-map-marker\" aria-hidden=\"true\"></i><span>{{ shift.location }}</span></p>\n }\n @if(shift.role) {\n <p><i class=\"pi pi-user\" aria-hidden=\"true\"></i><span>{{ shift.role }}</span></p>\n }\n }\n }\n</article>\n", styles: [":host{display:block;width:100%;min-width:0}.max-agent-shift-card{--max-agent-shift-accent: #64748b;display:grid;gap:6px;box-sizing:border-box;width:100%;min-width:0;max-width:100%;padding:9px 10px 8px;overflow:hidden;border:1px solid var(--max-border, #dbe2ea);border-bottom:4px solid var(--max-agent-shift-accent);border-radius:8px;color:var(--max-text, #1e293b);background:var(--max-surface, #fff);box-shadow:0 1px 2px #0f172a14}.max-agent-shift-card header{display:flex;gap:8px;align-items:baseline;justify-content:space-between;min-width:0}.max-agent-shift-card header strong{flex:0 0 auto;color:var(--max-text, #1e293b);font-size:12px;line-height:1.3;white-space:nowrap}.max-agent-shift-card header span{overflow:hidden;color:var(--max-text, #1e293b);font-size:10px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.max-agent-shift-card p{display:grid;grid-template-columns:14px minmax(0,1fr);gap:6px;align-items:start;margin:0;color:var(--max-text, #334155);font-size:11px;line-height:1.3}.max-agent-shift-card p i{margin-top:1px;color:var(--max-text, #334155);font-size:11px}.max-agent-shift-card p span{min-width:0;overflow-wrap:anywhere}.definition-card{min-height:128px}.rota-card{min-height:54px}\n"] }]
768
+ }], propDecorators: { shift: [{
769
+ type: Input,
770
+ args: [{ required: true }]
771
+ }], variant: [{
772
+ type: Input
773
+ }], icons: [{
774
+ type: Input
775
+ }] } });
776
+
777
+ class MaxAgentPersonComponent {
778
+ person;
779
+ photoUnavailable = false;
780
+ previousPhoto;
781
+ ngOnChanges() {
782
+ // Table presentation may recreate identity objects during change detection.
783
+ // Retry a failed image only when its URL changes.
784
+ if (this.previousPhoto !== this.person.photo) {
785
+ this.photoUnavailable = false;
786
+ this.previousPhoto = this.person.photo;
787
+ }
788
+ }
789
+ get code() { return this.person.code ?? this.person.id; }
790
+ get photo() {
791
+ const value = this.person.photo?.trim();
792
+ return !this.photoUnavailable && value && /^(?:https?:\/\/|data:image\/(?:png|jpeg|webp|gif);base64,|\/|assets\/)/iu.test(value) ? value : undefined;
793
+ }
794
+ get initials() {
795
+ return this.person.name.split(/\s+/u).filter(Boolean).slice(0, 2).map(part => part[0]?.toUpperCase()).join('');
796
+ }
797
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentPersonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
798
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAgentPersonComponent, isStandalone: true, selector: "max-agent-person", inputs: { person: "person" }, host: { classAttribute: "gap-2" }, usesOnChanges: true, ngImport: i0, template: `
799
+ <p-avatar class="flex-shrink-0" shape="circle" [image]="photo" [label]="photo ? undefined : initials"
800
+ [ariaLabel]="person.name + ' photo'" (onImageError)="photoUnavailable = true"></p-avatar>
801
+ <span class="person-copy">
802
+ <span class="person-name">{{ person.name }}</span>
803
+ @if(code !== undefined && code !== '') { <small><em>#{{ code }}</em></small> }
804
+ </span>
805
+ `, isInline: true, styles: [":host{display:flex;align-items:center;min-width:0;font-size:inherit}p-avatar{font:inherit;line-height:1lh;width:2lh;height:2lh}.person-copy{display:flex;flex-direction:column;min-width:0;overflow-wrap:anywhere;line-height:1lh}.person-name{font:inherit;font-weight:600;color:var(--primary-color)}small{color:var(--text-color-secondary);line-height:inherit}\n"], dependencies: [{ kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i1$1.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
806
+ }
807
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentPersonComponent, decorators: [{
808
+ type: Component,
809
+ args: [{ selector: 'max-agent-person', standalone: true, imports: [AvatarModule], host: { class: 'gap-2' }, changeDetection: ChangeDetectionStrategy.OnPush, template: `
810
+ <p-avatar class="flex-shrink-0" shape="circle" [image]="photo" [label]="photo ? undefined : initials"
811
+ [ariaLabel]="person.name + ' photo'" (onImageError)="photoUnavailable = true"></p-avatar>
812
+ <span class="person-copy">
813
+ <span class="person-name">{{ person.name }}</span>
814
+ @if(code !== undefined && code !== '') { <small><em>#{{ code }}</em></small> }
815
+ </span>
816
+ `, styles: [":host{display:flex;align-items:center;min-width:0;font-size:inherit}p-avatar{font:inherit;line-height:1lh;width:2lh;height:2lh}.person-copy{display:flex;flex-direction:column;min-width:0;overflow-wrap:anywhere;line-height:1lh}.person-name{font:inherit;font-weight:600;color:var(--primary-color)}small{color:var(--text-color-secondary);line-height:inherit}\n"] }]
817
+ }], propDecorators: { person: [{
818
+ type: Input,
819
+ args: [{ required: true }]
820
+ }] } });
821
+
822
+ const ENTITY_ICONS = {
823
+ team: 'pi pi-users',
824
+ role: 'pi pi-id-card',
825
+ location: 'pi pi-map-marker',
826
+ position: 'pi pi-briefcase',
827
+ department: 'pi pi-building',
828
+ entity: 'pi pi-tag',
829
+ };
830
+ class MaxAgentEntityOptionComponent {
831
+ entity;
832
+ disabled = false;
833
+ availability;
834
+ icons = {};
835
+ selected = new EventEmitter();
836
+ get isPerson() {
837
+ return this.entity.kind === 'person' || this.entity.kind === 'employee';
838
+ }
839
+ get entityColor() {
840
+ return this.normaliseColor(this.entity.color);
841
+ }
842
+ get entityTextColor() {
843
+ return this.normaliseColor(this.entity.textColor);
844
+ }
845
+ get entityIcon() {
846
+ return ENTITY_ICONS[this.entity.kind] ?? 'pi pi-tag';
847
+ }
848
+ choose() {
849
+ if (!this.disabled) {
850
+ this.selected.emit();
851
+ }
852
+ }
853
+ normaliseColor(value) {
854
+ const color = value?.trim();
855
+ if (!color) {
856
+ return undefined;
857
+ }
858
+ return /^[\da-f]{3,8}$/iu.test(color) ? `#${color}` : color;
859
+ }
860
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentEntityOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
861
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAgentEntityOptionComponent, isStandalone: true, selector: "max-agent-entity-option", inputs: { entity: "entity", disabled: "disabled", availability: "availability", icons: "icons" }, outputs: { selected: "selected" }, ngImport: i0, template: "<ng-template #personHeader>\n <max-agent-person class=\"flex-1\" [person]=\"entity\"></max-agent-person>\n</ng-template>\n@if(availability; as person) {\n <article class=\"entity-option entity-option-person availability-person\" [attr.aria-label]=\"person.name\">\n <header class=\"flex align-items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"personHeader\"></ng-container>\n <p-button class=\"flex-shrink-0\" label=\"Assign\" severity=\"primary\" size=\"small\" [disabled]=\"true\"></p-button>\n </header>\n <p-divider></p-divider>\n <div class=\"flex flex-column gap-2\">\n <div class=\"flex align-items-center gap-2\">@if(icons.team) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.team\" title=\"Team\" aria-hidden=\"true\"></i> }<span>{{ person.team }}</span></div>\n <div class=\"flex align-items-center gap-2\">@if(icons.role) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.role\" title=\"Role\" aria-hidden=\"true\"></i> }<span>{{ person.role }}</span></div>\n <div class=\"flex align-items-center gap-2\">@if(icons.location) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.location\" title=\"Location\" aria-hidden=\"true\"></i> }<span>{{ person.location }}</span></div>\n </div>\n </article>\n} @else {\n<button\n type=\"button\"\n class=\"entity-option\"\n [class.entity-option-person]=\"isPerson\"\n [class.entity-option-tag]=\"!isPerson\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'Choose ' + entity.name\"\n [style.--max-agent-entity-color]=\"entityColor\"\n [style.--max-agent-entity-text-color]=\"entityTextColor\"\n (click)=\"choose()\"\n>\n @if (isPerson) {\n <ng-container [ngTemplateOutlet]=\"personHeader\"></ng-container>\n <i class=\"pi pi-arrow-right option-arrow\" aria-hidden=\"true\"></i>\n } @else {\n <span class=\"entity-icon\" aria-hidden=\"true\">\n <i [class]=\"entityIcon\"></i>\n </span>\n <span class=\"entity-name\">{{ entity.name }}</span>\n }\n</button>\n}\n", styles: [":host{display:block;min-width:0}.entity-option{align-items:center;border:0;color:var(--text-color, #1e293b);cursor:pointer;display:flex;font:inherit;min-width:0;text-align:left;border-radius:16px}.entity-option:disabled{cursor:default;opacity:.55}.entity-option-person{font-size:var(--max-content-text-size, inherit);background:var(--surface-card, #fff);border:1px solid var(--border-color, #e2e8f0);gap:12px;padding:10px 12px;transition:background .16s ease,box-shadow .16s ease,transform .16s ease;width:100%}.entity-option-person:not(.availability-person):not(:disabled):hover{background:var(--surface-hover, #f8fafc);box-shadow:0 7px 18px #0f172a1a;transform:translateY(-1px)}.entity-option-person:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:2px}.option-arrow{color:var(--text-color-secondary, #64748b);flex:0 0 auto}.entity-option-tag{background:transparent;border-radius:var(--border-radius, 6px);gap:8px;padding:4px 8px 4px 4px}.entity-option-tag:not(:disabled):hover{background:var(--surface-hover, #f8fafc)}.entity-icon{align-items:center;background:var(--max-agent-entity-color, var(--surface-100, #f1f5f9));border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px);color:var(--max-agent-entity-text-color, var(--text-color, #1e293b));display:inline-flex;height:30px;justify-content:center;width:30px}.entity-name{font-weight:600}.availability-person{display:block;cursor:default;height:100%;box-sizing:border-box;overflow-wrap:anywhere}.availability-person i{font-size:inherit}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2$1.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "component", type: MaxAgentPersonComponent, selector: "max-agent-person", inputs: ["person"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
862
+ }
863
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAgentEntityOptionComponent, decorators: [{
864
+ type: Component,
865
+ args: [{ selector: 'max-agent-entity-option', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, ButtonModule, DividerModule, MaxAgentPersonComponent], template: "<ng-template #personHeader>\n <max-agent-person class=\"flex-1\" [person]=\"entity\"></max-agent-person>\n</ng-template>\n@if(availability; as person) {\n <article class=\"entity-option entity-option-person availability-person\" [attr.aria-label]=\"person.name\">\n <header class=\"flex align-items-center gap-2\">\n <ng-container [ngTemplateOutlet]=\"personHeader\"></ng-container>\n <p-button class=\"flex-shrink-0\" label=\"Assign\" severity=\"primary\" size=\"small\" [disabled]=\"true\"></p-button>\n </header>\n <p-divider></p-divider>\n <div class=\"flex flex-column gap-2\">\n <div class=\"flex align-items-center gap-2\">@if(icons.team) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.team\" title=\"Team\" aria-hidden=\"true\"></i> }<span>{{ person.team }}</span></div>\n <div class=\"flex align-items-center gap-2\">@if(icons.role) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.role\" title=\"Role\" aria-hidden=\"true\"></i> }<span>{{ person.role }}</span></div>\n <div class=\"flex align-items-center gap-2\">@if(icons.location) { <i class=\"fa-fw flex-shrink-0\" [class]=\"icons.location\" title=\"Location\" aria-hidden=\"true\"></i> }<span>{{ person.location }}</span></div>\n </div>\n </article>\n} @else {\n<button\n type=\"button\"\n class=\"entity-option\"\n [class.entity-option-person]=\"isPerson\"\n [class.entity-option-tag]=\"!isPerson\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'Choose ' + entity.name\"\n [style.--max-agent-entity-color]=\"entityColor\"\n [style.--max-agent-entity-text-color]=\"entityTextColor\"\n (click)=\"choose()\"\n>\n @if (isPerson) {\n <ng-container [ngTemplateOutlet]=\"personHeader\"></ng-container>\n <i class=\"pi pi-arrow-right option-arrow\" aria-hidden=\"true\"></i>\n } @else {\n <span class=\"entity-icon\" aria-hidden=\"true\">\n <i [class]=\"entityIcon\"></i>\n </span>\n <span class=\"entity-name\">{{ entity.name }}</span>\n }\n</button>\n}\n", styles: [":host{display:block;min-width:0}.entity-option{align-items:center;border:0;color:var(--text-color, #1e293b);cursor:pointer;display:flex;font:inherit;min-width:0;text-align:left;border-radius:16px}.entity-option:disabled{cursor:default;opacity:.55}.entity-option-person{font-size:var(--max-content-text-size, inherit);background:var(--surface-card, #fff);border:1px solid var(--border-color, #e2e8f0);gap:12px;padding:10px 12px;transition:background .16s ease,box-shadow .16s ease,transform .16s ease;width:100%}.entity-option-person:not(.availability-person):not(:disabled):hover{background:var(--surface-hover, #f8fafc);box-shadow:0 7px 18px #0f172a1a;transform:translateY(-1px)}.entity-option-person:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:2px}.option-arrow{color:var(--text-color-secondary, #64748b);flex:0 0 auto}.entity-option-tag{background:transparent;border-radius:var(--border-radius, 6px);gap:8px;padding:4px 8px 4px 4px}.entity-option-tag:not(:disabled):hover{background:var(--surface-hover, #f8fafc)}.entity-icon{align-items:center;background:var(--max-agent-entity-color, var(--surface-100, #f1f5f9));border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px);color:var(--max-agent-entity-text-color, var(--text-color, #1e293b));display:inline-flex;height:30px;justify-content:center;width:30px}.entity-name{font-weight:600}.availability-person{display:block;cursor:default;height:100%;box-sizing:border-box;overflow-wrap:anywhere}.availability-person i{font-size:inherit}\n"] }]
866
+ }], propDecorators: { entity: [{
867
+ type: Input,
868
+ args: [{ required: true }]
869
+ }], disabled: [{
870
+ type: Input
871
+ }], availability: [{
872
+ type: Input
873
+ }], icons: [{
874
+ type: Input
875
+ }], selected: [{
876
+ type: Output
877
+ }] } });
878
+
879
+ const key = (value) => value.toLowerCase().replace(/[^a-z]/g, '');
880
+ const names = new Set(['employee', 'employeename', 'person', 'personname', 'fullname']);
881
+ const codes = new Set(['code', 'empid', 'employeecode', 'employeeno', 'employeenumber', 'employeereference']);
882
+ const ids = new Set(['id', 'employeeid', 'personid']);
883
+ const photos = new Set(['photo', 'photourl', 'employeephoto', 'personphoto']);
884
+ const text = (value) => typeof value === 'string' || typeof value === 'number' ? String(value) : undefined;
885
+ function personTable(table) {
886
+ if (table.columns.some(column => column.kind === 'person'))
887
+ return table;
888
+ const find = (test) => table.columns.find(column => test(key(column.field)) || test(key(column.header)));
889
+ const explicitName = find(value => names.has(value));
890
+ const name = explicitName ?? find(value => value === 'name');
891
+ const first = find(value => value === 'forename' || value === 'firstname');
892
+ const last = find(value => value === 'surname' || value === 'lastname');
893
+ const code = find(value => codes.has(value));
894
+ const id = find(value => ids.has(value));
895
+ const photo = find(value => photos.has(value));
896
+ if (!name && !first)
897
+ return table;
898
+ const personContext = /employee|people|person|staff/i.test(table.title ?? '') || table.columns.some(column => /^(employeeid|personid|employeecode|empid)$/.test(key(column.field)));
899
+ if (!explicitName && !first && !personContext)
900
+ return table;
901
+ const hidden = new Set([name?.field, first?.field, last?.field, code?.field, id?.field, photo?.field].filter(Boolean));
902
+ const people = table.rows.map(row => {
903
+ let nameValue = text(name ? row[name.field] : [row[first.field], last ? row[last.field] : undefined].filter(Boolean).join(' ')) ?? 'Unknown person';
904
+ const embeddedCode = nameValue.match(/\s*\(#\s*([^)]*)\)\s*$/u);
905
+ if (embeddedCode)
906
+ nameValue = nameValue.slice(0, embeddedCode.index).trim();
907
+ return { name: nameValue, code: text(code ? row[code.field] : undefined) ?? embeddedCode?.[1] ?? text(id ? row[id.field] : undefined), photo: text(photo ? row[photo.field] : row['photo']) };
908
+ });
909
+ return { ...table, people,
910
+ columns: [{ field: '__person', header: 'Person', kind: 'person' }, ...table.columns.filter(column => !hidden.has(column.field))],
911
+ rows: table.rows.map((row, index) => ({ ...row, __person: people[index].name + (people[index].code ? ` (#${people[index].code})` : '') })) };
912
+ }
913
+ function personCard(card) {
914
+ if (card.person)
915
+ return card;
916
+ const name = card.metrics.find(metric => names.has(key(metric.label)) || key(metric.label) === 'name');
917
+ const first = card.metrics.find(metric => /^(forename|firstname)$/.test(key(metric.label)));
918
+ const last = card.metrics.find(metric => /^(surname|lastname)$/.test(key(metric.label)));
919
+ const code = card.metrics.find(metric => codes.has(key(metric.label)) || ids.has(key(metric.label)));
920
+ const photo = card.metrics.find(metric => photos.has(key(metric.label)));
921
+ if (!name && !first)
922
+ return card;
923
+ if (name && key(name.label) === 'name' && !first && !/employee|people|person|staff/i.test(card.title))
924
+ return card;
925
+ return { ...card, person: { name: name?.value ?? [first?.value, last?.value].filter(Boolean).join(' '), ...(code ? { code: code.value } : {}), ...(photo ? { photo: photo.value } : {}) },
926
+ metrics: card.metrics.filter(metric => ![name, first, last, code, photo].includes(metric)) };
927
+ }
928
+
834
929
  const ASSISTANT_UI_COPY = {
835
930
  title: 'Max AI',
836
931
  subtitle: 'Your Personal AI Assistant',
@@ -875,12 +970,12 @@ const ASSISTANT_HELP_ICONS = {
875
970
  workflow: 'pi pi-sitemap',
876
971
  };
877
972
  class MaxAssistantComponent {
878
- assistantService;
879
- exportService;
880
- feedbackService;
881
- supportService;
882
- destroyRef;
883
- defaultConfig;
973
+ assistantService = inject(MaxAssistantService);
974
+ exportService = inject(MaxAssistantExportService);
975
+ feedbackService = inject(MaxAssistantFeedbackService);
976
+ supportService = inject(MaxAssistantSupportService);
977
+ destroyRef = inject(DestroyRef);
978
+ defaultConfig = inject(MAX_ASSISTANT_CONFIG);
884
979
  sessionState = new AssistantConversationState();
885
980
  messagesViewport;
886
981
  activeTurnAnchorMessageId;
@@ -891,6 +986,7 @@ class MaxAssistantComponent {
891
986
  supportQueryInput;
892
987
  feedbackInput;
893
988
  app;
989
+ entityIcons = {};
894
990
  assistantApiUrl;
895
991
  user;
896
992
  context;
@@ -928,14 +1024,6 @@ class MaxAssistantComponent {
928
1024
  supportTicketError = signal(undefined, ...(ngDevMode ? [{ debugName: "supportTicketError" }] : []));
929
1025
  supportTicketSubmissionFailed = signal(false, ...(ngDevMode ? [{ debugName: "supportTicketSubmissionFailed" }] : []));
930
1026
  supportTicketForm = this.createSupportTicketForm();
931
- constructor(assistantService, exportService, feedbackService, supportService, destroyRef, defaultConfig) {
932
- this.assistantService = assistantService;
933
- this.exportService = exportService;
934
- this.feedbackService = feedbackService;
935
- this.supportService = supportService;
936
- this.destroyRef = destroyRef;
937
- this.defaultConfig = defaultConfig;
938
- }
939
1027
  ngOnInit() {
940
1028
  this.messages.set(this.createDefaultMessages());
941
1029
  this.destroyRef.onDestroy(() => {
@@ -1332,6 +1420,8 @@ class MaxAssistantComponent {
1332
1420
  return table.actions?.filter(action => action.rowIndex === rowIndex) ?? [];
1333
1421
  }
1334
1422
  useTableAction(action) {
1423
+ if (action.disabled || this.isSending())
1424
+ return;
1335
1425
  const label = action.label.trim();
1336
1426
  if (!label || this.isSending()) {
1337
1427
  return;
@@ -1453,8 +1543,9 @@ class MaxAssistantComponent {
1453
1543
  });
1454
1544
  }
1455
1545
  getResponseGrid(responseDetails) {
1456
- return responseDetails.grid?.length ? responseDetails.grid : responseDetails.tables ?? [];
1546
+ return (responseDetails.grid?.length ? responseDetails.grid : responseDetails.tables ?? []).map(personTable);
1457
1547
  }
1548
+ personCard = personCard;
1458
1549
  retrieveNextTablePage(message, table, tableIndex) {
1459
1550
  const pagination = table.pagination;
1460
1551
  if (!pagination || !this.hasNextTablePage(table) || this.isSending()) {
@@ -1951,6 +2042,7 @@ class MaxAssistantComponent {
1951
2042
  tables[tableIndex] = {
1952
2043
  ...currentTable,
1953
2044
  rows,
2045
+ ...(currentTable.people ? { people: [...currentTable.people, ...(nextTable.people ?? [])].slice(0, rows.length) } : {}),
1954
2046
  ...(nextTable.actions?.length
1955
2047
  ? {
1956
2048
  actions: [
@@ -2147,6 +2239,7 @@ class MaxAssistantComponent {
2147
2239
  searchResults: provided.searchResults,
2148
2240
  visualisations: provided.visualisations,
2149
2241
  shiftCardGroups: provided.shiftCardGroups,
2242
+ availablePeople: provided.availablePeople,
2150
2243
  rota: provided.rota,
2151
2244
  markdown: provided.markdown
2152
2245
  };
@@ -2195,7 +2288,7 @@ class MaxAssistantComponent {
2195
2288
  if (provided.tables?.length) {
2196
2289
  return provided.tables;
2197
2290
  }
2198
- if (provided.shiftCardGroups?.length || provided.rota) {
2291
+ if (provided.availablePeople?.length || provided.shiftCardGroups?.length || provided.rota) {
2199
2292
  return [];
2200
2293
  }
2201
2294
  const rows = this.extractTableRows(provided.apiResponse ?? response.apiResult);
@@ -2311,8 +2404,8 @@ class MaxAssistantComponent {
2311
2404
  viewport.scrollTop = Math.max(0, viewport.scrollTop + messageTop - viewportTop - paddingTop);
2312
2405
  });
2313
2406
  }
2314
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, deps: [{ token: MaxAssistantService }, { token: MaxAssistantExportService }, { token: MaxAssistantFeedbackService }, { token: MaxAssistantSupportService }, { token: i0.DestroyRef }, { token: MAX_ASSISTANT_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
2315
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAssistantComponent, isStandalone: true, selector: "max-assistant", inputs: { app: "app", assistantApiUrl: "assistantApiUrl", user: "user", context: "context", requestHeaders: "requestHeaders", developerDetailsEnabled: "developerDetailsEnabled" }, outputs: { hostAction: "hostAction", closeRequested: "closeRequested" }, host: { listeners: { "window:pagehide": "onPageHide()", "document:keydown.escape": "onDocumentEscape()" } }, viewQueries: [{ propertyName: "messagesViewport", first: true, predicate: ["messagesViewport"], descendants: true }, { propertyName: "composerInput", first: true, predicate: ["composerInput"], descendants: true }, { propertyName: "supportQueryInput", first: true, predicate: ["supportQueryInput"], descendants: true }, { propertyName: "feedbackInput", first: true, predicate: ["feedbackInput"], descendants: true }], ngImport: i0, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError && !message.isOffline && !message.isAccessUnavailable\"\n [class.streaming]=\"message.isStreaming\"\n [attr.aria-live]=\"message.isStreaming ? 'polite' : null\"\n [attr.aria-busy]=\"message.isStreaming || null\"\n [attr.role]=\"message.isStreaming ? 'status' : null\"\n >\n @if(message.isAccessUnavailable) {\n <section class=\"assistant-offline assistant-access-unavailable\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.accessUnavailableTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"52\" ry=\"6\" />\n <path class=\"offline-cloud-body\" d=\"M100 16 151 36v39c0 31-24 49-51 61-27-12-51-30-51-61V36Z\" />\n <path d=\"M84 73V60a16 16 0 0 1 32 0v13\" />\n <path class=\"offline-plug\" d=\"M77 73h46v37H77Z\" />\n <path d=\"M100 86v11\" />\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isOffline) {\n <section class=\"assistant-offline\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.offlineTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"61\" ry=\"6\" />\n <g class=\"offline-cloud\">\n <path class=\"offline-cloud-body\" d=\"M61 86a23 23 0 0 1-3-46 32 32 0 0 1 61-9 27 27 0 0 1 20 55Z\" />\n <path class=\"offline-face\" d=\"M80 58q5 4 10 0m18 0q5 4 10 0M95 72h9\" />\n </g>\n <g class=\"offline-plug-left\">\n <path class=\"offline-cable\" d=\"M25 98v7q0 11 11 11h20\" />\n <path class=\"offline-plug\" d=\"M56 107h15v18H56q-5 0-5-5v-8q0-5 5-5Z\" />\n <path class=\"offline-cable\" d=\"M71 111h8m-8 10h8\" />\n </g>\n <g class=\"offline-plug-right\">\n <path class=\"offline-cable\" d=\"M174 98v7q0 11-11 11h-20\" />\n <path class=\"offline-plug\" d=\"M143 107h-15v18h15q5 0 5-5v-8q0-5-5-5Z\" />\n <path class=\"offline-cable\" d=\"M132 113v6\" />\n </g>\n <g class=\"offline-disconnected\" aria-hidden=\"true\">\n <path d=\"m101 105-5 22m-9-23-3-5m29 5 3-5\" />\n </g>\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isStreaming && !message.displayResponse && !message.cards?.length) {\n <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @if(!message.streamingContent) {\n <p class=\"assistant-processing-update active\">\n <span class=\"assistant-processing-sparkles\" aria-hidden=\"true\">\n @for (star of ['main', 'upper', 'lower', 'small']; track star) {\n <img\n class=\"assistant-processing-star {{ star }}\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n >\n }\n </span>\n <span>{{ message.content }}</span>\n </p>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n <div class=\"assistant-card-metrics\">\n @for(metric of card.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'mediumTime' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n <h3>{{ group.title }}</h3>\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"definition\"\n ></max-agent-shift-card>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation, chartCanvas)\"\n ></button>\n </header>\n <div\n #chartCanvas\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel\"\n icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"\n ></button>\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th>SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th>{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th>Actions</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td>{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td>{{ row[column.field] }}</td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending()\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination; as pagination) {\n <footer class=\"assistant-table-pagination\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </footer>\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming && !message.isOffline && !message.isAccessUnavailable) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px 10px;border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:wrap;gap:6px;min-width:150px}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-blue: var(--assistant-sparkles-blue, #2563eb);--max-sparkles-purple: var(--assistant-sparkles-purple, #8b5cf6);--max-sparkles-pink: var(--assistant-sparkles-pink, #ec4899);--max-sparkles-gradient: linear-gradient( 90deg, var(--max-sparkles-blue) 0%, var(--max-sparkles-purple) 16.667%, var(--max-sparkles-pink) 33.333%, var(--max-sparkles-blue) 50%, var(--max-sparkles-purple) 66.667%, var(--max-sparkles-pink) 83.333%, var(--max-sparkles-blue) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.assistant-offline{display:grid;justify-items:center;gap:calc(var(--max-header-content-size) / 2);max-width:calc(var(--max-header-action-size) * 10);margin-inline:auto;padding-block:var(--max-header-sparkles-size);text-align:center}.assistant-offline p{margin:0;color:var(--max-muted);line-height:1.6}.assistant-offline p-button{margin-top:calc(var(--max-header-content-size) / 2)}.assistant-offline-art{width:calc(var(--max-header-action-size) * 5);max-width:100%;height:auto;overflow:visible}.assistant-offline-art path{stroke:var(--max-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;fill:none}.assistant-offline-art .offline-shadow{fill:var(--max-border);opacity:.35}.assistant-offline-art .offline-cloud-body{fill:var(--max-surface);stroke:var(--max-border)}.assistant-offline-art .offline-plug{fill:var(--max-surface-soft)}.assistant-offline-art .offline-disconnected path{stroke:var(--max-warning)}.assistant-offline-art .offline-cloud{animation:max-offline-float 4s ease-in-out infinite}.assistant-offline-art .offline-plug-left{animation:max-offline-left 4s ease-in-out infinite}.assistant-offline-art .offline-plug-right{animation:max-offline-right 4s ease-in-out infinite}.assistant-offline-art .offline-disconnected{animation:max-offline-signal 4s ease-in-out infinite}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-update{display:grid;grid-template-columns:var(--max-header-content-size) minmax(0,1fr);gap:9px;align-items:center;margin:0;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-update.active>span:last-child{background:var(--max-sparkles-gradient);width:fit-content;background-size:200% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-sparkles{position:relative;width:var(--max-header-content-size);height:var(--max-header-content-size)}.assistant-processing-star{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transform-origin:47.5% 50%;animation:max-processing-orbit 6s linear infinite}.assistant-processing-star.main{clip-path:polygon(47% 16%,62% 40%,82% 50%,62% 61%,47% 82%,34% 61%,14% 50%,34% 40%);animation:none}.assistant-processing-star.upper{clip-path:inset(6% 7% 60% 61%)}.assistant-processing-star.lower{clip-path:polygon(22.5% 62%,37% 77%,22.5% 91%,7% 77%)}.assistant-processing-star.small{clip-path:inset(64% 22% 21% 65%)}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3{color:var(--max-text);font-size:14px}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-offline-float{0%,to{transform:translateY(0)}50%{transform:translateY(-3%)}}@keyframes max-offline-left{0%,to{transform:translate(0)}50%{transform:translate(-2%)}}@keyframes max-offline-right{0%,to{transform:translate(0)}50%{transform:translate(2%)}}@keyframes max-offline-signal{0%,to{opacity:1}50%{opacity:.4}}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:100% 0}to{background-position:0% 0}}@keyframes max-processing-orbit{to{transform:rotate(360deg)}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-offline-art g,.assistant-processing-update.active>span:last-child,.assistant-processing-star,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ChartModule }, { kind: "component", type: i7.UIChart, selector: "p-chart", inputs: ["type", "plugins", "width", "height", "responsive", "ariaLabel", "ariaLabelledBy", "data", "options"], outputs: ["onDataSelect"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i9.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i10.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i11.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: MaxAgentEntityOptionComponent, selector: "max-agent-entity-option", inputs: ["entity", "disabled"], outputs: ["selected"] }, { kind: "component", type: MaxAgentShiftCardComponent, selector: "max-agent-shift-card", inputs: ["shift", "variant"] }, { kind: "pipe", type: i13.DatePipe, name: "date" }, { kind: "pipe", type: MaxAssistantMarkdownPipe, name: "maxAssistantMarkdown" }] });
2407
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2408
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAssistantComponent, isStandalone: true, selector: "max-assistant", inputs: { app: "app", entityIcons: "entityIcons", assistantApiUrl: "assistantApiUrl", user: "user", context: "context", requestHeaders: "requestHeaders", developerDetailsEnabled: "developerDetailsEnabled" }, outputs: { hostAction: "hostAction", closeRequested: "closeRequested" }, host: { listeners: { "window:pagehide": "onPageHide()", "document:keydown.escape": "onDocumentEscape()" } }, viewQueries: [{ propertyName: "messagesViewport", first: true, predicate: ["messagesViewport"], descendants: true }, { propertyName: "composerInput", first: true, predicate: ["composerInput"], descendants: true }, { propertyName: "supportQueryInput", first: true, predicate: ["supportQueryInput"], descendants: true }, { propertyName: "feedbackInput", first: true, predicate: ["feedbackInput"], descendants: true }], ngImport: i0, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError && !message.isOffline && !message.isAccessUnavailable\"\n [class.streaming]=\"message.isStreaming\"\n [attr.aria-live]=\"message.isStreaming ? 'polite' : null\"\n [attr.aria-busy]=\"message.isStreaming || null\"\n [attr.role]=\"message.isStreaming ? 'status' : null\"\n >\n @if(message.isAccessUnavailable) {\n <section class=\"assistant-offline assistant-access-unavailable\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.accessUnavailableTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"52\" ry=\"6\" />\n <path class=\"offline-cloud-body\" d=\"M100 16 151 36v39c0 31-24 49-51 61-27-12-51-30-51-61V36Z\" />\n <path d=\"M84 73V60a16 16 0 0 1 32 0v13\" />\n <path class=\"offline-plug\" d=\"M77 73h46v37H77Z\" />\n <path d=\"M100 86v11\" />\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isOffline) {\n <section class=\"assistant-offline\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.offlineTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"61\" ry=\"6\" />\n <g class=\"offline-cloud\">\n <path class=\"offline-cloud-body\" d=\"M61 86a23 23 0 0 1-3-46 32 32 0 0 1 61-9 27 27 0 0 1 20 55Z\" />\n <path class=\"offline-face\" d=\"M80 58q5 4 10 0m18 0q5 4 10 0M95 72h9\" />\n </g>\n <g class=\"offline-plug-left\">\n <path class=\"offline-cable\" d=\"M25 98v7q0 11 11 11h20\" />\n <path class=\"offline-plug\" d=\"M56 107h15v18H56q-5 0-5-5v-8q0-5 5-5Z\" />\n <path class=\"offline-cable\" d=\"M71 111h8m-8 10h8\" />\n </g>\n <g class=\"offline-plug-right\">\n <path class=\"offline-cable\" d=\"M174 98v7q0 11-11 11h-20\" />\n <path class=\"offline-plug\" d=\"M143 107h-15v18h15q5 0 5-5v-8q0-5-5-5Z\" />\n <path class=\"offline-cable\" d=\"M132 113v6\" />\n </g>\n <g class=\"offline-disconnected\" aria-hidden=\"true\">\n <path d=\"m101 105-5 22m-9-23-3-5m29 5 3-5\" />\n </g>\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isStreaming && !message.displayResponse && !message.cards?.length) {\n <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @if(!message.streamingContent) {\n <p class=\"assistant-processing-update active\">\n <span class=\"assistant-processing-sparkles\" aria-hidden=\"true\">\n @for (star of ['main', 'upper', 'lower', 'small']; track star) {\n <img\n class=\"assistant-processing-star {{ star }}\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n >\n }\n </span>\n <span>{{ message.content }}</span>\n </p>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n @let displayedCard = personCard(card);\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n @if(displayedCard.person; as person) {\n <max-agent-person [person]=\"person\"></max-agent-person>\n }\n <div class=\"assistant-card-metrics\">\n @for(metric of displayedCard.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'd MMM yyyy, h:mm a' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.availablePeople?.length) {\n <section class=\"assistant-people-section\" aria-label=\"Available people\">\n <h3>Available people</h3>\n <div class=\"entity-options\">\n @for(person of responseDetails.availablePeople; track person.id) {\n <max-agent-entity-option [entity]=\"person\" [availability]=\"person\" [icons]=\"entityIcons\"></max-agent-entity-option>\n }\n </div>\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n @if(group.variant !== 'assignment') { <h3>{{ group.title }}</h3> }\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n @if(shift.selection; as selection) {\n <button pButton type=\"button\" [text]=\"true\"\n class=\"assistant-shift-selection\"\n [attr.aria-label]=\"selection.label\"\n [disabled]=\"isSending()\"\n (click)=\"useSuggestion(selection)\">\n <max-agent-shift-card [shift]=\"shift\" [variant]=\"group.variant || 'rota'\" [icons]=\"entityIcons\"></max-agent-shift-card>\n </button>\n } @else {\n <max-agent-shift-card\n [shift]=\"shift\"\n [variant]=\"group.variant || 'definition'\"\n ></max-agent-shift-card>\n }\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation, chartCanvas)\"\n ></button>\n </header>\n <div\n #chartCanvas\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n @if(table.bulkActions?.length) {\n <div class=\"flex gap-2 flex-wrap justify-content-end ml-auto\">\n @for(action of table.bulkActions; track action.label) {\n <p-button [label]=\"action.label\" [severity]=\"action.tone || 'secondary'\" size=\"small\"\n [outlined]=\"action.outlined ?? action.tone === 'danger'\" [disabled]=\"isSending() || action.disabled === true\"\n (onClick)=\"useTableAction(action)\"></p-button>\n }\n </div>\n }\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th class=\"assistant-table-serial\">SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th [class.w-full]=\"column.kind === 'person' && !!table.actions?.length\"\n [class.white-space-nowrap]=\"!!table.actions?.length && column.kind !== 'person'\">{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th class=\"w-1 white-space-nowrap\">{{ table.actionsHeader ?? 'Actions' }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td class=\"assistant-table-serial\">{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td [class.white-space-nowrap]=\"!!table.actions?.length && column.kind !== 'person'\">\n @if(column.kind === 'person' && table.people?.[rowIndex]; as person) {\n <max-agent-person [person]=\"person\"></max-agent-person>\n } @else if(column.secondaryField) {\n <div class=\"white-space-nowrap\">{{ row[column.field] }}</div>\n @if(row[column.secondaryField]) {\n <div class=\"white-space-nowrap\">{{ row[column.secondaryField] }}</div>\n }\n } @else { {{ row[column.field] }} }\n </td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.outlined ?? action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending() || action.disabled === true\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination || (!table.actions?.length && !table.bulkActions?.length)) {\n <footer class=\"assistant-table-pagination flex-nowrap\">\n @if(table.pagination; as pagination) {\n <div class=\"flex flex-1 align-items-center flex-wrap gap-2\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </div>\n }\n @if(!table.actions?.length && !table.bulkActions?.length) {\n <button pButton type=\"button\" size=\"small\" severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel ml-auto flex-shrink-0\" icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"></button>\n }\n </footer>\n }\n @if(table.pagination) {\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming && !message.isOffline && !message.isAccessUnavailable) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3,.assistant-people-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{--max-table-cell-inline-padding: 10px;--max-table-serial-width: calc(6ch + 2 * var(--max-table-cell-inline-padding));overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px var(--max-table-cell-inline-padding);border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap .assistant-table-serial{box-sizing:border-box;width:var(--max-table-serial-width);min-width:var(--max-table-serial-width);max-width:var(--max-table-serial-width);white-space:nowrap;font-variant-numeric:tabular-nums}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:nowrap;gap:6px;width:max-content}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}:host .assistant-shift-selection{display:block;padding:0;width:100%;height:auto;min-width:0;text-align:start}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-blue: var(--assistant-sparkles-blue, #2563eb);--max-sparkles-purple: var(--assistant-sparkles-purple, #8b5cf6);--max-sparkles-pink: var(--assistant-sparkles-pink, #ec4899);--max-sparkles-gradient: linear-gradient( 90deg, var(--max-sparkles-blue) 0%, var(--max-sparkles-purple) 16.667%, var(--max-sparkles-pink) 33.333%, var(--max-sparkles-blue) 50%, var(--max-sparkles-purple) 66.667%, var(--max-sparkles-pink) 83.333%, var(--max-sparkles-blue) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--max-content-text-size: 14px;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.assistant-offline{display:grid;justify-items:center;gap:calc(var(--max-header-content-size) / 2);max-width:calc(var(--max-header-action-size) * 10);margin-inline:auto;padding-block:var(--max-header-sparkles-size);text-align:center}.assistant-offline p{margin:0;color:var(--max-muted);line-height:1.6}.assistant-offline p-button{margin-top:calc(var(--max-header-content-size) / 2)}.assistant-offline-art{width:calc(var(--max-header-action-size) * 5);max-width:100%;height:auto;overflow:visible}.assistant-offline-art path{stroke:var(--max-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;fill:none}.assistant-offline-art .offline-shadow{fill:var(--max-border);opacity:.35}.assistant-offline-art .offline-cloud-body{fill:var(--max-surface);stroke:var(--max-border)}.assistant-offline-art .offline-plug{fill:var(--max-surface-soft)}.assistant-offline-art .offline-disconnected path{stroke:var(--max-warning)}.assistant-offline-art .offline-cloud{animation:max-offline-float 4s ease-in-out infinite}.assistant-offline-art .offline-plug-left{animation:max-offline-left 4s ease-in-out infinite}.assistant-offline-art .offline-plug-right{animation:max-offline-right 4s ease-in-out infinite}.assistant-offline-art .offline-disconnected{animation:max-offline-signal 4s ease-in-out infinite}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-update{display:grid;grid-template-columns:var(--max-header-content-size) minmax(0,1fr);gap:9px;align-items:center;margin:0;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-update.active>span:last-child{background:var(--max-sparkles-gradient);width:fit-content;background-size:200% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-sparkles{position:relative;width:var(--max-header-content-size);height:var(--max-header-content-size)}.assistant-processing-star{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transform-origin:47.5% 50%;animation:max-processing-orbit 6s linear infinite}.assistant-processing-star.main{clip-path:polygon(47% 16%,62% 40%,82% 50%,62% 61%,47% 82%,34% 61%,14% 50%,34% 40%);animation:none}.assistant-processing-star.upper{clip-path:inset(6% 7% 60% 61%)}.assistant-processing-star.lower{clip-path:polygon(22.5% 62%,37% 77%,22.5% 91%,7% 77%)}.assistant-processing-star.small{clip-path:inset(64% 22% 21% 65%)}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-people-section,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3,.assistant-people-section h3{color:var(--max-text);font-size:var(--max-content-text-size)}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}:host .capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-offline-float{0%,to{transform:translateY(0)}50%{transform:translateY(-3%)}}@keyframes max-offline-left{0%,to{transform:translate(0)}50%{transform:translate(-2%)}}@keyframes max-offline-right{0%,to{transform:translate(0)}50%{transform:translate(2%)}}@keyframes max-offline-signal{0%,to{opacity:1}50%{opacity:.4}}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:100% 0}to{background-position:0% 0}}@keyframes max-processing-orbit{to{transform:rotate(360deg)}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-offline-art g,.assistant-processing-update.active>span:last-child,.assistant-processing-star,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ChartModule }, { kind: "component", type: i3.UIChart, selector: "p-chart", inputs: ["type", "plugins", "width", "height", "responsive", "ariaLabel", "ariaLabelledBy", "data", "options"], outputs: ["onDataSelect"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i4.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i6.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i7.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: MaxAgentEntityOptionComponent, selector: "max-agent-entity-option", inputs: ["entity", "disabled", "availability", "icons"], outputs: ["selected"] }, { kind: "component", type: MaxAgentPersonComponent, selector: "max-agent-person", inputs: ["person"] }, { kind: "component", type: MaxAgentShiftCardComponent, selector: "max-agent-shift-card", inputs: ["shift", "variant", "icons"] }, { kind: "pipe", type: i9.DatePipe, name: "date" }, { kind: "pipe", type: MaxAssistantMarkdownPipe, name: "maxAssistantMarkdown" }] });
2316
2409
  }
2317
2410
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, decorators: [{
2318
2411
  type: Component,
@@ -2328,12 +2421,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2328
2421
  TooltipModule,
2329
2422
  MaxAssistantMarkdownPipe,
2330
2423
  MaxAgentEntityOptionComponent,
2424
+ MaxAgentPersonComponent,
2331
2425
  MaxAgentShiftCardComponent,
2332
- ], encapsulation: ViewEncapsulation.Emulated, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError && !message.isOffline && !message.isAccessUnavailable\"\n [class.streaming]=\"message.isStreaming\"\n [attr.aria-live]=\"message.isStreaming ? 'polite' : null\"\n [attr.aria-busy]=\"message.isStreaming || null\"\n [attr.role]=\"message.isStreaming ? 'status' : null\"\n >\n @if(message.isAccessUnavailable) {\n <section class=\"assistant-offline assistant-access-unavailable\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.accessUnavailableTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"52\" ry=\"6\" />\n <path class=\"offline-cloud-body\" d=\"M100 16 151 36v39c0 31-24 49-51 61-27-12-51-30-51-61V36Z\" />\n <path d=\"M84 73V60a16 16 0 0 1 32 0v13\" />\n <path class=\"offline-plug\" d=\"M77 73h46v37H77Z\" />\n <path d=\"M100 86v11\" />\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isOffline) {\n <section class=\"assistant-offline\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.offlineTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"61\" ry=\"6\" />\n <g class=\"offline-cloud\">\n <path class=\"offline-cloud-body\" d=\"M61 86a23 23 0 0 1-3-46 32 32 0 0 1 61-9 27 27 0 0 1 20 55Z\" />\n <path class=\"offline-face\" d=\"M80 58q5 4 10 0m18 0q5 4 10 0M95 72h9\" />\n </g>\n <g class=\"offline-plug-left\">\n <path class=\"offline-cable\" d=\"M25 98v7q0 11 11 11h20\" />\n <path class=\"offline-plug\" d=\"M56 107h15v18H56q-5 0-5-5v-8q0-5 5-5Z\" />\n <path class=\"offline-cable\" d=\"M71 111h8m-8 10h8\" />\n </g>\n <g class=\"offline-plug-right\">\n <path class=\"offline-cable\" d=\"M174 98v7q0 11-11 11h-20\" />\n <path class=\"offline-plug\" d=\"M143 107h-15v18h15q5 0 5-5v-8q0-5-5-5Z\" />\n <path class=\"offline-cable\" d=\"M132 113v6\" />\n </g>\n <g class=\"offline-disconnected\" aria-hidden=\"true\">\n <path d=\"m101 105-5 22m-9-23-3-5m29 5 3-5\" />\n </g>\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isStreaming && !message.displayResponse && !message.cards?.length) {\n <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @if(!message.streamingContent) {\n <p class=\"assistant-processing-update active\">\n <span class=\"assistant-processing-sparkles\" aria-hidden=\"true\">\n @for (star of ['main', 'upper', 'lower', 'small']; track star) {\n <img\n class=\"assistant-processing-star {{ star }}\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n >\n }\n </span>\n <span>{{ message.content }}</span>\n </p>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n <div class=\"assistant-card-metrics\">\n @for(metric of card.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'mediumTime' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n <h3>{{ group.title }}</h3>\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"definition\"\n ></max-agent-shift-card>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation, chartCanvas)\"\n ></button>\n </header>\n <div\n #chartCanvas\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel\"\n icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"\n ></button>\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th>SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th>{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th>Actions</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td>{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td>{{ row[column.field] }}</td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending()\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination; as pagination) {\n <footer class=\"assistant-table-pagination\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </footer>\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming && !message.isOffline && !message.isAccessUnavailable) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px 10px;border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:wrap;gap:6px;min-width:150px}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-blue: var(--assistant-sparkles-blue, #2563eb);--max-sparkles-purple: var(--assistant-sparkles-purple, #8b5cf6);--max-sparkles-pink: var(--assistant-sparkles-pink, #ec4899);--max-sparkles-gradient: linear-gradient( 90deg, var(--max-sparkles-blue) 0%, var(--max-sparkles-purple) 16.667%, var(--max-sparkles-pink) 33.333%, var(--max-sparkles-blue) 50%, var(--max-sparkles-purple) 66.667%, var(--max-sparkles-pink) 83.333%, var(--max-sparkles-blue) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.assistant-offline{display:grid;justify-items:center;gap:calc(var(--max-header-content-size) / 2);max-width:calc(var(--max-header-action-size) * 10);margin-inline:auto;padding-block:var(--max-header-sparkles-size);text-align:center}.assistant-offline p{margin:0;color:var(--max-muted);line-height:1.6}.assistant-offline p-button{margin-top:calc(var(--max-header-content-size) / 2)}.assistant-offline-art{width:calc(var(--max-header-action-size) * 5);max-width:100%;height:auto;overflow:visible}.assistant-offline-art path{stroke:var(--max-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;fill:none}.assistant-offline-art .offline-shadow{fill:var(--max-border);opacity:.35}.assistant-offline-art .offline-cloud-body{fill:var(--max-surface);stroke:var(--max-border)}.assistant-offline-art .offline-plug{fill:var(--max-surface-soft)}.assistant-offline-art .offline-disconnected path{stroke:var(--max-warning)}.assistant-offline-art .offline-cloud{animation:max-offline-float 4s ease-in-out infinite}.assistant-offline-art .offline-plug-left{animation:max-offline-left 4s ease-in-out infinite}.assistant-offline-art .offline-plug-right{animation:max-offline-right 4s ease-in-out infinite}.assistant-offline-art .offline-disconnected{animation:max-offline-signal 4s ease-in-out infinite}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-update{display:grid;grid-template-columns:var(--max-header-content-size) minmax(0,1fr);gap:9px;align-items:center;margin:0;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-update.active>span:last-child{background:var(--max-sparkles-gradient);width:fit-content;background-size:200% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-sparkles{position:relative;width:var(--max-header-content-size);height:var(--max-header-content-size)}.assistant-processing-star{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transform-origin:47.5% 50%;animation:max-processing-orbit 6s linear infinite}.assistant-processing-star.main{clip-path:polygon(47% 16%,62% 40%,82% 50%,62% 61%,47% 82%,34% 61%,14% 50%,34% 40%);animation:none}.assistant-processing-star.upper{clip-path:inset(6% 7% 60% 61%)}.assistant-processing-star.lower{clip-path:polygon(22.5% 62%,37% 77%,22.5% 91%,7% 77%)}.assistant-processing-star.small{clip-path:inset(64% 22% 21% 65%)}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3{color:var(--max-text);font-size:14px}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-offline-float{0%,to{transform:translateY(0)}50%{transform:translateY(-3%)}}@keyframes max-offline-left{0%,to{transform:translate(0)}50%{transform:translate(-2%)}}@keyframes max-offline-right{0%,to{transform:translate(0)}50%{transform:translate(2%)}}@keyframes max-offline-signal{0%,to{opacity:1}50%{opacity:.4}}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:100% 0}to{background-position:0% 0}}@keyframes max-processing-orbit{to{transform:rotate(360deg)}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-offline-art g,.assistant-processing-update.active>span:last-child,.assistant-processing-star,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"] }]
2333
- }], ctorParameters: () => [{ type: MaxAssistantService }, { type: MaxAssistantExportService }, { type: MaxAssistantFeedbackService }, { type: MaxAssistantSupportService }, { type: i0.DestroyRef }, { type: undefined, decorators: [{
2334
- type: Inject,
2335
- args: [MAX_ASSISTANT_CONFIG]
2336
- }] }], propDecorators: { messagesViewport: [{
2426
+ ], encapsulation: ViewEncapsulation.Emulated, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError && !message.isOffline && !message.isAccessUnavailable\"\n [class.streaming]=\"message.isStreaming\"\n [attr.aria-live]=\"message.isStreaming ? 'polite' : null\"\n [attr.aria-busy]=\"message.isStreaming || null\"\n [attr.role]=\"message.isStreaming ? 'status' : null\"\n >\n @if(message.isAccessUnavailable) {\n <section class=\"assistant-offline assistant-access-unavailable\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.accessUnavailableTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"52\" ry=\"6\" />\n <path class=\"offline-cloud-body\" d=\"M100 16 151 36v39c0 31-24 49-51 61-27-12-51-30-51-61V36Z\" />\n <path d=\"M84 73V60a16 16 0 0 1 32 0v13\" />\n <path class=\"offline-plug\" d=\"M77 73h46v37H77Z\" />\n <path d=\"M100 86v11\" />\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isOffline) {\n <section class=\"assistant-offline\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.offlineTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"61\" ry=\"6\" />\n <g class=\"offline-cloud\">\n <path class=\"offline-cloud-body\" d=\"M61 86a23 23 0 0 1-3-46 32 32 0 0 1 61-9 27 27 0 0 1 20 55Z\" />\n <path class=\"offline-face\" d=\"M80 58q5 4 10 0m18 0q5 4 10 0M95 72h9\" />\n </g>\n <g class=\"offline-plug-left\">\n <path class=\"offline-cable\" d=\"M25 98v7q0 11 11 11h20\" />\n <path class=\"offline-plug\" d=\"M56 107h15v18H56q-5 0-5-5v-8q0-5 5-5Z\" />\n <path class=\"offline-cable\" d=\"M71 111h8m-8 10h8\" />\n </g>\n <g class=\"offline-plug-right\">\n <path class=\"offline-cable\" d=\"M174 98v7q0 11-11 11h-20\" />\n <path class=\"offline-plug\" d=\"M143 107h-15v18h15q5 0 5-5v-8q0-5-5-5Z\" />\n <path class=\"offline-cable\" d=\"M132 113v6\" />\n </g>\n <g class=\"offline-disconnected\" aria-hidden=\"true\">\n <path d=\"m101 105-5 22m-9-23-3-5m29 5 3-5\" />\n </g>\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isStreaming && !message.displayResponse && !message.cards?.length) {\n <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @if(!message.streamingContent) {\n <p class=\"assistant-processing-update active\">\n <span class=\"assistant-processing-sparkles\" aria-hidden=\"true\">\n @for (star of ['main', 'upper', 'lower', 'small']; track star) {\n <img\n class=\"assistant-processing-star {{ star }}\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n >\n }\n </span>\n <span>{{ message.content }}</span>\n </p>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n @let displayedCard = personCard(card);\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n @if(displayedCard.person; as person) {\n <max-agent-person [person]=\"person\"></max-agent-person>\n }\n <div class=\"assistant-card-metrics\">\n @for(metric of displayedCard.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'd MMM yyyy, h:mm a' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.availablePeople?.length) {\n <section class=\"assistant-people-section\" aria-label=\"Available people\">\n <h3>Available people</h3>\n <div class=\"entity-options\">\n @for(person of responseDetails.availablePeople; track person.id) {\n <max-agent-entity-option [entity]=\"person\" [availability]=\"person\" [icons]=\"entityIcons\"></max-agent-entity-option>\n }\n </div>\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n @if(group.variant !== 'assignment') { <h3>{{ group.title }}</h3> }\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n @if(shift.selection; as selection) {\n <button pButton type=\"button\" [text]=\"true\"\n class=\"assistant-shift-selection\"\n [attr.aria-label]=\"selection.label\"\n [disabled]=\"isSending()\"\n (click)=\"useSuggestion(selection)\">\n <max-agent-shift-card [shift]=\"shift\" [variant]=\"group.variant || 'rota'\" [icons]=\"entityIcons\"></max-agent-shift-card>\n </button>\n } @else {\n <max-agent-shift-card\n [shift]=\"shift\"\n [variant]=\"group.variant || 'definition'\"\n ></max-agent-shift-card>\n }\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation, chartCanvas)\"\n ></button>\n </header>\n <div\n #chartCanvas\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n @if(table.bulkActions?.length) {\n <div class=\"flex gap-2 flex-wrap justify-content-end ml-auto\">\n @for(action of table.bulkActions; track action.label) {\n <p-button [label]=\"action.label\" [severity]=\"action.tone || 'secondary'\" size=\"small\"\n [outlined]=\"action.outlined ?? action.tone === 'danger'\" [disabled]=\"isSending() || action.disabled === true\"\n (onClick)=\"useTableAction(action)\"></p-button>\n }\n </div>\n }\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th class=\"assistant-table-serial\">SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th [class.w-full]=\"column.kind === 'person' && !!table.actions?.length\"\n [class.white-space-nowrap]=\"!!table.actions?.length && column.kind !== 'person'\">{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th class=\"w-1 white-space-nowrap\">{{ table.actionsHeader ?? 'Actions' }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td class=\"assistant-table-serial\">{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td [class.white-space-nowrap]=\"!!table.actions?.length && column.kind !== 'person'\">\n @if(column.kind === 'person' && table.people?.[rowIndex]; as person) {\n <max-agent-person [person]=\"person\"></max-agent-person>\n } @else if(column.secondaryField) {\n <div class=\"white-space-nowrap\">{{ row[column.field] }}</div>\n @if(row[column.secondaryField]) {\n <div class=\"white-space-nowrap\">{{ row[column.secondaryField] }}</div>\n }\n } @else { {{ row[column.field] }} }\n </td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.outlined ?? action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending() || action.disabled === true\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination || (!table.actions?.length && !table.bulkActions?.length)) {\n <footer class=\"assistant-table-pagination flex-nowrap\">\n @if(table.pagination; as pagination) {\n <div class=\"flex flex-1 align-items-center flex-wrap gap-2\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </div>\n }\n @if(!table.actions?.length && !table.bulkActions?.length) {\n <button pButton type=\"button\" size=\"small\" severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel ml-auto flex-shrink-0\" icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"></button>\n }\n </footer>\n }\n @if(table.pagination) {\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming && !message.isOffline && !message.isAccessUnavailable) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3,.assistant-people-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{--max-table-cell-inline-padding: 10px;--max-table-serial-width: calc(6ch + 2 * var(--max-table-cell-inline-padding));overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px var(--max-table-cell-inline-padding);border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap .assistant-table-serial{box-sizing:border-box;width:var(--max-table-serial-width);min-width:var(--max-table-serial-width);max-width:var(--max-table-serial-width);white-space:nowrap;font-variant-numeric:tabular-nums}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:nowrap;gap:6px;width:max-content}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}:host .assistant-shift-selection{display:block;padding:0;width:100%;height:auto;min-width:0;text-align:start}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-blue: var(--assistant-sparkles-blue, #2563eb);--max-sparkles-purple: var(--assistant-sparkles-purple, #8b5cf6);--max-sparkles-pink: var(--assistant-sparkles-pink, #ec4899);--max-sparkles-gradient: linear-gradient( 90deg, var(--max-sparkles-blue) 0%, var(--max-sparkles-purple) 16.667%, var(--max-sparkles-pink) 33.333%, var(--max-sparkles-blue) 50%, var(--max-sparkles-purple) 66.667%, var(--max-sparkles-pink) 83.333%, var(--max-sparkles-blue) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--max-content-text-size: 14px;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.assistant-offline{display:grid;justify-items:center;gap:calc(var(--max-header-content-size) / 2);max-width:calc(var(--max-header-action-size) * 10);margin-inline:auto;padding-block:var(--max-header-sparkles-size);text-align:center}.assistant-offline p{margin:0;color:var(--max-muted);line-height:1.6}.assistant-offline p-button{margin-top:calc(var(--max-header-content-size) / 2)}.assistant-offline-art{width:calc(var(--max-header-action-size) * 5);max-width:100%;height:auto;overflow:visible}.assistant-offline-art path{stroke:var(--max-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;fill:none}.assistant-offline-art .offline-shadow{fill:var(--max-border);opacity:.35}.assistant-offline-art .offline-cloud-body{fill:var(--max-surface);stroke:var(--max-border)}.assistant-offline-art .offline-plug{fill:var(--max-surface-soft)}.assistant-offline-art .offline-disconnected path{stroke:var(--max-warning)}.assistant-offline-art .offline-cloud{animation:max-offline-float 4s ease-in-out infinite}.assistant-offline-art .offline-plug-left{animation:max-offline-left 4s ease-in-out infinite}.assistant-offline-art .offline-plug-right{animation:max-offline-right 4s ease-in-out infinite}.assistant-offline-art .offline-disconnected{animation:max-offline-signal 4s ease-in-out infinite}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-update{display:grid;grid-template-columns:var(--max-header-content-size) minmax(0,1fr);gap:9px;align-items:center;margin:0;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-update.active>span:last-child{background:var(--max-sparkles-gradient);width:fit-content;background-size:200% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-sparkles{position:relative;width:var(--max-header-content-size);height:var(--max-header-content-size)}.assistant-processing-star{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transform-origin:47.5% 50%;animation:max-processing-orbit 6s linear infinite}.assistant-processing-star.main{clip-path:polygon(47% 16%,62% 40%,82% 50%,62% 61%,47% 82%,34% 61%,14% 50%,34% 40%);animation:none}.assistant-processing-star.upper{clip-path:inset(6% 7% 60% 61%)}.assistant-processing-star.lower{clip-path:polygon(22.5% 62%,37% 77%,22.5% 91%,7% 77%)}.assistant-processing-star.small{clip-path:inset(64% 22% 21% 65%)}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-people-section,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3,.assistant-people-section h3{color:var(--max-text);font-size:var(--max-content-text-size)}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}:host .capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-offline-float{0%,to{transform:translateY(0)}50%{transform:translateY(-3%)}}@keyframes max-offline-left{0%,to{transform:translate(0)}50%{transform:translate(-2%)}}@keyframes max-offline-right{0%,to{transform:translate(0)}50%{transform:translate(2%)}}@keyframes max-offline-signal{0%,to{opacity:1}50%{opacity:.4}}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:100% 0}to{background-position:0% 0}}@keyframes max-processing-orbit{to{transform:rotate(360deg)}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-offline-art g,.assistant-processing-update.active>span:last-child,.assistant-processing-star,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"] }]
2427
+ }], propDecorators: { messagesViewport: [{
2337
2428
  type: ViewChild,
2338
2429
  args: ['messagesViewport']
2339
2430
  }], composerInput: [{
@@ -2347,6 +2438,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2347
2438
  args: ['feedbackInput']
2348
2439
  }], app: [{
2349
2440
  type: Input
2441
+ }], entityIcons: [{
2442
+ type: Input
2350
2443
  }], assistantApiUrl: [{
2351
2444
  type: Input
2352
2445
  }], user: [{
@@ -2377,5 +2470,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2377
2470
  * Generated bundle index. Do not edit.
2378
2471
  */
2379
2472
 
2380
- export { MAX_ASSISTANT_CONFIG, MaxAgentEntityOptionComponent, MaxAgentShiftCardComponent, MaxAssistantComponent, MaxAssistantFeedbackService, MaxAssistantService, MaxAssistantSupportService };
2473
+ export { MAX_ASSISTANT_CONFIG, MaxAgentEntityOptionComponent, MaxAgentPersonComponent, MaxAgentShiftCardComponent, MaxAssistantComponent, MaxAssistantFeedbackService, MaxAssistantService, MaxAssistantSupportService };
2381
2474
  //# sourceMappingURL=max-agent-ui.mjs.map