@praxisui/ai 8.0.0-beta.31 → 8.0.0-beta.33
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.
- package/README.md +5 -5
- package/fesm2022/praxisui-ai.mjs +497 -429
- package/package.json +11 -10
- /package/{index.d.ts → types/praxisui-ai.d.ts} +0 -0
package/fesm2022/praxisui-ai.mjs
CHANGED
|
@@ -5,50 +5,50 @@ import { throwError, from, Observable, of, BehaviorSubject, tap, map as map$1, c
|
|
|
5
5
|
import { map, catchError, filter, take } from 'rxjs/operators';
|
|
6
6
|
import { HttpClient, HttpParams, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
|
|
7
7
|
import { API_URL } from '@praxisui/core';
|
|
8
|
-
import * as
|
|
9
|
-
import { CommonModule } from '@angular/common';
|
|
10
|
-
import * as
|
|
8
|
+
import * as i1$3 from '@angular/common';
|
|
9
|
+
import { NgTemplateOutlet, DatePipe, JsonPipe, CommonModule } from '@angular/common';
|
|
10
|
+
import * as i3 from '@angular/forms';
|
|
11
11
|
import { FormsModule } from '@angular/forms';
|
|
12
|
-
import * as
|
|
12
|
+
import * as i4 from '@angular/cdk/overlay';
|
|
13
13
|
import { OverlayModule, CdkOverlayOrigin } from '@angular/cdk/overlay';
|
|
14
14
|
import * as i1 from '@angular/material/button';
|
|
15
15
|
import { MatButtonModule } from '@angular/material/button';
|
|
16
|
-
import * as
|
|
16
|
+
import * as i1$2 from '@angular/material/icon';
|
|
17
17
|
import { MatIconModule } from '@angular/material/icon';
|
|
18
|
-
import * as
|
|
18
|
+
import * as i7 from '@angular/material/progress-spinner';
|
|
19
19
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
20
|
-
import * as
|
|
20
|
+
import * as i8 from '@angular/material/tooltip';
|
|
21
21
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
22
|
-
import * as
|
|
22
|
+
import * as i15 from '@angular/material/chips';
|
|
23
23
|
import { MatChipsModule } from '@angular/material/chips';
|
|
24
24
|
import * as i1$1 from '@angular/material/dialog';
|
|
25
25
|
import { MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
|
|
26
|
-
import * as
|
|
26
|
+
import * as i10 from '@angular/material/menu';
|
|
27
27
|
import { MatMenuModule } from '@angular/material/menu';
|
|
28
|
-
import * as
|
|
28
|
+
import * as i5 from '@angular/cdk/a11y';
|
|
29
29
|
import { A11yModule } from '@angular/cdk/a11y';
|
|
30
|
-
import * as
|
|
30
|
+
import * as i9 from '@angular/material/form-field';
|
|
31
31
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
32
|
-
import * as
|
|
32
|
+
import * as i10$1 from '@angular/material/input';
|
|
33
33
|
import { MatInputModule } from '@angular/material/input';
|
|
34
|
-
import * as
|
|
34
|
+
import * as i11 from '@angular/material/select';
|
|
35
35
|
import { MatSelectModule } from '@angular/material/select';
|
|
36
36
|
import * as i4$1 from '@angular/material/snack-bar';
|
|
37
37
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
38
|
-
import * as
|
|
38
|
+
import * as i13 from '@angular/material/expansion';
|
|
39
39
|
import { MatExpansionModule } from '@angular/material/expansion';
|
|
40
|
-
import * as
|
|
40
|
+
import * as i14 from '@angular/material/tabs';
|
|
41
41
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
42
42
|
|
|
43
43
|
class PraxisAi {
|
|
44
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
45
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
44
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAi, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
45
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PraxisAi, isStandalone: true, selector: "lib-praxis-ai", ngImport: i0, template: `
|
|
46
46
|
<p>
|
|
47
47
|
praxis-ai works!
|
|
48
48
|
</p>
|
|
49
49
|
`, isInline: true, styles: [""] });
|
|
50
50
|
}
|
|
51
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAi, decorators: [{
|
|
52
52
|
type: Component,
|
|
53
53
|
args: [{ selector: 'lib-praxis-ai', imports: [], template: `
|
|
54
54
|
<p>
|
|
@@ -592,10 +592,10 @@ class SchemaMinifierService {
|
|
|
592
592
|
return SchemaType.STRING;
|
|
593
593
|
}
|
|
594
594
|
}
|
|
595
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
596
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
595
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SchemaMinifierService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
596
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SchemaMinifierService, providedIn: 'root' });
|
|
597
597
|
}
|
|
598
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
598
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SchemaMinifierService, decorators: [{
|
|
599
599
|
type: Injectable,
|
|
600
600
|
args: [{ providedIn: 'root' }]
|
|
601
601
|
}] });
|
|
@@ -1011,10 +1011,10 @@ class PraxisAiService {
|
|
|
1011
1011
|
isGeminiProvider() {
|
|
1012
1012
|
return this.resolveProvider() === 'gemini';
|
|
1013
1013
|
}
|
|
1014
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1015
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1014
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiService, deps: [{ token: PRAXIS_AI_CONFIG_SOURCE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1015
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiService, providedIn: 'root' });
|
|
1016
1016
|
}
|
|
1017
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1017
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiService, decorators: [{
|
|
1018
1018
|
type: Injectable,
|
|
1019
1019
|
args: [{ providedIn: 'root' }]
|
|
1020
1020
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
@@ -1537,10 +1537,10 @@ class AiBackendApiService {
|
|
|
1537
1537
|
return null;
|
|
1538
1538
|
}
|
|
1539
1539
|
}
|
|
1540
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1541
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1540
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiBackendApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1541
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiBackendApiService, providedIn: 'root' });
|
|
1542
1542
|
}
|
|
1543
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1543
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiBackendApiService, decorators: [{
|
|
1544
1544
|
type: Injectable,
|
|
1545
1545
|
args: [{ providedIn: 'root' }]
|
|
1546
1546
|
}] });
|
|
@@ -1949,10 +1949,10 @@ class AiResponseValidatorService {
|
|
|
1949
1949
|
return true;
|
|
1950
1950
|
}
|
|
1951
1951
|
}
|
|
1952
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1953
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1952
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiResponseValidatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1953
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiResponseValidatorService, providedIn: 'root' });
|
|
1954
1954
|
}
|
|
1955
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1955
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiResponseValidatorService, decorators: [{
|
|
1956
1956
|
type: Injectable,
|
|
1957
1957
|
args: [{ providedIn: 'root' }]
|
|
1958
1958
|
}] });
|
|
@@ -1961,10 +1961,10 @@ class PraxisAssistantTurnOrchestratorService {
|
|
|
1961
1961
|
createController(flow, options = {}) {
|
|
1962
1962
|
return new PraxisAssistantTurnController(flow, options);
|
|
1963
1963
|
}
|
|
1964
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1965
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1964
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantTurnOrchestratorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1965
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantTurnOrchestratorService, providedIn: 'root' });
|
|
1966
1966
|
}
|
|
1967
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1967
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantTurnOrchestratorService, decorators: [{
|
|
1968
1968
|
type: Injectable,
|
|
1969
1969
|
args: [{ providedIn: 'root' }]
|
|
1970
1970
|
}] });
|
|
@@ -2405,10 +2405,10 @@ class PraxisAssistantTurnController {
|
|
|
2405
2405
|
}
|
|
2406
2406
|
|
|
2407
2407
|
class PraxisAssistantSessionRegistryService {
|
|
2408
|
-
sessionsState = signal([], ...(ngDevMode ? [{ debugName: "sessionsState" }] : []));
|
|
2408
|
+
sessionsState = signal([], ...(ngDevMode ? [{ debugName: "sessionsState" }] : /* istanbul ignore next */ []));
|
|
2409
2409
|
sessions = this.sessionsState.asReadonly();
|
|
2410
|
-
activeSession = computed(() => this.sessions().find((session) => session.visibility === 'active') ?? null, ...(ngDevMode ? [{ debugName: "activeSession" }] : []));
|
|
2411
|
-
minimizedSessions = computed(() => this.sessions().filter((session) => session.visibility === 'minimized'), ...(ngDevMode ? [{ debugName: "minimizedSessions" }] : []));
|
|
2410
|
+
activeSession = computed(() => this.sessions().find((session) => session.visibility === 'active') ?? null, ...(ngDevMode ? [{ debugName: "activeSession" }] : /* istanbul ignore next */ []));
|
|
2411
|
+
minimizedSessions = computed(() => this.sessions().filter((session) => session.visibility === 'minimized'), ...(ngDevMode ? [{ debugName: "minimizedSessions" }] : /* istanbul ignore next */ []));
|
|
2412
2412
|
upsertSession(descriptor) {
|
|
2413
2413
|
const normalized = this.normalizeDescriptor(descriptor);
|
|
2414
2414
|
const existing = this.sessionsState().find((session) => session.id === normalized.id);
|
|
@@ -2550,10 +2550,10 @@ class PraxisAssistantSessionRegistryService {
|
|
|
2550
2550
|
: session)
|
|
2551
2551
|
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
2552
2552
|
}
|
|
2553
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2554
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2553
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantSessionRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2554
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantSessionRegistryService, providedIn: 'root' });
|
|
2555
2555
|
}
|
|
2556
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2556
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantSessionRegistryService, decorators: [{
|
|
2557
2557
|
type: Injectable,
|
|
2558
2558
|
args: [{ providedIn: 'root' }]
|
|
2559
2559
|
}] });
|
|
@@ -2878,10 +2878,10 @@ class AssistantHistoryService {
|
|
|
2878
2878
|
}
|
|
2879
2879
|
return `${prefix}-${Math.random().toString(36).slice(2, 10)}`;
|
|
2880
2880
|
}
|
|
2881
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2882
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2881
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AssistantHistoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2882
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AssistantHistoryService, providedIn: 'root' });
|
|
2883
2883
|
}
|
|
2884
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2884
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AssistantHistoryService, decorators: [{
|
|
2885
2885
|
type: Injectable,
|
|
2886
2886
|
args: [{ providedIn: 'root' }]
|
|
2887
2887
|
}] });
|
|
@@ -2892,8 +2892,8 @@ class PraxisAiAssistantConfirmDialogComponent {
|
|
|
2892
2892
|
constructor(data) {
|
|
2893
2893
|
this.data = data;
|
|
2894
2894
|
}
|
|
2895
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2896
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
2895
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantConfirmDialogComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
2896
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PraxisAiAssistantConfirmDialogComponent, isStandalone: true, selector: "praxis-ai-assistant-confirm-dialog", ngImport: i0, template: `
|
|
2897
2897
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|
|
2898
2898
|
<mat-dialog-content>{{ data.message }}</mat-dialog-content>
|
|
2899
2899
|
<mat-dialog-actions align="end">
|
|
@@ -2907,14 +2907,14 @@ class PraxisAiAssistantConfirmDialogComponent {
|
|
|
2907
2907
|
{{ data.confirmLabel }}
|
|
2908
2908
|
</button>
|
|
2909
2909
|
</mat-dialog-actions>
|
|
2910
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type:
|
|
2910
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }] });
|
|
2911
2911
|
}
|
|
2912
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2912
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantConfirmDialogComponent, decorators: [{
|
|
2913
2913
|
type: Component,
|
|
2914
2914
|
args: [{
|
|
2915
2915
|
selector: 'praxis-ai-assistant-confirm-dialog',
|
|
2916
2916
|
standalone: true,
|
|
2917
|
-
imports: [
|
|
2917
|
+
imports: [MatButtonModule, MatDialogModule],
|
|
2918
2918
|
template: `
|
|
2919
2919
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|
|
2920
2920
|
<mat-dialog-content>{{ data.message }}</mat-dialog-content>
|
|
@@ -6668,13 +6668,12 @@ class PraxisAiAssistantComponent {
|
|
|
6668
6668
|
}
|
|
6669
6669
|
return 'Erro ao comunicar com a IA. Tente novamente.';
|
|
6670
6670
|
}
|
|
6671
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
6672
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisAiAssistantComponent, isStandalone: true, selector: "praxis-ai-assistant", inputs: { adapter: "adapter", riskPolicy: "riskPolicy", allowManualPatchEdit: "allowManualPatchEdit", hasBackdrop: "hasBackdrop" }, viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: CdkOverlayOrigin, descendants: true }, { propertyName: "triggerButton", first: true, predicate: ["triggerBtn"], descendants: true, read: ElementRef }, { propertyName: "inputElement", first: true, predicate: ["inputEl"], descendants: true }], ngImport: i0, template: "<!-- Trigger Button -->\n<button \n mat-icon-button \n cdkOverlayOrigin \n #trigger=\"cdkOverlayOrigin\"\n #triggerBtn\n (click)=\"open()\"\n [disabled]=\"isOpen\"\n class=\"ai-trigger-btn\"\n matTooltip=\"Assistente de Configura\u00E7\u00E3o\"\n aria-label=\"Abrir Assistente IA\">\n <mat-icon>auto_awesome</mat-icon>\n</button>\n\n<!-- Overlay Template -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"12\"\n cdkConnectedOverlayPanelClass=\"ai-assistant-overlay-pane\"\n cdkConnectedOverlayBackdropClass=\"ai-assistant-backdrop\"\n (backdropClick)=\"close()\"\n (overlayOutsideClick)=\"close()\"\n (detach)=\"close()\">\n\n <div\n class=\"ai-assistant-panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Assistente de Configura\u00E7\u00E3o\"\n [attr.aria-busy]=\"isBusyState() ? 'true' : null\"\n [cdkTrapFocus]=\"hasBackdrop\"\n [cdkTrapFocusAutoCapture]=\"hasBackdrop\"\n (keydown)=\"onKeydown($event)\"\n >\n \n <!-- HEADER -->\n <div class=\"assistant-header\">\n <div class=\"assistant-header__left\">\n <mat-icon class=\"magic-icon\">auto_awesome</mat-icon>\n <div class=\"assistant-title-group\">\n <div class=\"assistant-title\">Assistente de Configura\u00E7\u00E3o</div>\n <div class=\"assistant-subtitle\">Copiloto contextual para ajustes guiados</div>\n <div class=\"assistant-header-chips\">\n <span\n class=\"mode-chip\"\n [class.mock]=\"mockMode\"\n [matTooltip]=\"mockMode ? 'Sem chave de API: respostas de demonstra\u00E7\u00E3o' : 'Conectado ao assistente configurado'\"\n >\n {{ mockMode ? 'Mock' : 'Conectado' }}\n </span>\n <span\n class=\"policy-chip\"\n [class.strict]=\"isStrictRiskPolicy()\"\n [matTooltip]=\"getRiskPolicyTooltip()\"\n >\n {{ getRiskPolicyLabel() }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"assistant-header__right\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"assistant-close-btn\"\n (click)=\"close()\"\n aria-label=\"Fechar assistente\"\n matTooltip=\"Fechar assistente\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n <div\n class=\"assistant-status\"\n [class.processing]=\"isBusyState()\"\n [class.pending]=\"state === 'clarification'\"\n [class.warning]=\"state === 'error'\"\n [class.success]=\"state === 'review' || state === 'success'\"\n [class.compact]=\"!shouldShowSystemStatusDetail()\"\n role=\"status\"\n [attr.aria-live]=\"getSystemStatusAriaLive()\"\n aria-atomic=\"true\"\n >\n <span class=\"assistant-status-dot\" aria-hidden=\"true\"></span>\n <div class=\"assistant-status-content\">\n <div class=\"assistant-status-label\">\n <span class=\"assistant-status-label-prefix\">Status:</span>\n <span>{{ getSystemStatusLabel() }}</span>\n <span *ngIf=\"shouldShowSnapshotFallbackBadge()\" class=\"assistant-status-mode\">Snapshot</span>\n </div>\n <div *ngIf=\"shouldShowSystemStatusDetail()\" class=\"assistant-status-detail\">{{ getSystemStatusDetail() }}</div>\n </div>\n </div>\n <div class=\"assistant-flow\" *ngIf=\"shouldShowTaskFlow()\" role=\"list\" aria-label=\"Fluxo da proposta\">\n <div\n class=\"flow-step\"\n role=\"listitem\"\n *ngFor=\"let step of flowSteps\"\n [class.active]=\"getFlowStepState(step.step) === 'active'\"\n [class.done]=\"getFlowStepState(step.step) === 'done'\"\n >\n <span class=\"flow-step-index\">{{ step.step }}</span>\n <span class=\"flow-step-content\">\n <span class=\"flow-step-label\">{{ step.label }}</span>\n <span class=\"flow-step-detail\">{{ getFlowStepDetail(step.step) }}</span>\n </span>\n </div>\n </div>\n <div class=\"assistant-nav\">\n <div\n class=\"assistant-tabs\"\n role=\"tablist\"\n aria-label=\"Se\u00E7\u00F5es do assistente\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n <button\n class=\"assistant-tab\"\n type=\"button\"\n *ngIf=\"isTaskMode()\"\n id=\"assistant-tab-task\"\n role=\"tab\"\n aria-label=\"Proposta atual\"\n [attr.aria-selected]=\"isActiveTab('task')\"\n aria-controls=\"assistant-panel-task\"\n [attr.tabindex]=\"isActiveTab('task') ? 0 : -1\"\n [class.active]=\"isActiveTab('task')\"\n (click)=\"setActiveTab('task')\"\n >\n Proposta\n <span *ngIf=\"hasPendingClarification() && !isActiveTab('task')\" class=\"assistant-tab-badge\">1</span>\n </button>\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-chat\"\n role=\"tab\"\n aria-label=\"Hist\u00F3rico\"\n [attr.aria-selected]=\"isActiveTab('chat')\"\n aria-controls=\"assistant-panel-chat\"\n [attr.tabindex]=\"isActiveTab('chat') ? 0 : -1\"\n [class.active]=\"isActiveTab('chat')\"\n (click)=\"setActiveTab('chat')\"\n >\n Hist\u00F3rico\n </button>\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-suggestions\"\n role=\"tab\"\n aria-label=\"Sugest\u00F5es de melhoria\"\n [attr.aria-selected]=\"isActiveTab('suggestions')\"\n aria-controls=\"assistant-panel-suggestions\"\n [attr.tabindex]=\"isActiveTab('suggestions') ? 0 : -1\"\n [class.active]=\"isActiveTab('suggestions')\"\n (click)=\"setActiveTab('suggestions')\"\n >\n Sugest\u00F5es\n </button>\n </div>\n </div>\n\n <!-- BODY: Dynamic Content based on State -->\n <div class=\"assistant-body\">\n <div class=\"assistant-thought assistant-section\" *ngIf=\"shouldShowThoughtCard()\">\n <div class=\"assistant-thought-meta\">\n <mat-icon>psychology</mat-icon>\n <span>{{ getThoughtTimingLabel() }}</span>\n </div>\n <div class=\"assistant-thought-summary\">{{ getThoughtSummary() }}</div>\n <div class=\"assistant-thought-plan\">\n <div class=\"assistant-thought-plan-title\">{{ getThoughtPlanTitle() }}</div>\n <div class=\"assistant-thought-plan-actions\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"thought-action-details\"\n (click)=\"openThoughtDetails()\"\n [attr.aria-label]=\"getThoughtDetailsLabel()\"\n [matTooltip]=\"getThoughtDetailsTooltip()\"\n >\n {{ getThoughtDetailsLabel() }}\n </button>\n <button\n *ngIf=\"shouldShowThoughtPreviewAction()\"\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"thought-action-preview\"\n (click)=\"openThoughtPreview()\"\n [matTooltip]=\"getThoughtPreviewTooltip()\"\n >\n Pr\u00E9via\n </button>\n </div>\n <div class=\"assistant-thought-plan-hint\">{{ getThoughtActionHint() }}</div>\n <ng-container *ngIf=\"getThoughtChecklist() as thoughtChecklist\">\n <div class=\"assistant-thought-checklist\" *ngIf=\"thoughtChecklist.length\">\n <div *ngFor=\"let item of thoughtChecklist\" class=\"assistant-thought-checklist-item\">\n <mat-icon>radio_button_unchecked</mat-icon>\n <span>{{ item }}</span>\n </div>\n </div>\n <div class=\"assistant-thought-shimmer\" *ngIf=\"isBusyState() && !thoughtChecklist.length\">\n <div class=\"shimmer-line shimmer-line-1\"></div>\n <div class=\"shimmer-line shimmer-line-2\"></div>\n <div class=\"shimmer-line shimmer-line-3\"></div>\n </div>\n </ng-container>\n </div>\n </div>\n <div *ngIf=\"processingInfoVisible\" class=\"processing-banner\">\n <mat-spinner diameter=\"16\"></mat-spinner>\n <span>{{ aiExplanation || 'Analisando solicita\u00E7\u00E3o e preparando proposta...' }}</span>\n <button mat-button type=\"button\" class=\"processing-retry\" (click)=\"retryProcessing()\">Tentar novamente</button>\n </div>\n <div\n class=\"assistant-history assistant-section\"\n *ngIf=\"historyContext && isActiveTab('chat')\"\n id=\"assistant-panel-chat\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-chat\"\n >\n <div class=\"section-header\">\n <div class=\"section-heading\">\n <div class=\"section-title\">Hist\u00F3rico</div>\n <div class=\"section-subtitle\">Sess\u00F5es recentes, pedidos reaproveit\u00E1veis e desfazer r\u00E1pido.</div>\n </div>\n <div class=\"history-actions\" role=\"group\" aria-label=\"A\u00E7\u00F5es do hist\u00F3rico\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"historyExpanded = !historyExpanded\"\n [matTooltip]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [attr.aria-label]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [disabled]=\"!historyWarnings.length && !historySessions.length && !activeHistoryMessages.length\"\n >\n <mat-icon>{{ historyExpanded ? 'expand_less' : 'expand_more' }}</mat-icon>\n <span>{{ historyExpanded ? 'Recolher' : 'Expandir' }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"startNewSession()\"\n matTooltip=\"Nova conversa\"\n aria-label=\"Nova conversa\"\n [disabled]=\"isBusyState()\"\n >\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"clearHistory()\"\n matTooltip=\"Limpar hist\u00F3rico local\"\n aria-label=\"Limpar hist\u00F3rico local\"\n class=\"history-action-btn history-action-btn--danger\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar</span>\n </button>\n </div>\n </div>\n <div *ngIf=\"historyUndoDeleteSession\" class=\"history-undo\">\n <span>Sess\u00E3o removida.</span>\n <button mat-button type=\"button\" (click)=\"undoRemoveHistorySession()\">\n Desfazer\n </button>\n </div>\n\n <div *ngIf=\"historyExpanded && historyWarnings.length\" class=\"history-warnings\">\n <mat-icon>info</mat-icon>\n <div class=\"history-warnings-list\">\n <div *ngFor=\"let warning of historyWarnings\">{{ warning }}</div>\n <div class=\"history-warnings-hint\">\n Configure headers via API_CONFIG_STORAGE_OPTIONS no host.\n </div>\n </div>\n </div>\n\n <div *ngIf=\"historyExpanded && historySessions.length\" class=\"history-sessions\">\n <div\n class=\"history-session\"\n *ngFor=\"let session of historySessions\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"selectHistorySession(session.id)\"\n (keydown)=\"onHistorySessionCardKeydown($event, session.id)\"\n [class.active]=\"session.id === activeHistorySession?.id\"\n [matTooltip]=\"getHistorySessionTooltip(session)\"\n [matTooltipDisabled]=\"!session.componentType && !session.componentId\"\n >\n <div class=\"history-session-main\">\n <span class=\"history-session-title\">{{ session.title }}</span>\n <div class=\"history-session-main-right\">\n <span class=\"history-session-time\">{{ session.updatedAt | date:'short' }}</span>\n <div class=\"history-session-tools\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool\"\n (click)=\"reuseHistorySessionPrompt(session.id, $event)\"\n matTooltip=\"Reusar \u00FAltimo pedido\"\n aria-label=\"Reusar \u00FAltimo pedido\"\n >\n <mat-icon>edit_note</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool history-session-tool--danger\"\n (click)=\"removeHistorySession(session.id, $event)\"\n matTooltip=\"Excluir sess\u00E3o\"\n aria-label=\"Excluir sess\u00E3o\"\n >\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <div class=\"history-session-meta\">\n <span *ngIf=\"session.componentType\" class=\"history-chip\">{{ session.componentType }}</span>\n <span *ngIf=\"session.componentId\" class=\"history-chip\">{{ session.componentId }}</span>\n </div>\n </div>\n </div>\n <div *ngIf=\"historyExpanded && !historySessions.length\" class=\"history-empty\">\n Nenhuma sess\u00E3o salva ainda.\n </div>\n\n <div *ngIf=\"historyExpanded && activeHistoryMessages.length\" class=\"history-messages\">\n <div\n *ngIf=\"activeHistoryTotalMessages > activeHistoryMessages.length\"\n class=\"history-messages-hint\"\n >\n Mostrando \u00FAltimas {{ activeHistoryMessages.length }} de {{ activeHistoryTotalMessages }} mensagens.\n </div>\n <div\n *ngFor=\"let msg of activeHistoryMessages\"\n class=\"history-message\"\n [class.user]=\"msg.role === 'user'\"\n [class.assistant]=\"msg.role === 'assistant'\"\n >\n <div class=\"history-message-header\">\n <span class=\"history-message-role\">{{ msg.role === 'user' ? 'Voc\u00EA' : 'Assistente' }}</span>\n <span class=\"history-message-time\">{{ msg.createdAt | date:'shortTime' }}</span>\n <span\n *ngIf=\"msg.context?.usedRag\"\n class=\"history-rag\"\n matTooltip=\"Resposta baseada em contexto recuperado (RAG)\"\n >RAG</span>\n </div>\n <div class=\"history-message-text\">{{ msg.text }}</div>\n </div>\n </div>\n <div *ngIf=\"historyExpanded && historySessions.length && !activeHistoryMessages.length\" class=\"history-empty history-empty--panel\">\n Selecione uma sess\u00E3o para visualizar as mensagens.\n </div>\n <div class=\"history-helper\" *ngIf=\"historyExpanded\">\n O hist\u00F3rico \u00E9 local ao usu\u00E1rio e ao componente atual.\n </div>\n </div>\n\n <div\n class=\"loading-suggestions assistant-section\"\n *ngIf=\"loadingSuggestions && isActiveTab('suggestions')\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <mat-spinner diameter=\"20\"></mat-spinner>\n <span>Carregando sugest\u00F5es de melhoria...</span>\n </div>\n \n <!-- STATE: LISTENING (Suggestions) -->\n <div\n *ngIf=\"state === 'listening' && isActiveTab('suggestions')\"\n class=\"suggestions-area assistant-section\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <div class=\"section-header\">\n <div class=\"section-title\">Sugest\u00F5es de melhoria</div>\n <div class=\"suggestions-actions\">\n <button mat-icon-button type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\" matTooltip=\"Atualizar sugest\u00F5es\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"suggestions-hero\" *ngIf=\"!loadingSuggestions\">\n <div class=\"suggestions-hero__label\">Contexto ativo</div>\n <div class=\"suggestions-hero__title\">{{ adapter.componentName || 'Componente atual' }}</div>\n <div class=\"suggestions-hero__detail\">{{ getSystemStatusDetail() }}</div>\n </div>\n <div *ngIf=\"suggestionsWarnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of suggestionsWarnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div class=\"suggestions-content\" *ngIf=\"!loadingSuggestions && (richSuggestions.length || hasDismissedSuggestions())\">\n <div class=\"suggestions-filter\" *ngIf=\"hasDismissedSuggestions()\">\n <span>{{ getDismissedSuggestionCount() }} oculta(s)</span>\n <button mat-button type=\"button\" (click)=\"restoreDismissedSuggestions()\">\n Restaurar\n </button>\n </div>\n <div class=\"suggestions-list\" *ngIf=\"getVisibleSuggestions().length; else allSuggestionsHidden\">\n <div\n class=\"suggestion-item\"\n *ngFor=\"let sug of getVisibleSuggestions()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Selecionar sugest\u00E3o: ' + sug.label\"\n (click)=\"selectSuggestion(sug)\"\n (keydown)=\"onSuggestionCardKeydown($event, sug)\"\n >\n <div class=\"suggestion-copy\">\n <div class=\"suggestion-main\">\n <mat-icon *ngIf=\"sug.icon\" class=\"suggestion-icon\">{{ sug.icon }}</mat-icon>\n <span class=\"suggestion-label\">{{ sug.label }}</span>\n <span *ngIf=\"sug.group\" class=\"suggestion-group\">{{ sug.group }}</span>\n </div>\n <div *ngIf=\"sug.description\" class=\"suggestion-desc\">{{ sug.description }}</div>\n </div>\n <div class=\"suggestion-actions\">\n <span class=\"suggestion-arrow\" aria-hidden=\"true\">\n <mat-icon>chevron_right</mat-icon>\n </span>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn\"\n (click)=\"prepareSuggestionPrompt(sug, $event)\"\n matTooltip=\"Refinar pedido\"\n aria-label=\"Refinar pedido\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn suggestion-action-btn--danger\"\n (click)=\"dismissSuggestion(sug, $event)\"\n matTooltip=\"Ocultar sugest\u00E3o\"\n aria-label=\"Ocultar sugest\u00E3o\"\n >\n <mat-icon>visibility_off</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <ng-template #allSuggestionsHidden>\n <div class=\"suggestions-empty suggestions-empty--inline\">\n Todas as sugest\u00F5es foram ocultadas.\n </div>\n </ng-template>\n </div>\n <div class=\"suggestions-empty\" *ngIf=\"!loadingSuggestions && !richSuggestions.length\">\n Nenhuma sugest\u00E3o dispon\u00EDvel no momento.\n </div>\n <div class=\"suggestions-helper\" *ngIf=\"!loadingSuggestions && !richSuggestions.length\">\n Selecione uma sugest\u00E3o acima ou descreva uma altera\u00E7\u00E3o no campo inferior.\n </div>\n </div>\n\n <!-- STATE: CLARIFICATION (Two-Step Flow) -->\n <div\n *ngIf=\"state === 'clarification' && isActiveTab('task')\"\n class=\"clarification-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n <div class=\"task-header\" *ngIf=\"!shouldShowThoughtCard()\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n <div *ngIf=\"clarificationOptions.length > 1 && getTaskSelectionSummary() as selectionSummary\" class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n <div *ngIf=\"shouldShowTaskSteps()\" class=\"task-steps\">\n <span class=\"task-step active\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step\">3 Revis\u00E3o</span>\n </div>\n </div>\n <div *ngIf=\"clarificationResponseType === 'context'\" class=\"context-only\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n <div class=\"context-only-hint\">Buscando contexto adicional...</div>\n </div>\n <ng-template #clarificationOptionContent let-opt let-index=\"index\" let-compact=\"compact\">\n <div class=\"clarification-decision-head\" *ngIf=\"!compact\">\n <span class=\"clarification-decision-index\">{{ index + 1 }}</span>\n <span class=\"clarification-decision-type\">{{ getClarificationOptionKindLabel(opt) }}</span>\n <span class=\"spacer\"></span>\n <span class=\"clarification-decision-state\" *ngIf=\"isClarificationSelected(opt)\">Selecionado</span>\n </div>\n <ng-container [ngSwitch]=\"getClarificationOptionLayout(opt)\">\n <div *ngSwitchCase=\"'endpoint'\" class=\"clarification-card\">\n <div class=\"clarification-card-header\">\n <mat-icon class=\"endpoint-icon\">{{ getEndpointIcon(opt) }}</mat-icon>\n <ng-container *ngIf=\"getEndpointMethod(opt) as method\">\n <span class=\"endpoint-method\" [attr.data-method]=\"method\">{{ method }}</span>\n </ng-container>\n <span class=\"endpoint-label\">{{ opt.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon class=\"select-indicator\">\n {{ isClarificationSelected(opt) ? 'check_circle' : 'radio_button_unchecked' }}\n </mat-icon>\n </div>\n <div class=\"clarification-card-body\">\n <ng-container *ngIf=\"getEndpointPath(opt) as path\">\n <div class=\"endpoint-path\">{{ path }}</div>\n </ng-container>\n <div\n *ngIf=\"opt.contextHints?.description\"\n class=\"endpoint-description\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </div>\n </div>\n </div>\n <div *ngSwitchCase=\"'color'\" class=\"clarification-color\">\n <span\n class=\"color-swatch\"\n [style.background]=\"getSafeHexColor(opt) || 'var(--md-sys-color-surface-container-highest)'\"\n ></span>\n <div class=\"color-meta\">\n <span class=\"color-label\">{{ opt.label }}</span>\n <span *ngIf=\"opt.contextHints?.hexColor\" class=\"color-value\">{{ opt.contextHints?.hexColor }}</span>\n </div>\n </div>\n <div *ngSwitchCase=\"'description'\" class=\"clarification-description\">\n <span class=\"clarification-label\">{{ opt.label }}</span>\n <span\n *ngIf=\"opt.contextHints?.description\"\n class=\"clarification-subtitle\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </span>\n </div>\n <span *ngSwitchDefault class=\"clarification-plain-label\">{{ opt.label }}</span>\n </ng-container>\n </ng-template>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"clarificationQuestions.length\"\n class=\"clarification-questions\"\n [class.attention-highlight]=\"highlightClarificationDetails && !clarificationOptions.length\"\n >\n <div *ngFor=\"let question of clarificationQuestions; let i = index\" class=\"clarification-question\">\n <div class=\"clarification-question-label\">{{ question }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationAnswers[i]\"\n [placeholder]=\"'Resposta ' + (i + 1)\"\n autocomplete=\"off\">\n </div>\n </div>\n <div\n *ngIf=\"clarificationOptions.length\"\n class=\"clarification-options-block\"\n [class.attention-highlight]=\"highlightClarificationDetails\"\n >\n <div class=\"clarification-options-title\">\n {{ clarificationOptions.length === 1 ? 'Decis\u00E3o sugerida' : 'Decis\u00F5es sugeridas' }}\n </div>\n <div *ngIf=\"clarificationOptions.length === 1\" class=\"clarification-options-hint\">\n Etapa 2 de 4: confirme a melhor op\u00E7\u00E3o para continuar.\n </div>\n <div *ngIf=\"clarificationOptions.length > 1\" class=\"clarification-options-hint\">\n Etapa 2 de 4: selecione a alternativa mais aderente para gerar a proposta.\n </div>\n <div\n *ngIf=\"clarificationResponseType === 'confirm'\"\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n <button\n mat-button\n type=\"button\"\n *ngFor=\"let opt of clarificationOptions; let i = index\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n </div>\n <div\n *ngIf=\"clarificationSelectionMode === 'multiple'\"\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n <button\n mat-button\n type=\"button\"\n *ngFor=\"let opt of clarificationOptions; let i = index\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n class=\"clarification-option\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n </div>\n <div\n *ngIf=\"clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation !== 'chips'\"\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n <button\n mat-button\n type=\"button\"\n *ngFor=\"let opt of clarificationOptions; let i = index\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n </div>\n <div\n *ngIf=\"clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation === 'chips'\"\n class=\"clarification-chips\"\n >\n <ng-container *ngFor=\"let opt of clarificationOptions; let i = index\">\n <button\n *ngIf=\"isEndpointOption(opt); else chipOption\"\n mat-button\n type=\"button\"\n class=\"clarification-option clarification-card-button\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n <ng-template #chipOption>\n <mat-chip\n (click)=\"onClarificationOptionClick(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt)\"\n class=\"clarification-chip\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: true }\"></ng-container>\n </mat-chip>\n </ng-template>\n </ng-container>\n </div>\n </div>\n <div\n *ngIf=\"clarificationAllowCustom && clarificationResponseType !== 'context'\"\n class=\"clarification-manual-toggle\"\n >\n <span class=\"clarification-manual-label\">N\u00E3o encontrou o recurso?</span>\n <button mat-button type=\"button\" (click)=\"toggleManualInput()\">\n {{ showManualInput ? 'Ocultar resposta manual' : 'Responder manualmente' }}\n </button>\n </div>\n <div\n *ngIf=\"clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context'\"\n class=\"clarification-free\"\n >\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationFreeText\"\n placeholder=\"Digite sua resposta\u2026\"\n autocomplete=\"off\"\n (keydown.enter)=\"confirmTaskAction()\"\n />\n </div>\n <div\n *ngIf=\"clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context'\"\n class=\"clarification-free-hint\"\n >\n Pressione Enter para enviar.\n </div>\n </div>\n\n <!-- STATE: REVIEW (Diff/Explanation) -->\n <div\n *ngIf=\"state === 'review' && isActiveTab('task')\"\n class=\"review-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n <div class=\"task-header\" *ngIf=\"!shouldShowThoughtCard()\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n <div *ngIf=\"clarificationOptions.length > 1 && getTaskSelectionSummary() as selectionSummary\" class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n <div *ngIf=\"shouldShowTaskSteps()\" class=\"task-steps\">\n <span class=\"task-step\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step active\">3 Revis\u00E3o</span>\n </div>\n </div>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div class=\"review-trust\">\n <span class=\"trust-chip\" [matTooltip]=\"getScopeTooltip()\">{{ getScopeLabel() }}</span>\n <span class=\"trust-chip\" [matTooltip]=\"getConfidenceTooltip()\">{{ getConfidenceLabel() }}</span>\n <span class=\"trust-chip risk-chip\" [class.medium]=\"getReviewRiskLevel() === 'm\u00E9dio'\" [class.high]=\"getReviewRiskLevel() === 'alto'\">\n Risco {{ getReviewRiskLevel() }}\n </span>\n </div>\n <div class=\"review-summary\" [class.attention-highlight]=\"highlightReviewDetails\">\n <div class=\"review-summary-title\">Resumo da proposta</div>\n <div class=\"review-summary-line\">{{ getReviewSummary() }}</div>\n </div>\n <div class=\"review-diff\">\n <div class=\"review-diff-title\">Pr\u00E9via de mudan\u00E7as</div>\n <ng-container *ngIf=\"pendingDiff.length; else noDiffPreview\">\n <div class=\"review-diff-summary\">\n <div *ngFor=\"let line of getDiffSummaryLines()\" class=\"review-diff-line\">{{ line }}</div>\n <div *ngIf=\"pendingDiff.length > 3\" class=\"review-diff-more\">\u2026 +{{ pendingDiff.length - 3 }} mudan\u00E7as</div>\n </div>\n <button mat-stroked-button type=\"button\" class=\"review-diff-toggle\" (click)=\"toggleFullDiff()\">\n {{ getDiffToggleLabel() }}\n </button>\n </ng-container>\n <ng-template #noDiffPreview>\n <div class=\"review-diff-empty\">\n N\u00E3o foi poss\u00EDvel gerar um diff estruturado. Revise o resumo e aplique com cautela.\n </div>\n </ng-template>\n <div *ngIf=\"showFullDiff && pendingDiff.length\" class=\"review-diff-full\">\n <div *ngFor=\"let diff of pendingDiff\" class=\"review-diff-block\">\n <div class=\"review-diff-path\">{{ diff.path }}</div>\n <div class=\"review-diff-label\">Antes:</div>\n <pre>{{ diff.before | json }}</pre>\n <div class=\"review-diff-label\">Depois:</div>\n <pre>{{ diff.after | json }}</pre>\n </div>\n </div>\n </div>\n <div class=\"ai-explanation\" *ngIf=\"aiExplanation.trim()\">\n {{ aiExplanation }}\n </div>\n </div>\n\n <!-- STATE: ERROR -->\n <div\n *ngIf=\"state === 'error' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))\"\n class=\"error-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"error-msg\">\n <mat-icon color=\"warn\">error_outline</mat-icon>\n <span>{{ errorMsg }}</span>\n </div>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div *ngIf=\"shouldShowApplyDetails()\" class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n <div class=\"apply-details-actions\" *ngIf=\"allowManualPatchEdit\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar patch' }}\n </button>\n </div>\n </div>\n <div class=\"apply-details-meta\" *ngIf=\"lastApplyAt\">\n \u00DAltima tentativa: {{ lastApplyAt | date:'short' }}\n </div>\n <div class=\"apply-paths\" *ngIf=\"getApplyPaths().length\">\n <span class=\"apply-path-chip\" *ngFor=\"let path of getApplyPaths()\">{{ path }}</span>\n </div>\n <div class=\"apply-warnings\" *ngIf=\"applyWarnings.length\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n <div *ngFor=\"let warning of applyWarnings\">{{ warning }}</div>\n </div>\n </div>\n <div class=\"patch-path-editor\" *ngIf=\"allowManualPatchEdit && patchPathEditorExpanded\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n <div class=\"patch-path-editor-empty\" *ngIf=\"!getEditablePatchPathEdits().length\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n <div class=\"patch-path-rows\" *ngIf=\"getEditablePatchPathEdits().length\">\n <div class=\"patch-path-row\" *ngFor=\"let edit of getEditablePatchPathEdits(); let i = index\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n <div *ngIf=\"patchPathEdits[i].error\" class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n </div>\n </div>\n <div *ngIf=\"patchPathEditorError\" class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n <div class=\"patch-editor\" *ngIf=\"allowManualPatchEdit && patchEditorExpanded\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n <div *ngIf=\"patchEditorError\" class=\"patch-editor-error\">{{ patchEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n </div>\n <div class=\"review-actions\">\n <button mat-button (click)=\"close()\">Fechar</button>\n <button mat-stroked-button (click)=\"retry()\">Tentar Novamente</button>\n </div>\n </div>\n\n <!-- STATE: SUCCESS -->\n <div\n *ngIf=\"state === 'success' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))\"\n class=\"success-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"success-msg\">\n <mat-icon class=\"success-icon\">check_circle</mat-icon>\n <span>{{ aiExplanation || 'Configura\u00E7\u00E3o atualizada.' }}</span>\n </div>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div *ngIf=\"shouldShowApplyDetails()\" class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n <div class=\"apply-details-actions\" *ngIf=\"allowManualPatchEdit\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar e reaplicar' }}\n </button>\n </div>\n </div>\n <div class=\"apply-details-meta\" *ngIf=\"lastApplyAt\">\n Aplicado em {{ lastApplyAt | date:'short' }}\n </div>\n <div class=\"apply-paths\" *ngIf=\"getApplyPaths().length\">\n <span class=\"apply-path-chip\" *ngFor=\"let path of getApplyPaths()\">{{ path }}</span>\n </div>\n <div class=\"apply-warnings\" *ngIf=\"applyWarnings.length\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n <div *ngFor=\"let warning of applyWarnings\">{{ warning }}</div>\n </div>\n </div>\n <div class=\"patch-path-editor\" *ngIf=\"allowManualPatchEdit && patchPathEditorExpanded\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n <div class=\"patch-path-editor-empty\" *ngIf=\"!getEditablePatchPathEdits().length\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n <div class=\"patch-path-rows\" *ngIf=\"getEditablePatchPathEdits().length\">\n <div class=\"patch-path-row\" *ngFor=\"let edit of getEditablePatchPathEdits(); let i = index\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n <div *ngIf=\"patchPathEdits[i].error\" class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n </div>\n </div>\n <div *ngIf=\"patchPathEditorError\" class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n <div class=\"patch-editor\" *ngIf=\"allowManualPatchEdit && patchEditorExpanded\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n <div *ngIf=\"patchEditorError\" class=\"patch-editor-error\">{{ patchEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n </div>\n <button mat-button color=\"warn\" (click)=\"undoLastChange()\">\n <mat-icon>undo</mat-icon> Desfazer\n </button>\n </div>\n\n </div>\n\n <div class=\"assistant-footer\">\n <ng-container *ngIf=\"!isTaskMode(); else taskFooter\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"composer-leading composer-leading-btn\"\n [matMenuTriggerFor]=\"assistantQuickMenu\"\n aria-label=\"Abrir a\u00E7\u00F5es r\u00E1pidas\"\n matTooltip=\"A\u00E7\u00F5es r\u00E1pidas\"\n >\n <mat-icon>add</mat-icon>\n </button>\n <input\n #inputEl\n type=\"text\"\n [(ngModel)]=\"userPrompt\"\n [disabled]=\"state === 'processing' || state === 'applying'\"\n placeholder=\"Descreva a altera\u00E7\u00E3o que deseja aplicar\u2026\"\n autocomplete=\"off\"\n />\n <div class=\"send-actions\">\n <button\n mat-icon-button\n class=\"send-btn\"\n *ngIf=\"state === 'listening'\"\n (click)=\"submitPrompt()\"\n [disabled]=\"!userPrompt.trim()\"\n [class.ready]=\"!!userPrompt.trim()\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <mat-spinner diameter=\"20\" *ngIf=\"state === 'processing' || state === 'applying'\"></mat-spinner>\n </div>\n </ng-container>\n <ng-template #taskFooter>\n <div class=\"task-footer\">\n <div class=\"task-footer-left\">\n <button mat-button type=\"button\" (click)=\"handleTaskSecondary()\">{{ getTaskCancelLabel() }}</button>\n <button\n *ngIf=\"state === 'review'\"\n mat-stroked-button\n type=\"button\"\n (click)=\"retry()\"\n >\n {{ getTaskSecondaryLabel() }}\n </button>\n </div>\n <div class=\"task-footer-right\">\n <button\n class=\"task-primary-btn\"\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"confirmTaskAction()\"\n [disabled]=\"isTaskPrimaryDisabled()\"\n >\n {{ getTaskPrimaryLabel() }}\n </button>\n <mat-spinner diameter=\"20\" *ngIf=\"state === 'processing' || state === 'applying'\"></mat-spinner>\n </div>\n </div>\n </ng-template>\n </div>\n\n <mat-menu #assistantQuickMenu=\"matMenu\" panelClass=\"assistant-quick-menu-panel\">\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('chat')\">\n <mat-icon>history</mat-icon>\n <span>Hist\u00F3rico</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('suggestions')\">\n <mat-icon>lightbulb</mat-icon>\n <span>Sugest\u00F5es</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"startNewSession()\">\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\">\n <mat-icon>refresh</mat-icon>\n <span>Atualizar sugest\u00F5es</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n (click)=\"restoreDismissedSuggestions()\"\n [disabled]=\"!hasDismissedSuggestions()\"\n >\n <mat-icon>visibility</mat-icon>\n <span>Restaurar sugest\u00F5es ocultas</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n class=\"assistant-quick-menu-danger\"\n (click)=\"clearHistory()\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar hist\u00F3rico local</span>\n </button>\n </mat-menu>\n </div>\n\n</ng-template>\n", styles: ["@keyframes assistantPremiumEnter{0%{opacity:0;transform:translate(14px) scale(.99)}to{opacity:1;transform:translate(0) scale(1)}}:host ::ng-deep .ai-assistant-backdrop{background:color-mix(in srgb,var(--md-sys-color-scrim, var(--md-sys-color-shadow, var(--md-sys-color-on-surface))) 42%,transparent);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}::ng-deep .ai-assistant-overlay-pane{max-width:calc(100vw - 24px);max-height:calc(100vh - 24px)}.ai-assistant-panel{box-sizing:border-box;width:min(604px,100vw - 18px);min-height:min(620px,100vh - 18px);max-height:min(820px,100vh - 18px);display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border-left:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-top:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));box-shadow:0 18px 48px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 42%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);background:radial-gradient(circle at 14% 8%,color-mix(in srgb,var(--md-sys-color-primary-container) 38%,transparent) 0%,transparent 44%),linear-gradient(165deg,color-mix(in srgb,var(--md-sys-color-surface-container-highest) 88%,var(--md-sys-color-surface)),var(--md-sys-color-surface));animation:assistantPremiumEnter .24s cubic-bezier(.22,1,.36,1)}.assistant-header{position:relative;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:12px 16px 10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(130deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.assistant-header:after{content:\"\";position:absolute;left:16px;right:16px;bottom:-1px;height:1px;background:linear-gradient(90deg,color-mix(in srgb,var(--md-sys-color-primary) 55%,transparent),transparent);pointer-events:none}.assistant-header .assistant-header__left{min-width:0;display:flex;align-items:flex-start;gap:12px}.assistant-header .magic-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:30px;height:30px;font-size:18px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent);box-shadow:0 4px 12px color-mix(in srgb,var(--md-sys-color-primary) 26%,transparent)}.assistant-header .assistant-title-group{min-width:0;display:flex;flex-direction:column;gap:4px}.assistant-header .assistant-title{font-size:15px;font-weight:700;letter-spacing:.01em;overflow-wrap:anywhere}.assistant-header .assistant-subtitle{display:block;font-size:11px;line-height:1.25;color:color-mix(in srgb,var(--md-sys-color-on-surface) 70%,var(--md-sys-color-on-surface-variant));overflow-wrap:anywhere}.assistant-header-chips{display:inline-flex;align-items:center;flex-wrap:wrap;gap:6px}.assistant-header .mode-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 28%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 64%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-primary-container) 85%,var(--md-sys-color-on-surface));font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.assistant-header .mode-chip:before{content:\"\";width:6px;height:6px;border-radius:999px;background:currentColor;box-shadow:0 0 0 3px color-mix(in srgb,currentColor 16%,transparent)}.assistant-header .mode-chip.mock{border-color:color-mix(in srgb,var(--md-sys-color-error) 34%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-error-container) 72%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-error-container) 85%,var(--md-sys-color-error))}.assistant-header .policy-chip{padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 84%,transparent);background:var(--md-sys-color-surface-container-high);font-size:10px;letter-spacing:.02em;font-weight:600}.assistant-header .policy-chip.strict{border-color:color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 56%,var(--md-sys-color-surface-container-high))}.assistant-status{display:flex;align-items:flex-start;gap:10px;padding:10px 16px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-radius:0;background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 24%,transparent),transparent 48%),var(--md-sys-color-surface-container-low)}.assistant-status-dot{width:8px;height:8px;margin-top:6px;border-radius:999px;flex:0 0 auto;background:var(--md-sys-color-primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.assistant-status.warning .assistant-status-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.assistant-status.success .assistant-status-dot{background:color-mix(in srgb,var(--md-sys-color-primary) 74%,var(--md-sys-color-tertiary, var(--md-sys-color-primary)))}.assistant-status-content{min-width:0;display:flex;flex-direction:column;gap:2px}.assistant-status-label{display:flex;align-items:center;flex-wrap:wrap;gap:4px;font-size:12px;font-weight:700;line-height:1.35}.assistant-status-detail{font-size:11px;line-height:1.4;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.assistant-status-mode{padding:1px 6px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent);color:var(--md-sys-color-on-primary-container);font-size:10px;font-weight:700}.assistant-nav{padding:8px 16px 0}.assistant-nav .assistant-tabs{display:flex;align-items:center;gap:4px;border-radius:12px;padding:5px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(155deg,color-mix(in srgb,var(--md-sys-color-primary-container) 14%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-nav .assistant-tab{appearance:none;min-width:0;min-height:30px;border:0;border-radius:8px;padding:0 10px;background:transparent;color:var(--md-sys-color-on-surface-variant);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex:1 1 0;font-size:11px;font-weight:700;letter-spacing:.01em}.assistant-nav .assistant-tab.active{background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent),0 6px 12px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.assistant-section,.assistant-card{border-radius:14px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 50%),var(--md-sys-color-surface-container-lowest);box-shadow:0 6px 18px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 7%,transparent)}.suggestions-hero{margin:2px 0 4px;padding:10px 12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(120deg,color-mix(in srgb,var(--md-sys-color-primary-container) 34%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.suggestions-hero__label{font-size:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:var(--md-sys-color-on-surface-variant);opacity:.88}.suggestions-hero__title{margin-top:2px;font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.suggestions-hero__detail{margin-top:4px;font-size:12px;line-height:1.4;color:color-mix(in srgb,var(--md-sys-color-on-surface) 78%,var(--md-sys-color-on-surface-variant))}.suggestions-content .suggestion-item{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(140deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-lowest);transition:transform .2s cubic-bezier(.25,.8,.25,1),border-color .2s ease,box-shadow .2s ease}.suggestions-list{display:flex;flex-direction:column;gap:10px}.suggestion-copy{min-width:0;display:grid;gap:4px}.suggestion-main{min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.suggestion-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto;color:var(--md-sys-color-primary)}.suggestion-label{min-width:0;font-size:13px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestion-group{padding:2px 6px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:10px;font-weight:700;line-height:1.2}.suggestion-desc{font-size:12px;line-height:1.35;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.suggestion-actions{display:inline-flex;align-items:center;justify-content:flex-end;gap:4px}.suggestion-action-btn,.suggestion-arrow{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--md-sys-color-on-surface-variant)}.suggestions-content .suggestion-item:hover,.suggestions-content .suggestion-item:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant));box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 28%,transparent);transform:translateY(-2px) scale(1.01)}.assistant-footer{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:10px 16px;border-top-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-low)}.assistant-footer .task-footer{grid-column:1/-1}.composer-leading{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 70%,var(--md-sys-color-surface-container-low));color:var(--md-sys-color-primary);box-shadow:0 4px 10px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.composer-leading mat-icon{width:16px;height:16px;font-size:16px}.assistant-footer input{box-sizing:border-box;width:100%;min-width:0;height:34px;border:1px solid;border-radius:8px;padding:0 12px;color:var(--md-sys-color-on-surface);border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface);box-shadow:inset 0 1px 2px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent)}.send-actions{min-width:36px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn{--mdc-icon-button-icon-size: 20px;--mdc-icon-button-state-layer-size: 36px;--mat-icon-button-state-layer-size: 36px;width:36px;height:36px;padding:8px;line-height:1;display:inline-flex;align-items:center;justify-content:center;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface)}.assistant-footer .send-btn mat-icon{width:20px;height:20px;margin:0;font-size:20px;line-height:20px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn.ready{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary-container) 84%,var(--md-sys-color-primary)),var(--md-sys-color-primary));color:var(--md-sys-color-on-primary);box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent)}.task-primary-btn{border-radius:12px;box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 24%,transparent)}@media(max-width:959px){.assistant-header{padding:12px 12px 10px}.assistant-section,.assistant-card{margin:4px 12px 10px}.assistant-header:after{left:12px;right:12px}.assistant-header .assistant-title{font-size:14px}.assistant-header .assistant-subtitle{font-size:10px}.assistant-footer{grid-template-columns:minmax(0,1fr) auto}.composer-leading{display:none}}.assistant-thought{margin-top:0;gap:10px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-thought-meta{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-meta mat-icon{width:15px;height:15px;font-size:15px;color:var(--md-sys-color-primary)}.assistant-thought-summary{font-size:13px;line-height:1.45;color:var(--md-sys-color-on-surface)}.assistant-thought-plan{border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 32%,var(--md-sys-color-outline-variant));border-radius:12px;padding:10px;background:var(--md-sys-color-surface-container-lowest);display:flex;flex-direction:column;gap:8px}.assistant-thought-plan-title{font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.assistant-thought-plan-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px}.assistant-thought-plan-actions .mdc-button{min-width:0}.assistant-thought-plan-hint{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.35}.assistant-thought-checklist{display:flex;flex-direction:column;gap:5px}.assistant-thought-checklist-item{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-checklist-item mat-icon{width:14px;height:14px;font-size:14px}.assistant-thought-shimmer{display:flex;flex-direction:column;gap:8px;margin-top:4px}.assistant-thought-shimmer .shimmer-line{height:12px;border-radius:4px;position:relative;overflow:hidden;background:var(--md-sys-color-surface-container-highest)}.assistant-thought-shimmer .shimmer-line:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent);animation:assistantShimmerEffect 1.5s infinite}.assistant-thought-shimmer .shimmer-line-1{width:85%}.assistant-thought-shimmer .shimmer-line-2{width:92%}.assistant-thought-shimmer .shimmer-line-3{width:64%}@keyframes assistantShimmerEffect{to{transform:translate(100%)}}.assistant-flow{grid-template-columns:1fr;gap:6px}.flow-step{display:flex;align-items:flex-start;gap:8px;text-align:left;padding:7px 8px;border-radius:10px}.flow-step-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.flow-step-content{min-width:0;display:flex;flex-direction:column;gap:1px}.flow-step-label{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.flow-step-detail{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.3}.flow-step.active .flow-step-index{border-color:color-mix(in srgb,var(--md-sys-color-primary) 60%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 85%,var(--md-sys-color-surface-container-highest));color:var(--md-sys-color-on-primary-container)}.flow-step.done .flow-step-index{border-color:transparent;background:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-surface-container-highest))}.task-timeline{margin-top:4px;display:grid;gap:6px}.task-timeline-item{display:flex;align-items:flex-start;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);opacity:.76}.task-timeline-item.active{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 40%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-low))}.task-timeline-item.done{opacity:.9;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant))}.task-timeline-dot{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.task-timeline-copy{min-width:0;display:flex;flex-direction:column;gap:1px}.task-timeline-title{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.task-timeline-detail{font-size:11px;line-height:1.3;color:var(--md-sys-color-on-surface-variant)}.clarification-decision-head{display:inline-flex;align-items:center;width:100%;gap:6px;padding:8px 12px 0;box-sizing:border-box}.clarification-decision-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 68%,transparent)}.clarification-decision-type{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);opacity:.92}.clarification-decision-state{font-size:10px;font-weight:700;color:var(--md-sys-color-primary)}.clarification-option{border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 55%),var(--md-sys-color-surface-container-low)}.clarification-option.selected{border-color:color-mix(in srgb,var(--md-sys-color-primary) 56%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 44%,transparent),transparent 62%),var(--md-sys-color-surface-container);box-shadow:0 8px 16px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.clarification-options-block{overflow:visible;padding-right:4px}@media(max-width:959px){.assistant-thought-plan-actions{grid-template-columns:1fr}}.ai-assistant-panel{width:min(604px,100vw - 18px)}.assistant-section,.assistant-card{margin:0;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant))}.assistant-section{min-height:0;padding:14px 16px;overflow:visible}.assistant-card{min-height:0;padding:14px 16px 16px;overflow:visible}.suggestions-area,.assistant-history,.loading-suggestions{overflow-y:auto;overflow-x:hidden}.section-header{min-width:0;display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}.section-title{min-width:0;font-size:14px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestions-actions{flex:0 0 auto;display:inline-flex;align-items:center}.review-area,.error-area,.success-area,.clarification-area{padding:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:auto}.review-trust{margin:2px 0 4px}.trust-chip{max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.warnings-area,.review-summary,.review-diff,.apply-details,.clarification-options-block,.clarification-manual-toggle{width:100%;max-width:100%;min-width:0}.review-diff{padding:12px 14px}.review-diff-full{padding:10px;overflow-x:auto}.review-diff-block{min-width:0}.review-diff-block pre{overflow-wrap:anywhere;word-break:break-word}.clarification-options-block{padding:4px 2px 10px}.clarification-option{line-height:normal}:host ::ng-deep .clarification-option .mdc-button__label{line-height:1.35!important}.clarification-plain-label{padding:6px 12px 12px;font-size:14px;line-height:1.35}.clarification-manual-toggle{margin-top:10px;padding:10px 2px 0;flex-wrap:wrap;row-gap:6px}.suggestions-content .suggestion-actions{gap:6px}.suggestions-content .suggestion-arrow,.suggestions-content .suggestion-action-btn mat-icon,.suggestions-content .suggestion-arrow mat-icon{display:inline-flex;align-items:center;justify-content:center}:host ::ng-deep .assistant-quick-menu-panel{min-width:244px;max-width:min(90vw,320px);border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high);box-shadow:0 12px 28px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 32%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 6%,transparent);overflow:hidden;padding:6px}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item{min-height:36px;border-radius:10px;color:var(--md-sys-color-on-surface);font-size:12px;font-weight:500;margin:1px 0}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item .mat-icon{color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,var(--md-sys-color-on-surface-variant))}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:hover:not([disabled]){background:color-mix(in srgb,var(--md-sys-color-primary-container) 45%,transparent)}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:-2px}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger{color:var(--md-sys-color-error)}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger .mat-icon{color:var(--md-sys-color-error)}@media(max-width:959px){::ng-deep .ai-assistant-overlay-pane{top:12px!important;left:12px!important;width:calc(100vw - 24px)!important;height:calc(100vh - 24px)!important;max-width:calc(100vw - 24px);max-height:calc(100vh - 24px);transform:none!important}.ai-assistant-panel{width:calc(100vw - 48px);min-height:min(620px,100vh - 48px);max-height:calc(100vh - 48px)}.assistant-section,.assistant-card{margin:0}.assistant-card,.assistant-section{padding:12px}}.ai-trigger-btn{--mdc-icon-button-state-layer-size: 36px;width:36px;height:36px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary) 9%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent);color:var(--md-sys-color-primary);opacity:1}.ai-trigger-btn:hover:not(:disabled){background:color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent);border-color:color-mix(in srgb,var(--md-sys-color-primary) 36%,transparent);color:var(--md-sys-color-on-primary-container)}.ai-trigger-btn:focus-visible,.assistant-close-btn:focus-visible,.assistant-tab:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.assistant-close-btn{width:28px;height:28px;color:var(--md-sys-color-on-surface-variant)}.assistant-close-btn:hover:not(:disabled){background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.assistant-body{padding:12px 16px;overflow:hidden;min-height:0;flex:1;display:flex;flex-direction:column;gap:12px}.assistant-body>*{min-height:0}@media(max-width:959px){.assistant-nav{padding:8px 12px 0}.assistant-body,.assistant-footer{padding:10px 12px}.suggestions-content .suggestion-item{grid-template-columns:1fr;align-items:start}.suggestion-actions{justify-content:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i5.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i5.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i6.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i16.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i11.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i11.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i11.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "pipe", type: i3.JsonPipe, name: "json" }, { kind: "pipe", type: i3.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6671
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6672
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisAiAssistantComponent, isStandalone: true, selector: "praxis-ai-assistant", inputs: { adapter: "adapter", riskPolicy: "riskPolicy", allowManualPatchEdit: "allowManualPatchEdit", hasBackdrop: "hasBackdrop" }, viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: CdkOverlayOrigin, descendants: true }, { propertyName: "triggerButton", first: true, predicate: ["triggerBtn"], descendants: true, read: ElementRef }, { propertyName: "inputElement", first: true, predicate: ["inputEl"], descendants: true }], ngImport: i0, template: "<!-- Trigger Button -->\n<button\n mat-icon-button\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n #triggerBtn\n (click)=\"open()\"\n [disabled]=\"isOpen\"\n class=\"ai-trigger-btn\"\n matTooltip=\"Assistente de Configura\u00E7\u00E3o\"\n aria-label=\"Abrir Assistente IA\">\n <mat-icon>auto_awesome</mat-icon>\n</button>\n\n<!-- Overlay Template -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"12\"\n cdkConnectedOverlayPanelClass=\"ai-assistant-overlay-pane\"\n cdkConnectedOverlayBackdropClass=\"ai-assistant-backdrop\"\n (backdropClick)=\"close()\"\n (overlayOutsideClick)=\"close()\"\n (detach)=\"close()\">\n\n <div\n class=\"ai-assistant-panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Assistente de Configura\u00E7\u00E3o\"\n [attr.aria-busy]=\"isBusyState() ? 'true' : null\"\n [cdkTrapFocus]=\"hasBackdrop\"\n [cdkTrapFocusAutoCapture]=\"hasBackdrop\"\n (keydown)=\"onKeydown($event)\"\n >\n\n <!-- HEADER -->\n <div class=\"assistant-header\">\n <div class=\"assistant-header__left\">\n <mat-icon class=\"magic-icon\">auto_awesome</mat-icon>\n <div class=\"assistant-title-group\">\n <div class=\"assistant-title\">Assistente de Configura\u00E7\u00E3o</div>\n <div class=\"assistant-subtitle\">Copiloto contextual para ajustes guiados</div>\n <div class=\"assistant-header-chips\">\n <span\n class=\"mode-chip\"\n [class.mock]=\"mockMode\"\n [matTooltip]=\"mockMode ? 'Sem chave de API: respostas de demonstra\u00E7\u00E3o' : 'Conectado ao assistente configurado'\"\n >\n {{ mockMode ? 'Mock' : 'Conectado' }}\n </span>\n <span\n class=\"policy-chip\"\n [class.strict]=\"isStrictRiskPolicy()\"\n [matTooltip]=\"getRiskPolicyTooltip()\"\n >\n {{ getRiskPolicyLabel() }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"assistant-header__right\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"assistant-close-btn\"\n (click)=\"close()\"\n aria-label=\"Fechar assistente\"\n matTooltip=\"Fechar assistente\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n <div\n class=\"assistant-status\"\n [class.processing]=\"isBusyState()\"\n [class.pending]=\"state === 'clarification'\"\n [class.warning]=\"state === 'error'\"\n [class.success]=\"state === 'review' || state === 'success'\"\n [class.compact]=\"!shouldShowSystemStatusDetail()\"\n role=\"status\"\n [attr.aria-live]=\"getSystemStatusAriaLive()\"\n aria-atomic=\"true\"\n >\n <span class=\"assistant-status-dot\" aria-hidden=\"true\"></span>\n <div class=\"assistant-status-content\">\n <div class=\"assistant-status-label\">\n <span class=\"assistant-status-label-prefix\">Status:</span>\n <span>{{ getSystemStatusLabel() }}</span>\n @if (shouldShowSnapshotFallbackBadge()) {\n <span class=\"assistant-status-mode\">Snapshot</span>\n }\n </div>\n @if (shouldShowSystemStatusDetail()) {\n <div class=\"assistant-status-detail\">{{ getSystemStatusDetail() }}</div>\n }\n </div>\n </div>\n @if (shouldShowTaskFlow()) {\n <div class=\"assistant-flow\" role=\"list\" aria-label=\"Fluxo da proposta\">\n @for (step of flowSteps; track step) {\n <div\n class=\"flow-step\"\n role=\"listitem\"\n [class.active]=\"getFlowStepState(step.step) === 'active'\"\n [class.done]=\"getFlowStepState(step.step) === 'done'\"\n >\n <span class=\"flow-step-index\">{{ step.step }}</span>\n <span class=\"flow-step-content\">\n <span class=\"flow-step-label\">{{ step.label }}</span>\n <span class=\"flow-step-detail\">{{ getFlowStepDetail(step.step) }}</span>\n </span>\n </div>\n }\n </div>\n }\n <div class=\"assistant-nav\">\n <div\n class=\"assistant-tabs\"\n role=\"tablist\"\n aria-label=\"Se\u00E7\u00F5es do assistente\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n @if (isTaskMode()) {\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-task\"\n role=\"tab\"\n aria-label=\"Proposta atual\"\n [attr.aria-selected]=\"isActiveTab('task')\"\n aria-controls=\"assistant-panel-task\"\n [attr.tabindex]=\"isActiveTab('task') ? 0 : -1\"\n [class.active]=\"isActiveTab('task')\"\n (click)=\"setActiveTab('task')\"\n >\n Proposta\n @if (hasPendingClarification() && !isActiveTab('task')) {\n <span class=\"assistant-tab-badge\">1</span>\n }\n </button>\n }\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-chat\"\n role=\"tab\"\n aria-label=\"Hist\u00F3rico\"\n [attr.aria-selected]=\"isActiveTab('chat')\"\n aria-controls=\"assistant-panel-chat\"\n [attr.tabindex]=\"isActiveTab('chat') ? 0 : -1\"\n [class.active]=\"isActiveTab('chat')\"\n (click)=\"setActiveTab('chat')\"\n >\n Hist\u00F3rico\n </button>\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-suggestions\"\n role=\"tab\"\n aria-label=\"Sugest\u00F5es de melhoria\"\n [attr.aria-selected]=\"isActiveTab('suggestions')\"\n aria-controls=\"assistant-panel-suggestions\"\n [attr.tabindex]=\"isActiveTab('suggestions') ? 0 : -1\"\n [class.active]=\"isActiveTab('suggestions')\"\n (click)=\"setActiveTab('suggestions')\"\n >\n Sugest\u00F5es\n </button>\n </div>\n </div>\n\n <!-- BODY: Dynamic Content based on State -->\n <div class=\"assistant-body\">\n @if (shouldShowThoughtCard()) {\n <div class=\"assistant-thought assistant-section\">\n <div class=\"assistant-thought-meta\">\n <mat-icon>psychology</mat-icon>\n <span>{{ getThoughtTimingLabel() }}</span>\n </div>\n <div class=\"assistant-thought-summary\">{{ getThoughtSummary() }}</div>\n <div class=\"assistant-thought-plan\">\n <div class=\"assistant-thought-plan-title\">{{ getThoughtPlanTitle() }}</div>\n <div class=\"assistant-thought-plan-actions\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"thought-action-details\"\n (click)=\"openThoughtDetails()\"\n [attr.aria-label]=\"getThoughtDetailsLabel()\"\n [matTooltip]=\"getThoughtDetailsTooltip()\"\n >\n {{ getThoughtDetailsLabel() }}\n </button>\n @if (shouldShowThoughtPreviewAction()) {\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"thought-action-preview\"\n (click)=\"openThoughtPreview()\"\n [matTooltip]=\"getThoughtPreviewTooltip()\"\n >\n Pr\u00E9via\n </button>\n }\n </div>\n <div class=\"assistant-thought-plan-hint\">{{ getThoughtActionHint() }}</div>\n @if (getThoughtChecklist(); as thoughtChecklist) {\n @if (thoughtChecklist.length) {\n <div class=\"assistant-thought-checklist\">\n @for (item of thoughtChecklist; track item) {\n <div class=\"assistant-thought-checklist-item\">\n <mat-icon>radio_button_unchecked</mat-icon>\n <span>{{ item }}</span>\n </div>\n }\n </div>\n }\n @if (isBusyState() && !thoughtChecklist.length) {\n <div class=\"assistant-thought-shimmer\">\n <div class=\"shimmer-line shimmer-line-1\"></div>\n <div class=\"shimmer-line shimmer-line-2\"></div>\n <div class=\"shimmer-line shimmer-line-3\"></div>\n </div>\n }\n }\n </div>\n </div>\n }\n @if (processingInfoVisible) {\n <div class=\"processing-banner\">\n <mat-spinner diameter=\"16\"></mat-spinner>\n <span>{{ aiExplanation || 'Analisando solicita\u00E7\u00E3o e preparando proposta...' }}</span>\n <button mat-button type=\"button\" class=\"processing-retry\" (click)=\"retryProcessing()\">Tentar novamente</button>\n </div>\n }\n @if (historyContext && isActiveTab('chat')) {\n <div\n class=\"assistant-history assistant-section\"\n id=\"assistant-panel-chat\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-chat\"\n >\n <div class=\"section-header\">\n <div class=\"section-heading\">\n <div class=\"section-title\">Hist\u00F3rico</div>\n <div class=\"section-subtitle\">Sess\u00F5es recentes, pedidos reaproveit\u00E1veis e desfazer r\u00E1pido.</div>\n </div>\n <div class=\"history-actions\" role=\"group\" aria-label=\"A\u00E7\u00F5es do hist\u00F3rico\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"historyExpanded = !historyExpanded\"\n [matTooltip]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [attr.aria-label]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [disabled]=\"!historyWarnings.length && !historySessions.length && !activeHistoryMessages.length\"\n >\n <mat-icon>{{ historyExpanded ? 'expand_less' : 'expand_more' }}</mat-icon>\n <span>{{ historyExpanded ? 'Recolher' : 'Expandir' }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"startNewSession()\"\n matTooltip=\"Nova conversa\"\n aria-label=\"Nova conversa\"\n [disabled]=\"isBusyState()\"\n >\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"clearHistory()\"\n matTooltip=\"Limpar hist\u00F3rico local\"\n aria-label=\"Limpar hist\u00F3rico local\"\n class=\"history-action-btn history-action-btn--danger\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar</span>\n </button>\n </div>\n </div>\n @if (historyUndoDeleteSession) {\n <div class=\"history-undo\">\n <span>Sess\u00E3o removida.</span>\n <button mat-button type=\"button\" (click)=\"undoRemoveHistorySession()\">\n Desfazer\n </button>\n </div>\n }\n @if (historyExpanded && historyWarnings.length) {\n <div class=\"history-warnings\">\n <mat-icon>info</mat-icon>\n <div class=\"history-warnings-list\">\n @for (warning of historyWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n <div class=\"history-warnings-hint\">\n Configure headers via API_CONFIG_STORAGE_OPTIONS no host.\n </div>\n </div>\n </div>\n }\n @if (historyExpanded && historySessions.length) {\n <div class=\"history-sessions\">\n @for (session of historySessions; track session) {\n <div\n class=\"history-session\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"selectHistorySession(session.id)\"\n (keydown)=\"onHistorySessionCardKeydown($event, session.id)\"\n [class.active]=\"session.id === activeHistorySession?.id\"\n [matTooltip]=\"getHistorySessionTooltip(session)\"\n [matTooltipDisabled]=\"!session.componentType && !session.componentId\"\n >\n <div class=\"history-session-main\">\n <span class=\"history-session-title\">{{ session.title }}</span>\n <div class=\"history-session-main-right\">\n <span class=\"history-session-time\">{{ session.updatedAt | date:'short' }}</span>\n <div class=\"history-session-tools\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool\"\n (click)=\"reuseHistorySessionPrompt(session.id, $event)\"\n matTooltip=\"Reusar \u00FAltimo pedido\"\n aria-label=\"Reusar \u00FAltimo pedido\"\n >\n <mat-icon>edit_note</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool history-session-tool--danger\"\n (click)=\"removeHistorySession(session.id, $event)\"\n matTooltip=\"Excluir sess\u00E3o\"\n aria-label=\"Excluir sess\u00E3o\"\n >\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <div class=\"history-session-meta\">\n @if (session.componentType) {\n <span class=\"history-chip\">{{ session.componentType }}</span>\n }\n @if (session.componentId) {\n <span class=\"history-chip\">{{ session.componentId }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n @if (historyExpanded && !historySessions.length) {\n <div class=\"history-empty\">\n Nenhuma sess\u00E3o salva ainda.\n </div>\n }\n @if (historyExpanded && activeHistoryMessages.length) {\n <div class=\"history-messages\">\n @if (activeHistoryTotalMessages > activeHistoryMessages.length) {\n <div\n class=\"history-messages-hint\"\n >\n Mostrando \u00FAltimas {{ activeHistoryMessages.length }} de {{ activeHistoryTotalMessages }} mensagens.\n </div>\n }\n @for (msg of activeHistoryMessages; track msg) {\n <div\n class=\"history-message\"\n [class.user]=\"msg.role === 'user'\"\n [class.assistant]=\"msg.role === 'assistant'\"\n >\n <div class=\"history-message-header\">\n <span class=\"history-message-role\">{{ msg.role === 'user' ? 'Voc\u00EA' : 'Assistente' }}</span>\n <span class=\"history-message-time\">{{ msg.createdAt | date:'shortTime' }}</span>\n @if (msg.context?.usedRag) {\n <span\n class=\"history-rag\"\n matTooltip=\"Resposta baseada em contexto recuperado (RAG)\"\n >RAG</span>\n }\n </div>\n <div class=\"history-message-text\">{{ msg.text }}</div>\n </div>\n }\n </div>\n }\n @if (historyExpanded && historySessions.length && !activeHistoryMessages.length) {\n <div class=\"history-empty history-empty--panel\">\n Selecione uma sess\u00E3o para visualizar as mensagens.\n </div>\n }\n @if (historyExpanded) {\n <div class=\"history-helper\">\n O hist\u00F3rico \u00E9 local ao usu\u00E1rio e ao componente atual.\n </div>\n }\n </div>\n }\n\n @if (loadingSuggestions && isActiveTab('suggestions')) {\n <div\n class=\"loading-suggestions assistant-section\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <mat-spinner diameter=\"20\"></mat-spinner>\n <span>Carregando sugest\u00F5es de melhoria...</span>\n </div>\n }\n\n <!-- STATE: LISTENING (Suggestions) -->\n @if (state === 'listening' && isActiveTab('suggestions')) {\n <div\n class=\"suggestions-area assistant-section\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <div class=\"section-header\">\n <div class=\"section-title\">Sugest\u00F5es de melhoria</div>\n <div class=\"suggestions-actions\">\n <button mat-icon-button type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\" matTooltip=\"Atualizar sugest\u00F5es\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n @if (!loadingSuggestions) {\n <div class=\"suggestions-hero\">\n <div class=\"suggestions-hero__label\">Contexto ativo</div>\n <div class=\"suggestions-hero__title\">{{ adapter.componentName || 'Componente atual' }}</div>\n <div class=\"suggestions-hero__detail\">{{ getSystemStatusDetail() }}</div>\n </div>\n }\n @if (suggestionsWarnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of suggestionsWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (!loadingSuggestions && (richSuggestions.length || hasDismissedSuggestions())) {\n <div class=\"suggestions-content\">\n @if (hasDismissedSuggestions()) {\n <div class=\"suggestions-filter\">\n <span>{{ getDismissedSuggestionCount() }} oculta(s)</span>\n <button mat-button type=\"button\" (click)=\"restoreDismissedSuggestions()\">\n Restaurar\n </button>\n </div>\n }\n @if (getVisibleSuggestions().length) {\n <div class=\"suggestions-list\">\n @for (sug of getVisibleSuggestions(); track sug) {\n <div\n class=\"suggestion-item\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Selecionar sugest\u00E3o: ' + sug.label\"\n (click)=\"selectSuggestion(sug)\"\n (keydown)=\"onSuggestionCardKeydown($event, sug)\"\n >\n <div class=\"suggestion-copy\">\n <div class=\"suggestion-main\">\n @if (sug.icon) {\n <mat-icon class=\"suggestion-icon\">{{ sug.icon }}</mat-icon>\n }\n <span class=\"suggestion-label\">{{ sug.label }}</span>\n @if (sug.group) {\n <span class=\"suggestion-group\">{{ sug.group }}</span>\n }\n </div>\n @if (sug.description) {\n <div class=\"suggestion-desc\">{{ sug.description }}</div>\n }\n </div>\n <div class=\"suggestion-actions\">\n <span class=\"suggestion-arrow\" aria-hidden=\"true\">\n <mat-icon>chevron_right</mat-icon>\n </span>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn\"\n (click)=\"prepareSuggestionPrompt(sug, $event)\"\n matTooltip=\"Refinar pedido\"\n aria-label=\"Refinar pedido\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn suggestion-action-btn--danger\"\n (click)=\"dismissSuggestion(sug, $event)\"\n matTooltip=\"Ocultar sugest\u00E3o\"\n aria-label=\"Ocultar sugest\u00E3o\"\n >\n <mat-icon>visibility_off</mat-icon>\n </button>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"suggestions-empty suggestions-empty--inline\">\n Todas as sugest\u00F5es foram ocultadas.\n </div>\n }\n </div>\n }\n @if (!loadingSuggestions && !richSuggestions.length) {\n <div class=\"suggestions-empty\">\n Nenhuma sugest\u00E3o dispon\u00EDvel no momento.\n </div>\n }\n @if (!loadingSuggestions && !richSuggestions.length) {\n <div class=\"suggestions-helper\">\n Selecione uma sugest\u00E3o acima ou descreva uma altera\u00E7\u00E3o no campo inferior.\n </div>\n }\n </div>\n }\n\n <!-- STATE: CLARIFICATION (Two-Step Flow) -->\n @if (state === 'clarification' && isActiveTab('task')) {\n <div\n class=\"clarification-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n @if (!shouldShowThoughtCard()) {\n <div class=\"task-header\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n @if (clarificationOptions.length > 1 && getTaskSelectionSummary(); as selectionSummary) {\n <div class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n }\n @if (shouldShowTaskSteps()) {\n <div class=\"task-steps\">\n <span class=\"task-step active\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step\">3 Revis\u00E3o</span>\n </div>\n }\n </div>\n }\n @if (clarificationResponseType === 'context') {\n <div class=\"context-only\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n <div class=\"context-only-hint\">Buscando contexto adicional...</div>\n </div>\n }\n <ng-template #clarificationOptionContent let-opt let-index=\"index\" let-compact=\"compact\">\n @if (!compact) {\n <div class=\"clarification-decision-head\">\n <span class=\"clarification-decision-index\">{{ index + 1 }}</span>\n <span class=\"clarification-decision-type\">{{ getClarificationOptionKindLabel(opt) }}</span>\n <span class=\"spacer\"></span>\n @if (isClarificationSelected(opt)) {\n <span class=\"clarification-decision-state\">Selecionado</span>\n }\n </div>\n }\n @switch (getClarificationOptionLayout(opt)) {\n @case ('endpoint') {\n <div class=\"clarification-card\">\n <div class=\"clarification-card-header\">\n <mat-icon class=\"endpoint-icon\">{{ getEndpointIcon(opt) }}</mat-icon>\n @if (getEndpointMethod(opt); as method) {\n <span class=\"endpoint-method\" [attr.data-method]=\"method\">{{ method }}</span>\n }\n <span class=\"endpoint-label\">{{ opt.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon class=\"select-indicator\">\n {{ isClarificationSelected(opt) ? 'check_circle' : 'radio_button_unchecked' }}\n </mat-icon>\n </div>\n <div class=\"clarification-card-body\">\n @if (getEndpointPath(opt); as path) {\n <div class=\"endpoint-path\">{{ path }}</div>\n }\n @if (opt.contextHints?.description) {\n <div\n class=\"endpoint-description\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </div>\n }\n </div>\n </div>\n }\n @case ('color') {\n <div class=\"clarification-color\">\n <span\n class=\"color-swatch\"\n [style.background]=\"getSafeHexColor(opt) || 'var(--md-sys-color-surface-container-highest)'\"\n ></span>\n <div class=\"color-meta\">\n <span class=\"color-label\">{{ opt.label }}</span>\n @if (opt.contextHints?.hexColor) {\n <span class=\"color-value\">{{ opt.contextHints?.hexColor }}</span>\n }\n </div>\n </div>\n }\n @case ('description') {\n <div class=\"clarification-description\">\n <span class=\"clarification-label\">{{ opt.label }}</span>\n @if (opt.contextHints?.description) {\n <span\n class=\"clarification-subtitle\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </span>\n }\n </div>\n }\n @default {\n <span class=\"clarification-plain-label\">{{ opt.label }}</span>\n }\n }\n </ng-template>\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (clarificationQuestions.length) {\n <div\n class=\"clarification-questions\"\n [class.attention-highlight]=\"highlightClarificationDetails && !clarificationOptions.length\"\n >\n @for (question of clarificationQuestions; track question; let i = $index) {\n <div class=\"clarification-question\">\n <div class=\"clarification-question-label\">{{ question }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationAnswers[i]\"\n [placeholder]=\"'Resposta ' + (i + 1)\"\n autocomplete=\"off\">\n </div>\n }\n </div>\n }\n @if (clarificationOptions.length) {\n <div\n class=\"clarification-options-block\"\n [class.attention-highlight]=\"highlightClarificationDetails\"\n >\n <div class=\"clarification-options-title\">\n {{ clarificationOptions.length === 1 ? 'Decis\u00E3o sugerida' : 'Decis\u00F5es sugeridas' }}\n </div>\n @if (clarificationOptions.length === 1) {\n <div class=\"clarification-options-hint\">\n Etapa 2 de 4: confirme a melhor op\u00E7\u00E3o para continuar.\n </div>\n }\n @if (clarificationOptions.length > 1) {\n <div class=\"clarification-options-hint\">\n Etapa 2 de 4: selecione a alternativa mais aderente para gerar a proposta.\n </div>\n }\n @if (clarificationResponseType === 'confirm') {\n <div\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n <button\n mat-button\n type=\"button\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n }\n </div>\n }\n @if (clarificationSelectionMode === 'multiple') {\n <div\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n <button\n mat-button\n type=\"button\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n class=\"clarification-option\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n }\n </div>\n }\n @if (clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation !== 'chips') {\n <div\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n <button\n mat-button\n type=\"button\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n }\n </div>\n }\n @if (clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation === 'chips') {\n <div\n class=\"clarification-chips\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n @if (isEndpointOption(opt)) {\n <button\n mat-button\n type=\"button\"\n class=\"clarification-option clarification-card-button\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n } @else {\n <mat-chip\n (click)=\"onClarificationOptionClick(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt)\"\n class=\"clarification-chip\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: true }\"></ng-container>\n </mat-chip>\n }\n }\n </div>\n }\n </div>\n }\n @if (clarificationAllowCustom && clarificationResponseType !== 'context') {\n <div\n class=\"clarification-manual-toggle\"\n >\n <span class=\"clarification-manual-label\">N\u00E3o encontrou o recurso?</span>\n <button mat-button type=\"button\" (click)=\"toggleManualInput()\">\n {{ showManualInput ? 'Ocultar resposta manual' : 'Responder manualmente' }}\n </button>\n </div>\n }\n @if (clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context') {\n <div\n class=\"clarification-free\"\n >\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationFreeText\"\n placeholder=\"Digite sua resposta\u2026\"\n autocomplete=\"off\"\n (keydown.enter)=\"confirmTaskAction()\"\n />\n </div>\n }\n @if (clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context') {\n <div\n class=\"clarification-free-hint\"\n >\n Pressione Enter para enviar.\n </div>\n }\n </div>\n }\n\n <!-- STATE: REVIEW (Diff/Explanation) -->\n @if (state === 'review' && isActiveTab('task')) {\n <div\n class=\"review-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n @if (!shouldShowThoughtCard()) {\n <div class=\"task-header\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n @if (clarificationOptions.length > 1 && getTaskSelectionSummary(); as selectionSummary) {\n <div class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n }\n @if (shouldShowTaskSteps()) {\n <div class=\"task-steps\">\n <span class=\"task-step\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step active\">3 Revis\u00E3o</span>\n </div>\n }\n </div>\n }\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n <div class=\"review-trust\">\n <span class=\"trust-chip\" [matTooltip]=\"getScopeTooltip()\">{{ getScopeLabel() }}</span>\n <span class=\"trust-chip\" [matTooltip]=\"getConfidenceTooltip()\">{{ getConfidenceLabel() }}</span>\n <span class=\"trust-chip risk-chip\" [class.medium]=\"getReviewRiskLevel() === 'm\u00E9dio'\" [class.high]=\"getReviewRiskLevel() === 'alto'\">\n Risco {{ getReviewRiskLevel() }}\n </span>\n </div>\n <div class=\"review-summary\" [class.attention-highlight]=\"highlightReviewDetails\">\n <div class=\"review-summary-title\">Resumo da proposta</div>\n <div class=\"review-summary-line\">{{ getReviewSummary() }}</div>\n </div>\n <div class=\"review-diff\">\n <div class=\"review-diff-title\">Pr\u00E9via de mudan\u00E7as</div>\n @if (pendingDiff.length) {\n <div class=\"review-diff-summary\">\n @for (line of getDiffSummaryLines(); track line) {\n <div class=\"review-diff-line\">{{ line }}</div>\n }\n @if (pendingDiff.length > 3) {\n <div class=\"review-diff-more\">\u2026 +{{ pendingDiff.length - 3 }} mudan\u00E7as</div>\n }\n </div>\n <button mat-stroked-button type=\"button\" class=\"review-diff-toggle\" (click)=\"toggleFullDiff()\">\n {{ getDiffToggleLabel() }}\n </button>\n } @else {\n <div class=\"review-diff-empty\">\n N\u00E3o foi poss\u00EDvel gerar um diff estruturado. Revise o resumo e aplique com cautela.\n </div>\n }\n @if (showFullDiff && pendingDiff.length) {\n <div class=\"review-diff-full\">\n @for (diff of pendingDiff; track diff) {\n <div class=\"review-diff-block\">\n <div class=\"review-diff-path\">{{ diff.path }}</div>\n <div class=\"review-diff-label\">Antes:</div>\n <pre>{{ diff.before | json }}</pre>\n <div class=\"review-diff-label\">Depois:</div>\n <pre>{{ diff.after | json }}</pre>\n </div>\n }\n </div>\n }\n </div>\n @if (aiExplanation.trim()) {\n <div class=\"ai-explanation\">\n {{ aiExplanation }}\n </div>\n }\n </div>\n }\n\n <!-- STATE: ERROR -->\n @if (state === 'error' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))) {\n <div\n class=\"error-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"error-msg\">\n <mat-icon color=\"warn\">error_outline</mat-icon>\n <span>{{ errorMsg }}</span>\n </div>\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (shouldShowApplyDetails()) {\n <div class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n @if (allowManualPatchEdit) {\n <div class=\"apply-details-actions\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar patch' }}\n </button>\n </div>\n }\n </div>\n @if (lastApplyAt) {\n <div class=\"apply-details-meta\">\n \u00DAltima tentativa: {{ lastApplyAt | date:'short' }}\n </div>\n }\n @if (getApplyPaths().length) {\n <div class=\"apply-paths\">\n @for (path of getApplyPaths(); track path) {\n <span class=\"apply-path-chip\">{{ path }}</span>\n }\n </div>\n }\n @if (applyWarnings.length) {\n <div class=\"apply-warnings\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n @for (warning of applyWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchPathEditorExpanded) {\n <div class=\"patch-path-editor\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n @if (!getEditablePatchPathEdits().length) {\n <div class=\"patch-path-editor-empty\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n }\n @if (getEditablePatchPathEdits().length) {\n <div class=\"patch-path-rows\">\n @for (edit of getEditablePatchPathEdits(); track edit; let i = $index) {\n <div class=\"patch-path-row\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (patchPathEdits[i].error) {\n <div class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n }\n </div>\n }\n </div>\n }\n @if (patchPathEditorError) {\n <div class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchEditorExpanded) {\n <div class=\"patch-editor\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n @if (patchEditorError) {\n <div class=\"patch-editor-error\">{{ patchEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n }\n </div>\n }\n <div class=\"review-actions\">\n <button mat-button (click)=\"close()\">Fechar</button>\n <button mat-stroked-button (click)=\"retry()\">Tentar Novamente</button>\n </div>\n </div>\n }\n\n <!-- STATE: SUCCESS -->\n @if (state === 'success' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))) {\n <div\n class=\"success-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"success-msg\">\n <mat-icon class=\"success-icon\">check_circle</mat-icon>\n <span>{{ aiExplanation || 'Configura\u00E7\u00E3o atualizada.' }}</span>\n </div>\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (shouldShowApplyDetails()) {\n <div class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n @if (allowManualPatchEdit) {\n <div class=\"apply-details-actions\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar e reaplicar' }}\n </button>\n </div>\n }\n </div>\n @if (lastApplyAt) {\n <div class=\"apply-details-meta\">\n Aplicado em {{ lastApplyAt | date:'short' }}\n </div>\n }\n @if (getApplyPaths().length) {\n <div class=\"apply-paths\">\n @for (path of getApplyPaths(); track path) {\n <span class=\"apply-path-chip\">{{ path }}</span>\n }\n </div>\n }\n @if (applyWarnings.length) {\n <div class=\"apply-warnings\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n @for (warning of applyWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchPathEditorExpanded) {\n <div class=\"patch-path-editor\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n @if (!getEditablePatchPathEdits().length) {\n <div class=\"patch-path-editor-empty\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n }\n @if (getEditablePatchPathEdits().length) {\n <div class=\"patch-path-rows\">\n @for (edit of getEditablePatchPathEdits(); track edit; let i = $index) {\n <div class=\"patch-path-row\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (patchPathEdits[i].error) {\n <div class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n }\n </div>\n }\n </div>\n }\n @if (patchPathEditorError) {\n <div class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchEditorExpanded) {\n <div class=\"patch-editor\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n @if (patchEditorError) {\n <div class=\"patch-editor-error\">{{ patchEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n }\n </div>\n }\n <button mat-button color=\"warn\" (click)=\"undoLastChange()\">\n <mat-icon>undo</mat-icon> Desfazer\n </button>\n </div>\n }\n\n </div>\n\n <div class=\"assistant-footer\">\n @if (!isTaskMode()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"composer-leading composer-leading-btn\"\n [matMenuTriggerFor]=\"assistantQuickMenu\"\n aria-label=\"Abrir a\u00E7\u00F5es r\u00E1pidas\"\n matTooltip=\"A\u00E7\u00F5es r\u00E1pidas\"\n >\n <mat-icon>add</mat-icon>\n </button>\n <input\n #inputEl\n type=\"text\"\n [(ngModel)]=\"userPrompt\"\n [disabled]=\"state === 'processing' || state === 'applying'\"\n placeholder=\"Descreva a altera\u00E7\u00E3o que deseja aplicar\u2026\"\n autocomplete=\"off\"\n />\n <div class=\"send-actions\">\n @if (state === 'listening') {\n <button\n mat-icon-button\n class=\"send-btn\"\n (click)=\"submitPrompt()\"\n [disabled]=\"!userPrompt.trim()\"\n [class.ready]=\"!!userPrompt.trim()\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n }\n @if (state === 'processing' || state === 'applying') {\n <mat-spinner diameter=\"20\"></mat-spinner>\n }\n </div>\n } @else {\n <div class=\"task-footer\">\n <div class=\"task-footer-left\">\n <button mat-button type=\"button\" (click)=\"handleTaskSecondary()\">{{ getTaskCancelLabel() }}</button>\n @if (state === 'review') {\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"retry()\"\n >\n {{ getTaskSecondaryLabel() }}\n </button>\n }\n </div>\n <div class=\"task-footer-right\">\n <button\n class=\"task-primary-btn\"\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"confirmTaskAction()\"\n [disabled]=\"isTaskPrimaryDisabled()\"\n >\n {{ getTaskPrimaryLabel() }}\n </button>\n @if (state === 'processing' || state === 'applying') {\n <mat-spinner diameter=\"20\"></mat-spinner>\n }\n </div>\n </div>\n }\n </div>\n\n <mat-menu #assistantQuickMenu=\"matMenu\" panelClass=\"assistant-quick-menu-panel\">\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('chat')\">\n <mat-icon>history</mat-icon>\n <span>Hist\u00F3rico</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('suggestions')\">\n <mat-icon>lightbulb</mat-icon>\n <span>Sugest\u00F5es</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"startNewSession()\">\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\">\n <mat-icon>refresh</mat-icon>\n <span>Atualizar sugest\u00F5es</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n (click)=\"restoreDismissedSuggestions()\"\n [disabled]=\"!hasDismissedSuggestions()\"\n >\n <mat-icon>visibility</mat-icon>\n <span>Restaurar sugest\u00F5es ocultas</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n class=\"assistant-quick-menu-danger\"\n (click)=\"clearHistory()\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar hist\u00F3rico local</span>\n </button>\n </mat-menu>\n </div>\n\n</ng-template>\n", styles: ["@keyframes assistantPremiumEnter{0%{opacity:0;transform:translate(14px) scale(.99)}to{opacity:1;transform:translate(0) scale(1)}}:host ::ng-deep .ai-assistant-backdrop{background:color-mix(in srgb,var(--md-sys-color-scrim, var(--md-sys-color-shadow, var(--md-sys-color-on-surface))) 42%,transparent);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}::ng-deep .ai-assistant-overlay-pane{max-width:calc(100vw - 24px);max-height:calc(100vh - 24px)}.ai-assistant-panel{box-sizing:border-box;width:min(604px,100vw - 18px);min-height:min(620px,100vh - 18px);max-height:min(820px,100vh - 18px);display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border-left:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-top:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));box-shadow:0 18px 48px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 42%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);background:radial-gradient(circle at 14% 8%,color-mix(in srgb,var(--md-sys-color-primary-container) 38%,transparent) 0%,transparent 44%),linear-gradient(165deg,color-mix(in srgb,var(--md-sys-color-surface-container-highest) 88%,var(--md-sys-color-surface)),var(--md-sys-color-surface));animation:assistantPremiumEnter .24s cubic-bezier(.22,1,.36,1)}.assistant-header{position:relative;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:12px 16px 10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(130deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.assistant-header:after{content:\"\";position:absolute;left:16px;right:16px;bottom:-1px;height:1px;background:linear-gradient(90deg,color-mix(in srgb,var(--md-sys-color-primary) 55%,transparent),transparent);pointer-events:none}.assistant-header .assistant-header__left{min-width:0;display:flex;align-items:flex-start;gap:12px}.assistant-header .magic-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:30px;height:30px;font-size:18px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent);box-shadow:0 4px 12px color-mix(in srgb,var(--md-sys-color-primary) 26%,transparent)}.assistant-header .assistant-title-group{min-width:0;display:flex;flex-direction:column;gap:4px}.assistant-header .assistant-title{font-size:15px;font-weight:700;letter-spacing:.01em;overflow-wrap:anywhere}.assistant-header .assistant-subtitle{display:block;font-size:11px;line-height:1.25;color:color-mix(in srgb,var(--md-sys-color-on-surface) 70%,var(--md-sys-color-on-surface-variant));overflow-wrap:anywhere}.assistant-header-chips{display:inline-flex;align-items:center;flex-wrap:wrap;gap:6px}.assistant-header .mode-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 28%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 64%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-primary-container) 85%,var(--md-sys-color-on-surface));font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.assistant-header .mode-chip:before{content:\"\";width:6px;height:6px;border-radius:999px;background:currentColor;box-shadow:0 0 0 3px color-mix(in srgb,currentColor 16%,transparent)}.assistant-header .mode-chip.mock{border-color:color-mix(in srgb,var(--md-sys-color-error) 34%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-error-container) 72%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-error-container) 85%,var(--md-sys-color-error))}.assistant-header .policy-chip{padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 84%,transparent);background:var(--md-sys-color-surface-container-high);font-size:10px;letter-spacing:.02em;font-weight:600}.assistant-header .policy-chip.strict{border-color:color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 56%,var(--md-sys-color-surface-container-high))}.assistant-status{display:flex;align-items:flex-start;gap:10px;padding:10px 16px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-radius:0;background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 24%,transparent),transparent 48%),var(--md-sys-color-surface-container-low)}.assistant-status-dot{width:8px;height:8px;margin-top:6px;border-radius:999px;flex:0 0 auto;background:var(--md-sys-color-primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.assistant-status.warning .assistant-status-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.assistant-status.success .assistant-status-dot{background:color-mix(in srgb,var(--md-sys-color-primary) 74%,var(--md-sys-color-tertiary, var(--md-sys-color-primary)))}.assistant-status-content{min-width:0;display:flex;flex-direction:column;gap:2px}.assistant-status-label{display:flex;align-items:center;flex-wrap:wrap;gap:4px;font-size:12px;font-weight:700;line-height:1.35}.assistant-status-detail{font-size:11px;line-height:1.4;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.assistant-status-mode{padding:1px 6px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent);color:var(--md-sys-color-on-primary-container);font-size:10px;font-weight:700}.assistant-nav{padding:8px 16px 0}.assistant-nav .assistant-tabs{display:flex;align-items:center;gap:4px;border-radius:12px;padding:5px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(155deg,color-mix(in srgb,var(--md-sys-color-primary-container) 14%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-nav .assistant-tab{appearance:none;min-width:0;min-height:30px;border:0;border-radius:8px;padding:0 10px;background:transparent;color:var(--md-sys-color-on-surface-variant);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex:1 1 0;font-size:11px;font-weight:700;letter-spacing:.01em}.assistant-nav .assistant-tab.active{background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent),0 6px 12px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.assistant-section,.assistant-card{border-radius:14px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 50%),var(--md-sys-color-surface-container-lowest);box-shadow:0 6px 18px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 7%,transparent)}.suggestions-hero{margin:2px 0 4px;padding:10px 12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(120deg,color-mix(in srgb,var(--md-sys-color-primary-container) 34%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.suggestions-hero__label{font-size:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:var(--md-sys-color-on-surface-variant);opacity:.88}.suggestions-hero__title{margin-top:2px;font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.suggestions-hero__detail{margin-top:4px;font-size:12px;line-height:1.4;color:color-mix(in srgb,var(--md-sys-color-on-surface) 78%,var(--md-sys-color-on-surface-variant))}.suggestions-content .suggestion-item{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(140deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-lowest);transition:transform .2s cubic-bezier(.25,.8,.25,1),border-color .2s ease,box-shadow .2s ease}.suggestions-list{display:flex;flex-direction:column;gap:10px}.suggestion-copy{min-width:0;display:grid;gap:4px}.suggestion-main{min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.suggestion-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto;color:var(--md-sys-color-primary)}.suggestion-label{min-width:0;font-size:13px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestion-group{padding:2px 6px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:10px;font-weight:700;line-height:1.2}.suggestion-desc{font-size:12px;line-height:1.35;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.suggestion-actions{display:inline-flex;align-items:center;justify-content:flex-end;gap:4px}.suggestion-action-btn,.suggestion-arrow{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--md-sys-color-on-surface-variant)}.suggestions-content .suggestion-item:hover,.suggestions-content .suggestion-item:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant));box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 28%,transparent);transform:translateY(-2px) scale(1.01)}.assistant-footer{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:10px 16px;border-top-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-low)}.assistant-footer .task-footer{grid-column:1/-1}.composer-leading{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 70%,var(--md-sys-color-surface-container-low));color:var(--md-sys-color-primary);box-shadow:0 4px 10px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.composer-leading mat-icon{width:16px;height:16px;font-size:16px}.assistant-footer input{box-sizing:border-box;width:100%;min-width:0;height:34px;border:1px solid;border-radius:8px;padding:0 12px;color:var(--md-sys-color-on-surface);border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface);box-shadow:inset 0 1px 2px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent)}.send-actions{min-width:36px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn{--mdc-icon-button-icon-size: 20px;--mdc-icon-button-state-layer-size: 36px;--mat-icon-button-state-layer-size: 36px;width:36px;height:36px;padding:8px;line-height:1;display:inline-flex;align-items:center;justify-content:center;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface)}.assistant-footer .send-btn mat-icon{width:20px;height:20px;margin:0;font-size:20px;line-height:20px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn.ready{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary-container) 84%,var(--md-sys-color-primary)),var(--md-sys-color-primary));color:var(--md-sys-color-on-primary);box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent)}.task-primary-btn{border-radius:12px;box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 24%,transparent)}@media(max-width:959px){.assistant-header{padding:12px 12px 10px}.assistant-section,.assistant-card{margin:4px 12px 10px}.assistant-header:after{left:12px;right:12px}.assistant-header .assistant-title{font-size:14px}.assistant-header .assistant-subtitle{font-size:10px}.assistant-footer{grid-template-columns:minmax(0,1fr) auto}.composer-leading{display:none}}.assistant-thought{margin-top:0;gap:10px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-thought-meta{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-meta mat-icon{width:15px;height:15px;font-size:15px;color:var(--md-sys-color-primary)}.assistant-thought-summary{font-size:13px;line-height:1.45;color:var(--md-sys-color-on-surface)}.assistant-thought-plan{border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 32%,var(--md-sys-color-outline-variant));border-radius:12px;padding:10px;background:var(--md-sys-color-surface-container-lowest);display:flex;flex-direction:column;gap:8px}.assistant-thought-plan-title{font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.assistant-thought-plan-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px}.assistant-thought-plan-actions .mdc-button{min-width:0}.assistant-thought-plan-hint{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.35}.assistant-thought-checklist{display:flex;flex-direction:column;gap:5px}.assistant-thought-checklist-item{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-checklist-item mat-icon{width:14px;height:14px;font-size:14px}.assistant-thought-shimmer{display:flex;flex-direction:column;gap:8px;margin-top:4px}.assistant-thought-shimmer .shimmer-line{height:12px;border-radius:4px;position:relative;overflow:hidden;background:var(--md-sys-color-surface-container-highest)}.assistant-thought-shimmer .shimmer-line:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent);animation:assistantShimmerEffect 1.5s infinite}.assistant-thought-shimmer .shimmer-line-1{width:85%}.assistant-thought-shimmer .shimmer-line-2{width:92%}.assistant-thought-shimmer .shimmer-line-3{width:64%}@keyframes assistantShimmerEffect{to{transform:translate(100%)}}.assistant-flow{grid-template-columns:1fr;gap:6px}.flow-step{display:flex;align-items:flex-start;gap:8px;text-align:left;padding:7px 8px;border-radius:10px}.flow-step-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.flow-step-content{min-width:0;display:flex;flex-direction:column;gap:1px}.flow-step-label{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.flow-step-detail{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.3}.flow-step.active .flow-step-index{border-color:color-mix(in srgb,var(--md-sys-color-primary) 60%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 85%,var(--md-sys-color-surface-container-highest));color:var(--md-sys-color-on-primary-container)}.flow-step.done .flow-step-index{border-color:transparent;background:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-surface-container-highest))}.task-timeline{margin-top:4px;display:grid;gap:6px}.task-timeline-item{display:flex;align-items:flex-start;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);opacity:.76}.task-timeline-item.active{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 40%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-low))}.task-timeline-item.done{opacity:.9;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant))}.task-timeline-dot{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.task-timeline-copy{min-width:0;display:flex;flex-direction:column;gap:1px}.task-timeline-title{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.task-timeline-detail{font-size:11px;line-height:1.3;color:var(--md-sys-color-on-surface-variant)}.clarification-decision-head{display:inline-flex;align-items:center;width:100%;gap:6px;padding:8px 12px 0;box-sizing:border-box}.clarification-decision-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 68%,transparent)}.clarification-decision-type{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);opacity:.92}.clarification-decision-state{font-size:10px;font-weight:700;color:var(--md-sys-color-primary)}.clarification-option{border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 55%),var(--md-sys-color-surface-container-low)}.clarification-option.selected{border-color:color-mix(in srgb,var(--md-sys-color-primary) 56%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 44%,transparent),transparent 62%),var(--md-sys-color-surface-container);box-shadow:0 8px 16px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.clarification-options-block{overflow:visible;padding-right:4px}@media(max-width:959px){.assistant-thought-plan-actions{grid-template-columns:1fr}}.ai-assistant-panel{width:min(604px,100vw - 18px)}.assistant-section,.assistant-card{margin:0;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant))}.assistant-section{min-height:0;padding:14px 16px;overflow:visible}.assistant-card{min-height:0;padding:14px 16px 16px;overflow:visible}.suggestions-area,.assistant-history,.loading-suggestions{overflow-y:auto;overflow-x:hidden}.section-header{min-width:0;display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}.section-title{min-width:0;font-size:14px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestions-actions{flex:0 0 auto;display:inline-flex;align-items:center}.review-area,.error-area,.success-area,.clarification-area{padding:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:auto}.review-trust{margin:2px 0 4px}.trust-chip{max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.warnings-area,.review-summary,.review-diff,.apply-details,.clarification-options-block,.clarification-manual-toggle{width:100%;max-width:100%;min-width:0}.review-diff{padding:12px 14px}.review-diff-full{padding:10px;overflow-x:auto}.review-diff-block{min-width:0}.review-diff-block pre{overflow-wrap:anywhere;word-break:break-word}.clarification-options-block{padding:4px 2px 10px}.clarification-option{line-height:normal}:host ::ng-deep .clarification-option .mdc-button__label{line-height:1.35!important}.clarification-plain-label{padding:6px 12px 12px;font-size:14px;line-height:1.35}.clarification-manual-toggle{margin-top:10px;padding:10px 2px 0;flex-wrap:wrap;row-gap:6px}.suggestions-content .suggestion-actions{gap:6px}.suggestions-content .suggestion-arrow,.suggestions-content .suggestion-action-btn mat-icon,.suggestions-content .suggestion-arrow mat-icon{display:inline-flex;align-items:center;justify-content:center}:host ::ng-deep .assistant-quick-menu-panel{min-width:244px;max-width:min(90vw,320px);border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high);box-shadow:0 12px 28px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 32%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 6%,transparent);overflow:hidden;padding:6px}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item{min-height:36px;border-radius:10px;color:var(--md-sys-color-on-surface);font-size:12px;font-weight:500;margin:1px 0}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item .mat-icon{color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,var(--md-sys-color-on-surface-variant))}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:hover:not([disabled]){background:color-mix(in srgb,var(--md-sys-color-primary-container) 45%,transparent)}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:-2px}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger{color:var(--md-sys-color-error)}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger .mat-icon{color:var(--md-sys-color-error)}@media(max-width:959px){::ng-deep .ai-assistant-overlay-pane{top:12px!important;left:12px!important;width:calc(100vw - 24px)!important;height:calc(100vh - 24px)!important;max-width:calc(100vw - 24px);max-height:calc(100vh - 24px);transform:none!important}.ai-assistant-panel{width:calc(100vw - 48px);min-height:min(620px,100vh - 48px);max-height:calc(100vh - 48px)}.assistant-section,.assistant-card{margin:0}.assistant-card,.assistant-section{padding:12px}}.ai-trigger-btn{--mdc-icon-button-state-layer-size: 36px;width:36px;height:36px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary) 9%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent);color:var(--md-sys-color-primary);opacity:1}.ai-trigger-btn:hover:not(:disabled){background:color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent);border-color:color-mix(in srgb,var(--md-sys-color-primary) 36%,transparent);color:var(--md-sys-color-on-primary-container)}.ai-trigger-btn:focus-visible,.assistant-close-btn:focus-visible,.assistant-tab:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.assistant-close-btn{width:28px;height:28px;color:var(--md-sys-color-on-surface-variant)}.assistant-close-btn:hover:not(:disabled){background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.assistant-body{padding:12px 16px;overflow:hidden;min-height:0;flex:1;display:flex;flex-direction:column;gap:12px}.assistant-body>*{min-height:0}@media(max-width:959px){.assistant-nav{padding:8px 12px 0}.assistant-body,.assistant-footer{padding:10px 12px}.suggestions-content .suggestion-item{grid-template-columns:1fr;align-items:start}.suggestion-actions{justify-content:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i5.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i10.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i10.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i10.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6673
6673
|
}
|
|
6674
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
6674
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantComponent, decorators: [{
|
|
6675
6675
|
type: Component,
|
|
6676
6676
|
args: [{ selector: 'praxis-ai-assistant', standalone: true, imports: [
|
|
6677
|
-
CommonModule,
|
|
6678
6677
|
FormsModule,
|
|
6679
6678
|
OverlayModule,
|
|
6680
6679
|
A11yModule,
|
|
@@ -6685,7 +6684,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
6685
6684
|
MatTooltipModule,
|
|
6686
6685
|
MatChipsModule,
|
|
6687
6686
|
MatMenuModule,
|
|
6688
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Trigger Button -->\n<button \n mat-icon-button \n cdkOverlayOrigin \n #trigger=\"cdkOverlayOrigin\"\n #triggerBtn\n (click)=\"open()\"\n [disabled]=\"isOpen\"\n class=\"ai-trigger-btn\"\n matTooltip=\"Assistente de Configura\u00E7\u00E3o\"\n aria-label=\"Abrir Assistente IA\">\n <mat-icon>auto_awesome</mat-icon>\n</button>\n\n<!-- Overlay Template -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"12\"\n cdkConnectedOverlayPanelClass=\"ai-assistant-overlay-pane\"\n cdkConnectedOverlayBackdropClass=\"ai-assistant-backdrop\"\n (backdropClick)=\"close()\"\n (overlayOutsideClick)=\"close()\"\n (detach)=\"close()\">\n\n <div\n class=\"ai-assistant-panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Assistente de Configura\u00E7\u00E3o\"\n [attr.aria-busy]=\"isBusyState() ? 'true' : null\"\n [cdkTrapFocus]=\"hasBackdrop\"\n [cdkTrapFocusAutoCapture]=\"hasBackdrop\"\n (keydown)=\"onKeydown($event)\"\n >\n \n <!-- HEADER -->\n <div class=\"assistant-header\">\n <div class=\"assistant-header__left\">\n <mat-icon class=\"magic-icon\">auto_awesome</mat-icon>\n <div class=\"assistant-title-group\">\n <div class=\"assistant-title\">Assistente de Configura\u00E7\u00E3o</div>\n <div class=\"assistant-subtitle\">Copiloto contextual para ajustes guiados</div>\n <div class=\"assistant-header-chips\">\n <span\n class=\"mode-chip\"\n [class.mock]=\"mockMode\"\n [matTooltip]=\"mockMode ? 'Sem chave de API: respostas de demonstra\u00E7\u00E3o' : 'Conectado ao assistente configurado'\"\n >\n {{ mockMode ? 'Mock' : 'Conectado' }}\n </span>\n <span\n class=\"policy-chip\"\n [class.strict]=\"isStrictRiskPolicy()\"\n [matTooltip]=\"getRiskPolicyTooltip()\"\n >\n {{ getRiskPolicyLabel() }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"assistant-header__right\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"assistant-close-btn\"\n (click)=\"close()\"\n aria-label=\"Fechar assistente\"\n matTooltip=\"Fechar assistente\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n <div\n class=\"assistant-status\"\n [class.processing]=\"isBusyState()\"\n [class.pending]=\"state === 'clarification'\"\n [class.warning]=\"state === 'error'\"\n [class.success]=\"state === 'review' || state === 'success'\"\n [class.compact]=\"!shouldShowSystemStatusDetail()\"\n role=\"status\"\n [attr.aria-live]=\"getSystemStatusAriaLive()\"\n aria-atomic=\"true\"\n >\n <span class=\"assistant-status-dot\" aria-hidden=\"true\"></span>\n <div class=\"assistant-status-content\">\n <div class=\"assistant-status-label\">\n <span class=\"assistant-status-label-prefix\">Status:</span>\n <span>{{ getSystemStatusLabel() }}</span>\n <span *ngIf=\"shouldShowSnapshotFallbackBadge()\" class=\"assistant-status-mode\">Snapshot</span>\n </div>\n <div *ngIf=\"shouldShowSystemStatusDetail()\" class=\"assistant-status-detail\">{{ getSystemStatusDetail() }}</div>\n </div>\n </div>\n <div class=\"assistant-flow\" *ngIf=\"shouldShowTaskFlow()\" role=\"list\" aria-label=\"Fluxo da proposta\">\n <div\n class=\"flow-step\"\n role=\"listitem\"\n *ngFor=\"let step of flowSteps\"\n [class.active]=\"getFlowStepState(step.step) === 'active'\"\n [class.done]=\"getFlowStepState(step.step) === 'done'\"\n >\n <span class=\"flow-step-index\">{{ step.step }}</span>\n <span class=\"flow-step-content\">\n <span class=\"flow-step-label\">{{ step.label }}</span>\n <span class=\"flow-step-detail\">{{ getFlowStepDetail(step.step) }}</span>\n </span>\n </div>\n </div>\n <div class=\"assistant-nav\">\n <div\n class=\"assistant-tabs\"\n role=\"tablist\"\n aria-label=\"Se\u00E7\u00F5es do assistente\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n <button\n class=\"assistant-tab\"\n type=\"button\"\n *ngIf=\"isTaskMode()\"\n id=\"assistant-tab-task\"\n role=\"tab\"\n aria-label=\"Proposta atual\"\n [attr.aria-selected]=\"isActiveTab('task')\"\n aria-controls=\"assistant-panel-task\"\n [attr.tabindex]=\"isActiveTab('task') ? 0 : -1\"\n [class.active]=\"isActiveTab('task')\"\n (click)=\"setActiveTab('task')\"\n >\n Proposta\n <span *ngIf=\"hasPendingClarification() && !isActiveTab('task')\" class=\"assistant-tab-badge\">1</span>\n </button>\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-chat\"\n role=\"tab\"\n aria-label=\"Hist\u00F3rico\"\n [attr.aria-selected]=\"isActiveTab('chat')\"\n aria-controls=\"assistant-panel-chat\"\n [attr.tabindex]=\"isActiveTab('chat') ? 0 : -1\"\n [class.active]=\"isActiveTab('chat')\"\n (click)=\"setActiveTab('chat')\"\n >\n Hist\u00F3rico\n </button>\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-suggestions\"\n role=\"tab\"\n aria-label=\"Sugest\u00F5es de melhoria\"\n [attr.aria-selected]=\"isActiveTab('suggestions')\"\n aria-controls=\"assistant-panel-suggestions\"\n [attr.tabindex]=\"isActiveTab('suggestions') ? 0 : -1\"\n [class.active]=\"isActiveTab('suggestions')\"\n (click)=\"setActiveTab('suggestions')\"\n >\n Sugest\u00F5es\n </button>\n </div>\n </div>\n\n <!-- BODY: Dynamic Content based on State -->\n <div class=\"assistant-body\">\n <div class=\"assistant-thought assistant-section\" *ngIf=\"shouldShowThoughtCard()\">\n <div class=\"assistant-thought-meta\">\n <mat-icon>psychology</mat-icon>\n <span>{{ getThoughtTimingLabel() }}</span>\n </div>\n <div class=\"assistant-thought-summary\">{{ getThoughtSummary() }}</div>\n <div class=\"assistant-thought-plan\">\n <div class=\"assistant-thought-plan-title\">{{ getThoughtPlanTitle() }}</div>\n <div class=\"assistant-thought-plan-actions\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"thought-action-details\"\n (click)=\"openThoughtDetails()\"\n [attr.aria-label]=\"getThoughtDetailsLabel()\"\n [matTooltip]=\"getThoughtDetailsTooltip()\"\n >\n {{ getThoughtDetailsLabel() }}\n </button>\n <button\n *ngIf=\"shouldShowThoughtPreviewAction()\"\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"thought-action-preview\"\n (click)=\"openThoughtPreview()\"\n [matTooltip]=\"getThoughtPreviewTooltip()\"\n >\n Pr\u00E9via\n </button>\n </div>\n <div class=\"assistant-thought-plan-hint\">{{ getThoughtActionHint() }}</div>\n <ng-container *ngIf=\"getThoughtChecklist() as thoughtChecklist\">\n <div class=\"assistant-thought-checklist\" *ngIf=\"thoughtChecklist.length\">\n <div *ngFor=\"let item of thoughtChecklist\" class=\"assistant-thought-checklist-item\">\n <mat-icon>radio_button_unchecked</mat-icon>\n <span>{{ item }}</span>\n </div>\n </div>\n <div class=\"assistant-thought-shimmer\" *ngIf=\"isBusyState() && !thoughtChecklist.length\">\n <div class=\"shimmer-line shimmer-line-1\"></div>\n <div class=\"shimmer-line shimmer-line-2\"></div>\n <div class=\"shimmer-line shimmer-line-3\"></div>\n </div>\n </ng-container>\n </div>\n </div>\n <div *ngIf=\"processingInfoVisible\" class=\"processing-banner\">\n <mat-spinner diameter=\"16\"></mat-spinner>\n <span>{{ aiExplanation || 'Analisando solicita\u00E7\u00E3o e preparando proposta...' }}</span>\n <button mat-button type=\"button\" class=\"processing-retry\" (click)=\"retryProcessing()\">Tentar novamente</button>\n </div>\n <div\n class=\"assistant-history assistant-section\"\n *ngIf=\"historyContext && isActiveTab('chat')\"\n id=\"assistant-panel-chat\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-chat\"\n >\n <div class=\"section-header\">\n <div class=\"section-heading\">\n <div class=\"section-title\">Hist\u00F3rico</div>\n <div class=\"section-subtitle\">Sess\u00F5es recentes, pedidos reaproveit\u00E1veis e desfazer r\u00E1pido.</div>\n </div>\n <div class=\"history-actions\" role=\"group\" aria-label=\"A\u00E7\u00F5es do hist\u00F3rico\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"historyExpanded = !historyExpanded\"\n [matTooltip]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [attr.aria-label]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [disabled]=\"!historyWarnings.length && !historySessions.length && !activeHistoryMessages.length\"\n >\n <mat-icon>{{ historyExpanded ? 'expand_less' : 'expand_more' }}</mat-icon>\n <span>{{ historyExpanded ? 'Recolher' : 'Expandir' }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"startNewSession()\"\n matTooltip=\"Nova conversa\"\n aria-label=\"Nova conversa\"\n [disabled]=\"isBusyState()\"\n >\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"clearHistory()\"\n matTooltip=\"Limpar hist\u00F3rico local\"\n aria-label=\"Limpar hist\u00F3rico local\"\n class=\"history-action-btn history-action-btn--danger\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar</span>\n </button>\n </div>\n </div>\n <div *ngIf=\"historyUndoDeleteSession\" class=\"history-undo\">\n <span>Sess\u00E3o removida.</span>\n <button mat-button type=\"button\" (click)=\"undoRemoveHistorySession()\">\n Desfazer\n </button>\n </div>\n\n <div *ngIf=\"historyExpanded && historyWarnings.length\" class=\"history-warnings\">\n <mat-icon>info</mat-icon>\n <div class=\"history-warnings-list\">\n <div *ngFor=\"let warning of historyWarnings\">{{ warning }}</div>\n <div class=\"history-warnings-hint\">\n Configure headers via API_CONFIG_STORAGE_OPTIONS no host.\n </div>\n </div>\n </div>\n\n <div *ngIf=\"historyExpanded && historySessions.length\" class=\"history-sessions\">\n <div\n class=\"history-session\"\n *ngFor=\"let session of historySessions\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"selectHistorySession(session.id)\"\n (keydown)=\"onHistorySessionCardKeydown($event, session.id)\"\n [class.active]=\"session.id === activeHistorySession?.id\"\n [matTooltip]=\"getHistorySessionTooltip(session)\"\n [matTooltipDisabled]=\"!session.componentType && !session.componentId\"\n >\n <div class=\"history-session-main\">\n <span class=\"history-session-title\">{{ session.title }}</span>\n <div class=\"history-session-main-right\">\n <span class=\"history-session-time\">{{ session.updatedAt | date:'short' }}</span>\n <div class=\"history-session-tools\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool\"\n (click)=\"reuseHistorySessionPrompt(session.id, $event)\"\n matTooltip=\"Reusar \u00FAltimo pedido\"\n aria-label=\"Reusar \u00FAltimo pedido\"\n >\n <mat-icon>edit_note</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool history-session-tool--danger\"\n (click)=\"removeHistorySession(session.id, $event)\"\n matTooltip=\"Excluir sess\u00E3o\"\n aria-label=\"Excluir sess\u00E3o\"\n >\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <div class=\"history-session-meta\">\n <span *ngIf=\"session.componentType\" class=\"history-chip\">{{ session.componentType }}</span>\n <span *ngIf=\"session.componentId\" class=\"history-chip\">{{ session.componentId }}</span>\n </div>\n </div>\n </div>\n <div *ngIf=\"historyExpanded && !historySessions.length\" class=\"history-empty\">\n Nenhuma sess\u00E3o salva ainda.\n </div>\n\n <div *ngIf=\"historyExpanded && activeHistoryMessages.length\" class=\"history-messages\">\n <div\n *ngIf=\"activeHistoryTotalMessages > activeHistoryMessages.length\"\n class=\"history-messages-hint\"\n >\n Mostrando \u00FAltimas {{ activeHistoryMessages.length }} de {{ activeHistoryTotalMessages }} mensagens.\n </div>\n <div\n *ngFor=\"let msg of activeHistoryMessages\"\n class=\"history-message\"\n [class.user]=\"msg.role === 'user'\"\n [class.assistant]=\"msg.role === 'assistant'\"\n >\n <div class=\"history-message-header\">\n <span class=\"history-message-role\">{{ msg.role === 'user' ? 'Voc\u00EA' : 'Assistente' }}</span>\n <span class=\"history-message-time\">{{ msg.createdAt | date:'shortTime' }}</span>\n <span\n *ngIf=\"msg.context?.usedRag\"\n class=\"history-rag\"\n matTooltip=\"Resposta baseada em contexto recuperado (RAG)\"\n >RAG</span>\n </div>\n <div class=\"history-message-text\">{{ msg.text }}</div>\n </div>\n </div>\n <div *ngIf=\"historyExpanded && historySessions.length && !activeHistoryMessages.length\" class=\"history-empty history-empty--panel\">\n Selecione uma sess\u00E3o para visualizar as mensagens.\n </div>\n <div class=\"history-helper\" *ngIf=\"historyExpanded\">\n O hist\u00F3rico \u00E9 local ao usu\u00E1rio e ao componente atual.\n </div>\n </div>\n\n <div\n class=\"loading-suggestions assistant-section\"\n *ngIf=\"loadingSuggestions && isActiveTab('suggestions')\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <mat-spinner diameter=\"20\"></mat-spinner>\n <span>Carregando sugest\u00F5es de melhoria...</span>\n </div>\n \n <!-- STATE: LISTENING (Suggestions) -->\n <div\n *ngIf=\"state === 'listening' && isActiveTab('suggestions')\"\n class=\"suggestions-area assistant-section\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <div class=\"section-header\">\n <div class=\"section-title\">Sugest\u00F5es de melhoria</div>\n <div class=\"suggestions-actions\">\n <button mat-icon-button type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\" matTooltip=\"Atualizar sugest\u00F5es\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"suggestions-hero\" *ngIf=\"!loadingSuggestions\">\n <div class=\"suggestions-hero__label\">Contexto ativo</div>\n <div class=\"suggestions-hero__title\">{{ adapter.componentName || 'Componente atual' }}</div>\n <div class=\"suggestions-hero__detail\">{{ getSystemStatusDetail() }}</div>\n </div>\n <div *ngIf=\"suggestionsWarnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of suggestionsWarnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div class=\"suggestions-content\" *ngIf=\"!loadingSuggestions && (richSuggestions.length || hasDismissedSuggestions())\">\n <div class=\"suggestions-filter\" *ngIf=\"hasDismissedSuggestions()\">\n <span>{{ getDismissedSuggestionCount() }} oculta(s)</span>\n <button mat-button type=\"button\" (click)=\"restoreDismissedSuggestions()\">\n Restaurar\n </button>\n </div>\n <div class=\"suggestions-list\" *ngIf=\"getVisibleSuggestions().length; else allSuggestionsHidden\">\n <div\n class=\"suggestion-item\"\n *ngFor=\"let sug of getVisibleSuggestions()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Selecionar sugest\u00E3o: ' + sug.label\"\n (click)=\"selectSuggestion(sug)\"\n (keydown)=\"onSuggestionCardKeydown($event, sug)\"\n >\n <div class=\"suggestion-copy\">\n <div class=\"suggestion-main\">\n <mat-icon *ngIf=\"sug.icon\" class=\"suggestion-icon\">{{ sug.icon }}</mat-icon>\n <span class=\"suggestion-label\">{{ sug.label }}</span>\n <span *ngIf=\"sug.group\" class=\"suggestion-group\">{{ sug.group }}</span>\n </div>\n <div *ngIf=\"sug.description\" class=\"suggestion-desc\">{{ sug.description }}</div>\n </div>\n <div class=\"suggestion-actions\">\n <span class=\"suggestion-arrow\" aria-hidden=\"true\">\n <mat-icon>chevron_right</mat-icon>\n </span>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn\"\n (click)=\"prepareSuggestionPrompt(sug, $event)\"\n matTooltip=\"Refinar pedido\"\n aria-label=\"Refinar pedido\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn suggestion-action-btn--danger\"\n (click)=\"dismissSuggestion(sug, $event)\"\n matTooltip=\"Ocultar sugest\u00E3o\"\n aria-label=\"Ocultar sugest\u00E3o\"\n >\n <mat-icon>visibility_off</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <ng-template #allSuggestionsHidden>\n <div class=\"suggestions-empty suggestions-empty--inline\">\n Todas as sugest\u00F5es foram ocultadas.\n </div>\n </ng-template>\n </div>\n <div class=\"suggestions-empty\" *ngIf=\"!loadingSuggestions && !richSuggestions.length\">\n Nenhuma sugest\u00E3o dispon\u00EDvel no momento.\n </div>\n <div class=\"suggestions-helper\" *ngIf=\"!loadingSuggestions && !richSuggestions.length\">\n Selecione uma sugest\u00E3o acima ou descreva uma altera\u00E7\u00E3o no campo inferior.\n </div>\n </div>\n\n <!-- STATE: CLARIFICATION (Two-Step Flow) -->\n <div\n *ngIf=\"state === 'clarification' && isActiveTab('task')\"\n class=\"clarification-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n <div class=\"task-header\" *ngIf=\"!shouldShowThoughtCard()\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n <div *ngIf=\"clarificationOptions.length > 1 && getTaskSelectionSummary() as selectionSummary\" class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n <div *ngIf=\"shouldShowTaskSteps()\" class=\"task-steps\">\n <span class=\"task-step active\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step\">3 Revis\u00E3o</span>\n </div>\n </div>\n <div *ngIf=\"clarificationResponseType === 'context'\" class=\"context-only\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n <div class=\"context-only-hint\">Buscando contexto adicional...</div>\n </div>\n <ng-template #clarificationOptionContent let-opt let-index=\"index\" let-compact=\"compact\">\n <div class=\"clarification-decision-head\" *ngIf=\"!compact\">\n <span class=\"clarification-decision-index\">{{ index + 1 }}</span>\n <span class=\"clarification-decision-type\">{{ getClarificationOptionKindLabel(opt) }}</span>\n <span class=\"spacer\"></span>\n <span class=\"clarification-decision-state\" *ngIf=\"isClarificationSelected(opt)\">Selecionado</span>\n </div>\n <ng-container [ngSwitch]=\"getClarificationOptionLayout(opt)\">\n <div *ngSwitchCase=\"'endpoint'\" class=\"clarification-card\">\n <div class=\"clarification-card-header\">\n <mat-icon class=\"endpoint-icon\">{{ getEndpointIcon(opt) }}</mat-icon>\n <ng-container *ngIf=\"getEndpointMethod(opt) as method\">\n <span class=\"endpoint-method\" [attr.data-method]=\"method\">{{ method }}</span>\n </ng-container>\n <span class=\"endpoint-label\">{{ opt.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon class=\"select-indicator\">\n {{ isClarificationSelected(opt) ? 'check_circle' : 'radio_button_unchecked' }}\n </mat-icon>\n </div>\n <div class=\"clarification-card-body\">\n <ng-container *ngIf=\"getEndpointPath(opt) as path\">\n <div class=\"endpoint-path\">{{ path }}</div>\n </ng-container>\n <div\n *ngIf=\"opt.contextHints?.description\"\n class=\"endpoint-description\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </div>\n </div>\n </div>\n <div *ngSwitchCase=\"'color'\" class=\"clarification-color\">\n <span\n class=\"color-swatch\"\n [style.background]=\"getSafeHexColor(opt) || 'var(--md-sys-color-surface-container-highest)'\"\n ></span>\n <div class=\"color-meta\">\n <span class=\"color-label\">{{ opt.label }}</span>\n <span *ngIf=\"opt.contextHints?.hexColor\" class=\"color-value\">{{ opt.contextHints?.hexColor }}</span>\n </div>\n </div>\n <div *ngSwitchCase=\"'description'\" class=\"clarification-description\">\n <span class=\"clarification-label\">{{ opt.label }}</span>\n <span\n *ngIf=\"opt.contextHints?.description\"\n class=\"clarification-subtitle\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </span>\n </div>\n <span *ngSwitchDefault class=\"clarification-plain-label\">{{ opt.label }}</span>\n </ng-container>\n </ng-template>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"clarificationQuestions.length\"\n class=\"clarification-questions\"\n [class.attention-highlight]=\"highlightClarificationDetails && !clarificationOptions.length\"\n >\n <div *ngFor=\"let question of clarificationQuestions; let i = index\" class=\"clarification-question\">\n <div class=\"clarification-question-label\">{{ question }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationAnswers[i]\"\n [placeholder]=\"'Resposta ' + (i + 1)\"\n autocomplete=\"off\">\n </div>\n </div>\n <div\n *ngIf=\"clarificationOptions.length\"\n class=\"clarification-options-block\"\n [class.attention-highlight]=\"highlightClarificationDetails\"\n >\n <div class=\"clarification-options-title\">\n {{ clarificationOptions.length === 1 ? 'Decis\u00E3o sugerida' : 'Decis\u00F5es sugeridas' }}\n </div>\n <div *ngIf=\"clarificationOptions.length === 1\" class=\"clarification-options-hint\">\n Etapa 2 de 4: confirme a melhor op\u00E7\u00E3o para continuar.\n </div>\n <div *ngIf=\"clarificationOptions.length > 1\" class=\"clarification-options-hint\">\n Etapa 2 de 4: selecione a alternativa mais aderente para gerar a proposta.\n </div>\n <div\n *ngIf=\"clarificationResponseType === 'confirm'\"\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n <button\n mat-button\n type=\"button\"\n *ngFor=\"let opt of clarificationOptions; let i = index\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n </div>\n <div\n *ngIf=\"clarificationSelectionMode === 'multiple'\"\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n <button\n mat-button\n type=\"button\"\n *ngFor=\"let opt of clarificationOptions; let i = index\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n class=\"clarification-option\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n </div>\n <div\n *ngIf=\"clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation !== 'chips'\"\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n <button\n mat-button\n type=\"button\"\n *ngFor=\"let opt of clarificationOptions; let i = index\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n </div>\n <div\n *ngIf=\"clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation === 'chips'\"\n class=\"clarification-chips\"\n >\n <ng-container *ngFor=\"let opt of clarificationOptions; let i = index\">\n <button\n *ngIf=\"isEndpointOption(opt); else chipOption\"\n mat-button\n type=\"button\"\n class=\"clarification-option clarification-card-button\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n <ng-template #chipOption>\n <mat-chip\n (click)=\"onClarificationOptionClick(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt)\"\n class=\"clarification-chip\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: true }\"></ng-container>\n </mat-chip>\n </ng-template>\n </ng-container>\n </div>\n </div>\n <div\n *ngIf=\"clarificationAllowCustom && clarificationResponseType !== 'context'\"\n class=\"clarification-manual-toggle\"\n >\n <span class=\"clarification-manual-label\">N\u00E3o encontrou o recurso?</span>\n <button mat-button type=\"button\" (click)=\"toggleManualInput()\">\n {{ showManualInput ? 'Ocultar resposta manual' : 'Responder manualmente' }}\n </button>\n </div>\n <div\n *ngIf=\"clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context'\"\n class=\"clarification-free\"\n >\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationFreeText\"\n placeholder=\"Digite sua resposta\u2026\"\n autocomplete=\"off\"\n (keydown.enter)=\"confirmTaskAction()\"\n />\n </div>\n <div\n *ngIf=\"clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context'\"\n class=\"clarification-free-hint\"\n >\n Pressione Enter para enviar.\n </div>\n </div>\n\n <!-- STATE: REVIEW (Diff/Explanation) -->\n <div\n *ngIf=\"state === 'review' && isActiveTab('task')\"\n class=\"review-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n <div class=\"task-header\" *ngIf=\"!shouldShowThoughtCard()\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n <div *ngIf=\"clarificationOptions.length > 1 && getTaskSelectionSummary() as selectionSummary\" class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n <div *ngIf=\"shouldShowTaskSteps()\" class=\"task-steps\">\n <span class=\"task-step\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step active\">3 Revis\u00E3o</span>\n </div>\n </div>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div class=\"review-trust\">\n <span class=\"trust-chip\" [matTooltip]=\"getScopeTooltip()\">{{ getScopeLabel() }}</span>\n <span class=\"trust-chip\" [matTooltip]=\"getConfidenceTooltip()\">{{ getConfidenceLabel() }}</span>\n <span class=\"trust-chip risk-chip\" [class.medium]=\"getReviewRiskLevel() === 'm\u00E9dio'\" [class.high]=\"getReviewRiskLevel() === 'alto'\">\n Risco {{ getReviewRiskLevel() }}\n </span>\n </div>\n <div class=\"review-summary\" [class.attention-highlight]=\"highlightReviewDetails\">\n <div class=\"review-summary-title\">Resumo da proposta</div>\n <div class=\"review-summary-line\">{{ getReviewSummary() }}</div>\n </div>\n <div class=\"review-diff\">\n <div class=\"review-diff-title\">Pr\u00E9via de mudan\u00E7as</div>\n <ng-container *ngIf=\"pendingDiff.length; else noDiffPreview\">\n <div class=\"review-diff-summary\">\n <div *ngFor=\"let line of getDiffSummaryLines()\" class=\"review-diff-line\">{{ line }}</div>\n <div *ngIf=\"pendingDiff.length > 3\" class=\"review-diff-more\">\u2026 +{{ pendingDiff.length - 3 }} mudan\u00E7as</div>\n </div>\n <button mat-stroked-button type=\"button\" class=\"review-diff-toggle\" (click)=\"toggleFullDiff()\">\n {{ getDiffToggleLabel() }}\n </button>\n </ng-container>\n <ng-template #noDiffPreview>\n <div class=\"review-diff-empty\">\n N\u00E3o foi poss\u00EDvel gerar um diff estruturado. Revise o resumo e aplique com cautela.\n </div>\n </ng-template>\n <div *ngIf=\"showFullDiff && pendingDiff.length\" class=\"review-diff-full\">\n <div *ngFor=\"let diff of pendingDiff\" class=\"review-diff-block\">\n <div class=\"review-diff-path\">{{ diff.path }}</div>\n <div class=\"review-diff-label\">Antes:</div>\n <pre>{{ diff.before | json }}</pre>\n <div class=\"review-diff-label\">Depois:</div>\n <pre>{{ diff.after | json }}</pre>\n </div>\n </div>\n </div>\n <div class=\"ai-explanation\" *ngIf=\"aiExplanation.trim()\">\n {{ aiExplanation }}\n </div>\n </div>\n\n <!-- STATE: ERROR -->\n <div\n *ngIf=\"state === 'error' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))\"\n class=\"error-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"error-msg\">\n <mat-icon color=\"warn\">error_outline</mat-icon>\n <span>{{ errorMsg }}</span>\n </div>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div *ngIf=\"shouldShowApplyDetails()\" class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n <div class=\"apply-details-actions\" *ngIf=\"allowManualPatchEdit\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar patch' }}\n </button>\n </div>\n </div>\n <div class=\"apply-details-meta\" *ngIf=\"lastApplyAt\">\n \u00DAltima tentativa: {{ lastApplyAt | date:'short' }}\n </div>\n <div class=\"apply-paths\" *ngIf=\"getApplyPaths().length\">\n <span class=\"apply-path-chip\" *ngFor=\"let path of getApplyPaths()\">{{ path }}</span>\n </div>\n <div class=\"apply-warnings\" *ngIf=\"applyWarnings.length\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n <div *ngFor=\"let warning of applyWarnings\">{{ warning }}</div>\n </div>\n </div>\n <div class=\"patch-path-editor\" *ngIf=\"allowManualPatchEdit && patchPathEditorExpanded\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n <div class=\"patch-path-editor-empty\" *ngIf=\"!getEditablePatchPathEdits().length\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n <div class=\"patch-path-rows\" *ngIf=\"getEditablePatchPathEdits().length\">\n <div class=\"patch-path-row\" *ngFor=\"let edit of getEditablePatchPathEdits(); let i = index\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n <div *ngIf=\"patchPathEdits[i].error\" class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n </div>\n </div>\n <div *ngIf=\"patchPathEditorError\" class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n <div class=\"patch-editor\" *ngIf=\"allowManualPatchEdit && patchEditorExpanded\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n <div *ngIf=\"patchEditorError\" class=\"patch-editor-error\">{{ patchEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n </div>\n <div class=\"review-actions\">\n <button mat-button (click)=\"close()\">Fechar</button>\n <button mat-stroked-button (click)=\"retry()\">Tentar Novamente</button>\n </div>\n </div>\n\n <!-- STATE: SUCCESS -->\n <div\n *ngIf=\"state === 'success' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))\"\n class=\"success-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"success-msg\">\n <mat-icon class=\"success-icon\">check_circle</mat-icon>\n <span>{{ aiExplanation || 'Configura\u00E7\u00E3o atualizada.' }}</span>\n </div>\n <div *ngIf=\"warnings.length\" class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n <div *ngFor=\"let warning of warnings\">{{ warning }}</div>\n </div>\n </div>\n </div>\n <div *ngIf=\"shouldShowApplyDetails()\" class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n <div class=\"apply-details-actions\" *ngIf=\"allowManualPatchEdit\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar e reaplicar' }}\n </button>\n </div>\n </div>\n <div class=\"apply-details-meta\" *ngIf=\"lastApplyAt\">\n Aplicado em {{ lastApplyAt | date:'short' }}\n </div>\n <div class=\"apply-paths\" *ngIf=\"getApplyPaths().length\">\n <span class=\"apply-path-chip\" *ngFor=\"let path of getApplyPaths()\">{{ path }}</span>\n </div>\n <div class=\"apply-warnings\" *ngIf=\"applyWarnings.length\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n <div *ngFor=\"let warning of applyWarnings\">{{ warning }}</div>\n </div>\n </div>\n <div class=\"patch-path-editor\" *ngIf=\"allowManualPatchEdit && patchPathEditorExpanded\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n <div class=\"patch-path-editor-empty\" *ngIf=\"!getEditablePatchPathEdits().length\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n <div class=\"patch-path-rows\" *ngIf=\"getEditablePatchPathEdits().length\">\n <div class=\"patch-path-row\" *ngFor=\"let edit of getEditablePatchPathEdits(); let i = index\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n <div *ngIf=\"patchPathEdits[i].error\" class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n </div>\n </div>\n <div *ngIf=\"patchPathEditorError\" class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n <div class=\"patch-editor\" *ngIf=\"allowManualPatchEdit && patchEditorExpanded\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n <div *ngIf=\"patchEditorError\" class=\"patch-editor-error\">{{ patchEditorError }}</div>\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n </div>\n <button mat-button color=\"warn\" (click)=\"undoLastChange()\">\n <mat-icon>undo</mat-icon> Desfazer\n </button>\n </div>\n\n </div>\n\n <div class=\"assistant-footer\">\n <ng-container *ngIf=\"!isTaskMode(); else taskFooter\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"composer-leading composer-leading-btn\"\n [matMenuTriggerFor]=\"assistantQuickMenu\"\n aria-label=\"Abrir a\u00E7\u00F5es r\u00E1pidas\"\n matTooltip=\"A\u00E7\u00F5es r\u00E1pidas\"\n >\n <mat-icon>add</mat-icon>\n </button>\n <input\n #inputEl\n type=\"text\"\n [(ngModel)]=\"userPrompt\"\n [disabled]=\"state === 'processing' || state === 'applying'\"\n placeholder=\"Descreva a altera\u00E7\u00E3o que deseja aplicar\u2026\"\n autocomplete=\"off\"\n />\n <div class=\"send-actions\">\n <button\n mat-icon-button\n class=\"send-btn\"\n *ngIf=\"state === 'listening'\"\n (click)=\"submitPrompt()\"\n [disabled]=\"!userPrompt.trim()\"\n [class.ready]=\"!!userPrompt.trim()\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <mat-spinner diameter=\"20\" *ngIf=\"state === 'processing' || state === 'applying'\"></mat-spinner>\n </div>\n </ng-container>\n <ng-template #taskFooter>\n <div class=\"task-footer\">\n <div class=\"task-footer-left\">\n <button mat-button type=\"button\" (click)=\"handleTaskSecondary()\">{{ getTaskCancelLabel() }}</button>\n <button\n *ngIf=\"state === 'review'\"\n mat-stroked-button\n type=\"button\"\n (click)=\"retry()\"\n >\n {{ getTaskSecondaryLabel() }}\n </button>\n </div>\n <div class=\"task-footer-right\">\n <button\n class=\"task-primary-btn\"\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"confirmTaskAction()\"\n [disabled]=\"isTaskPrimaryDisabled()\"\n >\n {{ getTaskPrimaryLabel() }}\n </button>\n <mat-spinner diameter=\"20\" *ngIf=\"state === 'processing' || state === 'applying'\"></mat-spinner>\n </div>\n </div>\n </ng-template>\n </div>\n\n <mat-menu #assistantQuickMenu=\"matMenu\" panelClass=\"assistant-quick-menu-panel\">\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('chat')\">\n <mat-icon>history</mat-icon>\n <span>Hist\u00F3rico</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('suggestions')\">\n <mat-icon>lightbulb</mat-icon>\n <span>Sugest\u00F5es</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"startNewSession()\">\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\">\n <mat-icon>refresh</mat-icon>\n <span>Atualizar sugest\u00F5es</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n (click)=\"restoreDismissedSuggestions()\"\n [disabled]=\"!hasDismissedSuggestions()\"\n >\n <mat-icon>visibility</mat-icon>\n <span>Restaurar sugest\u00F5es ocultas</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n class=\"assistant-quick-menu-danger\"\n (click)=\"clearHistory()\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar hist\u00F3rico local</span>\n </button>\n </mat-menu>\n </div>\n\n</ng-template>\n", styles: ["@keyframes assistantPremiumEnter{0%{opacity:0;transform:translate(14px) scale(.99)}to{opacity:1;transform:translate(0) scale(1)}}:host ::ng-deep .ai-assistant-backdrop{background:color-mix(in srgb,var(--md-sys-color-scrim, var(--md-sys-color-shadow, var(--md-sys-color-on-surface))) 42%,transparent);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}::ng-deep .ai-assistant-overlay-pane{max-width:calc(100vw - 24px);max-height:calc(100vh - 24px)}.ai-assistant-panel{box-sizing:border-box;width:min(604px,100vw - 18px);min-height:min(620px,100vh - 18px);max-height:min(820px,100vh - 18px);display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border-left:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-top:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));box-shadow:0 18px 48px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 42%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);background:radial-gradient(circle at 14% 8%,color-mix(in srgb,var(--md-sys-color-primary-container) 38%,transparent) 0%,transparent 44%),linear-gradient(165deg,color-mix(in srgb,var(--md-sys-color-surface-container-highest) 88%,var(--md-sys-color-surface)),var(--md-sys-color-surface));animation:assistantPremiumEnter .24s cubic-bezier(.22,1,.36,1)}.assistant-header{position:relative;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:12px 16px 10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(130deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.assistant-header:after{content:\"\";position:absolute;left:16px;right:16px;bottom:-1px;height:1px;background:linear-gradient(90deg,color-mix(in srgb,var(--md-sys-color-primary) 55%,transparent),transparent);pointer-events:none}.assistant-header .assistant-header__left{min-width:0;display:flex;align-items:flex-start;gap:12px}.assistant-header .magic-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:30px;height:30px;font-size:18px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent);box-shadow:0 4px 12px color-mix(in srgb,var(--md-sys-color-primary) 26%,transparent)}.assistant-header .assistant-title-group{min-width:0;display:flex;flex-direction:column;gap:4px}.assistant-header .assistant-title{font-size:15px;font-weight:700;letter-spacing:.01em;overflow-wrap:anywhere}.assistant-header .assistant-subtitle{display:block;font-size:11px;line-height:1.25;color:color-mix(in srgb,var(--md-sys-color-on-surface) 70%,var(--md-sys-color-on-surface-variant));overflow-wrap:anywhere}.assistant-header-chips{display:inline-flex;align-items:center;flex-wrap:wrap;gap:6px}.assistant-header .mode-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 28%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 64%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-primary-container) 85%,var(--md-sys-color-on-surface));font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.assistant-header .mode-chip:before{content:\"\";width:6px;height:6px;border-radius:999px;background:currentColor;box-shadow:0 0 0 3px color-mix(in srgb,currentColor 16%,transparent)}.assistant-header .mode-chip.mock{border-color:color-mix(in srgb,var(--md-sys-color-error) 34%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-error-container) 72%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-error-container) 85%,var(--md-sys-color-error))}.assistant-header .policy-chip{padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 84%,transparent);background:var(--md-sys-color-surface-container-high);font-size:10px;letter-spacing:.02em;font-weight:600}.assistant-header .policy-chip.strict{border-color:color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 56%,var(--md-sys-color-surface-container-high))}.assistant-status{display:flex;align-items:flex-start;gap:10px;padding:10px 16px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-radius:0;background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 24%,transparent),transparent 48%),var(--md-sys-color-surface-container-low)}.assistant-status-dot{width:8px;height:8px;margin-top:6px;border-radius:999px;flex:0 0 auto;background:var(--md-sys-color-primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.assistant-status.warning .assistant-status-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.assistant-status.success .assistant-status-dot{background:color-mix(in srgb,var(--md-sys-color-primary) 74%,var(--md-sys-color-tertiary, var(--md-sys-color-primary)))}.assistant-status-content{min-width:0;display:flex;flex-direction:column;gap:2px}.assistant-status-label{display:flex;align-items:center;flex-wrap:wrap;gap:4px;font-size:12px;font-weight:700;line-height:1.35}.assistant-status-detail{font-size:11px;line-height:1.4;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.assistant-status-mode{padding:1px 6px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent);color:var(--md-sys-color-on-primary-container);font-size:10px;font-weight:700}.assistant-nav{padding:8px 16px 0}.assistant-nav .assistant-tabs{display:flex;align-items:center;gap:4px;border-radius:12px;padding:5px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(155deg,color-mix(in srgb,var(--md-sys-color-primary-container) 14%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-nav .assistant-tab{appearance:none;min-width:0;min-height:30px;border:0;border-radius:8px;padding:0 10px;background:transparent;color:var(--md-sys-color-on-surface-variant);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex:1 1 0;font-size:11px;font-weight:700;letter-spacing:.01em}.assistant-nav .assistant-tab.active{background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent),0 6px 12px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.assistant-section,.assistant-card{border-radius:14px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 50%),var(--md-sys-color-surface-container-lowest);box-shadow:0 6px 18px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 7%,transparent)}.suggestions-hero{margin:2px 0 4px;padding:10px 12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(120deg,color-mix(in srgb,var(--md-sys-color-primary-container) 34%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.suggestions-hero__label{font-size:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:var(--md-sys-color-on-surface-variant);opacity:.88}.suggestions-hero__title{margin-top:2px;font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.suggestions-hero__detail{margin-top:4px;font-size:12px;line-height:1.4;color:color-mix(in srgb,var(--md-sys-color-on-surface) 78%,var(--md-sys-color-on-surface-variant))}.suggestions-content .suggestion-item{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(140deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-lowest);transition:transform .2s cubic-bezier(.25,.8,.25,1),border-color .2s ease,box-shadow .2s ease}.suggestions-list{display:flex;flex-direction:column;gap:10px}.suggestion-copy{min-width:0;display:grid;gap:4px}.suggestion-main{min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.suggestion-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto;color:var(--md-sys-color-primary)}.suggestion-label{min-width:0;font-size:13px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestion-group{padding:2px 6px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:10px;font-weight:700;line-height:1.2}.suggestion-desc{font-size:12px;line-height:1.35;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.suggestion-actions{display:inline-flex;align-items:center;justify-content:flex-end;gap:4px}.suggestion-action-btn,.suggestion-arrow{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--md-sys-color-on-surface-variant)}.suggestions-content .suggestion-item:hover,.suggestions-content .suggestion-item:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant));box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 28%,transparent);transform:translateY(-2px) scale(1.01)}.assistant-footer{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:10px 16px;border-top-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-low)}.assistant-footer .task-footer{grid-column:1/-1}.composer-leading{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 70%,var(--md-sys-color-surface-container-low));color:var(--md-sys-color-primary);box-shadow:0 4px 10px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.composer-leading mat-icon{width:16px;height:16px;font-size:16px}.assistant-footer input{box-sizing:border-box;width:100%;min-width:0;height:34px;border:1px solid;border-radius:8px;padding:0 12px;color:var(--md-sys-color-on-surface);border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface);box-shadow:inset 0 1px 2px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent)}.send-actions{min-width:36px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn{--mdc-icon-button-icon-size: 20px;--mdc-icon-button-state-layer-size: 36px;--mat-icon-button-state-layer-size: 36px;width:36px;height:36px;padding:8px;line-height:1;display:inline-flex;align-items:center;justify-content:center;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface)}.assistant-footer .send-btn mat-icon{width:20px;height:20px;margin:0;font-size:20px;line-height:20px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn.ready{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary-container) 84%,var(--md-sys-color-primary)),var(--md-sys-color-primary));color:var(--md-sys-color-on-primary);box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent)}.task-primary-btn{border-radius:12px;box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 24%,transparent)}@media(max-width:959px){.assistant-header{padding:12px 12px 10px}.assistant-section,.assistant-card{margin:4px 12px 10px}.assistant-header:after{left:12px;right:12px}.assistant-header .assistant-title{font-size:14px}.assistant-header .assistant-subtitle{font-size:10px}.assistant-footer{grid-template-columns:minmax(0,1fr) auto}.composer-leading{display:none}}.assistant-thought{margin-top:0;gap:10px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-thought-meta{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-meta mat-icon{width:15px;height:15px;font-size:15px;color:var(--md-sys-color-primary)}.assistant-thought-summary{font-size:13px;line-height:1.45;color:var(--md-sys-color-on-surface)}.assistant-thought-plan{border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 32%,var(--md-sys-color-outline-variant));border-radius:12px;padding:10px;background:var(--md-sys-color-surface-container-lowest);display:flex;flex-direction:column;gap:8px}.assistant-thought-plan-title{font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.assistant-thought-plan-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px}.assistant-thought-plan-actions .mdc-button{min-width:0}.assistant-thought-plan-hint{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.35}.assistant-thought-checklist{display:flex;flex-direction:column;gap:5px}.assistant-thought-checklist-item{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-checklist-item mat-icon{width:14px;height:14px;font-size:14px}.assistant-thought-shimmer{display:flex;flex-direction:column;gap:8px;margin-top:4px}.assistant-thought-shimmer .shimmer-line{height:12px;border-radius:4px;position:relative;overflow:hidden;background:var(--md-sys-color-surface-container-highest)}.assistant-thought-shimmer .shimmer-line:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent);animation:assistantShimmerEffect 1.5s infinite}.assistant-thought-shimmer .shimmer-line-1{width:85%}.assistant-thought-shimmer .shimmer-line-2{width:92%}.assistant-thought-shimmer .shimmer-line-3{width:64%}@keyframes assistantShimmerEffect{to{transform:translate(100%)}}.assistant-flow{grid-template-columns:1fr;gap:6px}.flow-step{display:flex;align-items:flex-start;gap:8px;text-align:left;padding:7px 8px;border-radius:10px}.flow-step-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.flow-step-content{min-width:0;display:flex;flex-direction:column;gap:1px}.flow-step-label{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.flow-step-detail{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.3}.flow-step.active .flow-step-index{border-color:color-mix(in srgb,var(--md-sys-color-primary) 60%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 85%,var(--md-sys-color-surface-container-highest));color:var(--md-sys-color-on-primary-container)}.flow-step.done .flow-step-index{border-color:transparent;background:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-surface-container-highest))}.task-timeline{margin-top:4px;display:grid;gap:6px}.task-timeline-item{display:flex;align-items:flex-start;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);opacity:.76}.task-timeline-item.active{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 40%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-low))}.task-timeline-item.done{opacity:.9;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant))}.task-timeline-dot{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.task-timeline-copy{min-width:0;display:flex;flex-direction:column;gap:1px}.task-timeline-title{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.task-timeline-detail{font-size:11px;line-height:1.3;color:var(--md-sys-color-on-surface-variant)}.clarification-decision-head{display:inline-flex;align-items:center;width:100%;gap:6px;padding:8px 12px 0;box-sizing:border-box}.clarification-decision-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 68%,transparent)}.clarification-decision-type{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);opacity:.92}.clarification-decision-state{font-size:10px;font-weight:700;color:var(--md-sys-color-primary)}.clarification-option{border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 55%),var(--md-sys-color-surface-container-low)}.clarification-option.selected{border-color:color-mix(in srgb,var(--md-sys-color-primary) 56%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 44%,transparent),transparent 62%),var(--md-sys-color-surface-container);box-shadow:0 8px 16px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.clarification-options-block{overflow:visible;padding-right:4px}@media(max-width:959px){.assistant-thought-plan-actions{grid-template-columns:1fr}}.ai-assistant-panel{width:min(604px,100vw - 18px)}.assistant-section,.assistant-card{margin:0;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant))}.assistant-section{min-height:0;padding:14px 16px;overflow:visible}.assistant-card{min-height:0;padding:14px 16px 16px;overflow:visible}.suggestions-area,.assistant-history,.loading-suggestions{overflow-y:auto;overflow-x:hidden}.section-header{min-width:0;display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}.section-title{min-width:0;font-size:14px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestions-actions{flex:0 0 auto;display:inline-flex;align-items:center}.review-area,.error-area,.success-area,.clarification-area{padding:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:auto}.review-trust{margin:2px 0 4px}.trust-chip{max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.warnings-area,.review-summary,.review-diff,.apply-details,.clarification-options-block,.clarification-manual-toggle{width:100%;max-width:100%;min-width:0}.review-diff{padding:12px 14px}.review-diff-full{padding:10px;overflow-x:auto}.review-diff-block{min-width:0}.review-diff-block pre{overflow-wrap:anywhere;word-break:break-word}.clarification-options-block{padding:4px 2px 10px}.clarification-option{line-height:normal}:host ::ng-deep .clarification-option .mdc-button__label{line-height:1.35!important}.clarification-plain-label{padding:6px 12px 12px;font-size:14px;line-height:1.35}.clarification-manual-toggle{margin-top:10px;padding:10px 2px 0;flex-wrap:wrap;row-gap:6px}.suggestions-content .suggestion-actions{gap:6px}.suggestions-content .suggestion-arrow,.suggestions-content .suggestion-action-btn mat-icon,.suggestions-content .suggestion-arrow mat-icon{display:inline-flex;align-items:center;justify-content:center}:host ::ng-deep .assistant-quick-menu-panel{min-width:244px;max-width:min(90vw,320px);border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high);box-shadow:0 12px 28px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 32%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 6%,transparent);overflow:hidden;padding:6px}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item{min-height:36px;border-radius:10px;color:var(--md-sys-color-on-surface);font-size:12px;font-weight:500;margin:1px 0}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item .mat-icon{color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,var(--md-sys-color-on-surface-variant))}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:hover:not([disabled]){background:color-mix(in srgb,var(--md-sys-color-primary-container) 45%,transparent)}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:-2px}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger{color:var(--md-sys-color-error)}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger .mat-icon{color:var(--md-sys-color-error)}@media(max-width:959px){::ng-deep .ai-assistant-overlay-pane{top:12px!important;left:12px!important;width:calc(100vw - 24px)!important;height:calc(100vh - 24px)!important;max-width:calc(100vw - 24px);max-height:calc(100vh - 24px);transform:none!important}.ai-assistant-panel{width:calc(100vw - 48px);min-height:min(620px,100vh - 48px);max-height:calc(100vh - 48px)}.assistant-section,.assistant-card{margin:0}.assistant-card,.assistant-section{padding:12px}}.ai-trigger-btn{--mdc-icon-button-state-layer-size: 36px;width:36px;height:36px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary) 9%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent);color:var(--md-sys-color-primary);opacity:1}.ai-trigger-btn:hover:not(:disabled){background:color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent);border-color:color-mix(in srgb,var(--md-sys-color-primary) 36%,transparent);color:var(--md-sys-color-on-primary-container)}.ai-trigger-btn:focus-visible,.assistant-close-btn:focus-visible,.assistant-tab:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.assistant-close-btn{width:28px;height:28px;color:var(--md-sys-color-on-surface-variant)}.assistant-close-btn:hover:not(:disabled){background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.assistant-body{padding:12px 16px;overflow:hidden;min-height:0;flex:1;display:flex;flex-direction:column;gap:12px}.assistant-body>*{min-height:0}@media(max-width:959px){.assistant-nav{padding:8px 12px 0}.assistant-body,.assistant-footer{padding:10px 12px}.suggestions-content .suggestion-item{grid-template-columns:1fr;align-items:start}.suggestion-actions{justify-content:flex-start}}\n"] }]
|
|
6687
|
+
DatePipe,
|
|
6688
|
+
JsonPipe,
|
|
6689
|
+
NgTemplateOutlet,
|
|
6690
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Trigger Button -->\n<button\n mat-icon-button\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n #triggerBtn\n (click)=\"open()\"\n [disabled]=\"isOpen\"\n class=\"ai-trigger-btn\"\n matTooltip=\"Assistente de Configura\u00E7\u00E3o\"\n aria-label=\"Abrir Assistente IA\">\n <mat-icon>auto_awesome</mat-icon>\n</button>\n\n<!-- Overlay Template -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"12\"\n cdkConnectedOverlayPanelClass=\"ai-assistant-overlay-pane\"\n cdkConnectedOverlayBackdropClass=\"ai-assistant-backdrop\"\n (backdropClick)=\"close()\"\n (overlayOutsideClick)=\"close()\"\n (detach)=\"close()\">\n\n <div\n class=\"ai-assistant-panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Assistente de Configura\u00E7\u00E3o\"\n [attr.aria-busy]=\"isBusyState() ? 'true' : null\"\n [cdkTrapFocus]=\"hasBackdrop\"\n [cdkTrapFocusAutoCapture]=\"hasBackdrop\"\n (keydown)=\"onKeydown($event)\"\n >\n\n <!-- HEADER -->\n <div class=\"assistant-header\">\n <div class=\"assistant-header__left\">\n <mat-icon class=\"magic-icon\">auto_awesome</mat-icon>\n <div class=\"assistant-title-group\">\n <div class=\"assistant-title\">Assistente de Configura\u00E7\u00E3o</div>\n <div class=\"assistant-subtitle\">Copiloto contextual para ajustes guiados</div>\n <div class=\"assistant-header-chips\">\n <span\n class=\"mode-chip\"\n [class.mock]=\"mockMode\"\n [matTooltip]=\"mockMode ? 'Sem chave de API: respostas de demonstra\u00E7\u00E3o' : 'Conectado ao assistente configurado'\"\n >\n {{ mockMode ? 'Mock' : 'Conectado' }}\n </span>\n <span\n class=\"policy-chip\"\n [class.strict]=\"isStrictRiskPolicy()\"\n [matTooltip]=\"getRiskPolicyTooltip()\"\n >\n {{ getRiskPolicyLabel() }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"assistant-header__right\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"assistant-close-btn\"\n (click)=\"close()\"\n aria-label=\"Fechar assistente\"\n matTooltip=\"Fechar assistente\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n <div\n class=\"assistant-status\"\n [class.processing]=\"isBusyState()\"\n [class.pending]=\"state === 'clarification'\"\n [class.warning]=\"state === 'error'\"\n [class.success]=\"state === 'review' || state === 'success'\"\n [class.compact]=\"!shouldShowSystemStatusDetail()\"\n role=\"status\"\n [attr.aria-live]=\"getSystemStatusAriaLive()\"\n aria-atomic=\"true\"\n >\n <span class=\"assistant-status-dot\" aria-hidden=\"true\"></span>\n <div class=\"assistant-status-content\">\n <div class=\"assistant-status-label\">\n <span class=\"assistant-status-label-prefix\">Status:</span>\n <span>{{ getSystemStatusLabel() }}</span>\n @if (shouldShowSnapshotFallbackBadge()) {\n <span class=\"assistant-status-mode\">Snapshot</span>\n }\n </div>\n @if (shouldShowSystemStatusDetail()) {\n <div class=\"assistant-status-detail\">{{ getSystemStatusDetail() }}</div>\n }\n </div>\n </div>\n @if (shouldShowTaskFlow()) {\n <div class=\"assistant-flow\" role=\"list\" aria-label=\"Fluxo da proposta\">\n @for (step of flowSteps; track step) {\n <div\n class=\"flow-step\"\n role=\"listitem\"\n [class.active]=\"getFlowStepState(step.step) === 'active'\"\n [class.done]=\"getFlowStepState(step.step) === 'done'\"\n >\n <span class=\"flow-step-index\">{{ step.step }}</span>\n <span class=\"flow-step-content\">\n <span class=\"flow-step-label\">{{ step.label }}</span>\n <span class=\"flow-step-detail\">{{ getFlowStepDetail(step.step) }}</span>\n </span>\n </div>\n }\n </div>\n }\n <div class=\"assistant-nav\">\n <div\n class=\"assistant-tabs\"\n role=\"tablist\"\n aria-label=\"Se\u00E7\u00F5es do assistente\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n @if (isTaskMode()) {\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-task\"\n role=\"tab\"\n aria-label=\"Proposta atual\"\n [attr.aria-selected]=\"isActiveTab('task')\"\n aria-controls=\"assistant-panel-task\"\n [attr.tabindex]=\"isActiveTab('task') ? 0 : -1\"\n [class.active]=\"isActiveTab('task')\"\n (click)=\"setActiveTab('task')\"\n >\n Proposta\n @if (hasPendingClarification() && !isActiveTab('task')) {\n <span class=\"assistant-tab-badge\">1</span>\n }\n </button>\n }\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-chat\"\n role=\"tab\"\n aria-label=\"Hist\u00F3rico\"\n [attr.aria-selected]=\"isActiveTab('chat')\"\n aria-controls=\"assistant-panel-chat\"\n [attr.tabindex]=\"isActiveTab('chat') ? 0 : -1\"\n [class.active]=\"isActiveTab('chat')\"\n (click)=\"setActiveTab('chat')\"\n >\n Hist\u00F3rico\n </button>\n <button\n class=\"assistant-tab\"\n type=\"button\"\n id=\"assistant-tab-suggestions\"\n role=\"tab\"\n aria-label=\"Sugest\u00F5es de melhoria\"\n [attr.aria-selected]=\"isActiveTab('suggestions')\"\n aria-controls=\"assistant-panel-suggestions\"\n [attr.tabindex]=\"isActiveTab('suggestions') ? 0 : -1\"\n [class.active]=\"isActiveTab('suggestions')\"\n (click)=\"setActiveTab('suggestions')\"\n >\n Sugest\u00F5es\n </button>\n </div>\n </div>\n\n <!-- BODY: Dynamic Content based on State -->\n <div class=\"assistant-body\">\n @if (shouldShowThoughtCard()) {\n <div class=\"assistant-thought assistant-section\">\n <div class=\"assistant-thought-meta\">\n <mat-icon>psychology</mat-icon>\n <span>{{ getThoughtTimingLabel() }}</span>\n </div>\n <div class=\"assistant-thought-summary\">{{ getThoughtSummary() }}</div>\n <div class=\"assistant-thought-plan\">\n <div class=\"assistant-thought-plan-title\">{{ getThoughtPlanTitle() }}</div>\n <div class=\"assistant-thought-plan-actions\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"thought-action-details\"\n (click)=\"openThoughtDetails()\"\n [attr.aria-label]=\"getThoughtDetailsLabel()\"\n [matTooltip]=\"getThoughtDetailsTooltip()\"\n >\n {{ getThoughtDetailsLabel() }}\n </button>\n @if (shouldShowThoughtPreviewAction()) {\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"thought-action-preview\"\n (click)=\"openThoughtPreview()\"\n [matTooltip]=\"getThoughtPreviewTooltip()\"\n >\n Pr\u00E9via\n </button>\n }\n </div>\n <div class=\"assistant-thought-plan-hint\">{{ getThoughtActionHint() }}</div>\n @if (getThoughtChecklist(); as thoughtChecklist) {\n @if (thoughtChecklist.length) {\n <div class=\"assistant-thought-checklist\">\n @for (item of thoughtChecklist; track item) {\n <div class=\"assistant-thought-checklist-item\">\n <mat-icon>radio_button_unchecked</mat-icon>\n <span>{{ item }}</span>\n </div>\n }\n </div>\n }\n @if (isBusyState() && !thoughtChecklist.length) {\n <div class=\"assistant-thought-shimmer\">\n <div class=\"shimmer-line shimmer-line-1\"></div>\n <div class=\"shimmer-line shimmer-line-2\"></div>\n <div class=\"shimmer-line shimmer-line-3\"></div>\n </div>\n }\n }\n </div>\n </div>\n }\n @if (processingInfoVisible) {\n <div class=\"processing-banner\">\n <mat-spinner diameter=\"16\"></mat-spinner>\n <span>{{ aiExplanation || 'Analisando solicita\u00E7\u00E3o e preparando proposta...' }}</span>\n <button mat-button type=\"button\" class=\"processing-retry\" (click)=\"retryProcessing()\">Tentar novamente</button>\n </div>\n }\n @if (historyContext && isActiveTab('chat')) {\n <div\n class=\"assistant-history assistant-section\"\n id=\"assistant-panel-chat\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-chat\"\n >\n <div class=\"section-header\">\n <div class=\"section-heading\">\n <div class=\"section-title\">Hist\u00F3rico</div>\n <div class=\"section-subtitle\">Sess\u00F5es recentes, pedidos reaproveit\u00E1veis e desfazer r\u00E1pido.</div>\n </div>\n <div class=\"history-actions\" role=\"group\" aria-label=\"A\u00E7\u00F5es do hist\u00F3rico\">\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"historyExpanded = !historyExpanded\"\n [matTooltip]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [attr.aria-label]=\"historyExpanded ? 'Recolher hist\u00F3rico' : 'Expandir hist\u00F3rico'\"\n [disabled]=\"!historyWarnings.length && !historySessions.length && !activeHistoryMessages.length\"\n >\n <mat-icon>{{ historyExpanded ? 'expand_less' : 'expand_more' }}</mat-icon>\n <span>{{ historyExpanded ? 'Recolher' : 'Expandir' }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"history-action-btn\"\n (click)=\"startNewSession()\"\n matTooltip=\"Nova conversa\"\n aria-label=\"Nova conversa\"\n [disabled]=\"isBusyState()\"\n >\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"clearHistory()\"\n matTooltip=\"Limpar hist\u00F3rico local\"\n aria-label=\"Limpar hist\u00F3rico local\"\n class=\"history-action-btn history-action-btn--danger\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar</span>\n </button>\n </div>\n </div>\n @if (historyUndoDeleteSession) {\n <div class=\"history-undo\">\n <span>Sess\u00E3o removida.</span>\n <button mat-button type=\"button\" (click)=\"undoRemoveHistorySession()\">\n Desfazer\n </button>\n </div>\n }\n @if (historyExpanded && historyWarnings.length) {\n <div class=\"history-warnings\">\n <mat-icon>info</mat-icon>\n <div class=\"history-warnings-list\">\n @for (warning of historyWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n <div class=\"history-warnings-hint\">\n Configure headers via API_CONFIG_STORAGE_OPTIONS no host.\n </div>\n </div>\n </div>\n }\n @if (historyExpanded && historySessions.length) {\n <div class=\"history-sessions\">\n @for (session of historySessions; track session) {\n <div\n class=\"history-session\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"selectHistorySession(session.id)\"\n (keydown)=\"onHistorySessionCardKeydown($event, session.id)\"\n [class.active]=\"session.id === activeHistorySession?.id\"\n [matTooltip]=\"getHistorySessionTooltip(session)\"\n [matTooltipDisabled]=\"!session.componentType && !session.componentId\"\n >\n <div class=\"history-session-main\">\n <span class=\"history-session-title\">{{ session.title }}</span>\n <div class=\"history-session-main-right\">\n <span class=\"history-session-time\">{{ session.updatedAt | date:'short' }}</span>\n <div class=\"history-session-tools\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool\"\n (click)=\"reuseHistorySessionPrompt(session.id, $event)\"\n matTooltip=\"Reusar \u00FAltimo pedido\"\n aria-label=\"Reusar \u00FAltimo pedido\"\n >\n <mat-icon>edit_note</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"history-session-tool history-session-tool--danger\"\n (click)=\"removeHistorySession(session.id, $event)\"\n matTooltip=\"Excluir sess\u00E3o\"\n aria-label=\"Excluir sess\u00E3o\"\n >\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <div class=\"history-session-meta\">\n @if (session.componentType) {\n <span class=\"history-chip\">{{ session.componentType }}</span>\n }\n @if (session.componentId) {\n <span class=\"history-chip\">{{ session.componentId }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n @if (historyExpanded && !historySessions.length) {\n <div class=\"history-empty\">\n Nenhuma sess\u00E3o salva ainda.\n </div>\n }\n @if (historyExpanded && activeHistoryMessages.length) {\n <div class=\"history-messages\">\n @if (activeHistoryTotalMessages > activeHistoryMessages.length) {\n <div\n class=\"history-messages-hint\"\n >\n Mostrando \u00FAltimas {{ activeHistoryMessages.length }} de {{ activeHistoryTotalMessages }} mensagens.\n </div>\n }\n @for (msg of activeHistoryMessages; track msg) {\n <div\n class=\"history-message\"\n [class.user]=\"msg.role === 'user'\"\n [class.assistant]=\"msg.role === 'assistant'\"\n >\n <div class=\"history-message-header\">\n <span class=\"history-message-role\">{{ msg.role === 'user' ? 'Voc\u00EA' : 'Assistente' }}</span>\n <span class=\"history-message-time\">{{ msg.createdAt | date:'shortTime' }}</span>\n @if (msg.context?.usedRag) {\n <span\n class=\"history-rag\"\n matTooltip=\"Resposta baseada em contexto recuperado (RAG)\"\n >RAG</span>\n }\n </div>\n <div class=\"history-message-text\">{{ msg.text }}</div>\n </div>\n }\n </div>\n }\n @if (historyExpanded && historySessions.length && !activeHistoryMessages.length) {\n <div class=\"history-empty history-empty--panel\">\n Selecione uma sess\u00E3o para visualizar as mensagens.\n </div>\n }\n @if (historyExpanded) {\n <div class=\"history-helper\">\n O hist\u00F3rico \u00E9 local ao usu\u00E1rio e ao componente atual.\n </div>\n }\n </div>\n }\n\n @if (loadingSuggestions && isActiveTab('suggestions')) {\n <div\n class=\"loading-suggestions assistant-section\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <mat-spinner diameter=\"20\"></mat-spinner>\n <span>Carregando sugest\u00F5es de melhoria...</span>\n </div>\n }\n\n <!-- STATE: LISTENING (Suggestions) -->\n @if (state === 'listening' && isActiveTab('suggestions')) {\n <div\n class=\"suggestions-area assistant-section\"\n id=\"assistant-panel-suggestions\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-suggestions\"\n >\n <div class=\"section-header\">\n <div class=\"section-title\">Sugest\u00F5es de melhoria</div>\n <div class=\"suggestions-actions\">\n <button mat-icon-button type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\" matTooltip=\"Atualizar sugest\u00F5es\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n @if (!loadingSuggestions) {\n <div class=\"suggestions-hero\">\n <div class=\"suggestions-hero__label\">Contexto ativo</div>\n <div class=\"suggestions-hero__title\">{{ adapter.componentName || 'Componente atual' }}</div>\n <div class=\"suggestions-hero__detail\">{{ getSystemStatusDetail() }}</div>\n </div>\n }\n @if (suggestionsWarnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of suggestionsWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (!loadingSuggestions && (richSuggestions.length || hasDismissedSuggestions())) {\n <div class=\"suggestions-content\">\n @if (hasDismissedSuggestions()) {\n <div class=\"suggestions-filter\">\n <span>{{ getDismissedSuggestionCount() }} oculta(s)</span>\n <button mat-button type=\"button\" (click)=\"restoreDismissedSuggestions()\">\n Restaurar\n </button>\n </div>\n }\n @if (getVisibleSuggestions().length) {\n <div class=\"suggestions-list\">\n @for (sug of getVisibleSuggestions(); track sug) {\n <div\n class=\"suggestion-item\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Selecionar sugest\u00E3o: ' + sug.label\"\n (click)=\"selectSuggestion(sug)\"\n (keydown)=\"onSuggestionCardKeydown($event, sug)\"\n >\n <div class=\"suggestion-copy\">\n <div class=\"suggestion-main\">\n @if (sug.icon) {\n <mat-icon class=\"suggestion-icon\">{{ sug.icon }}</mat-icon>\n }\n <span class=\"suggestion-label\">{{ sug.label }}</span>\n @if (sug.group) {\n <span class=\"suggestion-group\">{{ sug.group }}</span>\n }\n </div>\n @if (sug.description) {\n <div class=\"suggestion-desc\">{{ sug.description }}</div>\n }\n </div>\n <div class=\"suggestion-actions\">\n <span class=\"suggestion-arrow\" aria-hidden=\"true\">\n <mat-icon>chevron_right</mat-icon>\n </span>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn\"\n (click)=\"prepareSuggestionPrompt(sug, $event)\"\n matTooltip=\"Refinar pedido\"\n aria-label=\"Refinar pedido\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"suggestion-action-btn suggestion-action-btn--danger\"\n (click)=\"dismissSuggestion(sug, $event)\"\n matTooltip=\"Ocultar sugest\u00E3o\"\n aria-label=\"Ocultar sugest\u00E3o\"\n >\n <mat-icon>visibility_off</mat-icon>\n </button>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"suggestions-empty suggestions-empty--inline\">\n Todas as sugest\u00F5es foram ocultadas.\n </div>\n }\n </div>\n }\n @if (!loadingSuggestions && !richSuggestions.length) {\n <div class=\"suggestions-empty\">\n Nenhuma sugest\u00E3o dispon\u00EDvel no momento.\n </div>\n }\n @if (!loadingSuggestions && !richSuggestions.length) {\n <div class=\"suggestions-helper\">\n Selecione uma sugest\u00E3o acima ou descreva uma altera\u00E7\u00E3o no campo inferior.\n </div>\n }\n </div>\n }\n\n <!-- STATE: CLARIFICATION (Two-Step Flow) -->\n @if (state === 'clarification' && isActiveTab('task')) {\n <div\n class=\"clarification-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n @if (!shouldShowThoughtCard()) {\n <div class=\"task-header\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n @if (clarificationOptions.length > 1 && getTaskSelectionSummary(); as selectionSummary) {\n <div class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n }\n @if (shouldShowTaskSteps()) {\n <div class=\"task-steps\">\n <span class=\"task-step active\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step\">3 Revis\u00E3o</span>\n </div>\n }\n </div>\n }\n @if (clarificationResponseType === 'context') {\n <div class=\"context-only\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n <div class=\"context-only-hint\">Buscando contexto adicional...</div>\n </div>\n }\n <ng-template #clarificationOptionContent let-opt let-index=\"index\" let-compact=\"compact\">\n @if (!compact) {\n <div class=\"clarification-decision-head\">\n <span class=\"clarification-decision-index\">{{ index + 1 }}</span>\n <span class=\"clarification-decision-type\">{{ getClarificationOptionKindLabel(opt) }}</span>\n <span class=\"spacer\"></span>\n @if (isClarificationSelected(opt)) {\n <span class=\"clarification-decision-state\">Selecionado</span>\n }\n </div>\n }\n @switch (getClarificationOptionLayout(opt)) {\n @case ('endpoint') {\n <div class=\"clarification-card\">\n <div class=\"clarification-card-header\">\n <mat-icon class=\"endpoint-icon\">{{ getEndpointIcon(opt) }}</mat-icon>\n @if (getEndpointMethod(opt); as method) {\n <span class=\"endpoint-method\" [attr.data-method]=\"method\">{{ method }}</span>\n }\n <span class=\"endpoint-label\">{{ opt.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon class=\"select-indicator\">\n {{ isClarificationSelected(opt) ? 'check_circle' : 'radio_button_unchecked' }}\n </mat-icon>\n </div>\n <div class=\"clarification-card-body\">\n @if (getEndpointPath(opt); as path) {\n <div class=\"endpoint-path\">{{ path }}</div>\n }\n @if (opt.contextHints?.description) {\n <div\n class=\"endpoint-description\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </div>\n }\n </div>\n </div>\n }\n @case ('color') {\n <div class=\"clarification-color\">\n <span\n class=\"color-swatch\"\n [style.background]=\"getSafeHexColor(opt) || 'var(--md-sys-color-surface-container-highest)'\"\n ></span>\n <div class=\"color-meta\">\n <span class=\"color-label\">{{ opt.label }}</span>\n @if (opt.contextHints?.hexColor) {\n <span class=\"color-value\">{{ opt.contextHints?.hexColor }}</span>\n }\n </div>\n </div>\n }\n @case ('description') {\n <div class=\"clarification-description\">\n <span class=\"clarification-label\">{{ opt.label }}</span>\n @if (opt.contextHints?.description) {\n <span\n class=\"clarification-subtitle\"\n [matTooltip]=\"getDescriptionTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowDescriptionTooltip(opt)\"\n >\n {{ opt.contextHints?.description }}\n </span>\n }\n </div>\n }\n @default {\n <span class=\"clarification-plain-label\">{{ opt.label }}</span>\n }\n }\n </ng-template>\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (clarificationQuestions.length) {\n <div\n class=\"clarification-questions\"\n [class.attention-highlight]=\"highlightClarificationDetails && !clarificationOptions.length\"\n >\n @for (question of clarificationQuestions; track question; let i = $index) {\n <div class=\"clarification-question\">\n <div class=\"clarification-question-label\">{{ question }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationAnswers[i]\"\n [placeholder]=\"'Resposta ' + (i + 1)\"\n autocomplete=\"off\">\n </div>\n }\n </div>\n }\n @if (clarificationOptions.length) {\n <div\n class=\"clarification-options-block\"\n [class.attention-highlight]=\"highlightClarificationDetails\"\n >\n <div class=\"clarification-options-title\">\n {{ clarificationOptions.length === 1 ? 'Decis\u00E3o sugerida' : 'Decis\u00F5es sugeridas' }}\n </div>\n @if (clarificationOptions.length === 1) {\n <div class=\"clarification-options-hint\">\n Etapa 2 de 4: confirme a melhor op\u00E7\u00E3o para continuar.\n </div>\n }\n @if (clarificationOptions.length > 1) {\n <div class=\"clarification-options-hint\">\n Etapa 2 de 4: selecione a alternativa mais aderente para gerar a proposta.\n </div>\n }\n @if (clarificationResponseType === 'confirm') {\n <div\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n <button\n mat-button\n type=\"button\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n }\n </div>\n }\n @if (clarificationSelectionMode === 'multiple') {\n <div\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n <button\n mat-button\n type=\"button\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n class=\"clarification-option\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n }\n </div>\n }\n @if (clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation !== 'chips') {\n <div\n class=\"clarification-buttons\"\n [class.list]=\"clarificationPresentation === 'list'\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n <button\n mat-button\n type=\"button\"\n (click)=\"onClarificationOptionClick(opt)\"\n class=\"clarification-option\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n }\n </div>\n }\n @if (clarificationResponseType !== 'confirm' && clarificationSelectionMode === 'single' && clarificationPresentation === 'chips') {\n <div\n class=\"clarification-chips\"\n >\n @for (opt of clarificationOptions; track opt; let i = $index) {\n @if (isEndpointOption(opt)) {\n <button\n mat-button\n type=\"button\"\n class=\"clarification-option clarification-card-button\"\n (click)=\"onClarificationOptionClick(opt)\"\n [class.selected]=\"isClarificationSelected(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt) || isEndpointOption(opt)\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: false }\"></ng-container>\n </button>\n } @else {\n <mat-chip\n (click)=\"onClarificationOptionClick(opt)\"\n [matTooltip]=\"getClarificationTooltip(opt)\"\n [matTooltipDisabled]=\"!shouldShowClarificationTooltip(opt)\"\n class=\"clarification-chip\"\n >\n <ng-container *ngTemplateOutlet=\"clarificationOptionContent; context: { $implicit: opt, index: i, compact: true }\"></ng-container>\n </mat-chip>\n }\n }\n </div>\n }\n </div>\n }\n @if (clarificationAllowCustom && clarificationResponseType !== 'context') {\n <div\n class=\"clarification-manual-toggle\"\n >\n <span class=\"clarification-manual-label\">N\u00E3o encontrou o recurso?</span>\n <button mat-button type=\"button\" (click)=\"toggleManualInput()\">\n {{ showManualInput ? 'Ocultar resposta manual' : 'Responder manualmente' }}\n </button>\n </div>\n }\n @if (clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context') {\n <div\n class=\"clarification-free\"\n >\n <input\n type=\"text\"\n [(ngModel)]=\"clarificationFreeText\"\n placeholder=\"Digite sua resposta\u2026\"\n autocomplete=\"off\"\n (keydown.enter)=\"confirmTaskAction()\"\n />\n </div>\n }\n @if (clarificationAllowCustom && showManualInput && clarificationResponseType !== 'context') {\n <div\n class=\"clarification-free-hint\"\n >\n Pressione Enter para enviar.\n </div>\n }\n </div>\n }\n\n <!-- STATE: REVIEW (Diff/Explanation) -->\n @if (state === 'review' && isActiveTab('task')) {\n <div\n class=\"review-area assistant-card\"\n id=\"assistant-panel-task\"\n role=\"tabpanel\"\n aria-labelledby=\"assistant-tab-task\"\n >\n @if (!shouldShowThoughtCard()) {\n <div class=\"task-header\">\n <div class=\"task-title\">{{ getTaskTitle() }}</div>\n <div class=\"task-subtitle\">{{ getTaskSubtitle() }}</div>\n @if (clarificationOptions.length > 1 && getTaskSelectionSummary(); as selectionSummary) {\n <div class=\"task-meta\">\n <span class=\"task-meta-label\">Selecionado:</span>\n <span class=\"task-meta-value\">{{ selectionSummary }}</span>\n </div>\n }\n @if (shouldShowTaskSteps()) {\n <div class=\"task-steps\">\n <span class=\"task-step\">1 Dados</span>\n <span class=\"task-step\">2 Layout</span>\n <span class=\"task-step active\">3 Revis\u00E3o</span>\n </div>\n }\n </div>\n }\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n <div class=\"review-trust\">\n <span class=\"trust-chip\" [matTooltip]=\"getScopeTooltip()\">{{ getScopeLabel() }}</span>\n <span class=\"trust-chip\" [matTooltip]=\"getConfidenceTooltip()\">{{ getConfidenceLabel() }}</span>\n <span class=\"trust-chip risk-chip\" [class.medium]=\"getReviewRiskLevel() === 'm\u00E9dio'\" [class.high]=\"getReviewRiskLevel() === 'alto'\">\n Risco {{ getReviewRiskLevel() }}\n </span>\n </div>\n <div class=\"review-summary\" [class.attention-highlight]=\"highlightReviewDetails\">\n <div class=\"review-summary-title\">Resumo da proposta</div>\n <div class=\"review-summary-line\">{{ getReviewSummary() }}</div>\n </div>\n <div class=\"review-diff\">\n <div class=\"review-diff-title\">Pr\u00E9via de mudan\u00E7as</div>\n @if (pendingDiff.length) {\n <div class=\"review-diff-summary\">\n @for (line of getDiffSummaryLines(); track line) {\n <div class=\"review-diff-line\">{{ line }}</div>\n }\n @if (pendingDiff.length > 3) {\n <div class=\"review-diff-more\">\u2026 +{{ pendingDiff.length - 3 }} mudan\u00E7as</div>\n }\n </div>\n <button mat-stroked-button type=\"button\" class=\"review-diff-toggle\" (click)=\"toggleFullDiff()\">\n {{ getDiffToggleLabel() }}\n </button>\n } @else {\n <div class=\"review-diff-empty\">\n N\u00E3o foi poss\u00EDvel gerar um diff estruturado. Revise o resumo e aplique com cautela.\n </div>\n }\n @if (showFullDiff && pendingDiff.length) {\n <div class=\"review-diff-full\">\n @for (diff of pendingDiff; track diff) {\n <div class=\"review-diff-block\">\n <div class=\"review-diff-path\">{{ diff.path }}</div>\n <div class=\"review-diff-label\">Antes:</div>\n <pre>{{ diff.before | json }}</pre>\n <div class=\"review-diff-label\">Depois:</div>\n <pre>{{ diff.after | json }}</pre>\n </div>\n }\n </div>\n }\n </div>\n @if (aiExplanation.trim()) {\n <div class=\"ai-explanation\">\n {{ aiExplanation }}\n </div>\n }\n </div>\n }\n\n <!-- STATE: ERROR -->\n @if (state === 'error' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))) {\n <div\n class=\"error-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"error-msg\">\n <mat-icon color=\"warn\">error_outline</mat-icon>\n <span>{{ errorMsg }}</span>\n </div>\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (shouldShowApplyDetails()) {\n <div class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n @if (allowManualPatchEdit) {\n <div class=\"apply-details-actions\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar patch' }}\n </button>\n </div>\n }\n </div>\n @if (lastApplyAt) {\n <div class=\"apply-details-meta\">\n \u00DAltima tentativa: {{ lastApplyAt | date:'short' }}\n </div>\n }\n @if (getApplyPaths().length) {\n <div class=\"apply-paths\">\n @for (path of getApplyPaths(); track path) {\n <span class=\"apply-path-chip\">{{ path }}</span>\n }\n </div>\n }\n @if (applyWarnings.length) {\n <div class=\"apply-warnings\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n @for (warning of applyWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchPathEditorExpanded) {\n <div class=\"patch-path-editor\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n @if (!getEditablePatchPathEdits().length) {\n <div class=\"patch-path-editor-empty\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n }\n @if (getEditablePatchPathEdits().length) {\n <div class=\"patch-path-rows\">\n @for (edit of getEditablePatchPathEdits(); track edit; let i = $index) {\n <div class=\"patch-path-row\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (patchPathEdits[i].error) {\n <div class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n }\n </div>\n }\n </div>\n }\n @if (patchPathEditorError) {\n <div class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchEditorExpanded) {\n <div class=\"patch-editor\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n @if (patchEditorError) {\n <div class=\"patch-editor-error\">{{ patchEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n }\n </div>\n }\n <div class=\"review-actions\">\n <button mat-button (click)=\"close()\">Fechar</button>\n <button mat-stroked-button (click)=\"retry()\">Tentar Novamente</button>\n </div>\n </div>\n }\n\n <!-- STATE: SUCCESS -->\n @if (state === 'success' && (isActiveTab('task') || (!isTaskMode() && isActiveTab('suggestions')))) {\n <div\n class=\"success-area assistant-card\"\n [attr.id]=\"isTaskMode() ? 'assistant-panel-task' : 'assistant-panel-suggestions'\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"isTaskMode() ? 'assistant-tab-task' : 'assistant-tab-suggestions'\"\n >\n <div class=\"success-msg\">\n <mat-icon class=\"success-icon\">check_circle</mat-icon>\n <span>{{ aiExplanation || 'Configura\u00E7\u00E3o atualizada.' }}</span>\n </div>\n @if (warnings.length) {\n <div class=\"warnings-area\">\n <mat-icon class=\"warnings-icon\">warning_amber</mat-icon>\n <div class=\"warnings-content\">\n <div class=\"warnings-title\">Avisos</div>\n <div class=\"warnings-list\">\n @for (warning of warnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n </div>\n }\n @if (shouldShowApplyDetails()) {\n <div class=\"apply-details\">\n <div class=\"apply-details-header\">\n <div class=\"apply-details-title\">Detalhes da aplica\u00E7\u00E3o</div>\n @if (allowManualPatchEdit) {\n <div class=\"apply-details-actions\">\n <button mat-button type=\"button\" (click)=\"togglePatchPathEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchPathEditorExpanded ? 'Ocultar paths' : 'Editar por path' }}\n </button>\n <button mat-button type=\"button\" (click)=\"togglePatchEditor()\" [disabled]=\"!pendingPatch\">\n {{ patchEditorExpanded ? 'Ocultar editor' : 'Editar e reaplicar' }}\n </button>\n </div>\n }\n </div>\n @if (lastApplyAt) {\n <div class=\"apply-details-meta\">\n Aplicado em {{ lastApplyAt | date:'short' }}\n </div>\n }\n @if (getApplyPaths().length) {\n <div class=\"apply-paths\">\n @for (path of getApplyPaths(); track path) {\n <span class=\"apply-path-chip\">{{ path }}</span>\n }\n </div>\n }\n @if (applyWarnings.length) {\n <div class=\"apply-warnings\">\n <div class=\"apply-warnings-title\">Avisos da aplica\u00E7\u00E3o</div>\n <div class=\"apply-warnings-list\">\n @for (warning of applyWarnings; track warning) {\n <div>{{ warning }}</div>\n }\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchPathEditorExpanded) {\n <div class=\"patch-path-editor\">\n <div class=\"patch-editor-label\">Editar por path</div>\n <div class=\"patch-editor-hint\">Texto simples vira string; para for\u00E7ar texto em true/false/n\u00FAmero, use aspas.</div>\n @if (!getEditablePatchPathEdits().length) {\n <div class=\"patch-path-editor-empty\">\n Nenhum path edit\u00E1vel dispon\u00EDvel para este patch.\n </div>\n }\n @if (getEditablePatchPathEdits().length) {\n <div class=\"patch-path-rows\">\n @for (edit of getEditablePatchPathEdits(); track edit; let i = $index) {\n <div class=\"patch-path-row\">\n <div class=\"patch-path-label\">{{ edit.path }}</div>\n <input\n type=\"text\"\n [(ngModel)]=\"patchPathEdits[i].valueText\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (patchPathEdits[i].error) {\n <div class=\"patch-editor-error\">{{ patchPathEdits[i].error }}</div>\n }\n </div>\n }\n </div>\n }\n @if (patchPathEditorError) {\n <div class=\"patch-editor-error\">{{ patchPathEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchPathEdits()\">\n Restaurar valores\n </button>\n <button mat-button type=\"button\" (click)=\"applyPathEditsToPatch()\">\n Aplicar no patch\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyPathEdits()\">\n Reaplicar por path\n </button>\n </div>\n </div>\n }\n @if (allowManualPatchEdit && patchEditorExpanded) {\n <div class=\"patch-editor\">\n <label class=\"patch-editor-label\">Patch JSON</label>\n <textarea\n [(ngModel)]=\"patchEditorText\"\n spellcheck=\"false\"\n ></textarea>\n @if (patchEditorError) {\n <div class=\"patch-editor-error\">{{ patchEditorError }}</div>\n }\n <div class=\"patch-editor-actions\">\n <button mat-button type=\"button\" (click)=\"resetPatchEditor()\">\n Restaurar original\n </button>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"reapplyEditedPatch()\">\n Reaplicar patch\n </button>\n </div>\n </div>\n }\n </div>\n }\n <button mat-button color=\"warn\" (click)=\"undoLastChange()\">\n <mat-icon>undo</mat-icon> Desfazer\n </button>\n </div>\n }\n\n </div>\n\n <div class=\"assistant-footer\">\n @if (!isTaskMode()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"composer-leading composer-leading-btn\"\n [matMenuTriggerFor]=\"assistantQuickMenu\"\n aria-label=\"Abrir a\u00E7\u00F5es r\u00E1pidas\"\n matTooltip=\"A\u00E7\u00F5es r\u00E1pidas\"\n >\n <mat-icon>add</mat-icon>\n </button>\n <input\n #inputEl\n type=\"text\"\n [(ngModel)]=\"userPrompt\"\n [disabled]=\"state === 'processing' || state === 'applying'\"\n placeholder=\"Descreva a altera\u00E7\u00E3o que deseja aplicar\u2026\"\n autocomplete=\"off\"\n />\n <div class=\"send-actions\">\n @if (state === 'listening') {\n <button\n mat-icon-button\n class=\"send-btn\"\n (click)=\"submitPrompt()\"\n [disabled]=\"!userPrompt.trim()\"\n [class.ready]=\"!!userPrompt.trim()\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n }\n @if (state === 'processing' || state === 'applying') {\n <mat-spinner diameter=\"20\"></mat-spinner>\n }\n </div>\n } @else {\n <div class=\"task-footer\">\n <div class=\"task-footer-left\">\n <button mat-button type=\"button\" (click)=\"handleTaskSecondary()\">{{ getTaskCancelLabel() }}</button>\n @if (state === 'review') {\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"retry()\"\n >\n {{ getTaskSecondaryLabel() }}\n </button>\n }\n </div>\n <div class=\"task-footer-right\">\n <button\n class=\"task-primary-btn\"\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"confirmTaskAction()\"\n [disabled]=\"isTaskPrimaryDisabled()\"\n >\n {{ getTaskPrimaryLabel() }}\n </button>\n @if (state === 'processing' || state === 'applying') {\n <mat-spinner diameter=\"20\"></mat-spinner>\n }\n </div>\n </div>\n }\n </div>\n\n <mat-menu #assistantQuickMenu=\"matMenu\" panelClass=\"assistant-quick-menu-panel\">\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('chat')\">\n <mat-icon>history</mat-icon>\n <span>Hist\u00F3rico</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"setActiveTab('suggestions')\">\n <mat-icon>lightbulb</mat-icon>\n <span>Sugest\u00F5es</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"startNewSession()\">\n <mat-icon>add_comment</mat-icon>\n <span>Nova conversa</span>\n </button>\n <button mat-menu-item type=\"button\" (click)=\"refreshSuggestions()\" [disabled]=\"loadingSuggestions\">\n <mat-icon>refresh</mat-icon>\n <span>Atualizar sugest\u00F5es</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n (click)=\"restoreDismissedSuggestions()\"\n [disabled]=\"!hasDismissedSuggestions()\"\n >\n <mat-icon>visibility</mat-icon>\n <span>Restaurar sugest\u00F5es ocultas</span>\n </button>\n <button\n mat-menu-item\n type=\"button\"\n class=\"assistant-quick-menu-danger\"\n (click)=\"clearHistory()\"\n [disabled]=\"!historySessions.length\"\n >\n <mat-icon>delete_outline</mat-icon>\n <span>Limpar hist\u00F3rico local</span>\n </button>\n </mat-menu>\n </div>\n\n</ng-template>\n", styles: ["@keyframes assistantPremiumEnter{0%{opacity:0;transform:translate(14px) scale(.99)}to{opacity:1;transform:translate(0) scale(1)}}:host ::ng-deep .ai-assistant-backdrop{background:color-mix(in srgb,var(--md-sys-color-scrim, var(--md-sys-color-shadow, var(--md-sys-color-on-surface))) 42%,transparent);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}::ng-deep .ai-assistant-overlay-pane{max-width:calc(100vw - 24px);max-height:calc(100vh - 24px)}.ai-assistant-panel{box-sizing:border-box;width:min(604px,100vw - 18px);min-height:min(620px,100vh - 18px);max-height:min(820px,100vh - 18px);display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border-left:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-top:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));box-shadow:0 18px 48px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 42%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);background:radial-gradient(circle at 14% 8%,color-mix(in srgb,var(--md-sys-color-primary-container) 38%,transparent) 0%,transparent 44%),linear-gradient(165deg,color-mix(in srgb,var(--md-sys-color-surface-container-highest) 88%,var(--md-sys-color-surface)),var(--md-sys-color-surface));animation:assistantPremiumEnter .24s cubic-bezier(.22,1,.36,1)}.assistant-header{position:relative;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:12px 16px 10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(130deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.assistant-header:after{content:\"\";position:absolute;left:16px;right:16px;bottom:-1px;height:1px;background:linear-gradient(90deg,color-mix(in srgb,var(--md-sys-color-primary) 55%,transparent),transparent);pointer-events:none}.assistant-header .assistant-header__left{min-width:0;display:flex;align-items:flex-start;gap:12px}.assistant-header .magic-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:30px;height:30px;font-size:18px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent);box-shadow:0 4px 12px color-mix(in srgb,var(--md-sys-color-primary) 26%,transparent)}.assistant-header .assistant-title-group{min-width:0;display:flex;flex-direction:column;gap:4px}.assistant-header .assistant-title{font-size:15px;font-weight:700;letter-spacing:.01em;overflow-wrap:anywhere}.assistant-header .assistant-subtitle{display:block;font-size:11px;line-height:1.25;color:color-mix(in srgb,var(--md-sys-color-on-surface) 70%,var(--md-sys-color-on-surface-variant));overflow-wrap:anywhere}.assistant-header-chips{display:inline-flex;align-items:center;flex-wrap:wrap;gap:6px}.assistant-header .mode-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 28%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 64%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-primary-container) 85%,var(--md-sys-color-on-surface));font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.assistant-header .mode-chip:before{content:\"\";width:6px;height:6px;border-radius:999px;background:currentColor;box-shadow:0 0 0 3px color-mix(in srgb,currentColor 16%,transparent)}.assistant-header .mode-chip.mock{border-color:color-mix(in srgb,var(--md-sys-color-error) 34%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-error-container) 72%,var(--md-sys-color-surface-container));color:color-mix(in srgb,var(--md-sys-color-on-error-container) 85%,var(--md-sys-color-error))}.assistant-header .policy-chip{padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 84%,transparent);background:var(--md-sys-color-surface-container-high);font-size:10px;letter-spacing:.02em;font-weight:600}.assistant-header .policy-chip.strict{border-color:color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 56%,var(--md-sys-color-surface-container-high))}.assistant-status{display:flex;align-items:flex-start;gap:10px;padding:10px 16px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-radius:0;background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 24%,transparent),transparent 48%),var(--md-sys-color-surface-container-low)}.assistant-status-dot{width:8px;height:8px;margin-top:6px;border-radius:999px;flex:0 0 auto;background:var(--md-sys-color-primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.assistant-status.warning .assistant-status-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 4px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.assistant-status.success .assistant-status-dot{background:color-mix(in srgb,var(--md-sys-color-primary) 74%,var(--md-sys-color-tertiary, var(--md-sys-color-primary)))}.assistant-status-content{min-width:0;display:flex;flex-direction:column;gap:2px}.assistant-status-label{display:flex;align-items:center;flex-wrap:wrap;gap:4px;font-size:12px;font-weight:700;line-height:1.35}.assistant-status-detail{font-size:11px;line-height:1.4;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.assistant-status-mode{padding:1px 6px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent);color:var(--md-sys-color-on-primary-container);font-size:10px;font-weight:700}.assistant-nav{padding:8px 16px 0}.assistant-nav .assistant-tabs{display:flex;align-items:center;gap:4px;border-radius:12px;padding:5px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(155deg,color-mix(in srgb,var(--md-sys-color-primary-container) 14%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-nav .assistant-tab{appearance:none;min-width:0;min-height:30px;border:0;border-radius:8px;padding:0 10px;background:transparent;color:var(--md-sys-color-on-surface-variant);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex:1 1 0;font-size:11px;font-weight:700;letter-spacing:.01em}.assistant-nav .assistant-tab.active{background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent),0 6px 12px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.assistant-section,.assistant-card{border-radius:14px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(160deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 50%),var(--md-sys-color-surface-container-lowest);box-shadow:0 6px 18px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 7%,transparent)}.suggestions-hero{margin:2px 0 4px;padding:10px 12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:linear-gradient(120deg,color-mix(in srgb,var(--md-sys-color-primary-container) 34%,transparent) 0%,transparent 52%),var(--md-sys-color-surface-container-low)}.suggestions-hero__label{font-size:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:var(--md-sys-color-on-surface-variant);opacity:.88}.suggestions-hero__title{margin-top:2px;font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.suggestions-hero__detail{margin-top:4px;font-size:12px;line-height:1.4;color:color-mix(in srgb,var(--md-sys-color-on-surface) 78%,var(--md-sys-color-on-surface-variant))}.suggestions-content .suggestion-item{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));border-color:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant));background:linear-gradient(140deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-lowest);transition:transform .2s cubic-bezier(.25,.8,.25,1),border-color .2s ease,box-shadow .2s ease}.suggestions-list{display:flex;flex-direction:column;gap:10px}.suggestion-copy{min-width:0;display:grid;gap:4px}.suggestion-main{min-width:0;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.suggestion-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto;color:var(--md-sys-color-primary)}.suggestion-label{min-width:0;font-size:13px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestion-group{padding:2px 6px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:10px;font-weight:700;line-height:1.2}.suggestion-desc{font-size:12px;line-height:1.35;color:var(--md-sys-color-on-surface-variant);overflow-wrap:anywhere}.suggestion-actions{display:inline-flex;align-items:center;justify-content:flex-end;gap:4px}.suggestion-action-btn,.suggestion-arrow{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--md-sys-color-on-surface-variant)}.suggestions-content .suggestion-item:hover,.suggestions-content .suggestion-item:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant));box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 28%,transparent);transform:translateY(-2px) scale(1.01)}.assistant-footer{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:10px 16px;border-top-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 56%),var(--md-sys-color-surface-container-low)}.assistant-footer .task-footer{grid-column:1/-1}.composer-leading{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 30%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 70%,var(--md-sys-color-surface-container-low));color:var(--md-sys-color-primary);box-shadow:0 4px 10px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.composer-leading mat-icon{width:16px;height:16px;font-size:16px}.assistant-footer input{box-sizing:border-box;width:100%;min-width:0;height:34px;border:1px solid;border-radius:8px;padding:0 12px;color:var(--md-sys-color-on-surface);border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface);box-shadow:inset 0 1px 2px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 12%,transparent)}.send-actions{min-width:36px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn{--mdc-icon-button-icon-size: 20px;--mdc-icon-button-state-layer-size: 36px;--mat-icon-button-state-layer-size: 36px;width:36px;height:36px;padding:8px;line-height:1;display:inline-flex;align-items:center;justify-content:center;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface)}.assistant-footer .send-btn mat-icon{width:20px;height:20px;margin:0;font-size:20px;line-height:20px;display:inline-flex;align-items:center;justify-content:center}.assistant-footer .send-btn.ready{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary-container) 84%,var(--md-sys-color-primary)),var(--md-sys-color-primary));color:var(--md-sys-color-on-primary);box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 30%,transparent)}.task-primary-btn{border-radius:12px;box-shadow:0 8px 18px color-mix(in srgb,var(--md-sys-color-primary) 24%,transparent)}@media(max-width:959px){.assistant-header{padding:12px 12px 10px}.assistant-section,.assistant-card{margin:4px 12px 10px}.assistant-header:after{left:12px;right:12px}.assistant-header .assistant-title{font-size:14px}.assistant-header .assistant-subtitle{font-size:10px}.assistant-footer{grid-template-columns:minmax(0,1fr) auto}.composer-leading{display:none}}.assistant-thought{margin-top:0;gap:10px;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 28%,transparent),transparent 58%),var(--md-sys-color-surface-container-low)}.assistant-thought-meta{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-meta mat-icon{width:15px;height:15px;font-size:15px;color:var(--md-sys-color-primary)}.assistant-thought-summary{font-size:13px;line-height:1.45;color:var(--md-sys-color-on-surface)}.assistant-thought-plan{border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 32%,var(--md-sys-color-outline-variant));border-radius:12px;padding:10px;background:var(--md-sys-color-surface-container-lowest);display:flex;flex-direction:column;gap:8px}.assistant-thought-plan-title{font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.assistant-thought-plan-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px}.assistant-thought-plan-actions .mdc-button{min-width:0}.assistant-thought-plan-hint{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.35}.assistant-thought-checklist{display:flex;flex-direction:column;gap:5px}.assistant-thought-checklist-item{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.assistant-thought-checklist-item mat-icon{width:14px;height:14px;font-size:14px}.assistant-thought-shimmer{display:flex;flex-direction:column;gap:8px;margin-top:4px}.assistant-thought-shimmer .shimmer-line{height:12px;border-radius:4px;position:relative;overflow:hidden;background:var(--md-sys-color-surface-container-highest)}.assistant-thought-shimmer .shimmer-line:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent);animation:assistantShimmerEffect 1.5s infinite}.assistant-thought-shimmer .shimmer-line-1{width:85%}.assistant-thought-shimmer .shimmer-line-2{width:92%}.assistant-thought-shimmer .shimmer-line-3{width:64%}@keyframes assistantShimmerEffect{to{transform:translate(100%)}}.assistant-flow{grid-template-columns:1fr;gap:6px}.flow-step{display:flex;align-items:flex-start;gap:8px;text-align:left;padding:7px 8px;border-radius:10px}.flow-step-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.flow-step-content{min-width:0;display:flex;flex-direction:column;gap:1px}.flow-step-label{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.flow-step-detail{font-size:11px;color:var(--md-sys-color-on-surface-variant);line-height:1.3}.flow-step.active .flow-step-index{border-color:color-mix(in srgb,var(--md-sys-color-primary) 60%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 85%,var(--md-sys-color-surface-container-highest));color:var(--md-sys-color-on-primary-container)}.flow-step.done .flow-step-index{border-color:transparent;background:color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-surface-container-highest))}.task-timeline{margin-top:4px;display:grid;gap:6px}.task-timeline-item{display:flex;align-items:flex-start;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);opacity:.76}.task-timeline-item.active{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 40%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-low))}.task-timeline-item.done{opacity:.9;border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant))}.task-timeline-dot{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-highest);color:var(--md-sys-color-on-surface);flex:0 0 auto}.task-timeline-copy{min-width:0;display:flex;flex-direction:column;gap:1px}.task-timeline-title{font-size:11px;font-weight:700;color:var(--md-sys-color-on-surface)}.task-timeline-detail{font-size:11px;line-height:1.3;color:var(--md-sys-color-on-surface-variant)}.clarification-decision-head{display:inline-flex;align-items:center;width:100%;gap:6px;padding:8px 12px 0;box-sizing:border-box}.clarification-decision-index{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 68%,transparent)}.clarification-decision-type{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);opacity:.92}.clarification-decision-state{font-size:10px;font-weight:700;color:var(--md-sys-color-primary)}.clarification-option{border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 16%,transparent),transparent 55%),var(--md-sys-color-surface-container-low)}.clarification-option.selected{border-color:color-mix(in srgb,var(--md-sys-color-primary) 56%,var(--md-sys-color-outline-variant));background:linear-gradient(145deg,color-mix(in srgb,var(--md-sys-color-primary-container) 44%,transparent),transparent 62%),var(--md-sys-color-surface-container);box-shadow:0 8px 16px color-mix(in srgb,var(--md-sys-color-primary) 18%,transparent)}.clarification-options-block{overflow:visible;padding-right:4px}@media(max-width:959px){.assistant-thought-plan-actions{grid-template-columns:1fr}}.ai-assistant-panel{width:min(604px,100vw - 18px)}.assistant-section,.assistant-card{margin:0;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 20%,var(--md-sys-color-outline-variant))}.assistant-section{min-height:0;padding:14px 16px;overflow:visible}.assistant-card{min-height:0;padding:14px 16px 16px;overflow:visible}.suggestions-area,.assistant-history,.loading-suggestions{overflow-y:auto;overflow-x:hidden}.section-header{min-width:0;display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}.section-title{min-width:0;font-size:14px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.suggestions-actions{flex:0 0 auto;display:inline-flex;align-items:center}.review-area,.error-area,.success-area,.clarification-area{padding:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:auto}.review-trust{margin:2px 0 4px}.trust-chip{max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.warnings-area,.review-summary,.review-diff,.apply-details,.clarification-options-block,.clarification-manual-toggle{width:100%;max-width:100%;min-width:0}.review-diff{padding:12px 14px}.review-diff-full{padding:10px;overflow-x:auto}.review-diff-block{min-width:0}.review-diff-block pre{overflow-wrap:anywhere;word-break:break-word}.clarification-options-block{padding:4px 2px 10px}.clarification-option{line-height:normal}:host ::ng-deep .clarification-option .mdc-button__label{line-height:1.35!important}.clarification-plain-label{padding:6px 12px 12px;font-size:14px;line-height:1.35}.clarification-manual-toggle{margin-top:10px;padding:10px 2px 0;flex-wrap:wrap;row-gap:6px}.suggestions-content .suggestion-actions{gap:6px}.suggestions-content .suggestion-arrow,.suggestions-content .suggestion-action-btn mat-icon,.suggestions-content .suggestion-arrow mat-icon{display:inline-flex;align-items:center;justify-content:center}:host ::ng-deep .assistant-quick-menu-panel{min-width:244px;max-width:min(90vw,320px);border-radius:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high);box-shadow:0 12px 28px color-mix(in srgb,var(--md-sys-color-shadow, var(--md-sys-color-on-surface)) 32%,transparent),inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface) 6%,transparent);overflow:hidden;padding:6px}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item{min-height:36px;border-radius:10px;color:var(--md-sys-color-on-surface);font-size:12px;font-weight:500;margin:1px 0}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item .mat-icon{color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,var(--md-sys-color-on-surface-variant))}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:hover:not([disabled]){background:color-mix(in srgb,var(--md-sys-color-primary-container) 45%,transparent)}:host ::ng-deep .assistant-quick-menu-panel .mat-mdc-menu-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:-2px}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger{color:var(--md-sys-color-error)}:host ::ng-deep .assistant-quick-menu-panel .assistant-quick-menu-danger .mat-icon{color:var(--md-sys-color-error)}@media(max-width:959px){::ng-deep .ai-assistant-overlay-pane{top:12px!important;left:12px!important;width:calc(100vw - 24px)!important;height:calc(100vh - 24px)!important;max-width:calc(100vw - 24px);max-height:calc(100vh - 24px);transform:none!important}.ai-assistant-panel{width:calc(100vw - 48px);min-height:min(620px,100vh - 48px);max-height:calc(100vh - 48px)}.assistant-section,.assistant-card{margin:0}.assistant-card,.assistant-section{padding:12px}}.ai-trigger-btn{--mdc-icon-button-state-layer-size: 36px;width:36px;height:36px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary) 9%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent);color:var(--md-sys-color-primary);opacity:1}.ai-trigger-btn:hover:not(:disabled){background:color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent);border-color:color-mix(in srgb,var(--md-sys-color-primary) 36%,transparent);color:var(--md-sys-color-on-primary-container)}.ai-trigger-btn:focus-visible,.assistant-close-btn:focus-visible,.assistant-tab:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.assistant-close-btn{width:28px;height:28px;color:var(--md-sys-color-on-surface-variant)}.assistant-close-btn:hover:not(:disabled){background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}.assistant-body{padding:12px 16px;overflow:hidden;min-height:0;flex:1;display:flex;flex-direction:column;gap:12px}.assistant-body>*{min-height:0}@media(max-width:959px){.assistant-nav{padding:8px 12px 0}.assistant-body,.assistant-footer{padding:10px 12px}.suggestions-content .suggestion-item{grid-template-columns:1fr;align-items:start}.suggestion-actions{justify-content:flex-start}}\n"] }]
|
|
6689
6691
|
}], propDecorators: { adapter: [{
|
|
6690
6692
|
type: Input,
|
|
6691
6693
|
args: [{ required: true }]
|
|
@@ -7904,10 +7906,10 @@ class PraxisAiAssistantShellComponent {
|
|
|
7904
7906
|
URL.revokeObjectURL(previewUrl);
|
|
7905
7907
|
this.ownedPreviewUrls.delete(previewUrl);
|
|
7906
7908
|
}
|
|
7907
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
7908
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisAiAssistantShellComponent, isStandalone: true, selector: "praxis-ai-assistant-shell", inputs: { labels: "labels", mode: "mode", state: "state", contextItems: "contextItems", attachments: "attachments", messages: "messages", quickReplies: "quickReplies", prompt: "prompt", statusText: "statusText", errorText: "errorText", testIdPrefix: "testIdPrefix", panelTestId: "panelTestId", submitTestId: "submitTestId", applyTestId: "applyTestId", primaryAction: "primaryAction", secondaryActions: "secondaryActions", governanceActions: "governanceActions", busy: "busy", canSubmit: "canSubmit", canApply: "canApply", submitOnEnter: "submitOnEnter", showAttachAction: "showAttachAction", enablePastedAttachments: "enablePastedAttachments", enableFileAttachments: "enableFileAttachments", attachmentAccept: "attachmentAccept", attachmentMultiple: "attachmentMultiple", draggable: "draggable", resizable: "resizable", minWidth: "minWidth", minHeight: "minHeight", margin: "margin", layout: "layout" }, outputs: { promptChange: "promptChange", submitPrompt: "submitPrompt", apply: "apply", retryTurn: "retryTurn", cancelTurn: "cancelTurn", shellAction: "shellAction", close: "close", attach: "attach", attachmentsPasted: "attachmentsPasted", attachmentsSelected: "attachmentsSelected", removeAttachment: "removeAttachment", messageAction: "messageAction", editMessage: "editMessage", resendMessage: "resendMessage", quickReply: "quickReply", layoutChange: "layoutChange" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true, static: true }, { propertyName: "conversation", first: true, predicate: ["conversation"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<section\n #panel\n class=\"praxis-ai-assistant-shell\"\n role=\"dialog\"\n [attr.aria-label]=\"resolvedLabels.title\"\n [attr.aria-busy]=\"busy ? 'true' : null\"\n [style.left.px]=\"currentLayout.left\"\n [style.top.px]=\"currentLayout.top\"\n [style.width.px]=\"currentLayout.width\"\n [style.height.px]=\"currentLayout.height\"\n [attr.data-testid]=\"panelTestId || testIdPrefix\"\n>\n <header\n class=\"praxis-ai-assistant-shell__header\"\n [attr.data-testid]=\"testIdPrefix + '-drag-handle'\"\n [attr.aria-label]=\"resolvedLabels.dragHandleAria\"\n (pointerdown)=\"startDrag($event)\"\n >\n <div class=\"praxis-ai-assistant-shell__identity\" aria-hidden=\"true\">\n <mat-icon>auto_awesome</mat-icon>\n </div>\n <div class=\"praxis-ai-assistant-shell__title-group\">\n <div class=\"praxis-ai-assistant-shell__title-row\">\n <strong>{{ resolvedLabels.title }}</strong>\n <div class=\"praxis-ai-assistant-shell__badges\" aria-hidden=\"true\">\n <span class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--context\">\n {{ getModeLabel() }}\n </span>\n <span\n class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--state\"\n [class.praxis-ai-assistant-shell__badge--error]=\"state === 'error'\"\n >\n <span class=\"praxis-ai-assistant-shell__state-dot\" aria-hidden=\"true\"></span>\n {{ getStateLabel() }}\n </span>\n </div>\n </div>\n <p *ngIf=\"resolvedLabels.subtitle\">{{ resolvedLabels.subtitle }}</p>\n </div>\n <div class=\"praxis-ai-assistant-shell__header-actions\">\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"resolvedLabels.close\"\n [attr.aria-label]=\"resolvedLabels.close\"\n (pointerdown)=\"$event.stopPropagation()\"\n (click)=\"close.emit()\"\n [attr.data-testid]=\"testIdPrefix + '-close'\"\n >\n <mat-icon>{{ getCloseIcon() }}</mat-icon>\n </button>\n </div>\n </header>\n\n <div class=\"praxis-ai-assistant-shell__body\">\n <div\n *ngIf=\"contextItems.length\"\n class=\"praxis-ai-assistant-shell__context\"\n [attr.aria-label]=\"resolvedLabels.contextAria\"\n [attr.data-testid]=\"testIdPrefix + '-context'\"\n >\n <span\n *ngFor=\"let item of contextItems; trackBy: trackContextItem\"\n class=\"praxis-ai-assistant-shell__context-item\"\n [attr.data-testid]=\"testIdPrefix + '-context-' + item.id\"\n >\n <mat-icon *ngIf=\"item.icon\" aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n <span class=\"praxis-ai-assistant-shell__context-label\">{{ item.label }}</span>\n <span *ngIf=\"item.value\" class=\"praxis-ai-assistant-shell__context-value\">{{ item.value }}</span>\n </span>\n </div>\n\n <div\n #conversation\n class=\"praxis-ai-assistant-shell__conversation\"\n [attr.data-testid]=\"testIdPrefix + '-conversation'\"\n [attr.aria-label]=\"resolvedLabels.conversationAria\"\n >\n <article\n *ngIf=\"!messages.length\"\n class=\"praxis-ai-assistant-shell__message praxis-ai-assistant-shell__message--assistant\"\n [attr.data-testid]=\"testIdPrefix + '-message-assistant-empty'\"\n >\n {{ resolvedLabels.emptyConversation }}\n </article>\n <article\n *ngFor=\"let message of messages; trackBy: trackMessage\"\n class=\"praxis-ai-assistant-shell__message\"\n [class.praxis-ai-assistant-shell__message--user]=\"message.role === 'user'\"\n [class.praxis-ai-assistant-shell__message--assistant]=\"message.role === 'assistant'\"\n [class.praxis-ai-assistant-shell__message--status]=\"message.role === 'status'\"\n [class.praxis-ai-assistant-shell__message--error]=\"message.role === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-message-' + message.role\"\n >\n <div\n class=\"praxis-ai-assistant-shell__message-content\"\n [innerHTML]=\"renderMessageText(message.text)\"\n ></div>\n <div\n *ngIf=\"message.actions?.length || message.editable || message.resendable\"\n class=\"praxis-ai-assistant-shell__message-actions\"\n >\n <button\n *ngIf=\"message.editable\"\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.editMessage\"\n [attr.aria-label]=\"resolvedLabels.editMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-edit-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'edit', label: resolvedLabels.editMessage, kind: 'edit' })\"\n >\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n <button\n *ngIf=\"message.resendable\"\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.resendMessage\"\n [attr.aria-label]=\"resolvedLabels.resendMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-resend-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'resend', label: resolvedLabels.resendMessage, kind: 'resend' })\"\n >\n <mat-icon aria-hidden=\"true\">replay</mat-icon>\n </button>\n <ng-container *ngFor=\"let action of message.actions || []; trackBy: trackMessageAction\">\n <button\n *ngIf=\"isMessageActionIconOnly(action); else textualMessageAction\"\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy || action.disabled\"\n [matTooltip]=\"getMessageActionLabel(action)\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n <mat-icon aria-hidden=\"true\">{{ getMessageActionIcon(action) }}</mat-icon>\n </button>\n <ng-template #textualMessageAction>\n <button\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action\"\n [disabled]=\"busy || action.disabled\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n {{ action.label }}\n </button>\n </ng-template>\n </ng-container>\n </div>\n </article>\n </div>\n\n <div\n *ngIf=\"attachments.length\"\n class=\"praxis-ai-assistant-shell__attachments\"\n [attr.aria-label]=\"resolvedLabels.attachmentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-attachments'\"\n >\n <div\n *ngFor=\"let attachment of attachments; trackBy: trackAttachment\"\n class=\"praxis-ai-assistant-shell__attachment\"\n [class.praxis-ai-assistant-shell__attachment--error]=\"attachment.status === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-' + attachment.id\"\n >\n <img\n *ngIf=\"attachment.previewUrl && attachment.kind === 'image'\"\n class=\"praxis-ai-assistant-shell__attachment-preview\"\n [src]=\"attachment.previewUrl\"\n [alt]=\"attachment.name\"\n >\n <span class=\"praxis-ai-assistant-shell__attachment-name\">{{ attachment.name }}</span>\n <span class=\"praxis-ai-assistant-shell__attachment-kind\">{{ attachment.kind }}</span>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.removeAttachment\"\n [attr.aria-label]=\"resolvedLabels.removeAttachment + ': ' + attachment.name\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-remove-' + attachment.id\"\n (click)=\"onRemoveAttachment(attachment)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n\n <div\n *ngIf=\"quickReplies.length\"\n class=\"praxis-ai-assistant-shell__quick-replies\"\n [class.praxis-ai-assistant-shell__quick-replies--inline]=\"shouldUseInlineQuickReplies()\"\n [attr.data-testid]=\"testIdPrefix + '-quick-replies'\"\n [attr.aria-label]=\"resolvedLabels.quickRepliesAria\"\n >\n <button\n *ngFor=\"let reply of quickReplies; trackBy: trackQuickReply\"\n mat-stroked-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__quick-reply\"\n [class.praxis-ai-assistant-shell__quick-reply--compact]=\"!isRichQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--guided-action]=\"isGuidedActionQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--contextual-action]=\"isContextualPreviewActionQuickReply(reply)\"\n [ngClass]=\"'praxis-ai-assistant-shell__quick-reply--tone-' + getQuickReplyTone(reply)\"\n [attr.data-testid]=\"testIdPrefix + '-quick-reply-' + (reply.id || reply.kind)\"\n [attr.aria-label]=\"getQuickReplyAriaLabel(reply)\"\n [disabled]=\"busy\"\n (click)=\"onQuickReply(reply)\"\n >\n <span class=\"praxis-ai-assistant-shell__quick-reply-ambient\" aria-hidden=\"true\"></span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-icon-frame\" aria-hidden=\"true\">\n <mat-icon\n class=\"praxis-ai-assistant-shell__quick-reply-icon\"\n >\n {{ getQuickReplyIcon(reply) }}\n </mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-header\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-heading\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-label\">{{ reply.label }}</span>\n <span\n *ngIf=\"getQuickReplyDescription(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-description\"\n >\n {{ getQuickReplyDescription(reply) }}\n </span>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-actions\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-badge\">\n {{ getQuickReplyCategoryLabel(reply) }}\n </span>\n <mat-icon\n *ngIf=\"getQuickReplyTechnicalDetails(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-details\"\n [matTooltip]=\"getQuickReplyTechnicalDetails(reply)\"\n [attr.aria-label]=\"resolvedLabels.quickReplyDetails\"\n >\n info\n </mat-icon>\n </span>\n </span>\n <span\n *ngIf=\"getQuickReplyContextChips(reply).length\"\n class=\"praxis-ai-assistant-shell__quick-reply-context\"\n >\n <span\n *ngFor=\"let chip of getQuickReplyContextChips(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-context-chip\"\n [attr.aria-label]=\"chip.ariaLabel\"\n >\n <mat-icon aria-hidden=\"true\">{{ chip.icon }}</mat-icon>\n <span>{{ chip.value }}</span>\n </span>\n </span>\n <span\n *ngIf=\"getQuickReplyPresentationItems(reply).length\"\n class=\"praxis-ai-assistant-shell__quick-reply-insights\"\n >\n <span\n *ngFor=\"let item of getQuickReplyPresentationItems(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-insight\"\n >\n <mat-icon aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-label\">\n {{ item.label }}\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-value\">\n {{ item.value }}\n </span>\n </span>\n </span>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-cta\">\n {{ getQuickReplyCtaLabel(reply) }}\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n </div>\n <p\n *ngIf=\"shouldShowStatusText()\"\n class=\"praxis-ai-assistant-shell__status\"\n [attr.data-testid]=\"testIdPrefix + '-status'\"\n >\n {{ statusText }}\n </p>\n <p\n *ngIf=\"shouldShowErrorText()\"\n class=\"praxis-ai-assistant-shell__error\"\n [attr.data-testid]=\"testIdPrefix + '-error'\"\n >\n {{ errorText }}\n </p>\n </div>\n\n <footer class=\"praxis-ai-assistant-shell__footer\">\n <label class=\"praxis-ai-assistant-shell__label\" for=\"praxis-ai-assistant-shell-prompt\">\n {{ resolvedLabels.prompt }}\n </label>\n <div class=\"praxis-ai-assistant-shell__composer\">\n <textarea\n id=\"praxis-ai-assistant-shell-prompt\"\n class=\"praxis-ai-assistant-shell__prompt\"\n [attr.data-testid]=\"testIdPrefix + '-prompt'\"\n [placeholder]=\"resolvedLabels.promptPlaceholder\"\n [ngModel]=\"currentPrompt\"\n [disabled]=\"busy\"\n (ngModelChange)=\"onPromptInput($event)\"\n (keydown)=\"onPromptKeydown($event)\"\n (paste)=\"onPromptPaste($event)\"\n ></textarea>\n <div class=\"praxis-ai-assistant-shell__composer-actions\">\n <ng-container *ngIf=\"showAttachAction\">\n <input\n #attachmentInput\n type=\"file\"\n hidden\n [attr.accept]=\"attachmentAccept || null\"\n [attr.multiple]=\"attachmentMultiple ? '' : null\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-input'\"\n (change)=\"onAttachmentFilesSelected($event)\"\n >\n <button\n mat-stroked-button\n type=\"button\"\n [disabled]=\"busy\"\n (click)=\"onAttachClick(attachmentInput)\"\n [attr.data-testid]=\"testIdPrefix + '-attach'\"\n >\n <mat-icon>attach_file</mat-icon>\n {{ resolvedLabels.attach }}\n </button>\n </ng-container>\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--primary\"\n [class.praxis-ai-assistant-shell__action--icon-only]=\"getPrimaryAction().iconOnly\"\n [matTooltip]=\"getPrimaryActionTooltip(getPrimaryAction())\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(getPrimaryAction())\"\n [disabled]=\"isShellActionDisabled(getPrimaryAction())\"\n (click)=\"onShellAction(getPrimaryAction())\"\n [attr.data-testid]=\"getPrimaryAction().testId || (submitTestId || (testIdPrefix + '-submit'))\"\n [attr.aria-label]=\"getPrimaryAction().ariaLabel || getPrimaryAction().label\"\n >\n <mat-icon *ngIf=\"getPrimaryAction().icon\" aria-hidden=\"true\">{{ getPrimaryAction().icon }}</mat-icon>\n <span *ngIf=\"!getPrimaryAction().iconOnly\">{{ getPrimaryAction().label }}</span>\n </button>\n <button\n *ngFor=\"let action of getSecondaryActions(); trackBy: trackShellAction\"\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--secondary\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(action)\"\n [disabled]=\"isShellActionDisabled(action)\"\n (click)=\"onShellAction(action)\"\n [attr.data-testid]=\"action.testId || (testIdPrefix + '-action-' + action.id)\"\n [attr.aria-label]=\"action.ariaLabel || action.label\"\n >\n <mat-icon *ngIf=\"action.icon\" aria-hidden=\"true\">{{ action.icon }}</mat-icon>\n {{ action.label }}\n </button>\n <mat-spinner *ngIf=\"busy\" diameter=\"20\" [attr.data-testid]=\"testIdPrefix + '-spinner'\"></mat-spinner>\n </div>\n </div>\n </footer>\n\n <ng-container *ngIf=\"resizable\">\n <span\n *ngFor=\"let direction of resizeHandles; trackBy: trackResizeHandle\"\n class=\"praxis-ai-assistant-shell__resize-handle praxis-ai-assistant-shell__resize-handle--{{ direction }}\"\n [attr.data-testid]=\"direction === 'se' ? testIdPrefix + '-resize-handle' : testIdPrefix + '-resize-handle-' + direction\"\n aria-hidden=\"true\"\n role=\"presentation\"\n (pointerdown)=\"startResize(direction, $event)\"\n ></span>\n </ng-container>\n</section>\n", styles: [":host{display:block}.praxis-ai-assistant-shell{--praxis-ai-assistant-shell-shadow-color: var(--md-sys-color-shadow);--praxis-ai-assistant-shell-highlight-color: var(--md-sys-color-on-surface);--praxis-ai-assistant-shell-tone-analytics: var(--md-sys-color-primary);--praxis-ai-assistant-shell-tone-resource: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-success: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-warning: var(--md-sys-color-secondary);--praxis-ai-assistant-shell-tone-danger: var(--md-sys-color-error);--praxis-ai-assistant-shell-tone-neutral: var(--md-sys-color-outline);position:fixed;box-sizing:border-box;min-width:360px;min-height:360px;display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface);box-shadow:0 24px 60px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 40%,transparent);z-index:var(--praxis-ai-assistant-shell-z-index, 1200)}.praxis-ai-assistant-shell__header{flex:0 0 auto;display:flex;align-items:flex-start;gap:9px;padding:10px 10px 9px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container)}.praxis-ai-assistant-shell__header{justify-content:flex-start;border-bottom:1px solid;cursor:move;touch-action:none}.praxis-ai-assistant-shell__identity{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border-radius:8px;background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary);box-shadow:0 6px 16px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.praxis-ai-assistant-shell__identity mat-icon{width:18px;height:18px;font-size:18px}.praxis-ai-assistant-shell__title-group{min-width:0;flex:1 1 auto;display:grid;gap:4px}.praxis-ai-assistant-shell__title-row{min-width:0;display:flex;align-items:center;gap:8px}.praxis-ai-assistant-shell__badges{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;min-width:0;flex-wrap:wrap}.praxis-ai-assistant-shell__badge{display:inline-flex;align-items:center;gap:5px;min-height:20px;max-width:120px;padding:2px 7px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);border-radius:8px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-high);font-size:11px;line-height:1.2;overflow-wrap:anywhere}.praxis-ai-assistant-shell__badge--context{color:var(--md-sys-color-on-surface);background:color-mix(in srgb,var(--md-sys-color-primary) 9%,var(--md-sys-color-surface-container-high))}.praxis-ai-assistant-shell__badge--state{border-color:transparent;background:transparent;color:var(--md-sys-color-on-surface-variant);padding-inline:3px}.praxis-ai-assistant-shell__badge--error{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__state-dot{flex:0 0 auto;width:6px;height:6px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__badge--error .praxis-ai-assistant-shell__state-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.praxis-ai-assistant-shell__title-group strong,.praxis-ai-assistant-shell__title-group p{min-width:0;margin:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__title-group strong{flex:1 1 auto;font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__title-group p{color:var(--md-sys-color-on-surface-variant);font-size:11.5px;line-height:1.3}.praxis-ai-assistant-shell__header-actions{flex:0 0 auto;display:flex;align-items:center;gap:2px;margin-top:-3px}.praxis-ai-assistant-shell__header-actions button{display:inline-grid;place-items:center;width:34px;height:34px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1;opacity:.78}.praxis-ai-assistant-shell__header-actions button:hover,.praxis-ai-assistant-shell__header-actions button:focus-visible{opacity:1}.praxis-ai-assistant-shell__header-actions mat-icon{display:block;width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__body{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:10px;padding:12px 12px 10px;overflow:auto;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface))}.praxis-ai-assistant-shell__context,.praxis-ai-assistant-shell__attachments{flex:0 0 auto;display:flex;align-items:center;gap:8px;overflow-x:auto}.praxis-ai-assistant-shell__context-item{flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;max-width:240px;padding:5px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high);font-size:12px;line-height:1.25}.praxis-ai-assistant-shell__context-item mat-icon{width:16px;height:16px;font-size:16px}.praxis-ai-assistant-shell__context-label,.praxis-ai-assistant-shell__context-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__context-label{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__context-value{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-ai-assistant-shell__prompt{box-sizing:border-box;width:100%;min-height:46px;max-height:96px;resize:none;border:0;padding:10px 12px 8px;color:var(--md-sys-color-on-surface);background:transparent;font:inherit;line-height:1.45;outline:none}.praxis-ai-assistant-shell__conversation{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:8px;overflow:auto;padding:2px}.praxis-ai-assistant-shell__message{max-width:86%;align-self:flex-start;padding:9px 11px;border-radius:8px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__message-content{white-space:normal}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5){margin:0}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5)+:where(p,ul,h3,h4,h5){margin-top:8px}.praxis-ai-assistant-shell__message-content ul{padding-left:18px}.praxis-ai-assistant-shell__message-content li+li{margin-top:4px}.praxis-ai-assistant-shell__message-content code{padding:1px 4px;border-radius:4px;background:color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.94em}.praxis-ai-assistant-shell__message-actions{display:flex;align-items:center;gap:4px;flex-wrap:wrap;margin-top:8px}.praxis-ai-assistant-shell__message-action{min-height:28px;padding:0 8px;border-radius:8px;font-size:12px}.praxis-ai-assistant-shell__message-action--icon{width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message-action--icon mat-icon{width:17px;height:17px;font-size:17px}.praxis-ai-assistant-shell__message--assistant{border-bottom-left-radius:2px}.praxis-ai-assistant-shell__message--user{align-self:flex-end;border-bottom-right-radius:2px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.praxis-ai-assistant-shell__message--status{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message--error,.praxis-ai-assistant-shell__error{color:var(--md-sys-color-error)}.praxis-ai-assistant-shell__quick-replies{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,520px),1fr));gap:8px;align-items:stretch;padding-bottom:4px}.praxis-ai-assistant-shell__quick-replies--inline{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.praxis-ai-assistant-shell__attachment{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;max-width:260px;min-height:34px;padding:4px 4px 4px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high)}.praxis-ai-assistant-shell__attachment--error{border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__attachment-preview{flex:0 0 auto;width:28px;height:28px;border-radius:6px;object-fit:cover}.praxis-ai-assistant-shell__attachment-name,.praxis-ai-assistant-shell__attachment-kind{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}.praxis-ai-assistant-shell__attachment-name{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__attachment-kind{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__quick-reply{--praxis-ai-assistant-shell-quick-reply-accent: var(--md-sys-color-primary);--praxis-ai-assistant-shell-quick-reply-background: color-mix( in srgb, var(--praxis-ai-assistant-shell-quick-reply-accent) 7%, var(--md-sys-color-surface-container-high) );--praxis-ai-assistant-shell-quick-reply-foreground: var(--md-sys-color-on-surface);width:100%;max-width:100%;height:auto;min-height:0;position:relative;overflow:hidden;padding:15px 16px;align-items:stretch;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 36%,transparent);border-radius:22px;color:var(--praxis-ai-assistant-shell-quick-reply-foreground);background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent),transparent 46%),radial-gradient(circle at 92% 10%,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent),transparent 32%),var(--praxis-ai-assistant-shell-quick-reply-background);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 22%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 16%,transparent);letter-spacing:normal;white-space:normal;text-align:left;text-transform:none;-webkit-user-select:none;user-select:none;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease,background .16s ease;--mdc-outlined-button-container-height: auto;--mat-outlined-button-horizontal-padding: 0}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 74%,transparent);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 24%,transparent),0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 18%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent);transform:translateY(-1px)}.praxis-ai-assistant-shell__quick-reply--contextual-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 92%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--guided-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 30%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--contextual-action:focus-visible,.praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 62%,transparent);box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent);transform:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-ambient,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-ambient{display:none}.praxis-ai-assistant-shell__quick-reply--contextual-action ::ng-deep .mdc-button__label,.praxis-ai-assistant-shell__quick-reply--guided-action ::ng-deep .mdc-button__label{gap:10px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon-frame,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:8px;box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-copy{gap:6px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-label{font-size:13.5px;font-weight:760;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-description{display:-webkit-box;overflow:hidden;font-size:12px;line-height:1.34;-webkit-box-orient:vertical;-webkit-line-clamp:2}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-badge{border-radius:8px;font-size:10px;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-context-chip{border-radius:8px;padding:4px 7px;font-size:10.5px;font-weight:650}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-cta,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta{font-size:11.5px}.praxis-ai-assistant-shell__quick-reply--compact{justify-self:start;width:fit-content;min-width:min(100%,210px);max-width:min(100%,320px);padding:9px 11px;border-radius:16px;background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),transparent 55%),var(--md-sys-color-surface-container-high);box-shadow:0 8px 18px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 16%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 10%,transparent)}.praxis-ai-assistant-shell__quick-reply.praxis-ai-assistant-shell__quick-reply--compact ::ng-deep .mdc-button__label{align-items:center;gap:10px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:12px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-copy{gap:4px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-header{align-items:center}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-label{font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply{width:auto;min-width:0;max-width:100%;padding:6px 10px;border-radius:999px;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 52%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{display:inline-flex;grid-template-columns:none;align-items:center;gap:6px;width:auto}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{min-height:34px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon-frame{width:18px;height:18px;border:0;border-radius:0;background:transparent;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon{width:16px;height:16px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:16px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-heading,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-header{display:inline-flex;align-items:center;gap:0}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:12.5px;font-weight:650;line-height:1.2;white-space:nowrap}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-actions,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{position:relative;z-index:1;min-width:0;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:flex-start;gap:14px;width:100%;height:auto;line-height:normal}.praxis-ai-assistant-shell__quick-reply-ambient{position:absolute;inset:0;pointer-events:none}.praxis-ai-assistant-shell__quick-reply-ambient:before{content:\"\";position:absolute;inset:0 18px auto;height:1px;border-radius:999px;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 90%,var(--praxis-ai-assistant-shell-highlight-color)),transparent);opacity:.58}.praxis-ai-assistant-shell__quick-reply-ambient:after{content:\"\";position:absolute;top:-34px;right:-44px;width:150px;height:150px;border-radius:999px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 13%,transparent);filter:blur(18px)}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{height:100%;min-height:48px}.praxis-ai-assistant-shell__quick-reply-icon-frame{flex:0 0 auto;width:46px;height:46px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);background:linear-gradient(145deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 24%,transparent),color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 6%,transparent));box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent),0 10px 24px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-reply-icon{width:24px;height:24px;font-size:24px}.praxis-ai-assistant-shell__quick-reply-details{flex:0 0 auto;width:24px;height:24px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 14%,transparent);border-radius:50%;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-outline) 14%,transparent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-copy{min-width:0;display:grid;gap:10px;flex:1 1 auto}.praxis-ai-assistant-shell__quick-reply-header{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.praxis-ai-assistant-shell__quick-reply-heading{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__quick-reply-actions{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:flex-end;gap:7px;max-width:46%}.praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply-description{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:17px;font-weight:760;letter-spacing:.005em;line-height:1.18;text-transform:none}.praxis-ai-assistant-shell__quick-reply-badge{flex:0 0 auto;max-width:100%;padding:4px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 28%,transparent);border-radius:999px;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 86%,var(--praxis-ai-assistant-shell-highlight-color));background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 11%,transparent);font-size:10.5px;font-weight:700;letter-spacing:.02em;line-height:1.1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-description{color:color-mix(in srgb,var(--md-sys-color-on-surface) 80%,transparent);font-size:13px;line-height:1.46}.praxis-ai-assistant-shell__quick-reply-context{display:flex;flex-wrap:wrap;gap:7px;align-items:center}.praxis-ai-assistant-shell__quick-reply-context-chip{min-width:0;display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:5px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent);border-radius:999px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,transparent);font-size:11px;font-weight:650;line-height:1.15}.praxis-ai-assistant-shell__quick-reply-context-chip mat-icon{width:14px;height:14px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:14px}.praxis-ai-assistant-shell__quick-reply-context-chip span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-insights{display:grid;grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:8px;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent);border-radius:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 5%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 26%,transparent))}.praxis-ai-assistant-shell__quick-reply-insight{min-width:0;display:grid;grid-template-columns:20px minmax(0,1fr);gap:8px;align-items:start;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent);border-radius:13px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 86%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 44%,transparent);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__quick-reply-insight mat-icon{width:17px;height:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-insight-copy{min-width:0;display:grid;gap:1px}.praxis-ai-assistant-shell__quick-reply-insight-label{color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 82%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:760;letter-spacing:.045em;line-height:1.2;text-transform:uppercase}.praxis-ai-assistant-shell__quick-reply-insight-value{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-cta{display:inline-flex;align-items:center;justify-self:start;gap:5px;padding:3px 0;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:12px;font-weight:760;letter-spacing:.01em;line-height:1.2}.praxis-ai-assistant-shell__quick-reply-cta mat-icon{width:15px;height:15px;font-size:15px;transition:transform .16s ease}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled) .praxis-ai-assistant-shell__quick-reply-cta mat-icon,.praxis-ai-assistant-shell__quick-reply:focus-visible .praxis-ai-assistant-shell__quick-reply-cta mat-icon{transform:translate(2px)}.praxis-ai-assistant-shell__quick-reply--tone-analytics{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__quick-reply--tone-resource{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__quick-reply--tone-warning{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__quick-reply--tone-success{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__quick-reply--tone-danger{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__quick-reply--tone-neutral{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-neutral)}@media(max-width:640px){.praxis-ai-assistant-shell__quick-reply{padding:13px;border-radius:19px}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{grid-template-columns:minmax(0,1fr);gap:10px}.praxis-ai-assistant-shell__quick-reply-icon-frame{width:38px;height:38px;border-radius:14px}.praxis-ai-assistant-shell__quick-reply-header{display:grid}.praxis-ai-assistant-shell__quick-reply-actions{justify-content:flex-start;max-width:100%}.praxis-ai-assistant-shell__quick-reply-insights{grid-template-columns:minmax(0,1fr)}}.praxis-ai-assistant-shell__status,.praxis-ai-assistant-shell__error{margin:0;font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__footer{flex:0 0 auto;padding:8px 10px 10px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container-low)}.praxis-ai-assistant-shell__composer{display:grid;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-lowest);box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 4%,transparent)}.praxis-ai-assistant-shell__composer:focus-within{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__composer-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 8px 7px;flex-wrap:wrap}.praxis-ai-assistant-shell__action{min-height:36px;border-radius:10px;font-weight:650}.praxis-ai-assistant-shell__action mat-icon{width:18px;height:18px;margin-right:6px;font-size:18px}.praxis-ai-assistant-shell__action--icon-only{width:40px;min-width:40px;height:40px;padding-inline:0;border-radius:50%}.praxis-ai-assistant-shell__action--icon-only mat-icon{margin-right:0}.praxis-ai-assistant-shell__action--secondary{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__action--tone-governance{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-success{color:var(--praxis-ai-assistant-shell-tone-success);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-warning{color:var(--praxis-ai-assistant-shell-tone-warning);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-warning) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-danger{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__resize-handle{position:absolute;z-index:2;border:0;background:transparent;touch-action:none}.praxis-ai-assistant-shell__resize-handle--n,.praxis-ai-assistant-shell__resize-handle--s{left:16px;right:16px;height:10px;cursor:ns-resize}.praxis-ai-assistant-shell__resize-handle--n{top:-5px}.praxis-ai-assistant-shell__resize-handle--s{bottom:-5px}.praxis-ai-assistant-shell__resize-handle--e,.praxis-ai-assistant-shell__resize-handle--w{top:16px;bottom:16px;width:10px;cursor:ew-resize}.praxis-ai-assistant-shell__resize-handle--e{right:-5px}.praxis-ai-assistant-shell__resize-handle--w{left:-5px}.praxis-ai-assistant-shell__resize-handle--ne,.praxis-ai-assistant-shell__resize-handle--nw,.praxis-ai-assistant-shell__resize-handle--se,.praxis-ai-assistant-shell__resize-handle--sw{width:22px;height:22px}.praxis-ai-assistant-shell__resize-handle--ne{top:-5px;right:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--nw{top:-5px;left:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--se{right:-5px;bottom:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--sw{bottom:-5px;left:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--se:after{content:\"\";position:absolute;right:8px;bottom:8px;width:10px;height:10px;border-right:2px solid var(--md-sys-color-outline);border-bottom:2px solid var(--md-sys-color-outline)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7909
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7910
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisAiAssistantShellComponent, isStandalone: true, selector: "praxis-ai-assistant-shell", inputs: { labels: "labels", mode: "mode", state: "state", contextItems: "contextItems", attachments: "attachments", messages: "messages", quickReplies: "quickReplies", prompt: "prompt", statusText: "statusText", errorText: "errorText", testIdPrefix: "testIdPrefix", panelTestId: "panelTestId", submitTestId: "submitTestId", applyTestId: "applyTestId", primaryAction: "primaryAction", secondaryActions: "secondaryActions", governanceActions: "governanceActions", busy: "busy", canSubmit: "canSubmit", canApply: "canApply", submitOnEnter: "submitOnEnter", showAttachAction: "showAttachAction", enablePastedAttachments: "enablePastedAttachments", enableFileAttachments: "enableFileAttachments", attachmentAccept: "attachmentAccept", attachmentMultiple: "attachmentMultiple", draggable: "draggable", resizable: "resizable", minWidth: "minWidth", minHeight: "minHeight", margin: "margin", layout: "layout" }, outputs: { promptChange: "promptChange", submitPrompt: "submitPrompt", apply: "apply", retryTurn: "retryTurn", cancelTurn: "cancelTurn", shellAction: "shellAction", close: "close", attach: "attach", attachmentsPasted: "attachmentsPasted", attachmentsSelected: "attachmentsSelected", removeAttachment: "removeAttachment", messageAction: "messageAction", editMessage: "editMessage", resendMessage: "resendMessage", quickReply: "quickReply", layoutChange: "layoutChange" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true, static: true }, { propertyName: "conversation", first: true, predicate: ["conversation"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<section\n #panel\n class=\"praxis-ai-assistant-shell\"\n role=\"dialog\"\n [attr.aria-label]=\"resolvedLabels.title\"\n [attr.aria-busy]=\"busy ? 'true' : null\"\n [style.left.px]=\"currentLayout.left\"\n [style.top.px]=\"currentLayout.top\"\n [style.width.px]=\"currentLayout.width\"\n [style.height.px]=\"currentLayout.height\"\n [attr.data-testid]=\"panelTestId || testIdPrefix\"\n >\n <header\n class=\"praxis-ai-assistant-shell__header\"\n [attr.data-testid]=\"testIdPrefix + '-drag-handle'\"\n [attr.aria-label]=\"resolvedLabels.dragHandleAria\"\n (pointerdown)=\"startDrag($event)\"\n >\n <div class=\"praxis-ai-assistant-shell__identity\" aria-hidden=\"true\">\n <mat-icon>auto_awesome</mat-icon>\n </div>\n <div class=\"praxis-ai-assistant-shell__title-group\">\n <div class=\"praxis-ai-assistant-shell__title-row\">\n <strong>{{ resolvedLabels.title }}</strong>\n <div class=\"praxis-ai-assistant-shell__badges\" aria-hidden=\"true\">\n <span class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--context\">\n {{ getModeLabel() }}\n </span>\n <span\n class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--state\"\n [class.praxis-ai-assistant-shell__badge--error]=\"state === 'error'\"\n >\n <span class=\"praxis-ai-assistant-shell__state-dot\" aria-hidden=\"true\"></span>\n {{ getStateLabel() }}\n </span>\n </div>\n </div>\n @if (resolvedLabels.subtitle) {\n <p>{{ resolvedLabels.subtitle }}</p>\n }\n </div>\n <div class=\"praxis-ai-assistant-shell__header-actions\">\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"resolvedLabels.close\"\n [attr.aria-label]=\"resolvedLabels.close\"\n (pointerdown)=\"$event.stopPropagation()\"\n (click)=\"close.emit()\"\n [attr.data-testid]=\"testIdPrefix + '-close'\"\n >\n <mat-icon>{{ getCloseIcon() }}</mat-icon>\n </button>\n </div>\n </header>\n\n <div class=\"praxis-ai-assistant-shell__body\">\n @if (contextItems.length) {\n <div\n class=\"praxis-ai-assistant-shell__context\"\n [attr.aria-label]=\"resolvedLabels.contextAria\"\n [attr.data-testid]=\"testIdPrefix + '-context'\"\n >\n @for (item of contextItems; track trackContextItem($index, item)) {\n <span\n class=\"praxis-ai-assistant-shell__context-item\"\n [attr.data-testid]=\"testIdPrefix + '-context-' + item.id\"\n >\n @if (item.icon) {\n <mat-icon aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n }\n <span class=\"praxis-ai-assistant-shell__context-label\">{{ item.label }}</span>\n @if (item.value) {\n <span class=\"praxis-ai-assistant-shell__context-value\">{{ item.value }}</span>\n }\n </span>\n }\n </div>\n }\n\n <div\n #conversation\n class=\"praxis-ai-assistant-shell__conversation\"\n [attr.data-testid]=\"testIdPrefix + '-conversation'\"\n [attr.aria-label]=\"resolvedLabels.conversationAria\"\n >\n @if (!messages.length) {\n <article\n class=\"praxis-ai-assistant-shell__message praxis-ai-assistant-shell__message--assistant\"\n [attr.data-testid]=\"testIdPrefix + '-message-assistant-empty'\"\n >\n {{ resolvedLabels.emptyConversation }}\n </article>\n }\n @for (message of messages; track trackMessage($index, message)) {\n <article\n class=\"praxis-ai-assistant-shell__message\"\n [class.praxis-ai-assistant-shell__message--user]=\"message.role === 'user'\"\n [class.praxis-ai-assistant-shell__message--assistant]=\"message.role === 'assistant'\"\n [class.praxis-ai-assistant-shell__message--status]=\"message.role === 'status'\"\n [class.praxis-ai-assistant-shell__message--error]=\"message.role === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-message-' + message.role\"\n >\n <div\n class=\"praxis-ai-assistant-shell__message-content\"\n [innerHTML]=\"renderMessageText(message.text)\"\n ></div>\n @if (message.actions?.length || message.editable || message.resendable) {\n <div\n class=\"praxis-ai-assistant-shell__message-actions\"\n >\n @if (message.editable) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.editMessage\"\n [attr.aria-label]=\"resolvedLabels.editMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-edit-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'edit', label: resolvedLabels.editMessage, kind: 'edit' })\"\n >\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n }\n @if (message.resendable) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.resendMessage\"\n [attr.aria-label]=\"resolvedLabels.resendMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-resend-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'resend', label: resolvedLabels.resendMessage, kind: 'resend' })\"\n >\n <mat-icon aria-hidden=\"true\">replay</mat-icon>\n </button>\n }\n @for (action of message.actions || []; track trackMessageAction($index, action)) {\n @if (isMessageActionIconOnly(action)) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy || action.disabled\"\n [matTooltip]=\"getMessageActionLabel(action)\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n <mat-icon aria-hidden=\"true\">{{ getMessageActionIcon(action) }}</mat-icon>\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action\"\n [disabled]=\"busy || action.disabled\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n {{ action.label }}\n </button>\n }\n }\n </div>\n }\n </article>\n }\n </div>\n\n @if (attachments.length) {\n <div\n class=\"praxis-ai-assistant-shell__attachments\"\n [attr.aria-label]=\"resolvedLabels.attachmentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-attachments'\"\n >\n @for (attachment of attachments; track trackAttachment($index, attachment)) {\n <div\n class=\"praxis-ai-assistant-shell__attachment\"\n [class.praxis-ai-assistant-shell__attachment--error]=\"attachment.status === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-' + attachment.id\"\n >\n @if (attachment.previewUrl && attachment.kind === 'image') {\n <img\n class=\"praxis-ai-assistant-shell__attachment-preview\"\n [src]=\"attachment.previewUrl\"\n [alt]=\"attachment.name\"\n >\n }\n <span class=\"praxis-ai-assistant-shell__attachment-name\">{{ attachment.name }}</span>\n <span class=\"praxis-ai-assistant-shell__attachment-kind\">{{ attachment.kind }}</span>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.removeAttachment\"\n [attr.aria-label]=\"resolvedLabels.removeAttachment + ': ' + attachment.name\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-remove-' + attachment.id\"\n (click)=\"onRemoveAttachment(attachment)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n }\n </div>\n }\n\n @if (quickReplies.length) {\n <div\n class=\"praxis-ai-assistant-shell__quick-replies\"\n [class.praxis-ai-assistant-shell__quick-replies--inline]=\"shouldUseInlineQuickReplies()\"\n [attr.data-testid]=\"testIdPrefix + '-quick-replies'\"\n [attr.aria-label]=\"resolvedLabels.quickRepliesAria\"\n >\n @for (reply of quickReplies; track trackQuickReply($index, reply)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__quick-reply\"\n [class.praxis-ai-assistant-shell__quick-reply--compact]=\"!isRichQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--guided-action]=\"isGuidedActionQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--contextual-action]=\"isContextualPreviewActionQuickReply(reply)\"\n [ngClass]=\"'praxis-ai-assistant-shell__quick-reply--tone-' + getQuickReplyTone(reply)\"\n [attr.data-testid]=\"testIdPrefix + '-quick-reply-' + (reply.id || reply.kind)\"\n [attr.aria-label]=\"getQuickReplyAriaLabel(reply)\"\n [disabled]=\"busy\"\n (click)=\"onQuickReply(reply)\"\n >\n <span class=\"praxis-ai-assistant-shell__quick-reply-ambient\" aria-hidden=\"true\"></span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-icon-frame\" aria-hidden=\"true\">\n <mat-icon\n class=\"praxis-ai-assistant-shell__quick-reply-icon\"\n >\n {{ getQuickReplyIcon(reply) }}\n </mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-header\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-heading\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-label\">{{ reply.label }}</span>\n @if (getQuickReplyDescription(reply)) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-description\"\n >\n {{ getQuickReplyDescription(reply) }}\n </span>\n }\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-actions\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-badge\">\n {{ getQuickReplyCategoryLabel(reply) }}\n </span>\n @if (getQuickReplyTechnicalDetails(reply)) {\n <mat-icon\n class=\"praxis-ai-assistant-shell__quick-reply-details\"\n [matTooltip]=\"getQuickReplyTechnicalDetails(reply)\"\n [attr.aria-label]=\"resolvedLabels.quickReplyDetails\"\n >\n info\n </mat-icon>\n }\n </span>\n </span>\n @if (getQuickReplyContextChips(reply).length) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-context\"\n >\n @for (chip of getQuickReplyContextChips(reply); track chip) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-context-chip\"\n [attr.aria-label]=\"chip.ariaLabel\"\n >\n <mat-icon aria-hidden=\"true\">{{ chip.icon }}</mat-icon>\n <span>{{ chip.value }}</span>\n </span>\n }\n </span>\n }\n @if (getQuickReplyPresentationItems(reply).length) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-insights\"\n >\n @for (item of getQuickReplyPresentationItems(reply); track item) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-insight\"\n >\n <mat-icon aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-label\">\n {{ item.label }}\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-value\">\n {{ item.value }}\n </span>\n </span>\n </span>\n }\n </span>\n }\n <span class=\"praxis-ai-assistant-shell__quick-reply-cta\">\n {{ getQuickReplyCtaLabel(reply) }}\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n }\n </div>\n }\n @if (shouldShowStatusText()) {\n <p\n class=\"praxis-ai-assistant-shell__status\"\n [attr.data-testid]=\"testIdPrefix + '-status'\"\n >\n {{ statusText }}\n </p>\n }\n @if (shouldShowErrorText()) {\n <p\n class=\"praxis-ai-assistant-shell__error\"\n [attr.data-testid]=\"testIdPrefix + '-error'\"\n >\n {{ errorText }}\n </p>\n }\n </div>\n\n <footer class=\"praxis-ai-assistant-shell__footer\">\n <label class=\"praxis-ai-assistant-shell__label\" for=\"praxis-ai-assistant-shell-prompt\">\n {{ resolvedLabels.prompt }}\n </label>\n <div class=\"praxis-ai-assistant-shell__composer\">\n <textarea\n id=\"praxis-ai-assistant-shell-prompt\"\n class=\"praxis-ai-assistant-shell__prompt\"\n [attr.data-testid]=\"testIdPrefix + '-prompt'\"\n [placeholder]=\"resolvedLabels.promptPlaceholder\"\n [ngModel]=\"currentPrompt\"\n [disabled]=\"busy\"\n (ngModelChange)=\"onPromptInput($event)\"\n (keydown)=\"onPromptKeydown($event)\"\n (paste)=\"onPromptPaste($event)\"\n ></textarea>\n <div class=\"praxis-ai-assistant-shell__composer-actions\">\n @if (showAttachAction) {\n <input\n #attachmentInput\n type=\"file\"\n hidden\n [attr.accept]=\"attachmentAccept || null\"\n [attr.multiple]=\"attachmentMultiple ? '' : null\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-input'\"\n (change)=\"onAttachmentFilesSelected($event)\"\n >\n <button\n mat-stroked-button\n type=\"button\"\n [disabled]=\"busy\"\n (click)=\"onAttachClick(attachmentInput)\"\n [attr.data-testid]=\"testIdPrefix + '-attach'\"\n >\n <mat-icon>attach_file</mat-icon>\n {{ resolvedLabels.attach }}\n </button>\n }\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--primary\"\n [class.praxis-ai-assistant-shell__action--icon-only]=\"getPrimaryAction().iconOnly\"\n [matTooltip]=\"getPrimaryActionTooltip(getPrimaryAction())\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(getPrimaryAction())\"\n [disabled]=\"isShellActionDisabled(getPrimaryAction())\"\n (click)=\"onShellAction(getPrimaryAction())\"\n [attr.data-testid]=\"getPrimaryAction().testId || (submitTestId || (testIdPrefix + '-submit'))\"\n [attr.aria-label]=\"getPrimaryAction().ariaLabel || getPrimaryAction().label\"\n >\n @if (getPrimaryAction().icon) {\n <mat-icon aria-hidden=\"true\">{{ getPrimaryAction().icon }}</mat-icon>\n }\n @if (!getPrimaryAction().iconOnly) {\n <span>{{ getPrimaryAction().label }}</span>\n }\n </button>\n @for (action of getSecondaryActions(); track trackShellAction($index, action)) {\n <button\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--secondary\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(action)\"\n [disabled]=\"isShellActionDisabled(action)\"\n (click)=\"onShellAction(action)\"\n [attr.data-testid]=\"action.testId || (testIdPrefix + '-action-' + action.id)\"\n [attr.aria-label]=\"action.ariaLabel || action.label\"\n >\n @if (action.icon) {\n <mat-icon aria-hidden=\"true\">{{ action.icon }}</mat-icon>\n }\n {{ action.label }}\n </button>\n }\n @if (busy) {\n <mat-spinner diameter=\"20\" [attr.data-testid]=\"testIdPrefix + '-spinner'\"></mat-spinner>\n }\n </div>\n </div>\n </footer>\n\n @if (resizable) {\n @for (direction of resizeHandles; track trackResizeHandle($index, direction)) {\n <span\n class=\"praxis-ai-assistant-shell__resize-handle praxis-ai-assistant-shell__resize-handle--{{ direction }}\"\n [attr.data-testid]=\"direction === 'se' ? testIdPrefix + '-resize-handle' : testIdPrefix + '-resize-handle-' + direction\"\n aria-hidden=\"true\"\n role=\"presentation\"\n (pointerdown)=\"startResize(direction, $event)\"\n ></span>\n }\n }\n</section>\n", styles: [":host{display:block}.praxis-ai-assistant-shell{--praxis-ai-assistant-shell-shadow-color: var(--md-sys-color-shadow);--praxis-ai-assistant-shell-highlight-color: var(--md-sys-color-on-surface);--praxis-ai-assistant-shell-tone-analytics: var(--md-sys-color-primary);--praxis-ai-assistant-shell-tone-resource: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-success: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-warning: var(--md-sys-color-secondary);--praxis-ai-assistant-shell-tone-danger: var(--md-sys-color-error);--praxis-ai-assistant-shell-tone-neutral: var(--md-sys-color-outline);position:fixed;box-sizing:border-box;min-width:360px;min-height:360px;display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface);box-shadow:0 24px 60px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 40%,transparent);z-index:var(--praxis-ai-assistant-shell-z-index, 1200)}.praxis-ai-assistant-shell__header{flex:0 0 auto;display:flex;align-items:flex-start;gap:9px;padding:10px 10px 9px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container)}.praxis-ai-assistant-shell__header{justify-content:flex-start;border-bottom:1px solid;cursor:move;touch-action:none}.praxis-ai-assistant-shell__identity{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border-radius:8px;background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary);box-shadow:0 6px 16px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.praxis-ai-assistant-shell__identity mat-icon{width:18px;height:18px;font-size:18px}.praxis-ai-assistant-shell__title-group{min-width:0;flex:1 1 auto;display:grid;gap:4px}.praxis-ai-assistant-shell__title-row{min-width:0;display:flex;align-items:center;gap:8px}.praxis-ai-assistant-shell__badges{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;min-width:0;flex-wrap:wrap}.praxis-ai-assistant-shell__badge{display:inline-flex;align-items:center;gap:5px;min-height:20px;max-width:120px;padding:2px 7px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);border-radius:8px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-high);font-size:11px;line-height:1.2;overflow-wrap:anywhere}.praxis-ai-assistant-shell__badge--context{color:var(--md-sys-color-on-surface);background:color-mix(in srgb,var(--md-sys-color-primary) 9%,var(--md-sys-color-surface-container-high))}.praxis-ai-assistant-shell__badge--state{border-color:transparent;background:transparent;color:var(--md-sys-color-on-surface-variant);padding-inline:3px}.praxis-ai-assistant-shell__badge--error{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__state-dot{flex:0 0 auto;width:6px;height:6px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__badge--error .praxis-ai-assistant-shell__state-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.praxis-ai-assistant-shell__title-group strong,.praxis-ai-assistant-shell__title-group p{min-width:0;margin:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__title-group strong{flex:1 1 auto;font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__title-group p{color:var(--md-sys-color-on-surface-variant);font-size:11.5px;line-height:1.3}.praxis-ai-assistant-shell__header-actions{flex:0 0 auto;display:flex;align-items:center;gap:2px;margin-top:-3px}.praxis-ai-assistant-shell__header-actions button{display:inline-grid;place-items:center;width:34px;height:34px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1;opacity:.78}.praxis-ai-assistant-shell__header-actions button:hover,.praxis-ai-assistant-shell__header-actions button:focus-visible{opacity:1}.praxis-ai-assistant-shell__header-actions mat-icon{display:block;width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__body{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:10px;padding:12px 12px 10px;overflow:auto;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface))}.praxis-ai-assistant-shell__context,.praxis-ai-assistant-shell__attachments{flex:0 0 auto;display:flex;align-items:center;gap:8px;overflow-x:auto}.praxis-ai-assistant-shell__context-item{flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;max-width:240px;padding:5px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high);font-size:12px;line-height:1.25}.praxis-ai-assistant-shell__context-item mat-icon{width:16px;height:16px;font-size:16px}.praxis-ai-assistant-shell__context-label,.praxis-ai-assistant-shell__context-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__context-label{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__context-value{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-ai-assistant-shell__prompt{box-sizing:border-box;width:100%;min-height:46px;max-height:96px;resize:none;border:0;padding:10px 12px 8px;color:var(--md-sys-color-on-surface);background:transparent;font:inherit;line-height:1.45;outline:none}.praxis-ai-assistant-shell__conversation{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:8px;overflow:auto;padding:2px}.praxis-ai-assistant-shell__message{max-width:86%;align-self:flex-start;padding:9px 11px;border-radius:8px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__message-content{white-space:normal}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5){margin:0}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5)+:where(p,ul,h3,h4,h5){margin-top:8px}.praxis-ai-assistant-shell__message-content ul{padding-left:18px}.praxis-ai-assistant-shell__message-content li+li{margin-top:4px}.praxis-ai-assistant-shell__message-content code{padding:1px 4px;border-radius:4px;background:color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.94em}.praxis-ai-assistant-shell__message-actions{display:flex;align-items:center;gap:4px;flex-wrap:wrap;margin-top:8px}.praxis-ai-assistant-shell__message-action{min-height:28px;padding:0 8px;border-radius:8px;font-size:12px}.praxis-ai-assistant-shell__message-action--icon{width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message-action--icon mat-icon{width:17px;height:17px;font-size:17px}.praxis-ai-assistant-shell__message--assistant{border-bottom-left-radius:2px}.praxis-ai-assistant-shell__message--user{align-self:flex-end;border-bottom-right-radius:2px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.praxis-ai-assistant-shell__message--status{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message--error,.praxis-ai-assistant-shell__error{color:var(--md-sys-color-error)}.praxis-ai-assistant-shell__quick-replies{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,520px),1fr));gap:8px;align-items:stretch;padding-bottom:4px}.praxis-ai-assistant-shell__quick-replies--inline{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.praxis-ai-assistant-shell__attachment{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;max-width:260px;min-height:34px;padding:4px 4px 4px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high)}.praxis-ai-assistant-shell__attachment--error{border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__attachment-preview{flex:0 0 auto;width:28px;height:28px;border-radius:6px;object-fit:cover}.praxis-ai-assistant-shell__attachment-name,.praxis-ai-assistant-shell__attachment-kind{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}.praxis-ai-assistant-shell__attachment-name{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__attachment-kind{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__quick-reply{--praxis-ai-assistant-shell-quick-reply-accent: var(--md-sys-color-primary);--praxis-ai-assistant-shell-quick-reply-background: color-mix( in srgb, var(--praxis-ai-assistant-shell-quick-reply-accent) 7%, var(--md-sys-color-surface-container-high) );--praxis-ai-assistant-shell-quick-reply-foreground: var(--md-sys-color-on-surface);width:100%;max-width:100%;height:auto;min-height:0;position:relative;overflow:hidden;padding:15px 16px;align-items:stretch;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 36%,transparent);border-radius:22px;color:var(--praxis-ai-assistant-shell-quick-reply-foreground);background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent),transparent 46%),radial-gradient(circle at 92% 10%,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent),transparent 32%),var(--praxis-ai-assistant-shell-quick-reply-background);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 22%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 16%,transparent);letter-spacing:normal;white-space:normal;text-align:left;text-transform:none;-webkit-user-select:none;user-select:none;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease,background .16s ease;--mdc-outlined-button-container-height: auto;--mat-outlined-button-horizontal-padding: 0}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 74%,transparent);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 24%,transparent),0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 18%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent);transform:translateY(-1px)}.praxis-ai-assistant-shell__quick-reply--contextual-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 92%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--guided-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 30%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--contextual-action:focus-visible,.praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 62%,transparent);box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent);transform:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-ambient,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-ambient{display:none}.praxis-ai-assistant-shell__quick-reply--contextual-action ::ng-deep .mdc-button__label,.praxis-ai-assistant-shell__quick-reply--guided-action ::ng-deep .mdc-button__label{gap:10px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon-frame,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:8px;box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-copy{gap:6px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-label{font-size:13.5px;font-weight:760;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-description{display:-webkit-box;overflow:hidden;font-size:12px;line-height:1.34;-webkit-box-orient:vertical;-webkit-line-clamp:2}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-badge{border-radius:8px;font-size:10px;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-context-chip{border-radius:8px;padding:4px 7px;font-size:10.5px;font-weight:650}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-cta,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta{font-size:11.5px}.praxis-ai-assistant-shell__quick-reply--compact{justify-self:start;width:fit-content;min-width:min(100%,210px);max-width:min(100%,320px);padding:9px 11px;border-radius:16px;background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),transparent 55%),var(--md-sys-color-surface-container-high);box-shadow:0 8px 18px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 16%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 10%,transparent)}.praxis-ai-assistant-shell__quick-reply.praxis-ai-assistant-shell__quick-reply--compact ::ng-deep .mdc-button__label{align-items:center;gap:10px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:12px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-copy{gap:4px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-header{align-items:center}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-label{font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply{width:auto;min-width:0;max-width:100%;padding:6px 10px;border-radius:999px;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 52%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{display:inline-flex;grid-template-columns:none;align-items:center;gap:6px;width:auto}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{min-height:34px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon-frame{width:18px;height:18px;border:0;border-radius:0;background:transparent;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon{width:16px;height:16px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:16px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-heading,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-header{display:inline-flex;align-items:center;gap:0}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:12.5px;font-weight:650;line-height:1.2;white-space:nowrap}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-actions,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{position:relative;z-index:1;min-width:0;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:flex-start;gap:14px;width:100%;height:auto;line-height:normal}.praxis-ai-assistant-shell__quick-reply-ambient{position:absolute;inset:0;pointer-events:none}.praxis-ai-assistant-shell__quick-reply-ambient:before{content:\"\";position:absolute;inset:0 18px auto;height:1px;border-radius:999px;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 90%,var(--praxis-ai-assistant-shell-highlight-color)),transparent);opacity:.58}.praxis-ai-assistant-shell__quick-reply-ambient:after{content:\"\";position:absolute;top:-34px;right:-44px;width:150px;height:150px;border-radius:999px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 13%,transparent);filter:blur(18px)}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{height:100%;min-height:48px}.praxis-ai-assistant-shell__quick-reply-icon-frame{flex:0 0 auto;width:46px;height:46px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);background:linear-gradient(145deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 24%,transparent),color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 6%,transparent));box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent),0 10px 24px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-reply-icon{width:24px;height:24px;font-size:24px}.praxis-ai-assistant-shell__quick-reply-details{flex:0 0 auto;width:24px;height:24px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 14%,transparent);border-radius:50%;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-outline) 14%,transparent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-copy{min-width:0;display:grid;gap:10px;flex:1 1 auto}.praxis-ai-assistant-shell__quick-reply-header{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.praxis-ai-assistant-shell__quick-reply-heading{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__quick-reply-actions{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:flex-end;gap:7px;max-width:46%}.praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply-description{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:17px;font-weight:760;letter-spacing:.005em;line-height:1.18;text-transform:none}.praxis-ai-assistant-shell__quick-reply-badge{flex:0 0 auto;max-width:100%;padding:4px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 28%,transparent);border-radius:999px;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 86%,var(--praxis-ai-assistant-shell-highlight-color));background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 11%,transparent);font-size:10.5px;font-weight:700;letter-spacing:.02em;line-height:1.1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-description{color:color-mix(in srgb,var(--md-sys-color-on-surface) 80%,transparent);font-size:13px;line-height:1.46}.praxis-ai-assistant-shell__quick-reply-context{display:flex;flex-wrap:wrap;gap:7px;align-items:center}.praxis-ai-assistant-shell__quick-reply-context-chip{min-width:0;display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:5px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent);border-radius:999px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,transparent);font-size:11px;font-weight:650;line-height:1.15}.praxis-ai-assistant-shell__quick-reply-context-chip mat-icon{width:14px;height:14px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:14px}.praxis-ai-assistant-shell__quick-reply-context-chip span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-insights{display:grid;grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:8px;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent);border-radius:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 5%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 26%,transparent))}.praxis-ai-assistant-shell__quick-reply-insight{min-width:0;display:grid;grid-template-columns:20px minmax(0,1fr);gap:8px;align-items:start;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent);border-radius:13px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 86%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 44%,transparent);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__quick-reply-insight mat-icon{width:17px;height:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-insight-copy{min-width:0;display:grid;gap:1px}.praxis-ai-assistant-shell__quick-reply-insight-label{color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 82%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:760;letter-spacing:.045em;line-height:1.2;text-transform:uppercase}.praxis-ai-assistant-shell__quick-reply-insight-value{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-cta{display:inline-flex;align-items:center;justify-self:start;gap:5px;padding:3px 0;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:12px;font-weight:760;letter-spacing:.01em;line-height:1.2}.praxis-ai-assistant-shell__quick-reply-cta mat-icon{width:15px;height:15px;font-size:15px;transition:transform .16s ease}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled) .praxis-ai-assistant-shell__quick-reply-cta mat-icon,.praxis-ai-assistant-shell__quick-reply:focus-visible .praxis-ai-assistant-shell__quick-reply-cta mat-icon{transform:translate(2px)}.praxis-ai-assistant-shell__quick-reply--tone-analytics{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__quick-reply--tone-resource{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__quick-reply--tone-warning{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__quick-reply--tone-success{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__quick-reply--tone-danger{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__quick-reply--tone-neutral{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-neutral)}@media(max-width:640px){.praxis-ai-assistant-shell__quick-reply{padding:13px;border-radius:19px}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{grid-template-columns:minmax(0,1fr);gap:10px}.praxis-ai-assistant-shell__quick-reply-icon-frame{width:38px;height:38px;border-radius:14px}.praxis-ai-assistant-shell__quick-reply-header{display:grid}.praxis-ai-assistant-shell__quick-reply-actions{justify-content:flex-start;max-width:100%}.praxis-ai-assistant-shell__quick-reply-insights{grid-template-columns:minmax(0,1fr)}}.praxis-ai-assistant-shell__status,.praxis-ai-assistant-shell__error{margin:0;font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__footer{flex:0 0 auto;padding:8px 10px 10px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container-low)}.praxis-ai-assistant-shell__composer{display:grid;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-lowest);box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 4%,transparent)}.praxis-ai-assistant-shell__composer:focus-within{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__composer-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 8px 7px;flex-wrap:wrap}.praxis-ai-assistant-shell__action{min-height:36px;border-radius:10px;font-weight:650}.praxis-ai-assistant-shell__action mat-icon{width:18px;height:18px;margin-right:6px;font-size:18px}.praxis-ai-assistant-shell__action--icon-only{width:40px;min-width:40px;height:40px;padding-inline:0;border-radius:50%}.praxis-ai-assistant-shell__action--icon-only mat-icon{margin-right:0}.praxis-ai-assistant-shell__action--secondary{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__action--tone-governance{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-success{color:var(--praxis-ai-assistant-shell-tone-success);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-warning{color:var(--praxis-ai-assistant-shell-tone-warning);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-warning) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-danger{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__resize-handle{position:absolute;z-index:2;border:0;background:transparent;touch-action:none}.praxis-ai-assistant-shell__resize-handle--n,.praxis-ai-assistant-shell__resize-handle--s{left:16px;right:16px;height:10px;cursor:ns-resize}.praxis-ai-assistant-shell__resize-handle--n{top:-5px}.praxis-ai-assistant-shell__resize-handle--s{bottom:-5px}.praxis-ai-assistant-shell__resize-handle--e,.praxis-ai-assistant-shell__resize-handle--w{top:16px;bottom:16px;width:10px;cursor:ew-resize}.praxis-ai-assistant-shell__resize-handle--e{right:-5px}.praxis-ai-assistant-shell__resize-handle--w{left:-5px}.praxis-ai-assistant-shell__resize-handle--ne,.praxis-ai-assistant-shell__resize-handle--nw,.praxis-ai-assistant-shell__resize-handle--se,.praxis-ai-assistant-shell__resize-handle--sw{width:22px;height:22px}.praxis-ai-assistant-shell__resize-handle--ne{top:-5px;right:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--nw{top:-5px;left:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--se{right:-5px;bottom:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--sw{bottom:-5px;left:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--se:after{content:\"\";position:absolute;right:8px;bottom:8px;width:10px;height:10px;border-right:2px solid var(--md-sys-color-outline);border-bottom:2px solid var(--md-sys-color-outline)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7909
7911
|
}
|
|
7910
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
7912
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantShellComponent, decorators: [{
|
|
7911
7913
|
type: Component,
|
|
7912
7914
|
args: [{ selector: 'praxis-ai-assistant-shell', standalone: true, imports: [
|
|
7913
7915
|
CommonModule,
|
|
@@ -7916,7 +7918,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
7916
7918
|
MatIconModule,
|
|
7917
7919
|
MatProgressSpinnerModule,
|
|
7918
7920
|
MatTooltipModule,
|
|
7919
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n #panel\n class=\"praxis-ai-assistant-shell\"\n role=\"dialog\"\n [attr.aria-label]=\"resolvedLabels.title\"\n [attr.aria-busy]=\"busy ? 'true' : null\"\n [style.left.px]=\"currentLayout.left\"\n [style.top.px]=\"currentLayout.top\"\n [style.width.px]=\"currentLayout.width\"\n [style.height.px]=\"currentLayout.height\"\n [attr.data-testid]=\"panelTestId || testIdPrefix\"\n>\n <header\n class=\"praxis-ai-assistant-shell__header\"\n [attr.data-testid]=\"testIdPrefix + '-drag-handle'\"\n [attr.aria-label]=\"resolvedLabels.dragHandleAria\"\n (pointerdown)=\"startDrag($event)\"\n >\n <div class=\"praxis-ai-assistant-shell__identity\" aria-hidden=\"true\">\n <mat-icon>auto_awesome</mat-icon>\n </div>\n <div class=\"praxis-ai-assistant-shell__title-group\">\n <div class=\"praxis-ai-assistant-shell__title-row\">\n <strong>{{ resolvedLabels.title }}</strong>\n <div class=\"praxis-ai-assistant-shell__badges\" aria-hidden=\"true\">\n <span class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--context\">\n {{ getModeLabel() }}\n </span>\n <span\n class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--state\"\n [class.praxis-ai-assistant-shell__badge--error]=\"state === 'error'\"\n >\n <span class=\"praxis-ai-assistant-shell__state-dot\" aria-hidden=\"true\"></span>\n {{ getStateLabel() }}\n </span>\n </div>\n </div>\n <p *ngIf=\"resolvedLabels.subtitle\">{{ resolvedLabels.subtitle }}</p>\n </div>\n <div class=\"praxis-ai-assistant-shell__header-actions\">\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"resolvedLabels.close\"\n [attr.aria-label]=\"resolvedLabels.close\"\n (pointerdown)=\"$event.stopPropagation()\"\n (click)=\"close.emit()\"\n [attr.data-testid]=\"testIdPrefix + '-close'\"\n >\n <mat-icon>{{ getCloseIcon() }}</mat-icon>\n </button>\n </div>\n </header>\n\n <div class=\"praxis-ai-assistant-shell__body\">\n <div\n *ngIf=\"contextItems.length\"\n class=\"praxis-ai-assistant-shell__context\"\n [attr.aria-label]=\"resolvedLabels.contextAria\"\n [attr.data-testid]=\"testIdPrefix + '-context'\"\n >\n <span\n *ngFor=\"let item of contextItems; trackBy: trackContextItem\"\n class=\"praxis-ai-assistant-shell__context-item\"\n [attr.data-testid]=\"testIdPrefix + '-context-' + item.id\"\n >\n <mat-icon *ngIf=\"item.icon\" aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n <span class=\"praxis-ai-assistant-shell__context-label\">{{ item.label }}</span>\n <span *ngIf=\"item.value\" class=\"praxis-ai-assistant-shell__context-value\">{{ item.value }}</span>\n </span>\n </div>\n\n <div\n #conversation\n class=\"praxis-ai-assistant-shell__conversation\"\n [attr.data-testid]=\"testIdPrefix + '-conversation'\"\n [attr.aria-label]=\"resolvedLabels.conversationAria\"\n >\n <article\n *ngIf=\"!messages.length\"\n class=\"praxis-ai-assistant-shell__message praxis-ai-assistant-shell__message--assistant\"\n [attr.data-testid]=\"testIdPrefix + '-message-assistant-empty'\"\n >\n {{ resolvedLabels.emptyConversation }}\n </article>\n <article\n *ngFor=\"let message of messages; trackBy: trackMessage\"\n class=\"praxis-ai-assistant-shell__message\"\n [class.praxis-ai-assistant-shell__message--user]=\"message.role === 'user'\"\n [class.praxis-ai-assistant-shell__message--assistant]=\"message.role === 'assistant'\"\n [class.praxis-ai-assistant-shell__message--status]=\"message.role === 'status'\"\n [class.praxis-ai-assistant-shell__message--error]=\"message.role === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-message-' + message.role\"\n >\n <div\n class=\"praxis-ai-assistant-shell__message-content\"\n [innerHTML]=\"renderMessageText(message.text)\"\n ></div>\n <div\n *ngIf=\"message.actions?.length || message.editable || message.resendable\"\n class=\"praxis-ai-assistant-shell__message-actions\"\n >\n <button\n *ngIf=\"message.editable\"\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.editMessage\"\n [attr.aria-label]=\"resolvedLabels.editMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-edit-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'edit', label: resolvedLabels.editMessage, kind: 'edit' })\"\n >\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n <button\n *ngIf=\"message.resendable\"\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.resendMessage\"\n [attr.aria-label]=\"resolvedLabels.resendMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-resend-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'resend', label: resolvedLabels.resendMessage, kind: 'resend' })\"\n >\n <mat-icon aria-hidden=\"true\">replay</mat-icon>\n </button>\n <ng-container *ngFor=\"let action of message.actions || []; trackBy: trackMessageAction\">\n <button\n *ngIf=\"isMessageActionIconOnly(action); else textualMessageAction\"\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy || action.disabled\"\n [matTooltip]=\"getMessageActionLabel(action)\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n <mat-icon aria-hidden=\"true\">{{ getMessageActionIcon(action) }}</mat-icon>\n </button>\n <ng-template #textualMessageAction>\n <button\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action\"\n [disabled]=\"busy || action.disabled\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n {{ action.label }}\n </button>\n </ng-template>\n </ng-container>\n </div>\n </article>\n </div>\n\n <div\n *ngIf=\"attachments.length\"\n class=\"praxis-ai-assistant-shell__attachments\"\n [attr.aria-label]=\"resolvedLabels.attachmentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-attachments'\"\n >\n <div\n *ngFor=\"let attachment of attachments; trackBy: trackAttachment\"\n class=\"praxis-ai-assistant-shell__attachment\"\n [class.praxis-ai-assistant-shell__attachment--error]=\"attachment.status === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-' + attachment.id\"\n >\n <img\n *ngIf=\"attachment.previewUrl && attachment.kind === 'image'\"\n class=\"praxis-ai-assistant-shell__attachment-preview\"\n [src]=\"attachment.previewUrl\"\n [alt]=\"attachment.name\"\n >\n <span class=\"praxis-ai-assistant-shell__attachment-name\">{{ attachment.name }}</span>\n <span class=\"praxis-ai-assistant-shell__attachment-kind\">{{ attachment.kind }}</span>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.removeAttachment\"\n [attr.aria-label]=\"resolvedLabels.removeAttachment + ': ' + attachment.name\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-remove-' + attachment.id\"\n (click)=\"onRemoveAttachment(attachment)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n\n <div\n *ngIf=\"quickReplies.length\"\n class=\"praxis-ai-assistant-shell__quick-replies\"\n [class.praxis-ai-assistant-shell__quick-replies--inline]=\"shouldUseInlineQuickReplies()\"\n [attr.data-testid]=\"testIdPrefix + '-quick-replies'\"\n [attr.aria-label]=\"resolvedLabels.quickRepliesAria\"\n >\n <button\n *ngFor=\"let reply of quickReplies; trackBy: trackQuickReply\"\n mat-stroked-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__quick-reply\"\n [class.praxis-ai-assistant-shell__quick-reply--compact]=\"!isRichQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--guided-action]=\"isGuidedActionQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--contextual-action]=\"isContextualPreviewActionQuickReply(reply)\"\n [ngClass]=\"'praxis-ai-assistant-shell__quick-reply--tone-' + getQuickReplyTone(reply)\"\n [attr.data-testid]=\"testIdPrefix + '-quick-reply-' + (reply.id || reply.kind)\"\n [attr.aria-label]=\"getQuickReplyAriaLabel(reply)\"\n [disabled]=\"busy\"\n (click)=\"onQuickReply(reply)\"\n >\n <span class=\"praxis-ai-assistant-shell__quick-reply-ambient\" aria-hidden=\"true\"></span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-icon-frame\" aria-hidden=\"true\">\n <mat-icon\n class=\"praxis-ai-assistant-shell__quick-reply-icon\"\n >\n {{ getQuickReplyIcon(reply) }}\n </mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-header\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-heading\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-label\">{{ reply.label }}</span>\n <span\n *ngIf=\"getQuickReplyDescription(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-description\"\n >\n {{ getQuickReplyDescription(reply) }}\n </span>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-actions\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-badge\">\n {{ getQuickReplyCategoryLabel(reply) }}\n </span>\n <mat-icon\n *ngIf=\"getQuickReplyTechnicalDetails(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-details\"\n [matTooltip]=\"getQuickReplyTechnicalDetails(reply)\"\n [attr.aria-label]=\"resolvedLabels.quickReplyDetails\"\n >\n info\n </mat-icon>\n </span>\n </span>\n <span\n *ngIf=\"getQuickReplyContextChips(reply).length\"\n class=\"praxis-ai-assistant-shell__quick-reply-context\"\n >\n <span\n *ngFor=\"let chip of getQuickReplyContextChips(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-context-chip\"\n [attr.aria-label]=\"chip.ariaLabel\"\n >\n <mat-icon aria-hidden=\"true\">{{ chip.icon }}</mat-icon>\n <span>{{ chip.value }}</span>\n </span>\n </span>\n <span\n *ngIf=\"getQuickReplyPresentationItems(reply).length\"\n class=\"praxis-ai-assistant-shell__quick-reply-insights\"\n >\n <span\n *ngFor=\"let item of getQuickReplyPresentationItems(reply)\"\n class=\"praxis-ai-assistant-shell__quick-reply-insight\"\n >\n <mat-icon aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-label\">\n {{ item.label }}\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-value\">\n {{ item.value }}\n </span>\n </span>\n </span>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-cta\">\n {{ getQuickReplyCtaLabel(reply) }}\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n </div>\n <p\n *ngIf=\"shouldShowStatusText()\"\n class=\"praxis-ai-assistant-shell__status\"\n [attr.data-testid]=\"testIdPrefix + '-status'\"\n >\n {{ statusText }}\n </p>\n <p\n *ngIf=\"shouldShowErrorText()\"\n class=\"praxis-ai-assistant-shell__error\"\n [attr.data-testid]=\"testIdPrefix + '-error'\"\n >\n {{ errorText }}\n </p>\n </div>\n\n <footer class=\"praxis-ai-assistant-shell__footer\">\n <label class=\"praxis-ai-assistant-shell__label\" for=\"praxis-ai-assistant-shell-prompt\">\n {{ resolvedLabels.prompt }}\n </label>\n <div class=\"praxis-ai-assistant-shell__composer\">\n <textarea\n id=\"praxis-ai-assistant-shell-prompt\"\n class=\"praxis-ai-assistant-shell__prompt\"\n [attr.data-testid]=\"testIdPrefix + '-prompt'\"\n [placeholder]=\"resolvedLabels.promptPlaceholder\"\n [ngModel]=\"currentPrompt\"\n [disabled]=\"busy\"\n (ngModelChange)=\"onPromptInput($event)\"\n (keydown)=\"onPromptKeydown($event)\"\n (paste)=\"onPromptPaste($event)\"\n ></textarea>\n <div class=\"praxis-ai-assistant-shell__composer-actions\">\n <ng-container *ngIf=\"showAttachAction\">\n <input\n #attachmentInput\n type=\"file\"\n hidden\n [attr.accept]=\"attachmentAccept || null\"\n [attr.multiple]=\"attachmentMultiple ? '' : null\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-input'\"\n (change)=\"onAttachmentFilesSelected($event)\"\n >\n <button\n mat-stroked-button\n type=\"button\"\n [disabled]=\"busy\"\n (click)=\"onAttachClick(attachmentInput)\"\n [attr.data-testid]=\"testIdPrefix + '-attach'\"\n >\n <mat-icon>attach_file</mat-icon>\n {{ resolvedLabels.attach }}\n </button>\n </ng-container>\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--primary\"\n [class.praxis-ai-assistant-shell__action--icon-only]=\"getPrimaryAction().iconOnly\"\n [matTooltip]=\"getPrimaryActionTooltip(getPrimaryAction())\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(getPrimaryAction())\"\n [disabled]=\"isShellActionDisabled(getPrimaryAction())\"\n (click)=\"onShellAction(getPrimaryAction())\"\n [attr.data-testid]=\"getPrimaryAction().testId || (submitTestId || (testIdPrefix + '-submit'))\"\n [attr.aria-label]=\"getPrimaryAction().ariaLabel || getPrimaryAction().label\"\n >\n <mat-icon *ngIf=\"getPrimaryAction().icon\" aria-hidden=\"true\">{{ getPrimaryAction().icon }}</mat-icon>\n <span *ngIf=\"!getPrimaryAction().iconOnly\">{{ getPrimaryAction().label }}</span>\n </button>\n <button\n *ngFor=\"let action of getSecondaryActions(); trackBy: trackShellAction\"\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--secondary\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(action)\"\n [disabled]=\"isShellActionDisabled(action)\"\n (click)=\"onShellAction(action)\"\n [attr.data-testid]=\"action.testId || (testIdPrefix + '-action-' + action.id)\"\n [attr.aria-label]=\"action.ariaLabel || action.label\"\n >\n <mat-icon *ngIf=\"action.icon\" aria-hidden=\"true\">{{ action.icon }}</mat-icon>\n {{ action.label }}\n </button>\n <mat-spinner *ngIf=\"busy\" diameter=\"20\" [attr.data-testid]=\"testIdPrefix + '-spinner'\"></mat-spinner>\n </div>\n </div>\n </footer>\n\n <ng-container *ngIf=\"resizable\">\n <span\n *ngFor=\"let direction of resizeHandles; trackBy: trackResizeHandle\"\n class=\"praxis-ai-assistant-shell__resize-handle praxis-ai-assistant-shell__resize-handle--{{ direction }}\"\n [attr.data-testid]=\"direction === 'se' ? testIdPrefix + '-resize-handle' : testIdPrefix + '-resize-handle-' + direction\"\n aria-hidden=\"true\"\n role=\"presentation\"\n (pointerdown)=\"startResize(direction, $event)\"\n ></span>\n </ng-container>\n</section>\n", styles: [":host{display:block}.praxis-ai-assistant-shell{--praxis-ai-assistant-shell-shadow-color: var(--md-sys-color-shadow);--praxis-ai-assistant-shell-highlight-color: var(--md-sys-color-on-surface);--praxis-ai-assistant-shell-tone-analytics: var(--md-sys-color-primary);--praxis-ai-assistant-shell-tone-resource: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-success: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-warning: var(--md-sys-color-secondary);--praxis-ai-assistant-shell-tone-danger: var(--md-sys-color-error);--praxis-ai-assistant-shell-tone-neutral: var(--md-sys-color-outline);position:fixed;box-sizing:border-box;min-width:360px;min-height:360px;display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface);box-shadow:0 24px 60px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 40%,transparent);z-index:var(--praxis-ai-assistant-shell-z-index, 1200)}.praxis-ai-assistant-shell__header{flex:0 0 auto;display:flex;align-items:flex-start;gap:9px;padding:10px 10px 9px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container)}.praxis-ai-assistant-shell__header{justify-content:flex-start;border-bottom:1px solid;cursor:move;touch-action:none}.praxis-ai-assistant-shell__identity{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border-radius:8px;background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary);box-shadow:0 6px 16px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.praxis-ai-assistant-shell__identity mat-icon{width:18px;height:18px;font-size:18px}.praxis-ai-assistant-shell__title-group{min-width:0;flex:1 1 auto;display:grid;gap:4px}.praxis-ai-assistant-shell__title-row{min-width:0;display:flex;align-items:center;gap:8px}.praxis-ai-assistant-shell__badges{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;min-width:0;flex-wrap:wrap}.praxis-ai-assistant-shell__badge{display:inline-flex;align-items:center;gap:5px;min-height:20px;max-width:120px;padding:2px 7px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);border-radius:8px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-high);font-size:11px;line-height:1.2;overflow-wrap:anywhere}.praxis-ai-assistant-shell__badge--context{color:var(--md-sys-color-on-surface);background:color-mix(in srgb,var(--md-sys-color-primary) 9%,var(--md-sys-color-surface-container-high))}.praxis-ai-assistant-shell__badge--state{border-color:transparent;background:transparent;color:var(--md-sys-color-on-surface-variant);padding-inline:3px}.praxis-ai-assistant-shell__badge--error{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__state-dot{flex:0 0 auto;width:6px;height:6px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__badge--error .praxis-ai-assistant-shell__state-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.praxis-ai-assistant-shell__title-group strong,.praxis-ai-assistant-shell__title-group p{min-width:0;margin:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__title-group strong{flex:1 1 auto;font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__title-group p{color:var(--md-sys-color-on-surface-variant);font-size:11.5px;line-height:1.3}.praxis-ai-assistant-shell__header-actions{flex:0 0 auto;display:flex;align-items:center;gap:2px;margin-top:-3px}.praxis-ai-assistant-shell__header-actions button{display:inline-grid;place-items:center;width:34px;height:34px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1;opacity:.78}.praxis-ai-assistant-shell__header-actions button:hover,.praxis-ai-assistant-shell__header-actions button:focus-visible{opacity:1}.praxis-ai-assistant-shell__header-actions mat-icon{display:block;width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__body{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:10px;padding:12px 12px 10px;overflow:auto;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface))}.praxis-ai-assistant-shell__context,.praxis-ai-assistant-shell__attachments{flex:0 0 auto;display:flex;align-items:center;gap:8px;overflow-x:auto}.praxis-ai-assistant-shell__context-item{flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;max-width:240px;padding:5px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high);font-size:12px;line-height:1.25}.praxis-ai-assistant-shell__context-item mat-icon{width:16px;height:16px;font-size:16px}.praxis-ai-assistant-shell__context-label,.praxis-ai-assistant-shell__context-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__context-label{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__context-value{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-ai-assistant-shell__prompt{box-sizing:border-box;width:100%;min-height:46px;max-height:96px;resize:none;border:0;padding:10px 12px 8px;color:var(--md-sys-color-on-surface);background:transparent;font:inherit;line-height:1.45;outline:none}.praxis-ai-assistant-shell__conversation{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:8px;overflow:auto;padding:2px}.praxis-ai-assistant-shell__message{max-width:86%;align-self:flex-start;padding:9px 11px;border-radius:8px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__message-content{white-space:normal}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5){margin:0}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5)+:where(p,ul,h3,h4,h5){margin-top:8px}.praxis-ai-assistant-shell__message-content ul{padding-left:18px}.praxis-ai-assistant-shell__message-content li+li{margin-top:4px}.praxis-ai-assistant-shell__message-content code{padding:1px 4px;border-radius:4px;background:color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.94em}.praxis-ai-assistant-shell__message-actions{display:flex;align-items:center;gap:4px;flex-wrap:wrap;margin-top:8px}.praxis-ai-assistant-shell__message-action{min-height:28px;padding:0 8px;border-radius:8px;font-size:12px}.praxis-ai-assistant-shell__message-action--icon{width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message-action--icon mat-icon{width:17px;height:17px;font-size:17px}.praxis-ai-assistant-shell__message--assistant{border-bottom-left-radius:2px}.praxis-ai-assistant-shell__message--user{align-self:flex-end;border-bottom-right-radius:2px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.praxis-ai-assistant-shell__message--status{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message--error,.praxis-ai-assistant-shell__error{color:var(--md-sys-color-error)}.praxis-ai-assistant-shell__quick-replies{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,520px),1fr));gap:8px;align-items:stretch;padding-bottom:4px}.praxis-ai-assistant-shell__quick-replies--inline{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.praxis-ai-assistant-shell__attachment{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;max-width:260px;min-height:34px;padding:4px 4px 4px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high)}.praxis-ai-assistant-shell__attachment--error{border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__attachment-preview{flex:0 0 auto;width:28px;height:28px;border-radius:6px;object-fit:cover}.praxis-ai-assistant-shell__attachment-name,.praxis-ai-assistant-shell__attachment-kind{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}.praxis-ai-assistant-shell__attachment-name{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__attachment-kind{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__quick-reply{--praxis-ai-assistant-shell-quick-reply-accent: var(--md-sys-color-primary);--praxis-ai-assistant-shell-quick-reply-background: color-mix( in srgb, var(--praxis-ai-assistant-shell-quick-reply-accent) 7%, var(--md-sys-color-surface-container-high) );--praxis-ai-assistant-shell-quick-reply-foreground: var(--md-sys-color-on-surface);width:100%;max-width:100%;height:auto;min-height:0;position:relative;overflow:hidden;padding:15px 16px;align-items:stretch;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 36%,transparent);border-radius:22px;color:var(--praxis-ai-assistant-shell-quick-reply-foreground);background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent),transparent 46%),radial-gradient(circle at 92% 10%,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent),transparent 32%),var(--praxis-ai-assistant-shell-quick-reply-background);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 22%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 16%,transparent);letter-spacing:normal;white-space:normal;text-align:left;text-transform:none;-webkit-user-select:none;user-select:none;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease,background .16s ease;--mdc-outlined-button-container-height: auto;--mat-outlined-button-horizontal-padding: 0}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 74%,transparent);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 24%,transparent),0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 18%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent);transform:translateY(-1px)}.praxis-ai-assistant-shell__quick-reply--contextual-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 92%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--guided-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 30%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--contextual-action:focus-visible,.praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 62%,transparent);box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent);transform:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-ambient,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-ambient{display:none}.praxis-ai-assistant-shell__quick-reply--contextual-action ::ng-deep .mdc-button__label,.praxis-ai-assistant-shell__quick-reply--guided-action ::ng-deep .mdc-button__label{gap:10px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon-frame,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:8px;box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-copy{gap:6px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-label{font-size:13.5px;font-weight:760;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-description{display:-webkit-box;overflow:hidden;font-size:12px;line-height:1.34;-webkit-box-orient:vertical;-webkit-line-clamp:2}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-badge{border-radius:8px;font-size:10px;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-context-chip{border-radius:8px;padding:4px 7px;font-size:10.5px;font-weight:650}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-cta,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta{font-size:11.5px}.praxis-ai-assistant-shell__quick-reply--compact{justify-self:start;width:fit-content;min-width:min(100%,210px);max-width:min(100%,320px);padding:9px 11px;border-radius:16px;background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),transparent 55%),var(--md-sys-color-surface-container-high);box-shadow:0 8px 18px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 16%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 10%,transparent)}.praxis-ai-assistant-shell__quick-reply.praxis-ai-assistant-shell__quick-reply--compact ::ng-deep .mdc-button__label{align-items:center;gap:10px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:12px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-copy{gap:4px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-header{align-items:center}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-label{font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply{width:auto;min-width:0;max-width:100%;padding:6px 10px;border-radius:999px;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 52%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{display:inline-flex;grid-template-columns:none;align-items:center;gap:6px;width:auto}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{min-height:34px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon-frame{width:18px;height:18px;border:0;border-radius:0;background:transparent;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon{width:16px;height:16px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:16px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-heading,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-header{display:inline-flex;align-items:center;gap:0}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:12.5px;font-weight:650;line-height:1.2;white-space:nowrap}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-actions,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{position:relative;z-index:1;min-width:0;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:flex-start;gap:14px;width:100%;height:auto;line-height:normal}.praxis-ai-assistant-shell__quick-reply-ambient{position:absolute;inset:0;pointer-events:none}.praxis-ai-assistant-shell__quick-reply-ambient:before{content:\"\";position:absolute;inset:0 18px auto;height:1px;border-radius:999px;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 90%,var(--praxis-ai-assistant-shell-highlight-color)),transparent);opacity:.58}.praxis-ai-assistant-shell__quick-reply-ambient:after{content:\"\";position:absolute;top:-34px;right:-44px;width:150px;height:150px;border-radius:999px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 13%,transparent);filter:blur(18px)}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{height:100%;min-height:48px}.praxis-ai-assistant-shell__quick-reply-icon-frame{flex:0 0 auto;width:46px;height:46px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);background:linear-gradient(145deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 24%,transparent),color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 6%,transparent));box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent),0 10px 24px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-reply-icon{width:24px;height:24px;font-size:24px}.praxis-ai-assistant-shell__quick-reply-details{flex:0 0 auto;width:24px;height:24px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 14%,transparent);border-radius:50%;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-outline) 14%,transparent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-copy{min-width:0;display:grid;gap:10px;flex:1 1 auto}.praxis-ai-assistant-shell__quick-reply-header{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.praxis-ai-assistant-shell__quick-reply-heading{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__quick-reply-actions{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:flex-end;gap:7px;max-width:46%}.praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply-description{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:17px;font-weight:760;letter-spacing:.005em;line-height:1.18;text-transform:none}.praxis-ai-assistant-shell__quick-reply-badge{flex:0 0 auto;max-width:100%;padding:4px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 28%,transparent);border-radius:999px;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 86%,var(--praxis-ai-assistant-shell-highlight-color));background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 11%,transparent);font-size:10.5px;font-weight:700;letter-spacing:.02em;line-height:1.1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-description{color:color-mix(in srgb,var(--md-sys-color-on-surface) 80%,transparent);font-size:13px;line-height:1.46}.praxis-ai-assistant-shell__quick-reply-context{display:flex;flex-wrap:wrap;gap:7px;align-items:center}.praxis-ai-assistant-shell__quick-reply-context-chip{min-width:0;display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:5px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent);border-radius:999px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,transparent);font-size:11px;font-weight:650;line-height:1.15}.praxis-ai-assistant-shell__quick-reply-context-chip mat-icon{width:14px;height:14px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:14px}.praxis-ai-assistant-shell__quick-reply-context-chip span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-insights{display:grid;grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:8px;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent);border-radius:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 5%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 26%,transparent))}.praxis-ai-assistant-shell__quick-reply-insight{min-width:0;display:grid;grid-template-columns:20px minmax(0,1fr);gap:8px;align-items:start;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent);border-radius:13px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 86%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 44%,transparent);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__quick-reply-insight mat-icon{width:17px;height:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-insight-copy{min-width:0;display:grid;gap:1px}.praxis-ai-assistant-shell__quick-reply-insight-label{color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 82%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:760;letter-spacing:.045em;line-height:1.2;text-transform:uppercase}.praxis-ai-assistant-shell__quick-reply-insight-value{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-cta{display:inline-flex;align-items:center;justify-self:start;gap:5px;padding:3px 0;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:12px;font-weight:760;letter-spacing:.01em;line-height:1.2}.praxis-ai-assistant-shell__quick-reply-cta mat-icon{width:15px;height:15px;font-size:15px;transition:transform .16s ease}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled) .praxis-ai-assistant-shell__quick-reply-cta mat-icon,.praxis-ai-assistant-shell__quick-reply:focus-visible .praxis-ai-assistant-shell__quick-reply-cta mat-icon{transform:translate(2px)}.praxis-ai-assistant-shell__quick-reply--tone-analytics{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__quick-reply--tone-resource{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__quick-reply--tone-warning{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__quick-reply--tone-success{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__quick-reply--tone-danger{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__quick-reply--tone-neutral{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-neutral)}@media(max-width:640px){.praxis-ai-assistant-shell__quick-reply{padding:13px;border-radius:19px}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{grid-template-columns:minmax(0,1fr);gap:10px}.praxis-ai-assistant-shell__quick-reply-icon-frame{width:38px;height:38px;border-radius:14px}.praxis-ai-assistant-shell__quick-reply-header{display:grid}.praxis-ai-assistant-shell__quick-reply-actions{justify-content:flex-start;max-width:100%}.praxis-ai-assistant-shell__quick-reply-insights{grid-template-columns:minmax(0,1fr)}}.praxis-ai-assistant-shell__status,.praxis-ai-assistant-shell__error{margin:0;font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__footer{flex:0 0 auto;padding:8px 10px 10px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container-low)}.praxis-ai-assistant-shell__composer{display:grid;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-lowest);box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 4%,transparent)}.praxis-ai-assistant-shell__composer:focus-within{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__composer-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 8px 7px;flex-wrap:wrap}.praxis-ai-assistant-shell__action{min-height:36px;border-radius:10px;font-weight:650}.praxis-ai-assistant-shell__action mat-icon{width:18px;height:18px;margin-right:6px;font-size:18px}.praxis-ai-assistant-shell__action--icon-only{width:40px;min-width:40px;height:40px;padding-inline:0;border-radius:50%}.praxis-ai-assistant-shell__action--icon-only mat-icon{margin-right:0}.praxis-ai-assistant-shell__action--secondary{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__action--tone-governance{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-success{color:var(--praxis-ai-assistant-shell-tone-success);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-warning{color:var(--praxis-ai-assistant-shell-tone-warning);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-warning) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-danger{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__resize-handle{position:absolute;z-index:2;border:0;background:transparent;touch-action:none}.praxis-ai-assistant-shell__resize-handle--n,.praxis-ai-assistant-shell__resize-handle--s{left:16px;right:16px;height:10px;cursor:ns-resize}.praxis-ai-assistant-shell__resize-handle--n{top:-5px}.praxis-ai-assistant-shell__resize-handle--s{bottom:-5px}.praxis-ai-assistant-shell__resize-handle--e,.praxis-ai-assistant-shell__resize-handle--w{top:16px;bottom:16px;width:10px;cursor:ew-resize}.praxis-ai-assistant-shell__resize-handle--e{right:-5px}.praxis-ai-assistant-shell__resize-handle--w{left:-5px}.praxis-ai-assistant-shell__resize-handle--ne,.praxis-ai-assistant-shell__resize-handle--nw,.praxis-ai-assistant-shell__resize-handle--se,.praxis-ai-assistant-shell__resize-handle--sw{width:22px;height:22px}.praxis-ai-assistant-shell__resize-handle--ne{top:-5px;right:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--nw{top:-5px;left:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--se{right:-5px;bottom:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--sw{bottom:-5px;left:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--se:after{content:\"\";position:absolute;right:8px;bottom:8px;width:10px;height:10px;border-right:2px solid var(--md-sys-color-outline);border-bottom:2px solid var(--md-sys-color-outline)}\n"] }]
|
|
7921
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n #panel\n class=\"praxis-ai-assistant-shell\"\n role=\"dialog\"\n [attr.aria-label]=\"resolvedLabels.title\"\n [attr.aria-busy]=\"busy ? 'true' : null\"\n [style.left.px]=\"currentLayout.left\"\n [style.top.px]=\"currentLayout.top\"\n [style.width.px]=\"currentLayout.width\"\n [style.height.px]=\"currentLayout.height\"\n [attr.data-testid]=\"panelTestId || testIdPrefix\"\n >\n <header\n class=\"praxis-ai-assistant-shell__header\"\n [attr.data-testid]=\"testIdPrefix + '-drag-handle'\"\n [attr.aria-label]=\"resolvedLabels.dragHandleAria\"\n (pointerdown)=\"startDrag($event)\"\n >\n <div class=\"praxis-ai-assistant-shell__identity\" aria-hidden=\"true\">\n <mat-icon>auto_awesome</mat-icon>\n </div>\n <div class=\"praxis-ai-assistant-shell__title-group\">\n <div class=\"praxis-ai-assistant-shell__title-row\">\n <strong>{{ resolvedLabels.title }}</strong>\n <div class=\"praxis-ai-assistant-shell__badges\" aria-hidden=\"true\">\n <span class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--context\">\n {{ getModeLabel() }}\n </span>\n <span\n class=\"praxis-ai-assistant-shell__badge praxis-ai-assistant-shell__badge--state\"\n [class.praxis-ai-assistant-shell__badge--error]=\"state === 'error'\"\n >\n <span class=\"praxis-ai-assistant-shell__state-dot\" aria-hidden=\"true\"></span>\n {{ getStateLabel() }}\n </span>\n </div>\n </div>\n @if (resolvedLabels.subtitle) {\n <p>{{ resolvedLabels.subtitle }}</p>\n }\n </div>\n <div class=\"praxis-ai-assistant-shell__header-actions\">\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"resolvedLabels.close\"\n [attr.aria-label]=\"resolvedLabels.close\"\n (pointerdown)=\"$event.stopPropagation()\"\n (click)=\"close.emit()\"\n [attr.data-testid]=\"testIdPrefix + '-close'\"\n >\n <mat-icon>{{ getCloseIcon() }}</mat-icon>\n </button>\n </div>\n </header>\n\n <div class=\"praxis-ai-assistant-shell__body\">\n @if (contextItems.length) {\n <div\n class=\"praxis-ai-assistant-shell__context\"\n [attr.aria-label]=\"resolvedLabels.contextAria\"\n [attr.data-testid]=\"testIdPrefix + '-context'\"\n >\n @for (item of contextItems; track trackContextItem($index, item)) {\n <span\n class=\"praxis-ai-assistant-shell__context-item\"\n [attr.data-testid]=\"testIdPrefix + '-context-' + item.id\"\n >\n @if (item.icon) {\n <mat-icon aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n }\n <span class=\"praxis-ai-assistant-shell__context-label\">{{ item.label }}</span>\n @if (item.value) {\n <span class=\"praxis-ai-assistant-shell__context-value\">{{ item.value }}</span>\n }\n </span>\n }\n </div>\n }\n\n <div\n #conversation\n class=\"praxis-ai-assistant-shell__conversation\"\n [attr.data-testid]=\"testIdPrefix + '-conversation'\"\n [attr.aria-label]=\"resolvedLabels.conversationAria\"\n >\n @if (!messages.length) {\n <article\n class=\"praxis-ai-assistant-shell__message praxis-ai-assistant-shell__message--assistant\"\n [attr.data-testid]=\"testIdPrefix + '-message-assistant-empty'\"\n >\n {{ resolvedLabels.emptyConversation }}\n </article>\n }\n @for (message of messages; track trackMessage($index, message)) {\n <article\n class=\"praxis-ai-assistant-shell__message\"\n [class.praxis-ai-assistant-shell__message--user]=\"message.role === 'user'\"\n [class.praxis-ai-assistant-shell__message--assistant]=\"message.role === 'assistant'\"\n [class.praxis-ai-assistant-shell__message--status]=\"message.role === 'status'\"\n [class.praxis-ai-assistant-shell__message--error]=\"message.role === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-message-' + message.role\"\n >\n <div\n class=\"praxis-ai-assistant-shell__message-content\"\n [innerHTML]=\"renderMessageText(message.text)\"\n ></div>\n @if (message.actions?.length || message.editable || message.resendable) {\n <div\n class=\"praxis-ai-assistant-shell__message-actions\"\n >\n @if (message.editable) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.editMessage\"\n [attr.aria-label]=\"resolvedLabels.editMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-edit-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'edit', label: resolvedLabels.editMessage, kind: 'edit' })\"\n >\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n }\n @if (message.resendable) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.resendMessage\"\n [attr.aria-label]=\"resolvedLabels.resendMessage\"\n [attr.data-testid]=\"testIdPrefix + '-message-resend-' + message.id\"\n (click)=\"onMessageAction(message, { id: 'resend', label: resolvedLabels.resendMessage, kind: 'resend' })\"\n >\n <mat-icon aria-hidden=\"true\">replay</mat-icon>\n </button>\n }\n @for (action of message.actions || []; track trackMessageAction($index, action)) {\n @if (isMessageActionIconOnly(action)) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action praxis-ai-assistant-shell__message-action--icon\"\n [disabled]=\"busy || action.disabled\"\n [matTooltip]=\"getMessageActionLabel(action)\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n <mat-icon aria-hidden=\"true\">{{ getMessageActionIcon(action) }}</mat-icon>\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-action\"\n [disabled]=\"busy || action.disabled\"\n [attr.aria-label]=\"getMessageActionLabel(action)\"\n [attr.data-testid]=\"testIdPrefix + '-message-action-' + message.id + '-' + action.id\"\n (click)=\"onMessageAction(message, action)\"\n >\n {{ action.label }}\n </button>\n }\n }\n </div>\n }\n </article>\n }\n </div>\n\n @if (attachments.length) {\n <div\n class=\"praxis-ai-assistant-shell__attachments\"\n [attr.aria-label]=\"resolvedLabels.attachmentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-attachments'\"\n >\n @for (attachment of attachments; track trackAttachment($index, attachment)) {\n <div\n class=\"praxis-ai-assistant-shell__attachment\"\n [class.praxis-ai-assistant-shell__attachment--error]=\"attachment.status === 'error'\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-' + attachment.id\"\n >\n @if (attachment.previewUrl && attachment.kind === 'image') {\n <img\n class=\"praxis-ai-assistant-shell__attachment-preview\"\n [src]=\"attachment.previewUrl\"\n [alt]=\"attachment.name\"\n >\n }\n <span class=\"praxis-ai-assistant-shell__attachment-name\">{{ attachment.name }}</span>\n <span class=\"praxis-ai-assistant-shell__attachment-kind\">{{ attachment.kind }}</span>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.removeAttachment\"\n [attr.aria-label]=\"resolvedLabels.removeAttachment + ': ' + attachment.name\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-remove-' + attachment.id\"\n (click)=\"onRemoveAttachment(attachment)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n }\n </div>\n }\n\n @if (quickReplies.length) {\n <div\n class=\"praxis-ai-assistant-shell__quick-replies\"\n [class.praxis-ai-assistant-shell__quick-replies--inline]=\"shouldUseInlineQuickReplies()\"\n [attr.data-testid]=\"testIdPrefix + '-quick-replies'\"\n [attr.aria-label]=\"resolvedLabels.quickRepliesAria\"\n >\n @for (reply of quickReplies; track trackQuickReply($index, reply)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__quick-reply\"\n [class.praxis-ai-assistant-shell__quick-reply--compact]=\"!isRichQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--guided-action]=\"isGuidedActionQuickReply(reply)\"\n [class.praxis-ai-assistant-shell__quick-reply--contextual-action]=\"isContextualPreviewActionQuickReply(reply)\"\n [ngClass]=\"'praxis-ai-assistant-shell__quick-reply--tone-' + getQuickReplyTone(reply)\"\n [attr.data-testid]=\"testIdPrefix + '-quick-reply-' + (reply.id || reply.kind)\"\n [attr.aria-label]=\"getQuickReplyAriaLabel(reply)\"\n [disabled]=\"busy\"\n (click)=\"onQuickReply(reply)\"\n >\n <span class=\"praxis-ai-assistant-shell__quick-reply-ambient\" aria-hidden=\"true\"></span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-icon-frame\" aria-hidden=\"true\">\n <mat-icon\n class=\"praxis-ai-assistant-shell__quick-reply-icon\"\n >\n {{ getQuickReplyIcon(reply) }}\n </mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-header\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-heading\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-label\">{{ reply.label }}</span>\n @if (getQuickReplyDescription(reply)) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-description\"\n >\n {{ getQuickReplyDescription(reply) }}\n </span>\n }\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-actions\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-badge\">\n {{ getQuickReplyCategoryLabel(reply) }}\n </span>\n @if (getQuickReplyTechnicalDetails(reply)) {\n <mat-icon\n class=\"praxis-ai-assistant-shell__quick-reply-details\"\n [matTooltip]=\"getQuickReplyTechnicalDetails(reply)\"\n [attr.aria-label]=\"resolvedLabels.quickReplyDetails\"\n >\n info\n </mat-icon>\n }\n </span>\n </span>\n @if (getQuickReplyContextChips(reply).length) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-context\"\n >\n @for (chip of getQuickReplyContextChips(reply); track chip) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-context-chip\"\n [attr.aria-label]=\"chip.ariaLabel\"\n >\n <mat-icon aria-hidden=\"true\">{{ chip.icon }}</mat-icon>\n <span>{{ chip.value }}</span>\n </span>\n }\n </span>\n }\n @if (getQuickReplyPresentationItems(reply).length) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-insights\"\n >\n @for (item of getQuickReplyPresentationItems(reply); track item) {\n <span\n class=\"praxis-ai-assistant-shell__quick-reply-insight\"\n >\n <mat-icon aria-hidden=\"true\">{{ item.icon }}</mat-icon>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-copy\">\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-label\">\n {{ item.label }}\n </span>\n <span class=\"praxis-ai-assistant-shell__quick-reply-insight-value\">\n {{ item.value }}\n </span>\n </span>\n </span>\n }\n </span>\n }\n <span class=\"praxis-ai-assistant-shell__quick-reply-cta\">\n {{ getQuickReplyCtaLabel(reply) }}\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n }\n </div>\n }\n @if (shouldShowStatusText()) {\n <p\n class=\"praxis-ai-assistant-shell__status\"\n [attr.data-testid]=\"testIdPrefix + '-status'\"\n >\n {{ statusText }}\n </p>\n }\n @if (shouldShowErrorText()) {\n <p\n class=\"praxis-ai-assistant-shell__error\"\n [attr.data-testid]=\"testIdPrefix + '-error'\"\n >\n {{ errorText }}\n </p>\n }\n </div>\n\n <footer class=\"praxis-ai-assistant-shell__footer\">\n <label class=\"praxis-ai-assistant-shell__label\" for=\"praxis-ai-assistant-shell-prompt\">\n {{ resolvedLabels.prompt }}\n </label>\n <div class=\"praxis-ai-assistant-shell__composer\">\n <textarea\n id=\"praxis-ai-assistant-shell-prompt\"\n class=\"praxis-ai-assistant-shell__prompt\"\n [attr.data-testid]=\"testIdPrefix + '-prompt'\"\n [placeholder]=\"resolvedLabels.promptPlaceholder\"\n [ngModel]=\"currentPrompt\"\n [disabled]=\"busy\"\n (ngModelChange)=\"onPromptInput($event)\"\n (keydown)=\"onPromptKeydown($event)\"\n (paste)=\"onPromptPaste($event)\"\n ></textarea>\n <div class=\"praxis-ai-assistant-shell__composer-actions\">\n @if (showAttachAction) {\n <input\n #attachmentInput\n type=\"file\"\n hidden\n [attr.accept]=\"attachmentAccept || null\"\n [attr.multiple]=\"attachmentMultiple ? '' : null\"\n [attr.data-testid]=\"testIdPrefix + '-attachment-input'\"\n (change)=\"onAttachmentFilesSelected($event)\"\n >\n <button\n mat-stroked-button\n type=\"button\"\n [disabled]=\"busy\"\n (click)=\"onAttachClick(attachmentInput)\"\n [attr.data-testid]=\"testIdPrefix + '-attach'\"\n >\n <mat-icon>attach_file</mat-icon>\n {{ resolvedLabels.attach }}\n </button>\n }\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--primary\"\n [class.praxis-ai-assistant-shell__action--icon-only]=\"getPrimaryAction().iconOnly\"\n [matTooltip]=\"getPrimaryActionTooltip(getPrimaryAction())\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(getPrimaryAction())\"\n [disabled]=\"isShellActionDisabled(getPrimaryAction())\"\n (click)=\"onShellAction(getPrimaryAction())\"\n [attr.data-testid]=\"getPrimaryAction().testId || (submitTestId || (testIdPrefix + '-submit'))\"\n [attr.aria-label]=\"getPrimaryAction().ariaLabel || getPrimaryAction().label\"\n >\n @if (getPrimaryAction().icon) {\n <mat-icon aria-hidden=\"true\">{{ getPrimaryAction().icon }}</mat-icon>\n }\n @if (!getPrimaryAction().iconOnly) {\n <span>{{ getPrimaryAction().label }}</span>\n }\n </button>\n @for (action of getSecondaryActions(); track trackShellAction($index, action)) {\n <button\n mat-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__action praxis-ai-assistant-shell__action--secondary\"\n [ngClass]=\"'praxis-ai-assistant-shell__action--tone-' + getShellActionTone(action)\"\n [disabled]=\"isShellActionDisabled(action)\"\n (click)=\"onShellAction(action)\"\n [attr.data-testid]=\"action.testId || (testIdPrefix + '-action-' + action.id)\"\n [attr.aria-label]=\"action.ariaLabel || action.label\"\n >\n @if (action.icon) {\n <mat-icon aria-hidden=\"true\">{{ action.icon }}</mat-icon>\n }\n {{ action.label }}\n </button>\n }\n @if (busy) {\n <mat-spinner diameter=\"20\" [attr.data-testid]=\"testIdPrefix + '-spinner'\"></mat-spinner>\n }\n </div>\n </div>\n </footer>\n\n @if (resizable) {\n @for (direction of resizeHandles; track trackResizeHandle($index, direction)) {\n <span\n class=\"praxis-ai-assistant-shell__resize-handle praxis-ai-assistant-shell__resize-handle--{{ direction }}\"\n [attr.data-testid]=\"direction === 'se' ? testIdPrefix + '-resize-handle' : testIdPrefix + '-resize-handle-' + direction\"\n aria-hidden=\"true\"\n role=\"presentation\"\n (pointerdown)=\"startResize(direction, $event)\"\n ></span>\n }\n }\n</section>\n", styles: [":host{display:block}.praxis-ai-assistant-shell{--praxis-ai-assistant-shell-shadow-color: var(--md-sys-color-shadow);--praxis-ai-assistant-shell-highlight-color: var(--md-sys-color-on-surface);--praxis-ai-assistant-shell-tone-analytics: var(--md-sys-color-primary);--praxis-ai-assistant-shell-tone-resource: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-success: var(--md-sys-color-tertiary);--praxis-ai-assistant-shell-tone-warning: var(--md-sys-color-secondary);--praxis-ai-assistant-shell-tone-danger: var(--md-sys-color-error);--praxis-ai-assistant-shell-tone-neutral: var(--md-sys-color-outline);position:fixed;box-sizing:border-box;min-width:360px;min-height:360px;display:flex;flex-direction:column;overflow:hidden;color:var(--md-sys-color-on-surface);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface);box-shadow:0 24px 60px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 40%,transparent);z-index:var(--praxis-ai-assistant-shell-z-index, 1200)}.praxis-ai-assistant-shell__header{flex:0 0 auto;display:flex;align-items:flex-start;gap:9px;padding:10px 10px 9px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container)}.praxis-ai-assistant-shell__header{justify-content:flex-start;border-bottom:1px solid;cursor:move;touch-action:none}.praxis-ai-assistant-shell__identity{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border-radius:8px;background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary);box-shadow:0 6px 16px color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.praxis-ai-assistant-shell__identity mat-icon{width:18px;height:18px;font-size:18px}.praxis-ai-assistant-shell__title-group{min-width:0;flex:1 1 auto;display:grid;gap:4px}.praxis-ai-assistant-shell__title-row{min-width:0;display:flex;align-items:center;gap:8px}.praxis-ai-assistant-shell__badges{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;min-width:0;flex-wrap:wrap}.praxis-ai-assistant-shell__badge{display:inline-flex;align-items:center;gap:5px;min-height:20px;max-width:120px;padding:2px 7px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);border-radius:8px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-high);font-size:11px;line-height:1.2;overflow-wrap:anywhere}.praxis-ai-assistant-shell__badge--context{color:var(--md-sys-color-on-surface);background:color-mix(in srgb,var(--md-sys-color-primary) 9%,var(--md-sys-color-surface-container-high))}.praxis-ai-assistant-shell__badge--state{border-color:transparent;background:transparent;color:var(--md-sys-color-on-surface-variant);padding-inline:3px}.praxis-ai-assistant-shell__badge--error{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__state-dot{flex:0 0 auto;width:6px;height:6px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__badge--error .praxis-ai-assistant-shell__state-dot{background:var(--md-sys-color-error);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-error) 16%,transparent)}.praxis-ai-assistant-shell__title-group strong,.praxis-ai-assistant-shell__title-group p{min-width:0;margin:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__title-group strong{flex:1 1 auto;font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__title-group p{color:var(--md-sys-color-on-surface-variant);font-size:11.5px;line-height:1.3}.praxis-ai-assistant-shell__header-actions{flex:0 0 auto;display:flex;align-items:center;gap:2px;margin-top:-3px}.praxis-ai-assistant-shell__header-actions button{display:inline-grid;place-items:center;width:34px;height:34px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1;opacity:.78}.praxis-ai-assistant-shell__header-actions button:hover,.praxis-ai-assistant-shell__header-actions button:focus-visible{opacity:1}.praxis-ai-assistant-shell__header-actions mat-icon{display:block;width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__body{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:10px;padding:12px 12px 10px;overflow:auto;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface))}.praxis-ai-assistant-shell__context,.praxis-ai-assistant-shell__attachments{flex:0 0 auto;display:flex;align-items:center;gap:8px;overflow-x:auto}.praxis-ai-assistant-shell__context-item{flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;max-width:240px;padding:5px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high);font-size:12px;line-height:1.25}.praxis-ai-assistant-shell__context-item mat-icon{width:16px;height:16px;font-size:16px}.praxis-ai-assistant-shell__context-label,.praxis-ai-assistant-shell__context-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__context-label{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__context-value{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-ai-assistant-shell__prompt{box-sizing:border-box;width:100%;min-height:46px;max-height:96px;resize:none;border:0;padding:10px 12px 8px;color:var(--md-sys-color-on-surface);background:transparent;font:inherit;line-height:1.45;outline:none}.praxis-ai-assistant-shell__conversation{min-height:0;flex:1 1 auto;display:flex;flex-direction:column;gap:8px;overflow:auto;padding:2px}.praxis-ai-assistant-shell__message{max-width:86%;align-self:flex-start;padding:9px 11px;border-radius:8px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__message-content{white-space:normal}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5){margin:0}.praxis-ai-assistant-shell__message-content :where(p,ul,h3,h4,h5)+:where(p,ul,h3,h4,h5){margin-top:8px}.praxis-ai-assistant-shell__message-content ul{padding-left:18px}.praxis-ai-assistant-shell__message-content li+li{margin-top:4px}.praxis-ai-assistant-shell__message-content code{padding:1px 4px;border-radius:4px;background:color-mix(in srgb,var(--md-sys-color-on-surface) 10%,transparent);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.94em}.praxis-ai-assistant-shell__message-actions{display:flex;align-items:center;gap:4px;flex-wrap:wrap;margin-top:8px}.praxis-ai-assistant-shell__message-action{min-height:28px;padding:0 8px;border-radius:8px;font-size:12px}.praxis-ai-assistant-shell__message-action--icon{width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message-action--icon mat-icon{width:17px;height:17px;font-size:17px}.praxis-ai-assistant-shell__message--assistant{border-bottom-left-radius:2px}.praxis-ai-assistant-shell__message--user{align-self:flex-end;border-bottom-right-radius:2px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.praxis-ai-assistant-shell__message--status{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__message--error,.praxis-ai-assistant-shell__error{color:var(--md-sys-color-error)}.praxis-ai-assistant-shell__quick-replies{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,520px),1fr));gap:8px;align-items:stretch;padding-bottom:4px}.praxis-ai-assistant-shell__quick-replies--inline{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.praxis-ai-assistant-shell__attachment{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;max-width:260px;min-height:34px;padding:4px 4px 4px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high)}.praxis-ai-assistant-shell__attachment--error{border-color:color-mix(in srgb,var(--md-sys-color-error) 60%,transparent)}.praxis-ai-assistant-shell__attachment-preview{flex:0 0 auto;width:28px;height:28px;border-radius:6px;object-fit:cover}.praxis-ai-assistant-shell__attachment-name,.praxis-ai-assistant-shell__attachment-kind{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}.praxis-ai-assistant-shell__attachment-name{color:var(--md-sys-color-on-surface)}.praxis-ai-assistant-shell__attachment-kind{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__quick-reply{--praxis-ai-assistant-shell-quick-reply-accent: var(--md-sys-color-primary);--praxis-ai-assistant-shell-quick-reply-background: color-mix( in srgb, var(--praxis-ai-assistant-shell-quick-reply-accent) 7%, var(--md-sys-color-surface-container-high) );--praxis-ai-assistant-shell-quick-reply-foreground: var(--md-sys-color-on-surface);width:100%;max-width:100%;height:auto;min-height:0;position:relative;overflow:hidden;padding:15px 16px;align-items:stretch;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 36%,transparent);border-radius:22px;color:var(--praxis-ai-assistant-shell-quick-reply-foreground);background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent),transparent 46%),radial-gradient(circle at 92% 10%,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent),transparent 32%),var(--praxis-ai-assistant-shell-quick-reply-background);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 22%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 16%,transparent);letter-spacing:normal;white-space:normal;text-align:left;text-transform:none;-webkit-user-select:none;user-select:none;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease,background .16s ease;--mdc-outlined-button-container-height: auto;--mat-outlined-button-horizontal-padding: 0}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 74%,transparent);box-shadow:0 18px 42px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 24%,transparent),0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 18%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent);transform:translateY(-1px)}.praxis-ai-assistant-shell__quick-reply--contextual-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 92%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--guided-action{padding:10px 12px;border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 30%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)),var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--contextual-action:focus-visible,.praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 62%,transparent);box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 15%,transparent);transform:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-ambient,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-ambient{display:none}.praxis-ai-assistant-shell__quick-reply--contextual-action ::ng-deep .mdc-button__label,.praxis-ai-assistant-shell__quick-reply--guided-action ::ng-deep .mdc-button__label{gap:10px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon-frame,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:8px;box-shadow:none}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-icon,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-copy{gap:6px}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-label{font-size:13.5px;font-weight:760;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-description{display:-webkit-box;overflow:hidden;font-size:12px;line-height:1.34;-webkit-box-orient:vertical;-webkit-line-clamp:2}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-badge{border-radius:8px;font-size:10px;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-context-chip{border-radius:8px;padding:4px 7px;font-size:10.5px;font-weight:650}.praxis-ai-assistant-shell__quick-reply--contextual-action .praxis-ai-assistant-shell__quick-reply-cta,.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta{font-size:11.5px}.praxis-ai-assistant-shell__quick-reply--compact{justify-self:start;width:fit-content;min-width:min(100%,210px);max-width:min(100%,320px);padding:9px 11px;border-radius:16px;background:linear-gradient(135deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent),transparent 55%),var(--md-sys-color-surface-container-high);box-shadow:0 8px 18px color-mix(in srgb,var(--praxis-ai-assistant-shell-shadow-color) 16%,transparent),inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 10%,transparent)}.praxis-ai-assistant-shell__quick-reply.praxis-ai-assistant-shell__quick-reply--compact ::ng-deep .mdc-button__label{align-items:center;gap:10px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:12px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-icon{width:19px;height:19px;font-size:19px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-copy{gap:4px}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-header{align-items:center}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-label{font-size:13px;line-height:1.2}.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--compact .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply{width:auto;min-width:0;max-width:100%;padding:6px 10px;border-radius:999px;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 96%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 52%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{display:inline-flex;grid-template-columns:none;align-items:center;gap:6px;width:auto}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{min-height:34px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon-frame{width:18px;height:18px;border:0;border-radius:0;background:transparent;box-shadow:none}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-icon{width:16px;height:16px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:16px}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-copy,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-heading,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-header{display:inline-flex;align-items:center;gap:0}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:12.5px;font-weight:650;line-height:1.2;white-space:nowrap}.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-description,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-actions,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-replies--inline .praxis-ai-assistant-shell__quick-reply-cta{display:none}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{position:relative;z-index:1;min-width:0;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:flex-start;gap:14px;width:100%;height:auto;line-height:normal}.praxis-ai-assistant-shell__quick-reply-ambient{position:absolute;inset:0;pointer-events:none}.praxis-ai-assistant-shell__quick-reply-ambient:before{content:\"\";position:absolute;inset:0 18px auto;height:1px;border-radius:999px;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 90%,var(--praxis-ai-assistant-shell-highlight-color)),transparent);opacity:.58}.praxis-ai-assistant-shell__quick-reply-ambient:after{content:\"\";position:absolute;top:-34px;right:-44px;width:150px;height:150px;border-radius:999px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 13%,transparent);filter:blur(18px)}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mat-mdc-button-touch-target{height:100%;min-height:48px}.praxis-ai-assistant-shell__quick-reply-icon-frame{flex:0 0 auto;width:46px;height:46px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 34%,transparent);border-radius:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);background:linear-gradient(145deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 24%,transparent),color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 6%,transparent));box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 18%,transparent),0 10px 24px color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 12%,transparent)}.praxis-ai-assistant-shell__quick-reply-icon{width:24px;height:24px;font-size:24px}.praxis-ai-assistant-shell__quick-reply-details{flex:0 0 auto;width:24px;height:24px;display:inline-grid;place-items:center;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 14%,transparent);border-radius:50%;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-outline) 14%,transparent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-copy{min-width:0;display:grid;gap:10px;flex:1 1 auto}.praxis-ai-assistant-shell__quick-reply-header{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.praxis-ai-assistant-shell__quick-reply-heading{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__quick-reply-actions{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:flex-end;gap:7px;max-width:46%}.praxis-ai-assistant-shell__quick-reply-label,.praxis-ai-assistant-shell__quick-reply-description{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-label{color:var(--md-sys-color-on-surface);font-size:17px;font-weight:760;letter-spacing:.005em;line-height:1.18;text-transform:none}.praxis-ai-assistant-shell__quick-reply-badge{flex:0 0 auto;max-width:100%;padding:4px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 28%,transparent);border-radius:999px;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 86%,var(--praxis-ai-assistant-shell-highlight-color));background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 11%,transparent);font-size:10.5px;font-weight:700;letter-spacing:.02em;line-height:1.1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-description{color:color-mix(in srgb,var(--md-sys-color-on-surface) 80%,transparent);font-size:13px;line-height:1.46}.praxis-ai-assistant-shell__quick-reply-context{display:flex;flex-wrap:wrap;gap:7px;align-items:center}.praxis-ai-assistant-shell__quick-reply-context-chip{min-width:0;display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:5px 8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 22%,transparent);border-radius:999px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 82%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 9%,transparent);font-size:11px;font-weight:650;line-height:1.15}.praxis-ai-assistant-shell__quick-reply-context-chip mat-icon{width:14px;height:14px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:14px}.praxis-ai-assistant-shell__quick-reply-context-chip span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__quick-reply-insights{display:grid;grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:8px;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 16%,transparent);border-radius:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 5%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 26%,transparent))}.praxis-ai-assistant-shell__quick-reply-insight{min-width:0;display:grid;grid-template-columns:20px minmax(0,1fr);gap:8px;align-items:start;padding:8px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 10%,transparent);border-radius:13px;color:color-mix(in srgb,var(--md-sys-color-on-surface) 86%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 44%,transparent);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__quick-reply-insight mat-icon{width:17px;height:17px;color:var(--praxis-ai-assistant-shell-quick-reply-accent);font-size:17px;opacity:.9}.praxis-ai-assistant-shell__quick-reply-insight-copy{min-width:0;display:grid;gap:1px}.praxis-ai-assistant-shell__quick-reply-insight-label{color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 82%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:760;letter-spacing:.045em;line-height:1.2;text-transform:uppercase}.praxis-ai-assistant-shell__quick-reply-insight-value{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__quick-reply-cta{display:inline-flex;align-items:center;justify-self:start;gap:5px;padding:3px 0;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:12px;font-weight:760;letter-spacing:.01em;line-height:1.2}.praxis-ai-assistant-shell__quick-reply-cta mat-icon{width:15px;height:15px;font-size:15px;transition:transform .16s ease}.praxis-ai-assistant-shell__quick-reply:hover:not(:disabled) .praxis-ai-assistant-shell__quick-reply-cta mat-icon,.praxis-ai-assistant-shell__quick-reply:focus-visible .praxis-ai-assistant-shell__quick-reply-cta mat-icon{transform:translate(2px)}.praxis-ai-assistant-shell__quick-reply--tone-analytics{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__quick-reply--tone-resource{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__quick-reply--tone-warning{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__quick-reply--tone-success{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__quick-reply--tone-danger{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__quick-reply--tone-neutral{--praxis-ai-assistant-shell-quick-reply-accent: var(--praxis-ai-assistant-shell-tone-neutral)}@media(max-width:640px){.praxis-ai-assistant-shell__quick-reply{padding:13px;border-radius:19px}.praxis-ai-assistant-shell__quick-reply ::ng-deep .mdc-button__label{grid-template-columns:minmax(0,1fr);gap:10px}.praxis-ai-assistant-shell__quick-reply-icon-frame{width:38px;height:38px;border-radius:14px}.praxis-ai-assistant-shell__quick-reply-header{display:grid}.praxis-ai-assistant-shell__quick-reply-actions{justify-content:flex-start;max-width:100%}.praxis-ai-assistant-shell__quick-reply-insights{grid-template-columns:minmax(0,1fr)}}.praxis-ai-assistant-shell__status,.praxis-ai-assistant-shell__error{margin:0;font-size:13px;line-height:1.35;overflow-wrap:anywhere}.praxis-ai-assistant-shell__footer{flex:0 0 auto;padding:8px 10px 10px;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent);background:var(--md-sys-color-surface-container-low)}.praxis-ai-assistant-shell__composer{display:grid;gap:8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-lowest);box-shadow:inset 0 1px color-mix(in srgb,var(--praxis-ai-assistant-shell-highlight-color) 4%,transparent)}.praxis-ai-assistant-shell__composer:focus-within{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.praxis-ai-assistant-shell__composer-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 8px 7px;flex-wrap:wrap}.praxis-ai-assistant-shell__action{min-height:36px;border-radius:10px;font-weight:650}.praxis-ai-assistant-shell__action mat-icon{width:18px;height:18px;margin-right:6px;font-size:18px}.praxis-ai-assistant-shell__action--icon-only{width:40px;min-width:40px;height:40px;padding-inline:0;border-radius:50%}.praxis-ai-assistant-shell__action--icon-only mat-icon{margin-right:0}.praxis-ai-assistant-shell__action--secondary{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__action--tone-governance{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-success{color:var(--praxis-ai-assistant-shell-tone-success);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-warning{color:var(--praxis-ai-assistant-shell-tone-warning);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-warning) 10%,transparent)}.praxis-ai-assistant-shell__action--tone-danger{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__resize-handle{position:absolute;z-index:2;border:0;background:transparent;touch-action:none}.praxis-ai-assistant-shell__resize-handle--n,.praxis-ai-assistant-shell__resize-handle--s{left:16px;right:16px;height:10px;cursor:ns-resize}.praxis-ai-assistant-shell__resize-handle--n{top:-5px}.praxis-ai-assistant-shell__resize-handle--s{bottom:-5px}.praxis-ai-assistant-shell__resize-handle--e,.praxis-ai-assistant-shell__resize-handle--w{top:16px;bottom:16px;width:10px;cursor:ew-resize}.praxis-ai-assistant-shell__resize-handle--e{right:-5px}.praxis-ai-assistant-shell__resize-handle--w{left:-5px}.praxis-ai-assistant-shell__resize-handle--ne,.praxis-ai-assistant-shell__resize-handle--nw,.praxis-ai-assistant-shell__resize-handle--se,.praxis-ai-assistant-shell__resize-handle--sw{width:22px;height:22px}.praxis-ai-assistant-shell__resize-handle--ne{top:-5px;right:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--nw{top:-5px;left:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--se{right:-5px;bottom:-5px;cursor:nwse-resize}.praxis-ai-assistant-shell__resize-handle--sw{bottom:-5px;left:-5px;cursor:nesw-resize}.praxis-ai-assistant-shell__resize-handle--se:after{content:\"\";position:absolute;right:8px;bottom:8px;width:10px;height:10px;border-right:2px solid var(--md-sys-color-outline);border-bottom:2px solid var(--md-sys-color-outline)}\n"] }]
|
|
7920
7922
|
}], propDecorators: { labels: [{
|
|
7921
7923
|
type: Input
|
|
7922
7924
|
}], mode: [{
|
|
@@ -8113,8 +8115,8 @@ class PraxisAiAssistantDockComponent {
|
|
|
8113
8115
|
return 'Governed';
|
|
8114
8116
|
return 'Ready';
|
|
8115
8117
|
}
|
|
8116
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8117
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
8118
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantDockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8119
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PraxisAiAssistantDockComponent, isStandalone: true, selector: "praxis-ai-assistant-dock", inputs: { title: "title", summary: "summary", badge: "badge", icon: "icon", state: "state", tone: "tone", ariaLabel: "ariaLabel", openAriaLabel: "openAriaLabel", openTooltip: "openTooltip", testId: "testId", openTestId: "openTestId" }, outputs: { open: "open" }, ngImport: i0, template: `
|
|
8118
8120
|
<section
|
|
8119
8121
|
class="praxis-ai-assistant-dock"
|
|
8120
8122
|
[class.praxis-ai-assistant-dock--working]="resolvedTone() === 'working'"
|
|
@@ -8143,11 +8145,11 @@ class PraxisAiAssistantDockComponent {
|
|
|
8143
8145
|
<span class="praxis-ai-assistant-dock__badge">{{ resolvedBadge() }}</span>
|
|
8144
8146
|
</button>
|
|
8145
8147
|
</section>
|
|
8146
|
-
`, isInline: true, styles: [":host{display:block;position:var(--praxis-ai-assistant-dock-position, absolute);z-index:var(--praxis-ai-assistant-dock-z-index, 135);right:var(--praxis-ai-assistant-dock-right, 16px);bottom:var(--praxis-ai-assistant-dock-bottom, 88px);width:min(var(--praxis-ai-assistant-dock-width, 560px),calc(100% - 32px));pointer-events:auto}.praxis-ai-assistant-dock__main{appearance:none;width:100%;min-height:76px;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;border:1px solid rgba(56,189,248,.34);border-radius:18px;background:radial-gradient(circle at 8% 18%,rgba(14,165,233,.24),transparent 34%),linear-gradient(135deg,#0f172af0,#1e293beb 48%,#082f49e6);color:#e0f2fe;box-shadow:0 22px 58px #02061757,inset 0 1px #ffffff1f;cursor:pointer;text-align:left}.praxis-ai-assistant-dock__main:hover,.praxis-ai-assistant-dock__main:focus-visible{border-color:#7dd3fc9e;box-shadow:0 26px 72px #0206176b,0 0 0 3px #0ea5e92e;outline:none}.praxis-ai-assistant-dock__orb{width:46px;height:46px;display:inline-grid;place-items:center;border-radius:16px;background:linear-gradient(135deg,#38bdf8,#22c55e);color:#082f49;box-shadow:0 12px 28px #22c55e3d}.praxis-ai-assistant-dock--working .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#38bdf8,#a78bfa)}.praxis-ai-assistant-dock--review .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#facc15,#38bdf8)}.praxis-ai-assistant-dock--governed .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#22c55e,#14b8a6)}.praxis-ai-assistant-dock--error .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#f97316,#ef4444);color:#fff7ed}.praxis-ai-assistant-dock__copy{min-width:0;display:grid;gap:3px}.praxis-ai-assistant-dock__copy strong{color:#f8fafc;font-size:14px;line-height:1.2}.praxis-ai-assistant-dock__copy span{color:#bae6fd;font-size:12px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-dock__badge{max-width:132px;padding:5px 9px;border:1px solid rgba(186,230,253,.24);border-radius:999px;background:#0f172a7a;color:#f0f9ff;font-size:11px;font-weight:800;letter-spacing:.02em;overflow:hidden;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}@media(max-width:720px){:host{right:var(--praxis-ai-assistant-dock-mobile-right, 12px);bottom:var(--praxis-ai-assistant-dock-mobile-bottom, 84px);width:calc(100% - 24px)}.praxis-ai-assistant-dock__main{grid-template-columns:auto minmax(0,1fr)}.praxis-ai-assistant-dock__badge{grid-column:2;justify-self:start}}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
8148
|
+
`, isInline: true, styles: [":host{display:block;position:var(--praxis-ai-assistant-dock-position, absolute);z-index:var(--praxis-ai-assistant-dock-z-index, 135);right:var(--praxis-ai-assistant-dock-right, 16px);bottom:var(--praxis-ai-assistant-dock-bottom, 88px);width:min(var(--praxis-ai-assistant-dock-width, 560px),calc(100% - 32px));pointer-events:auto}.praxis-ai-assistant-dock__main{appearance:none;width:100%;min-height:76px;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;border:1px solid rgba(56,189,248,.34);border-radius:18px;background:radial-gradient(circle at 8% 18%,rgba(14,165,233,.24),transparent 34%),linear-gradient(135deg,#0f172af0,#1e293beb 48%,#082f49e6);color:#e0f2fe;box-shadow:0 22px 58px #02061757,inset 0 1px #ffffff1f;cursor:pointer;text-align:left}.praxis-ai-assistant-dock__main:hover,.praxis-ai-assistant-dock__main:focus-visible{border-color:#7dd3fc9e;box-shadow:0 26px 72px #0206176b,0 0 0 3px #0ea5e92e;outline:none}.praxis-ai-assistant-dock__orb{width:46px;height:46px;display:inline-grid;place-items:center;border-radius:16px;background:linear-gradient(135deg,#38bdf8,#22c55e);color:#082f49;box-shadow:0 12px 28px #22c55e3d}.praxis-ai-assistant-dock--working .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#38bdf8,#a78bfa)}.praxis-ai-assistant-dock--review .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#facc15,#38bdf8)}.praxis-ai-assistant-dock--governed .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#22c55e,#14b8a6)}.praxis-ai-assistant-dock--error .praxis-ai-assistant-dock__orb{background:linear-gradient(135deg,#f97316,#ef4444);color:#fff7ed}.praxis-ai-assistant-dock__copy{min-width:0;display:grid;gap:3px}.praxis-ai-assistant-dock__copy strong{color:#f8fafc;font-size:14px;line-height:1.2}.praxis-ai-assistant-dock__copy span{color:#bae6fd;font-size:12px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-dock__badge{max-width:132px;padding:5px 9px;border:1px solid rgba(186,230,253,.24);border-radius:999px;background:#0f172a7a;color:#f0f9ff;font-size:11px;font-weight:800;letter-spacing:.02em;overflow:hidden;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}@media(max-width:720px){:host{right:var(--praxis-ai-assistant-dock-mobile-right, 12px);bottom:var(--praxis-ai-assistant-dock-mobile-bottom, 84px);width:calc(100% - 24px)}.praxis-ai-assistant-dock__main{grid-template-columns:auto minmax(0,1fr)}.praxis-ai-assistant-dock__badge{grid-column:2;justify-self:start}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8147
8149
|
}
|
|
8148
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8150
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantDockComponent, decorators: [{
|
|
8149
8151
|
type: Component,
|
|
8150
|
-
args: [{ selector: 'praxis-ai-assistant-dock', standalone: true, imports: [
|
|
8152
|
+
args: [{ selector: 'praxis-ai-assistant-dock', standalone: true, imports: [MatIconModule, MatTooltipModule], template: `
|
|
8151
8153
|
<section
|
|
8152
8154
|
class="praxis-ai-assistant-dock"
|
|
8153
8155
|
[class.praxis-ai-assistant-dock--working]="resolvedTone() === 'working'"
|
|
@@ -8250,56 +8252,60 @@ class PraxisAiAssistantSessionHostComponent {
|
|
|
8250
8252
|
safeId(value) {
|
|
8251
8253
|
return value.replace(/[^a-zA-Z0-9_-]+/g, '-');
|
|
8252
8254
|
}
|
|
8253
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8254
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8255
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantSessionHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8256
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisAiAssistantSessionHostComponent, isStandalone: true, selector: "praxis-ai-assistant-session-host", inputs: { testId: "testId", dockTestIdPrefix: "dockTestIdPrefix", ariaLabel: "ariaLabel", openAriaLabel: "openAriaLabel", openTooltip: "openTooltip", ownerType: "ownerType", ownerId: "ownerId", visibility: "visibility", includeOriginAnchored: ["includeOriginAnchored", "includeOriginAnchored", booleanAttribute] }, outputs: { sessionOpen: "sessionOpen" }, ngImport: i0, template: `
|
|
8257
|
+
@if (visibleSessions().length) {
|
|
8258
|
+
<section
|
|
8259
|
+
class="praxis-ai-assistant-session-host"
|
|
8260
|
+
[attr.data-testid]="testId"
|
|
8261
|
+
[attr.aria-label]="ariaLabel"
|
|
8262
|
+
>
|
|
8263
|
+
@for (session of visibleSessions(); track trackSession($index, session); let first = $first) {
|
|
8264
|
+
<praxis-ai-assistant-dock
|
|
8265
|
+
[title]="session.title"
|
|
8266
|
+
[summary]="session.summary"
|
|
8267
|
+
[badge]="session.badge"
|
|
8268
|
+
[icon]="session.icon"
|
|
8269
|
+
[state]="session.state"
|
|
8270
|
+
[ariaLabel]="sessionAriaLabel(session)"
|
|
8271
|
+
[openAriaLabel]="openAriaLabel"
|
|
8272
|
+
[openTooltip]="openTooltip"
|
|
8273
|
+
[testId]="dockTestId(session, first)"
|
|
8274
|
+
[openTestId]="dockOpenTestId(session, first)"
|
|
8275
|
+
(open)="openSession(session.id)"
|
|
8276
|
+
/>
|
|
8277
|
+
}
|
|
8278
|
+
</section>
|
|
8279
|
+
}
|
|
8280
|
+
`, isInline: true, styles: [":host{display:block;position:absolute;z-index:var(--praxis-ai-assistant-session-host-z-index, 136);right:var(--praxis-ai-assistant-session-host-right, 16px);bottom:var(--praxis-ai-assistant-session-host-bottom, 88px);width:min(var(--praxis-ai-assistant-session-host-width, 560px),calc(100% - 32px));pointer-events:none}.praxis-ai-assistant-session-host{display:grid;gap:10px;pointer-events:auto}praxis-ai-assistant-dock{--praxis-ai-assistant-dock-position: static;--praxis-ai-assistant-dock-width: 100%}@media(max-width:720px){:host{right:var(--praxis-ai-assistant-session-host-mobile-right, 12px);bottom:var(--praxis-ai-assistant-session-host-mobile-bottom, 84px);width:calc(100% - 24px)}}\n"], dependencies: [{ kind: "component", type: PraxisAiAssistantDockComponent, selector: "praxis-ai-assistant-dock", inputs: ["title", "summary", "badge", "icon", "state", "tone", "ariaLabel", "openAriaLabel", "openTooltip", "testId", "openTestId"], outputs: ["open"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8277
8281
|
}
|
|
8278
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8282
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantSessionHostComponent, decorators: [{
|
|
8279
8283
|
type: Component,
|
|
8280
|
-
args: [{ selector: 'praxis-ai-assistant-session-host', standalone: true, imports: [
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
|
|
8285
|
-
|
|
8286
|
-
|
|
8287
|
-
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8284
|
+
args: [{ selector: 'praxis-ai-assistant-session-host', standalone: true, imports: [PraxisAiAssistantDockComponent], template: `
|
|
8285
|
+
@if (visibleSessions().length) {
|
|
8286
|
+
<section
|
|
8287
|
+
class="praxis-ai-assistant-session-host"
|
|
8288
|
+
[attr.data-testid]="testId"
|
|
8289
|
+
[attr.aria-label]="ariaLabel"
|
|
8290
|
+
>
|
|
8291
|
+
@for (session of visibleSessions(); track trackSession($index, session); let first = $first) {
|
|
8292
|
+
<praxis-ai-assistant-dock
|
|
8293
|
+
[title]="session.title"
|
|
8294
|
+
[summary]="session.summary"
|
|
8295
|
+
[badge]="session.badge"
|
|
8296
|
+
[icon]="session.icon"
|
|
8297
|
+
[state]="session.state"
|
|
8298
|
+
[ariaLabel]="sessionAriaLabel(session)"
|
|
8299
|
+
[openAriaLabel]="openAriaLabel"
|
|
8300
|
+
[openTooltip]="openTooltip"
|
|
8301
|
+
[testId]="dockTestId(session, first)"
|
|
8302
|
+
[openTestId]="dockOpenTestId(session, first)"
|
|
8303
|
+
(open)="openSession(session.id)"
|
|
8304
|
+
/>
|
|
8305
|
+
}
|
|
8306
|
+
</section>
|
|
8307
|
+
}
|
|
8308
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;position:absolute;z-index:var(--praxis-ai-assistant-session-host-z-index, 136);right:var(--praxis-ai-assistant-session-host-right, 16px);bottom:var(--praxis-ai-assistant-session-host-bottom, 88px);width:min(var(--praxis-ai-assistant-session-host-width, 560px),calc(100% - 32px));pointer-events:none}.praxis-ai-assistant-session-host{display:grid;gap:10px;pointer-events:auto}praxis-ai-assistant-dock{--praxis-ai-assistant-dock-position: static;--praxis-ai-assistant-dock-width: 100%}@media(max-width:720px){:host{right:var(--praxis-ai-assistant-session-host-mobile-right, 12px);bottom:var(--praxis-ai-assistant-session-host-mobile-bottom, 84px);width:calc(100% - 24px)}}\n"] }]
|
|
8303
8309
|
}], propDecorators: { testId: [{
|
|
8304
8310
|
type: Input
|
|
8305
8311
|
}], dockTestIdPrefix: [{
|
|
@@ -8327,34 +8333,38 @@ class StreamingFeedbackComponent {
|
|
|
8327
8333
|
title = 'Processando...';
|
|
8328
8334
|
displayText = '';
|
|
8329
8335
|
isThinking = false;
|
|
8330
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8331
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
8336
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: StreamingFeedbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8337
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: StreamingFeedbackComponent, isStandalone: true, selector: "praxis-ai-streaming-feedback", inputs: { title: "title", displayText: "displayText", isThinking: "isThinking" }, ngImport: i0, template: `
|
|
8332
8338
|
<div class="ai-processing-overlay">
|
|
8333
8339
|
<div class="ai-pulse-ring"></div>
|
|
8334
8340
|
<mat-icon class="sparkle-icon">auto_awesome</mat-icon>
|
|
8335
8341
|
<div class="processing-text">
|
|
8336
|
-
|
|
8342
|
+
@if (title) {
|
|
8343
|
+
<h3>{{ title }}</h3>
|
|
8344
|
+
}
|
|
8337
8345
|
<div class="stream-content">
|
|
8338
8346
|
<p class="fade-text" [class.thinking]="isThinking">{{ displayText }}<span class="cursor">|</span></p>
|
|
8339
8347
|
</div>
|
|
8340
8348
|
</div>
|
|
8341
8349
|
</div>
|
|
8342
|
-
|
|
8350
|
+
`, isInline: true, styles: [".ai-processing-overlay{position:absolute;inset:0;background:#ffffffeb;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);z-index:100;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;border-radius:8px;padding:32px;text-align:center}.sparkle-icon{font-size:48px;width:48px;height:48px;color:#673ab7;animation:ai-pulse 2s infinite;z-index:2}.ai-pulse-ring{position:absolute;width:120px;height:120px;border-radius:50%;background:radial-gradient(circle,#673ab726,#673ab700 70%);animation:ai-ripple 2s infinite;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);margin-top:-40px}.processing-text{z-index:2;max-width:400px;width:100%}.processing-text h3{margin:0 0 12px;color:#311b92;font-size:18px;font-weight:500}.stream-content{min-height:48px;display:flex;align-items:center;justify-content:center}.fade-text{margin:0;color:#455a64;font-size:14px;line-height:1.5;white-space:pre-wrap;font-family:monospace}.fade-text.thinking{color:#673ab7;font-style:italic}.cursor{display:inline-block;width:2px;background-color:#673ab7;animation:blink 1s step-end infinite;margin-left:2px;vertical-align:text-bottom}@keyframes ai-pulse{0%{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}50%{transform:scale(1.1);opacity:.8;text-shadow:0 0 20px rgba(103,58,183,.8)}to{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}}@keyframes ai-ripple{0%{transform:translate(-50%,-50%) scale(.8);opacity:.6}to{transform:translate(-50%,-50%) scale(2.5);opacity:0}}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8343
8351
|
}
|
|
8344
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8352
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: StreamingFeedbackComponent, decorators: [{
|
|
8345
8353
|
type: Component,
|
|
8346
|
-
args: [{ selector: 'praxis-ai-streaming-feedback', standalone: true, imports: [
|
|
8354
|
+
args: [{ selector: 'praxis-ai-streaming-feedback', standalone: true, imports: [MatIconModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
8347
8355
|
<div class="ai-processing-overlay">
|
|
8348
8356
|
<div class="ai-pulse-ring"></div>
|
|
8349
8357
|
<mat-icon class="sparkle-icon">auto_awesome</mat-icon>
|
|
8350
8358
|
<div class="processing-text">
|
|
8351
|
-
|
|
8359
|
+
@if (title) {
|
|
8360
|
+
<h3>{{ title }}</h3>
|
|
8361
|
+
}
|
|
8352
8362
|
<div class="stream-content">
|
|
8353
8363
|
<p class="fade-text" [class.thinking]="isThinking">{{ displayText }}<span class="cursor">|</span></p>
|
|
8354
8364
|
</div>
|
|
8355
8365
|
</div>
|
|
8356
8366
|
</div>
|
|
8357
|
-
|
|
8367
|
+
`, styles: [".ai-processing-overlay{position:absolute;inset:0;background:#ffffffeb;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);z-index:100;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;border-radius:8px;padding:32px;text-align:center}.sparkle-icon{font-size:48px;width:48px;height:48px;color:#673ab7;animation:ai-pulse 2s infinite;z-index:2}.ai-pulse-ring{position:absolute;width:120px;height:120px;border-radius:50%;background:radial-gradient(circle,#673ab726,#673ab700 70%);animation:ai-ripple 2s infinite;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);margin-top:-40px}.processing-text{z-index:2;max-width:400px;width:100%}.processing-text h3{margin:0 0 12px;color:#311b92;font-size:18px;font-weight:500}.stream-content{min-height:48px;display:flex;align-items:center;justify-content:center}.fade-text{margin:0;color:#455a64;font-size:14px;line-height:1.5;white-space:pre-wrap;font-family:monospace}.fade-text.thinking{color:#673ab7;font-style:italic}.cursor{display:inline-block;width:2px;background-color:#673ab7;animation:blink 1s step-end infinite;margin-left:2px;vertical-align:text-bottom}@keyframes ai-pulse{0%{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}50%{transform:scale(1.1);opacity:.8;text-shadow:0 0 20px rgba(103,58,183,.8)}to{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}}@keyframes ai-ripple{0%{transform:translate(-50%,-50%) scale(.8);opacity:.6}to{transform:translate(-50%,-50%) scale(2.5);opacity:0}}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}\n"] }]
|
|
8358
8368
|
}], propDecorators: { title: [{
|
|
8359
8369
|
type: Input
|
|
8360
8370
|
}], displayText: [{
|
|
@@ -8520,10 +8530,10 @@ LÓGICOS:
|
|
|
8520
8530
|
- { "!": [condicao] }
|
|
8521
8531
|
`.trim();
|
|
8522
8532
|
}
|
|
8523
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8524
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
8533
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiContextBuilderService, deps: [{ token: SchemaMinifierService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
8534
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiContextBuilderService, providedIn: 'root' });
|
|
8525
8535
|
}
|
|
8526
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8536
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiContextBuilderService, decorators: [{
|
|
8527
8537
|
type: Injectable,
|
|
8528
8538
|
args: [{ providedIn: 'root' }]
|
|
8529
8539
|
}], ctorParameters: () => [{ type: SchemaMinifierService }] });
|
|
@@ -8702,202 +8712,231 @@ class AiRuleWizardDialogComponent {
|
|
|
8702
8712
|
hasProps(obj) {
|
|
8703
8713
|
return obj && Object.keys(obj).length > 0;
|
|
8704
8714
|
}
|
|
8705
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
8706
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
8715
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiRuleWizardDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: PraxisAiService }, { token: AiResponseValidatorService }, { token: i4$1.MatSnackBar }, { token: AiContextBuilderService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
8716
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: AiRuleWizardDialogComponent, isStandalone: true, selector: "praxis-ai-rule-wizard-dialog", ngImport: i0, template: `
|
|
8707
8717
|
<div class="ai-wizard-container">
|
|
8708
8718
|
<h2 mat-dialog-title class="wizard-title">
|
|
8709
8719
|
<mat-icon class="ai-icon">auto_awesome</mat-icon>
|
|
8710
8720
|
<span>Criar Regra com IA</span>
|
|
8711
|
-
|
|
8721
|
+
@if (currentStep === 'review') {
|
|
8722
|
+
<span class="step-badge">Revisão</span>
|
|
8723
|
+
}
|
|
8712
8724
|
</h2>
|
|
8713
|
-
|
|
8725
|
+
|
|
8714
8726
|
<mat-dialog-content class="wizard-content">
|
|
8715
|
-
|
|
8727
|
+
|
|
8716
8728
|
<!-- STEP 1: PROMPT -->
|
|
8717
|
-
|
|
8718
|
-
<
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8729
|
+
@if (currentStep === 'prompt') {
|
|
8730
|
+
<div class="step-prompt">
|
|
8731
|
+
<p class="intro-text">
|
|
8732
|
+
Descreva a regra que você deseja criar em linguagem natural e a IA irá gerar a configuração para você revisar.
|
|
8733
|
+
</p>
|
|
8734
|
+
<div class="form-row">
|
|
8735
|
+
<mat-form-field appearance="outline" class="type-select">
|
|
8736
|
+
<mat-label>Tipo de Alvo</mat-label>
|
|
8737
|
+
<mat-select [(ngModel)]="selectedTargetType" (selectionChange)="onTargetTypeChange()">
|
|
8738
|
+
<mat-option value="field">Campo (Field)</mat-option>
|
|
8739
|
+
<mat-option value="section">Seção (Section)</mat-option>
|
|
8740
|
+
<mat-option value="action">Ação (Action)</mat-option>
|
|
8741
|
+
<mat-option value="row">Linha (Row)</mat-option>
|
|
8742
|
+
<mat-option value="column">Coluna (Column)</mat-option>
|
|
8743
|
+
</mat-select>
|
|
8744
|
+
</mat-form-field>
|
|
8745
|
+
</div>
|
|
8746
|
+
<mat-form-field appearance="outline" class="prompt-input">
|
|
8747
|
+
<mat-label>Descreva sua regra</mat-label>
|
|
8748
|
+
<textarea
|
|
8749
|
+
matInput
|
|
8750
|
+
[(ngModel)]="userPrompt"
|
|
8751
|
+
rows="6"
|
|
8752
|
+
placeholder="Ex: Esconder o campo telefone se a idade for menor que 18 anos..."
|
|
8753
|
+
[disabled]="isGenerating"
|
|
8754
|
+
></textarea>
|
|
8755
|
+
<mat-hint align="end">{{userPrompt.length}} caracteres</mat-hint>
|
|
8732
8756
|
</mat-form-field>
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
[disabled]="isGenerating"
|
|
8743
|
-
></textarea>
|
|
8744
|
-
<mat-hint align="end">{{userPrompt.length}} caracteres</mat-hint>
|
|
8745
|
-
</mat-form-field>
|
|
8746
|
-
|
|
8747
|
-
<div class="suggestions-card" data-testid="ai-suggestions">
|
|
8748
|
-
<div class="suggestions-header">
|
|
8749
|
-
<div class="title">
|
|
8750
|
-
<mat-icon>lightbulb</mat-icon>
|
|
8751
|
-
Sugestões da IA
|
|
8757
|
+
<div class="suggestions-card" data-testid="ai-suggestions">
|
|
8758
|
+
<div class="suggestions-header">
|
|
8759
|
+
<div class="title">
|
|
8760
|
+
<mat-icon>lightbulb</mat-icon>
|
|
8761
|
+
Sugestões da IA
|
|
8762
|
+
</div>
|
|
8763
|
+
<button mat-icon-button type="button" (click)="reloadSuggestions()" [disabled]="loadingSuggestions">
|
|
8764
|
+
<mat-icon>refresh</mat-icon>
|
|
8765
|
+
</button>
|
|
8752
8766
|
</div>
|
|
8753
|
-
|
|
8754
|
-
<
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8767
|
+
@if (!loadingSuggestions && suggestions.length > 0) {
|
|
8768
|
+
<div class="suggestions-body">
|
|
8769
|
+
<mat-chip-set aria-label="Sugestões de regras">
|
|
8770
|
+
@for (suggestion of suggestions; track suggestion) {
|
|
8771
|
+
<mat-chip (click)="applySuggestion(suggestion)" class="suggestion-chip">
|
|
8772
|
+
{{ suggestion }}
|
|
8773
|
+
</mat-chip>
|
|
8774
|
+
}
|
|
8775
|
+
</mat-chip-set>
|
|
8776
|
+
</div>
|
|
8777
|
+
} @else {
|
|
8778
|
+
@if (loadingSuggestions) {
|
|
8779
|
+
<div class="suggestions-loading">
|
|
8780
|
+
<mat-progress-spinner diameter="20" mode="indeterminate"></mat-progress-spinner>
|
|
8781
|
+
<span>Gerando sugestões...</span>
|
|
8782
|
+
</div>
|
|
8783
|
+
}
|
|
8784
|
+
@if (!loadingSuggestions && suggestions.length === 0) {
|
|
8785
|
+
<div class="suggestions-empty">
|
|
8786
|
+
Nenhuma sugestão disponível no momento.
|
|
8787
|
+
</div>
|
|
8788
|
+
}
|
|
8789
|
+
}
|
|
8763
8790
|
</div>
|
|
8764
|
-
<
|
|
8765
|
-
<
|
|
8766
|
-
<mat-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
|
|
8791
|
+
<mat-expansion-panel class="properties-panel">
|
|
8792
|
+
<mat-expansion-panel-header>
|
|
8793
|
+
<mat-panel-title>
|
|
8794
|
+
<mat-icon>info</mat-icon>
|
|
8795
|
+
Ver propriedades disponíveis
|
|
8796
|
+
</mat-panel-title>
|
|
8797
|
+
</mat-expansion-panel-header>
|
|
8798
|
+
<div class="properties-list">
|
|
8799
|
+
@for (prop of getAvailableProperties(); track prop) {
|
|
8800
|
+
<div class="prop-item">
|
|
8801
|
+
<span class="prop-name">{{prop.name}}</span>
|
|
8802
|
+
<span class="prop-type">{{prop.type}}</span>
|
|
8803
|
+
@if (prop.label) {
|
|
8804
|
+
<span class="prop-desc">- {{prop.label}}</span>
|
|
8805
|
+
}
|
|
8806
|
+
</div>
|
|
8807
|
+
}
|
|
8771
8808
|
</div>
|
|
8772
|
-
</
|
|
8809
|
+
</mat-expansion-panel>
|
|
8773
8810
|
</div>
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
<mat-expansion-panel-header>
|
|
8777
|
-
<mat-panel-title>
|
|
8778
|
-
<mat-icon>info</mat-icon>
|
|
8779
|
-
Ver propriedades disponíveis
|
|
8780
|
-
</mat-panel-title>
|
|
8781
|
-
</mat-expansion-panel-header>
|
|
8782
|
-
<div class="properties-list">
|
|
8783
|
-
<div *ngFor="let prop of getAvailableProperties()" class="prop-item">
|
|
8784
|
-
<span class="prop-name">{{prop.name}}</span>
|
|
8785
|
-
<span class="prop-type">{{prop.type}}</span>
|
|
8786
|
-
<span class="prop-desc" *ngIf="prop.label">- {{prop.label}}</span>
|
|
8787
|
-
</div>
|
|
8788
|
-
</div>
|
|
8789
|
-
</mat-expansion-panel>
|
|
8790
|
-
</div>
|
|
8791
|
-
|
|
8811
|
+
}
|
|
8812
|
+
|
|
8792
8813
|
<!-- STEP 2: REVIEW -->
|
|
8793
|
-
|
|
8794
|
-
<div class="review
|
|
8795
|
-
<
|
|
8796
|
-
|
|
8797
|
-
<
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
<div class="warning-title">
|
|
8804
|
-
<mat-icon>auto_fix_high</mat-icon>
|
|
8805
|
-
Correções Automáticas
|
|
8814
|
+
@if (currentStep === 'review' && generatedResponse) {
|
|
8815
|
+
<div class="step-review">
|
|
8816
|
+
<div class="review-header">
|
|
8817
|
+
<h3>{{ generatedResponse.ruleName }}</h3>
|
|
8818
|
+
<div class="target-badges">
|
|
8819
|
+
<span class="badge-type">{{ generatedResponse.targetType }}</span>
|
|
8820
|
+
@for (id of generatedResponse.targetIds; track id) {
|
|
8821
|
+
<span class="badge-id">{{ id }}</span>
|
|
8822
|
+
}
|
|
8823
|
+
</div>
|
|
8806
8824
|
</div>
|
|
8807
|
-
|
|
8808
|
-
<
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
</div>
|
|
8813
|
-
|
|
8814
|
-
<mat-tab-group class="preview-tabs" animationDuration="0ms">
|
|
8815
|
-
<mat-tab label="Resumo">
|
|
8816
|
-
<div class="summary-view">
|
|
8817
|
-
<div class="summary-row">
|
|
8818
|
-
<span class="label">Condição:</span>
|
|
8819
|
-
<code class="value condition" *ngIf="generatedResponse.condition">{{ generatedResponse.condition | json }}</code>
|
|
8820
|
-
<span class="value" *ngIf="!generatedResponse.condition"><em>(Sempre aplicada)</em></span>
|
|
8825
|
+
@if (warnings.length > 0) {
|
|
8826
|
+
<div class="warnings-box">
|
|
8827
|
+
<div class="warning-title">
|
|
8828
|
+
<mat-icon>auto_fix_high</mat-icon>
|
|
8829
|
+
Correções Automáticas
|
|
8821
8830
|
</div>
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
+
<ul class="warning-list">
|
|
8832
|
+
@for (w of warnings; track w) {
|
|
8833
|
+
<li>
|
|
8834
|
+
{{ w.message }}
|
|
8835
|
+
</li>
|
|
8836
|
+
}
|
|
8837
|
+
</ul>
|
|
8838
|
+
</div>
|
|
8839
|
+
}
|
|
8840
|
+
<mat-tab-group class="preview-tabs" animationDuration="0ms">
|
|
8841
|
+
<mat-tab label="Resumo">
|
|
8842
|
+
<div class="summary-view">
|
|
8843
|
+
<div class="summary-row">
|
|
8844
|
+
<span class="label">Condição:</span>
|
|
8845
|
+
@if (generatedResponse.condition) {
|
|
8846
|
+
<code class="value condition">{{ generatedResponse.condition | json }}</code>
|
|
8847
|
+
}
|
|
8848
|
+
@if (!generatedResponse.condition) {
|
|
8849
|
+
<span class="value"><em>(Sempre aplicada)</em></span>
|
|
8850
|
+
}
|
|
8831
8851
|
</div>
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
|
|
8839
|
-
|
|
8852
|
+
<div class="summary-row">
|
|
8853
|
+
<span class="label">Propriedades (True):</span>
|
|
8854
|
+
<div class="props-grid">
|
|
8855
|
+
@for (p of getProps(generatedResponse.effects.properties); track p) {
|
|
8856
|
+
<div class="prop-pair">
|
|
8857
|
+
<span class="p-key">{{p.key}}:</span>
|
|
8858
|
+
<span class="p-val">{{p.value}}</span>
|
|
8859
|
+
</div>
|
|
8860
|
+
}
|
|
8861
|
+
@if (!hasProps(generatedResponse.effects.properties)) {
|
|
8862
|
+
<span>-</span>
|
|
8863
|
+
}
|
|
8840
8864
|
</div>
|
|
8841
8865
|
</div>
|
|
8866
|
+
@if (hasProps(generatedResponse.effects.propertiesWhenFalse)) {
|
|
8867
|
+
<div class="summary-row">
|
|
8868
|
+
<span class="label">Propriedades (False):</span>
|
|
8869
|
+
<div class="props-grid">
|
|
8870
|
+
@for (p of getProps(generatedResponse.effects.propertiesWhenFalse); track p) {
|
|
8871
|
+
<div class="prop-pair">
|
|
8872
|
+
<span class="p-key">{{p.key}}:</span>
|
|
8873
|
+
<span class="p-val">{{p.value}}</span>
|
|
8874
|
+
</div>
|
|
8875
|
+
}
|
|
8876
|
+
</div>
|
|
8877
|
+
</div>
|
|
8878
|
+
}
|
|
8842
8879
|
</div>
|
|
8843
|
-
</
|
|
8844
|
-
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
</mat-tab>
|
|
8848
|
-
</
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8880
|
+
</mat-tab>
|
|
8881
|
+
<mat-tab label="JSON">
|
|
8882
|
+
<pre class="json-preview">{{ generatedResponse | json }}</pre>
|
|
8883
|
+
</mat-tab>
|
|
8884
|
+
</mat-tab-group>
|
|
8885
|
+
</div>
|
|
8886
|
+
}
|
|
8887
|
+
|
|
8852
8888
|
<!-- COMMON: LOADING & ERROR -->
|
|
8853
|
-
|
|
8854
|
-
<
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8889
|
+
@if (validationError) {
|
|
8890
|
+
<div class="error-box">
|
|
8891
|
+
<mat-icon>error</mat-icon>
|
|
8892
|
+
<span>{{validationError}}</span>
|
|
8893
|
+
</div>
|
|
8894
|
+
}
|
|
8895
|
+
|
|
8896
|
+
@if (isGenerating) {
|
|
8897
|
+
<praxis-ai-streaming-feedback
|
|
8898
|
+
[displayText]="streamingText || currentLoadingMessage"
|
|
8899
|
+
[isThinking]="true"
|
|
8900
|
+
[title]="'Criando sua regra...'"
|
|
8901
|
+
></praxis-ai-streaming-feedback>
|
|
8902
|
+
}
|
|
8864
8903
|
</mat-dialog-content>
|
|
8865
|
-
|
|
8904
|
+
|
|
8866
8905
|
<mat-dialog-actions align="end" class="sticky-actions">
|
|
8867
8906
|
<!-- ACTIONS: PROMPT -->
|
|
8868
|
-
|
|
8907
|
+
@if (currentStep === 'prompt') {
|
|
8869
8908
|
<button mat-button mat-dialog-close [disabled]="isGenerating">Cancelar</button>
|
|
8870
|
-
<button
|
|
8871
|
-
mat-flat-button
|
|
8872
|
-
color="primary"
|
|
8873
|
-
(click)="generate()"
|
|
8909
|
+
<button
|
|
8910
|
+
mat-flat-button
|
|
8911
|
+
color="primary"
|
|
8912
|
+
(click)="generate()"
|
|
8874
8913
|
[disabled]="!userPrompt.trim() || isGenerating"
|
|
8875
|
-
|
|
8914
|
+
>
|
|
8876
8915
|
<mat-icon>auto_awesome</mat-icon>
|
|
8877
8916
|
Gerar Regra
|
|
8878
8917
|
</button>
|
|
8879
|
-
|
|
8880
|
-
|
|
8918
|
+
}
|
|
8919
|
+
|
|
8881
8920
|
<!-- ACTIONS: REVIEW -->
|
|
8882
|
-
|
|
8921
|
+
@if (currentStep === 'review') {
|
|
8883
8922
|
<button mat-button (click)="backToPrompt()">
|
|
8884
8923
|
<mat-icon>arrow_back</mat-icon>
|
|
8885
8924
|
Refinar Prompt
|
|
8886
8925
|
</button>
|
|
8887
|
-
<button
|
|
8888
|
-
mat-flat-button
|
|
8889
|
-
color="primary"
|
|
8926
|
+
<button
|
|
8927
|
+
mat-flat-button
|
|
8928
|
+
color="primary"
|
|
8890
8929
|
(click)="confirm()"
|
|
8891
|
-
|
|
8930
|
+
>
|
|
8892
8931
|
<mat-icon>check</mat-icon>
|
|
8893
8932
|
Aplicar Regra
|
|
8894
8933
|
</button>
|
|
8895
|
-
|
|
8934
|
+
}
|
|
8896
8935
|
</mat-dialog-actions>
|
|
8897
8936
|
</div>
|
|
8898
|
-
`, isInline: true, styles: [".ai-wizard-container{position:relative;padding-bottom:0;max-height:85vh;display:flex;flex-direction:column}.wizard-title{display:flex;align-items:center;gap:12px;color:#673ab7;margin:0;padding:20px 24px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);z-index:1}.step-badge{font-size:12px;background:#673ab71a;padding:2px 8px;border-radius:12px;margin-left:auto}.ai-icon{color:#673ab7}.wizard-content{flex:1;overflow-y:auto;padding:0;min-height:300px}.step-prompt,.step-review{padding:20px 24px}.intro-text{color:var(--md-sys-color-on-surface-variant);margin-bottom:24px;font-size:14px}.form-row{display:flex;gap:16px;margin-bottom:8px}.type-select{width:200px}.prompt-input{width:100%}.properties-panel{margin-top:16px;box-shadow:none;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px!important}.suggestions-card{border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;padding:12px;margin:12px 0 4px;background:var(--md-sys-color-surface-container-low)}.suggestions-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;gap:8px}.suggestions-header .title{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px}.suggestions-body{display:flex;flex-wrap:wrap;gap:8px}.suggestion-chip{cursor:pointer;max-width:100%;white-space:normal;line-height:1.3}.suggestions-loading,.suggestions-empty{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:13px}.properties-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;padding:8px 0}.prop-item{font-size:12px;display:flex;align-items:center;gap:6px}.prop-name{font-weight:600;font-family:monospace}.prop-type{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);padding:2px 6px;border-radius:4px;font-size:10px}.prop-desc{color:var(--md-sys-color-on-surface-variant);font-style:italic}.review-header{margin-bottom:20px;border-bottom:1px solid var(--md-sys-color-outline-variant);padding-bottom:12px}.review-header h3{margin:0 0 8px;font-size:18px}.target-badges{display:flex;gap:8px}.badge-type{background:#e0e0e0;color:#424242;padding:2px 8px;border-radius:4px;font-size:11px;text-transform:uppercase;font-weight:700}.badge-id{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);padding:2px 8px;border-radius:4px;font-size:12px;font-family:monospace}.warnings-box{background:#fff8e1;border:1px solid #ffecb3;border-radius:8px;padding:12px;margin-bottom:16px}.warning-title{display:flex;align-items:center;gap:8px;color:#f57f17;font-weight:600;font-size:13px;margin-bottom:8px}.warning-title mat-icon{font-size:18px;width:18px;height:18px}.warning-list{margin:0;padding-left:24px;font-size:13px;color:#5d4037}.summary-view{padding:16px;background:var(--md-sys-color-surface-container-low);border-radius:8px;margin-top:12px}.summary-row{margin-bottom:12px}.summary-row:last-child{margin-bottom:0}.label{display:block;font-size:11px;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);margin-bottom:4px}.value{font-size:14px}.value.condition{font-family:monospace;color:var(--md-sys-color-primary);background:#00000008;padding:2px 4px;border-radius:4px}.props-grid{display:flex;flex-wrap:wrap;gap:12px}.prop-pair{background:#fff;border:1px solid var(--md-sys-color-outline-variant);padding:4px 8px;border-radius:4px;font-size:13px}.p-key{font-weight:600;margin-right:4px}.p-val{color:var(--md-sys-color-primary)}.json-preview{background:#f5f5f5;padding:12px;border-radius:8px;font-size:12px;max-height:300px;overflow:auto;margin-top:12px}.error-box{margin-top:16px;padding:12px;background-color:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:8px;display:flex;align-items:flex-start;gap:12px;font-size:13px}.ai-processing-overlay{position:absolute;inset:0;background:#ffffffd9;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;border-radius:8px}.sparkle-icon{font-size:48px;width:48px;height:48px;color:#673ab7;animation:ai-pulse 2s infinite;z-index:2}.ai-pulse-ring{position:absolute;width:80px;height:80px;border-radius:50%;background:radial-gradient(circle,#673ab733,#673ab700 70%);animation:ai-ripple 2s infinite;z-index:1}.processing-text{text-align:center;z-index:2}.processing-text h3{margin:0 0 8px;color:#311b92;font-size:18px;font-weight:500}.fade-text{margin:0;color:#673ab7;font-size:14px;font-style:italic;min-height:20px;animation:text-fade .5s ease-in-out}@keyframes ai-pulse{0%{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}50%{transform:scale(1.1);opacity:.8;text-shadow:0 0 20px rgba(103,58,183,.8)}to{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}}@keyframes ai-ripple{0%{transform:scale(.8);opacity:.6}to{transform:scale(2.5);opacity:0}}@keyframes text-fade{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i11$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i12.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i14.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i14.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i14.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i15.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i15.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i16.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i16.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: StreamingFeedbackComponent, selector: "praxis-ai-streaming-feedback", inputs: ["title", "displayText", "isThinking"] }, { kind: "pipe", type: i3.JsonPipe, name: "json" }] });
|
|
8937
|
+
`, isInline: true, styles: [".ai-wizard-container{position:relative;padding-bottom:0;max-height:85vh;display:flex;flex-direction:column}.wizard-title{display:flex;align-items:center;gap:12px;color:#673ab7;margin:0;padding:20px 24px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);z-index:1}.step-badge{font-size:12px;background:#673ab71a;padding:2px 8px;border-radius:12px;margin-left:auto}.ai-icon{color:#673ab7}.wizard-content{flex:1;overflow-y:auto;padding:0;min-height:300px}.step-prompt,.step-review{padding:20px 24px}.intro-text{color:var(--md-sys-color-on-surface-variant);margin-bottom:24px;font-size:14px}.form-row{display:flex;gap:16px;margin-bottom:8px}.type-select{width:200px}.prompt-input{width:100%}.properties-panel{margin-top:16px;box-shadow:none;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px!important}.suggestions-card{border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;padding:12px;margin:12px 0 4px;background:var(--md-sys-color-surface-container-low)}.suggestions-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;gap:8px}.suggestions-header .title{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px}.suggestions-body{display:flex;flex-wrap:wrap;gap:8px}.suggestion-chip{cursor:pointer;max-width:100%;white-space:normal;line-height:1.3}.suggestions-loading,.suggestions-empty{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:13px}.properties-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;padding:8px 0}.prop-item{font-size:12px;display:flex;align-items:center;gap:6px}.prop-name{font-weight:600;font-family:monospace}.prop-type{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);padding:2px 6px;border-radius:4px;font-size:10px}.prop-desc{color:var(--md-sys-color-on-surface-variant);font-style:italic}.review-header{margin-bottom:20px;border-bottom:1px solid var(--md-sys-color-outline-variant);padding-bottom:12px}.review-header h3{margin:0 0 8px;font-size:18px}.target-badges{display:flex;gap:8px}.badge-type{background:#e0e0e0;color:#424242;padding:2px 8px;border-radius:4px;font-size:11px;text-transform:uppercase;font-weight:700}.badge-id{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);padding:2px 8px;border-radius:4px;font-size:12px;font-family:monospace}.warnings-box{background:#fff8e1;border:1px solid #ffecb3;border-radius:8px;padding:12px;margin-bottom:16px}.warning-title{display:flex;align-items:center;gap:8px;color:#f57f17;font-weight:600;font-size:13px;margin-bottom:8px}.warning-title mat-icon{font-size:18px;width:18px;height:18px}.warning-list{margin:0;padding-left:24px;font-size:13px;color:#5d4037}.summary-view{padding:16px;background:var(--md-sys-color-surface-container-low);border-radius:8px;margin-top:12px}.summary-row{margin-bottom:12px}.summary-row:last-child{margin-bottom:0}.label{display:block;font-size:11px;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);margin-bottom:4px}.value{font-size:14px}.value.condition{font-family:monospace;color:var(--md-sys-color-primary);background:#00000008;padding:2px 4px;border-radius:4px}.props-grid{display:flex;flex-wrap:wrap;gap:12px}.prop-pair{background:#fff;border:1px solid var(--md-sys-color-outline-variant);padding:4px 8px;border-radius:4px;font-size:13px}.p-key{font-weight:600;margin-right:4px}.p-val{color:var(--md-sys-color-primary)}.json-preview{background:#f5f5f5;padding:12px;border-radius:8px;font-size:12px;max-height:300px;overflow:auto;margin-top:12px}.error-box{margin-top:16px;padding:12px;background-color:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:8px;display:flex;align-items:flex-start;gap:12px;font-size:13px}.ai-processing-overlay{position:absolute;inset:0;background:#ffffffd9;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;border-radius:8px}.sparkle-icon{font-size:48px;width:48px;height:48px;color:#673ab7;animation:ai-pulse 2s infinite;z-index:2}.ai-pulse-ring{position:absolute;width:80px;height:80px;border-radius:50%;background:radial-gradient(circle,#673ab733,#673ab700 70%);animation:ai-ripple 2s infinite;z-index:1}.processing-text{text-align:center;z-index:2}.processing-text h3{margin:0 0 8px;color:#311b92;font-size:18px;font-weight:500}.fade-text{margin:0;color:#673ab7;font-size:14px;font-style:italic;min-height:20px;animation:text-fade .5s ease-in-out}@keyframes ai-pulse{0%{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}50%{transform:scale(1.1);opacity:.8;text-shadow:0 0 20px rgba(103,58,183,.8)}to{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}}@keyframes ai-ripple{0%{transform:scale(.8);opacity:.6}to{transform:scale(2.5);opacity:0}}@keyframes text-fade{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i10$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i11.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i11.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i13.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i13.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i13.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i14.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i14.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i15.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: StreamingFeedbackComponent, selector: "praxis-ai-streaming-feedback", inputs: ["title", "displayText", "isThinking"] }, { kind: "pipe", type: i1$3.JsonPipe, name: "json" }] });
|
|
8899
8938
|
}
|
|
8900
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
8939
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiRuleWizardDialogComponent, decorators: [{
|
|
8901
8940
|
type: Component,
|
|
8902
8941
|
args: [{ selector: 'praxis-ai-rule-wizard-dialog', standalone: true, imports: [
|
|
8903
8942
|
CommonModule,
|
|
@@ -8919,194 +8958,223 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
8919
8958
|
<h2 mat-dialog-title class="wizard-title">
|
|
8920
8959
|
<mat-icon class="ai-icon">auto_awesome</mat-icon>
|
|
8921
8960
|
<span>Criar Regra com IA</span>
|
|
8922
|
-
|
|
8961
|
+
@if (currentStep === 'review') {
|
|
8962
|
+
<span class="step-badge">Revisão</span>
|
|
8963
|
+
}
|
|
8923
8964
|
</h2>
|
|
8924
|
-
|
|
8965
|
+
|
|
8925
8966
|
<mat-dialog-content class="wizard-content">
|
|
8926
|
-
|
|
8967
|
+
|
|
8927
8968
|
<!-- STEP 1: PROMPT -->
|
|
8928
|
-
|
|
8929
|
-
<
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8969
|
+
@if (currentStep === 'prompt') {
|
|
8970
|
+
<div class="step-prompt">
|
|
8971
|
+
<p class="intro-text">
|
|
8972
|
+
Descreva a regra que você deseja criar em linguagem natural e a IA irá gerar a configuração para você revisar.
|
|
8973
|
+
</p>
|
|
8974
|
+
<div class="form-row">
|
|
8975
|
+
<mat-form-field appearance="outline" class="type-select">
|
|
8976
|
+
<mat-label>Tipo de Alvo</mat-label>
|
|
8977
|
+
<mat-select [(ngModel)]="selectedTargetType" (selectionChange)="onTargetTypeChange()">
|
|
8978
|
+
<mat-option value="field">Campo (Field)</mat-option>
|
|
8979
|
+
<mat-option value="section">Seção (Section)</mat-option>
|
|
8980
|
+
<mat-option value="action">Ação (Action)</mat-option>
|
|
8981
|
+
<mat-option value="row">Linha (Row)</mat-option>
|
|
8982
|
+
<mat-option value="column">Coluna (Column)</mat-option>
|
|
8983
|
+
</mat-select>
|
|
8984
|
+
</mat-form-field>
|
|
8985
|
+
</div>
|
|
8986
|
+
<mat-form-field appearance="outline" class="prompt-input">
|
|
8987
|
+
<mat-label>Descreva sua regra</mat-label>
|
|
8988
|
+
<textarea
|
|
8989
|
+
matInput
|
|
8990
|
+
[(ngModel)]="userPrompt"
|
|
8991
|
+
rows="6"
|
|
8992
|
+
placeholder="Ex: Esconder o campo telefone se a idade for menor que 18 anos..."
|
|
8993
|
+
[disabled]="isGenerating"
|
|
8994
|
+
></textarea>
|
|
8995
|
+
<mat-hint align="end">{{userPrompt.length}} caracteres</mat-hint>
|
|
8943
8996
|
</mat-form-field>
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
[disabled]="isGenerating"
|
|
8954
|
-
></textarea>
|
|
8955
|
-
<mat-hint align="end">{{userPrompt.length}} caracteres</mat-hint>
|
|
8956
|
-
</mat-form-field>
|
|
8957
|
-
|
|
8958
|
-
<div class="suggestions-card" data-testid="ai-suggestions">
|
|
8959
|
-
<div class="suggestions-header">
|
|
8960
|
-
<div class="title">
|
|
8961
|
-
<mat-icon>lightbulb</mat-icon>
|
|
8962
|
-
Sugestões da IA
|
|
8997
|
+
<div class="suggestions-card" data-testid="ai-suggestions">
|
|
8998
|
+
<div class="suggestions-header">
|
|
8999
|
+
<div class="title">
|
|
9000
|
+
<mat-icon>lightbulb</mat-icon>
|
|
9001
|
+
Sugestões da IA
|
|
9002
|
+
</div>
|
|
9003
|
+
<button mat-icon-button type="button" (click)="reloadSuggestions()" [disabled]="loadingSuggestions">
|
|
9004
|
+
<mat-icon>refresh</mat-icon>
|
|
9005
|
+
</button>
|
|
8963
9006
|
</div>
|
|
8964
|
-
|
|
8965
|
-
<
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
9007
|
+
@if (!loadingSuggestions && suggestions.length > 0) {
|
|
9008
|
+
<div class="suggestions-body">
|
|
9009
|
+
<mat-chip-set aria-label="Sugestões de regras">
|
|
9010
|
+
@for (suggestion of suggestions; track suggestion) {
|
|
9011
|
+
<mat-chip (click)="applySuggestion(suggestion)" class="suggestion-chip">
|
|
9012
|
+
{{ suggestion }}
|
|
9013
|
+
</mat-chip>
|
|
9014
|
+
}
|
|
9015
|
+
</mat-chip-set>
|
|
9016
|
+
</div>
|
|
9017
|
+
} @else {
|
|
9018
|
+
@if (loadingSuggestions) {
|
|
9019
|
+
<div class="suggestions-loading">
|
|
9020
|
+
<mat-progress-spinner diameter="20" mode="indeterminate"></mat-progress-spinner>
|
|
9021
|
+
<span>Gerando sugestões...</span>
|
|
9022
|
+
</div>
|
|
9023
|
+
}
|
|
9024
|
+
@if (!loadingSuggestions && suggestions.length === 0) {
|
|
9025
|
+
<div class="suggestions-empty">
|
|
9026
|
+
Nenhuma sugestão disponível no momento.
|
|
9027
|
+
</div>
|
|
9028
|
+
}
|
|
9029
|
+
}
|
|
8974
9030
|
</div>
|
|
8975
|
-
<
|
|
8976
|
-
<
|
|
8977
|
-
<mat-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
9031
|
+
<mat-expansion-panel class="properties-panel">
|
|
9032
|
+
<mat-expansion-panel-header>
|
|
9033
|
+
<mat-panel-title>
|
|
9034
|
+
<mat-icon>info</mat-icon>
|
|
9035
|
+
Ver propriedades disponíveis
|
|
9036
|
+
</mat-panel-title>
|
|
9037
|
+
</mat-expansion-panel-header>
|
|
9038
|
+
<div class="properties-list">
|
|
9039
|
+
@for (prop of getAvailableProperties(); track prop) {
|
|
9040
|
+
<div class="prop-item">
|
|
9041
|
+
<span class="prop-name">{{prop.name}}</span>
|
|
9042
|
+
<span class="prop-type">{{prop.type}}</span>
|
|
9043
|
+
@if (prop.label) {
|
|
9044
|
+
<span class="prop-desc">- {{prop.label}}</span>
|
|
9045
|
+
}
|
|
9046
|
+
</div>
|
|
9047
|
+
}
|
|
8982
9048
|
</div>
|
|
8983
|
-
</
|
|
9049
|
+
</mat-expansion-panel>
|
|
8984
9050
|
</div>
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
<mat-expansion-panel-header>
|
|
8988
|
-
<mat-panel-title>
|
|
8989
|
-
<mat-icon>info</mat-icon>
|
|
8990
|
-
Ver propriedades disponíveis
|
|
8991
|
-
</mat-panel-title>
|
|
8992
|
-
</mat-expansion-panel-header>
|
|
8993
|
-
<div class="properties-list">
|
|
8994
|
-
<div *ngFor="let prop of getAvailableProperties()" class="prop-item">
|
|
8995
|
-
<span class="prop-name">{{prop.name}}</span>
|
|
8996
|
-
<span class="prop-type">{{prop.type}}</span>
|
|
8997
|
-
<span class="prop-desc" *ngIf="prop.label">- {{prop.label}}</span>
|
|
8998
|
-
</div>
|
|
8999
|
-
</div>
|
|
9000
|
-
</mat-expansion-panel>
|
|
9001
|
-
</div>
|
|
9002
|
-
|
|
9051
|
+
}
|
|
9052
|
+
|
|
9003
9053
|
<!-- STEP 2: REVIEW -->
|
|
9004
|
-
|
|
9005
|
-
<div class="review
|
|
9006
|
-
<
|
|
9007
|
-
|
|
9008
|
-
<
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
<div class="warning-title">
|
|
9015
|
-
<mat-icon>auto_fix_high</mat-icon>
|
|
9016
|
-
Correções Automáticas
|
|
9054
|
+
@if (currentStep === 'review' && generatedResponse) {
|
|
9055
|
+
<div class="step-review">
|
|
9056
|
+
<div class="review-header">
|
|
9057
|
+
<h3>{{ generatedResponse.ruleName }}</h3>
|
|
9058
|
+
<div class="target-badges">
|
|
9059
|
+
<span class="badge-type">{{ generatedResponse.targetType }}</span>
|
|
9060
|
+
@for (id of generatedResponse.targetIds; track id) {
|
|
9061
|
+
<span class="badge-id">{{ id }}</span>
|
|
9062
|
+
}
|
|
9063
|
+
</div>
|
|
9017
9064
|
</div>
|
|
9018
|
-
|
|
9019
|
-
<
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
</div>
|
|
9024
|
-
|
|
9025
|
-
<mat-tab-group class="preview-tabs" animationDuration="0ms">
|
|
9026
|
-
<mat-tab label="Resumo">
|
|
9027
|
-
<div class="summary-view">
|
|
9028
|
-
<div class="summary-row">
|
|
9029
|
-
<span class="label">Condição:</span>
|
|
9030
|
-
<code class="value condition" *ngIf="generatedResponse.condition">{{ generatedResponse.condition | json }}</code>
|
|
9031
|
-
<span class="value" *ngIf="!generatedResponse.condition"><em>(Sempre aplicada)</em></span>
|
|
9065
|
+
@if (warnings.length > 0) {
|
|
9066
|
+
<div class="warnings-box">
|
|
9067
|
+
<div class="warning-title">
|
|
9068
|
+
<mat-icon>auto_fix_high</mat-icon>
|
|
9069
|
+
Correções Automáticas
|
|
9032
9070
|
</div>
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9071
|
+
<ul class="warning-list">
|
|
9072
|
+
@for (w of warnings; track w) {
|
|
9073
|
+
<li>
|
|
9074
|
+
{{ w.message }}
|
|
9075
|
+
</li>
|
|
9076
|
+
}
|
|
9077
|
+
</ul>
|
|
9078
|
+
</div>
|
|
9079
|
+
}
|
|
9080
|
+
<mat-tab-group class="preview-tabs" animationDuration="0ms">
|
|
9081
|
+
<mat-tab label="Resumo">
|
|
9082
|
+
<div class="summary-view">
|
|
9083
|
+
<div class="summary-row">
|
|
9084
|
+
<span class="label">Condição:</span>
|
|
9085
|
+
@if (generatedResponse.condition) {
|
|
9086
|
+
<code class="value condition">{{ generatedResponse.condition | json }}</code>
|
|
9087
|
+
}
|
|
9088
|
+
@if (!generatedResponse.condition) {
|
|
9089
|
+
<span class="value"><em>(Sempre aplicada)</em></span>
|
|
9090
|
+
}
|
|
9042
9091
|
</div>
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9092
|
+
<div class="summary-row">
|
|
9093
|
+
<span class="label">Propriedades (True):</span>
|
|
9094
|
+
<div class="props-grid">
|
|
9095
|
+
@for (p of getProps(generatedResponse.effects.properties); track p) {
|
|
9096
|
+
<div class="prop-pair">
|
|
9097
|
+
<span class="p-key">{{p.key}}:</span>
|
|
9098
|
+
<span class="p-val">{{p.value}}</span>
|
|
9099
|
+
</div>
|
|
9100
|
+
}
|
|
9101
|
+
@if (!hasProps(generatedResponse.effects.properties)) {
|
|
9102
|
+
<span>-</span>
|
|
9103
|
+
}
|
|
9051
9104
|
</div>
|
|
9052
9105
|
</div>
|
|
9106
|
+
@if (hasProps(generatedResponse.effects.propertiesWhenFalse)) {
|
|
9107
|
+
<div class="summary-row">
|
|
9108
|
+
<span class="label">Propriedades (False):</span>
|
|
9109
|
+
<div class="props-grid">
|
|
9110
|
+
@for (p of getProps(generatedResponse.effects.propertiesWhenFalse); track p) {
|
|
9111
|
+
<div class="prop-pair">
|
|
9112
|
+
<span class="p-key">{{p.key}}:</span>
|
|
9113
|
+
<span class="p-val">{{p.value}}</span>
|
|
9114
|
+
</div>
|
|
9115
|
+
}
|
|
9116
|
+
</div>
|
|
9117
|
+
</div>
|
|
9118
|
+
}
|
|
9053
9119
|
</div>
|
|
9054
|
-
</
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
</mat-tab>
|
|
9059
|
-
</
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9120
|
+
</mat-tab>
|
|
9121
|
+
<mat-tab label="JSON">
|
|
9122
|
+
<pre class="json-preview">{{ generatedResponse | json }}</pre>
|
|
9123
|
+
</mat-tab>
|
|
9124
|
+
</mat-tab-group>
|
|
9125
|
+
</div>
|
|
9126
|
+
}
|
|
9127
|
+
|
|
9063
9128
|
<!-- COMMON: LOADING & ERROR -->
|
|
9064
|
-
|
|
9065
|
-
<
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9129
|
+
@if (validationError) {
|
|
9130
|
+
<div class="error-box">
|
|
9131
|
+
<mat-icon>error</mat-icon>
|
|
9132
|
+
<span>{{validationError}}</span>
|
|
9133
|
+
</div>
|
|
9134
|
+
}
|
|
9135
|
+
|
|
9136
|
+
@if (isGenerating) {
|
|
9137
|
+
<praxis-ai-streaming-feedback
|
|
9138
|
+
[displayText]="streamingText || currentLoadingMessage"
|
|
9139
|
+
[isThinking]="true"
|
|
9140
|
+
[title]="'Criando sua regra...'"
|
|
9141
|
+
></praxis-ai-streaming-feedback>
|
|
9142
|
+
}
|
|
9075
9143
|
</mat-dialog-content>
|
|
9076
|
-
|
|
9144
|
+
|
|
9077
9145
|
<mat-dialog-actions align="end" class="sticky-actions">
|
|
9078
9146
|
<!-- ACTIONS: PROMPT -->
|
|
9079
|
-
|
|
9147
|
+
@if (currentStep === 'prompt') {
|
|
9080
9148
|
<button mat-button mat-dialog-close [disabled]="isGenerating">Cancelar</button>
|
|
9081
|
-
<button
|
|
9082
|
-
mat-flat-button
|
|
9083
|
-
color="primary"
|
|
9084
|
-
(click)="generate()"
|
|
9149
|
+
<button
|
|
9150
|
+
mat-flat-button
|
|
9151
|
+
color="primary"
|
|
9152
|
+
(click)="generate()"
|
|
9085
9153
|
[disabled]="!userPrompt.trim() || isGenerating"
|
|
9086
|
-
|
|
9154
|
+
>
|
|
9087
9155
|
<mat-icon>auto_awesome</mat-icon>
|
|
9088
9156
|
Gerar Regra
|
|
9089
9157
|
</button>
|
|
9090
|
-
|
|
9091
|
-
|
|
9158
|
+
}
|
|
9159
|
+
|
|
9092
9160
|
<!-- ACTIONS: REVIEW -->
|
|
9093
|
-
|
|
9161
|
+
@if (currentStep === 'review') {
|
|
9094
9162
|
<button mat-button (click)="backToPrompt()">
|
|
9095
9163
|
<mat-icon>arrow_back</mat-icon>
|
|
9096
9164
|
Refinar Prompt
|
|
9097
9165
|
</button>
|
|
9098
|
-
<button
|
|
9099
|
-
mat-flat-button
|
|
9100
|
-
color="primary"
|
|
9166
|
+
<button
|
|
9167
|
+
mat-flat-button
|
|
9168
|
+
color="primary"
|
|
9101
9169
|
(click)="confirm()"
|
|
9102
|
-
|
|
9170
|
+
>
|
|
9103
9171
|
<mat-icon>check</mat-icon>
|
|
9104
9172
|
Aplicar Regra
|
|
9105
9173
|
</button>
|
|
9106
|
-
|
|
9174
|
+
}
|
|
9107
9175
|
</mat-dialog-actions>
|
|
9108
9176
|
</div>
|
|
9109
|
-
|
|
9177
|
+
`, styles: [".ai-wizard-container{position:relative;padding-bottom:0;max-height:85vh;display:flex;flex-direction:column}.wizard-title{display:flex;align-items:center;gap:12px;color:#673ab7;margin:0;padding:20px 24px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);z-index:1}.step-badge{font-size:12px;background:#673ab71a;padding:2px 8px;border-radius:12px;margin-left:auto}.ai-icon{color:#673ab7}.wizard-content{flex:1;overflow-y:auto;padding:0;min-height:300px}.step-prompt,.step-review{padding:20px 24px}.intro-text{color:var(--md-sys-color-on-surface-variant);margin-bottom:24px;font-size:14px}.form-row{display:flex;gap:16px;margin-bottom:8px}.type-select{width:200px}.prompt-input{width:100%}.properties-panel{margin-top:16px;box-shadow:none;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px!important}.suggestions-card{border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;padding:12px;margin:12px 0 4px;background:var(--md-sys-color-surface-container-low)}.suggestions-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;gap:8px}.suggestions-header .title{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px}.suggestions-body{display:flex;flex-wrap:wrap;gap:8px}.suggestion-chip{cursor:pointer;max-width:100%;white-space:normal;line-height:1.3}.suggestions-loading,.suggestions-empty{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:13px}.properties-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;padding:8px 0}.prop-item{font-size:12px;display:flex;align-items:center;gap:6px}.prop-name{font-weight:600;font-family:monospace}.prop-type{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);padding:2px 6px;border-radius:4px;font-size:10px}.prop-desc{color:var(--md-sys-color-on-surface-variant);font-style:italic}.review-header{margin-bottom:20px;border-bottom:1px solid var(--md-sys-color-outline-variant);padding-bottom:12px}.review-header h3{margin:0 0 8px;font-size:18px}.target-badges{display:flex;gap:8px}.badge-type{background:#e0e0e0;color:#424242;padding:2px 8px;border-radius:4px;font-size:11px;text-transform:uppercase;font-weight:700}.badge-id{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);padding:2px 8px;border-radius:4px;font-size:12px;font-family:monospace}.warnings-box{background:#fff8e1;border:1px solid #ffecb3;border-radius:8px;padding:12px;margin-bottom:16px}.warning-title{display:flex;align-items:center;gap:8px;color:#f57f17;font-weight:600;font-size:13px;margin-bottom:8px}.warning-title mat-icon{font-size:18px;width:18px;height:18px}.warning-list{margin:0;padding-left:24px;font-size:13px;color:#5d4037}.summary-view{padding:16px;background:var(--md-sys-color-surface-container-low);border-radius:8px;margin-top:12px}.summary-row{margin-bottom:12px}.summary-row:last-child{margin-bottom:0}.label{display:block;font-size:11px;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);margin-bottom:4px}.value{font-size:14px}.value.condition{font-family:monospace;color:var(--md-sys-color-primary);background:#00000008;padding:2px 4px;border-radius:4px}.props-grid{display:flex;flex-wrap:wrap;gap:12px}.prop-pair{background:#fff;border:1px solid var(--md-sys-color-outline-variant);padding:4px 8px;border-radius:4px;font-size:13px}.p-key{font-weight:600;margin-right:4px}.p-val{color:var(--md-sys-color-primary)}.json-preview{background:#f5f5f5;padding:12px;border-radius:8px;font-size:12px;max-height:300px;overflow:auto;margin-top:12px}.error-box{margin-top:16px;padding:12px;background-color:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:8px;display:flex;align-items:flex-start;gap:12px;font-size:13px}.ai-processing-overlay{position:absolute;inset:0;background:#ffffffd9;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;border-radius:8px}.sparkle-icon{font-size:48px;width:48px;height:48px;color:#673ab7;animation:ai-pulse 2s infinite;z-index:2}.ai-pulse-ring{position:absolute;width:80px;height:80px;border-radius:50%;background:radial-gradient(circle,#673ab733,#673ab700 70%);animation:ai-ripple 2s infinite;z-index:1}.processing-text{text-align:center;z-index:2}.processing-text h3{margin:0 0 8px;color:#311b92;font-size:18px;font-weight:500}.fade-text{margin:0;color:#673ab7;font-size:14px;font-style:italic;min-height:20px;animation:text-fade .5s ease-in-out}@keyframes ai-pulse{0%{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}50%{transform:scale(1.1);opacity:.8;text-shadow:0 0 20px rgba(103,58,183,.8)}to{transform:scale(1);opacity:1;text-shadow:0 0 10px rgba(103,58,183,.5)}}@keyframes ai-ripple{0%{transform:scale(.8);opacity:.6}to{transform:scale(2.5);opacity:0}}@keyframes text-fade{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
9110
9178
|
}], ctorParameters: () => [{ type: i1$1.MatDialogRef }, { type: undefined, decorators: [{
|
|
9111
9179
|
type: Inject,
|
|
9112
9180
|
args: [MAT_DIALOG_DATA]
|