max-agent-ui 0.0.19 → 0.0.21

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,25 +1,25 @@
1
- import * as i10 from '@angular/common';
1
+ import * as i11 from '@angular/common';
2
2
  import { 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, Inject, Optional, Injectable, EventEmitter, signal, isDevMode, HostListener, Output, ViewChild, ViewEncapsulation } from '@angular/core';
6
+ import { InjectionToken, Pipe, Input, Component, isDevMode, Inject, Optional, Injectable, EventEmitter, signal, HostListener, Output, ViewChild, ViewEncapsulation } from '@angular/core';
7
7
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
- import * as i3 from '@angular/forms';
8
+ import * as i4 from '@angular/forms';
9
9
  import { FormsModule } from '@angular/forms';
10
- import * as i4 from 'primeng/button';
10
+ import * as i5 from 'primeng/button';
11
11
  import { ButtonModule } from 'primeng/button';
12
- import * as i5 from 'primeng/multiselect';
12
+ import * as i6 from 'primeng/multiselect';
13
13
  import { MultiSelectModule } from 'primeng/multiselect';
14
- import * as i6 from 'primeng/select';
14
+ import * as i7 from 'primeng/select';
15
15
  import { SelectModule } from 'primeng/select';
16
- import * as i7 from 'primeng/tag';
16
+ import * as i8 from 'primeng/tag';
17
17
  import { TagModule } from 'primeng/tag';
18
- import * as i8 from 'primeng/textarea';
18
+ import * as i9 from 'primeng/textarea';
19
19
  import { TextareaModule } from 'primeng/textarea';
20
- import * as i9 from 'primeng/tooltip';
20
+ import * as i10 from 'primeng/tooltip';
21
21
  import { TooltipModule } from 'primeng/tooltip';
22
- import { throwError, Observable, of, switchMap } from 'rxjs';
22
+ import { throwError, Observable, of, delay, switchMap } from 'rxjs';
23
23
  import { marked } from 'marked';
24
24
 
25
25
  const INITIAL_MESSAGE = 'Hi! 👋';
@@ -142,7 +142,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
142
142
  type: Input
143
143
  }] } });
144
144
 
145
- const DEFAULT_ASSISTANT_CHAT_URL = '/agent-api/v1/chat';
145
+ const ASSISTANT_CHAT_ENDPOINTS = {
146
+ development: '/agent-api/v1/chat',
147
+ production: 'https://agent.maxtime.cloud/v1/chat'
148
+ };
149
+ function getDefaultAssistantChatUrl(developmentMode = isDevMode()) {
150
+ return developmentMode
151
+ ? ASSISTANT_CHAT_ENDPOINTS.development
152
+ : ASSISTANT_CHAT_ENDPOINTS.production;
153
+ }
154
+
146
155
  const DEFAULT_APP = 'cortex';
147
156
  const DEFAULT_TIMEZONE = 'UTC';
148
157
  class MaxAssistantService {
@@ -263,7 +272,7 @@ class MaxAssistantService {
263
272
  });
264
273
  }
265
274
  getChatUrl(config) {
266
- return config.assistantApiUrl?.trim() || DEFAULT_ASSISTANT_CHAT_URL;
275
+ return config.assistantApiUrl?.trim() || getDefaultAssistantChatUrl();
267
276
  }
268
277
  getApp(config) {
269
278
  return config.app || DEFAULT_APP;
@@ -332,6 +341,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
332
341
  type: Optional
333
342
  }] }] });
334
343
 
344
+ let mockFeedbackSequence = 1000;
345
+ class MaxAssistantFeedbackService {
346
+ endpoint = '/agent-api/v1/feedback';
347
+ method = 'POST';
348
+ submitFeedback(_feedback) {
349
+ mockFeedbackSequence += 1;
350
+ return of({
351
+ success: true,
352
+ feedbackReference: `MAX-FEEDBACK-${mockFeedbackSequence}`,
353
+ message: 'Thank you. Your feedback has been shared with the Maxtime development team.',
354
+ submittedAt: new Date().toISOString()
355
+ }).pipe(delay(350));
356
+ }
357
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
358
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, providedIn: 'root' });
359
+ }
360
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantFeedbackService, decorators: [{
361
+ type: Injectable,
362
+ args: [{ providedIn: 'root' }]
363
+ }] });
364
+
335
365
  const MOCK_SUPPORT_TAGS = [
336
366
  { value: 'scheduling', label: 'Scheduling & Rotas', icon: 'pi pi-calendar', severity: 'info' },
337
367
  { value: 'timesheets', label: 'Timesheets', icon: 'pi pi-clock', severity: 'secondary' },
@@ -377,6 +407,8 @@ const ASSISTANT_UI_COPY = {
377
407
  clearTooltip: 'Start a new session',
378
408
  closeLabel: 'Close AI assistant',
379
409
  closeTooltip: 'Close AI assistant',
410
+ feedbackLabel: 'Provide feedback on this response',
411
+ feedbackTooltip: 'Provide feedback',
380
412
  placeholder: 'Ask Max',
381
413
  startingMessage: 'Understanding your request…',
382
414
  errorMessage: 'Maxtime virtual assistant could not be reached. Please try again.'
@@ -395,12 +427,14 @@ const ASSISTANT_SEARCH_RESULT_ICONS = {
395
427
  };
396
428
  class MaxAssistantComponent {
397
429
  assistantService;
430
+ feedbackService;
398
431
  supportService;
399
432
  destroyRef;
400
433
  defaultConfig;
401
434
  messagesViewport;
402
435
  composerInput;
403
436
  supportQueryInput;
437
+ feedbackInput;
404
438
  app;
405
439
  assistantApiUrl;
406
440
  user;
@@ -415,6 +449,19 @@ class MaxAssistantComponent {
415
449
  expandedDetailMessageIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedDetailMessageIds" }] : []));
416
450
  expandedTraceStepKeys = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedTraceStepKeys" }] : []));
417
451
  developerDetailsEnabled = isDevMode();
452
+ feedbackVisible = signal(false, ...(ngDevMode ? [{ debugName: "feedbackVisible" }] : []));
453
+ feedbackSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "feedbackSubmitting" }] : []));
454
+ feedbackResult = signal(undefined, ...(ngDevMode ? [{ debugName: "feedbackResult" }] : []));
455
+ feedbackError = signal(undefined, ...(ngDevMode ? [{ debugName: "feedbackError" }] : []));
456
+ feedbackCategoryOptions = [
457
+ { label: 'Incorrect answer', value: 'incorrect' },
458
+ { label: 'Incomplete answer', value: 'incomplete' },
459
+ { label: 'Hard to understand', value: 'unclear' },
460
+ { label: 'Unexpected behaviour', value: 'unexpected' },
461
+ { label: 'Suggestion', value: 'suggestion' },
462
+ { label: 'Other', value: 'other' }
463
+ ];
464
+ feedbackForm = this.createFeedbackForm();
418
465
  supportTicketVisible = signal(false, ...(ngDevMode ? [{ debugName: "supportTicketVisible" }] : []));
419
466
  supportTicketSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "supportTicketSubmitting" }] : []));
420
467
  supportTagsLoading = signal(false, ...(ngDevMode ? [{ debugName: "supportTagsLoading" }] : []));
@@ -428,8 +475,9 @@ class MaxAssistantComponent {
428
475
  { label: 'Critical', value: 'critical', severity: 'danger' }
429
476
  ];
430
477
  supportTicketForm = this.createSupportTicketForm();
431
- constructor(assistantService, supportService, destroyRef, defaultConfig) {
478
+ constructor(assistantService, feedbackService, supportService, destroyRef, defaultConfig) {
432
479
  this.assistantService = assistantService;
480
+ this.feedbackService = feedbackService;
433
481
  this.supportService = supportService;
434
482
  this.destroyRef = destroyRef;
435
483
  this.defaultConfig = defaultConfig;
@@ -456,6 +504,10 @@ class MaxAssistantComponent {
456
504
  return this.messages().length === 1 && this.isWelcomeMessage(message);
457
505
  }
458
506
  onDocumentEscape() {
507
+ if (this.feedbackVisible()) {
508
+ this.closeFeedback();
509
+ return;
510
+ }
459
511
  if (this.supportTicketVisible()) {
460
512
  this.closeSupportTicket();
461
513
  return;
@@ -466,6 +518,7 @@ class MaxAssistantComponent {
466
518
  }
467
519
  }
468
520
  clearChatSession() {
521
+ this.closeFeedback(false);
469
522
  this.closeSupportTicket(false);
470
523
  this.input.set('');
471
524
  this.isSending.set(false);
@@ -510,6 +563,25 @@ class MaxAssistantComponent {
510
563
  suggestionLabel(suggestion) {
511
564
  return typeof suggestion === 'string' ? suggestion : suggestion.label;
512
565
  }
566
+ hasCapabilitySuggestions(suggestions = []) {
567
+ return suggestions.some(suggestion => typeof suggestion !== 'string' &&
568
+ suggestion.presentation === 'capability_card');
569
+ }
570
+ capabilitySuggestionGroups(suggestions = []) {
571
+ const groups = new Map();
572
+ for (const suggestion of suggestions) {
573
+ if (typeof suggestion === 'string' ||
574
+ suggestion.presentation !== 'capability_card') {
575
+ continue;
576
+ }
577
+ const section = suggestion.section?.trim() || 'More';
578
+ groups.set(section, [...(groups.get(section) ?? []), suggestion]);
579
+ }
580
+ return [...groups.entries()].map(([section, options]) => ({
581
+ section,
582
+ options
583
+ }));
584
+ }
513
585
  useSuggestion(suggestion) {
514
586
  if (typeof suggestion === 'string' || !suggestion.structuredAction) {
515
587
  this.sendMessage(typeof suggestion === 'string' ? suggestion : suggestion.message);
@@ -550,6 +622,7 @@ class MaxAssistantComponent {
550
622
  return this.messages().some(message => message.role === 'user');
551
623
  }
552
624
  openSupportTicket() {
625
+ this.closeFeedback(false);
553
626
  const user = this.getConfiguredUser();
554
627
  this.supportTicketForm = this.createSupportTicketForm(user);
555
628
  this.supportTicketResult.set(undefined);
@@ -618,6 +691,65 @@ class MaxAssistantComponent {
618
691
  }
619
692
  });
620
693
  }
694
+ openFeedback(responseMessage) {
695
+ this.closeSupportTicket(false);
696
+ this.feedbackForm = this.createFeedbackForm(this.getConfiguredUser(), responseMessage);
697
+ this.feedbackResult.set(undefined);
698
+ this.feedbackError.set(undefined);
699
+ this.feedbackVisible.set(true);
700
+ setTimeout(() => this.feedbackInput?.nativeElement.focus());
701
+ }
702
+ closeFeedback(restoreComposerFocus = true) {
703
+ this.feedbackVisible.set(false);
704
+ this.feedbackSubmitting.set(false);
705
+ this.feedbackResult.set(undefined);
706
+ this.feedbackError.set(undefined);
707
+ if (restoreComposerFocus) {
708
+ setTimeout(() => this.focusComposer());
709
+ }
710
+ }
711
+ canSubmitFeedback() {
712
+ return Boolean(this.feedbackForm.name.trim() &&
713
+ this.feedbackForm.email.trim() &&
714
+ this.feedbackForm.category &&
715
+ this.feedbackForm.query.trim() &&
716
+ this.feedbackForm.feedback.trim() &&
717
+ !this.feedbackSubmitting());
718
+ }
719
+ submitFeedback() {
720
+ if (!this.canSubmitFeedback()) {
721
+ return;
722
+ }
723
+ this.feedbackSubmitting.set(true);
724
+ this.feedbackError.set(undefined);
725
+ this.feedbackService
726
+ .submitFeedback({
727
+ name: this.feedbackForm.name.trim(),
728
+ email: this.feedbackForm.email.trim(),
729
+ ...(this.feedbackForm.phone.trim()
730
+ ? { phone: this.feedbackForm.phone.trim() }
731
+ : {}),
732
+ category: this.feedbackForm.category,
733
+ query: this.feedbackForm.query.trim(),
734
+ ...(this.feedbackForm.assistantResponse.trim()
735
+ ? { assistantResponse: this.feedbackForm.assistantResponse.trim() }
736
+ : {}),
737
+ feedback: this.feedbackForm.feedback.trim(),
738
+ app: this.app ?? this.defaultConfig.app ?? 'nemesys',
739
+ ...(this.conversationId() ? { conversationId: this.conversationId() } : {})
740
+ })
741
+ .pipe(takeUntilDestroyed(this.destroyRef))
742
+ .subscribe({
743
+ next: result => {
744
+ this.feedbackResult.set(result);
745
+ this.feedbackSubmitting.set(false);
746
+ },
747
+ error: () => {
748
+ this.feedbackSubmitting.set(false);
749
+ this.feedbackError.set('Your feedback could not be submitted. Please check the details and try again.');
750
+ }
751
+ });
752
+ }
621
753
  searchResultIcon(type) {
622
754
  return ASSISTANT_SEARCH_RESULT_ICONS[type.trim().toUpperCase()]
623
755
  ?? ASSISTANT_SEARCH_RESULT_ICONS['DEFAULT'];
@@ -966,6 +1098,41 @@ class MaxAssistantComponent {
966
1098
  tags: []
967
1099
  };
968
1100
  }
1101
+ createFeedbackForm(user, responseMessage) {
1102
+ const conversation = responseMessage
1103
+ ? this.getConversationPair(responseMessage)
1104
+ : { query: '', assistantResponse: '' };
1105
+ return {
1106
+ name: this.getUserText(user, [
1107
+ 'displayName',
1108
+ 'name',
1109
+ 'username',
1110
+ 'firstName',
1111
+ 'firstname'
1112
+ ]),
1113
+ email: this.getUserText(user, ['email', 'emailAddress']),
1114
+ phone: this.getUserText(user, ['phone', 'phoneNumber', 'mobile']),
1115
+ category: 'suggestion',
1116
+ query: conversation.query,
1117
+ assistantResponse: conversation.assistantResponse,
1118
+ feedback: ''
1119
+ };
1120
+ }
1121
+ getConversationPair(responseMessage) {
1122
+ const messages = this.messages();
1123
+ const responseIndex = messages.findIndex(message => message.id === responseMessage.id);
1124
+ let precedingUserIndex = -1;
1125
+ for (let index = responseIndex - 1; index >= 0; index -= 1) {
1126
+ if (messages[index]?.role === 'user') {
1127
+ precedingUserIndex = index;
1128
+ break;
1129
+ }
1130
+ }
1131
+ return {
1132
+ query: messages[precedingUserIndex]?.content ?? '',
1133
+ assistantResponse: responseMessage.content
1134
+ };
1135
+ }
969
1136
  getUserText(user, keys) {
970
1137
  const value = keys
971
1138
  .map(key => user?.[key])
@@ -1169,8 +1336,8 @@ class MaxAssistantComponent {
1169
1336
  }
1170
1337
  });
1171
1338
  }
1172
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, deps: [{ token: MaxAssistantService }, { token: MaxAssistantSupportService }, { token: i0.DestroyRef }, { token: MAX_ASSISTANT_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
1173
- 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" }, outputs: { hostAction: "hostAction", closeRequested: "closeRequested" }, host: { listeners: { "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 }], 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 <i class=\"max-assistant-sparkles far fa-sparkles\" aria-hidden=\"true\"></i>\n <div class=\"assistant-identity\">\n <h2 class=\"assistant-name\">{{ uiCopy.title }}</h2>\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 [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError\"\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.isStreaming) {\n <p class=\"streaming-progress\">{{ message.content }}</p>\n } @else if(message.displayResponse; as responseDetails) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\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 <strong>{{ card.title }}</strong>\n @if(card.subtitle) {\n <span>{{ 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\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span>{{ metric.label }}</span>\n <strong>{{ metric.value }}</strong>\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 <h3>{{ visualisation.title }}</h3>\n @if(visualisation.type === 'doughnut') {\n <div class=\"assistant-doughnut-layout\">\n <div\n class=\"assistant-doughnut\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n <svg viewBox=\"0 0 42 42\" aria-hidden=\"true\" focusable=\"false\">\n <circle\n class=\"assistant-doughnut-track\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n ></circle>\n @for(value of visualisation.values; track $index; let valueIndex = $index) {\n <circle\n class=\"assistant-doughnut-segment\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n pathLength=\"100\"\n [attr.stroke]=\"chartColor(visualisation, valueIndex)\"\n [attr.stroke-dasharray]=\"doughnutDashArray(visualisation, valueIndex)\"\n [attr.stroke-dashoffset]=\"doughnutDashOffset(visualisation, valueIndex)\"\n ></circle>\n }\n </svg>\n <span><strong>{{ chartTotal(visualisation) }}</strong>people</span>\n </div>\n <div class=\"assistant-chart-legend\">\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-chart-legend-item\">\n <i [style.background]=\"chartColor(visualisation, labelIndex)\"></i>\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n }\n </div>\n </div>\n } @else {\n <div\n class=\"assistant-bar-chart\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-bar-row\">\n <div class=\"assistant-bar-label\">\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n <div class=\"assistant-bar-track\" aria-hidden=\"true\">\n <i\n [style.width.%]=\"barWidth(visualisation, labelIndex)\"\n [style.background]=\"chartColor(visualisation, labelIndex)\"\n ></i>\n </div>\n </div>\n }\n </div>\n }\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index) {\n <section class=\"assistant-table-section\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\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 @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 </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 <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 Details' : 'Show Details' }}\n </button>\n\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 <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 <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 </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 <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 </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(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 <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\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\">\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]=\"supportSeverityOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [severity]=\"severity.severity\"\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 [severity]=\"severity.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\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 optionValue=\"value\"\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.value) {\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>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</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(--primary-color, #2563eb);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{white-space:pre-line}.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 #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff);box-shadow:0 8px 22px #0f172a0f}.assistant-card>header{display:grid;gap:2px;padding:11px 12px;border-bottom:1px solid #e2e8f0}.assistant-card>header strong{color:#0f172a;font-size:14px}.assistant-card>header span,.assistant-card>footer{color:#64748b;font-size:11px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.assistant-card-metric{display:grid;min-width:0;gap:3px;padding:11px 9px;border-right:1px solid #e2e8f0}.assistant-card-metric:last-child{border-right:0}.assistant-card-metric span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.assistant-card-metric strong{color:#1e293b;font-size:13px;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] strong{color:#047857}.assistant-card-metric[data-tone=warning] strong{color:#b45309}.assistant-card>footer{padding:8px 12px;border-top:1px solid #e2e8f0;background:#f8fafcb8}: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-doughnut-layout{display:grid;grid-template-columns:112px minmax(0,1fr);gap:14px;align-items:center}.assistant-doughnut{position:relative;display:grid;place-items:center;width:112px;aspect-ratio:1}.assistant-doughnut svg{width:100%;height:100%;transform:rotate(-90deg)}.assistant-doughnut circle{fill:none;stroke-width:6}.assistant-doughnut-track{stroke:#e2e8f0}.assistant-doughnut-segment{transition:stroke-dasharray .18s ease}.assistant-doughnut>span{position:absolute;display:grid;color:#64748b;font-size:9px;line-height:1.1;text-align:center}.assistant-doughnut>span strong{color:#0f172a;font-size:18px}.assistant-chart-legend{display:grid;gap:7px;min-width:0}.assistant-chart-legend-item{display:grid;grid-template-columns:9px minmax(0,1fr) auto;gap:7px;align-items:center;color:#475569;font-size:11px}.assistant-chart-legend-item i{width:9px;height:9px;border-radius:999px}.assistant-chart-legend-item strong,.assistant-bar-label strong{color:#0f172a;font-size:11px}.assistant-bar-chart,.assistant-bar-row{display:grid;gap:6px}.assistant-bar-chart{gap:11px}.assistant-bar-label{display:flex;gap:12px;align-items:baseline;justify-content:space-between;color:#475569;font-size:11px}.assistant-bar-track{height:9px;overflow:hidden;border-radius:999px;background:#e2e8f0}.assistant-bar-track i{display:block;height:100%;min-width:0;border-radius:var(--max-frame-radius, 0);transition:width .18s ease}.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}.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}.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,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{border-right:0;border-bottom:1px solid #e2e8f0}.assistant-card-metric:last-child{border-bottom: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-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-gradient: linear-gradient( 135deg, color-mix(in srgb, var(--max-accent) 58%, white) 0%, var(--max-accent) 46%, color-mix(in srgb, var(--max-accent) 55%, var(--max-accent-strong)) 72%, var(--max-accent-strong) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--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:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;font-size:var(--max-header-content-size);line-height:1;vertical-align:middle;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;filter:drop-shadow(0 2px 3px rgba(60,64,67,.18))}.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:20px;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;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;font:inherit;font-size:var(--max-header-content-size);font-weight:600;line-height:1}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.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:12px 18px;border:0;border-radius:22px 22px 6px;color:var(--max-text);background:color-mix(in srgb,var(--max-accent) 8%,var(--max-surface))}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.message.streaming{display:flex;gap:10px;align-items:center;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{width:16px;height:16px;flex:0 0 auto;border-radius:6px;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));content:\"\";animation:max-thinking 1.4s ease-in-out infinite alternate}.streaming-progress{color:var(--max-muted);font-size:14px;white-space:pre-line}.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)}.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{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}.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:14px}.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 h3,.assistant-doughnut>span strong,.assistant-chart-legend-item strong,.assistant-bar-label strong{color:var(--max-text)}.assistant-chart-legend-item,.assistant-bar-label,.assistant-doughnut>span{color:var(--max-muted)}.assistant-doughnut-track,.assistant-bar-track{stroke:var(--max-border);background:var(--max-border)}.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-top:16px;color:var(--max-accent);font-size:12px;text-decoration:none}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.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}.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]{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 .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{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.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));font-size:32px}.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}.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-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@media (prefers-reduced-motion: reduce){.message.streaming:before{animation:none}.suggestion-chip,.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{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}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.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: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i5.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: i6.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: i7.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i8.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i9.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: MaxAgentShiftCardComponent, selector: "max-agent-shift-card", inputs: ["shift", "variant"] }, { kind: "pipe", type: i10.DatePipe, name: "date" }, { kind: "pipe", type: MaxAssistantMarkdownPipe, name: "maxAssistantMarkdown" }] });
1339
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, deps: [{ token: MaxAssistantService }, { token: MaxAssistantFeedbackService }, { token: MaxAssistantSupportService }, { token: i0.DestroyRef }, { token: MAX_ASSISTANT_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
1340
+ 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" }, outputs: { hostAction: "hostAction", closeRequested: "closeRequested" }, host: { listeners: { "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 <i class=\"max-assistant-sparkles far fa-sparkles\" aria-hidden=\"true\"></i>\n <div class=\"assistant-identity\">\n <h2 class=\"assistant-name\">{{ uiCopy.title }}</h2>\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 [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError\"\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.isStreaming) {\n <p class=\"streaming-progress\">{{ message.content }}</p>\n } @else if(message.displayResponse; as responseDetails) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\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 <strong>{{ card.title }}</strong>\n @if(card.subtitle) {\n <span>{{ 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\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span>{{ metric.label }}</span>\n <strong>{{ metric.value }}</strong>\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 <h3>{{ visualisation.title }}</h3>\n @if(visualisation.type === 'doughnut') {\n <div class=\"assistant-doughnut-layout\">\n <div\n class=\"assistant-doughnut\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n <svg viewBox=\"0 0 42 42\" aria-hidden=\"true\" focusable=\"false\">\n <circle\n class=\"assistant-doughnut-track\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n ></circle>\n @for(value of visualisation.values; track $index; let valueIndex = $index) {\n <circle\n class=\"assistant-doughnut-segment\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n pathLength=\"100\"\n [attr.stroke]=\"chartColor(visualisation, valueIndex)\"\n [attr.stroke-dasharray]=\"doughnutDashArray(visualisation, valueIndex)\"\n [attr.stroke-dashoffset]=\"doughnutDashOffset(visualisation, valueIndex)\"\n ></circle>\n }\n </svg>\n <span><strong>{{ chartTotal(visualisation) }}</strong>people</span>\n </div>\n <div class=\"assistant-chart-legend\">\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-chart-legend-item\">\n <i [style.background]=\"chartColor(visualisation, labelIndex)\"></i>\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n }\n </div>\n </div>\n } @else {\n <div\n class=\"assistant-bar-chart\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-bar-row\">\n <div class=\"assistant-bar-label\">\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n <div class=\"assistant-bar-track\" aria-hidden=\"true\">\n <i\n [style.width.%]=\"barWidth(visualisation, labelIndex)\"\n [style.background]=\"chartColor(visualisation, labelIndex)\"\n ></i>\n </div>\n </div>\n }\n </div>\n }\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index) {\n <section class=\"assistant-table-section\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\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 @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 </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 <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 <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 </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 {\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) {\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(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 <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\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\">\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]=\"supportSeverityOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [severity]=\"severity.severity\"\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 [severity]=\"severity.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\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 optionValue=\"value\"\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.value) {\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>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>Feedback received</h3>\n <p>{{ result.message }}</p>\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.feedbackReference }}</strong>\n </div>\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>Name</span>\n <input\n type=\"text\"\n name=\"feedbackName\"\n autocomplete=\"name\"\n [value]=\"feedbackForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"feedbackEmail\"\n autocomplete=\"email\"\n [value]=\"feedbackForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"feedbackPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"feedbackForm.phone\"\n />\n </label>\n\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(!feedbackForm.name || !feedbackForm.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(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(--primary-color, #2563eb);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{white-space:pre-line}.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 #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff);box-shadow:0 8px 22px #0f172a0f}.assistant-card>header{display:grid;gap:2px;padding:11px 12px;border-bottom:1px solid #e2e8f0}.assistant-card>header strong{color:#0f172a;font-size:14px}.assistant-card>header span,.assistant-card>footer{color:#64748b;font-size:11px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.assistant-card-metric{display:grid;min-width:0;gap:3px;padding:11px 9px;border-right:1px solid #e2e8f0}.assistant-card-metric:last-child{border-right:0}.assistant-card-metric span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.assistant-card-metric strong{color:#1e293b;font-size:13px;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] strong{color:#047857}.assistant-card-metric[data-tone=warning] strong{color:#b45309}.assistant-card>footer{padding:8px 12px;border-top:1px solid #e2e8f0;background:#f8fafcb8}: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-doughnut-layout{display:grid;grid-template-columns:112px minmax(0,1fr);gap:14px;align-items:center}.assistant-doughnut{position:relative;display:grid;place-items:center;width:112px;aspect-ratio:1}.assistant-doughnut svg{width:100%;height:100%;transform:rotate(-90deg)}.assistant-doughnut circle{fill:none;stroke-width:6}.assistant-doughnut-track{stroke:#e2e8f0}.assistant-doughnut-segment{transition:stroke-dasharray .18s ease}.assistant-doughnut>span{position:absolute;display:grid;color:#64748b;font-size:9px;line-height:1.1;text-align:center}.assistant-doughnut>span strong{color:#0f172a;font-size:18px}.assistant-chart-legend{display:grid;gap:7px;min-width:0}.assistant-chart-legend-item{display:grid;grid-template-columns:9px minmax(0,1fr) auto;gap:7px;align-items:center;color:#475569;font-size:11px}.assistant-chart-legend-item i{width:9px;height:9px;border-radius:999px}.assistant-chart-legend-item strong,.assistant-bar-label strong{color:#0f172a;font-size:11px}.assistant-bar-chart,.assistant-bar-row{display:grid;gap:6px}.assistant-bar-chart{gap:11px}.assistant-bar-label{display:flex;gap:12px;align-items:baseline;justify-content:space-between;color:#475569;font-size:11px}.assistant-bar-track{height:9px;overflow:hidden;border-radius:999px;background:#e2e8f0}.assistant-bar-track i{display:block;height:100%;min-width:0;border-radius:var(--max-frame-radius, 0);transition:width .18s ease}.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}.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}.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,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{border-right:0;border-bottom:1px solid #e2e8f0}.assistant-card-metric:last-child{border-bottom: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-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-gradient: linear-gradient( 135deg, color-mix(in srgb, var(--max-accent) 58%, white) 0%, var(--max-accent) 46%, color-mix(in srgb, var(--max-accent) 55%, var(--max-accent-strong)) 72%, var(--max-accent-strong) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--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:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;font-size:var(--max-header-content-size);line-height:1;vertical-align:middle;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;filter:drop-shadow(0 2px 3px rgba(60,64,67,.18))}.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:20px;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;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;font:inherit;font-size:var(--max-header-content-size);font-weight:600;line-height:1}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.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:12px 18px;border:0;border-radius:22px 22px 6px;color:var(--max-text);background:color-mix(in srgb,var(--max-accent) 8%,var(--max-surface))}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.message.streaming{display:flex;gap:10px;align-items:center;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{width:16px;height:16px;flex:0 0 auto;border-radius:6px;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));content:\"\";animation:max-thinking 1.4s ease-in-out infinite alternate}.streaming-progress{color:var(--max-muted);font-size:14px;white-space:pre-line}.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)}.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}.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:14px}.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 h3,.assistant-doughnut>span strong,.assistant-chart-legend-item strong,.assistant-bar-label strong{color:var(--max-text)}.assistant-chart-legend-item,.assistant-bar-label,.assistant-doughnut>span{color:var(--max-muted)}.assistant-doughnut-track,.assistant-bar-track{stroke:var(--max-border);background:var(--max-border)}.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:none}.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}.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(--max-control-radius);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 .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{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.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));font-size:32px}.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}.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-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@media (prefers-reduced-motion: reduce){.message.streaming:before{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: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i5.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i6.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: i7.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: i8.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i9.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i10.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: MaxAgentShiftCardComponent, selector: "max-agent-shift-card", inputs: ["shift", "variant"] }, { kind: "pipe", type: i11.DatePipe, name: "date" }, { kind: "pipe", type: MaxAssistantMarkdownPipe, name: "maxAssistantMarkdown" }] });
1174
1341
  }
1175
1342
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, decorators: [{
1176
1343
  type: Component,
@@ -1185,8 +1352,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
1185
1352
  TooltipModule,
1186
1353
  MaxAssistantMarkdownPipe,
1187
1354
  MaxAgentShiftCardComponent
1188
- ], 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 <i class=\"max-assistant-sparkles far fa-sparkles\" aria-hidden=\"true\"></i>\n <div class=\"assistant-identity\">\n <h2 class=\"assistant-name\">{{ uiCopy.title }}</h2>\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 [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError\"\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.isStreaming) {\n <p class=\"streaming-progress\">{{ message.content }}</p>\n } @else if(message.displayResponse; as responseDetails) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\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 <strong>{{ card.title }}</strong>\n @if(card.subtitle) {\n <span>{{ 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\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span>{{ metric.label }}</span>\n <strong>{{ metric.value }}</strong>\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 <h3>{{ visualisation.title }}</h3>\n @if(visualisation.type === 'doughnut') {\n <div class=\"assistant-doughnut-layout\">\n <div\n class=\"assistant-doughnut\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n <svg viewBox=\"0 0 42 42\" aria-hidden=\"true\" focusable=\"false\">\n <circle\n class=\"assistant-doughnut-track\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n ></circle>\n @for(value of visualisation.values; track $index; let valueIndex = $index) {\n <circle\n class=\"assistant-doughnut-segment\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n pathLength=\"100\"\n [attr.stroke]=\"chartColor(visualisation, valueIndex)\"\n [attr.stroke-dasharray]=\"doughnutDashArray(visualisation, valueIndex)\"\n [attr.stroke-dashoffset]=\"doughnutDashOffset(visualisation, valueIndex)\"\n ></circle>\n }\n </svg>\n <span><strong>{{ chartTotal(visualisation) }}</strong>people</span>\n </div>\n <div class=\"assistant-chart-legend\">\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-chart-legend-item\">\n <i [style.background]=\"chartColor(visualisation, labelIndex)\"></i>\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n }\n </div>\n </div>\n } @else {\n <div\n class=\"assistant-bar-chart\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-bar-row\">\n <div class=\"assistant-bar-label\">\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n <div class=\"assistant-bar-track\" aria-hidden=\"true\">\n <i\n [style.width.%]=\"barWidth(visualisation, labelIndex)\"\n [style.background]=\"chartColor(visualisation, labelIndex)\"\n ></i>\n </div>\n </div>\n }\n </div>\n }\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index) {\n <section class=\"assistant-table-section\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\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 @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 </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 <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 Details' : 'Show Details' }}\n </button>\n\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 <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 <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 </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 <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 </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(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 <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\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\">\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]=\"supportSeverityOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [severity]=\"severity.severity\"\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 [severity]=\"severity.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\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 optionValue=\"value\"\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.value) {\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>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</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(--primary-color, #2563eb);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{white-space:pre-line}.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 #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff);box-shadow:0 8px 22px #0f172a0f}.assistant-card>header{display:grid;gap:2px;padding:11px 12px;border-bottom:1px solid #e2e8f0}.assistant-card>header strong{color:#0f172a;font-size:14px}.assistant-card>header span,.assistant-card>footer{color:#64748b;font-size:11px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.assistant-card-metric{display:grid;min-width:0;gap:3px;padding:11px 9px;border-right:1px solid #e2e8f0}.assistant-card-metric:last-child{border-right:0}.assistant-card-metric span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.assistant-card-metric strong{color:#1e293b;font-size:13px;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] strong{color:#047857}.assistant-card-metric[data-tone=warning] strong{color:#b45309}.assistant-card>footer{padding:8px 12px;border-top:1px solid #e2e8f0;background:#f8fafcb8}: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-doughnut-layout{display:grid;grid-template-columns:112px minmax(0,1fr);gap:14px;align-items:center}.assistant-doughnut{position:relative;display:grid;place-items:center;width:112px;aspect-ratio:1}.assistant-doughnut svg{width:100%;height:100%;transform:rotate(-90deg)}.assistant-doughnut circle{fill:none;stroke-width:6}.assistant-doughnut-track{stroke:#e2e8f0}.assistant-doughnut-segment{transition:stroke-dasharray .18s ease}.assistant-doughnut>span{position:absolute;display:grid;color:#64748b;font-size:9px;line-height:1.1;text-align:center}.assistant-doughnut>span strong{color:#0f172a;font-size:18px}.assistant-chart-legend{display:grid;gap:7px;min-width:0}.assistant-chart-legend-item{display:grid;grid-template-columns:9px minmax(0,1fr) auto;gap:7px;align-items:center;color:#475569;font-size:11px}.assistant-chart-legend-item i{width:9px;height:9px;border-radius:999px}.assistant-chart-legend-item strong,.assistant-bar-label strong{color:#0f172a;font-size:11px}.assistant-bar-chart,.assistant-bar-row{display:grid;gap:6px}.assistant-bar-chart{gap:11px}.assistant-bar-label{display:flex;gap:12px;align-items:baseline;justify-content:space-between;color:#475569;font-size:11px}.assistant-bar-track{height:9px;overflow:hidden;border-radius:999px;background:#e2e8f0}.assistant-bar-track i{display:block;height:100%;min-width:0;border-radius:var(--max-frame-radius, 0);transition:width .18s ease}.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}.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}.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,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{border-right:0;border-bottom:1px solid #e2e8f0}.assistant-card-metric:last-child{border-bottom: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-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-gradient: linear-gradient( 135deg, color-mix(in srgb, var(--max-accent) 58%, white) 0%, var(--max-accent) 46%, color-mix(in srgb, var(--max-accent) 55%, var(--max-accent-strong)) 72%, var(--max-accent-strong) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--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:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;font-size:var(--max-header-content-size);line-height:1;vertical-align:middle;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;filter:drop-shadow(0 2px 3px rgba(60,64,67,.18))}.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:20px;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;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;font:inherit;font-size:var(--max-header-content-size);font-weight:600;line-height:1}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.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:12px 18px;border:0;border-radius:22px 22px 6px;color:var(--max-text);background:color-mix(in srgb,var(--max-accent) 8%,var(--max-surface))}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.message.streaming{display:flex;gap:10px;align-items:center;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{width:16px;height:16px;flex:0 0 auto;border-radius:6px;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));content:\"\";animation:max-thinking 1.4s ease-in-out infinite alternate}.streaming-progress{color:var(--max-muted);font-size:14px;white-space:pre-line}.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)}.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{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}.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:14px}.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 h3,.assistant-doughnut>span strong,.assistant-chart-legend-item strong,.assistant-bar-label strong{color:var(--max-text)}.assistant-chart-legend-item,.assistant-bar-label,.assistant-doughnut>span{color:var(--max-muted)}.assistant-doughnut-track,.assistant-bar-track{stroke:var(--max-border);background:var(--max-border)}.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-top:16px;color:var(--max-accent);font-size:12px;text-decoration:none}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.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}.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]{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 .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{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.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));font-size:32px}.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}.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-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@media (prefers-reduced-motion: reduce){.message.streaming:before{animation:none}.suggestion-chip,.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{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}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.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"] }]
1189
- }], ctorParameters: () => [{ type: MaxAssistantService }, { type: MaxAssistantSupportService }, { type: i0.DestroyRef }, { type: undefined, decorators: [{
1355
+ ], 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 <i class=\"max-assistant-sparkles far fa-sparkles\" aria-hidden=\"true\"></i>\n <div class=\"assistant-identity\">\n <h2 class=\"assistant-name\">{{ uiCopy.title }}</h2>\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 [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError\"\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.isStreaming) {\n <p class=\"streaming-progress\">{{ message.content }}</p>\n } @else if(message.displayResponse; as responseDetails) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\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 <strong>{{ card.title }}</strong>\n @if(card.subtitle) {\n <span>{{ 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\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span>{{ metric.label }}</span>\n <strong>{{ metric.value }}</strong>\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 <h3>{{ visualisation.title }}</h3>\n @if(visualisation.type === 'doughnut') {\n <div class=\"assistant-doughnut-layout\">\n <div\n class=\"assistant-doughnut\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n <svg viewBox=\"0 0 42 42\" aria-hidden=\"true\" focusable=\"false\">\n <circle\n class=\"assistant-doughnut-track\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n ></circle>\n @for(value of visualisation.values; track $index; let valueIndex = $index) {\n <circle\n class=\"assistant-doughnut-segment\"\n cx=\"21\"\n cy=\"21\"\n r=\"15.9155\"\n pathLength=\"100\"\n [attr.stroke]=\"chartColor(visualisation, valueIndex)\"\n [attr.stroke-dasharray]=\"doughnutDashArray(visualisation, valueIndex)\"\n [attr.stroke-dashoffset]=\"doughnutDashOffset(visualisation, valueIndex)\"\n ></circle>\n }\n </svg>\n <span><strong>{{ chartTotal(visualisation) }}</strong>people</span>\n </div>\n <div class=\"assistant-chart-legend\">\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-chart-legend-item\">\n <i [style.background]=\"chartColor(visualisation, labelIndex)\"></i>\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n }\n </div>\n </div>\n } @else {\n <div\n class=\"assistant-bar-chart\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n >\n @for(label of visualisation.labels; track $index; let labelIndex = $index) {\n <div class=\"assistant-bar-row\">\n <div class=\"assistant-bar-label\">\n <span>{{ label }}</span>\n <strong>{{ visualisation.values[labelIndex] || 0 }}</strong>\n </div>\n <div class=\"assistant-bar-track\" aria-hidden=\"true\">\n <i\n [style.width.%]=\"barWidth(visualisation, labelIndex)\"\n [style.background]=\"chartColor(visualisation, labelIndex)\"\n ></i>\n </div>\n </div>\n }\n </div>\n }\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index) {\n <section class=\"assistant-table-section\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\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 @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 </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 <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 <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 </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 {\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) {\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(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 <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\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\">\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]=\"supportSeverityOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [severity]=\"severity.severity\"\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 [severity]=\"severity.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\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 optionValue=\"value\"\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.value) {\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>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>Feedback received</h3>\n <p>{{ result.message }}</p>\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.feedbackReference }}</strong>\n </div>\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>Name</span>\n <input\n type=\"text\"\n name=\"feedbackName\"\n autocomplete=\"name\"\n [value]=\"feedbackForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"feedbackEmail\"\n autocomplete=\"email\"\n [value]=\"feedbackForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"feedbackPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"feedbackForm.phone\"\n />\n </label>\n\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(!feedbackForm.name || !feedbackForm.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(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(--primary-color, #2563eb);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{white-space:pre-line}.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 #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff);box-shadow:0 8px 22px #0f172a0f}.assistant-card>header{display:grid;gap:2px;padding:11px 12px;border-bottom:1px solid #e2e8f0}.assistant-card>header strong{color:#0f172a;font-size:14px}.assistant-card>header span,.assistant-card>footer{color:#64748b;font-size:11px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.assistant-card-metric{display:grid;min-width:0;gap:3px;padding:11px 9px;border-right:1px solid #e2e8f0}.assistant-card-metric:last-child{border-right:0}.assistant-card-metric span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.assistant-card-metric strong{color:#1e293b;font-size:13px;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] strong{color:#047857}.assistant-card-metric[data-tone=warning] strong{color:#b45309}.assistant-card>footer{padding:8px 12px;border-top:1px solid #e2e8f0;background:#f8fafcb8}: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-doughnut-layout{display:grid;grid-template-columns:112px minmax(0,1fr);gap:14px;align-items:center}.assistant-doughnut{position:relative;display:grid;place-items:center;width:112px;aspect-ratio:1}.assistant-doughnut svg{width:100%;height:100%;transform:rotate(-90deg)}.assistant-doughnut circle{fill:none;stroke-width:6}.assistant-doughnut-track{stroke:#e2e8f0}.assistant-doughnut-segment{transition:stroke-dasharray .18s ease}.assistant-doughnut>span{position:absolute;display:grid;color:#64748b;font-size:9px;line-height:1.1;text-align:center}.assistant-doughnut>span strong{color:#0f172a;font-size:18px}.assistant-chart-legend{display:grid;gap:7px;min-width:0}.assistant-chart-legend-item{display:grid;grid-template-columns:9px minmax(0,1fr) auto;gap:7px;align-items:center;color:#475569;font-size:11px}.assistant-chart-legend-item i{width:9px;height:9px;border-radius:999px}.assistant-chart-legend-item strong,.assistant-bar-label strong{color:#0f172a;font-size:11px}.assistant-bar-chart,.assistant-bar-row{display:grid;gap:6px}.assistant-bar-chart{gap:11px}.assistant-bar-label{display:flex;gap:12px;align-items:baseline;justify-content:space-between;color:#475569;font-size:11px}.assistant-bar-track{height:9px;overflow:hidden;border-radius:999px;background:#e2e8f0}.assistant-bar-track i{display:block;height:100%;min-width:0;border-radius:var(--max-frame-radius, 0);transition:width .18s ease}.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}.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}.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,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{border-right:0;border-bottom:1px solid #e2e8f0}.assistant-card-metric:last-child{border-bottom: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-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-gradient: linear-gradient( 135deg, color-mix(in srgb, var(--max-accent) 58%, white) 0%, var(--max-accent) 46%, color-mix(in srgb, var(--max-accent) 55%, var(--max-accent-strong)) 72%, var(--max-accent-strong) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--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:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;font-size:var(--max-header-content-size);line-height:1;vertical-align:middle;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;filter:drop-shadow(0 2px 3px rgba(60,64,67,.18))}.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:20px;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;color:transparent;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;font:inherit;font-size:var(--max-header-content-size);font-weight:600;line-height:1}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.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:12px 18px;border:0;border-radius:22px 22px 6px;color:var(--max-text);background:color-mix(in srgb,var(--max-accent) 8%,var(--max-surface))}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.message.streaming{display:flex;gap:10px;align-items:center;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{width:16px;height:16px;flex:0 0 auto;border-radius:6px;background:var(--assistant-sparkles-gradient, var(--max-sparkles-gradient));content:\"\";animation:max-thinking 1.4s ease-in-out infinite alternate}.streaming-progress{color:var(--max-muted);font-size:14px;white-space:pre-line}.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)}.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}.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:14px}.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 h3,.assistant-doughnut>span strong,.assistant-chart-legend-item strong,.assistant-bar-label strong{color:var(--max-text)}.assistant-chart-legend-item,.assistant-bar-label,.assistant-doughnut>span{color:var(--max-muted)}.assistant-doughnut-track,.assistant-bar-track{stroke:var(--max-border);background:var(--max-border)}.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:none}.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}.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(--max-control-radius);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 .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{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.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));font-size:32px}.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}.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-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@media (prefers-reduced-motion: reduce){.message.streaming:before{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"] }]
1356
+ }], ctorParameters: () => [{ type: MaxAssistantService }, { type: MaxAssistantFeedbackService }, { type: MaxAssistantSupportService }, { type: i0.DestroyRef }, { type: undefined, decorators: [{
1190
1357
  type: Inject,
1191
1358
  args: [MAX_ASSISTANT_CONFIG]
1192
1359
  }] }], propDecorators: { messagesViewport: [{
@@ -1198,6 +1365,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
1198
1365
  }], supportQueryInput: [{
1199
1366
  type: ViewChild,
1200
1367
  args: ['supportQueryInput']
1368
+ }], feedbackInput: [{
1369
+ type: ViewChild,
1370
+ args: ['feedbackInput']
1201
1371
  }], app: [{
1202
1372
  type: Input
1203
1373
  }], assistantApiUrl: [{
@@ -1225,5 +1395,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
1225
1395
  * Generated bundle index. Do not edit.
1226
1396
  */
1227
1397
 
1228
- export { MAX_ASSISTANT_CONFIG, MaxAgentShiftCardComponent, MaxAssistantComponent, MaxAssistantService, MaxAssistantSupportService };
1398
+ export { MAX_ASSISTANT_CONFIG, MaxAgentShiftCardComponent, MaxAssistantComponent, MaxAssistantFeedbackService, MaxAssistantService, MaxAssistantSupportService };
1229
1399
  //# sourceMappingURL=max-agent-ui.mjs.map