max-agent-ui 0.0.37 → 0.0.39

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.
@@ -21,9 +21,56 @@ import * as i11 from 'primeng/textarea';
21
21
  import { TextareaModule } from 'primeng/textarea';
22
22
  import * as i12 from 'primeng/tooltip';
23
23
  import { TooltipModule } from 'primeng/tooltip';
24
- import { throwError, Observable, map, switchMap, of } from 'rxjs';
24
+ import { Subject, throwError, Observable, map, takeUntil, switchMap, of } from 'rxjs';
25
25
  import { marked } from 'marked';
26
26
 
27
+ /** Owned by one assistant component. Never persists, shares across tabs, or decodes signed state. */
28
+ class AssistantConversationState {
29
+ resetRequests = new Subject();
30
+ token;
31
+ identity;
32
+ reset() {
33
+ this.resetRequests.next();
34
+ this.token = undefined;
35
+ }
36
+ accept(response) {
37
+ this.token = response.conversationState?.length && response.conversationState.length <= 250_000
38
+ ? response.conversationState : undefined;
39
+ }
40
+ changedIdentity(identity) {
41
+ const changed = this.identity !== undefined && this.identity !== identity;
42
+ this.identity = identity;
43
+ return changed;
44
+ }
45
+ history(messages, question = '') {
46
+ let candidates = messages.slice(-8);
47
+ if (question && messages.length > 8) {
48
+ const ignored = new Set(['show', 'tell', 'what', 'that', 'this', 'with', 'from', 'have', 'were', 'many', 'about', 'please']);
49
+ const words = [...new Set(question.toLowerCase().match(/[\p{L}\p{N}]{4,}/gu) ?? [])].filter(word => !ignored.has(word));
50
+ const older = messages.slice(0, -4).map((message, index) => ({ message, index,
51
+ score: message.role === 'user' ? words.filter(word => message.content.toLowerCase().includes(word)).length : 0
52
+ })).filter(item => item.score > 0).sort((a, b) => b.score - a.score || b.index - a.index).slice(0, 2).sort((a, b) => a.index - b.index);
53
+ if (older.length)
54
+ candidates = [...older.flatMap(item => messages.slice(item.index, messages[item.index + 1]?.role === 'assistant' ? item.index + 2 : item.index + 1)), ...messages.slice(-4)];
55
+ }
56
+ const encoder = new TextEncoder();
57
+ let remaining = 8_000;
58
+ return candidates.reverse().flatMap(message => {
59
+ let content = '';
60
+ let bytes = 0;
61
+ for (const character of message.content) {
62
+ const size = encoder.encode(character).length;
63
+ if (bytes + size > Math.min(3_000, remaining))
64
+ break;
65
+ content += character;
66
+ bytes += size;
67
+ }
68
+ remaining -= bytes;
69
+ return content ? [{ ...message, content }] : [];
70
+ }).reverse();
71
+ }
72
+ }
73
+
27
74
  const INITIAL_MESSAGE = 'Hi! 👋';
28
75
  const INITIAL_DESCRIPTION = "I'm here to help. Whether you need information, want to complete a task, or just have a question, let me know and we'll get started.\n\nI'm still in my early days and learning every day. If I can't do something just yet, I hope you'll bear with me—I'll always do my best to help.\n\nWhat would you like to do today?";
29
76
  const DEFAULT_ASSISTANT_BOOTSTRAP = {
@@ -230,6 +277,7 @@ function getDefaultAssistantFeedbackUrl(developmentMode = isDevMode()) {
230
277
 
231
278
  const DEFAULT_APP = 'cortex';
232
279
  const DEFAULT_TIMEZONE = 'UTC';
280
+ const STREAM_IDLE_TIMEOUT_MS = 45_000;
233
281
  class MaxAssistantService {
234
282
  config;
235
283
  http;
@@ -287,6 +335,10 @@ class MaxAssistantService {
287
335
  return this.postMessage(request, assistantConfig);
288
336
  }
289
337
  postMessage(request, config, onProgress) {
338
+ request = { ...request,
339
+ ...(config.conversationStateVersion ? { conversationStateVersion: config.conversationStateVersion } : {}),
340
+ ...(request.conversationId && config.conversationState ? { conversationState: config.conversationState } : {})
341
+ };
290
342
  if (!this.http) {
291
343
  return throwError(() => new Error('HttpClient is not available. Add provideHttpClient() to the host app.'));
292
344
  }
@@ -298,6 +350,20 @@ class MaxAssistantService {
298
350
  streamMessage(request, config, onProgress) {
299
351
  return new Observable(subscriber => {
300
352
  const controller = new AbortController();
353
+ const streamError = (message, code) => new HttpErrorResponse({
354
+ error: { message, code },
355
+ status: code === 'request_timeout' ? 504 : 502,
356
+ url: this.getChatUrl(config)
357
+ });
358
+ let idleTimer;
359
+ const resetIdleTimer = () => {
360
+ clearTimeout(idleTimer);
361
+ idleTimer = setTimeout(() => {
362
+ subscriber.error(streamError('This request is taking longer than expected. Please try again.', 'request_timeout'));
363
+ controller.abort();
364
+ }, STREAM_IDLE_TIMEOUT_MS);
365
+ };
366
+ resetIdleTimer();
301
367
  const headers = this.getHeaders(config);
302
368
  const fetchHeaders = Object.fromEntries(headers.keys().map(name => [name, headers.get(name) ?? '']));
303
369
  void fetch(this.getChatUrl(config), {
@@ -323,6 +389,8 @@ class MaxAssistantService {
323
389
  let buffer = '';
324
390
  let receivedResult = false;
325
391
  const processLine = (line) => {
392
+ if (subscriber.closed)
393
+ return;
326
394
  const trimmedLine = line.trim();
327
395
  if (!trimmedLine) {
328
396
  return;
@@ -332,38 +400,50 @@ class MaxAssistantService {
332
400
  onProgress(event);
333
401
  return;
334
402
  }
335
- if (event.type === 'delta') {
403
+ if (event.type === 'delta' || event.type === 'data') {
336
404
  onProgress(event);
337
405
  return;
338
406
  }
339
407
  if (event.type === 'error') {
340
- throw new Error(event.message);
408
+ throw streamError(event.message, event.code ?? 'request_failed');
409
+ }
410
+ if (event.type === 'result') {
411
+ receivedResult = true;
412
+ subscriber.next(event.response);
413
+ subscriber.complete();
341
414
  }
342
- receivedResult = true;
343
- subscriber.next(event.response);
344
415
  };
345
416
  while (true) {
346
417
  const { done, value } = await reader.read();
347
418
  if (done) {
348
419
  break;
349
420
  }
421
+ resetIdleTimer();
350
422
  buffer += decoder.decode(value, { stream: true });
351
423
  const lines = buffer.split('\n');
352
424
  buffer = lines.pop() ?? '';
353
425
  lines.forEach(processLine);
426
+ if (receivedResult || subscriber.closed) {
427
+ return;
428
+ }
354
429
  }
355
430
  buffer += decoder.decode();
356
431
  processLine(buffer);
357
432
  if (!receivedResult) {
358
- throw new Error('The assistant response stream ended before a result was returned.');
433
+ throw streamError('The connection was interrupted before the answer was ready. Please try again.', 'stream_interrupted');
359
434
  }
360
435
  subscriber.complete();
361
436
  }).catch(error => {
362
- if (!subscriber.closed && error?.name !== 'AbortError') {
363
- subscriber.error(error);
437
+ if (!subscriber.closed) {
438
+ subscriber.error(error?.name === 'AbortError'
439
+ ? streamError('The connection was interrupted before the answer was ready. Please try again.', 'stream_interrupted')
440
+ : error);
364
441
  }
365
442
  });
366
- return () => controller.abort();
443
+ return () => {
444
+ clearTimeout(idleTimer);
445
+ controller.abort();
446
+ };
367
447
  });
368
448
  }
369
449
  getChatUrl(config) {
@@ -489,89 +569,52 @@ class MaxAssistantExportService {
489
569
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
490
570
  }), `${this.exportFileName(table.title, 'agent-results')}.xlsx`);
491
571
  }
492
- async exportVisualisationToPdf(visualisation) {
572
+ async exportVisualisationToPdf(visualisation, visualisationElement) {
573
+ const canvas = visualisationElement.querySelector('canvas');
574
+ if (!canvas || !canvas.width || !canvas.height) {
575
+ throw new Error('The rendered chart is not available for export.');
576
+ }
493
577
  const { jsPDF } = await import('jspdf');
494
- const document = new jsPDF({ format: 'a4', orientation: 'portrait', unit: 'mm' });
578
+ const orientation = canvas.width > canvas.height ? 'landscape' : 'portrait';
579
+ const document = new jsPDF({ format: 'a4', orientation, unit: 'mm' });
495
580
  const pageWidth = document.internal.pageSize.getWidth();
496
581
  const pageHeight = document.internal.pageSize.getHeight();
497
582
  const margin = 16;
498
583
  const contentWidth = pageWidth - (margin * 2);
499
- const datasets = visualisation.datasets?.length
500
- ? visualisation.datasets
501
- : [{
502
- label: visualisation.valueLabel || 'Value',
503
- values: visualisation.values,
504
- colors: visualisation.colors,
505
- }];
506
- let cursorY = 20;
584
+ const chartTop = 30;
585
+ const availableHeight = pageHeight - chartTop - margin;
586
+ const scale = Math.min(contentWidth / canvas.width, availableHeight / canvas.height);
587
+ const imageWidth = canvas.width * scale;
588
+ const imageHeight = canvas.height * scale;
589
+ const imageX = (pageWidth - imageWidth) / 2;
590
+ const { Chart } = await import('chart.js');
591
+ const chart = Chart.getChart(canvas);
592
+ let chartImage;
593
+ if (chart) {
594
+ const originalPixelRatio = chart.options.devicePixelRatio;
595
+ // Render fresh chart pixels at 300 DPI; enlarging the screen bitmap blurs labels.
596
+ const printPixelRatio = Math.ceil((imageWidth / 25.4 * 300) / chart.width);
597
+ try {
598
+ chart.options.devicePixelRatio = Math.max(originalPixelRatio ?? 1, printPixelRatio);
599
+ chart.resize();
600
+ chart.update('none');
601
+ chartImage = canvas.toDataURL('image/png', 1);
602
+ }
603
+ finally {
604
+ chart.options.devicePixelRatio = originalPixelRatio;
605
+ chart.resize();
606
+ chart.update('none');
607
+ }
608
+ }
609
+ else {
610
+ chartImage = canvas.toDataURL('image/png', 1);
611
+ }
507
612
  document.setFont('helvetica', 'bold');
508
613
  document.setFontSize(16);
509
- document.text(visualisation.title, margin, cursorY, { maxWidth: contentWidth });
510
- cursorY += 9;
511
- document.setFont('helvetica', 'normal');
512
- document.setFontSize(10);
513
- document.text(this.chartTypeLabel(visualisation.type), margin, cursorY);
514
- if (['doughnut', 'pie', 'polarArea'].includes(visualisation.type)) {
515
- const valueLabel = visualisation.valueLabel ? ` ${visualisation.valueLabel}` : '';
516
- document.text(`Total: ${this.chartTotal(visualisation)}${valueLabel}`, pageWidth - margin, cursorY, { align: 'right' });
517
- }
518
- cursorY += 10;
519
- datasets.forEach((dataset, datasetIndex) => {
520
- if (datasets.length > 1) {
521
- if (cursorY + 12 > pageHeight - margin) {
522
- document.addPage();
523
- cursorY = margin;
524
- }
525
- document.setFont('helvetica', 'bold');
526
- document.setTextColor(31, 41, 55);
527
- document.text(dataset.label, margin, cursorY);
528
- document.setFont('helvetica', 'normal');
529
- cursorY += 7;
530
- }
531
- visualisation.labels.forEach((label, index) => {
532
- const value = Number(dataset.values[index]) || 0;
533
- const labelLines = document.splitTextToSize(label, contentWidth - 32);
534
- const rowHeight = Math.max(8, labelLines.length * 5 + 3);
535
- if (cursorY + rowHeight > pageHeight - margin) {
536
- document.addPage();
537
- cursorY = margin;
538
- }
539
- const colour = dataset.colors?.[index]
540
- ?? dataset.color
541
- ?? visualisation.colors?.[datasets.length === 1 ? index : datasetIndex]
542
- ?? this.fallbackColor(datasets.length === 1 ? index : datasetIndex);
543
- const [red, green, blue] = this.pdfColor(colour);
544
- document.setFillColor(red, green, blue);
545
- document.rect(margin, cursorY, 4, 4, 'F');
546
- document.setTextColor(31, 41, 55);
547
- document.text(labelLines, margin + 7, cursorY + 3);
548
- document.setFont('helvetica', 'bold');
549
- document.text(String(value), pageWidth - margin, cursorY + 3, { align: 'right' });
550
- document.setFont('helvetica', 'normal');
551
- cursorY += rowHeight;
552
- });
553
- cursorY += datasets.length > 1 ? 3 : 0;
554
- });
614
+ document.text(visualisation.title, margin, 20, { maxWidth: contentWidth });
615
+ document.addImage(chartImage, 'PNG', imageX, chartTop, imageWidth, imageHeight, undefined, 'FAST');
555
616
  this.downloadFile(new Blob([document.output('arraybuffer')], { type: 'application/pdf' }), `${this.exportFileName(visualisation.title, 'agent-chart')}.pdf`);
556
617
  }
557
- chartTotal(visualisation) {
558
- return visualisation.values.reduce((total, value) => total + Math.max(0, Number(value) || 0), 0);
559
- }
560
- chartTypeLabel(type) {
561
- const labels = {
562
- bar: 'Vertical bar chart',
563
- horizontalBar: 'Horizontal bar chart',
564
- stackedBar: 'Stacked bar chart',
565
- doughnut: 'Doughnut chart',
566
- pie: 'Pie chart',
567
- line: 'Line chart',
568
- lineStyles: 'Line styles chart',
569
- radar: 'Radar chart',
570
- polarArea: 'Polar area chart',
571
- barLine: 'Combined bar and line chart',
572
- };
573
- return labels[type];
574
- }
575
618
  toExportCellValue(value) {
576
619
  if (value === null || value === undefined) {
577
620
  return '';
@@ -595,24 +638,6 @@ class MaxAssistantExportService {
595
638
  .replace(/^-+|-+$/g, '');
596
639
  return normalised || fallback;
597
640
  }
598
- fallbackColor(index) {
599
- const colors = ['#42A5F5', '#FFA5F5', '#66BB6A', '#FFA726', '#228888'];
600
- return colors[index % colors.length];
601
- }
602
- pdfColor(color) {
603
- const normalised = color.trim().replace(/^#/, '');
604
- const expanded = normalised.length === 3
605
- ? normalised.split('').map(character => `${character}${character}`).join('')
606
- : normalised;
607
- if (!/^[0-9a-f]{6}$/i.test(expanded)) {
608
- return [66, 165, 245];
609
- }
610
- return [
611
- Number.parseInt(expanded.slice(0, 2), 16),
612
- Number.parseInt(expanded.slice(2, 4), 16),
613
- Number.parseInt(expanded.slice(4, 6), 16),
614
- ];
615
- }
616
641
  downloadFile(file, fileName) {
617
642
  const url = URL.createObjectURL(file);
618
643
  const link = document.createElement('a');
@@ -816,8 +841,12 @@ const ASSISTANT_UI_COPY = {
816
841
  feedbackLabel: 'Provide feedback on this response',
817
842
  feedbackTooltip: 'Provide feedback',
818
843
  placeholder: 'Ask Max AI',
819
- startingMessage: 'Reviewing your request…',
820
- errorMessage: 'Maxtime virtual assistant could not be reached. Please try again.',
844
+ startingMessage: 'Preparing your answer…',
845
+ errorMessage: 'Sorry, something went wrong while preparing your response. Please try again in a little while.',
846
+ offlineTitle: "I'm currently offline",
847
+ accessUnavailableTitle: "I can't verify your access right now",
848
+ accessUnavailableMessage: "Sorry, I can't verify your access right now, so I can't answer your request. Please try again in a little while. You can continue using Maxtime in the meantime. If this continues, contact your administrator.",
849
+ offlineMessage: "Sorry, I can't connect right now. Please try again in a little while. You can continue using Maxtime in the meantime.",
821
850
  };
822
851
  const ASSISTANT_SEARCH_RESULT_ICONS = {
823
852
  EMPLOYEE: 'pi pi-user',
@@ -852,6 +881,7 @@ class MaxAssistantComponent {
852
881
  supportService;
853
882
  destroyRef;
854
883
  defaultConfig;
884
+ sessionState = new AssistantConversationState();
855
885
  messagesViewport;
856
886
  activeTurnAnchorMessageId;
857
887
  scrollToLatestTimer;
@@ -908,7 +938,26 @@ class MaxAssistantComponent {
908
938
  }
909
939
  ngOnInit() {
910
940
  this.messages.set(this.createDefaultMessages());
941
+ this.destroyRef.onDestroy(() => {
942
+ this.sessionState.reset();
943
+ this.sessionState.resetRequests.complete();
944
+ clearTimeout(this.scrollToLatestTimer);
945
+ });
911
946
  }
947
+ ngDoCheck() {
948
+ const configuredUser = typeof this.defaultConfig.user === 'function' ? this.defaultConfig.user() : this.defaultConfig.user;
949
+ const localUser = typeof this.user === 'function' ? this.user() : this.user;
950
+ const user = { ...configuredUser, ...localUser };
951
+ const contextSource = this.context ?? this.defaultConfig.context;
952
+ const context = typeof contextSource === 'function' ? contextSource() : contextSource;
953
+ if (this.sessionState.changedIdentity(JSON.stringify([this.app ?? this.defaultConfig.app,
954
+ user.token, user.version, user.username, user.email, context?.tenantId, context?.organisationId, context?.userId]))) {
955
+ this.clearChatSession();
956
+ }
957
+ }
958
+ resetSession() { this.clearChatSession(); }
959
+ // Also clears memory if the browser keeps this document in its back/forward cache.
960
+ onPageHide() { this.clearChatSession(); }
912
961
  focusComposer() {
913
962
  this.composerInput?.nativeElement.focus();
914
963
  }
@@ -942,6 +991,7 @@ class MaxAssistantComponent {
942
991
  }
943
992
  }
944
993
  clearChatSession() {
994
+ this.sessionState.reset();
945
995
  this.closeFeedback(false);
946
996
  this.closeSupportTicket(false);
947
997
  this.input.set('');
@@ -960,7 +1010,7 @@ class MaxAssistantComponent {
960
1010
  if (!trimmedMessage || this.isSending()) {
961
1011
  return;
962
1012
  }
963
- const history = this.getConversationHistory();
1013
+ const history = this.getConversationHistory(trimmedMessage);
964
1014
  this.input.set('');
965
1015
  this.appendMessage(this.createMessage('user', trimmedMessage));
966
1016
  const initialProgress = {
@@ -977,18 +1027,26 @@ class MaxAssistantComponent {
977
1027
  this.isSending.set(true);
978
1028
  this.assistantService
979
1029
  .sendMessage(trimmedMessage, this.conversationId(), this.getAssistantConfig(), undefined, history, activity => this.updateStreamingMessage(streamingMessage.id, activity))
980
- .pipe(takeUntilDestroyed(this.destroyRef))
1030
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
981
1031
  .subscribe({
982
1032
  next: response => {
1033
+ this.sessionState.accept(response);
983
1034
  this.conversationId.set(response.conversationId);
984
1035
  this.replaceMessage(streamingMessage.id, this.createAssistantResponseMessage(response, trimmedMessage));
985
1036
  this.isSending.set(false);
986
1037
  },
987
1038
  error: error => {
988
- this.replaceMessage(streamingMessage.id, {
989
- ...this.createMessage('assistant', this.resolveErrorMessage(error)),
990
- isError: true
991
- });
1039
+ const preview = this.messages().find(message => message.id === streamingMessage.id);
1040
+ if (preview?.displayResponse || preview?.cards?.length) {
1041
+ this.replaceMessage(streamingMessage.id, {
1042
+ ...preview,
1043
+ content: 'The data was retrieved, but the explanation could not be completed.',
1044
+ streamingContent: undefined,
1045
+ });
1046
+ this.isSending.set(false);
1047
+ return;
1048
+ }
1049
+ this.replaceMessage(streamingMessage.id, this.createErrorMessage(error));
992
1050
  this.isSending.set(false);
993
1051
  }
994
1052
  });
@@ -1070,18 +1128,16 @@ class MaxAssistantComponent {
1070
1128
  this.isSending.set(true);
1071
1129
  this.assistantService
1072
1130
  .sendStructuredAction(suggestion.message, suggestion.structuredAction, this.conversationId(), this.getAssistantConfig(), history)
1073
- .pipe(takeUntilDestroyed(this.destroyRef))
1131
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1074
1132
  .subscribe({
1075
1133
  next: response => {
1134
+ this.sessionState.accept(response);
1076
1135
  this.conversationId.set(response.conversationId);
1077
1136
  this.appendMessage(this.createAssistantResponseMessage(response, suggestion.message));
1078
1137
  this.isSending.set(false);
1079
1138
  },
1080
1139
  error: error => {
1081
- this.appendMessage({
1082
- ...this.createMessage('assistant', this.resolveErrorMessage(error)),
1083
- isError: true
1084
- });
1140
+ this.appendMessage(this.createErrorMessage(error));
1085
1141
  this.isSending.set(false);
1086
1142
  }
1087
1143
  });
@@ -1108,7 +1164,7 @@ class MaxAssistantComponent {
1108
1164
  this.supportTicketVisible.set(true);
1109
1165
  this.supportService
1110
1166
  .getSupportTags()
1111
- .pipe(takeUntilDestroyed(this.destroyRef))
1167
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1112
1168
  .subscribe({
1113
1169
  next: tags => {
1114
1170
  this.supportTags.set(tags);
@@ -1121,7 +1177,7 @@ class MaxAssistantComponent {
1121
1177
  });
1122
1178
  this.supportService
1123
1179
  .getSupportSeverities()
1124
- .pipe(takeUntilDestroyed(this.destroyRef))
1180
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1125
1181
  .subscribe({
1126
1182
  next: severities => this.supportSeverities.set(severities),
1127
1183
  error: () => this.supportTicketError.set('Severity options could not be loaded. Please try again.')
@@ -1173,8 +1229,8 @@ class MaxAssistantComponent {
1173
1229
  severity,
1174
1230
  tags: this.supportTicketForm.tags.map(({ id, label }) => ({ id, label })),
1175
1231
  app: this.app ?? this.defaultConfig.app ?? 'nemesys'
1176
- }, this.getAssistantConfig())
1177
- .pipe(takeUntilDestroyed(this.destroyRef))
1232
+ }, this.getAssistantConfig(false))
1233
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1178
1234
  .subscribe({
1179
1235
  next: result => {
1180
1236
  this.supportTicketResult.set(result);
@@ -1226,8 +1282,8 @@ class MaxAssistantComponent {
1226
1282
  feedback: this.feedbackForm.feedback.trim(),
1227
1283
  app: this.app ?? this.defaultConfig.app ?? 'nemesys',
1228
1284
  ...(this.conversationId() ? { conversationId: this.conversationId() } : {})
1229
- }, this.getAssistantConfig())
1230
- .pipe(takeUntilDestroyed(this.destroyRef))
1285
+ }, this.getAssistantConfig(false))
1286
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1231
1287
  .subscribe({
1232
1288
  next: result => {
1233
1289
  this.feedbackResult.set(result);
@@ -1290,18 +1346,16 @@ class MaxAssistantComponent {
1290
1346
  return of(response);
1291
1347
  }
1292
1348
  return this.assistantService.confirmAction(response.pendingAction.id, 'approve', response.conversationId, this.getAssistantConfig(), history);
1293
- }), takeUntilDestroyed(this.destroyRef))
1349
+ }), takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1294
1350
  .subscribe({
1295
1351
  next: response => {
1352
+ this.sessionState.accept(response);
1296
1353
  this.conversationId.set(response.conversationId);
1297
1354
  this.appendMessage(this.createAssistantResponseMessage(response, action.message));
1298
1355
  this.isSending.set(false);
1299
1356
  },
1300
1357
  error: error => {
1301
- this.appendMessage({
1302
- ...this.createMessage('assistant', this.resolveErrorMessage(error)),
1303
- isError: true
1304
- });
1358
+ this.appendMessage(this.createErrorMessage(error));
1305
1359
  this.isSending.set(false);
1306
1360
  }
1307
1361
  });
@@ -1324,23 +1378,37 @@ class MaxAssistantComponent {
1324
1378
  this.isSending.set(true);
1325
1379
  this.assistantService
1326
1380
  .confirmAction(pendingAction.id, decision, currentConversationId, this.getAssistantConfig(), history)
1327
- .pipe(takeUntilDestroyed(this.destroyRef))
1381
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1328
1382
  .subscribe({
1329
1383
  next: response => {
1384
+ this.sessionState.accept(response);
1330
1385
  this.conversationId.set(response.conversationId);
1331
1386
  this.appendMessage(this.createAssistantResponseMessage(response, userMessage));
1332
1387
  this.isSending.set(false);
1333
1388
  },
1334
1389
  error: error => {
1335
1390
  this.messages.update(messages => messages.map(item => item.id === message.id ? { ...item, actionDecision: undefined } : item));
1336
- this.appendMessage({
1337
- ...this.createMessage('assistant', this.resolveErrorMessage(error)),
1338
- isError: true
1339
- });
1391
+ this.appendMessage(this.createErrorMessage(error));
1340
1392
  this.isSending.set(false);
1341
1393
  }
1342
1394
  });
1343
1395
  }
1396
+ createErrorMessage(error) {
1397
+ const isAccessUnavailable = error instanceof HttpErrorResponse && (error.error?.code === 'authorization_unavailable' ||
1398
+ error.error?.error === 'authorization_unavailable' ||
1399
+ error.error?.message === 'Access could not be verified with the calling Maxtime product.');
1400
+ // Do not label permissions, validation or a model timeout as an outage.
1401
+ const isOffline = !isAccessUnavailable && (error instanceof HttpErrorResponse
1402
+ ? error.status === 0 || (error.status === 500 && !error.error) ||
1403
+ ([502, 503, 504].includes(error.status) && !error.error?.code)
1404
+ : error instanceof TypeError && /fetch|network|load failed/iu.test(error.message));
1405
+ return {
1406
+ ...this.createMessage('assistant', isAccessUnavailable ? this.uiCopy.accessUnavailableMessage : isOffline ? this.uiCopy.offlineMessage : this.resolveErrorMessage(error)),
1407
+ isError: true,
1408
+ isOffline,
1409
+ isAccessUnavailable
1410
+ };
1411
+ }
1344
1412
  resolveErrorMessage(error) {
1345
1413
  if (error instanceof HttpErrorResponse &&
1346
1414
  typeof error.error === 'object' &&
@@ -1406,11 +1474,11 @@ class MaxAssistantComponent {
1406
1474
  this.loadingTablePage.set(tableKey);
1407
1475
  this.isSending.set(true);
1408
1476
  this.assistantService
1409
- .retrieveAnalyticsPage(pagination.query, { offset: nextOffset, pageSize: 250 }, this.conversationId(), this.getAssistantConfig(), history)
1410
- .pipe(takeUntilDestroyed(this.destroyRef))
1477
+ .retrieveAnalyticsPage(pagination.query, { offset: nextOffset, pageSize: 100 }, this.conversationId(), this.getAssistantConfig(), history)
1478
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1411
1479
  .subscribe({
1412
1480
  next: response => {
1413
- this.conversationId.set(response.conversationId);
1481
+ // Paging an older table must not replace the active conversational topic.
1414
1482
  this.mergeTablePage(message.id, tableIndex, response, pagination.query);
1415
1483
  this.loadingTablePage.set(undefined);
1416
1484
  this.isSending.set(false);
@@ -1461,8 +1529,8 @@ class MaxAssistantComponent {
1461
1529
  exportTable(table) {
1462
1530
  void this.exportService.exportTableToExcel(table);
1463
1531
  }
1464
- exportVisualisation(visualisation) {
1465
- void this.exportService.exportVisualisationToPdf(visualisation);
1532
+ exportVisualisation(visualisation, visualisationElement) {
1533
+ void this.exportService.exportVisualisationToPdf(visualisation, visualisationElement);
1466
1534
  }
1467
1535
  chartType(visualisation) {
1468
1536
  switch (visualisation.type) {
@@ -1732,8 +1800,10 @@ class MaxAssistantComponent {
1732
1800
  };
1733
1801
  return labels[category] ?? this.formatTraceLabel(category);
1734
1802
  }
1735
- getAssistantConfig() {
1736
- const config = {};
1803
+ getAssistantConfig(includeConversation = true) {
1804
+ const config = includeConversation
1805
+ ? { conversationStateVersion: 1, ...(this.sessionState.token ? { conversationState: this.sessionState.token } : {}) }
1806
+ : {};
1737
1807
  if (this.assistantApiUrl) {
1738
1808
  config.assistantApiUrl = this.assistantApiUrl;
1739
1809
  }
@@ -1777,8 +1847,24 @@ class MaxAssistantComponent {
1777
1847
  return {
1778
1848
  ...message,
1779
1849
  streamingContent: `${message.streamingContent ?? ''}${activity.delta}`,
1850
+ ...(message.displayResponse || message.cards?.length
1851
+ ? { content: `${message.streamingContent ?? ''}${activity.delta}` }
1852
+ : {}),
1780
1853
  };
1781
1854
  }
1855
+ if (activity.type === 'data') {
1856
+ messageUpdated = true;
1857
+ return {
1858
+ ...message,
1859
+ ...activity.data,
1860
+ displayResponse: activity.data.displayResponse ?? {},
1861
+ content: message.streamingContent ?? '',
1862
+ processingUpdates: [],
1863
+ };
1864
+ }
1865
+ if (message.displayResponse || message.cards?.length) {
1866
+ return message;
1867
+ }
1782
1868
  const progressMessage = activity.message.trim();
1783
1869
  if (!progressMessage) {
1784
1870
  return message;
@@ -1794,7 +1880,6 @@ class MaxAssistantComponent {
1794
1880
  ...message,
1795
1881
  content: progressMessage,
1796
1882
  processingUpdates: [
1797
- ...processingUpdates,
1798
1883
  { ...activity, message: progressMessage },
1799
1884
  ],
1800
1885
  };
@@ -2186,21 +2271,20 @@ class MaxAssistantComponent {
2186
2271
  traceStepKey(messageId, stepId) {
2187
2272
  return `${messageId}:${stepId}`;
2188
2273
  }
2189
- getConversationHistory() {
2274
+ getConversationHistory(question = '') {
2190
2275
  const messages = this.messages();
2191
2276
  const firstUserIndex = messages.findIndex(message => message.role === 'user');
2192
2277
  if (firstUserIndex < 0) {
2193
2278
  return [];
2194
2279
  }
2195
- return messages
2280
+ return this.sessionState.history(messages
2196
2281
  .slice(firstUserIndex)
2197
2282
  .filter(message => !message.isError && !message.isStreaming)
2198
- .slice(-20)
2199
2283
  .map(message => ({
2200
2284
  role: message.role,
2201
- content: message.content.slice(0, 4_000),
2285
+ content: message.content,
2202
2286
  ...(message.capabilityKey ? { capabilityKey: message.capabilityKey } : {})
2203
- }));
2287
+ })), question);
2204
2288
  }
2205
2289
  scrollToLatest() {
2206
2290
  if (this.scrollToLatestTimer) {
@@ -2228,7 +2312,7 @@ class MaxAssistantComponent {
2228
2312
  });
2229
2313
  }
2230
2314
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, deps: [{ token: MaxAssistantService }, { token: MaxAssistantExportService }, { token: MaxAssistantFeedbackService }, { token: MaxAssistantSupportService }, { token: i0.DestroyRef }, { token: MAX_ASSISTANT_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
2231
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAssistantComponent, isStandalone: true, selector: "max-assistant", inputs: { app: "app", assistantApiUrl: "assistantApiUrl", user: "user", context: "context", requestHeaders: "requestHeaders", developerDetailsEnabled: "developerDetailsEnabled" }, outputs: { hostAction: "hostAction", closeRequested: "closeRequested" }, host: { listeners: { "document:keydown.escape": "onDocumentEscape()" } }, viewQueries: [{ propertyName: "messagesViewport", first: true, predicate: ["messagesViewport"], descendants: true }, { propertyName: "composerInput", first: true, predicate: ["composerInput"], descendants: true }, { propertyName: "supportQueryInput", first: true, predicate: ["supportQueryInput"], descendants: true }, { propertyName: "feedbackInput", first: true, predicate: ["feedbackInput"], descendants: true }], ngImport: i0, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError\"\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 <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @for(update of message.processingUpdates; track $index) {\n <div\n class=\"assistant-processing-step\"\n [class.complete]=\"$index < (message.processingUpdates?.length || 0) - 1 || !!message.streamingContent\"\n [class.active]=\"$index === (message.processingUpdates?.length || 0) - 1 && !message.streamingContent\"\n >\n <span class=\"assistant-processing-indicator\" aria-hidden=\"true\">\n @if($index < (message.processingUpdates?.length || 0) - 1 || message.streamingContent) {\n <i class=\"pi pi-check\"></i>\n } @else {\n <i class=\"pi pi-spinner pi-spin\"></i>\n }\n </span>\n <span>{{ update.message }}</span>\n </div>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n <div class=\"assistant-card-metrics\">\n @for(metric of card.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'mediumTime' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n <h3>{{ group.title }}</h3>\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"definition\"\n ></max-agent-shift-card>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation)\"\n ></button>\n </header>\n <div\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel\"\n icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"\n ></button>\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th>SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th>{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th>Actions</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td>{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td>{{ row[column.field] }}</td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending()\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination; as pagination) {\n <footer class=\"assistant-table-pagination\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </footer>\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px 10px;border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:wrap;gap:6px;min-width:150px}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-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;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-step{display:grid;grid-template-columns:18px minmax(0,1fr);gap:9px;align-items:center;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-step.complete{color:color-mix(in srgb,var(--max-muted) 82%,transparent)}.assistant-processing-step.active>span:last-child{background:linear-gradient(100deg,var(--max-muted) 12%,var(--max-accent) 42%,color-mix(in srgb,var(--max-accent) 55%,#a855f7) 52%,var(--max-accent) 62%,var(--max-muted) 88%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-indicator{display:grid;place-items:center;width:18px;height:18px;border-radius:50%;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface));font-size:10px}.assistant-processing-step.complete .assistant-processing-indicator{color:var(--max-success);background:color-mix(in srgb,var(--max-success) 10%,var(--max-surface))}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3{color:var(--max-text);font-size:14px}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:-120% 0}to{background-position:120% 0}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-processing-step.active>span:last-child,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: ChartModule }, { kind: "component", type: i7.UIChart, selector: "p-chart", inputs: ["type", "plugins", "width", "height", "responsive", "ariaLabel", "ariaLabelledBy", "data", "options"], outputs: ["onDataSelect"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i9.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i10.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i11.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: MaxAgentEntityOptionComponent, selector: "max-agent-entity-option", inputs: ["entity", "disabled"], outputs: ["selected"] }, { kind: "component", type: MaxAgentShiftCardComponent, selector: "max-agent-shift-card", inputs: ["shift", "variant"] }, { kind: "pipe", type: i13.DatePipe, name: "date" }, { kind: "pipe", type: MaxAssistantMarkdownPipe, name: "maxAssistantMarkdown" }] });
2315
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: MaxAssistantComponent, isStandalone: true, selector: "max-assistant", inputs: { app: "app", assistantApiUrl: "assistantApiUrl", user: "user", context: "context", requestHeaders: "requestHeaders", developerDetailsEnabled: "developerDetailsEnabled" }, outputs: { hostAction: "hostAction", closeRequested: "closeRequested" }, host: { listeners: { "window:pagehide": "onPageHide()", "document:keydown.escape": "onDocumentEscape()" } }, viewQueries: [{ propertyName: "messagesViewport", first: true, predicate: ["messagesViewport"], descendants: true }, { propertyName: "composerInput", first: true, predicate: ["composerInput"], descendants: true }, { propertyName: "supportQueryInput", first: true, predicate: ["supportQueryInput"], descendants: true }, { propertyName: "feedbackInput", first: true, predicate: ["feedbackInput"], descendants: true }], ngImport: i0, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError && !message.isOffline && !message.isAccessUnavailable\"\n [class.streaming]=\"message.isStreaming\"\n [attr.aria-live]=\"message.isStreaming ? 'polite' : null\"\n [attr.aria-busy]=\"message.isStreaming || null\"\n [attr.role]=\"message.isStreaming ? 'status' : null\"\n >\n @if(message.isAccessUnavailable) {\n <section class=\"assistant-offline assistant-access-unavailable\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.accessUnavailableTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"52\" ry=\"6\" />\n <path class=\"offline-cloud-body\" d=\"M100 16 151 36v39c0 31-24 49-51 61-27-12-51-30-51-61V36Z\" />\n <path d=\"M84 73V60a16 16 0 0 1 32 0v13\" />\n <path class=\"offline-plug\" d=\"M77 73h46v37H77Z\" />\n <path d=\"M100 86v11\" />\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isOffline) {\n <section class=\"assistant-offline\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.offlineTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"61\" ry=\"6\" />\n <g class=\"offline-cloud\">\n <path class=\"offline-cloud-body\" d=\"M61 86a23 23 0 0 1-3-46 32 32 0 0 1 61-9 27 27 0 0 1 20 55Z\" />\n <path class=\"offline-face\" d=\"M80 58q5 4 10 0m18 0q5 4 10 0M95 72h9\" />\n </g>\n <g class=\"offline-plug-left\">\n <path class=\"offline-cable\" d=\"M25 98v7q0 11 11 11h20\" />\n <path class=\"offline-plug\" d=\"M56 107h15v18H56q-5 0-5-5v-8q0-5 5-5Z\" />\n <path class=\"offline-cable\" d=\"M71 111h8m-8 10h8\" />\n </g>\n <g class=\"offline-plug-right\">\n <path class=\"offline-cable\" d=\"M174 98v7q0 11-11 11h-20\" />\n <path class=\"offline-plug\" d=\"M143 107h-15v18h15q5 0 5-5v-8q0-5-5-5Z\" />\n <path class=\"offline-cable\" d=\"M132 113v6\" />\n </g>\n <g class=\"offline-disconnected\" aria-hidden=\"true\">\n <path d=\"m101 105-5 22m-9-23-3-5m29 5 3-5\" />\n </g>\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isStreaming && !message.displayResponse && !message.cards?.length) {\n <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @if(!message.streamingContent) {\n <p class=\"assistant-processing-update active\">\n <span class=\"assistant-processing-sparkles\" aria-hidden=\"true\">\n @for (star of ['main', 'upper', 'lower', 'small']; track star) {\n <img\n class=\"assistant-processing-star {{ star }}\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n >\n }\n </span>\n <span>{{ message.content }}</span>\n </p>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n <div class=\"assistant-card-metrics\">\n @for(metric of card.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'mediumTime' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n <h3>{{ group.title }}</h3>\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"definition\"\n ></max-agent-shift-card>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation, chartCanvas)\"\n ></button>\n </header>\n <div\n #chartCanvas\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel\"\n icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"\n ></button>\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th>SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th>{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th>Actions</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td>{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td>{{ row[column.field] }}</td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending()\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination; as pagination) {\n <footer class=\"assistant-table-pagination\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </footer>\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming && !message.isOffline && !message.isAccessUnavailable) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px 10px;border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:wrap;gap:6px;min-width:150px}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-blue: var(--assistant-sparkles-blue, #2563eb);--max-sparkles-purple: var(--assistant-sparkles-purple, #8b5cf6);--max-sparkles-pink: var(--assistant-sparkles-pink, #ec4899);--max-sparkles-gradient: linear-gradient( 90deg, var(--max-sparkles-blue) 0%, var(--max-sparkles-purple) 16.667%, var(--max-sparkles-pink) 33.333%, var(--max-sparkles-blue) 50%, var(--max-sparkles-purple) 66.667%, var(--max-sparkles-pink) 83.333%, var(--max-sparkles-blue) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.assistant-offline{display:grid;justify-items:center;gap:calc(var(--max-header-content-size) / 2);max-width:calc(var(--max-header-action-size) * 10);margin-inline:auto;padding-block:var(--max-header-sparkles-size);text-align:center}.assistant-offline p{margin:0;color:var(--max-muted);line-height:1.6}.assistant-offline p-button{margin-top:calc(var(--max-header-content-size) / 2)}.assistant-offline-art{width:calc(var(--max-header-action-size) * 5);max-width:100%;height:auto;overflow:visible}.assistant-offline-art path{stroke:var(--max-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;fill:none}.assistant-offline-art .offline-shadow{fill:var(--max-border);opacity:.35}.assistant-offline-art .offline-cloud-body{fill:var(--max-surface);stroke:var(--max-border)}.assistant-offline-art .offline-plug{fill:var(--max-surface-soft)}.assistant-offline-art .offline-disconnected path{stroke:var(--max-warning)}.assistant-offline-art .offline-cloud{animation:max-offline-float 4s ease-in-out infinite}.assistant-offline-art .offline-plug-left{animation:max-offline-left 4s ease-in-out infinite}.assistant-offline-art .offline-plug-right{animation:max-offline-right 4s ease-in-out infinite}.assistant-offline-art .offline-disconnected{animation:max-offline-signal 4s ease-in-out infinite}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-update{display:grid;grid-template-columns:var(--max-header-content-size) minmax(0,1fr);gap:9px;align-items:center;margin:0;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-update.active>span:last-child{background:var(--max-sparkles-gradient);width:fit-content;background-size:200% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-sparkles{position:relative;width:var(--max-header-content-size);height:var(--max-header-content-size)}.assistant-processing-star{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transform-origin:47.5% 50%;animation:max-processing-orbit 6s linear infinite}.assistant-processing-star.main{clip-path:polygon(47% 16%,62% 40%,82% 50%,62% 61%,47% 82%,34% 61%,14% 50%,34% 40%);animation:none}.assistant-processing-star.upper{clip-path:inset(6% 7% 60% 61%)}.assistant-processing-star.lower{clip-path:polygon(22.5% 62%,37% 77%,22.5% 91%,7% 77%)}.assistant-processing-star.small{clip-path:inset(64% 22% 21% 65%)}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3{color:var(--max-text);font-size:14px}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-offline-float{0%,to{transform:translateY(0)}50%{transform:translateY(-3%)}}@keyframes max-offline-left{0%,to{transform:translate(0)}50%{transform:translate(-2%)}}@keyframes max-offline-right{0%,to{transform:translate(0)}50%{transform:translate(2%)}}@keyframes max-offline-signal{0%,to{opacity:1}50%{opacity:.4}}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:100% 0}to{background-position:0% 0}}@keyframes max-processing-orbit{to{transform:rotate(360deg)}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-offline-art g,.assistant-processing-update.active>span:last-child,.assistant-processing-star,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ChartModule }, { kind: "component", type: i7.UIChart, selector: "p-chart", inputs: ["type", "plugins", "width", "height", "responsive", "ariaLabel", "ariaLabelledBy", "data", "options"], outputs: ["onDataSelect"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i9.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i10.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i11.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: MaxAgentEntityOptionComponent, selector: "max-agent-entity-option", inputs: ["entity", "disabled"], outputs: ["selected"] }, { kind: "component", type: MaxAgentShiftCardComponent, selector: "max-agent-shift-card", inputs: ["shift", "variant"] }, { kind: "pipe", type: i13.DatePipe, name: "date" }, { kind: "pipe", type: MaxAssistantMarkdownPipe, name: "maxAssistantMarkdown" }] });
2232
2316
  }
2233
2317
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, decorators: [{
2234
2318
  type: Component,
@@ -2245,7 +2329,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2245
2329
  MaxAssistantMarkdownPipe,
2246
2330
  MaxAgentEntityOptionComponent,
2247
2331
  MaxAgentShiftCardComponent,
2248
- ], encapsulation: ViewEncapsulation.Emulated, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError\"\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 <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @for(update of message.processingUpdates; track $index) {\n <div\n class=\"assistant-processing-step\"\n [class.complete]=\"$index < (message.processingUpdates?.length || 0) - 1 || !!message.streamingContent\"\n [class.active]=\"$index === (message.processingUpdates?.length || 0) - 1 && !message.streamingContent\"\n >\n <span class=\"assistant-processing-indicator\" aria-hidden=\"true\">\n @if($index < (message.processingUpdates?.length || 0) - 1 || message.streamingContent) {\n <i class=\"pi pi-check\"></i>\n } @else {\n <i class=\"pi pi-spinner pi-spin\"></i>\n }\n </span>\n <span>{{ update.message }}</span>\n </div>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n <div class=\"assistant-card-metrics\">\n @for(metric of card.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'mediumTime' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n <h3>{{ group.title }}</h3>\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"definition\"\n ></max-agent-shift-card>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation)\"\n ></button>\n </header>\n <div\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel\"\n icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"\n ></button>\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th>SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th>{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th>Actions</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td>{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td>{{ row[column.field] }}</td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending()\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination; as pagination) {\n <footer class=\"assistant-table-pagination\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </footer>\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px 10px;border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:wrap;gap:6px;min-width:150px}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-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;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-step{display:grid;grid-template-columns:18px minmax(0,1fr);gap:9px;align-items:center;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-step.complete{color:color-mix(in srgb,var(--max-muted) 82%,transparent)}.assistant-processing-step.active>span:last-child{background:linear-gradient(100deg,var(--max-muted) 12%,var(--max-accent) 42%,color-mix(in srgb,var(--max-accent) 55%,#a855f7) 52%,var(--max-accent) 62%,var(--max-muted) 88%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-indicator{display:grid;place-items:center;width:18px;height:18px;border-radius:50%;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface));font-size:10px}.assistant-processing-step.complete .assistant-processing-indicator{color:var(--max-success);background:color-mix(in srgb,var(--max-success) 10%,var(--max-surface))}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3{color:var(--max-text);font-size:14px}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:-120% 0}to{background-position:120% 0}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-processing-step.active>span:last-child,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"] }]
2332
+ ], encapsulation: ViewEncapsulation.Emulated, template: "<aside\n class=\"assistant-window\"\n [attr.aria-label]=\"uiCopy.title\"\n role=\"region\"\n>\n <section class=\"assistant-panel\">\n <header class=\"assistant-header\">\n <img\n class=\"max-assistant-sparkles\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n aria-hidden=\"true\"\n >\n <div class=\"assistant-identity\">\n <div class=\"assistant-name-row\">\n <h2 class=\"assistant-name\">\n <img\n class=\"assistant-wordmark\"\n src=\"assets/max/max-ai-wordmark-styled-gradient.png\"\n [alt]=\"uiCopy.title\"\n >\n </h2>\n <span class=\"assistant-beta-tag\">Beta</span>\n </div>\n <span class=\"assistant-subtitle\">{{ uiCopy.subtitle }}</span>\n </div>\n <div class=\"assistant-header-actions\">\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.clearLabel\"\n [pTooltip]=\"uiCopy.clearTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"clearChatSession()\"\n >\n <i class=\"header-action-icon pi pi-refresh\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"header-action\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n [pTooltip]=\"uiCopy.closeTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"requestClose()\"\n >\n <i class=\"header-action-icon pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article\n class=\"message {{ message.role }}\"\n [attr.data-message-id]=\"message.id\"\n [class.welcome-message]=\"isWelcomeMessage(message)\"\n [class.welcome]=\"isWelcomeState(message)\"\n [class.error]=\"message.isError && !message.isOffline && !message.isAccessUnavailable\"\n [class.streaming]=\"message.isStreaming\"\n [attr.aria-live]=\"message.isStreaming ? 'polite' : null\"\n [attr.aria-busy]=\"message.isStreaming || null\"\n [attr.role]=\"message.isStreaming ? 'status' : null\"\n >\n @if(message.isAccessUnavailable) {\n <section class=\"assistant-offline assistant-access-unavailable\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.accessUnavailableTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"52\" ry=\"6\" />\n <path class=\"offline-cloud-body\" d=\"M100 16 151 36v39c0 31-24 49-51 61-27-12-51-30-51-61V36Z\" />\n <path d=\"M84 73V60a16 16 0 0 1 32 0v13\" />\n <path class=\"offline-plug\" d=\"M77 73h46v37H77Z\" />\n <path d=\"M100 86v11\" />\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isOffline) {\n <section class=\"assistant-offline\" role=\"status\" aria-live=\"polite\">\n <svg class=\"assistant-offline-art\" viewBox=\"0 0 200 160\" role=\"img\" [attr.aria-label]=\"uiCopy.offlineTitle\" focusable=\"false\">\n <ellipse class=\"offline-shadow\" cx=\"100\" cy=\"143\" rx=\"61\" ry=\"6\" />\n <g class=\"offline-cloud\">\n <path class=\"offline-cloud-body\" d=\"M61 86a23 23 0 0 1-3-46 32 32 0 0 1 61-9 27 27 0 0 1 20 55Z\" />\n <path class=\"offline-face\" d=\"M80 58q5 4 10 0m18 0q5 4 10 0M95 72h9\" />\n </g>\n <g class=\"offline-plug-left\">\n <path class=\"offline-cable\" d=\"M25 98v7q0 11 11 11h20\" />\n <path class=\"offline-plug\" d=\"M56 107h15v18H56q-5 0-5-5v-8q0-5 5-5Z\" />\n <path class=\"offline-cable\" d=\"M71 111h8m-8 10h8\" />\n </g>\n <g class=\"offline-plug-right\">\n <path class=\"offline-cable\" d=\"M174 98v7q0 11-11 11h-20\" />\n <path class=\"offline-plug\" d=\"M143 107h-15v18h15q5 0 5-5v-8q0-5-5-5Z\" />\n <path class=\"offline-cable\" d=\"M132 113v6\" />\n </g>\n <g class=\"offline-disconnected\" aria-hidden=\"true\">\n <path d=\"m101 105-5 22m-9-23-3-5m29 5 3-5\" />\n </g>\n </svg>\n <p>{{ message.content }}</p>\n <p-button label=\"Continue in Maxtime\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"requestClose()\" />\n </section>\n } @else if(message.isStreaming && !message.displayResponse && !message.cards?.length) {\n <div class=\"assistant-processing\" aria-label=\"Max AI activity\">\n @if(!message.streamingContent) {\n <p class=\"assistant-processing-update active\">\n <span class=\"assistant-processing-sparkles\" aria-hidden=\"true\">\n @for (star of ['main', 'upper', 'lower', 'small']; track star) {\n <img\n class=\"assistant-processing-star {{ star }}\"\n src=\"assets/max/max-assistant-sparkles-styled-gradient.png\"\n alt=\"\"\n >\n }\n </span>\n <span>{{ message.content }}</span>\n </p>\n }\n @if(message.streamingContent) {\n <div class=\"assistant-streaming-answer assistant-markdown\">\n <span class=\"assistant-streaming-answer-text\">{{ message.streamingContent }}</span>\n <span class=\"assistant-streaming-cursor\" aria-hidden=\"true\"></span>\n </div>\n }\n </div>\n } @else if(message.displayResponse; as responseDetails) {\n @if(responseDetails.helpGuide; as guide) {\n <section\n class=\"assistant-help-guide\"\n [class.assistant-information-guide]=\"isContentGuide(guide.kind)\"\n [class.assistant-continuation-guide]=\"guide.continuation\"\n [attr.aria-label]=\"helpGuideLabel(guide.kind)\"\n >\n @if(!guide.continuation) {\n <header class=\"assistant-help-heading\">\n <span class=\"assistant-help-topic-icon\" aria-hidden=\"true\">\n <i [class]=\"helpIcon(guide.icon)\"></i>\n </span>\n <div>\n <span class=\"assistant-help-eyebrow\">\n {{ helpGuideLabel(guide.kind) }}\n </span>\n <h3>{{ guide.title }}</h3>\n </div>\n </header>\n }\n\n @if(guide.summary) {\n <p class=\"assistant-help-summary\">{{ guide.summary }}</p>\n }\n\n @if(guide.content) {\n <div\n class=\"assistant-help-content assistant-information-content assistant-markdown\"\n [innerHTML]=\"guide.content | maxAssistantMarkdown: helpGuideMarkdownVariant(guide.kind)\"\n ></div>\n }\n\n @if(guide.steps.length) {\n <section class=\"assistant-help-section assistant-help-steps\">\n <h4>Steps to follow</h4>\n <ol>\n @for(step of guide.steps; track $index) {\n <li>{{ step }}</li>\n }\n </ol>\n </section>\n }\n\n @if(guide.tips?.length) {\n <aside class=\"assistant-help-callout assistant-help-tips\">\n <i class=\"pi pi-lightbulb\" aria-hidden=\"true\"></i>\n <div>\n <h4>Good to know</h4>\n <ul>\n @for(tip of guide.tips ?? []; track $index) {\n <li>{{ tip }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.restrictions?.length) {\n <aside class=\"assistant-help-callout assistant-help-restrictions\">\n <i class=\"pi pi-info-circle\" aria-hidden=\"true\"></i>\n <div>\n <h4>Keep in mind</h4>\n <ul>\n @for(restriction of guide.restrictions ?? []; track $index) {\n <li>{{ restriction }}</li>\n }\n </ul>\n </div>\n </aside>\n }\n\n @if(guide.accessNote) {\n <p class=\"assistant-help-access\">\n <i class=\"pi pi-lock\" aria-hidden=\"true\"></i>\n <span>{{ guide.accessNote }}</span>\n </p>\n }\n\n @if(guide.navigation; as navigation) {\n <div class=\"assistant-help-navigation-row\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n class=\"assistant-help-navigation\"\n [label]=\"navigation.label\"\n [icon]=\"helpIcon(guide.icon)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(navigation.hostAction)\"\n ></button>\n </div>\n }\n </section>\n } @else if(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) {\n <div\n class=\"assistant-result assistant-markdown\"\n [innerHTML]=\"(responseDetails.markdown || responseDetails.agentInferredResponse || message.content) | maxAssistantMarkdown\"\n ></div>\n }\n @if(message.cards?.length) {\n <div class=\"assistant-cards\">\n @for(card of message.cards ?? []; track $index) {\n <section class=\"assistant-card\">\n <header>\n <span class=\"assistant-card-title\">{{ card.title }}</span>\n @if(card.subtitle) {\n <span class=\"assistant-card-subtitle\">{{ card.subtitle }}</span>\n }\n </header>\n <div class=\"assistant-card-metrics\">\n @for(metric of card.metrics; track metric.label) {\n <div class=\"assistant-card-metric\" [class.assistant-card-metric-wide]=\"isListMetric(metric)\" [attr.data-tone]=\"metric.tone || 'default'\">\n <span class=\"assistant-card-label\">{{ metric.label }}</span>\n <span class=\"assistant-card-value\">{{ metric.value }}</span>\n </div>\n }\n </div>\n @if(card.footer) {\n <footer>{{ card.footer }}</footer>\n }\n </section>\n }\n </div>\n }\n @if(responseDetails.searchResults?.length) {\n <div class=\"assistant-cards assistant-search-results\" aria-label=\"Search results\">\n @for(result of responseDetails.searchResults ?? []; track $index) {\n <section class=\"assistant-card assistant-search-result\">\n <header>\n <i\n class=\"assistant-search-result-icon\"\n [class]=\"searchResultIcon(result.type)\"\n aria-hidden=\"true\"\n ></i>\n <div class=\"assistant-search-result-copy\">\n <strong>{{ result.title }}</strong>\n <span>{{ result.type }}</span>\n </div>\n </header>\n <div class=\"suggestions\" aria-label=\"Available destinations\">\n @for(action of result.actions; track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"action.label\"\n [icon]=\"searchActionIcon(action)\"\n [disabled]=\"isSending()\"\n (click)=\"performHostAction(action.hostAction)\"\n ></button>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(message.pendingAction; as pendingAction) {\n <section class=\"pending-action\" aria-label=\"Cortex action confirmation\">\n <div class=\"pending-action-heading\">\n <strong>Confirmation required</strong>\n <span>{{ pendingAction.method }}</span>\n </div>\n <p>{{ pendingAction.summary }}</p>\n <small>Expires {{ pendingAction.expiresAt | date: 'mediumTime' }}</small>\n @if(message.actionDecision; as actionDecision) {\n <p class=\"action-decision\">\n {{ actionDecision === 'approve' ? 'Approval sent' : 'Rejection sent' }}\n </p>\n } @else {\n <div class=\"pending-action-buttons\">\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"success\"\n label=\"Approve\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'approve')\"\n ></button>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n outlined\n severity=\"secondary\"\n label=\"Reject\"\n [disabled]=\"isSending()\"\n (click)=\"resolvePendingAction(message, 'reject')\"\n ></button>\n </div>\n }\n </section>\n }\n @if(responseDetails.shiftCardGroups?.length) {\n <div class=\"assistant-shift-groups\" aria-label=\"Team shifts\">\n @for(group of responseDetails.shiftCardGroups ?? []; track group.title) {\n <section class=\"assistant-shift-group\">\n <h3>{{ group.title }}</h3>\n <div class=\"assistant-shift-card-grid\">\n @for(shift of group.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"definition\"\n ></max-agent-shift-card>\n }\n </div>\n </section>\n }\n </div>\n }\n @if(responseDetails.rota; as rota) {\n <section class=\"assistant-rota\" [attr.aria-label]=\"rota.title\">\n <div class=\"assistant-rota-heading\">\n <h3>{{ rota.title }}</h3>\n <div class=\"assistant-rota-summary\">\n @if(rota.startDate) {\n <span><small>From</small><strong>{{ rota.startDate }}</strong></span>\n }\n <span><small>Weeks</small><strong>{{ rota.weeksCount }}</strong></span>\n @if(rota.contracted) {\n <span><small>Contracted</small><strong>{{ rota.contracted }}</strong></span>\n }\n @if(rota.autoPublish) {\n <span><small>Auto publish</small><strong>{{ rota.autoPublish }}</strong></span>\n }\n </div>\n </div>\n <div class=\"assistant-rota-scroll\">\n @for(week of rota.weeks; track week.week) {\n <section class=\"assistant-rota-week\">\n <header class=\"assistant-rota-week-heading\">\n <strong>Week {{ week.week }}</strong>\n @if(week.duration) {\n <span>{{ week.duration }}</span>\n }\n </header>\n <div class=\"assistant-rota-week-grid\">\n @for(day of week.days; track day.day) {\n <article class=\"assistant-rota-day\">\n <header>\n <strong>{{ day.label }}</strong>\n @if(day.period) {\n <span>{{ day.period }}</span>\n }\n </header>\n <div class=\"assistant-rota-day-shifts\">\n @for(shift of day.shifts; track shift.id || $index) {\n <max-agent-shift-card\n [shift]=\"shift\"\n variant=\"rota\"\n ></max-agent-shift-card>\n } @empty {\n <span class=\"assistant-rota-empty\">No shifts</span>\n }\n </div>\n </article>\n }\n </div>\n </section>\n } @empty {\n <p class=\"assistant-rota-no-weeks\">No rota weeks were returned.</p>\n }\n </div>\n </section>\n }\n @if(responseDetails.visualisations?.length) {\n <div class=\"assistant-visualisations\">\n @for(visualisation of responseDetails.visualisations ?? []; track visualisation.title) {\n <section class=\"assistant-visualisation\">\n <header class=\"assistant-export-heading\">\n <h3>{{ visualisation.title }}</h3>\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-pdf\"\n icon=\"pi pi-file-pdf\"\n [attr.aria-label]=\"'Export ' + visualisation.title + ' as PDF'\"\n (click)=\"exportVisualisation(visualisation, chartCanvas)\"\n ></button>\n </header>\n <div\n #chartCanvas\n class=\"assistant-chart-canvas\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel(visualisation)\"\n [style.height.px]=\"chartHeight(visualisation)\"\n >\n <p-chart\n class=\"assistant-prime-chart\"\n [type]=\"chartType(visualisation)\"\n [data]=\"chartData(visualisation)\"\n [options]=\"chartOptions(visualisation)\"\n ></p-chart>\n </div>\n </section>\n }\n </div>\n }\n @if(getResponseGrid(responseDetails).length) {\n <div class=\"assistant-tables\">\n @for(table of getResponseGrid(responseDetails); track $index; let tableIndex = $index) {\n <section class=\"assistant-table-section\">\n <header class=\"assistant-export-heading\">\n @if(table.title) {\n <h3>{{ table.title }}</h3>\n }\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-export-action assistant-export-action-excel\"\n icon=\"pi pi-file-excel\"\n [attr.aria-label]=\"'Export ' + (table.title || 'results') + ' to Excel'\"\n (click)=\"exportTable(table)\"\n ></button>\n </header>\n <div class=\"assistant-table-wrap\">\n <table>\n <thead>\n <tr>\n @if(table.pagination) {\n <th>SL. No</th>\n }\n @for(column of table.columns; track column.field) {\n <th>{{ column.header }}</th>\n }\n @if(table.actions?.length) {\n <th>Actions</th>\n }\n </tr>\n </thead>\n <tbody>\n @for(row of table.rows; track $index; let rowIndex = $index) {\n <tr>\n @if(table.pagination) {\n <td>{{ rowIndex + 1 }}</td>\n }\n @for(column of table.columns; track column.field) {\n <td>{{ row[column.field] }}</td>\n }\n @if(table.actions?.length) {\n <td>\n <div class=\"assistant-table-actions\">\n @for(action of getTableRowActions(table, rowIndex); track action.label) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n [severity]=\"action.tone || 'secondary'\"\n [outlined]=\"action.tone === 'danger'\"\n [label]=\"action.label\"\n [disabled]=\"isSending()\"\n (click)=\"useTableAction(action)\"\n ></button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if(table.pagination; as pagination) {\n <footer class=\"assistant-table-pagination\">\n <span>{{ tablePageStatus(table) }}</span>\n @if(hasNextTablePage(table)) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n severity=\"secondary\"\n class=\"assistant-table-page-action\"\n icon=\"pi pi-arrow-down\"\n [label]=\"nextTablePageLabel(pagination)\"\n [loading]=\"isTablePageLoading(message.id, tableIndex)\"\n [disabled]=\"isSending()\"\n (click)=\"retrieveNextTablePage(message, table, tableIndex)\"\n ></button>\n }\n </footer>\n @if(tablePageError(message.id, tableIndex); as pageError) {\n <p class=\"assistant-table-page-error\" role=\"alert\">{{ pageError }}</p>\n }\n }\n </section>\n }\n </div>\n }\n @if(message.sources?.length) {\n <div class=\"assistant-sources\">\n <strong>Sources</strong>\n @for(source of message.sources ?? []; track source.citation) {\n <span>{{ source.citation }}</span>\n }\n </div>\n }\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n @if(isDetailsVisible(message.id)) {\n <div class=\"details-dialog-backdrop\" (click)=\"toggleDetails(message.id)\">\n <section\n class=\"developer-details\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Agent processing details\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"developer-details-header\">\n <div>\n <span class=\"developer-eyebrow\">Developer trace</span>\n <h3>How this request was processed</h3>\n <p>A technical, step-by-step account of routing, inference, tools and results.</p>\n </div>\n <div class=\"details-dialog-actions\">\n <button\n type=\"button\"\n class=\"details-dialog-close\"\n aria-label=\"Close processing details\"\n (click)=\"toggleDetails(message.id)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n @if(message.developerTrace!.run; as run) {\n <section class=\"trace-run-summary\" aria-label=\"Run summary\">\n <div class=\"trace-metric\"><span>Total runtime</span><strong>{{ run.durationMs }} ms</strong></div>\n <div class=\"trace-metric\"><span>Model calls</span><strong>{{ run.llmCalls }}</strong></div>\n <div class=\"trace-metric\"><span>Embedding calls</span><strong>{{ run.embeddingCalls }}</strong></div>\n <div class=\"trace-metric\"><span>API calls</span><strong>{{ run.apiCalls }}</strong></div>\n <div class=\"trace-loop-policy\">\n <div>\n <span>Execution architecture</span>\n <strong>Deterministic step pipeline</strong>\n </div>\n <span class=\"trace-no-loop\">No autonomous model loop</span>\n <p>{{ run.loopPolicy }}</p>\n </div>\n </section>\n }\n\n <ol class=\"workflow-trace\">\n @for(step of message.developerTrace!.steps; track step.id; let stepIndex = $index) {\n <li class=\"workflow-step\" [attr.data-status]=\"traceStepTone(step)\">\n <section class=\"workflow-section\">\n <button\n type=\"button\"\n class=\"workflow-step-toggle\"\n [attr.aria-expanded]=\"isTraceStepExpanded(message.id, step.id)\"\n (click)=\"toggleTraceStep(message.id, step.id)\"\n >\n <div>\n <span class=\"workflow-step-number\">Step {{ stepIndex + 1 }}</span>\n <h4>{{ step.title }}</h4>\n <span class=\"workflow-category\">{{ formatTraceCategory(step.category) }}</span>\n </div>\n <div class=\"workflow-meta\">\n <span class=\"workflow-status\">{{ traceStepStatus(step) }}</span>\n @if(step.durationMs !== undefined) {\n <span>{{ step.durationMs }} ms</span>\n }\n <i\n class=\"pi workflow-expand-icon\"\n [class.pi-chevron-down]=\"isTraceStepExpanded(message.id, step.id)\"\n [class.pi-chevron-right]=\"!isTraceStepExpanded(message.id, step.id)\"\n aria-hidden=\"true\"\n ></i>\n </div>\n </button>\n\n @if(isTraceStepExpanded(message.id, step.id)) {\n <div class=\"workflow-step-content\">\n @if(step.metadata?.summary) {\n <p class=\"workflow-summary\">{{ step.metadata!.summary }}</p>\n }\n\n @if(step.metadata?.technology; as technology) {\n <div class=\"trace-technology\">\n <span class=\"trace-section-label\">Technology</span>\n <div class=\"trace-inline-facts\">\n <span><small>Component</small>{{ technology.component }}</span>\n @if(technology.model) { <span><small>Model</small>{{ technology.model }}</span> }\n @if(technology.library) { <span><small>Library</small>{{ technology.library }}</span> }\n @if(technology.provider) { <span><small>Provider</small>{{ technology.provider }}</span> }\n @if(technology.operation) { <span><small>Operation</small>{{ technology.operation }}</span> }\n </div>\n </div>\n }\n\n @if(step.metadata?.control; as control) {\n <div class=\"trace-control\">\n <div>\n <span class=\"trace-section-label\">Stop control</span>\n <strong>{{ formatTraceLabel(control.mode) }}</strong>\n </div>\n @if(control.maximumIterations !== undefined) {\n <span>{{ control.iterationsUsed ?? 0 }} / {{ control.maximumIterations }} iteration</span>\n }\n <p>{{ control.stopCondition }}</p>\n </div>\n }\n\n @switch(step.category) {\n @case('request') {\n @if(traceField(step.input, 'userQuery'); as userQuery) {\n <div class=\"trace-query\">\n <span>Original user query</span>\n <blockquote>{{ formatTraceScalar(userQuery) }}</blockquote>\n </div>\n }\n <div class=\"trace-card-grid\">\n @for(group of [\n { label: 'Product', value: traceMapField(step.input, 'product') },\n { label: 'User', value: traceMapField(step.input, 'user') },\n { label: 'Request context', value: traceMapField(step.input, 'requestContext') },\n { label: 'Conversation', value: traceMapField(step.input, 'conversation') },\n { label: 'Live API context', value: traceMapField(step.input, 'liveApi') }\n ]; track group.label) {\n @if(group.value) {\n <section class=\"trace-data-card\">\n <h5>{{ group.label }}</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(group.value, group.label === 'User' ? ['permissions'] : []); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n }\n </div>\n }\n\n @case('intent_projection') {\n <div class=\"trace-transform\">\n <div>\n <span>Original query</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'originalUserQuery') ?? traceField(step.input, 'originalUserQuery')) }}</p>\n </div>\n <span class=\"trace-transform-arrow\" aria-hidden=\"true\">\u2192</span>\n <div class=\"trace-transform-result\">\n <span>Generalised intent sent to embedding</span>\n <p>{{ formatTraceScalar(traceField(step.output, 'generalisedIntent') ?? traceField(step.output, 'routingText')) }}</p>\n </div>\n </div>\n @if(traceArrayField(step.output, 'removedArguments').length) {\n <div class=\"trace-section\">\n <span class=\"trace-section-label\">Arguments removed before routing</span>\n <div class=\"trace-entity-list\">\n @for(argument of traceArrayField(step.output, 'removedArguments'); track $index) {\n <span><small>{{ formatTraceScalar(traceField(argument, 'kind')) }}</small>{{ formatTraceScalar(traceField(argument, 'value')) }}</span>\n }\n </div>\n </div>\n }\n }\n\n @case('embedding') {\n <div class=\"trace-query trace-query-compact\">\n <span>Embedded text</span>\n <blockquote>{{ formatTraceScalar(traceField(step.input, 'generalisedIntent')) }}</blockquote>\n </div>\n <div class=\"trace-stat-grid\">\n <div><span>Embedding model</span><strong>{{ formatTraceScalar(traceField(step.output, 'model') ?? traceField(step.input, 'model')) }}</strong></div>\n <div><span>Dimensions</span><strong>{{ formatTraceScalar(traceField(step.output, 'dimensions')) }}</strong></div>\n <div><span>Vector magnitude</span><strong>{{ formatTraceScalar(traceField(step.output, 'vectorMagnitude')) }}</strong></div>\n <div><span>Full vector exposed</span><strong>{{ formatTraceScalar(traceField(step.output, 'fullVectorShown')) }}</strong></div>\n </div>\n @if(traceField(step.output, 'vectorPreview'); as vectorPreview) {\n <div class=\"trace-vector\">\n <span>Vector preview</span>\n <code>{{ formatTraceScalar(vectorPreview) }}</code>\n </div>\n }\n }\n\n @case('capability_routing') {\n @if(traceMapField(step.output, 'routing'); as routing) {\n <div class=\"trace-supabase-call\">\n <div><span>Routing strategy</span><strong>{{ formatTraceScalar(traceField(routing, 'strategy')) }}</strong></div>\n <div><span>Cache status</span><strong>{{ formatTraceScalar(traceField(routing, 'cacheStatus')) }}</strong></div>\n <div><span>Supabase RPC executed</span><strong>{{ formatTraceScalar(traceField(routing, 'supabaseRpcExecuted')) }}</strong></div>\n <div><span>Vector search executed</span><strong>{{ formatTraceScalar(traceField(routing, 'vectorSearchExecuted')) }}</strong></div>\n @if(traceField(routing, 'supabaseRpcExecuted')) {\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(routing, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(routing, 'database')) }}</strong></div>\n @if(traceArrayField(routing, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(routing, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"trace-supabase-call\">\n <div><span>Supabase RPC</span><strong>{{ formatTraceScalar(traceField(step.input, 'rpc')) }}</strong></div>\n <div><span>Database</span><strong>{{ formatTraceScalar(traceField(step.input, 'database')) }}</strong></div>\n @if(traceArrayField(step.input, 'tables').length) {\n <div class=\"trace-table-list\">\n <span>Tables searched</span>\n <div>\n @for(table of traceArrayField(step.input, 'tables'); track $index) {\n <code>{{ formatTraceScalar(table) }}</code>\n }\n </div>\n </div>\n }\n </div>\n }\n @if(traceMapField(step.output, 'decision'); as decision) {\n <section class=\"trace-decision\">\n <span>Routing decision</span>\n <strong>{{ formatTraceScalar(decision['selectedCapabilityLabel'] ?? decision['selectedCapabilityKey']) }}</strong>\n <div>\n <span>Status: {{ formatTraceScalar(decision['status']) }}</span>\n <span>Confidence: {{ formatSimilarity(decision['confidence']) }}</span>\n <span>Runner-up: {{ formatSimilarity(decision['runnerUpConfidence']) }}</span>\n </div>\n </section>\n }\n @if(traceArrayField(step.output, 'matchedCapabilities').length) {\n <div class=\"trace-ranking-wrap\">\n <span class=\"trace-section-label\">Ranked capability matches</span>\n <table class=\"trace-ranking\">\n <thead><tr><th>#</th><th>Capability</th><th>Combined</th><th>Semantic</th><th>Definition</th><th>Example</th><th>Keyword</th></tr></thead>\n <tbody>\n @for(candidate of traceArrayField(step.output, 'matchedCapabilities'); track $index) {\n <tr>\n <td>{{ formatTraceScalar(traceField(candidate, 'rank')) }}</td>\n <td><strong>{{ formatTraceScalar(traceField(candidate, 'label')) }}</strong><code>{{ formatTraceScalar(traceField(candidate, 'capabilityKey')) }}</code></td>\n <td>{{ formatSimilarity(traceField(candidate, 'combinedScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'semanticScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'definitionScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'exampleScore')) }}</td>\n <td>{{ formatSimilarity(traceField(candidate, 'keywordScore')) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n\n @case('argument_extraction') {\n <div class=\"trace-card-grid\">\n @if(traceMapField(step.output, 'selectedCapability') ?? traceMapField(step.input, 'selectedCapability'); as capability) {\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Selected capability</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(capability); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.input, 'tool'); as tool) {\n <section class=\"trace-data-card\">\n <h5>Allowlisted tool</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(tool); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n </div>\n @if(traceMapField(step.output, 'extractedArguments'); as arguments) {\n <section class=\"trace-arguments\">\n <span class=\"trace-section-label\">Arguments extracted from the original query</span>\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(arguments); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n }\n @if(traceMapField(step.output, 'plannedToolCall'); as plannedCall) {\n <div class=\"trace-tool-call\">\n <span>Planned tool call</span>\n <strong>{{ formatTraceScalar(plannedCall['method']) }} \u00B7 {{ formatTraceScalar(plannedCall['toolName']) }}</strong>\n <pre>{{ formatTraceValue(plannedCall['arguments']) }}</pre>\n </div>\n }\n }\n\n @case('api_call') {\n @if(traceField(step.input, 'sql'); as sql) {\n <div class=\"trace-tool-call trace-sql-query\">\n <span>SQL sent to MySQL MCP</span>\n <strong>{{ formatTraceScalar(traceField(step.input, 'toolName')) }}</strong>\n <pre>{{ formatTraceScalar(sql) }}</pre>\n </div>\n }\n @if(traceField(step.input, 'method') || traceField(step.input, 'path')) {\n <div class=\"trace-api-route\">\n <span class=\"trace-http-method\">{{ formatTraceScalar(traceField(step.input, 'method')) }}</span>\n <code>{{ formatTraceScalar(traceField(step.input, 'path')) }}</code>\n @if(getHttpStatus(step); as statusCode) {\n <span class=\"trace-http-status\" [class.success]=\"isHttpSuccessful(step)\" [class.error]=\"!isHttpSuccessful(step)\">\n HTTP {{ statusCode }} \u00B7 {{ isHttpSuccessful(step) ? 'Success' : 'Error' }}\n </span>\n }\n </div>\n }\n <div class=\"trace-payload-grid\">\n @if(traceField(step.input, 'body'); as requestBody) {\n <section><span>Request payload</span><pre>{{ formatTraceValue(requestBody) }}</pre></section>\n }\n @if(traceField(step.output, 'response'); as apiResponse) {\n <section><span>API response</span><pre>{{ formatTraceValue(apiResponse) }}</pre></section>\n }\n @if(traceField(step.input, 'sql') && step.output !== undefined) {\n <section><span>MySQL MCP execution details</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n\n @case('action') {\n <div class=\"trace-card-grid\">\n <section class=\"trace-data-card\">\n <h5>Workflow input</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.input); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n <section class=\"trace-data-card trace-data-card-accent\">\n <h5>Outcome</h5>\n <dl class=\"trace-field-list\">\n @for(entry of traceEntries(step.output); track entry.key) {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n </dl>\n </section>\n </div>\n }\n\n @case('response') {\n @if(traceField(step.output, 'answer'); as answer) {\n <div class=\"trace-query\"><span>Final grounded response</span><blockquote>{{ formatTraceScalar(answer) }}</blockquote></div>\n }\n <dl class=\"trace-argument-grid\">\n @for(entry of traceEntries(step.output); track entry.key) {\n @if(entry.key !== 'answer') {\n <div><dt>{{ entry.label }}</dt><dd>{{ formatTraceScalar(entry.value) }}</dd></div>\n }\n }\n </dl>\n }\n\n @default {\n <div class=\"trace-payload-grid\">\n @if(step.input !== undefined) {\n <section><span>Input</span><pre>{{ formatTraceValue(step.input) }}</pre></section>\n }\n @if(step.output !== undefined) {\n <section><span>Output</span><pre>{{ formatTraceValue(step.output) }}</pre></section>\n }\n </div>\n }\n }\n\n @if(step.error; as error) {\n <div class=\"trace-error\" [class.trace-warning]=\"step.category === 'api_call' && isHttpSuccessful(step)\">\n <strong class=\"trace-error-heading\">\n @if(step.category === 'api_call' && isHttpSuccessful(step)) {\n Post-response processing stopped\n } @else {\n Step stopped@if(error.statusCode) { \u00B7 HTTP {{ error.statusCode }} }\n }\n </strong>\n <strong class=\"trace-error-legacy\" aria-hidden=\"true\">\n Failed@if(error.statusCode) { \u2014 HTTP {{ error.statusCode }} }\n </strong>\n <span>{{ error.message }}</span>\n </div>\n }\n </div>\n }\n </section>\n </li>\n }\n </ol>\n </section>\n </div>\n }\n }\n } @else {\n @if(message.role === 'assistant') {\n <div\n class=\"assistant-markdown\"\n [innerHTML]=\"message.content | maxAssistantMarkdown\"\n ></div>\n @if(isWelcomeState(message) && bootstrapConfig.initialDescription; as initialDescription) {\n <p class=\"welcome-description\">{{ initialDescription }}</p>\n }\n @if(isWelcomeState(message)) {\n <button\n type=\"button\"\n class=\"support-welcome-card\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <span class=\"support-welcome-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <span class=\"support-welcome-copy\">\n <strong>Raise a support ticket</strong>\n <small>Send details directly to our support team.</small>\n </span>\n <i class=\"support-welcome-arrow pi pi-arrow-right\" aria-hidden=\"true\"></i>\n </button>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n @if(hasCapabilitySuggestions(message.suggestions)) {\n <div class=\"capability-options\" aria-label=\"Available Maxtime capabilities\">\n @for(group of capabilitySuggestionGroups(message.suggestions); track group.section) {\n <section class=\"capability-option-section\">\n <h3>{{ group.section }}</h3>\n <div class=\"capability-option-grid\">\n @for(suggestion of group.options; track suggestion.structuredAction?.capabilityKey ?? suggestion.label; let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose capability: ' + suggestion.label\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestion.label }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </section>\n }\n </div>\n } @else if(hasOptionCardSuggestions(message.suggestions, message.status)) {\n <div class=\"clarification-options\" aria-label=\"Clarification options\">\n <div class=\"capability-option-grid clarification-option-grid\">\n @for(suggestion of optionCardSuggestions(message.suggestions, message.status); track suggestionLabel(suggestion); let optionIndex = $index) {\n <button\n pButton\n type=\"button\"\n severity=\"secondary\"\n class=\"capability-option-card clarification-option-card\"\n [disabled]=\"isSending()\"\n [attr.aria-label]=\"'Choose option: ' + suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n >\n <span class=\"capability-option-number\" aria-hidden=\"true\">\n {{ optionIndex + 1 }}\n </span>\n <span class=\"capability-option-copy\">{{ suggestionLabel(suggestion) }}</span>\n <i class=\"pi pi-arrow-right capability-option-arrow\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n } @else if(hasEntitySuggestions(message.suggestions)) {\n <div class=\"entity-options\" aria-label=\"Matching options\">\n @for(suggestion of entitySuggestionOptions(message.suggestions); track suggestion.entity.id ?? suggestion.label) {\n <max-agent-entity-option\n [entity]=\"suggestion.entity\"\n [disabled]=\"isSending()\"\n (selected)=\"useSuggestion(suggestion)\"\n ></max-agent-entity-option>\n }\n </div>\n } @else {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestionLabel(suggestion)\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n }\n @if(message.role === 'assistant' && !isWelcomeMessage(message) && !message.isStreaming && !message.isOffline && !message.isAccessUnavailable) {\n <div class=\"response-actions\">\n <button\n type=\"button\"\n class=\"response-feedback-action\"\n [attr.aria-label]=\"uiCopy.feedbackLabel\"\n [pTooltip]=\"uiCopy.feedbackTooltip\"\n tooltipPosition=\"bottom\"\n (click)=\"openFeedback(message)\"\n >\n <i class=\"pi pi-comment\" aria-hidden=\"true\"></i>\n </button>\n @if(developerDetailsEnabled && message.developerTrace?.steps?.length) {\n <button\n type=\"button\"\n class=\"details-toggle\"\n [attr.aria-expanded]=\"isDetailsVisible(message.id)\"\n (click)=\"toggleDetails(message.id, message.developerTrace!.steps[0]?.id)\"\n >\n {{ isDetailsVisible(message.id) ? 'Hide Developer Trace' : 'Show Developer Trace' }}\n </button>\n }\n </div>\n }\n </article>\n }\n </div>\n\n <footer class=\"assistant-footer\">\n @if(hasConversationStarted()) {\n <button\n type=\"button\"\n class=\"support-ticket-shortcut\"\n aria-label=\"Raise a support ticket\"\n (click)=\"openSupportTicket()\"\n >\n <i class=\"far fa-user-headset\" aria-hidden=\"true\"></i>\n <span>Raise a support ticket</span>\n </button>\n }\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n #composerInput\n pTextarea\n name=\"assistantPrompt\"\n rows=\"1\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </footer>\n </section>\n\n @if(supportTicketVisible()) {\n <section class=\"support-ticket-overlay\" aria-label=\"Support ticket form\">\n <div\n class=\"support-ticket-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"supportTicketTitle\"\n >\n <header class=\"support-ticket-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"far fa-user-headset\"></i>\n </span>\n <div>\n <h2 id=\"supportTicketTitle\">Raise a support ticket</h2>\n <p>Share the details and our support team will take it from here.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close\"\n aria-label=\"Close support ticket form\"\n (click)=\"closeSupportTicket()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(supportTicketSubmissionFailed()) {\n <div class=\"support-ticket-error-page\" role=\"alert\">\n <span class=\"support-ticket-error-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-times-circle\"></i>\n </span>\n <h3>Ticket could not be created</h3>\n <p>{{ supportTicketError() }}</p>\n <button\n pButton\n type=\"button\"\n label=\"Close\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else if(supportTicketResult(); as result) {\n <div class=\"support-ticket-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>Ticket raised</h3>\n <p>{{ result.message }}</p>\n @if(result.ticketReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ result.ticketReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeSupportTicket()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form\" (ngSubmit)=\"submitSupportTicket()\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Name</span>\n <input\n type=\"text\"\n name=\"supportName\"\n autocomplete=\"name\"\n [value]=\"supportTicketForm.name\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Email</span>\n <input\n type=\"email\"\n name=\"supportEmail\"\n autocomplete=\"email\"\n [value]=\"supportTicketForm.email\"\n readonly\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Phone <small>Optional</small></span>\n <input\n type=\"tel\"\n name=\"supportPhone\"\n autocomplete=\"tel\"\n placeholder=\"Add a contact number\"\n [(ngModel)]=\"supportTicketForm.phone\"\n />\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Severity</span>\n <p-select\n inputId=\"supportSeverity\"\n name=\"supportSeverity\"\n [options]=\"supportSeverities()\"\n optionLabel=\"label\"\n [fluid]=\"true\"\n [loading]=\"supportSeverities().length === 0\"\n [(ngModel)]=\"supportTicketForm.severity\"\n >\n <ng-template #selectedItem let-severity>\n <p-tag\n class=\"support-severity-tag\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n <ng-template #item let-severity>\n <p-tag\n class=\"support-severity-option\"\n [value]=\"severity.label\"\n [style.--support-severity-color]=\"supportSeverityColor(severity.color)\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-select>\n </label>\n\n <label class=\"support-ticket-field\">\n <span>Tags</span>\n <p-multiselect\n inputId=\"supportTags\"\n name=\"supportTags\"\n placeholder=\"Select relevant areas\"\n [options]=\"supportTags()\"\n optionLabel=\"label\"\n dataKey=\"id\"\n display=\"chip\"\n [filter]=\"true\"\n filterBy=\"label\"\n [showToggleAll]=\"false\"\n [loading]=\"supportTagsLoading()\"\n [fluid]=\"true\"\n [(ngModel)]=\"supportTicketForm.tags\"\n >\n <ng-template #selecteditems let-selectedTags>\n <span class=\"support-selected-tags\">\n @for(tag of selectedTags; track tag.id) {\n <p-tag\n class=\"support-selected-tag\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n }\n </span>\n </ng-template>\n <ng-template #item let-tag>\n <p-tag\n class=\"support-tag-option\"\n [value]=\"tag.label\"\n [icon]=\"tag.icon\"\n [severity]=\"tag.severity\"\n [rounded]=\"true\"\n ></p-tag>\n </ng-template>\n </p-multiselect>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Subject</span>\n <input\n type=\"text\"\n name=\"supportSubject\"\n maxlength=\"200\"\n placeholder=\"Summarise the issue\"\n required\n [(ngModel)]=\"supportTicketForm.subject\"\n />\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>How can we help?</span>\n <textarea\n #supportQueryInput\n pTextarea\n name=\"supportQuery\"\n rows=\"5\"\n placeholder=\"Describe the issue, what you expected, and anything you've already tried.\"\n required\n [(ngModel)]=\"supportTicketForm.query\"\n ></textarea>\n </label>\n </div>\n\n @if(!supportTicketForm.name || !supportTicketForm.email) {\n <p class=\"support-ticket-notice\" role=\"alert\">\n Your signed-in name and email are required. Please refresh your Nemesys session and try again.\n </p>\n }\n @if(supportTicketError(); as supportError) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ supportError }}</p>\n }\n\n <div class=\"support-ticket-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeSupportTicket()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Submit ticket\"\n icon=\"pi pi-send\"\n [loading]=\"supportTicketSubmitting()\"\n [disabled]=\"!canSubmitSupportTicket()\"\n ></button>\n </div>\n </form>\n }\n </div>\n </section>\n }\n\n @if(feedbackVisible()) {\n <section\n class=\"support-ticket-overlay feedback-overlay\"\n aria-label=\"Feedback form\"\n >\n <div\n class=\"support-ticket-dialog feedback-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"feedbackTitle\"\n >\n <header class=\"support-ticket-header feedback-header\">\n <span class=\"support-ticket-header-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-comment\"></i>\n </span>\n <div>\n <h2 id=\"feedbackTitle\">Help Max improve</h2>\n <p>Tell us what Max could do better.</p>\n </div>\n <button\n type=\"button\"\n class=\"support-ticket-close feedback-close\"\n aria-label=\"Close feedback form\"\n (click)=\"closeFeedback()\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </header>\n\n @if(feedbackResult(); as result) {\n <div class=\"support-ticket-success feedback-success\" role=\"status\">\n <span class=\"support-ticket-success-icon\" aria-hidden=\"true\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3>We value your feedback</h3>\n <p>{{ result.message }}</p>\n @if(result.feedbackReference; as feedbackReference) {\n <div class=\"support-ticket-reference\">\n <span>Reference</span>\n <strong>{{ feedbackReference }}</strong>\n </div>\n }\n <button\n pButton\n type=\"button\"\n label=\"Done\"\n icon=\"pi pi-check\"\n (click)=\"closeFeedback()\"\n ></button>\n </div>\n } @else {\n <form class=\"support-ticket-form feedback-form\" (ngSubmit)=\"submitFeedback()\">\n <div class=\"feedback-form-body\">\n <div class=\"support-ticket-fields\">\n <label class=\"support-ticket-field\">\n <span>Feedback type</span>\n <p-select\n inputId=\"feedbackCategory\"\n name=\"feedbackCategory\"\n [options]=\"feedbackCategoryOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [fluid]=\"true\"\n [(ngModel)]=\"feedbackForm.category\"\n ></p-select>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Your query</span>\n <textarea\n pTextarea\n name=\"feedbackQuery\"\n rows=\"2\"\n placeholder=\"Enter the question or request you gave Max.\"\n readonly\n required\n [(ngModel)]=\"feedbackForm.query\"\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>Assistant response <small>Added automatically when available</small></span>\n <textarea\n pTextarea\n name=\"feedbackAssistantResponse\"\n rows=\"3\"\n placeholder=\"No assistant response is available yet.\"\n [value]=\"feedbackForm.assistantResponse\"\n readonly\n ></textarea>\n </label>\n\n <label class=\"support-ticket-field support-ticket-field-wide\">\n <span>What could be improved?</span>\n <textarea\n #feedbackInput\n pTextarea\n name=\"feedbackDetails\"\n rows=\"3\"\n placeholder=\"Tell us what you expected, what was missing, or how the response could be more useful.\"\n required\n [(ngModel)]=\"feedbackForm.feedback\"\n ></textarea>\n </label>\n </div>\n\n @if(feedbackError(); as error) {\n <p class=\"support-ticket-error\" role=\"alert\">{{ error }}</p>\n }\n </div>\n\n <footer class=\"support-ticket-actions feedback-actions\">\n <button\n pButton\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n outlined\n (click)=\"closeFeedback()\"\n ></button>\n <button\n pButton\n type=\"submit\"\n label=\"Send feedback\"\n icon=\"pi pi-send\"\n [loading]=\"feedbackSubmitting()\"\n [disabled]=\"!canSubmitFeedback()\"\n ></button>\n </footer>\n </form>\n }\n </div>\n </section>\n }\n</aside>\n", styles: [":host{position:relative;display:block;width:100%;height:100%;min-height:0}.assistant-launcher{position:relative;width:64px!important;height:64px!important;min-height:64px!important;padding:7px;border:1px solid rgba(124,58,237,.24)!important;border-radius:22px!important;color:inherit!important;background:radial-gradient(circle at 28% 16%,rgba(255,255,255,.98),transparent 38%),linear-gradient(145deg,#fff7ed,#f5f3ff 52%,#fdf2f8)!important;box-shadow:0 0 0 1px #ffffffd9 inset,0 12px 30px #5b21b62e!important;overflow:visible;transition:border-color .22s ease,box-shadow .22s ease,transform .22s cubic-bezier(.2,.8,.2,1);z-index:2}.assistant-launcher:before,.assistant-launcher:after{content:\"\";position:absolute;top:50%;left:50%;width:22px;height:2px;border-radius:999px;background:#0f6cae;opacity:0;transform:translate(-50%,-50%) scale(.6) rotate(0);transition:opacity .18s ease,transform .22s ease;z-index:1}.assistant-launcher:before{transform:translate(-50%,-50%) scale(.6) rotate(45deg)}.assistant-launcher:after{transform:translate(-50%,-50%) scale(.6) rotate(-45deg)}.assistant-launcher:hover,.assistant-launcher:focus-visible{border-color:#ec489975!important;background:radial-gradient(circle at 30% 18%,#fff,transparent 38%),linear-gradient(145deg,#ffedd5,#ede9fe,#fce7f3)!important;box-shadow:0 0 0 3px #a855f71a,0 16px 34px #6d28d938!important;transform:translateY(-2px)}.assistant-launcher.is-open{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 14px 32px #0f172a2e!important;transform:translateY(0)}.assistant-launcher.is-open:before,.assistant-launcher.is-open:after{opacity:1}.assistant-launcher.is-open:before{transform:translate(-50%,-50%) scale(1) rotate(45deg)}.assistant-launcher.is-open:after{transform:translate(-50%,-50%) scale(1) rotate(-45deg)}.mascot{position:relative;display:inline-grid;width:54px;height:54px;place-items:center;transform-origin:50% 72%;transition:opacity .18s ease,transform .24s ease,filter .24s ease;z-index:0}.mascot-aura{position:absolute;inset:5px;border-radius:50%;background:conic-gradient(from 25deg,#f472b66b,#fbbf2452,#2dd4bf57,#8b5cf66b,#f472b66b);filter:blur(7px);animation:mascot-aura 3s ease-in-out infinite}.mascot-art{position:relative;width:100%;height:100%;overflow:visible;filter:drop-shadow(0 5px 5px rgba(2,75,116,.2));animation:mascot-idle 3.4s ease-in-out infinite}.mascot-shell{fill:#7c3aed}.mascot-ear-left{fill:#ec4899}.mascot-ear-right{fill:#f97316}.mascot-ear{transform-box:fill-box;transform-origin:center}.mascot-face{fill:#211747;stroke:#ffffff4d;stroke-width:1}.mascot-signal{fill:#facc15;stroke:#fff;stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:mascot-signal 2.2s ease-out infinite}.mascot-antenna,.mascot-sparkle,.mascot-shell-shine,.mascot-smile,.mascot-mark{fill:none;stroke-linecap:round;stroke-linejoin:round}.mascot-antenna{stroke:#6d28d9;stroke-width:2.5}.mascot-sparkle{stroke:#ec4899;stroke-width:2;transform-box:fill-box;transform-origin:center;animation:mascot-sparkle 3.4s ease-in-out infinite}.mascot-shell-shine{stroke:#e9d5ffd1;stroke-width:2}.mascot-eye{fill:#5eead4;transform-box:fill-box;transform-origin:center;animation:mascot-blink 5.2s ease-in-out infinite}.mascot-smile{stroke:#fbbf24;stroke-width:2}.mascot-mark{stroke:#ffffffd1;stroke-width:2.2}.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art{animation:mascot-greet .7s cubic-bezier(.2,.8,.2,1)}.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:mascot-ear-wave .7s ease-in-out}.assistant-launcher.is-open .mascot{filter:saturate(1.08);opacity:.24;transform:scale(.82) rotate(-5deg)}.mascot.large{width:52px;height:52px;flex:0 0 auto}@keyframes mascot-idle{0%,to{transform:translateY(0) rotate(0)}50%{transform:translateY(-2px) rotate(1deg)}}@keyframes mascot-greet{0%,to{transform:translateY(0) rotate(0)}35%{transform:translateY(-4px) rotate(-5deg)}65%{transform:translateY(-2px) rotate(4deg)}}@keyframes mascot-ear-wave{0%,to{transform:rotate(0) scaleY(1)}50%{transform:rotate(-12deg) scaleY(1.12)}}@keyframes mascot-blink{0%,45%,49%,to{transform:scaleY(1)}47%{transform:scaleY(.12)}}@keyframes mascot-signal{0%,55%,to{opacity:1;transform:scale(1)}70%{opacity:.55;transform:scale(1.42)}}@keyframes mascot-sparkle{0%,62%,to{opacity:0;transform:scale(.5) rotate(0)}72%{opacity:1;transform:scale(1) rotate(90deg)}84%{opacity:0;transform:scale(.7) rotate(150deg)}}@keyframes mascot-aura{0%,to{opacity:.45;transform:scale(.88)}50%{opacity:.85;transform:scale(1.08)}}.assistant-window{position:relative;width:100%;height:100%;min-height:0;border:1px solid rgba(148,163,184,.24);border-radius:24px;background:#fffffff5;box-shadow:0 24px 70px #0f172a33,0 0 0 1px #ffffffad inset;overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;border-radius:inherit;background:linear-gradient(180deg,#f8fafcd1,#f1f5f9f5),var(--max-canvas, #f8fafc);overflow:hidden}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px 18px;background:#ffffffeb;border-bottom:1px solid rgba(226,232,240,.86)}.assistant-identity{display:grid;gap:5px;min-width:0}.assistant-name{margin:0;width:fit-content;color:var(--max-accent, #2563eb);font:inherit;font-weight:600}.assistant-subtitle{color:#64748b;font-size:10px;font-weight:600;letter-spacing:.1em;line-height:1.2;text-transform:uppercase}.sources span{color:#64748b;font-size:12px;font-weight:600}.assistant-header .header-action:first-of-type{margin-left:auto}.assistant-header .header-action{width:38px;height:38px;margin-left:0;color:#475569;background:transparent}.assistant-header .header-action:hover{background:#0f172a0f}.assistant-messages{min-height:0;overflow:auto;padding:18px;scrollbar-width:thin}.assistant-messages,.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:#cbd5e1 transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar,.assistant-table-wrap::-webkit-scrollbar,.assistant-rota-scroll::-webkit-scrollbar{width:6px;height:6px}.assistant-messages::-webkit-scrollbar-track,.assistant-table-wrap::-webkit-scrollbar-track,.assistant-rota-scroll::-webkit-scrollbar-track{background:transparent}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:#cbd5e1}.message{position:relative;width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:16px;background:#fff;box-shadow:0 1px 2px #0f172a14,0 10px 24px #0f172a0f;-webkit-user-select:text;user-select:text}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--border-color, #e2e8f0);border-bottom-right-radius:6px}.message.user p{color:inherit}.message.error{border-color:var(--danger-color, #dc2626)}.message.streaming{padding:0;border:0;color:var(--text-color-secondary, #64748b);background:transparent;box-shadow:none;font-style:italic}.streaming-progress{background:linear-gradient(100deg,var(--max-muted, #64748b) 20%,var(--primary-color, #2563eb) 42%,#a855f7 50%,var(--primary-color, #2563eb) 58%,var(--max-muted, #64748b) 80%);background-size:220% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;white-space:pre-line;animation:assistant-progress-shimmer 2.2s ease-in-out infinite}@keyframes assistant-progress-shimmer{0%{background-position:120% 0}to{background-position:-20% 0}}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.assistant-cards{display:grid;gap:10px;margin-top:12px}.assistant-card{overflow:hidden;border:1px solid #e2e8f0;border-radius:12px;background:#fff;box-shadow:0 3px 12px #0f172a0d;font-weight:400}.assistant-card>header{display:grid;gap:3px;padding:13px 16px;border-bottom:1px solid #e2e8f0}.assistant-card-title{color:#0f172a;font-size:14px;font-weight:600}.assistant-card-subtitle,.assistant-card>footer{color:#64748b;font-size:12px}.assistant-card-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));padding:16px}.assistant-card-metric{display:grid;min-width:0;align-content:start;gap:5px}.assistant-card-metric-wide{grid-column:1/-1}.assistant-card-label{color:#64748b;font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25}.assistant-card-value{color:#0f172a;font-size:14px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}.assistant-card-metric[data-tone=positive] .assistant-card-value{color:#047857}.assistant-card-metric[data-tone=warning] .assistant-card-value{color:#b45309}.assistant-card :is(strong,b){font-weight:600}.assistant-card>footer{padding:0 16px 14px}:host ::ng-deep .assistant-markdown{line-height:1.45}:host ::ng-deep .assistant-markdown>:first-child{margin-top:0}:host ::ng-deep .assistant-markdown>:last-child{margin-bottom:0}:host ::ng-deep .assistant-markdown p{margin:0 0 8px}:host ::ng-deep .assistant-markdown ul,:host ::ng-deep .assistant-markdown ol{margin:8px 0;padding-left:22px}:host ::ng-deep .assistant-markdown li+li{margin-top:4px}:host ::ng-deep .assistant-markdown strong{font-weight:700}:host ::ng-deep .assistant-markdown code{padding:1px 4px;border-radius:4px;background:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .assistant-markdown a{color:var(--primary-color, #2563eb);text-decoration:underline}.assistant-status{display:inline-flex;margin-top:8px;padding:3px 8px;border-radius:999px;color:#475569;background:#e2e8f0;font-size:11px;font-weight:600;text-transform:capitalize}.pending-action{display:grid;gap:9px;margin-top:12px;padding:12px;border:1px solid #f59e0b;border-radius:12px;background:#fffbeb}.pending-action-heading{display:flex;align-items:center;justify-content:space-between;color:#92400e}.pending-action-heading span{padding:2px 7px;border-radius:999px;color:#78350f;background:#fde68a;font-size:11px;font-weight:700}.pending-action small{color:#78716c}.pending-action-buttons{display:flex;gap:8px}.action-decision{color:#475569;font-weight:600}.assistant-sources{display:grid;gap:4px;margin-top:12px;padding-top:10px;border-top:1px solid #e2e8f0;color:#64748b;font-size:12px}.assistant-shift-groups,.assistant-shift-group{display:grid;gap:10px}.assistant-shift-groups,.assistant-rota{margin-top:12px}.assistant-shift-group h3,.assistant-rota h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-shift-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:9px}.assistant-rota{display:grid;gap:10px}.assistant-rota-heading{display:grid;gap:8px}.assistant-rota-summary{display:flex;flex-wrap:wrap;gap:7px}.assistant-rota-summary>span{display:grid;gap:2px;min-width:86px;padding:7px 9px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc}.assistant-rota-summary small{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.assistant-rota-summary strong{color:#334155;font-size:11px}.assistant-rota-scroll{max-width:100%;overflow-x:auto;border:1px solid #e2e8f0;border-radius:10px;background:#fff}.assistant-rota-week{min-width:1288px}.assistant-rota-week+.assistant-rota-week{border-top:1px solid #cbd5e1}.assistant-rota-week-heading{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;color:#334155;background:#f1f5f9}.assistant-rota-week-heading strong{font-size:12px}.assistant-rota-week-heading span{color:#64748b;font-size:10px}.assistant-rota-week-grid{display:grid;grid-template-columns:repeat(7,minmax(184px,1fr))}.assistant-rota-day{min-width:0;min-height:120px;border-right:1px solid #e2e8f0}.assistant-rota-day:last-child{border-right:0}.assistant-rota-day>header{display:flex;align-items:baseline;justify-content:space-between;padding:7px 8px;border-bottom:1px solid #e2e8f0;color:#334155;background:#f8fafc}.assistant-rota-day>header strong{font-size:10px}.assistant-rota-day>header span{color:#64748b;font-size:9px}.assistant-rota-day-shifts{display:grid;gap:7px;padding:7px}.assistant-rota-empty,.assistant-rota-no-weeks{margin:0;color:#94a3b8;font-size:10px;font-style:italic}.assistant-visualisations{display:grid;gap:10px;margin-top:12px}.assistant-visualisation{display:grid;gap:12px;padding:13px;border:1px solid #dbeafe;border-radius:14px;background:linear-gradient(145deg,#f8fbff,#fff)}.assistant-visualisation h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-export-heading{display:flex;min-width:0;gap:8px;align-items:center}.assistant-export-heading h3{min-width:0}.assistant-export-action{flex:0 0 auto;margin-left:auto;padding:0;color:inherit;background:transparent;border-color:transparent;box-shadow:none}:host ::ng-deep .assistant-export-action .p-button-icon{font-size:20px!important}.assistant-export-action-pdf{color:#d32f2f}.assistant-export-action-excel{color:#217346}.assistant-export-action-pdf:hover{color:#b71c1c;background:transparent;border-color:transparent}.assistant-export-action-excel:hover{color:#185c37;background:transparent;border-color:transparent}.assistant-chart-canvas{position:relative;width:100%;min-height:300px}:host ::ng-deep .assistant-prime-chart,:host ::ng-deep .assistant-prime-chart .p-chart{display:block;width:100%;height:100%}:host ::ng-deep .assistant-prime-chart canvas{width:100%!important;height:100%!important}.assistant-tables{display:grid;gap:10px;margin-top:12px}.assistant-table-section{display:grid;gap:6px}.assistant-table-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.assistant-table-wrap{overflow:auto;max-height:450px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--border-radius, 6px)}.assistant-table-wrap table{width:100%;min-width:420px;border-collapse:collapse;background:#fff}.assistant-table-wrap th,.assistant-table-wrap td{padding:8px 10px;border-bottom:1px solid var(--border-color, #e2e8f0);color:#334155;font-size:12px;line-height:1.35;text-align:left;vertical-align:top}.assistant-table-wrap th{position:sticky;z-index:1;top:0;color:#475569;font-weight:600;background:#f8fafc}.assistant-table-wrap tr:last-child td{border-bottom:0}.assistant-table-actions{display:flex;flex-wrap:wrap;gap:6px;min-width:150px}.assistant-table-pagination{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;color:#64748b;font-size:12px}.assistant-table-page-error{margin:0;color:#b91c1c;font-size:12px}.details-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.details-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.details-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.developer-details{display:grid;gap:12px;margin-top:12px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:10px;background:#f8fafc}.developer-details-header h3,.developer-details-header p{margin:0}.developer-details-header h3{color:#0f172a;font-size:13px;font-weight:600}.developer-details-header p{margin-top:2px;color:#64748b;font-size:11px}.workflow-trace{display:grid;gap:0;margin:0;padding:0;list-style:none}.workflow-step{display:block;min-width:0}.workflow-category{color:#64748b;font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}.workflow-meta{display:grid;flex:0 0 auto;gap:2px;justify-items:end;color:#64748b;font-size:9px}.workflow-status{padding:2px 5px;border-radius:999px;color:#334155;background:#e2e8f0;font-weight:600;text-transform:capitalize}.workflow-step[data-status=succeeded] .workflow-status{color:#166534;background:#dcfce7}.workflow-step[data-status=failed] .workflow-status{color:#991b1b;background:#fee2e2}.trace-json{display:grid;gap:4px;margin-top:8px}.trace-json>span{color:#64748b;font-size:10px;font-weight:600;text-transform:uppercase}.trace-json pre{max-height:280px;margin:0;padding:8px;overflow:auto;border-radius:6px;color:#dbeafe;background:#0f172a;font-size:10px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-error{display:grid;gap:3px;margin-top:8px;padding:8px;border-left:3px solid #dc2626;border-radius:4px;color:#991b1b;background:#fef2f2;font-size:11px}.developer-details-header{display:flex;gap:12px;align-items:flex-start;justify-content:space-between}.developer-eyebrow{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.trace-section-label{color:var(--text-color, #0f172a);font-size:9px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-run-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.trace-metric{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}.trace-metric span,.trace-loop-policy span{color:#64748b;font-size:9px;font-weight:600}.trace-metric strong{color:#0f172a;font-size:13px}.trace-loop-policy{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-column:1/-1;gap:5px 12px;align-items:center;padding:10px;border:1px solid #c7d2fe;border-radius:9px;background:#eef2ff}.trace-loop-policy div{display:grid;gap:2px}.trace-loop-policy strong{color:#312e81;font-size:11px}.trace-loop-policy p{grid-column:1/-1;margin:0;color:#475569;font-size:10px;line-height:1.45}.trace-no-loop{padding:3px 7px;border-radius:999px;color:#166534!important;background:#dcfce7;font-weight:600!important}.workflow-summary{margin:9px 0 0;color:#475569;font-size:10.5px;line-height:1.5}.trace-technology{display:grid;gap:6px;margin-top:10px;padding:8px;border:1px solid #dbeafe;border-radius:7px;background:#f8fbff}.trace-inline-facts{display:flex;flex-wrap:wrap;gap:5px}.trace-inline-facts>span{display:grid;gap:1px;max-width:100%;padding:4px 6px;border-radius:5px;color:#1e293b;background:#fff;font-size:9.5px;overflow-wrap:anywhere}.trace-inline-facts small{color:#64748b;font-size:8px;font-weight:600;text-transform:uppercase}.trace-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 8px;margin-top:8px;padding:8px;border-left:3px solid #8b5cf6;border-radius:5px;background:#f5f3ff}.trace-control>div{display:grid;gap:2px}.trace-control strong,.trace-control>span{color:#5b21b6;font-size:9.5px}.trace-control p{grid-column:1/-1;margin:0;color:#475569;font-size:9.5px;line-height:1.4}.trace-query,.trace-section,.trace-arguments,.trace-ranking-wrap{display:grid;gap:5px;margin-top:10px}.trace-query>span,.trace-transform>div>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-supabase-call span,.trace-decision>span{color:#64748b;font-size:9px;font-weight:600;text-transform:uppercase}.trace-query>span,.trace-vector>span,.trace-payload-grid section>span,.trace-tool-call>span,.trace-decision>span{color:var(--text-color, #0f172a);text-decoration:underline;text-underline-offset:3px}.trace-query blockquote{margin:0;padding:8px 10px;border-left:3px solid #2563eb;border-radius:5px;color:#172554;background:#eff6ff;font-size:11px;font-weight:600;line-height:1.45}.trace-query-compact blockquote{border-color:#8b5cf6;color:#4c1d95;background:#f5f3ff}.trace-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px}.trace-data-card{min-width:0;padding:8px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-data-card-accent{border-color:#bfdbfe;background:#eff6ff}.trace-data-card h5{margin:0 0 5px;color:var(--text-color, #0f172a);font-size:10px;font-weight:600;text-decoration:underline;text-underline-offset:3px}.trace-field-list,.trace-argument-grid{display:grid;gap:4px;margin:0}.trace-field-list>div{display:grid;grid-template-columns:minmax(70px,.7fr) minmax(0,1.3fr);gap:6px}.trace-field-list dt,.trace-argument-grid dt{color:#64748b;font-size:8.5px}.trace-field-list dd,.trace-argument-grid dd{margin:0;color:#1e293b;font-size:9px;font-weight:600;overflow-wrap:anywhere}.trace-transform{display:grid;grid-template-columns:minmax(0,1fr) 18px minmax(0,1fr);gap:6px;align-items:stretch;margin-top:10px}.trace-transform>div{display:grid;gap:5px;padding:9px;border:1px solid #e2e8f0;border-radius:7px;background:#f8fafc}.trace-transform .trace-transform-result{border-color:#bfdbfe;background:#eff6ff}.trace-transform p{margin:0;color:#1e293b;font-size:10px;font-weight:600;line-height:1.4}.trace-transform-arrow{display:grid;place-items:center;color:#2563eb;font-size:16px;font-weight:600}.trace-entity-list{display:flex;flex-wrap:wrap;gap:5px}.trace-entity-list>span{display:flex;gap:5px;align-items:center;padding:4px 7px;border:1px solid #fed7aa;border-radius:999px;color:#9a3412;background:#fff7ed;font-size:9.5px}.trace-entity-list small{color:#c2410c;font-size:7.5px;font-weight:600;text-transform:uppercase}.trace-stat-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:8px}.trace-stat-grid>div{display:grid;gap:2px;padding:7px;border:1px solid #e2e8f0;border-radius:6px}.trace-stat-grid span{color:#64748b;font-size:8.5px}.trace-stat-grid strong{color:#0f172a;font-size:10px;overflow-wrap:anywhere}.trace-vector{display:grid;gap:4px;margin-top:7px}.trace-vector code{padding:7px;overflow:auto;border-radius:5px;color:#c4b5fd;background:#1e1b4b;font-size:8.5px;white-space:nowrap}.trace-supabase-call{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:10px;padding:9px;border:1px solid #a7f3d0;border-radius:7px;background:#ecfdf5}.trace-supabase-call>div{display:grid;gap:2px}.trace-supabase-call strong{color:#065f46;font-size:10px;overflow-wrap:anywhere}.trace-table-list{grid-column:1/-1}.trace-table-list>div{display:flex;flex-wrap:wrap;gap:4px}.trace-table-list code{padding:3px 5px;border-radius:4px;color:#065f46;background:#d1fae5;font-size:8.5px}.trace-decision{display:grid;gap:4px;margin-top:7px;padding:9px;border-left:3px solid #16a34a;border-radius:5px;background:#f0fdf4}.trace-decision strong{color:#14532d;font-size:11px}.trace-decision div{display:flex;flex-wrap:wrap;gap:8px;color:#166534;font-size:8.5px}.trace-ranking-wrap{overflow:auto}.trace-ranking{width:100%;min-width:610px;border-collapse:collapse;font-size:8.5px}.trace-ranking th,.trace-ranking td{padding:6px;border-bottom:1px solid #e2e8f0;color:#475569;text-align:right;vertical-align:top}.trace-ranking th{color:#64748b;background:#f8fafc;font-size:8px;text-transform:uppercase}.trace-ranking th:nth-child(2),.trace-ranking td:nth-child(2){text-align:left}.trace-ranking td:nth-child(2){display:grid;gap:2px;min-width:145px}.trace-ranking strong{color:#1e293b;font-size:9px}.trace-ranking code{color:#64748b;font-size:7.5px}.trace-argument-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:3px}.trace-argument-grid>div{min-width:0;padding:7px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc}.trace-tool-call,.trace-api-route{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;padding:8px;border-radius:6px;color:#dbeafe;background:#0f172a}.trace-tool-call>span{width:100%;color:#94a3b8}.trace-tool-call strong{color:#bfdbfe;font-size:10px}.trace-tool-call pre,.trace-payload-grid pre{width:100%;max-height:220px;margin:0;overflow:auto;color:#dbeafe;font-size:9px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.trace-api-route>code{flex:1 1 180px;color:#e2e8f0;font-size:9px;overflow-wrap:anywhere}.trace-http-method,.trace-http-status{padding:3px 6px;border-radius:4px;color:#fff;background:#2563eb;font-size:8.5px;font-weight:600}.trace-http-status.success{color:#bbf7d0;background:#166534}.trace-http-status.error{color:#fecaca;background:#991b1b}.trace-payload-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin-top:7px}.trace-payload-grid section{display:grid;gap:5px;min-width:0;padding:8px;border:1px solid #334155;border-radius:6px;background:#0f172a}.trace-payload-grid section>span{color:#94a3b8}.trace-error.trace-warning{border-left-color:#f59e0b;color:#92400e;background:#fffbeb}.trace-error-legacy{display:none}.trace-error-heading{font-size:10px}.details-dialog-backdrop{position:fixed;inset:0;z-index:20;display:grid;padding:14px;place-items:center;background:#0f172a7a;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.details-dialog-backdrop .developer-details{display:block;width:100%;max-height:100%;margin:0;padding:0 14px 14px;overflow:auto;overscroll-behavior:contain;border:0;border-radius:14px;background:#fff;box-shadow:0 24px 70px #0f172a4d}.details-dialog-backdrop .developer-details-header{position:sticky;top:0;z-index:3;margin:0 -14px 14px;padding:14px;border-bottom:1px solid #e2e8f0;background:#fffffff7;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.details-dialog-actions{display:flex;flex:0 0 auto;gap:7px;align-items:center}.details-dialog-close{display:grid;width:30px;height:30px;padding:0;place-items:center;border:1px solid #e2e8f0;border-radius:8px;color:#475569;background:#fff;cursor:pointer}.details-dialog-close:hover{color:#0f172a;background:#f1f5f9}.details-dialog-close:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.details-dialog-backdrop .trace-run-summary{margin-bottom:6px;padding-bottom:14px;border-bottom:1px solid #cbd5e1}.details-dialog-backdrop .trace-metric{padding:0 9px;border:0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-metric:nth-child(4){border-right:0}.details-dialog-backdrop .trace-loop-policy{margin-top:5px;padding:9px 0 0;border:0;border-top:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .workflow-trace{display:block}.details-dialog-backdrop .workflow-step{display:block;border-bottom:1px solid #cbd5e1}.workflow-section{display:block}.workflow-step-toggle{display:flex;gap:14px;align-items:center;justify-content:space-between;width:100%;padding:14px 2px;border:0;color:inherit;background:transparent;font:inherit;text-align:left;cursor:pointer}.workflow-step-toggle:hover{background:#f8fafc}.workflow-step-toggle:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.workflow-step-toggle>div:first-child{display:grid;min-width:0;gap:2px}.workflow-step-toggle h4{margin:0;color:var(--text-color, #0f172a);font-size:12px;font-weight:600;line-height:1.4;text-decoration:underline;text-decoration-color:#94a3b8;text-underline-offset:4px}.workflow-step-number{display:block;color:var(--primary-color, #2563eb);font-size:13px;font-weight:600}.workflow-expand-icon{color:#64748b;font-size:10px}.workflow-step-content{padding:0 2px 16px}.details-dialog-backdrop .workflow-summary{margin-top:0;padding-bottom:10px;border-bottom:1px solid #e2e8f0}.details-dialog-backdrop .trace-technology,.details-dialog-backdrop .trace-control{padding:9px 0;border:0;border-bottom:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop .trace-control{border-left:0}.details-dialog-backdrop .trace-inline-facts>span{padding:0 8px 0 0;border-right:1px solid #e2e8f0;border-radius:0;background:transparent}.details-dialog-backdrop :is(h3,h4,h5,strong,.workflow-status,.trace-section-label,.developer-eyebrow){font-weight:600!important}@media (max-width: 520px){.trace-run-summary,.trace-card-grid,.trace-stat-grid,.trace-payload-grid,.trace-argument-grid,.trace-transform{grid-template-columns:1fr}.trace-transform-arrow{transform:rotate(90deg)}}.suggestions{display:grid;gap:0;margin-top:12px}.entity-options{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:12px}.suggestion-chip{justify-content:flex-start;width:100%;padding:6px 0;border:1px solid transparent;border-radius:999px;color:var(--primary-color, #2563eb);background:transparent;font-weight:600;box-shadow:none;text-align:left;transition:padding .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease}.suggestion-chip:hover{padding:6px 12px;border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-color, #2563eb);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);box-shadow:0 4px 14px #0f172a0f}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:600}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary .detail-label,.json-block .detail-label{color:#64748b;font-size:11px;font-weight:600;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:600;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.assistant-composer{padding:14px 16px 16px;border-top:1px solid rgba(226,232,240,.9);border-bottom:0;box-shadow:0 -10px 30px #0f172a0a}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;border-radius:18px;background:#fff;resize:vertical}.assistant-composer button[type=submit]{width:44px;height:44px;border-radius:16px}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media (prefers-reduced-motion: reduce){.mascot-aura,.mascot-art,.mascot-eye,.mascot-signal,.mascot-sparkle,.assistant-launcher:hover .mascot-art,.assistant-launcher:focus-visible .mascot-art,.assistant-launcher:hover .mascot-ear-right,.assistant-launcher:focus-visible .mascot-ear-right{animation:none}.assistant-launcher,.mascot{transition-duration:.01ms}}@media (max-width: 640px){.assistant-messages{padding:14px}.detail-grid,.entity-options,.assistant-card-metrics{grid-template-columns:1fr}.assistant-card-metric{padding:0}}\n", ":host{--max-accent: var(--max-assistant-accent, #1a73e8);--max-accent-strong: var(--max-assistant-accent-strong, #1557b0);--max-canvas: var(--max-assistant-canvas, #f8f9fa);--max-surface: var(--max-assistant-surface, #ffffff);--max-surface-soft: color-mix(in srgb, var(--max-accent) 6%, var(--max-surface));--max-text: var(--max-assistant-text, #1f1f1f);--max-on-accent: var(--max-assistant-on-accent, #ffffff);--max-muted: var(--max-assistant-muted, #5f6368);--max-border: var(--max-assistant-border, #dfe1e5);--max-success: var(--max-assistant-success, #188038);--max-warning: var(--max-assistant-warning, #b06000);--max-danger: var(--max-assistant-danger, #b3261e);--max-support-text: var(--max-assistant-support-text, #3c4043);--max-control-radius: var(--max-assistant-control-radius, 6px);--max-frame-radius: var(--max-assistant-frame-radius, 0px);--max-sparkles-blue: var(--assistant-sparkles-blue, #2563eb);--max-sparkles-purple: var(--assistant-sparkles-purple, #8b5cf6);--max-sparkles-pink: var(--assistant-sparkles-pink, #ec4899);--max-sparkles-gradient: linear-gradient( 90deg, var(--max-sparkles-blue) 0%, var(--max-sparkles-purple) 16.667%, var(--max-sparkles-pink) 33.333%, var(--max-sparkles-blue) 50%, var(--max-sparkles-purple) 66.667%, var(--max-sparkles-pink) 83.333%, var(--max-sparkles-blue) 100% );--max-header-action-size: 40px;--max-header-content-size: 20px;--max-header-sparkles-size: 30px;--primary-color: var(--max-accent);--primary-color-rgb: var(--max-assistant-accent-rgb, 26, 115, 232);--primary-dark-color: var(--max-accent-strong);--background: var(--max-canvas);--background-color: var(--max-canvas);--panel-background: var(--max-surface);--text-color: var(--max-text);--text-color-secondary: var(--max-muted);--border-color: var(--max-border);--success-color: var(--max-success);--warning-color: var(--max-warning);--error-color: var(--max-danger);--danger-color: var(--max-danger);--border-radius: var(--max-control-radius);position:relative;display:block;width:100%;height:100%;min-height:0;isolation:isolate;color:var(--max-text);font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:400;line-height:normal;text-align:left;color-scheme:light}:host,:host *{box-sizing:border-box}:host button,:host ::ng-deep .p-button-label{text-transform:capitalize}.max-assistant-sparkles{display:block;width:var(--max-header-sparkles-size);height:var(--max-header-sparkles-size);flex:0 0 auto;object-fit:contain}.assistant-window{position:relative;inset:auto;width:100%;height:100%;max-height:none;overflow:hidden;opacity:1;visibility:visible;pointer-events:auto;translate:none;transform:none;border:0;border-radius:var(--max-frame-radius);background:var(--max-canvas);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;transition:none}.assistant-panel{grid-template-rows:72px minmax(0,1fr) auto;color:var(--max-text);background:radial-gradient(circle at 48% 0%,color-mix(in srgb,var(--max-accent) 10%,transparent),transparent 46%),radial-gradient(circle at 92% 72%,color-mix(in srgb,#c58af9 8%,transparent),transparent 38%),linear-gradient(145deg,var(--max-canvas),color-mix(in srgb,var(--max-canvas) 94%,#edf3ff))}.assistant-header{display:flex;gap:10px;align-items:center;padding:0 24px;border:0;border-bottom:1px solid var(--max-border);background:color-mix(in srgb,var(--max-canvas) 88%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}.assistant-header-actions{display:flex;gap:4px;align-items:center;margin-left:auto}.assistant-identity{display:flex;flex-direction:column}.assistant-name{align-self:flex-start;margin:0;line-height:0}.assistant-wordmark{display:block;width:auto;height:var(--max-header-content-size);object-fit:contain}.assistant-subtitle{color:var(--max-muted);font-size:12px;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}.assistant-name-row{display:flex;align-items:center;gap:8px}.assistant-beta-tag{padding:3px 6px;color:var(--max-text-color, #475569);font-size:11px;font-weight:700;line-height:1;background:var(--max-accent-color, #e2e8f0);border-radius:4px}.assistant-header .header-action{display:inline-flex;width:var(--max-header-action-size);min-width:var(--max-header-action-size);height:var(--max-header-action-size);align-items:center;justify-content:center;margin:0;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;line-height:1;cursor:pointer}.assistant-header .header-action-icon{font-size:var(--max-header-content-size);font-weight:400;line-height:1}.assistant-header .header-action:hover{color:var(--max-text);background:var(--max-surface-soft)}.assistant-header .header-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.assistant-messages{width:min(820px,100%);min-height:0;justify-self:center;box-sizing:border-box;padding:44px 28px 32px;overflow-x:hidden;overflow-y:auto;scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-table-wrap,.assistant-rota-scroll{scrollbar-color:color-mix(in srgb,var(--max-muted) 25%,transparent) transparent;scrollbar-width:thin}.assistant-messages::-webkit-scrollbar-thumb,.assistant-table-wrap::-webkit-scrollbar-thumb,.assistant-rota-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--max-muted) 25%,transparent)}.message{width:100%;max-width:100%;box-sizing:border-box;margin:0 0 34px;padding:0;border:0;border-radius:0;color:var(--max-text);background:transparent;box-shadow:none}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:min(76%,640px);margin:0 0 32px auto;padding:13px 18px;border:1px solid var(--max-border);border-radius:18px 18px 6px;color:var(--max-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),color-mix(in srgb,var(--max-accent) 5%,var(--max-surface)));box-shadow:0 1px 2px color-mix(in srgb,var(--max-text) 7%,transparent),0 6px 18px color-mix(in srgb,var(--max-accent) 8%,transparent)}.message.user p{color:inherit;font-size:15px;line-height:1.55}.message.error{padding-left:16px;border-left:3px solid var(--max-danger)}.assistant-offline{display:grid;justify-items:center;gap:calc(var(--max-header-content-size) / 2);max-width:calc(var(--max-header-action-size) * 10);margin-inline:auto;padding-block:var(--max-header-sparkles-size);text-align:center}.assistant-offline p{margin:0;color:var(--max-muted);line-height:1.6}.assistant-offline p-button{margin-top:calc(var(--max-header-content-size) / 2)}.assistant-offline-art{width:calc(var(--max-header-action-size) * 5);max-width:100%;height:auto;overflow:visible}.assistant-offline-art path{stroke:var(--max-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;fill:none}.assistant-offline-art .offline-shadow{fill:var(--max-border);opacity:.35}.assistant-offline-art .offline-cloud-body{fill:var(--max-surface);stroke:var(--max-border)}.assistant-offline-art .offline-plug{fill:var(--max-surface-soft)}.assistant-offline-art .offline-disconnected path{stroke:var(--max-warning)}.assistant-offline-art .offline-cloud{animation:max-offline-float 4s ease-in-out infinite}.assistant-offline-art .offline-plug-left{animation:max-offline-left 4s ease-in-out infinite}.assistant-offline-art .offline-plug-right{animation:max-offline-right 4s ease-in-out infinite}.assistant-offline-art .offline-disconnected{animation:max-offline-signal 4s ease-in-out infinite}.message.streaming{display:block;padding:0;color:var(--max-muted);background:transparent;font-style:normal}.message.streaming:before{content:none}.assistant-processing{display:grid;gap:9px;width:min(100%,620px)}.assistant-processing-update{display:grid;grid-template-columns:var(--max-header-content-size) minmax(0,1fr);gap:9px;align-items:center;margin:0;color:var(--max-muted);font-size:14px;line-height:1.45;transition:color .16s ease}.assistant-processing-update.active>span:last-child{background:var(--max-sparkles-gradient);width:fit-content;background-size:200% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:max-processing-progress 2s linear infinite}.assistant-processing-sparkles{position:relative;width:var(--max-header-content-size);height:var(--max-header-content-size)}.assistant-processing-star{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transform-origin:47.5% 50%;animation:max-processing-orbit 6s linear infinite}.assistant-processing-star.main{clip-path:polygon(47% 16%,62% 40%,82% 50%,62% 61%,47% 82%,34% 61%,14% 50%,34% 40%);animation:none}.assistant-processing-star.upper{clip-path:inset(6% 7% 60% 61%)}.assistant-processing-star.lower{clip-path:polygon(22.5% 62%,37% 77%,22.5% 91%,7% 77%)}.assistant-processing-star.small{clip-path:inset(64% 22% 21% 65%)}.assistant-streaming-answer{margin-top:5px;padding-top:12px;border-top:1px solid var(--max-border);color:var(--max-text);white-space:pre-wrap}.assistant-streaming-cursor{display:inline-block;width:2px;height:1em;margin-left:3px;vertical-align:-.12em;background:var(--max-accent);animation:max-streaming-cursor .85s ease-in-out infinite alternate}.message p,.assistant-result,:host ::ng-deep .assistant-markdown{color:var(--max-text);font-size:15px;line-height:1.65}:host ::ng-deep .assistant-markdown code{color:var(--max-text);background:color-mix(in srgb,var(--max-muted) 10%,transparent)}.assistant-help-guide{display:grid;gap:18px;max-width:760px}.assistant-help-heading{display:flex;gap:12px;align-items:center;padding:10px;border:1px solid var(--max-border);border-radius:16px;background:#fff}.assistant-help-topic-icon{display:inline-flex;width:42px;height:42px;flex:0 0 42px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:var(--max-surface-soft);font-size:18px}.assistant-help-heading>div{display:grid;min-width:0;gap:3px}.assistant-help-eyebrow{color:var(--max-muted);font-size:11px;font-weight:700;letter-spacing:.07em;line-height:1;text-transform:uppercase}.assistant-help-heading h3,.assistant-help-section h4,.assistant-help-callout h4{margin:0;color:var(--max-text)}.assistant-help-heading h3{font-size:19px;font-weight:500;letter-spacing:-.015em;line-height:1.25}.assistant-help-summary{margin:-2px 0 0;color:var(--max-text);font-size:15px;line-height:1.6}.assistant-help-content{min-width:0;color:var(--max-text)}:host ::ng-deep .assistant-help-content>:first-child{margin-top:0}:host ::ng-deep .assistant-help-content>:last-child{margin-bottom:0}:host ::ng-deep .assistant-help-content ul{padding-left:22px;list-style:disc}:host ::ng-deep .assistant-help-content ol{padding-left:22px;list-style:decimal}.assistant-information-guide{gap:16px}:host ::ng-deep .assistant-information-content{display:grid;gap:14px}:host ::ng-deep .assistant-information-content>p:first-child{margin:0;padding:13px 15px;border-left:3px solid var(--max-accent);border-radius:4px 10px 10px 4px;background:var(--max-surface-soft);font-weight:500;line-height:1.6}:host ::ng-deep .assistant-information-content h2,:host ::ng-deep .assistant-information-content h3,:host ::ng-deep .assistant-information-content h4{margin:5px 0 -2px;padding-bottom:8px;border-bottom:1px solid var(--max-border);color:var(--max-text);font-size:14px;font-weight:700;line-height:1.35}:host ::ng-deep .assistant-information-content p{margin:0}:host ::ng-deep .assistant-information-content ul,:host ::ng-deep .assistant-information-content ol{display:grid;gap:8px;margin:0;padding-left:0;list-style:none}:host ::ng-deep .assistant-information-content li{position:relative;padding-left:24px;list-style:none;line-height:1.55}:host ::ng-deep .assistant-information-content li>.fa-arrow-right{position:absolute;top:.42em;left:1px;color:var(--max-accent);font-size:11px}.assistant-help-section{display:grid;gap:12px}.assistant-help-section h4{font-size:14px;font-weight:700}.assistant-help-steps h4{padding-bottom:8px;border-bottom:1px solid var(--max-border)}.assistant-help-steps ol{display:grid;gap:10px;margin:0;padding:0;counter-reset:help-step;list-style:none}.assistant-help-steps li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:start;color:var(--max-text);font-size:14px;line-height:1.55;counter-increment:help-step}.assistant-help-steps li:before{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);content:counter(help-step);font-size:12px;font-weight:700;line-height:1}.assistant-help-callout{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;padding:12px 14px;border-left:3px solid color-mix(in srgb,var(--max-accent) 55%,var(--max-border));border-radius:4px 12px 12px 4px;background:color-mix(in srgb,var(--max-accent) 6%,var(--max-surface))}.assistant-help-callout>i{margin-top:2px;color:var(--max-accent);font-size:16px}.assistant-help-callout>div{display:grid;gap:7px}.assistant-help-callout h4{font-size:13px;font-weight:700}.assistant-help-callout ul{display:grid;gap:5px;margin:0}.assistant-help-callout li{color:var(--max-text);font-size:13px;line-height:1.5}.assistant-help-restrictions{border-left-color:color-mix(in srgb,var(--max-warning) 60%,var(--max-border));background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.assistant-help-restrictions>i{color:var(--max-warning)}.assistant-help-access{display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;border-radius:10px;color:var(--max-muted);background:color-mix(in srgb,var(--max-muted) 7%,var(--max-surface));font-size:13px;line-height:1.45}.assistant-help-access i{margin-top:2px;color:var(--max-muted)}.assistant-help-navigation-row{display:flex;align-items:center}:host ::ng-deep .assistant-help-navigation.p-button{width:auto;min-height:38px;padding:8px 13px;border-color:var(--max-accent);border-radius:9px;color:var(--max-on-accent);background:var(--max-accent);box-shadow:0 2px 7px color-mix(in srgb,var(--max-accent) 22%,transparent);font-size:13px;font-weight:600}:host ::ng-deep .assistant-help-navigation.p-button:hover{border-color:var(--max-accent-strong);color:var(--max-on-accent);background:var(--max-accent-strong)}:host ::ng-deep .assistant-help-navigation.p-button .p-button-icon{font-weight:400}.message.welcome{min-height:260px;margin:0;padding-top:clamp(28px,8vh,90px);text-align:center}.message.welcome .assistant-markdown{max-width:650px;margin:0 auto}:host ::ng-deep .message.welcome .assistant-markdown p{margin:0;font-size:clamp(28px,3.2vw,42px);font-weight:500;letter-spacing:-.04em;line-height:1.18}:host ::ng-deep .message.welcome-message .assistant-markdown p{color:var(--max-accent)}.welcome-description{max-width:620px;margin:0 auto!important;margin-top:2rem!important;color:var(--max-text);font-size:16px;line-height:1.6;white-space:pre-line}.support-welcome-card{display:flex;width:min(460px,100%);min-height:70px;gap:13px;align-items:center;margin:22px auto 0;padding:13px 16px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:16px;color:var(--max-support-text);background:linear-gradient(135deg,color-mix(in srgb,var(--max-accent) 10%,var(--max-surface)),var(--max-surface) 58%);box-shadow:0 8px 28px #3c40431a;font:inherit;text-align:left;cursor:pointer;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.support-welcome-card:hover{border-color:color-mix(in srgb,var(--max-accent) 48%,var(--max-border));box-shadow:0 12px 32px #3c404324;transform:translateY(-1px)}.support-welcome-card:focus-visible,.support-ticket-shortcut:focus-visible,.support-ticket-close:focus-visible,.response-feedback-action:focus-visible{outline:2px solid var(--max-accent);outline-offset:2px}.support-welcome-icon,.support-ticket-header-icon,.support-ticket-success-icon{display:inline-flex;width:40px;height:40px;flex:0 0 40px;align-items:center;justify-content:center;border-radius:13px;color:var(--max-accent);background:color-mix(in srgb,var(--max-accent) 13%,var(--max-surface));font-size:18px}.support-welcome-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:5px}.support-welcome-copy strong{color:var(--max-support-text);font-size:15px;font-weight:600;line-height:1.25}.support-welcome-copy small{color:var(--max-muted);font-size:12px;line-height:1.45}.support-welcome-arrow{flex:0 0 auto;color:var(--max-accent);font-size:16px}@media (min-width: 641px) and (max-height: 850px){.message.welcome{min-height:0;padding-top:22px;padding-bottom:22px}:host ::ng-deep .message.welcome .assistant-markdown p{font-size:clamp(24px,3vw,34px)}.welcome-description{margin-top:1rem!important;font-size:14px;line-height:1.45}.support-welcome-card{min-height:58px;margin-top:14px;padding:10px 13px}}.assistant-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-card{overflow:hidden;border:1px solid var(--max-border);border-radius:18px;background:var(--max-surface);box-shadow:none}.assistant-card>header{gap:4px;padding:16px;border-bottom:1px solid var(--max-border)}.assistant-card>header strong{color:var(--max-text);font-size:15px;font-weight:600}.assistant-card>header span,.assistant-card>footer,.assistant-card-metric span{color:var(--max-muted)}.assistant-card-metric{padding:14px;border-color:var(--max-border)}.assistant-card-metric strong{color:var(--max-text);font-size:10px}.assistant-card-metric[data-tone=positive] strong{color:var(--max-success)}.assistant-card-metric[data-tone=warning] strong{color:var(--max-warning)}.assistant-card>footer{padding:10px 16px;border-color:var(--max-border);background:var(--max-surface-soft)}.assistant-search-result>header{display:flex;gap:12px;align-items:center}.assistant-search-result-icon{display:inline-flex;width:36px;height:36px;flex:0 0 36px;align-items:center;justify-content:center;border-radius:12px;color:var(--max-accent);background:var(--max-surface-soft);font-size:16px;font-weight:400;line-height:1}.assistant-search-result-copy{display:grid;min-width:0;gap:4px}.assistant-search-result .suggestions{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;margin:0;padding:16px}.assistant-search-result .suggestion-chip{width:100%;min-height:44px;align-items:center;justify-content:flex-start;padding:10px 14px;border-color:var(--max-border);background:var(--max-surface-soft);line-height:1.25}.assistant-search-result .suggestion-chip:hover{padding:10px 14px;background:color-mix(in srgb,var(--max-accent) 10%,var(--max-surface))}:host ::ng-deep .assistant-search-result .suggestion-chip .p-button-icon{font-weight:400;line-height:1}.assistant-status{margin-top:12px;padding:0;border-radius:0;color:var(--max-muted);background:transparent;font-size:11px;letter-spacing:.05em;text-transform:uppercase}.pending-action{gap:12px;margin-top:18px;padding:18px;border:1px solid color-mix(in srgb,var(--max-warning) 38%,var(--max-border));border-radius:18px;background:color-mix(in srgb,var(--max-warning) 6%,var(--max-surface))}.pending-action-heading{color:var(--max-text)}.pending-action-heading span{color:var(--max-warning);background:transparent}.pending-action small,.action-decision{color:var(--max-muted)}.assistant-sources{margin-top:20px;padding-top:14px;border-color:var(--max-border);color:var(--max-muted)}.assistant-shift-groups,.assistant-rota{margin-top:20px}.assistant-shift-group h3,.assistant-rota h3,.assistant-rota-summary strong,.assistant-rota-week-heading,.assistant-rota-day>header{color:var(--max-text)}.assistant-rota-summary>span,.assistant-rota-scroll{border-color:var(--max-border);background:var(--max-surface)}.assistant-rota-summary small,.assistant-rota-week-heading span,.assistant-rota-day>header span{color:var(--max-muted)}.assistant-rota-week-heading,.assistant-rota-day>header{background:var(--max-surface-soft)}.assistant-rota-week+.assistant-rota-week,.assistant-rota-day,.assistant-rota-day>header{border-color:var(--max-border)}.assistant-visualisations{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:20px}.assistant-visualisation{padding:16px;border-color:var(--max-border);border-radius:18px;background:var(--max-surface)}.assistant-visualisation:only-child{grid-column:1/-1}.assistant-visualisation h3,.assistant-chart-canvas{color:var(--max-text)}.sources span{color:var(--max-muted)}.assistant-tables{gap:18px;margin-top:20px}.assistant-table-section{gap:10px}.assistant-table-section h3{color:var(--max-text);font-size:14px}.assistant-table-wrap{border-color:var(--max-border);border-radius:16px}.assistant-table-wrap table{background:var(--max-surface)}.assistant-table-wrap th,.assistant-table-wrap td{padding:11px 13px;border-color:var(--max-border);color:var(--max-text);font-size:12px}.assistant-table-wrap th{color:var(--max-muted);background:var(--max-surface-soft)}.details-toggle{margin:0 0 0 auto;color:var(--max-accent);font-size:12px;text-decoration:underline;text-underline-offset:3px}.details-toggle:hover{color:var(--max-accent-strong);text-decoration:underline}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.capability-options{display:grid;gap:22px;margin-top:18px}.clarification-options{margin-top:18px}.capability-option-section{display:grid;gap:10px}.capability-option-section h3{margin:0;color:var(--max-text);font-size:14px;font-weight:600}.capability-option-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.capability-option-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;width:100%;min-height:76px;padding:12px 14px;align-items:center;border:1px solid var(--max-border);border-radius:var(--border-radius, 6px);color:var(--max-text);background:var(--max-surface);box-shadow:none;text-align:left}.capability-option-card:hover:not(:disabled){border-color:color-mix(in srgb,var(--max-accent) 32%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.capability-option-number{display:inline-flex;min-width:24px;height:24px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-accent-strong);background:var(--max-surface-soft);font-size:12px;font-weight:600}.capability-option-copy{line-height:1.4}.capability-option-arrow{color:var(--max-muted);font-size:13px}.response-actions{display:flex;align-items:center;margin-top:8px}.response-feedback-action{display:inline-flex;width:32px;height:32px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.response-feedback-action:hover{color:var(--max-accent);background:var(--max-surface-soft)}.suggestion-chip{justify-content:flex-start;width:auto;min-height:40px;padding:8px 14px;border:1px solid var(--max-border);border-radius:14px;color:var(--max-text);background:var(--max-surface);font-weight:400;box-shadow:none;text-align:left}.suggestion-chip:hover{padding:8px 14px;border-color:color-mix(in srgb,var(--max-accent) 28%,var(--max-border));color:var(--max-text);background:var(--max-surface-soft);box-shadow:none}.message.welcome .suggestions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:0}.message.welcome .suggestion-chip{width:100%;min-height:74px;padding:14px 16px;align-items:flex-start;border-radius:18px;line-height:1.35}.message.welcome .suggestion-chip:hover{padding:14px 16px;transform:translateY(-1px)}.assistant-footer{display:flex;width:min(780px,100% - 48px);flex-direction:column;align-items:flex-end;justify-self:center}.support-ticket-shortcut{display:inline-flex;min-height:34px;gap:7px;align-items:center;margin:0 10px 9px 0;padding:7px 12px;appearance:none;border:1px solid color-mix(in srgb,var(--max-accent) 24%,var(--max-border));border-radius:999px;color:var(--max-accent-strong);background:color-mix(in srgb,var(--max-accent) 7%,var(--max-surface));box-shadow:0 2px 8px #3c404314;font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer}.support-ticket-shortcut:hover{border-color:color-mix(in srgb,var(--max-accent) 45%,var(--max-border));background:color-mix(in srgb,var(--max-accent) 11%,var(--max-surface))}.support-ticket-shortcut i{font-size:15px}.assistant-composer{display:flex;width:100%;box-sizing:border-box;gap:8px;align-items:center;margin:0 0 24px;padding:8px 8px 8px 18px;border:1px solid var(--max-border);border-radius:28px;background:var(--max-surface);box-shadow:0 1px 2px #3c404314,0 6px 20px #3c40431a;transition:border-color .16s ease,box-shadow .16s ease}.assistant-composer:focus-within{border-color:color-mix(in srgb,var(--max-accent) 36%,var(--max-border));box-shadow:0 1px 2px #3c404314,0 8px 24px #3c404324}.assistant-composer textarea{flex:1;min-height:44px;height:44px;max-height:132px;box-sizing:border-box;padding:11px 2px;border:0;border-radius:0;outline:0;color:var(--max-text);background:transparent;box-shadow:none;font:inherit;font-size:15px;line-height:22px;resize:none}.assistant-composer textarea::placeholder{color:var(--max-muted);opacity:.84}.assistant-composer textarea:focus{border:0;outline:0;box-shadow:none}.assistant-composer button[type=submit]{width:44px;height:44px;flex:0 0 auto;border-radius:50%;background:var(--max-accent)}.assistant-composer button[type=submit]:disabled{border-color:transparent;color:var(--max-muted);background:transparent;opacity:.5}.support-ticket-overlay{position:absolute;z-index:100;inset:0;display:flex;overflow:auto;align-items:flex-start;justify-content:center;padding:24px;background:#1f1f1f70;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.support-ticket-dialog{position:relative;display:flex;width:min(700px,100%);flex-direction:column;margin:auto 0;border:1px solid var(--max-border);border-radius:22px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 24px 72px #1f1f1f47}.feedback-dialog{max-height:calc(100% - 48px);overflow:hidden}.feedback-dialog .feedback-form{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;overflow:hidden;padding:0}.feedback-header{position:sticky;z-index:2;top:0;flex:0 0 auto;background:var(--max-surface)}.feedback-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feedback-form-body{min-height:0;flex:1 1 auto;padding:18px 22px;overflow-y:auto;overscroll-behavior:contain}.feedback-form .support-ticket-fields{gap:12px 18px}.feedback-form .support-ticket-field{gap:5px}.feedback-form .support-ticket-field textarea{min-height:72px}.feedback-actions{position:sticky;z-index:2;bottom:0;flex:0 0 auto;margin:0;padding:14px 22px;border-top:1px solid var(--max-border);background:var(--max-surface)}.support-ticket-header{display:flex;gap:14px;align-items:center;padding:20px 22px;border-bottom:1px solid var(--max-border)}.support-ticket-header-icon{width:44px;height:44px;flex-basis:44px;border-radius:14px;font-size:19px}.support-ticket-header>div{min-width:0;flex:1}.support-ticket-header h2,.support-ticket-header p,.support-ticket-success h3,.support-ticket-success p{margin:0}.support-ticket-header h2{color:var(--max-support-text);font-size:19px;font-weight:600;line-height:1.3}.support-ticket-header p{margin-top:3px;color:var(--max-muted);font-size:13px;line-height:1.4}.support-ticket-close{display:inline-flex;width:38px;height:38px;flex:0 0 38px;align-items:center;justify-content:center;padding:0;appearance:none;border:0;border-radius:50%;color:var(--max-muted);background:transparent;font:inherit;cursor:pointer}.support-ticket-close:hover{color:var(--max-support-text);background:var(--max-surface-soft)}.support-ticket-form{min-height:0;overflow:visible;padding:22px}.support-ticket-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.support-ticket-field{display:flex;min-width:0;flex-direction:column;gap:7px;color:var(--max-support-text);font-size:13px;font-weight:600}.support-ticket-field>span{display:flex;gap:5px;align-items:baseline}.support-ticket-field>span small{color:var(--max-muted);font-size:11px;font-weight:400}.support-ticket-field-wide{grid-column:1/-1}.support-ticket-field input,.support-ticket-field textarea{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--max-border);border-radius:10px;outline:0;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400;line-height:1.45}.support-ticket-field textarea{min-height:116px;resize:vertical}.support-ticket-field input[readonly],.support-ticket-field textarea[readonly]{color:color-mix(in srgb,var(--max-support-text) 82%,var(--max-muted));background:color-mix(in srgb,var(--max-muted) 6%,var(--max-surface));cursor:default}.support-ticket-field input::placeholder,.support-ticket-field textarea::placeholder{color:var(--max-muted);opacity:.82}.support-ticket-field input:focus,.support-ticket-field textarea:focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select,:host ::ng-deep .support-ticket-dialog .p-multiselect{min-height:44px;border-color:var(--max-border);border-radius:10px;color:var(--max-support-text);background:var(--max-surface);box-shadow:none;font:inherit;font-size:14px;font-weight:400}:host ::ng-deep .support-ticket-dialog .p-select:not(.p-disabled).p-focus,:host ::ng-deep .support-ticket-dialog .p-multiselect:not(.p-disabled).p-focus{border-color:var(--max-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--max-accent) 13%,transparent)}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label,:host ::ng-deep .support-ticket-dialog .p-select-dropdown,:host ::ng-deep .support-ticket-dialog .p-multiselect-dropdown{color:var(--max-support-text);font:inherit;font-size:14px}:host ::ng-deep .support-ticket-dialog .p-select-label,:host ::ng-deep .support-ticket-dialog .p-multiselect-label{display:flex;min-height:42px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-multiselect-label{flex-wrap:wrap;gap:5px;padding-block:5px}:host ::ng-deep .support-selected-tags{display:inline-flex;min-width:0;flex-wrap:wrap;gap:5px;align-items:center}:host ::ng-deep .support-ticket-dialog .p-tag{font-size:12px;font-weight:600}:host ::ng-deep .support-ticket-dialog .support-severity-tag,:host ::ng-deep .support-ticket-dialog .support-severity-option{color:#fff;background:var(--support-severity-color)}:host ::ng-deep .support-ticket-dialog .p-tag-icon{font-size:11px}:host ::ng-deep .support-ticket-dialog .p-select-option,:host ::ng-deep .support-ticket-dialog .p-multiselect-option{color:var(--max-support-text)}:host ::ng-deep .support-ticket-dialog .p-select-overlay,:host ::ng-deep .support-ticket-dialog .p-multiselect-overlay{border-color:var(--max-border);border-radius:12px;color:var(--max-support-text);background:var(--max-surface);box-shadow:0 12px 32px #1f1f1f2e;font:inherit}.support-ticket-notice,.support-ticket-error{margin:16px 0 0;padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.45}.support-ticket-notice{color:var(--max-warning);background:color-mix(in srgb,var(--max-warning) 9%,var(--max-surface))}.support-ticket-error{color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 8%,var(--max-surface))}.support-ticket-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:22px}.support-ticket-success,.support-ticket-error-page{display:flex;min-height:340px;align-items:center;justify-content:center;padding:38px 24px;flex-direction:column;text-align:center}.support-ticket-error-icon{display:inline-flex;width:64px;height:64px;align-items:center;justify-content:center;border-radius:50%;color:var(--max-danger);background:color-mix(in srgb,var(--max-danger) 12%,var(--max-surface))}.support-ticket-error-icon i,.support-ticket-success-icon i{font-size:40px}.support-ticket-error-page h3{margin:18px 0 0;color:var(--max-support-text);font-size:21px}.support-ticket-error-page p{max-width:420px;margin:7px 0 22px;color:var(--max-muted);font-size:14px;line-height:1.5}.support-ticket-success-icon{width:64px;height:64px;flex-basis:64px;border-radius:50%;color:var(--max-success);background:color-mix(in srgb,var(--max-success) 12%,var(--max-surface))}.support-ticket-success>button{margin-top:1rem}.support-ticket-close i{font-size:20px}.support-ticket-success h3{margin-top:18px;color:var(--max-support-text);font-size:21px}.support-ticket-success p{max-width:420px;margin-top:7px;color:var(--max-muted);font-size:14px;line-height:1.5;white-space:pre-line}.support-ticket-reference{display:flex;gap:6px;align-items:center;margin:22px 0;padding:10px 14px;border:1px solid var(--max-border);border-radius:10px;background:var(--max-surface-soft);font-size:13px}.support-ticket-reference span{color:var(--max-muted)}@keyframes max-offline-float{0%,to{transform:translateY(0)}50%{transform:translateY(-3%)}}@keyframes max-offline-left{0%,to{transform:translate(0)}50%{transform:translate(-2%)}}@keyframes max-offline-right{0%,to{transform:translate(0)}50%{transform:translate(2%)}}@keyframes max-offline-signal{0%,to{opacity:1}50%{opacity:.4}}@keyframes max-thinking{0%{opacity:.55;transform:rotate(-8deg) scale(.86)}to{opacity:1;transform:rotate(8deg) scale(1)}}@keyframes max-processing-progress{0%{background-position:100% 0}to{background-position:0% 0}}@keyframes max-processing-orbit{to{transform:rotate(360deg)}}@keyframes max-streaming-cursor{0%{opacity:.25}to{opacity:1}}@media (prefers-reduced-motion: reduce){.assistant-offline-art g,.assistant-processing-update.active>span:last-child,.assistant-processing-star,.assistant-streaming-cursor{animation:none}.suggestion-chip,.capability-option-card,.support-welcome-card{transition:none}}@media (max-width: 900px){.assistant-messages{padding-top:34px}}@media (max-width: 640px){.assistant-panel{grid-template-rows:64px minmax(0,1fr) auto}.assistant-header{padding:0 14px}.assistant-subtitle{display:none}.assistant-messages{padding:26px 18px 20px}.message.welcome{padding-top:24px}.message.welcome .suggestions,.assistant-cards,.assistant-visualisations,.capability-option-grid{grid-template-columns:1fr}.message.welcome .suggestion-chip{min-height:60px}.message.user{max-width:88%}.assistant-composer{width:100%;margin-bottom:12px}.assistant-footer{width:calc(100% - 24px)}.support-ticket-overlay{align-items:start;padding:10px}.support-ticket-dialog{max-height:none;border-radius:16px}.feedback-dialog{max-height:calc(100% - 20px)}.support-ticket-header{padding:16px}.support-ticket-header p{display:none}.feedback-header p{display:block}.feedback-form-body{padding:14px 16px}.feedback-actions{padding:12px 16px}.support-ticket-form{overflow:visible;padding:16px}.support-ticket-fields{grid-template-columns:1fr;gap:14px}.support-ticket-field-wide{grid-column:auto}.support-ticket-actions{flex-direction:column-reverse}.support-ticket-actions button{width:100%}}\n"] }]
2249
2333
  }], ctorParameters: () => [{ type: MaxAssistantService }, { type: MaxAssistantExportService }, { type: MaxAssistantFeedbackService }, { type: MaxAssistantSupportService }, { type: i0.DestroyRef }, { type: undefined, decorators: [{
2250
2334
  type: Inject,
2251
2335
  args: [MAX_ASSISTANT_CONFIG]
@@ -2277,6 +2361,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2277
2361
  type: Output
2278
2362
  }], closeRequested: [{
2279
2363
  type: Output
2364
+ }], onPageHide: [{
2365
+ type: HostListener,
2366
+ args: ['window:pagehide']
2280
2367
  }], onDocumentEscape: [{
2281
2368
  type: HostListener,
2282
2369
  args: ['document:keydown.escape']