max-agent-ui 0.0.37 → 0.0.38

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,7 +841,7 @@ 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…',
844
+ startingMessage: 'Preparing your answer…',
820
845
  errorMessage: 'Maxtime virtual assistant could not be reached. Please try again.',
821
846
  };
822
847
  const ASSISTANT_SEARCH_RESULT_ICONS = {
@@ -852,6 +877,7 @@ class MaxAssistantComponent {
852
877
  supportService;
853
878
  destroyRef;
854
879
  defaultConfig;
880
+ sessionState = new AssistantConversationState();
855
881
  messagesViewport;
856
882
  activeTurnAnchorMessageId;
857
883
  scrollToLatestTimer;
@@ -908,7 +934,26 @@ class MaxAssistantComponent {
908
934
  }
909
935
  ngOnInit() {
910
936
  this.messages.set(this.createDefaultMessages());
937
+ this.destroyRef.onDestroy(() => {
938
+ this.sessionState.reset();
939
+ this.sessionState.resetRequests.complete();
940
+ clearTimeout(this.scrollToLatestTimer);
941
+ });
942
+ }
943
+ ngDoCheck() {
944
+ const configuredUser = typeof this.defaultConfig.user === 'function' ? this.defaultConfig.user() : this.defaultConfig.user;
945
+ const localUser = typeof this.user === 'function' ? this.user() : this.user;
946
+ const user = { ...configuredUser, ...localUser };
947
+ const contextSource = this.context ?? this.defaultConfig.context;
948
+ const context = typeof contextSource === 'function' ? contextSource() : contextSource;
949
+ if (this.sessionState.changedIdentity(JSON.stringify([this.app ?? this.defaultConfig.app,
950
+ user.token, user.version, user.username, user.email, context?.tenantId, context?.organisationId, context?.userId]))) {
951
+ this.clearChatSession();
952
+ }
911
953
  }
954
+ resetSession() { this.clearChatSession(); }
955
+ // Also clears memory if the browser keeps this document in its back/forward cache.
956
+ onPageHide() { this.clearChatSession(); }
912
957
  focusComposer() {
913
958
  this.composerInput?.nativeElement.focus();
914
959
  }
@@ -942,6 +987,7 @@ class MaxAssistantComponent {
942
987
  }
943
988
  }
944
989
  clearChatSession() {
990
+ this.sessionState.reset();
945
991
  this.closeFeedback(false);
946
992
  this.closeSupportTicket(false);
947
993
  this.input.set('');
@@ -960,7 +1006,7 @@ class MaxAssistantComponent {
960
1006
  if (!trimmedMessage || this.isSending()) {
961
1007
  return;
962
1008
  }
963
- const history = this.getConversationHistory();
1009
+ const history = this.getConversationHistory(trimmedMessage);
964
1010
  this.input.set('');
965
1011
  this.appendMessage(this.createMessage('user', trimmedMessage));
966
1012
  const initialProgress = {
@@ -977,14 +1023,25 @@ class MaxAssistantComponent {
977
1023
  this.isSending.set(true);
978
1024
  this.assistantService
979
1025
  .sendMessage(trimmedMessage, this.conversationId(), this.getAssistantConfig(), undefined, history, activity => this.updateStreamingMessage(streamingMessage.id, activity))
980
- .pipe(takeUntilDestroyed(this.destroyRef))
1026
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
981
1027
  .subscribe({
982
1028
  next: response => {
1029
+ this.sessionState.accept(response);
983
1030
  this.conversationId.set(response.conversationId);
984
1031
  this.replaceMessage(streamingMessage.id, this.createAssistantResponseMessage(response, trimmedMessage));
985
1032
  this.isSending.set(false);
986
1033
  },
987
1034
  error: error => {
1035
+ const preview = this.messages().find(message => message.id === streamingMessage.id);
1036
+ if (preview?.displayResponse || preview?.cards?.length) {
1037
+ this.replaceMessage(streamingMessage.id, {
1038
+ ...preview,
1039
+ content: 'The data was retrieved, but the explanation could not be completed.',
1040
+ streamingContent: undefined,
1041
+ });
1042
+ this.isSending.set(false);
1043
+ return;
1044
+ }
988
1045
  this.replaceMessage(streamingMessage.id, {
989
1046
  ...this.createMessage('assistant', this.resolveErrorMessage(error)),
990
1047
  isError: true
@@ -1070,9 +1127,10 @@ class MaxAssistantComponent {
1070
1127
  this.isSending.set(true);
1071
1128
  this.assistantService
1072
1129
  .sendStructuredAction(suggestion.message, suggestion.structuredAction, this.conversationId(), this.getAssistantConfig(), history)
1073
- .pipe(takeUntilDestroyed(this.destroyRef))
1130
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1074
1131
  .subscribe({
1075
1132
  next: response => {
1133
+ this.sessionState.accept(response);
1076
1134
  this.conversationId.set(response.conversationId);
1077
1135
  this.appendMessage(this.createAssistantResponseMessage(response, suggestion.message));
1078
1136
  this.isSending.set(false);
@@ -1108,7 +1166,7 @@ class MaxAssistantComponent {
1108
1166
  this.supportTicketVisible.set(true);
1109
1167
  this.supportService
1110
1168
  .getSupportTags()
1111
- .pipe(takeUntilDestroyed(this.destroyRef))
1169
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1112
1170
  .subscribe({
1113
1171
  next: tags => {
1114
1172
  this.supportTags.set(tags);
@@ -1121,7 +1179,7 @@ class MaxAssistantComponent {
1121
1179
  });
1122
1180
  this.supportService
1123
1181
  .getSupportSeverities()
1124
- .pipe(takeUntilDestroyed(this.destroyRef))
1182
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1125
1183
  .subscribe({
1126
1184
  next: severities => this.supportSeverities.set(severities),
1127
1185
  error: () => this.supportTicketError.set('Severity options could not be loaded. Please try again.')
@@ -1173,8 +1231,8 @@ class MaxAssistantComponent {
1173
1231
  severity,
1174
1232
  tags: this.supportTicketForm.tags.map(({ id, label }) => ({ id, label })),
1175
1233
  app: this.app ?? this.defaultConfig.app ?? 'nemesys'
1176
- }, this.getAssistantConfig())
1177
- .pipe(takeUntilDestroyed(this.destroyRef))
1234
+ }, this.getAssistantConfig(false))
1235
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1178
1236
  .subscribe({
1179
1237
  next: result => {
1180
1238
  this.supportTicketResult.set(result);
@@ -1226,8 +1284,8 @@ class MaxAssistantComponent {
1226
1284
  feedback: this.feedbackForm.feedback.trim(),
1227
1285
  app: this.app ?? this.defaultConfig.app ?? 'nemesys',
1228
1286
  ...(this.conversationId() ? { conversationId: this.conversationId() } : {})
1229
- }, this.getAssistantConfig())
1230
- .pipe(takeUntilDestroyed(this.destroyRef))
1287
+ }, this.getAssistantConfig(false))
1288
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1231
1289
  .subscribe({
1232
1290
  next: result => {
1233
1291
  this.feedbackResult.set(result);
@@ -1290,9 +1348,10 @@ class MaxAssistantComponent {
1290
1348
  return of(response);
1291
1349
  }
1292
1350
  return this.assistantService.confirmAction(response.pendingAction.id, 'approve', response.conversationId, this.getAssistantConfig(), history);
1293
- }), takeUntilDestroyed(this.destroyRef))
1351
+ }), takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1294
1352
  .subscribe({
1295
1353
  next: response => {
1354
+ this.sessionState.accept(response);
1296
1355
  this.conversationId.set(response.conversationId);
1297
1356
  this.appendMessage(this.createAssistantResponseMessage(response, action.message));
1298
1357
  this.isSending.set(false);
@@ -1324,9 +1383,10 @@ class MaxAssistantComponent {
1324
1383
  this.isSending.set(true);
1325
1384
  this.assistantService
1326
1385
  .confirmAction(pendingAction.id, decision, currentConversationId, this.getAssistantConfig(), history)
1327
- .pipe(takeUntilDestroyed(this.destroyRef))
1386
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1328
1387
  .subscribe({
1329
1388
  next: response => {
1389
+ this.sessionState.accept(response);
1330
1390
  this.conversationId.set(response.conversationId);
1331
1391
  this.appendMessage(this.createAssistantResponseMessage(response, userMessage));
1332
1392
  this.isSending.set(false);
@@ -1406,11 +1466,11 @@ class MaxAssistantComponent {
1406
1466
  this.loadingTablePage.set(tableKey);
1407
1467
  this.isSending.set(true);
1408
1468
  this.assistantService
1409
- .retrieveAnalyticsPage(pagination.query, { offset: nextOffset, pageSize: 250 }, this.conversationId(), this.getAssistantConfig(), history)
1410
- .pipe(takeUntilDestroyed(this.destroyRef))
1469
+ .retrieveAnalyticsPage(pagination.query, { offset: nextOffset, pageSize: 100 }, this.conversationId(), this.getAssistantConfig(), history)
1470
+ .pipe(takeUntil(this.sessionState.resetRequests), takeUntilDestroyed(this.destroyRef))
1411
1471
  .subscribe({
1412
1472
  next: response => {
1413
- this.conversationId.set(response.conversationId);
1473
+ // Paging an older table must not replace the active conversational topic.
1414
1474
  this.mergeTablePage(message.id, tableIndex, response, pagination.query);
1415
1475
  this.loadingTablePage.set(undefined);
1416
1476
  this.isSending.set(false);
@@ -1461,8 +1521,8 @@ class MaxAssistantComponent {
1461
1521
  exportTable(table) {
1462
1522
  void this.exportService.exportTableToExcel(table);
1463
1523
  }
1464
- exportVisualisation(visualisation) {
1465
- void this.exportService.exportVisualisationToPdf(visualisation);
1524
+ exportVisualisation(visualisation, visualisationElement) {
1525
+ void this.exportService.exportVisualisationToPdf(visualisation, visualisationElement);
1466
1526
  }
1467
1527
  chartType(visualisation) {
1468
1528
  switch (visualisation.type) {
@@ -1732,8 +1792,10 @@ class MaxAssistantComponent {
1732
1792
  };
1733
1793
  return labels[category] ?? this.formatTraceLabel(category);
1734
1794
  }
1735
- getAssistantConfig() {
1736
- const config = {};
1795
+ getAssistantConfig(includeConversation = true) {
1796
+ const config = includeConversation
1797
+ ? { conversationStateVersion: 1, ...(this.sessionState.token ? { conversationState: this.sessionState.token } : {}) }
1798
+ : {};
1737
1799
  if (this.assistantApiUrl) {
1738
1800
  config.assistantApiUrl = this.assistantApiUrl;
1739
1801
  }
@@ -1777,8 +1839,24 @@ class MaxAssistantComponent {
1777
1839
  return {
1778
1840
  ...message,
1779
1841
  streamingContent: `${message.streamingContent ?? ''}${activity.delta}`,
1842
+ ...(message.displayResponse || message.cards?.length
1843
+ ? { content: `${message.streamingContent ?? ''}${activity.delta}` }
1844
+ : {}),
1845
+ };
1846
+ }
1847
+ if (activity.type === 'data') {
1848
+ messageUpdated = true;
1849
+ return {
1850
+ ...message,
1851
+ ...activity.data,
1852
+ displayResponse: activity.data.displayResponse ?? {},
1853
+ content: message.streamingContent ?? '',
1854
+ processingUpdates: [],
1780
1855
  };
1781
1856
  }
1857
+ if (message.displayResponse || message.cards?.length) {
1858
+ return message;
1859
+ }
1782
1860
  const progressMessage = activity.message.trim();
1783
1861
  if (!progressMessage) {
1784
1862
  return message;
@@ -1794,7 +1872,6 @@ class MaxAssistantComponent {
1794
1872
  ...message,
1795
1873
  content: progressMessage,
1796
1874
  processingUpdates: [
1797
- ...processingUpdates,
1798
1875
  { ...activity, message: progressMessage },
1799
1876
  ],
1800
1877
  };
@@ -2186,21 +2263,20 @@ class MaxAssistantComponent {
2186
2263
  traceStepKey(messageId, stepId) {
2187
2264
  return `${messageId}:${stepId}`;
2188
2265
  }
2189
- getConversationHistory() {
2266
+ getConversationHistory(question = '') {
2190
2267
  const messages = this.messages();
2191
2268
  const firstUserIndex = messages.findIndex(message => message.role === 'user');
2192
2269
  if (firstUserIndex < 0) {
2193
2270
  return [];
2194
2271
  }
2195
- return messages
2272
+ return this.sessionState.history(messages
2196
2273
  .slice(firstUserIndex)
2197
2274
  .filter(message => !message.isError && !message.isStreaming)
2198
- .slice(-20)
2199
2275
  .map(message => ({
2200
2276
  role: message.role,
2201
- content: message.content.slice(0, 4_000),
2277
+ content: message.content,
2202
2278
  ...(message.capabilityKey ? { capabilityKey: message.capabilityKey } : {})
2203
- }));
2279
+ })), question);
2204
2280
  }
2205
2281
  scrollToLatest() {
2206
2282
  if (this.scrollToLatestTimer) {
@@ -2228,7 +2304,7 @@ class MaxAssistantComponent {
2228
2304
  });
2229
2305
  }
2230
2306
  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" }] });
2307
+ 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\"\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 && !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) {\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)}.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-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-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: "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
2308
  }
2233
2309
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MaxAssistantComponent, decorators: [{
2234
2310
  type: Component,
@@ -2245,7 +2321,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2245
2321
  MaxAssistantMarkdownPipe,
2246
2322
  MaxAgentEntityOptionComponent,
2247
2323
  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"] }]
2324
+ ], 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 && !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) {\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)}.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-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-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
2325
  }], ctorParameters: () => [{ type: MaxAssistantService }, { type: MaxAssistantExportService }, { type: MaxAssistantFeedbackService }, { type: MaxAssistantSupportService }, { type: i0.DestroyRef }, { type: undefined, decorators: [{
2250
2326
  type: Inject,
2251
2327
  args: [MAX_ASSISTANT_CONFIG]
@@ -2277,6 +2353,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2277
2353
  type: Output
2278
2354
  }], closeRequested: [{
2279
2355
  type: Output
2356
+ }], onPageHide: [{
2357
+ type: HostListener,
2358
+ args: ['window:pagehide']
2280
2359
  }], onDocumentEscape: [{
2281
2360
  type: HostListener,
2282
2361
  args: ['document:keydown.escape']