@praxisui/ai 8.0.0-beta.103 → 8.0.0-beta.105
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 +2 -0
- package/fesm2022/praxisui-ai.mjs +493 -79
- package/package.json +2 -2
- package/types/praxisui-ai.d.ts +81 -9
package/fesm2022/praxisui-ai.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Component, Injectable, InjectionToken, Optional, Inject, inject, signal, computed, ChangeDetectorRef, ElementRef, ViewChild, Input, ChangeDetectionStrategy, EventEmitter, Injector, Output, booleanAttribute } from '@angular/core';
|
|
3
3
|
import { SchemaType, GoogleGenerativeAI } from '@google/generative-ai';
|
|
4
|
-
import { throwError, from, Observable, of, defer, switchMap, Subject, map as map$1, finalize, share, filter as filter$1, concat, merge, EMPTY, timer, takeUntil, BehaviorSubject,
|
|
4
|
+
import { throwError, from, Observable, of, defer, switchMap, Subject, map as map$1, finalize, share, filter as filter$1, concat, merge, EMPTY, timer, takeUntil, BehaviorSubject, catchError as catchError$1, tap, isObservable, firstValueFrom } from 'rxjs';
|
|
5
5
|
import { map, catchError, filter, take } from 'rxjs/operators';
|
|
6
6
|
import { HttpClient, HttpParams, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
|
|
7
|
-
import { API_URL } from '@praxisui/core';
|
|
7
|
+
import { API_URL, PraxisRuntimeComponentObservationRegistryService } from '@praxisui/core';
|
|
8
8
|
import * as i1$3 from '@angular/common';
|
|
9
9
|
import { NgTemplateOutlet, DatePipe, JsonPipe, CommonModule } from '@angular/common';
|
|
10
10
|
import * as i3 from '@angular/forms';
|
|
@@ -403,7 +403,7 @@ function toPraxisAssistantConversationMessageRole(role) {
|
|
|
403
403
|
* Do not edit manually. Run praxis-config-starter/tools/contracts/generate-ai-contract-bindings.js.
|
|
404
404
|
*/
|
|
405
405
|
const AI_CONTRACT_VERSION = 'v1.1';
|
|
406
|
-
const AI_CONTRACT_SCHEMA_HASH = '
|
|
406
|
+
const AI_CONTRACT_SCHEMA_HASH = 'daab9623a5c4d660105dfe1c85a6bd1ee1ef1b54ef5981e26d27c44aa82ddb4f';
|
|
407
407
|
const AI_STREAM_EVENT_SCHEMA_VERSION = 'v1';
|
|
408
408
|
const AI_DOMAIN_CATALOG_CONTEXT_HINT_SCHEMA_VERSION = 'praxis.ai.context-hints.domain-catalog/v0.2';
|
|
409
409
|
const AI_STREAM_EVENT_TYPES = ['status', 'thought.step', 'heartbeat', 'result', 'error', 'cancelled'];
|
|
@@ -1222,6 +1222,7 @@ class AiBackendApiService {
|
|
|
1222
1222
|
const probeEndpoint = `${streamPath}/probe${accessToken?.trim()
|
|
1223
1223
|
? `?accessToken=${encodeURIComponent(accessToken.trim())}`
|
|
1224
1224
|
: ''}`;
|
|
1225
|
+
const shouldUseFetchTransport = this.hasExplicitHeaders(options.headers);
|
|
1225
1226
|
let source = null;
|
|
1226
1227
|
let streamAbort = null;
|
|
1227
1228
|
const events$ = new Observable((subscriber) => {
|
|
@@ -1237,7 +1238,7 @@ class AiBackendApiService {
|
|
|
1237
1238
|
}
|
|
1238
1239
|
};
|
|
1239
1240
|
const openStream = async () => {
|
|
1240
|
-
if (typeof EventSource === 'undefined') {
|
|
1241
|
+
if (typeof EventSource === 'undefined' || shouldUseFetchTransport) {
|
|
1241
1242
|
if (typeof fetch === 'function' && typeof TextDecoder !== 'undefined') {
|
|
1242
1243
|
streamAbort = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
1243
1244
|
options.onLifecycle?.({
|
|
@@ -1245,7 +1246,7 @@ class AiBackendApiService {
|
|
|
1245
1246
|
transport: 'fetch',
|
|
1246
1247
|
connectElapsedMs: Math.max(0, Date.now() - connectStartedAt),
|
|
1247
1248
|
});
|
|
1248
|
-
void this.consumeFetchAgenticTurnStream(endpoint, streamAbort, (messageEvent) => handleMessage(messageEvent), () => disposed).catch((error) => {
|
|
1249
|
+
void this.consumeFetchAgenticTurnStream(endpoint, options.headers, streamAbort, (messageEvent) => handleMessage(messageEvent), () => disposed).catch((error) => {
|
|
1249
1250
|
if (disposed) {
|
|
1250
1251
|
return;
|
|
1251
1252
|
}
|
|
@@ -1258,7 +1259,7 @@ class AiBackendApiService {
|
|
|
1258
1259
|
subscriber.error(new AiPatchStreamConnectionError('unsupported', 'EventSource is not supported in this environment.'));
|
|
1259
1260
|
return;
|
|
1260
1261
|
}
|
|
1261
|
-
const probeStatus = await this.probePatchStreamEndpoint(probeEndpoint);
|
|
1262
|
+
const probeStatus = await this.probePatchStreamEndpoint(probeEndpoint, options.headers);
|
|
1262
1263
|
if (disposed) {
|
|
1263
1264
|
return;
|
|
1264
1265
|
}
|
|
@@ -1584,10 +1585,10 @@ class AiBackendApiService {
|
|
|
1584
1585
|
}
|
|
1585
1586
|
return `${this.aiBaseUrl()}/authoring`;
|
|
1586
1587
|
}
|
|
1587
|
-
async consumeFetchAgenticTurnStream(endpoint, abort, handleMessage, disposed) {
|
|
1588
|
+
async consumeFetchAgenticTurnStream(endpoint, headers, abort, handleMessage, disposed) {
|
|
1588
1589
|
const response = await fetch(endpoint, {
|
|
1589
1590
|
method: 'GET',
|
|
1590
|
-
headers: { Accept: 'text/event-stream' },
|
|
1591
|
+
headers: this.buildFetchHeaders(headers, { Accept: 'text/event-stream' }),
|
|
1591
1592
|
credentials: 'include',
|
|
1592
1593
|
cache: 'no-store',
|
|
1593
1594
|
signal: abort?.signal,
|
|
@@ -1646,13 +1647,14 @@ class AiBackendApiService {
|
|
|
1646
1647
|
}
|
|
1647
1648
|
return { index: crlf, length: 4 };
|
|
1648
1649
|
}
|
|
1649
|
-
async probePatchStreamEndpoint(endpoint) {
|
|
1650
|
+
async probePatchStreamEndpoint(endpoint, headers) {
|
|
1650
1651
|
if (typeof fetch === 'undefined') {
|
|
1651
1652
|
return null;
|
|
1652
1653
|
}
|
|
1653
1654
|
try {
|
|
1654
1655
|
const response = await fetch(endpoint, {
|
|
1655
1656
|
method: 'GET',
|
|
1657
|
+
headers: this.buildFetchHeaders(headers),
|
|
1656
1658
|
credentials: 'include',
|
|
1657
1659
|
cache: 'no-store',
|
|
1658
1660
|
});
|
|
@@ -1662,6 +1664,16 @@ class AiBackendApiService {
|
|
|
1662
1664
|
return null;
|
|
1663
1665
|
}
|
|
1664
1666
|
}
|
|
1667
|
+
buildFetchHeaders(extra, overrides) {
|
|
1668
|
+
const { merged } = this.resolveHeaderMap(extra);
|
|
1669
|
+
return { ...merged, ...(overrides ?? {}) };
|
|
1670
|
+
}
|
|
1671
|
+
hasExplicitHeaders(headers) {
|
|
1672
|
+
if (!headers) {
|
|
1673
|
+
return false;
|
|
1674
|
+
}
|
|
1675
|
+
return Object.values(headers).some((value) => typeof value === 'string' && value.trim().length > 0);
|
|
1676
|
+
}
|
|
1665
1677
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiBackendApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1666
1678
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AiBackendApiService, providedIn: 'root' });
|
|
1667
1679
|
}
|
|
@@ -1672,14 +1684,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1672
1684
|
|
|
1673
1685
|
class AgenticAuthoringTurnClientService {
|
|
1674
1686
|
aiApi = inject(AiBackendApiService);
|
|
1687
|
+
runtimeObservationRegistry = inject(PraxisRuntimeComponentObservationRegistryService, { optional: true });
|
|
1675
1688
|
streamEvents(request, options = {}) {
|
|
1676
|
-
return defer(() =>
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1689
|
+
return defer(() => {
|
|
1690
|
+
const startRequest = this.withRuntimeObservationTrustBoundary(request);
|
|
1691
|
+
const start$ = this.isPromiseLike(startRequest)
|
|
1692
|
+
? from(startRequest).pipe(switchMap((resolvedRequest) => this.startAuthoringTurnStream(resolvedRequest, options)))
|
|
1693
|
+
: this.startAuthoringTurnStream(startRequest, options);
|
|
1694
|
+
return start$;
|
|
1695
|
+
}).pipe(switchMap((start) => {
|
|
1680
1696
|
const lifecycle$ = new Subject();
|
|
1681
1697
|
const connection = this.aiApi.connectAgenticAuthoringTurnStream(start.streamId, undefined, start.streamAccessToken ?? undefined, {
|
|
1682
1698
|
baseUrl: options.baseUrl,
|
|
1699
|
+
headers: options.headers,
|
|
1683
1700
|
onLifecycle: (event) => lifecycle$.next(this.toLifecycleEvent(start, event)),
|
|
1684
1701
|
});
|
|
1685
1702
|
const events$ = connection.events$.pipe(map$1((event) => ({ kind: 'stream-event', event })), finalize(() => lifecycle$.complete()), share());
|
|
@@ -1688,6 +1705,7 @@ class AgenticAuthoringTurnClientService {
|
|
|
1688
1705
|
}));
|
|
1689
1706
|
}
|
|
1690
1707
|
streamTurn(request, options = {}) {
|
|
1708
|
+
const clientTurnId = request.clientTurnId;
|
|
1691
1709
|
return this.streamEvents(request, options).pipe(map$1((event) => {
|
|
1692
1710
|
if (event.kind === 'stream-started') {
|
|
1693
1711
|
return {
|
|
@@ -1695,7 +1713,7 @@ class AgenticAuthoringTurnClientService {
|
|
|
1695
1713
|
phase: 'contextualize',
|
|
1696
1714
|
statusText: options.initialStatusText ?? '',
|
|
1697
1715
|
sessionId: event.start.threadId,
|
|
1698
|
-
clientTurnId: event.start.turnId,
|
|
1716
|
+
clientTurnId: clientTurnId ?? event.start.turnId,
|
|
1699
1717
|
observationId: event.start.observationId ?? null,
|
|
1700
1718
|
canApply: false,
|
|
1701
1719
|
};
|
|
@@ -1706,7 +1724,7 @@ class AgenticAuthoringTurnClientService {
|
|
|
1706
1724
|
phase: 'contextualize',
|
|
1707
1725
|
statusText: event.statusText,
|
|
1708
1726
|
sessionId: event.start.threadId,
|
|
1709
|
-
clientTurnId: event.start.turnId,
|
|
1727
|
+
clientTurnId: clientTurnId ?? event.start.turnId,
|
|
1710
1728
|
observationId: event.start.observationId ?? null,
|
|
1711
1729
|
canApply: false,
|
|
1712
1730
|
preview: null,
|
|
@@ -1718,19 +1736,19 @@ class AgenticAuthoringTurnClientService {
|
|
|
1718
1736
|
},
|
|
1719
1737
|
};
|
|
1720
1738
|
}
|
|
1721
|
-
return this.toTurnResult(event.event);
|
|
1739
|
+
return this.toTurnResult(event.event, clientTurnId);
|
|
1722
1740
|
}));
|
|
1723
1741
|
}
|
|
1724
|
-
toTurnResult(event) {
|
|
1742
|
+
toTurnResult(event, clientTurnId) {
|
|
1725
1743
|
const payload = this.toJsonObject(event.payload) ?? {};
|
|
1726
1744
|
const base = {
|
|
1727
1745
|
sessionId: event.threadId,
|
|
1728
|
-
clientTurnId: event.turnId,
|
|
1746
|
+
clientTurnId: clientTurnId ?? event.turnId,
|
|
1729
1747
|
};
|
|
1730
1748
|
if (event.type === 'result') {
|
|
1731
1749
|
return {
|
|
1732
1750
|
...base,
|
|
1733
|
-
...this.toResultTurn(payload),
|
|
1751
|
+
...this.toResultTurn(payload, event),
|
|
1734
1752
|
};
|
|
1735
1753
|
}
|
|
1736
1754
|
if (event.type === 'error') {
|
|
@@ -1771,7 +1789,60 @@ class AgenticAuthoringTurnClientService {
|
|
|
1771
1789
|
diagnostics: { streamEvent: event },
|
|
1772
1790
|
};
|
|
1773
1791
|
}
|
|
1774
|
-
|
|
1792
|
+
withRuntimeObservationTrustBoundary(request) {
|
|
1793
|
+
const runtimeComponentObservations = this.collectRuntimeComponentObservations(request);
|
|
1794
|
+
const build = (collectedObservations) => {
|
|
1795
|
+
const observations = collectedObservations.filter(Boolean);
|
|
1796
|
+
const rest = { ...request };
|
|
1797
|
+
delete rest.runtimeComponentObservations;
|
|
1798
|
+
delete rest.runtimeComponentObservationTrustBoundary;
|
|
1799
|
+
if (observations.length === 0) {
|
|
1800
|
+
return rest;
|
|
1801
|
+
}
|
|
1802
|
+
return {
|
|
1803
|
+
...rest,
|
|
1804
|
+
runtimeComponentObservations: observations,
|
|
1805
|
+
runtimeComponentObservationTrustBoundary: 'untrusted_frontend_observation',
|
|
1806
|
+
};
|
|
1807
|
+
};
|
|
1808
|
+
return this.isPromiseLike(runtimeComponentObservations)
|
|
1809
|
+
? runtimeComponentObservations.then(build)
|
|
1810
|
+
: build(runtimeComponentObservations);
|
|
1811
|
+
}
|
|
1812
|
+
collectRuntimeComponentObservations(request) {
|
|
1813
|
+
if (Array.isArray(request.runtimeComponentObservations)) {
|
|
1814
|
+
return request.runtimeComponentObservations.filter(this.isRuntimeComponentObservationEnvelopeLike);
|
|
1815
|
+
}
|
|
1816
|
+
if (!this.runtimeObservationRegistry) {
|
|
1817
|
+
return [];
|
|
1818
|
+
}
|
|
1819
|
+
if (typeof this.runtimeObservationRegistry.registeredCount === 'function' &&
|
|
1820
|
+
this.runtimeObservationRegistry.registeredCount() === 0) {
|
|
1821
|
+
return [];
|
|
1822
|
+
}
|
|
1823
|
+
try {
|
|
1824
|
+
return this.runtimeObservationRegistry
|
|
1825
|
+
.listActive()
|
|
1826
|
+
.then((observations) => observations.length > 0 ? observations : [])
|
|
1827
|
+
.catch(() => []);
|
|
1828
|
+
}
|
|
1829
|
+
catch {
|
|
1830
|
+
return [];
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
isRuntimeComponentObservationEnvelopeLike(observation) {
|
|
1834
|
+
return observation !== null && typeof observation === 'object';
|
|
1835
|
+
}
|
|
1836
|
+
startAuthoringTurnStream(request, options) {
|
|
1837
|
+
return this.aiApi.startAgenticAuthoringTurnStream(request, {
|
|
1838
|
+
baseUrl: options.baseUrl,
|
|
1839
|
+
headers: options.headers,
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
isPromiseLike(value) {
|
|
1843
|
+
return !!value && typeof value.then === 'function';
|
|
1844
|
+
}
|
|
1845
|
+
toResultTurn(payload, event) {
|
|
1775
1846
|
const intentResolution = this.toJsonObject(payload['intentResolution']);
|
|
1776
1847
|
const preview = payload['preview'];
|
|
1777
1848
|
const quickReplies = this.toShellQuickReplies(this.toQuickReplies(payload['quickReplies'])
|
|
@@ -1783,18 +1854,22 @@ class AgenticAuthoringTurnClientService {
|
|
|
1783
1854
|
|| this.readString(intentResolution, 'assistantMessage')
|
|
1784
1855
|
|| this.readString(payload, 'message')
|
|
1785
1856
|
|| '';
|
|
1857
|
+
const assistantContent = this.toJsonObject(payload['assistantContent'])
|
|
1858
|
+
?? this.toJsonObject(intentResolution?.['assistantContent'])
|
|
1859
|
+
?? null;
|
|
1786
1860
|
const canApply = payload['canApply'] === true;
|
|
1787
1861
|
if (pendingClarification) {
|
|
1788
1862
|
return {
|
|
1789
1863
|
state: 'clarification',
|
|
1790
1864
|
phase: 'clarify',
|
|
1791
1865
|
assistantMessage: assistantMessage || pendingClarification.assistantMessage,
|
|
1866
|
+
assistantContent,
|
|
1792
1867
|
quickReplies,
|
|
1793
1868
|
clarificationQuestions: pendingClarification.questions,
|
|
1794
1869
|
canApply: false,
|
|
1795
1870
|
preview: preview ?? null,
|
|
1796
1871
|
pendingClarification,
|
|
1797
|
-
diagnostics: this.resultDiagnostics(payload),
|
|
1872
|
+
diagnostics: this.resultDiagnostics(payload, event),
|
|
1798
1873
|
};
|
|
1799
1874
|
}
|
|
1800
1875
|
if (canApply) {
|
|
@@ -1802,24 +1877,36 @@ class AgenticAuthoringTurnClientService {
|
|
|
1802
1877
|
state: 'review',
|
|
1803
1878
|
phase: 'review',
|
|
1804
1879
|
assistantMessage,
|
|
1880
|
+
assistantContent,
|
|
1805
1881
|
quickReplies,
|
|
1806
1882
|
canApply: true,
|
|
1807
1883
|
preview: preview ?? null,
|
|
1808
1884
|
pendingPatch: payload['patch'] ?? payload['compiledPatch'] ?? null,
|
|
1809
|
-
diagnostics: this.resultDiagnostics(payload),
|
|
1885
|
+
diagnostics: this.resultDiagnostics(payload, event),
|
|
1810
1886
|
};
|
|
1811
1887
|
}
|
|
1888
|
+
const consultativeCatalogAnswer = this.isConsultativeCatalogAnswer(payload, intentResolution);
|
|
1812
1889
|
return {
|
|
1813
|
-
state: quickReplies.length ? 'clarification' : 'success',
|
|
1814
|
-
phase: quickReplies.length ? 'clarify' : 'summarize',
|
|
1890
|
+
state: quickReplies.length && !consultativeCatalogAnswer ? 'clarification' : 'success',
|
|
1891
|
+
phase: quickReplies.length && !consultativeCatalogAnswer ? 'clarify' : 'summarize',
|
|
1815
1892
|
assistantMessage,
|
|
1893
|
+
assistantContent,
|
|
1816
1894
|
quickReplies,
|
|
1817
1895
|
canApply: false,
|
|
1818
1896
|
preview: preview ?? null,
|
|
1819
1897
|
pendingClarification: null,
|
|
1820
|
-
diagnostics: this.resultDiagnostics(payload),
|
|
1898
|
+
diagnostics: this.resultDiagnostics(payload, event),
|
|
1821
1899
|
};
|
|
1822
1900
|
}
|
|
1901
|
+
isConsultativeCatalogAnswer(payload, intentResolution) {
|
|
1902
|
+
const diagnostics = this.toJsonObject(payload['decisionDiagnostics']);
|
|
1903
|
+
if (diagnostics?.['consultativeFastPath'] === true)
|
|
1904
|
+
return true;
|
|
1905
|
+
if (this.readString(diagnostics, 'routeClass') === 'consultative_fast_path')
|
|
1906
|
+
return true;
|
|
1907
|
+
return this.readString(intentResolution, 'artifactKind') === 'api_catalog'
|
|
1908
|
+
&& this.readString(intentResolution, 'changeKind') === 'answer_api_catalog_question';
|
|
1909
|
+
}
|
|
1823
1910
|
toShellQuickReplies(quickReplies) {
|
|
1824
1911
|
return quickReplies
|
|
1825
1912
|
.filter((reply) => !!reply.id?.trim() && !!reply.label?.trim())
|
|
@@ -1889,13 +1976,73 @@ class AgenticAuthoringTurnClientService {
|
|
|
1889
1976
|
|| this.readString(payload, 'message')
|
|
1890
1977
|
|| '';
|
|
1891
1978
|
}
|
|
1892
|
-
resultDiagnostics(payload) {
|
|
1979
|
+
resultDiagnostics(payload, event) {
|
|
1893
1980
|
return {
|
|
1894
1981
|
intentResolution: this.toJsonObject(payload['intentResolution']) ?? undefined,
|
|
1895
1982
|
decisionDiagnostics: this.toJsonObject(payload['decisionDiagnostics']) ?? undefined,
|
|
1983
|
+
runtimeRelatedSurfaceDisambiguationContext: this.runtimeRelatedSurfaceDisambiguationContext(payload, event) ?? undefined,
|
|
1896
1984
|
toolLoopTrace: Array.isArray(payload['toolLoopTrace']) ? payload['toolLoopTrace'] : undefined,
|
|
1897
1985
|
};
|
|
1898
1986
|
}
|
|
1987
|
+
runtimeRelatedSurfaceDisambiguationContext(payload, event) {
|
|
1988
|
+
const evidenceBundle = this.toJsonObject(payload['evidenceBundle']);
|
|
1989
|
+
const disambiguation = this.toJsonObject(evidenceBundle?.['runtimeRelatedSurfaceDisambiguation']);
|
|
1990
|
+
const pageId = this.runtimeRelatedSurfaceDisambiguationPageId(evidenceBundle);
|
|
1991
|
+
const sessionId = event?.threadId?.trim() || '';
|
|
1992
|
+
const sourceTurnId = event?.turnId?.trim() || '';
|
|
1993
|
+
const rawOptions = Array.isArray(disambiguation?.['options'])
|
|
1994
|
+
? disambiguation['options']
|
|
1995
|
+
: [];
|
|
1996
|
+
const options = rawOptions
|
|
1997
|
+
.map((option) => this.toJsonObject(option))
|
|
1998
|
+
.filter((option) => !!option)
|
|
1999
|
+
.map((option) => ({
|
|
2000
|
+
surfaceRef: this.readString(option, 'surfaceRef'),
|
|
2001
|
+
optionRef: this.readString(option, 'optionRef'),
|
|
2002
|
+
candidateRef: this.readString(option, 'candidateRef'),
|
|
2003
|
+
label: this.readString(option, 'label') || this.readString(option, 'surfaceRef'),
|
|
2004
|
+
semanticAliases: Array.isArray(option['semanticAliases'])
|
|
2005
|
+
? option['semanticAliases']
|
|
2006
|
+
.filter((alias) => typeof alias === 'string' && !!alias.trim())
|
|
2007
|
+
.map((alias) => alias.trim())
|
|
2008
|
+
.slice(0, 12)
|
|
2009
|
+
: [],
|
|
2010
|
+
}))
|
|
2011
|
+
.filter((option) => !!option.surfaceRef
|
|
2012
|
+
&& option.optionRef === `runtime-surface-option:${option.surfaceRef}`
|
|
2013
|
+
&& option.candidateRef.startsWith('runtime-surface-candidate:'))
|
|
2014
|
+
.slice(0, 4);
|
|
2015
|
+
if (options.length < 2 || !sessionId || !sourceTurnId || !pageId) {
|
|
2016
|
+
return null;
|
|
2017
|
+
}
|
|
2018
|
+
return {
|
|
2019
|
+
schemaVersion: 'praxis-runtime-related-surface-disambiguation-context.v1',
|
|
2020
|
+
source: 'runtimeRelatedSurfaceDisambiguation',
|
|
2021
|
+
authority: 'grounding_only',
|
|
2022
|
+
sessionId,
|
|
2023
|
+
sourceTurnId,
|
|
2024
|
+
pageId,
|
|
2025
|
+
capturedAt: new Date().toISOString(),
|
|
2026
|
+
ttlMs: 300000,
|
|
2027
|
+
optionCount: options.length,
|
|
2028
|
+
options,
|
|
2029
|
+
rawRuntimeValuesCopied: false,
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
runtimeRelatedSurfaceDisambiguationPageId(evidenceBundle) {
|
|
2033
|
+
const runtimeContext = this.toJsonObject(evidenceBundle?.['runtimeConsultableContext']);
|
|
2034
|
+
const components = Array.isArray(runtimeContext?.['components'])
|
|
2035
|
+
? runtimeContext['components']
|
|
2036
|
+
: [];
|
|
2037
|
+
for (const component of components) {
|
|
2038
|
+
const refs = this.toJsonObject(this.toJsonObject(component)?.['refs']);
|
|
2039
|
+
const pageId = this.readString(refs, 'pageId');
|
|
2040
|
+
if (pageId) {
|
|
2041
|
+
return pageId;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
return '';
|
|
2045
|
+
}
|
|
1899
2046
|
toLifecycleEvent(start, event) {
|
|
1900
2047
|
return {
|
|
1901
2048
|
kind: 'stream-lifecycle',
|
|
@@ -2423,8 +2570,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2423
2570
|
}] });
|
|
2424
2571
|
|
|
2425
2572
|
class PraxisAssistantTurnOrchestratorService {
|
|
2573
|
+
runtimeObservationRegistry = inject(PraxisRuntimeComponentObservationRegistryService, { optional: true });
|
|
2426
2574
|
createController(flow, options = {}) {
|
|
2427
|
-
return new PraxisAssistantTurnController(flow, options);
|
|
2575
|
+
return new PraxisAssistantTurnController(flow, options, this.runtimeObservationRegistry);
|
|
2428
2576
|
}
|
|
2429
2577
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantTurnOrchestratorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2430
2578
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAssistantTurnOrchestratorService, providedIn: 'root' });
|
|
@@ -2436,12 +2584,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2436
2584
|
class PraxisAssistantTurnController {
|
|
2437
2585
|
flow;
|
|
2438
2586
|
options;
|
|
2587
|
+
runtimeObservationRegistry;
|
|
2439
2588
|
stateSubject;
|
|
2440
2589
|
state$;
|
|
2441
2590
|
activeFlowClientTurnId = null;
|
|
2442
|
-
constructor(flow, options) {
|
|
2591
|
+
constructor(flow, options, runtimeObservationRegistry) {
|
|
2443
2592
|
this.flow = flow;
|
|
2444
2593
|
this.options = options;
|
|
2594
|
+
this.runtimeObservationRegistry = runtimeObservationRegistry;
|
|
2445
2595
|
this.stateSubject = new BehaviorSubject({
|
|
2446
2596
|
mode: flow.mode,
|
|
2447
2597
|
state: 'idle',
|
|
@@ -2557,9 +2707,12 @@ class PraxisAssistantTurnController {
|
|
|
2557
2707
|
: this.semanticClarificationContextHints(option);
|
|
2558
2708
|
return this.submitPrompt(answer, {
|
|
2559
2709
|
kind: 'clarify',
|
|
2560
|
-
value: typeof option === 'string' ? option : option.value,
|
|
2710
|
+
value: typeof option === 'string' ? option : option.rawValue ?? option.value,
|
|
2561
2711
|
displayPrompt,
|
|
2562
2712
|
contextHints,
|
|
2713
|
+
activeSemanticDecision: typeof option === 'string'
|
|
2714
|
+
? undefined
|
|
2715
|
+
: option.semanticDecision ?? undefined,
|
|
2563
2716
|
});
|
|
2564
2717
|
}
|
|
2565
2718
|
semanticClarificationContextHints(option) {
|
|
@@ -2625,9 +2778,24 @@ class PraxisAssistantTurnController {
|
|
|
2625
2778
|
});
|
|
2626
2779
|
}
|
|
2627
2780
|
runFlow(method, partial) {
|
|
2628
|
-
const
|
|
2629
|
-
const requestClientTurnId =
|
|
2781
|
+
const current = this.stateSubject.value;
|
|
2782
|
+
const requestClientTurnId = current.clientTurnId ?? null;
|
|
2630
2783
|
this.activeFlowClientTurnId = requestClientTurnId;
|
|
2784
|
+
const request = this.buildRequest(partial, current);
|
|
2785
|
+
if (!this.isPromiseLike(request)) {
|
|
2786
|
+
return this.invokeFlow(method, request, requestClientTurnId);
|
|
2787
|
+
}
|
|
2788
|
+
return from(request).pipe(switchMap((resolvedRequest) => this.invokeFlow(method, resolvedRequest, requestClientTurnId)), catchError$1((error) => {
|
|
2789
|
+
if (this.shouldApplyFlowResult(requestClientTurnId)) {
|
|
2790
|
+
this.applyResult(this.buildFlowErrorResult(error));
|
|
2791
|
+
}
|
|
2792
|
+
return of(this.snapshot());
|
|
2793
|
+
}));
|
|
2794
|
+
}
|
|
2795
|
+
invokeFlow(method, request, requestClientTurnId) {
|
|
2796
|
+
if (!this.shouldApplyFlowResult(requestClientTurnId)) {
|
|
2797
|
+
return of(this.snapshot());
|
|
2798
|
+
}
|
|
2631
2799
|
const handler = this.flow[method];
|
|
2632
2800
|
if (!handler) {
|
|
2633
2801
|
return of(this.snapshot());
|
|
@@ -2657,9 +2825,9 @@ class PraxisAssistantTurnController {
|
|
|
2657
2825
|
return of(this.snapshot());
|
|
2658
2826
|
}));
|
|
2659
2827
|
}
|
|
2660
|
-
buildRequest(partial) {
|
|
2661
|
-
const
|
|
2662
|
-
|
|
2828
|
+
buildRequest(partial, current) {
|
|
2829
|
+
const runtimeComponentObservations = this.collectRuntimeComponentObservations();
|
|
2830
|
+
const build = (observations) => ({
|
|
2663
2831
|
mode: this.flow.mode,
|
|
2664
2832
|
componentId: this.options.componentId,
|
|
2665
2833
|
componentType: this.options.componentType,
|
|
@@ -2673,13 +2841,39 @@ class PraxisAssistantTurnController {
|
|
|
2673
2841
|
schemaFields: this.options.schemaFields,
|
|
2674
2842
|
dataProfile: this.options.dataProfile,
|
|
2675
2843
|
contextHints: this.options.contextHints,
|
|
2844
|
+
activeSemanticDecision: partial.activeSemanticDecision ?? partial.action?.activeSemanticDecision,
|
|
2676
2845
|
preview: current.preview,
|
|
2677
2846
|
pendingPatch: current.pendingPatch,
|
|
2678
2847
|
pendingClarification: current.pendingClarification,
|
|
2679
2848
|
diagnostics: current.diagnostics,
|
|
2680
2849
|
observationId: current.observationId,
|
|
2850
|
+
...(observations.length > 0 ? { runtimeComponentObservations: observations } : {}),
|
|
2681
2851
|
...partial,
|
|
2682
|
-
};
|
|
2852
|
+
});
|
|
2853
|
+
return this.isPromiseLike(runtimeComponentObservations)
|
|
2854
|
+
? runtimeComponentObservations.then(build)
|
|
2855
|
+
: build(runtimeComponentObservations);
|
|
2856
|
+
}
|
|
2857
|
+
collectRuntimeComponentObservations() {
|
|
2858
|
+
if (!this.runtimeObservationRegistry) {
|
|
2859
|
+
return [];
|
|
2860
|
+
}
|
|
2861
|
+
if (typeof this.runtimeObservationRegistry.registeredCount === 'function' &&
|
|
2862
|
+
this.runtimeObservationRegistry.registeredCount() === 0) {
|
|
2863
|
+
return [];
|
|
2864
|
+
}
|
|
2865
|
+
try {
|
|
2866
|
+
return this.runtimeObservationRegistry
|
|
2867
|
+
.listActive()
|
|
2868
|
+
.then((observations) => observations.length > 0 ? observations : [])
|
|
2869
|
+
.catch(() => []);
|
|
2870
|
+
}
|
|
2871
|
+
catch {
|
|
2872
|
+
return [];
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
isPromiseLike(value) {
|
|
2876
|
+
return !!value && typeof value.then === 'function';
|
|
2683
2877
|
}
|
|
2684
2878
|
submitExistingUserMessage(messageIndex, prompt, action) {
|
|
2685
2879
|
const normalized = prompt.trim();
|
|
@@ -2788,7 +2982,7 @@ class PraxisAssistantTurnController {
|
|
|
2788
2982
|
const messages = result.messages
|
|
2789
2983
|
? [...result.messages]
|
|
2790
2984
|
: result.assistantMessage
|
|
2791
|
-
? [...current.messages, this.buildMessage(this.resolveMessageRole(result), result.assistantMessage, false, result.observationId)]
|
|
2985
|
+
? [...current.messages, this.buildMessage(this.resolveMessageRole(result), result.assistantMessage, false, result.observationId, result.assistantContent)]
|
|
2792
2986
|
: current.messages;
|
|
2793
2987
|
const pendingClarification = hasPendingClarification
|
|
2794
2988
|
? result.pendingClarification ?? undefined
|
|
@@ -2863,7 +3057,7 @@ class PraxisAssistantTurnController {
|
|
|
2863
3057
|
return this.stateSubject.value.phase;
|
|
2864
3058
|
return 'capture';
|
|
2865
3059
|
}
|
|
2866
|
-
buildMessage(role, text, userAction = false, observationId) {
|
|
3060
|
+
buildMessage(role, text, userAction = false, observationId, assistantContent) {
|
|
2867
3061
|
return {
|
|
2868
3062
|
id: this.createId('message'),
|
|
2869
3063
|
role,
|
|
@@ -2871,6 +3065,7 @@ class PraxisAssistantTurnController {
|
|
|
2871
3065
|
editable: userAction,
|
|
2872
3066
|
resendable: userAction,
|
|
2873
3067
|
observationId: this.shouldAttachObservationId(role, observationId) ? observationId : null,
|
|
3068
|
+
assistantContent: assistantContent ?? null,
|
|
2874
3069
|
};
|
|
2875
3070
|
}
|
|
2876
3071
|
shouldAttachObservationId(role, observationId) {
|
|
@@ -2968,6 +3163,7 @@ function toPraxisAssistantClarificationOption(reply) {
|
|
|
2968
3163
|
id: reply.id,
|
|
2969
3164
|
label: reply.label,
|
|
2970
3165
|
value: canonicalQuickReplyPrompt(reply),
|
|
3166
|
+
rawValue: cloneValue(reply.value),
|
|
2971
3167
|
description: reply.description ?? undefined,
|
|
2972
3168
|
displayPrompt: reply.label,
|
|
2973
3169
|
contextHints: cloneRecord(reply.contextHints),
|
|
@@ -2985,7 +3181,7 @@ function submitPraxisAssistantQuickReply(controller, reply) {
|
|
|
2985
3181
|
return controller.submitPrompt(prompt, {
|
|
2986
3182
|
kind: reply.kind || 'quick-reply',
|
|
2987
3183
|
id: reply.id,
|
|
2988
|
-
value: prompt,
|
|
3184
|
+
value: cloneValue(reply.value) ?? prompt,
|
|
2989
3185
|
displayPrompt: reply.label,
|
|
2990
3186
|
contextHints,
|
|
2991
3187
|
});
|
|
@@ -3005,6 +3201,20 @@ function cloneRecord(value) {
|
|
|
3005
3201
|
return { ...value };
|
|
3006
3202
|
}
|
|
3007
3203
|
}
|
|
3204
|
+
function cloneValue(value) {
|
|
3205
|
+
if (value === undefined) {
|
|
3206
|
+
return undefined;
|
|
3207
|
+
}
|
|
3208
|
+
if (!value || typeof value !== 'object') {
|
|
3209
|
+
return value;
|
|
3210
|
+
}
|
|
3211
|
+
try {
|
|
3212
|
+
return JSON.parse(JSON.stringify(value));
|
|
3213
|
+
}
|
|
3214
|
+
catch {
|
|
3215
|
+
return Array.isArray(value) ? [...value] : { ...value };
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3008
3218
|
|
|
3009
3219
|
class PraxisAssistantSessionRegistryService {
|
|
3010
3220
|
sessionsState = signal([], ...(ngDevMode ? [{ debugName: "sessionsState" }] : /* istanbul ignore next */ []));
|
|
@@ -7456,10 +7666,10 @@ const DEFAULT_LABELS = {
|
|
|
7456
7666
|
promptPlaceholder: 'Descreva o que você quer criar ou alterar.',
|
|
7457
7667
|
emptyConversation: 'Diga o que você quer criar ou alterar.',
|
|
7458
7668
|
submit: 'Interpretar pedido',
|
|
7459
|
-
apply: '
|
|
7669
|
+
apply: 'Salvar alteração',
|
|
7460
7670
|
conversationAria: 'Conversa com IA',
|
|
7461
7671
|
quickRepliesAria: 'Respostas rápidas',
|
|
7462
|
-
quickReplyDetails: '
|
|
7672
|
+
quickReplyDetails: 'Ver detalhes',
|
|
7463
7673
|
recommendedIntentsAria: 'Sugestões iniciais do assistente',
|
|
7464
7674
|
recommendedIntentsTitle: 'Você pode começar por aqui',
|
|
7465
7675
|
recommendedIntentCta: 'Usar sugestão',
|
|
@@ -7804,6 +8014,92 @@ class PraxisAiAssistantShellComponent {
|
|
|
7804
8014
|
closeList();
|
|
7805
8015
|
return html.join('');
|
|
7806
8016
|
}
|
|
8017
|
+
hasStructuredAssistantContent(message) {
|
|
8018
|
+
return message.role === 'assistant' && this.getAssistantContentBlocks(message).length > 0;
|
|
8019
|
+
}
|
|
8020
|
+
getAssistantContentBlocks(message) {
|
|
8021
|
+
const content = this.asRecord(message.assistantContent);
|
|
8022
|
+
const blocks = Array.isArray(content?.['blocks']) ? content['blocks'] : [];
|
|
8023
|
+
return blocks
|
|
8024
|
+
.filter((block) => this.asRecord(block) !== null)
|
|
8025
|
+
.map((block) => block)
|
|
8026
|
+
.filter((block) => this.isSupportedAssistantContentBlock(block));
|
|
8027
|
+
}
|
|
8028
|
+
getAssistantContentBlockType(block) {
|
|
8029
|
+
return this.stringHint(block, 'type');
|
|
8030
|
+
}
|
|
8031
|
+
getAssistantContentBlockTitle(block, fallback = '') {
|
|
8032
|
+
return this.stringHint(block, 'title') || fallback;
|
|
8033
|
+
}
|
|
8034
|
+
getAssistantContentBlockText(block) {
|
|
8035
|
+
return this.stringHint(block, 'text');
|
|
8036
|
+
}
|
|
8037
|
+
getAssistantContentResources(block) {
|
|
8038
|
+
const resources = Array.isArray(block['resources']) ? block['resources'] : [];
|
|
8039
|
+
return resources
|
|
8040
|
+
.map((resource) => this.asRecord(resource))
|
|
8041
|
+
.filter((resource) => resource !== null)
|
|
8042
|
+
.map((resource) => ({
|
|
8043
|
+
id: this.stringHint(resource, 'id'),
|
|
8044
|
+
label: this.friendlyTechnicalLabel(this.stringHint(resource, 'label') || this.stringHint(resource, 'id')),
|
|
8045
|
+
description: this.stringHint(resource, 'description'),
|
|
8046
|
+
role: this.friendlyTechnicalLabel(this.stringHint(resource, 'role')),
|
|
8047
|
+
resourcePath: this.stringHint(resource, 'resourcePath'),
|
|
8048
|
+
fields: this.getAssistantContentResourceFields(resource),
|
|
8049
|
+
evidence: this.getStringArray(resource['evidence'])
|
|
8050
|
+
.map((item) => this.friendlyTechnicalLabel(item))
|
|
8051
|
+
.slice(0, 3),
|
|
8052
|
+
}))
|
|
8053
|
+
.filter((resource) => resource.label || resource.resourcePath || resource.fields.length);
|
|
8054
|
+
}
|
|
8055
|
+
getAssistantContentResourceFields(resource) {
|
|
8056
|
+
const fields = Array.isArray(resource['fields']) ? resource['fields'] : [];
|
|
8057
|
+
return fields
|
|
8058
|
+
.map((field) => this.asRecord(field))
|
|
8059
|
+
.filter((field) => field !== null)
|
|
8060
|
+
.map((field) => ({
|
|
8061
|
+
name: this.stringHint(field, 'name'),
|
|
8062
|
+
label: this.friendlyTechnicalLabel(this.stringHint(field, 'label') || this.stringHint(field, 'name')),
|
|
8063
|
+
description: this.stringHint(field, 'description'),
|
|
8064
|
+
}))
|
|
8065
|
+
.filter((field) => field.label);
|
|
8066
|
+
}
|
|
8067
|
+
getAssistantContentResourceMeta(resource) {
|
|
8068
|
+
return [
|
|
8069
|
+
resource.role,
|
|
8070
|
+
].filter((item) => item.length > 0);
|
|
8071
|
+
}
|
|
8072
|
+
trackAssistantContentBlock(index, block) {
|
|
8073
|
+
return `${this.getAssistantContentBlockType(block) || 'block'}-${index}`;
|
|
8074
|
+
}
|
|
8075
|
+
trackAssistantContentResource(index, resource) {
|
|
8076
|
+
return resource.id || resource.resourcePath || resource.label || `${index}`;
|
|
8077
|
+
}
|
|
8078
|
+
trackAssistantContentField(index, field) {
|
|
8079
|
+
return field.name || field.label || `${index}`;
|
|
8080
|
+
}
|
|
8081
|
+
trackAssistantContentValue(_index, value) {
|
|
8082
|
+
return value;
|
|
8083
|
+
}
|
|
8084
|
+
isSupportedAssistantContentBlock(block) {
|
|
8085
|
+
switch (this.getAssistantContentBlockType(block)) {
|
|
8086
|
+
case 'paragraph':
|
|
8087
|
+
return !!this.getAssistantContentBlockText(block);
|
|
8088
|
+
case 'resource-list':
|
|
8089
|
+
return this.getAssistantContentResources(block).length > 0;
|
|
8090
|
+
case 'recommendation':
|
|
8091
|
+
return !!this.getAssistantContentBlockText(block);
|
|
8092
|
+
default:
|
|
8093
|
+
return false;
|
|
8094
|
+
}
|
|
8095
|
+
}
|
|
8096
|
+
getStringArray(value) {
|
|
8097
|
+
if (!Array.isArray(value))
|
|
8098
|
+
return [];
|
|
8099
|
+
return value
|
|
8100
|
+
.filter((item) => typeof item === 'string' && item.trim().length > 0)
|
|
8101
|
+
.map((item) => item.trim());
|
|
8102
|
+
}
|
|
7807
8103
|
renderInlineMarkdown(value) {
|
|
7808
8104
|
return this.escapeHtml(value)
|
|
7809
8105
|
.replace(/`([^`]+)`/g, '<code>$1</code>')
|
|
@@ -7966,15 +8262,15 @@ class PraxisAiAssistantShellComponent {
|
|
|
7966
8262
|
if (this.state !== 'processing')
|
|
7967
8263
|
return '';
|
|
7968
8264
|
if (this.processingElapsedSeconds >= 30) {
|
|
7969
|
-
return 'Ainda
|
|
8265
|
+
return 'Ainda preparando a resposta. Você pode cancelar e tentar novamente se precisar.';
|
|
7970
8266
|
}
|
|
7971
8267
|
if (this.processingElapsedSeconds >= 12) {
|
|
7972
|
-
return 'Ainda
|
|
8268
|
+
return 'Ainda preparando a resposta com as informações disponíveis.';
|
|
7973
8269
|
}
|
|
7974
8270
|
if (this.processingElapsedSeconds >= 5) {
|
|
7975
|
-
return 'Consultando o
|
|
8271
|
+
return 'Consultando o domínio e conferindo o que pode ser criado com segurança.';
|
|
7976
8272
|
}
|
|
7977
|
-
return this.statusText || 'Interpretando o pedido e
|
|
8273
|
+
return this.statusText || 'Interpretando o pedido e organizando as informações da tela.';
|
|
7978
8274
|
}
|
|
7979
8275
|
shouldShowAuxiliaryText(text, errorOnly) {
|
|
7980
8276
|
const normalized = this.normalizeMessageText(text);
|
|
@@ -8129,7 +8425,7 @@ class PraxisAiAssistantShellComponent {
|
|
|
8129
8425
|
return intent.group?.label?.trim() || '';
|
|
8130
8426
|
}
|
|
8131
8427
|
getQuickReplyAriaLabel(reply) {
|
|
8132
|
-
const label =
|
|
8428
|
+
const label = this.getQuickReplyLabel(reply);
|
|
8133
8429
|
const description = this.getQuickReplyDescription(reply);
|
|
8134
8430
|
const presentation = this.getQuickReplyPresentationItems(reply)
|
|
8135
8431
|
.map((item) => `${item.label}: ${item.value}`)
|
|
@@ -8139,6 +8435,12 @@ class PraxisAiAssistantShellComponent {
|
|
|
8139
8435
|
.map((segment) => this.trimSentencePunctuation(segment))
|
|
8140
8436
|
.join('. ');
|
|
8141
8437
|
}
|
|
8438
|
+
getQuickReplyLabel(reply) {
|
|
8439
|
+
const label = reply.label?.trim() ?? '';
|
|
8440
|
+
if (!label)
|
|
8441
|
+
return '';
|
|
8442
|
+
return this.friendlyTechnicalLabel(label);
|
|
8443
|
+
}
|
|
8142
8444
|
getQuickReplyTechnicalDetails(reply) {
|
|
8143
8445
|
const explicit = this.quickReplyPresentation(reply)?.technicalDetails?.trim();
|
|
8144
8446
|
if (explicit)
|
|
@@ -8156,9 +8458,9 @@ class PraxisAiAssistantShellComponent {
|
|
|
8156
8458
|
const resourcePath = this.quickReplyHint(details, hints, 'resourcePath');
|
|
8157
8459
|
const schemaUrl = this.quickReplyHint(details, hints, 'schemaUrl');
|
|
8158
8460
|
return [
|
|
8159
|
-
submitMethod && submitUrl ?
|
|
8160
|
-
resourcePath && resourcePath !== submitUrl ? `
|
|
8161
|
-
schemaUrl ? `
|
|
8461
|
+
submitMethod && submitUrl ? `Operação da plataforma: ${submitMethod.toUpperCase()} ${submitUrl}` : '',
|
|
8462
|
+
resourcePath && resourcePath !== submitUrl ? `Fonte de dados: ${resourcePath}` : '',
|
|
8463
|
+
schemaUrl ? `Estrutura dos dados: ${schemaUrl}` : '',
|
|
8162
8464
|
].filter(Boolean).join('\n');
|
|
8163
8465
|
}
|
|
8164
8466
|
isRichQuickReply(reply) {
|
|
@@ -8213,39 +8515,32 @@ class PraxisAiAssistantShellComponent {
|
|
|
8213
8515
|
const details = this.asRecord(hints?.['technicalDetails']) ?? hints;
|
|
8214
8516
|
if (!details)
|
|
8215
8517
|
return [];
|
|
8216
|
-
const submitMethod = this.quickReplyHint(details, hints, 'submitMethod') || this.quickReplyHint(details, hints, 'operation');
|
|
8217
8518
|
const submitUrl = this.quickReplyHint(details, hints, 'submitUrl');
|
|
8218
8519
|
const resourcePath = this.quickReplyHint(details, hints, 'resourcePath');
|
|
8219
8520
|
const schemaUrl = this.quickReplyHint(details, hints, 'schemaUrl');
|
|
8220
8521
|
const chips = [];
|
|
8221
|
-
|
|
8222
|
-
chips.push({
|
|
8223
|
-
icon: 'bolt',
|
|
8224
|
-
value: submitMethod.toUpperCase(),
|
|
8225
|
-
ariaLabel: `Operação ${submitMethod.toUpperCase()}`,
|
|
8226
|
-
});
|
|
8227
|
-
}
|
|
8228
|
-
const resourceLabel = this.shortPathLabel(resourcePath || submitUrl);
|
|
8522
|
+
const resourceLabel = this.friendlyTechnicalLabel(this.quickReplyPublicResourceLabel(reply, details, hints) || this.shortPathLabel(resourcePath || submitUrl));
|
|
8229
8523
|
if (resourceLabel) {
|
|
8230
8524
|
chips.push({
|
|
8231
8525
|
icon: 'dataset',
|
|
8232
8526
|
value: resourceLabel,
|
|
8233
|
-
ariaLabel: `
|
|
8527
|
+
ariaLabel: `Fonte de dados ${resourceLabel}`,
|
|
8234
8528
|
});
|
|
8235
8529
|
}
|
|
8236
8530
|
if (schemaUrl) {
|
|
8237
8531
|
chips.push({
|
|
8238
|
-
icon: '
|
|
8239
|
-
value: '
|
|
8240
|
-
ariaLabel: '
|
|
8532
|
+
icon: 'view_list',
|
|
8533
|
+
value: 'estrutura',
|
|
8534
|
+
ariaLabel: 'Estrutura dos dados disponível',
|
|
8241
8535
|
});
|
|
8242
8536
|
}
|
|
8243
|
-
return chips;
|
|
8537
|
+
return chips.slice(0, 2);
|
|
8244
8538
|
}
|
|
8245
8539
|
getQuickReplyPresentationItems(reply) {
|
|
8246
8540
|
if (this.isFieldDiscoveryQuickReply(reply)
|
|
8247
8541
|
|| this.isGuidedActionQuickReply(reply)
|
|
8248
|
-
|| this.isContextualPreviewActionQuickReply(reply)
|
|
8542
|
+
|| this.isContextualPreviewActionQuickReply(reply)
|
|
8543
|
+
|| this.isSourceReviewQuickReply(reply))
|
|
8249
8544
|
return [];
|
|
8250
8545
|
const authoredItems = this.quickReplyPresentation(reply)?.items
|
|
8251
8546
|
?.filter((item) => !!item.label?.trim() && !!item.value?.trim())
|
|
@@ -8301,9 +8596,9 @@ class PraxisAiAssistantShellComponent {
|
|
|
8301
8596
|
if (!this.hasQuickReplyResourceContext(reply))
|
|
8302
8597
|
return null;
|
|
8303
8598
|
return {
|
|
8304
|
-
bestFor: '
|
|
8305
|
-
returns: '
|
|
8306
|
-
nextStep: '
|
|
8599
|
+
bestFor: 'Escolher quais informações do domínio serão usadas na tela.',
|
|
8600
|
+
returns: 'Dados que podem virar tabelas, filtros, indicadores ou gráficos.',
|
|
8601
|
+
nextStep: 'Use esta fonte para montar uma prévia e revisar antes de salvar.',
|
|
8307
8602
|
};
|
|
8308
8603
|
case 'revise':
|
|
8309
8604
|
case 'warning':
|
|
@@ -8315,7 +8610,7 @@ class PraxisAiAssistantShellComponent {
|
|
|
8315
8610
|
getQuickReplyCategoryLabel(reply) {
|
|
8316
8611
|
const categoryLabel = this.quickReplyPresentation(reply)?.categoryLabel?.trim();
|
|
8317
8612
|
if (categoryLabel)
|
|
8318
|
-
return categoryLabel;
|
|
8613
|
+
return this.friendlyTechnicalLabel(categoryLabel);
|
|
8319
8614
|
const kind = (reply.kind || '').toLowerCase();
|
|
8320
8615
|
const tone = (reply.tone || '').toLowerCase();
|
|
8321
8616
|
if (this.isContextualPreviewActionQuickReply(reply)) {
|
|
@@ -8337,7 +8632,7 @@ class PraxisAiAssistantShellComponent {
|
|
|
8337
8632
|
return 'Ajustar antes';
|
|
8338
8633
|
case 'resource':
|
|
8339
8634
|
case 'suggestion':
|
|
8340
|
-
return 'Fonte
|
|
8635
|
+
return 'Fonte de dados';
|
|
8341
8636
|
case 'success':
|
|
8342
8637
|
return 'Pronto para usar';
|
|
8343
8638
|
case 'cancel':
|
|
@@ -8397,7 +8692,7 @@ class PraxisAiAssistantShellComponent {
|
|
|
8397
8692
|
return 'Cancelar';
|
|
8398
8693
|
case 'resource':
|
|
8399
8694
|
case 'suggestion':
|
|
8400
|
-
return '
|
|
8695
|
+
return 'Usar fonte';
|
|
8401
8696
|
default:
|
|
8402
8697
|
return 'Usar esta opção';
|
|
8403
8698
|
}
|
|
@@ -8463,6 +8758,21 @@ class PraxisAiAssistantShellComponent {
|
|
|
8463
8758
|
quickReplyHint(primary, fallback, key) {
|
|
8464
8759
|
return this.stringHint(primary, key) || (fallback ? this.stringHint(fallback, key) : '');
|
|
8465
8760
|
}
|
|
8761
|
+
quickReplyPublicResourceLabel(reply, details, hints) {
|
|
8762
|
+
const value = this.asRecord(reply.value);
|
|
8763
|
+
const semanticDecision = this.asRecord(reply.semanticDecision);
|
|
8764
|
+
const candidates = [
|
|
8765
|
+
this.stringHint(value ?? {}, 'label'),
|
|
8766
|
+
this.stringHint(semanticDecision ?? {}, 'selectedResourceLabel'),
|
|
8767
|
+
this.quickReplyHint(details, hints, 'selectedResourceLabel'),
|
|
8768
|
+
this.quickReplyHint(details, hints, 'resourceLabel'),
|
|
8769
|
+
];
|
|
8770
|
+
return candidates.find((candidate) => this.isPublicDisplayText(candidate)) ?? '';
|
|
8771
|
+
}
|
|
8772
|
+
isPublicDisplayText(value) {
|
|
8773
|
+
const normalized = value.trim().toLocaleLowerCase('pt-BR');
|
|
8774
|
+
return !!normalized && normalized !== '[redacted]' && normalized !== '[jwt_redacted]';
|
|
8775
|
+
}
|
|
8466
8776
|
hasQuickReplyResourceContext(reply) {
|
|
8467
8777
|
if (this.isFieldDiscoveryQuickReply(reply) || this.isContextualPreviewActionQuickReply(reply))
|
|
8468
8778
|
return false;
|
|
@@ -8503,6 +8813,11 @@ class PraxisAiAssistantShellComponent {
|
|
|
8503
8813
|
|| id.startsWith('chart-')
|
|
8504
8814
|
|| id.startsWith('table-export-');
|
|
8505
8815
|
}
|
|
8816
|
+
isSourceReviewQuickReply(reply) {
|
|
8817
|
+
const kind = (reply.kind || '').trim().toLowerCase();
|
|
8818
|
+
return (kind === 'resource' || kind === 'suggestion')
|
|
8819
|
+
&& this.hasQuickReplyResourceContext(reply);
|
|
8820
|
+
}
|
|
8506
8821
|
isGuidedActionQuickReply(reply) {
|
|
8507
8822
|
const presentationKind = this.quickReplyPresentationKind(reply);
|
|
8508
8823
|
if (presentationKind === 'guided-option' || presentationKind === 'quick-action') {
|
|
@@ -8527,8 +8842,8 @@ class PraxisAiAssistantShellComponent {
|
|
|
8527
8842
|
const value = item.value.trim();
|
|
8528
8843
|
return {
|
|
8529
8844
|
icon: item.icon?.trim() || 'verified',
|
|
8530
|
-
value,
|
|
8531
|
-
ariaLabel: item.ariaLabel?.trim() || value,
|
|
8845
|
+
value: this.friendlyTechnicalLabel(value),
|
|
8846
|
+
ariaLabel: this.friendlyTechnicalLabel(item.ariaLabel?.trim() || value),
|
|
8532
8847
|
};
|
|
8533
8848
|
}
|
|
8534
8849
|
getContextualActionChips(reply) {
|
|
@@ -8545,22 +8860,22 @@ class PraxisAiAssistantShellComponent {
|
|
|
8545
8860
|
if (targetComponentId) {
|
|
8546
8861
|
chips.push({
|
|
8547
8862
|
icon: 'widgets',
|
|
8548
|
-
value: this.
|
|
8863
|
+
value: this.friendlyTechnicalLabel(targetComponentId),
|
|
8549
8864
|
ariaLabel: `Componente ${targetComponentId}`,
|
|
8550
8865
|
});
|
|
8551
8866
|
}
|
|
8552
8867
|
if (changeKind) {
|
|
8553
8868
|
chips.push({
|
|
8554
8869
|
icon: 'rule',
|
|
8555
|
-
value: this.
|
|
8870
|
+
value: this.friendlyTechnicalLabel(changeKind),
|
|
8556
8871
|
ariaLabel: `Mudança ${changeKind}`,
|
|
8557
8872
|
});
|
|
8558
8873
|
}
|
|
8559
8874
|
if (capabilityId) {
|
|
8560
8875
|
chips.push({
|
|
8561
8876
|
icon: 'verified',
|
|
8562
|
-
value: '
|
|
8563
|
-
ariaLabel: `
|
|
8877
|
+
value: 'permitido',
|
|
8878
|
+
ariaLabel: `Regra atendida ${capabilityId}`,
|
|
8564
8879
|
});
|
|
8565
8880
|
}
|
|
8566
8881
|
if (!capabilityId && selectedWidgetKey) {
|
|
@@ -8589,23 +8904,122 @@ class PraxisAiAssistantShellComponent {
|
|
|
8589
8904
|
return '';
|
|
8590
8905
|
const segments = normalized.split('/').filter(Boolean);
|
|
8591
8906
|
const last = segments.length > 0 ? segments[segments.length - 1] : normalized;
|
|
8907
|
+
const knownResourceLabel = this.knownPublicResourceLabel(last);
|
|
8908
|
+
if (knownResourceLabel)
|
|
8909
|
+
return knownResourceLabel;
|
|
8592
8910
|
return last
|
|
8593
8911
|
.replace(/^vw-/u, '')
|
|
8594
8912
|
.replace(/-/gu, ' ')
|
|
8595
|
-
.trim()
|
|
8913
|
+
.trim()
|
|
8914
|
+
.replace(/\b\p{L}/gu, (char) => char.toLocaleUpperCase('pt-BR'));
|
|
8915
|
+
}
|
|
8916
|
+
knownPublicResourceLabel(value) {
|
|
8917
|
+
const normalized = value
|
|
8918
|
+
.trim()
|
|
8919
|
+
.replace(/^vw-/u, '')
|
|
8920
|
+
.replace(/[_-]+/gu, ' ')
|
|
8921
|
+
.toLocaleLowerCase('pt-BR');
|
|
8922
|
+
const labels = {
|
|
8923
|
+
'missao participantes': 'Participantes da missão',
|
|
8924
|
+
'missao eventos': 'Eventos da missão',
|
|
8925
|
+
};
|
|
8926
|
+
return labels[normalized] ?? '';
|
|
8596
8927
|
}
|
|
8597
8928
|
shortTechnicalLabel(value) {
|
|
8598
|
-
return value
|
|
8929
|
+
return this.friendlyTechnicalLabel(value);
|
|
8930
|
+
}
|
|
8931
|
+
friendlyTechnicalLabel(value) {
|
|
8932
|
+
const raw = value.trim();
|
|
8933
|
+
const rawLower = raw.toLocaleLowerCase('pt-BR');
|
|
8934
|
+
if (rawLower.includes('/api/praxis/config/domain-rules')) {
|
|
8935
|
+
return 'revisão da regra';
|
|
8936
|
+
}
|
|
8937
|
+
if (rawLower.startsWith('/api/')) {
|
|
8938
|
+
return this.shortPathLabel(raw);
|
|
8939
|
+
}
|
|
8940
|
+
const normalized = value
|
|
8599
8941
|
.trim()
|
|
8600
8942
|
.replace(/^praxis-/u, '')
|
|
8601
8943
|
.replace(/@.*$/u, '')
|
|
8602
8944
|
.replace(/[_-]+/gu, ' ')
|
|
8603
8945
|
.trim();
|
|
8946
|
+
const lower = normalized.toLocaleLowerCase('pt-BR');
|
|
8947
|
+
const labels = {
|
|
8948
|
+
chart: 'gráfico',
|
|
8949
|
+
table: 'tabela',
|
|
8950
|
+
form: 'formulário',
|
|
8951
|
+
dashboard: 'painel',
|
|
8952
|
+
capability: 'permitido',
|
|
8953
|
+
'fonte candidata': 'Fonte de dados',
|
|
8954
|
+
'bind kpi value': 'Preencher indicador',
|
|
8955
|
+
'bind kpi values': 'Preencher indicadores',
|
|
8956
|
+
'add chart': 'Adicionar gráfico',
|
|
8957
|
+
'add charts': 'Adicionar gráficos',
|
|
8958
|
+
'add surface': 'Adicionar detalhe',
|
|
8959
|
+
'add surfaces': 'Adicionar detalhes',
|
|
8960
|
+
modify: 'alterar',
|
|
8961
|
+
create: 'criar',
|
|
8962
|
+
review: 'revisar',
|
|
8963
|
+
'shared rules': 'regras compartilhadas',
|
|
8964
|
+
'workflow action': 'ação do fluxo',
|
|
8965
|
+
'route required': 'revisão obrigatória',
|
|
8966
|
+
'blocked by governed shared rule route': 'prévia bloqueada até revisão',
|
|
8967
|
+
'domain catalog/context': 'catálogo governado',
|
|
8968
|
+
'compliance review': 'revisão de conformidade',
|
|
8969
|
+
surface: 'detalhe',
|
|
8970
|
+
surfaces: 'detalhes',
|
|
8971
|
+
action: 'ação',
|
|
8972
|
+
actions: 'ações',
|
|
8973
|
+
'set chart type': 'tipo do gráfico',
|
|
8974
|
+
'enable chart drilldown': 'detalhe do gráfico',
|
|
8975
|
+
'configure export': 'exportação',
|
|
8976
|
+
'create table': 'criar tabela',
|
|
8977
|
+
'create dashboard': 'criar painel',
|
|
8978
|
+
'create form': 'criar formulário',
|
|
8979
|
+
analytical: 'analítica',
|
|
8980
|
+
operational: 'operacional',
|
|
8981
|
+
reference: 'referência',
|
|
8982
|
+
'api metadata': 'metadados da API',
|
|
8983
|
+
'domain catalog context': 'catálogo governado',
|
|
8984
|
+
'analytics folha pagamento': 'Analytics Folha Pagamento',
|
|
8985
|
+
'acordos regulatorios': 'Acordos Regulatórios',
|
|
8986
|
+
'folha pagamento': 'Folha Pagamento',
|
|
8987
|
+
};
|
|
8988
|
+
if (lower.startsWith('capability ')) {
|
|
8989
|
+
return `Regra atendida ${normalized.slice('capability '.length)}`;
|
|
8990
|
+
}
|
|
8991
|
+
if (/[·|]/u.test(normalized)) {
|
|
8992
|
+
return normalized
|
|
8993
|
+
.split(/\s*[·|]\s*/u)
|
|
8994
|
+
.filter(Boolean)
|
|
8995
|
+
.map((part) => labels[part.toLocaleLowerCase('pt-BR')] ?? part)
|
|
8996
|
+
.join(' · ');
|
|
8997
|
+
}
|
|
8998
|
+
return labels[lower] ?? this.normalizePortugueseDisplayText(normalized);
|
|
8999
|
+
}
|
|
9000
|
+
normalizePortugueseDisplayText(value) {
|
|
9001
|
+
return value
|
|
9002
|
+
.replace(/\banalises\b/giu, 'análises')
|
|
9003
|
+
.replace(/\bgraficos\b/giu, 'gráficos')
|
|
9004
|
+
.replace(/\bpaineis\b/giu, 'painéis')
|
|
9005
|
+
.replace(/\bformularios\b/giu, 'formulários')
|
|
9006
|
+
.replace(/\boperacao\b/giu, 'operação')
|
|
9007
|
+
.replace(/\boperacoes\b/giu, 'operações')
|
|
9008
|
+
.replace(/\bmissao\b/giu, 'missão')
|
|
9009
|
+
.replace(/\bexecucao\b/giu, 'execução')
|
|
9010
|
+
.replace(/\btendencia\b/giu, 'tendência')
|
|
9011
|
+
.replace(/\bcatalogo\b/giu, 'catálogo')
|
|
9012
|
+
.replace(/\bcompetencia\b/giu, 'competência')
|
|
9013
|
+
.replace(/\bfuncionarios\b/giu, 'funcionários')
|
|
9014
|
+
.replace(/\bregulatorios\b/giu, 'regulatórios');
|
|
8604
9015
|
}
|
|
8605
9016
|
getCloseIcon() {
|
|
8606
9017
|
const label = this.resolvedLabels.close.toLocaleLowerCase('pt-BR');
|
|
8607
9018
|
return label.includes('minimiz') ? 'horizontal_rule' : 'close';
|
|
8608
9019
|
}
|
|
9020
|
+
getContextItemValue(item) {
|
|
9021
|
+
return item.value ? this.friendlyTechnicalLabel(item.value) : '';
|
|
9022
|
+
}
|
|
8609
9023
|
normalizeShellAction(action, fallback) {
|
|
8610
9024
|
const source = action ?? fallback;
|
|
8611
9025
|
return {
|
|
@@ -8949,7 +9363,7 @@ class PraxisAiAssistantShellComponent {
|
|
|
8949
9363
|
this.ownedPreviewUrls.delete(previewUrl);
|
|
8950
9364
|
}
|
|
8951
9365
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8952
|
-
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", recommendedIntents: "recommendedIntents", 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", voiceInputMode: "voiceInputMode", voiceLanguage: "voiceLanguage", 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", recommendedIntent: "recommendedIntent", layoutChange: "layoutChange" }, providers: [PraxisBrowserSpeechTranscriptionService], 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 @if (shouldShowRecommendedIntents()) {\n <section\n class=\"praxis-ai-assistant-shell__recommended\"\n [attr.aria-label]=\"resolvedLabels.recommendedIntentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intents'\"\n >\n <div class=\"praxis-ai-assistant-shell__recommended-header\">\n <mat-icon aria-hidden=\"true\">auto_awesome</mat-icon>\n <span>{{ resolvedLabels.recommendedIntentsTitle }}</span>\n </div>\n <div class=\"praxis-ai-assistant-shell__recommended-list\">\n @for (intent of recommendedIntents; track trackRecommendedIntent($index, intent)) {\n <button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__recommended-intent\"\n [ngClass]=\"'praxis-ai-assistant-shell__recommended-intent--tone-' + getRecommendedIntentTone(intent)\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intent-' + intent.id\"\n [attr.aria-label]=\"getRecommendedIntentAriaLabel(intent)\"\n [disabled]=\"isRecommendedIntentDisabled(intent)\"\n (click)=\"onRecommendedIntent(intent)\"\n >\n <span class=\"praxis-ai-assistant-shell__recommended-icon\" aria-hidden=\"true\">\n <mat-icon>{{ getRecommendedIntentIcon(intent) }}</mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__recommended-copy\">\n <span class=\"praxis-ai-assistant-shell__recommended-title-row\">\n <span class=\"praxis-ai-assistant-shell__recommended-title\">{{ intent.label }}</span>\n @if (getRecommendedIntentGroupLabel(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-group\">\n {{ getRecommendedIntentGroupLabel(intent) }}\n </span>\n }\n </span>\n @if (getRecommendedIntentDescription(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-description\">\n {{ getRecommendedIntentDescription(intent) }}\n </span>\n }\n <span class=\"praxis-ai-assistant-shell__recommended-cta\">\n @if (intent.requiresConfirmation && !intent.disabledReason) {\n <span>{{ resolvedLabels.recommendedIntentRequiresConfirmation }}</span>\n }\n <span>{{ getRecommendedIntentCtaLabel(intent) }}</span>\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n }\n </div>\n </section>\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 @if (canSendMessageFeedback(message)) {\n <div class=\"praxis-ai-assistant-shell__message-feedback\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackPositive\"\n [attr.aria-label]=\"resolvedLabels.feedbackPositive\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-positive-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'positive')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_up</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackNegative\"\n [attr.aria-label]=\"resolvedLabels.feedbackNegative\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-negative-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'negative')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_down</mat-icon>\n </button>\n </div>\n } @else if (isMessageFeedbackSubmitted(message)) {\n <div\n class=\"praxis-ai-assistant-shell__message-feedback-submitted\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-submitted-' + message.id\"\n >\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n <span>{{ resolvedLabels.feedbackSubmitted }}</span>\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.ariaLabel + ':' + chip.value) {\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.key) {\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 {{ getAuxiliaryStatusText() }}\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 (shouldShowVoiceInput()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__voice-action\"\n [class.praxis-ai-assistant-shell__voice-action--active]=\"isVoiceInputBusy()\"\n [class.praxis-ai-assistant-shell__voice-action--error]=\"voiceCaptureState === 'error' || voiceCaptureState === 'unsupported'\"\n [disabled]=\"isVoiceInputDisabled()\"\n [matTooltip]=\"getVoiceActionLabel()\"\n [attr.aria-label]=\"getVoiceActionLabel()\"\n [attr.aria-pressed]=\"isVoiceInputBusy() ? 'true' : 'false'\"\n [attr.data-testid]=\"testIdPrefix + '-voice'\"\n (click)=\"onVoiceInputClick()\"\n >\n <mat-icon aria-hidden=\"true\">{{ isVoiceInputBusy() ? 'stop_circle' : 'mic' }}</mat-icon>\n </button>\n }\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 @if (shouldShowVoiceFeedback()) {\n <p\n class=\"praxis-ai-assistant-shell__voice-status\"\n aria-live=\"polite\"\n [attr.data-testid]=\"testIdPrefix + '-voice-status'\"\n >\n {{ voiceFeedbackText }}\n </p>\n }\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__recommended{flex:0 0 auto;display:grid;gap:8px}.praxis-ai-assistant-shell__recommended-header{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600;line-height:1.25}.praxis-ai-assistant-shell__recommended-header mat-icon{width:16px;height:16px;color:var(--md-sys-color-primary);font-size:16px;line-height:16px}.praxis-ai-assistant-shell__recommended-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr));gap:8px}.praxis-ai-assistant-shell__recommended-intent{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral);appearance:none;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 34%,transparent);border-radius:8px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 8%,transparent),transparent),var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);cursor:pointer;display:flex;gap:9px;min-width:0;min-height:86px;padding:10px;text-align:left;transition:border-color .16s ease,box-shadow .16s ease,background-color .16s ease}.praxis-ai-assistant-shell__recommended-intent:hover:not(:disabled),.praxis-ai-assistant-shell__recommended-intent:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 68%,transparent);box-shadow:0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 15%,transparent);outline:none}.praxis-ai-assistant-shell__recommended-intent:disabled{cursor:default;opacity:.62}.praxis-ai-assistant-shell__recommended-icon{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 28%,transparent);border-radius:8px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 12%,transparent);color:var(--praxis-ai-assistant-shell-recommended-accent)}.praxis-ai-assistant-shell__recommended-icon mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__recommended-copy{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__recommended-title-row{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.praxis-ai-assistant-shell__recommended-title,.praxis-ai-assistant-shell__recommended-description,.praxis-ai-assistant-shell__recommended-group{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__recommended-title{color:var(--md-sys-color-on-surface);font-size:13px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-group{flex:0 1 auto;max-width:44%;border-radius:8px;padding:2px 6px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 10%,transparent);color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-description{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__recommended-cta{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:11.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-cta mat-icon{width:15px;height:15px;font-size:15px;line-height:15px}.praxis-ai-assistant-shell__recommended-intent--tone-analytics{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__recommended-intent--tone-resource{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__recommended-intent--tone-success{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__recommended-intent--tone-warning{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__recommended-intent--tone-danger{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__recommended-intent--tone-neutral{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral)}.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-feedback,.praxis-ai-assistant-shell__message-feedback-submitted{display:flex;align-items:center;gap:4px;margin-top:8px}.praxis-ai-assistant-shell__message-feedback-action{--mdc-icon-button-state-layer-size: 30px;--mat-icon-button-state-layer-size: 30px;display:inline-grid;place-items:center;width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1}.praxis-ai-assistant-shell__message-feedback-action mat-icon,.praxis-ai-assistant-shell__message-feedback-submitted mat-icon{display:block;width:17px;height:17px;font-size:17px;line-height:17px}.praxis-ai-assistant-shell__message-feedback-submitted{color:var(--md-sys-color-on-surface-variant);font-size:12px}.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(--md-sys-color-outline-variant) 82%,transparent);border-radius:8px;background: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{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--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 64%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 18%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 14%,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--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame{border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-high))}.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--guided-action .praxis-ai-assistant-shell__quick-reply-description{color:var(--md-sys-color-on-surface-variant)}.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--guided-action .praxis-ai-assistant-shell__quick-reply-badge{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 62%,transparent)}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta{color:var(--md-sys-color-primary)}.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__voice-action{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__voice-action--active{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__voice-action--error{color:var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__voice-status{margin:-2px 10px 8px;color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.3}.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 });
|
|
9366
|
+
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", recommendedIntents: "recommendedIntents", 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", voiceInputMode: "voiceInputMode", voiceLanguage: "voiceLanguage", 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", recommendedIntent: "recommendedIntent", layoutChange: "layoutChange" }, providers: [PraxisBrowserSpeechTranscriptionService], 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\">{{ getContextItemValue(item) }}</span>\n }\n </span>\n }\n </div>\n }\n\n @if (shouldShowRecommendedIntents()) {\n <section\n class=\"praxis-ai-assistant-shell__recommended\"\n [attr.aria-label]=\"resolvedLabels.recommendedIntentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intents'\"\n >\n <div class=\"praxis-ai-assistant-shell__recommended-header\">\n <mat-icon aria-hidden=\"true\">auto_awesome</mat-icon>\n <span>{{ resolvedLabels.recommendedIntentsTitle }}</span>\n </div>\n <div class=\"praxis-ai-assistant-shell__recommended-list\">\n @for (intent of recommendedIntents; track trackRecommendedIntent($index, intent)) {\n <button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__recommended-intent\"\n [ngClass]=\"'praxis-ai-assistant-shell__recommended-intent--tone-' + getRecommendedIntentTone(intent)\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intent-' + intent.id\"\n [attr.aria-label]=\"getRecommendedIntentAriaLabel(intent)\"\n [disabled]=\"isRecommendedIntentDisabled(intent)\"\n (click)=\"onRecommendedIntent(intent)\"\n >\n <span class=\"praxis-ai-assistant-shell__recommended-icon\" aria-hidden=\"true\">\n <mat-icon>{{ getRecommendedIntentIcon(intent) }}</mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__recommended-copy\">\n <span class=\"praxis-ai-assistant-shell__recommended-title-row\">\n <span class=\"praxis-ai-assistant-shell__recommended-title\">{{ intent.label }}</span>\n @if (getRecommendedIntentGroupLabel(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-group\">\n {{ getRecommendedIntentGroupLabel(intent) }}\n </span>\n }\n </span>\n @if (getRecommendedIntentDescription(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-description\">\n {{ getRecommendedIntentDescription(intent) }}\n </span>\n }\n <span class=\"praxis-ai-assistant-shell__recommended-cta\">\n @if (intent.requiresConfirmation && !intent.disabledReason) {\n <span>{{ resolvedLabels.recommendedIntentRequiresConfirmation }}</span>\n }\n <span>{{ getRecommendedIntentCtaLabel(intent) }}</span>\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n }\n </div>\n </section>\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 >\n @if (hasStructuredAssistantContent(message)) {\n <div class=\"praxis-ai-assistant-shell__assistant-content\">\n @for (block of getAssistantContentBlocks(message); track trackAssistantContentBlock($index, block)) {\n @switch (getAssistantContentBlockType(block)) {\n @case ('paragraph') {\n <section class=\"praxis-ai-assistant-shell__assistant-block praxis-ai-assistant-shell__assistant-block--summary\">\n <span class=\"praxis-ai-assistant-shell__assistant-block-icon\" aria-hidden=\"true\">\n <mat-icon>lightbulb</mat-icon>\n </span>\n <div\n class=\"praxis-ai-assistant-shell__assistant-block-copy\"\n [innerHTML]=\"renderMessageText(getAssistantContentBlockText(block))\"\n ></div>\n </section>\n }\n @case ('resource-list') {\n <section class=\"praxis-ai-assistant-shell__assistant-block\">\n <div class=\"praxis-ai-assistant-shell__assistant-block-heading\">\n <mat-icon aria-hidden=\"true\">database</mat-icon>\n <span>{{ getAssistantContentBlockTitle(block, 'Fontes confirmadas') }}</span>\n </div>\n <div class=\"praxis-ai-assistant-shell__assistant-resources\">\n @for (resource of getAssistantContentResources(block); track trackAssistantContentResource($index, resource)) {\n <article class=\"praxis-ai-assistant-shell__assistant-resource\">\n <div class=\"praxis-ai-assistant-shell__assistant-resource-head\">\n <strong>{{ resource.label }}</strong>\n @if (getAssistantContentResourceMeta(resource).length) {\n <span class=\"praxis-ai-assistant-shell__assistant-resource-meta\">\n @for (item of getAssistantContentResourceMeta(resource); track trackAssistantContentValue($index, item)) {\n <span>{{ item }}</span>\n }\n </span>\n }\n </div>\n @if (resource.description) {\n <p>{{ resource.description }}</p>\n }\n @if (resource.fields.length) {\n <div class=\"praxis-ai-assistant-shell__assistant-field-list\" aria-label=\"Campos dispon\u00EDveis\">\n @for (field of resource.fields; track trackAssistantContentField($index, field)) {\n <span\n class=\"praxis-ai-assistant-shell__assistant-field\"\n [matTooltip]=\"field.description || field.name\"\n >\n {{ field.label }}\n </span>\n }\n </div>\n }\n @if (resource.evidence.length) {\n <div class=\"praxis-ai-assistant-shell__assistant-evidence\" aria-label=\"Evid\u00EAncias\">\n @for (item of resource.evidence; track trackAssistantContentValue($index, item)) {\n <span>\n <mat-icon aria-hidden=\"true\">verified</mat-icon>\n {{ item }}\n </span>\n }\n </div>\n }\n </article>\n }\n </div>\n </section>\n }\n @case ('recommendation') {\n <section class=\"praxis-ai-assistant-shell__assistant-block praxis-ai-assistant-shell__assistant-block--recommendation\">\n <span class=\"praxis-ai-assistant-shell__assistant-block-icon\" aria-hidden=\"true\">\n <mat-icon>recommend</mat-icon>\n </span>\n <div class=\"praxis-ai-assistant-shell__assistant-block-copy\">\n <strong>{{ getAssistantContentBlockTitle(block, 'Recomenda\u00E7\u00E3o') }}</strong>\n <p>{{ getAssistantContentBlockText(block) }}</p>\n </div>\n </section>\n }\n }\n }\n </div>\n } @else {\n <div [innerHTML]=\"renderMessageText(message.text)\"></div>\n }\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 @if (canSendMessageFeedback(message)) {\n <div class=\"praxis-ai-assistant-shell__message-feedback\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackPositive\"\n [attr.aria-label]=\"resolvedLabels.feedbackPositive\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-positive-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'positive')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_up</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackNegative\"\n [attr.aria-label]=\"resolvedLabels.feedbackNegative\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-negative-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'negative')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_down</mat-icon>\n </button>\n </div>\n } @else if (isMessageFeedbackSubmitted(message)) {\n <div\n class=\"praxis-ai-assistant-shell__message-feedback-submitted\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-submitted-' + message.id\"\n >\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n <span>{{ resolvedLabels.feedbackSubmitted }}</span>\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 [class.praxis-ai-assistant-shell__quick-reply--source-review]=\"isSourceReviewQuickReply(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\">{{ getQuickReplyLabel(reply) }}</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.ariaLabel + ':' + chip.value) {\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.key) {\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 {{ getAuxiliaryStatusText() }}\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 (shouldShowVoiceInput()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__voice-action\"\n [class.praxis-ai-assistant-shell__voice-action--active]=\"isVoiceInputBusy()\"\n [class.praxis-ai-assistant-shell__voice-action--error]=\"voiceCaptureState === 'error' || voiceCaptureState === 'unsupported'\"\n [disabled]=\"isVoiceInputDisabled()\"\n [matTooltip]=\"getVoiceActionLabel()\"\n [attr.aria-label]=\"getVoiceActionLabel()\"\n [attr.aria-pressed]=\"isVoiceInputBusy() ? 'true' : 'false'\"\n [attr.data-testid]=\"testIdPrefix + '-voice'\"\n (click)=\"onVoiceInputClick()\"\n >\n <mat-icon aria-hidden=\"true\">{{ isVoiceInputBusy() ? 'stop_circle' : 'mic' }}</mat-icon>\n </button>\n }\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 @if (shouldShowVoiceFeedback()) {\n <p\n class=\"praxis-ai-assistant-shell__voice-status\"\n aria-live=\"polite\"\n [attr.data-testid]=\"testIdPrefix + '-voice-status'\"\n >\n {{ voiceFeedbackText }}\n </p>\n }\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;position:fixed;inset:0;z-index:var(--praxis-ai-assistant-shell-z-index, 1200);pointer-events:none}.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);pointer-events:auto;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__recommended{flex:0 0 auto;display:grid;gap:8px}.praxis-ai-assistant-shell__recommended-header{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600;line-height:1.25}.praxis-ai-assistant-shell__recommended-header mat-icon{width:16px;height:16px;color:var(--md-sys-color-primary);font-size:16px;line-height:16px}.praxis-ai-assistant-shell__recommended-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr));gap:8px}.praxis-ai-assistant-shell__recommended-intent{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral);appearance:none;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 34%,transparent);border-radius:8px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 8%,transparent),transparent),var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);cursor:pointer;display:flex;gap:9px;min-width:0;min-height:86px;padding:10px;text-align:left;transition:border-color .16s ease,box-shadow .16s ease,background-color .16s ease}.praxis-ai-assistant-shell__recommended-intent:hover:not(:disabled),.praxis-ai-assistant-shell__recommended-intent:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 68%,transparent);box-shadow:0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 15%,transparent);outline:none}.praxis-ai-assistant-shell__recommended-intent:disabled{cursor:default;opacity:.62}.praxis-ai-assistant-shell__recommended-icon{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 28%,transparent);border-radius:8px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 12%,transparent);color:var(--praxis-ai-assistant-shell-recommended-accent)}.praxis-ai-assistant-shell__recommended-icon mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__recommended-copy{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__recommended-title-row{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.praxis-ai-assistant-shell__recommended-title,.praxis-ai-assistant-shell__recommended-description,.praxis-ai-assistant-shell__recommended-group{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__recommended-title{color:var(--md-sys-color-on-surface);font-size:13px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-group{flex:0 1 auto;max-width:44%;border-radius:8px;padding:2px 6px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 10%,transparent);color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-description{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__recommended-cta{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:11.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-cta mat-icon{width:15px;height:15px;font-size:15px;line-height:15px}.praxis-ai-assistant-shell__recommended-intent--tone-analytics{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__recommended-intent--tone-resource{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__recommended-intent--tone-success{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__recommended-intent--tone-warning{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__recommended-intent--tone-danger{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__recommended-intent--tone-neutral{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral)}.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__assistant-content{display:grid;gap:8px}.praxis-ai-assistant-shell__assistant-block{display:grid;gap:8px;min-width:0}.praxis-ai-assistant-shell__assistant-block--summary,.praxis-ai-assistant-shell__assistant-block--recommendation{grid-template-columns:auto minmax(0,1fr);align-items:flex-start;padding:9px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent);border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary) 7%,transparent)}.praxis-ai-assistant-shell__assistant-block--recommendation{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 26%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 8%,transparent)}.praxis-ai-assistant-shell__assistant-block-icon{display:grid;place-items:center;width:24px;height:24px;border-radius:8px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent)}.praxis-ai-assistant-shell__assistant-block--recommendation .praxis-ai-assistant-shell__assistant-block-icon{color:var(--praxis-ai-assistant-shell-tone-success);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 14%,transparent)}.praxis-ai-assistant-shell__assistant-block-icon mat-icon{width:16px;height:16px;font-size:16px;line-height:16px}.praxis-ai-assistant-shell__assistant-block-copy{min-width:0}.praxis-ai-assistant-shell__assistant-block-copy strong{display:block;margin-bottom:3px}.praxis-ai-assistant-shell__assistant-block-heading{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-surface);font-size:12px;font-weight:700}.praxis-ai-assistant-shell__assistant-block-heading mat-icon{width:16px;height:16px;color:var(--md-sys-color-primary);font-size:16px}.praxis-ai-assistant-shell__assistant-resources{display:grid;gap:7px}.praxis-ai-assistant-shell__assistant-resource{display:grid;gap:7px;min-width:0;padding:9px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-surface-container-highest) 74%,transparent)}.praxis-ai-assistant-shell__assistant-resource-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;min-width:0}.praxis-ai-assistant-shell__assistant-resource-head strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__assistant-resource-meta,.praxis-ai-assistant-shell__assistant-field-list,.praxis-ai-assistant-shell__assistant-evidence{display:flex;flex-wrap:wrap;gap:5px}.praxis-ai-assistant-shell__assistant-resource-meta span,.praxis-ai-assistant-shell__assistant-field,.praxis-ai-assistant-shell__assistant-evidence span{display:inline-flex;align-items:center;gap:4px;min-width:0;max-width:100%;padding:3px 6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 62%,transparent);border-radius:999px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);font-size:11px;line-height:1.25}.praxis-ai-assistant-shell__assistant-field{color:color-mix(in srgb,var(--md-sys-color-primary) 88%,var(--md-sys-color-on-surface));background:color-mix(in srgb,var(--md-sys-color-primary) 9%,transparent);border-color:color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.praxis-ai-assistant-shell__assistant-evidence span{color:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 85%,var(--md-sys-color-on-surface));background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 9%,transparent);border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 22%,transparent)}.praxis-ai-assistant-shell__assistant-evidence mat-icon{width:13px;height:13px;font-size:13px}.praxis-ai-assistant-shell__assistant-resource p{margin:0;color:var(--md-sys-color-on-surface-variant)}.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-feedback,.praxis-ai-assistant-shell__message-feedback-submitted{display:flex;align-items:center;gap:4px;margin-top:8px}.praxis-ai-assistant-shell__message-feedback-action{--mdc-icon-button-state-layer-size: 30px;--mat-icon-button-state-layer-size: 30px;display:inline-grid;place-items:center;width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1}.praxis-ai-assistant-shell__message-feedback-action mat-icon,.praxis-ai-assistant-shell__message-feedback-submitted mat-icon{display:block;width:17px;height:17px;font-size:17px;line-height:17px}.praxis-ai-assistant-shell__message-feedback-submitted{color:var(--md-sys-color-on-surface-variant);font-size:12px}.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(--md-sys-color-outline-variant) 82%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--source-review{padding:11px 12px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 88%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 7%,transparent),transparent 58%),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{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--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible,.praxis-ai-assistant-shell__quick-reply--source-review:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--source-review:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 64%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 18%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 14%,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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review ::ng-deep .mdc-button__label{gap:10px;align-items:flex-start}.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,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:8px;box-shadow:none}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-icon-frame{border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-high))}.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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review .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--guided-action .praxis-ai-assistant-shell__quick-reply-description{color:var(--md-sys-color-on-surface-variant)}.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,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-badge{border-radius:8px;font-size:10px;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-badge{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 62%,transparent)}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-cta{color:var(--md-sys-color-primary)}.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-context{gap:5px}.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-context-chip{border-radius:8px;padding:4px 7px;background:color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 66%,transparent);font-size:10.5px;font-weight:650}.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-actions{max-width:40%}.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,.praxis-ai-assistant-shell__quick-reply--source-review .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__voice-action{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__voice-action--active{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__voice-action--error{color:var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__voice-status{margin:-2px 10px 8px;color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.3}.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 });
|
|
8953
9367
|
}
|
|
8954
9368
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisAiAssistantShellComponent, decorators: [{
|
|
8955
9369
|
type: Component,
|
|
@@ -8960,7 +9374,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
8960
9374
|
MatIconModule,
|
|
8961
9375
|
MatProgressSpinnerModule,
|
|
8962
9376
|
MatTooltipModule,
|
|
8963
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [PraxisBrowserSpeechTranscriptionService], 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 @if (shouldShowRecommendedIntents()) {\n <section\n class=\"praxis-ai-assistant-shell__recommended\"\n [attr.aria-label]=\"resolvedLabels.recommendedIntentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intents'\"\n >\n <div class=\"praxis-ai-assistant-shell__recommended-header\">\n <mat-icon aria-hidden=\"true\">auto_awesome</mat-icon>\n <span>{{ resolvedLabels.recommendedIntentsTitle }}</span>\n </div>\n <div class=\"praxis-ai-assistant-shell__recommended-list\">\n @for (intent of recommendedIntents; track trackRecommendedIntent($index, intent)) {\n <button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__recommended-intent\"\n [ngClass]=\"'praxis-ai-assistant-shell__recommended-intent--tone-' + getRecommendedIntentTone(intent)\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intent-' + intent.id\"\n [attr.aria-label]=\"getRecommendedIntentAriaLabel(intent)\"\n [disabled]=\"isRecommendedIntentDisabled(intent)\"\n (click)=\"onRecommendedIntent(intent)\"\n >\n <span class=\"praxis-ai-assistant-shell__recommended-icon\" aria-hidden=\"true\">\n <mat-icon>{{ getRecommendedIntentIcon(intent) }}</mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__recommended-copy\">\n <span class=\"praxis-ai-assistant-shell__recommended-title-row\">\n <span class=\"praxis-ai-assistant-shell__recommended-title\">{{ intent.label }}</span>\n @if (getRecommendedIntentGroupLabel(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-group\">\n {{ getRecommendedIntentGroupLabel(intent) }}\n </span>\n }\n </span>\n @if (getRecommendedIntentDescription(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-description\">\n {{ getRecommendedIntentDescription(intent) }}\n </span>\n }\n <span class=\"praxis-ai-assistant-shell__recommended-cta\">\n @if (intent.requiresConfirmation && !intent.disabledReason) {\n <span>{{ resolvedLabels.recommendedIntentRequiresConfirmation }}</span>\n }\n <span>{{ getRecommendedIntentCtaLabel(intent) }}</span>\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n }\n </div>\n </section>\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 @if (canSendMessageFeedback(message)) {\n <div class=\"praxis-ai-assistant-shell__message-feedback\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackPositive\"\n [attr.aria-label]=\"resolvedLabels.feedbackPositive\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-positive-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'positive')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_up</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackNegative\"\n [attr.aria-label]=\"resolvedLabels.feedbackNegative\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-negative-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'negative')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_down</mat-icon>\n </button>\n </div>\n } @else if (isMessageFeedbackSubmitted(message)) {\n <div\n class=\"praxis-ai-assistant-shell__message-feedback-submitted\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-submitted-' + message.id\"\n >\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n <span>{{ resolvedLabels.feedbackSubmitted }}</span>\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.ariaLabel + ':' + chip.value) {\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.key) {\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 {{ getAuxiliaryStatusText() }}\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 (shouldShowVoiceInput()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__voice-action\"\n [class.praxis-ai-assistant-shell__voice-action--active]=\"isVoiceInputBusy()\"\n [class.praxis-ai-assistant-shell__voice-action--error]=\"voiceCaptureState === 'error' || voiceCaptureState === 'unsupported'\"\n [disabled]=\"isVoiceInputDisabled()\"\n [matTooltip]=\"getVoiceActionLabel()\"\n [attr.aria-label]=\"getVoiceActionLabel()\"\n [attr.aria-pressed]=\"isVoiceInputBusy() ? 'true' : 'false'\"\n [attr.data-testid]=\"testIdPrefix + '-voice'\"\n (click)=\"onVoiceInputClick()\"\n >\n <mat-icon aria-hidden=\"true\">{{ isVoiceInputBusy() ? 'stop_circle' : 'mic' }}</mat-icon>\n </button>\n }\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 @if (shouldShowVoiceFeedback()) {\n <p\n class=\"praxis-ai-assistant-shell__voice-status\"\n aria-live=\"polite\"\n [attr.data-testid]=\"testIdPrefix + '-voice-status'\"\n >\n {{ voiceFeedbackText }}\n </p>\n }\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__recommended{flex:0 0 auto;display:grid;gap:8px}.praxis-ai-assistant-shell__recommended-header{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600;line-height:1.25}.praxis-ai-assistant-shell__recommended-header mat-icon{width:16px;height:16px;color:var(--md-sys-color-primary);font-size:16px;line-height:16px}.praxis-ai-assistant-shell__recommended-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr));gap:8px}.praxis-ai-assistant-shell__recommended-intent{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral);appearance:none;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 34%,transparent);border-radius:8px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 8%,transparent),transparent),var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);cursor:pointer;display:flex;gap:9px;min-width:0;min-height:86px;padding:10px;text-align:left;transition:border-color .16s ease,box-shadow .16s ease,background-color .16s ease}.praxis-ai-assistant-shell__recommended-intent:hover:not(:disabled),.praxis-ai-assistant-shell__recommended-intent:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 68%,transparent);box-shadow:0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 15%,transparent);outline:none}.praxis-ai-assistant-shell__recommended-intent:disabled{cursor:default;opacity:.62}.praxis-ai-assistant-shell__recommended-icon{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 28%,transparent);border-radius:8px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 12%,transparent);color:var(--praxis-ai-assistant-shell-recommended-accent)}.praxis-ai-assistant-shell__recommended-icon mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__recommended-copy{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__recommended-title-row{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.praxis-ai-assistant-shell__recommended-title,.praxis-ai-assistant-shell__recommended-description,.praxis-ai-assistant-shell__recommended-group{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__recommended-title{color:var(--md-sys-color-on-surface);font-size:13px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-group{flex:0 1 auto;max-width:44%;border-radius:8px;padding:2px 6px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 10%,transparent);color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-description{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__recommended-cta{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:11.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-cta mat-icon{width:15px;height:15px;font-size:15px;line-height:15px}.praxis-ai-assistant-shell__recommended-intent--tone-analytics{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__recommended-intent--tone-resource{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__recommended-intent--tone-success{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__recommended-intent--tone-warning{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__recommended-intent--tone-danger{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__recommended-intent--tone-neutral{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral)}.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-feedback,.praxis-ai-assistant-shell__message-feedback-submitted{display:flex;align-items:center;gap:4px;margin-top:8px}.praxis-ai-assistant-shell__message-feedback-action{--mdc-icon-button-state-layer-size: 30px;--mat-icon-button-state-layer-size: 30px;display:inline-grid;place-items:center;width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1}.praxis-ai-assistant-shell__message-feedback-action mat-icon,.praxis-ai-assistant-shell__message-feedback-submitted mat-icon{display:block;width:17px;height:17px;font-size:17px;line-height:17px}.praxis-ai-assistant-shell__message-feedback-submitted{color:var(--md-sys-color-on-surface-variant);font-size:12px}.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(--md-sys-color-outline-variant) 82%,transparent);border-radius:8px;background: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{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--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 64%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 18%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 14%,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--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame{border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-high))}.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--guided-action .praxis-ai-assistant-shell__quick-reply-description{color:var(--md-sys-color-on-surface-variant)}.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--guided-action .praxis-ai-assistant-shell__quick-reply-badge{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 62%,transparent)}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta{color:var(--md-sys-color-primary)}.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__voice-action{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__voice-action--active{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__voice-action--error{color:var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__voice-status{margin:-2px 10px 8px;color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.3}.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"] }]
|
|
9377
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [PraxisBrowserSpeechTranscriptionService], 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\">{{ getContextItemValue(item) }}</span>\n }\n </span>\n }\n </div>\n }\n\n @if (shouldShowRecommendedIntents()) {\n <section\n class=\"praxis-ai-assistant-shell__recommended\"\n [attr.aria-label]=\"resolvedLabels.recommendedIntentsAria\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intents'\"\n >\n <div class=\"praxis-ai-assistant-shell__recommended-header\">\n <mat-icon aria-hidden=\"true\">auto_awesome</mat-icon>\n <span>{{ resolvedLabels.recommendedIntentsTitle }}</span>\n </div>\n <div class=\"praxis-ai-assistant-shell__recommended-list\">\n @for (intent of recommendedIntents; track trackRecommendedIntent($index, intent)) {\n <button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__recommended-intent\"\n [ngClass]=\"'praxis-ai-assistant-shell__recommended-intent--tone-' + getRecommendedIntentTone(intent)\"\n [attr.data-testid]=\"testIdPrefix + '-recommended-intent-' + intent.id\"\n [attr.aria-label]=\"getRecommendedIntentAriaLabel(intent)\"\n [disabled]=\"isRecommendedIntentDisabled(intent)\"\n (click)=\"onRecommendedIntent(intent)\"\n >\n <span class=\"praxis-ai-assistant-shell__recommended-icon\" aria-hidden=\"true\">\n <mat-icon>{{ getRecommendedIntentIcon(intent) }}</mat-icon>\n </span>\n <span class=\"praxis-ai-assistant-shell__recommended-copy\">\n <span class=\"praxis-ai-assistant-shell__recommended-title-row\">\n <span class=\"praxis-ai-assistant-shell__recommended-title\">{{ intent.label }}</span>\n @if (getRecommendedIntentGroupLabel(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-group\">\n {{ getRecommendedIntentGroupLabel(intent) }}\n </span>\n }\n </span>\n @if (getRecommendedIntentDescription(intent)) {\n <span class=\"praxis-ai-assistant-shell__recommended-description\">\n {{ getRecommendedIntentDescription(intent) }}\n </span>\n }\n <span class=\"praxis-ai-assistant-shell__recommended-cta\">\n @if (intent.requiresConfirmation && !intent.disabledReason) {\n <span>{{ resolvedLabels.recommendedIntentRequiresConfirmation }}</span>\n }\n <span>{{ getRecommendedIntentCtaLabel(intent) }}</span>\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </span>\n </span>\n </button>\n }\n </div>\n </section>\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 >\n @if (hasStructuredAssistantContent(message)) {\n <div class=\"praxis-ai-assistant-shell__assistant-content\">\n @for (block of getAssistantContentBlocks(message); track trackAssistantContentBlock($index, block)) {\n @switch (getAssistantContentBlockType(block)) {\n @case ('paragraph') {\n <section class=\"praxis-ai-assistant-shell__assistant-block praxis-ai-assistant-shell__assistant-block--summary\">\n <span class=\"praxis-ai-assistant-shell__assistant-block-icon\" aria-hidden=\"true\">\n <mat-icon>lightbulb</mat-icon>\n </span>\n <div\n class=\"praxis-ai-assistant-shell__assistant-block-copy\"\n [innerHTML]=\"renderMessageText(getAssistantContentBlockText(block))\"\n ></div>\n </section>\n }\n @case ('resource-list') {\n <section class=\"praxis-ai-assistant-shell__assistant-block\">\n <div class=\"praxis-ai-assistant-shell__assistant-block-heading\">\n <mat-icon aria-hidden=\"true\">database</mat-icon>\n <span>{{ getAssistantContentBlockTitle(block, 'Fontes confirmadas') }}</span>\n </div>\n <div class=\"praxis-ai-assistant-shell__assistant-resources\">\n @for (resource of getAssistantContentResources(block); track trackAssistantContentResource($index, resource)) {\n <article class=\"praxis-ai-assistant-shell__assistant-resource\">\n <div class=\"praxis-ai-assistant-shell__assistant-resource-head\">\n <strong>{{ resource.label }}</strong>\n @if (getAssistantContentResourceMeta(resource).length) {\n <span class=\"praxis-ai-assistant-shell__assistant-resource-meta\">\n @for (item of getAssistantContentResourceMeta(resource); track trackAssistantContentValue($index, item)) {\n <span>{{ item }}</span>\n }\n </span>\n }\n </div>\n @if (resource.description) {\n <p>{{ resource.description }}</p>\n }\n @if (resource.fields.length) {\n <div class=\"praxis-ai-assistant-shell__assistant-field-list\" aria-label=\"Campos dispon\u00EDveis\">\n @for (field of resource.fields; track trackAssistantContentField($index, field)) {\n <span\n class=\"praxis-ai-assistant-shell__assistant-field\"\n [matTooltip]=\"field.description || field.name\"\n >\n {{ field.label }}\n </span>\n }\n </div>\n }\n @if (resource.evidence.length) {\n <div class=\"praxis-ai-assistant-shell__assistant-evidence\" aria-label=\"Evid\u00EAncias\">\n @for (item of resource.evidence; track trackAssistantContentValue($index, item)) {\n <span>\n <mat-icon aria-hidden=\"true\">verified</mat-icon>\n {{ item }}\n </span>\n }\n </div>\n }\n </article>\n }\n </div>\n </section>\n }\n @case ('recommendation') {\n <section class=\"praxis-ai-assistant-shell__assistant-block praxis-ai-assistant-shell__assistant-block--recommendation\">\n <span class=\"praxis-ai-assistant-shell__assistant-block-icon\" aria-hidden=\"true\">\n <mat-icon>recommend</mat-icon>\n </span>\n <div class=\"praxis-ai-assistant-shell__assistant-block-copy\">\n <strong>{{ getAssistantContentBlockTitle(block, 'Recomenda\u00E7\u00E3o') }}</strong>\n <p>{{ getAssistantContentBlockText(block) }}</p>\n </div>\n </section>\n }\n }\n }\n </div>\n } @else {\n <div [innerHTML]=\"renderMessageText(message.text)\"></div>\n }\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 @if (canSendMessageFeedback(message)) {\n <div class=\"praxis-ai-assistant-shell__message-feedback\">\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackPositive\"\n [attr.aria-label]=\"resolvedLabels.feedbackPositive\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-positive-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'positive')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_up</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__message-feedback-action\"\n [disabled]=\"busy\"\n [matTooltip]=\"resolvedLabels.feedbackNegative\"\n [attr.aria-label]=\"resolvedLabels.feedbackNegative\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-negative-' + message.id\"\n (click)=\"sendMessageFeedback(message, 'negative')\"\n >\n <mat-icon aria-hidden=\"true\">thumb_down</mat-icon>\n </button>\n </div>\n } @else if (isMessageFeedbackSubmitted(message)) {\n <div\n class=\"praxis-ai-assistant-shell__message-feedback-submitted\"\n [attr.data-testid]=\"testIdPrefix + '-message-feedback-submitted-' + message.id\"\n >\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n <span>{{ resolvedLabels.feedbackSubmitted }}</span>\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 [class.praxis-ai-assistant-shell__quick-reply--source-review]=\"isSourceReviewQuickReply(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\">{{ getQuickReplyLabel(reply) }}</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.ariaLabel + ':' + chip.value) {\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.key) {\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 {{ getAuxiliaryStatusText() }}\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 (shouldShowVoiceInput()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"praxis-ai-assistant-shell__voice-action\"\n [class.praxis-ai-assistant-shell__voice-action--active]=\"isVoiceInputBusy()\"\n [class.praxis-ai-assistant-shell__voice-action--error]=\"voiceCaptureState === 'error' || voiceCaptureState === 'unsupported'\"\n [disabled]=\"isVoiceInputDisabled()\"\n [matTooltip]=\"getVoiceActionLabel()\"\n [attr.aria-label]=\"getVoiceActionLabel()\"\n [attr.aria-pressed]=\"isVoiceInputBusy() ? 'true' : 'false'\"\n [attr.data-testid]=\"testIdPrefix + '-voice'\"\n (click)=\"onVoiceInputClick()\"\n >\n <mat-icon aria-hidden=\"true\">{{ isVoiceInputBusy() ? 'stop_circle' : 'mic' }}</mat-icon>\n </button>\n }\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 @if (shouldShowVoiceFeedback()) {\n <p\n class=\"praxis-ai-assistant-shell__voice-status\"\n aria-live=\"polite\"\n [attr.data-testid]=\"testIdPrefix + '-voice-status'\"\n >\n {{ voiceFeedbackText }}\n </p>\n }\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;position:fixed;inset:0;z-index:var(--praxis-ai-assistant-shell-z-index, 1200);pointer-events:none}.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);pointer-events:auto;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__recommended{flex:0 0 auto;display:grid;gap:8px}.praxis-ai-assistant-shell__recommended-header{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600;line-height:1.25}.praxis-ai-assistant-shell__recommended-header mat-icon{width:16px;height:16px;color:var(--md-sys-color-primary);font-size:16px;line-height:16px}.praxis-ai-assistant-shell__recommended-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr));gap:8px}.praxis-ai-assistant-shell__recommended-intent{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral);appearance:none;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 34%,transparent);border-radius:8px;background:linear-gradient(180deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 8%,transparent),transparent),var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);cursor:pointer;display:flex;gap:9px;min-width:0;min-height:86px;padding:10px;text-align:left;transition:border-color .16s ease,box-shadow .16s ease,background-color .16s ease}.praxis-ai-assistant-shell__recommended-intent:hover:not(:disabled),.praxis-ai-assistant-shell__recommended-intent:focus-visible{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 68%,transparent);box-shadow:0 0 0 3px color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 15%,transparent);outline:none}.praxis-ai-assistant-shell__recommended-intent:disabled{cursor:default;opacity:.62}.praxis-ai-assistant-shell__recommended-icon{flex:0 0 auto;display:grid;place-items:center;width:30px;height:30px;border:1px solid color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 28%,transparent);border-radius:8px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 12%,transparent);color:var(--praxis-ai-assistant-shell-recommended-accent)}.praxis-ai-assistant-shell__recommended-icon mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.praxis-ai-assistant-shell__recommended-copy{min-width:0;display:grid;gap:5px}.praxis-ai-assistant-shell__recommended-title-row{min-width:0;display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.praxis-ai-assistant-shell__recommended-title,.praxis-ai-assistant-shell__recommended-description,.praxis-ai-assistant-shell__recommended-group{min-width:0;overflow-wrap:anywhere}.praxis-ai-assistant-shell__recommended-title{color:var(--md-sys-color-on-surface);font-size:13px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-group{flex:0 1 auto;max-width:44%;border-radius:8px;padding:2px 6px;background:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 10%,transparent);color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:10.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-description{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.35}.praxis-ai-assistant-shell__recommended-cta{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap;color:color-mix(in srgb,var(--praxis-ai-assistant-shell-recommended-accent) 84%,var(--praxis-ai-assistant-shell-highlight-color));font-size:11.5px;font-weight:700;line-height:1.25}.praxis-ai-assistant-shell__recommended-cta mat-icon{width:15px;height:15px;font-size:15px;line-height:15px}.praxis-ai-assistant-shell__recommended-intent--tone-analytics{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-analytics)}.praxis-ai-assistant-shell__recommended-intent--tone-resource{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-resource)}.praxis-ai-assistant-shell__recommended-intent--tone-success{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-success)}.praxis-ai-assistant-shell__recommended-intent--tone-warning{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__recommended-intent--tone-danger{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-danger)}.praxis-ai-assistant-shell__recommended-intent--tone-neutral{--praxis-ai-assistant-shell-recommended-accent: var(--praxis-ai-assistant-shell-tone-neutral)}.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__assistant-content{display:grid;gap:8px}.praxis-ai-assistant-shell__assistant-block{display:grid;gap:8px;min-width:0}.praxis-ai-assistant-shell__assistant-block--summary,.praxis-ai-assistant-shell__assistant-block--recommendation{grid-template-columns:auto minmax(0,1fr);align-items:flex-start;padding:9px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent);border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary) 7%,transparent)}.praxis-ai-assistant-shell__assistant-block--recommendation{border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 26%,transparent);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 8%,transparent)}.praxis-ai-assistant-shell__assistant-block-icon{display:grid;place-items:center;width:24px;height:24px;border-radius:8px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent)}.praxis-ai-assistant-shell__assistant-block--recommendation .praxis-ai-assistant-shell__assistant-block-icon{color:var(--praxis-ai-assistant-shell-tone-success);background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 14%,transparent)}.praxis-ai-assistant-shell__assistant-block-icon mat-icon{width:16px;height:16px;font-size:16px;line-height:16px}.praxis-ai-assistant-shell__assistant-block-copy{min-width:0}.praxis-ai-assistant-shell__assistant-block-copy strong{display:block;margin-bottom:3px}.praxis-ai-assistant-shell__assistant-block-heading{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-surface);font-size:12px;font-weight:700}.praxis-ai-assistant-shell__assistant-block-heading mat-icon{width:16px;height:16px;color:var(--md-sys-color-primary);font-size:16px}.praxis-ai-assistant-shell__assistant-resources{display:grid;gap:7px}.praxis-ai-assistant-shell__assistant-resource{display:grid;gap:7px;min-width:0;padding:9px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-surface-container-highest) 74%,transparent)}.praxis-ai-assistant-shell__assistant-resource-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;min-width:0}.praxis-ai-assistant-shell__assistant-resource-head strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.praxis-ai-assistant-shell__assistant-resource-meta,.praxis-ai-assistant-shell__assistant-field-list,.praxis-ai-assistant-shell__assistant-evidence{display:flex;flex-wrap:wrap;gap:5px}.praxis-ai-assistant-shell__assistant-resource-meta span,.praxis-ai-assistant-shell__assistant-field,.praxis-ai-assistant-shell__assistant-evidence span{display:inline-flex;align-items:center;gap:4px;min-width:0;max-width:100%;padding:3px 6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 62%,transparent);border-radius:999px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);font-size:11px;line-height:1.25}.praxis-ai-assistant-shell__assistant-field{color:color-mix(in srgb,var(--md-sys-color-primary) 88%,var(--md-sys-color-on-surface));background:color-mix(in srgb,var(--md-sys-color-primary) 9%,transparent);border-color:color-mix(in srgb,var(--md-sys-color-primary) 22%,transparent)}.praxis-ai-assistant-shell__assistant-evidence span{color:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 85%,var(--md-sys-color-on-surface));background:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 9%,transparent);border-color:color-mix(in srgb,var(--praxis-ai-assistant-shell-tone-success) 22%,transparent)}.praxis-ai-assistant-shell__assistant-evidence mat-icon{width:13px;height:13px;font-size:13px}.praxis-ai-assistant-shell__assistant-resource p{margin:0;color:var(--md-sys-color-on-surface-variant)}.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-feedback,.praxis-ai-assistant-shell__message-feedback-submitted{display:flex;align-items:center;gap:4px;margin-top:8px}.praxis-ai-assistant-shell__message-feedback-action{--mdc-icon-button-state-layer-size: 30px;--mat-icon-button-state-layer-size: 30px;display:inline-grid;place-items:center;width:30px;min-width:30px;height:30px;padding:0;color:var(--md-sys-color-on-surface-variant);line-height:1}.praxis-ai-assistant-shell__message-feedback-action mat-icon,.praxis-ai-assistant-shell__message-feedback-submitted mat-icon{display:block;width:17px;height:17px;font-size:17px;line-height:17px}.praxis-ai-assistant-shell__message-feedback-submitted{color:var(--md-sys-color-on-surface-variant);font-size:12px}.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(--md-sys-color-outline-variant) 82%,transparent);border-radius:8px;background:var(--md-sys-color-surface-container-high);box-shadow:none}.praxis-ai-assistant-shell__quick-reply--source-review{padding:11px 12px;border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 88%,transparent);border-radius:8px;background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-ai-assistant-shell-quick-reply-accent) 7%,transparent),transparent 58%),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{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--guided-action:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--guided-action:focus-visible,.praxis-ai-assistant-shell__quick-reply--source-review:hover:not(:disabled),.praxis-ai-assistant-shell__quick-reply--source-review:focus-visible{border-color:color-mix(in srgb,var(--md-sys-color-primary) 64%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 18%,var(--md-sys-color-surface-container-high));box-shadow:0 0 0 2px color-mix(in srgb,var(--md-sys-color-primary) 14%,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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review ::ng-deep .mdc-button__label{gap:10px;align-items:flex-start}.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,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-icon-frame{width:34px;height:34px;border-radius:8px;box-shadow:none}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-icon-frame,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-icon-frame{border-color:color-mix(in srgb,var(--md-sys-color-primary) 24%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-high))}.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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review .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,.praxis-ai-assistant-shell__quick-reply--source-review .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--guided-action .praxis-ai-assistant-shell__quick-reply-description{color:var(--md-sys-color-on-surface-variant)}.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,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-badge{border-radius:8px;font-size:10px;letter-spacing:0}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-badge,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-badge{border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 76%,transparent);color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 62%,transparent)}.praxis-ai-assistant-shell__quick-reply--guided-action .praxis-ai-assistant-shell__quick-reply-cta,.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-cta{color:var(--md-sys-color-primary)}.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-context{gap:5px}.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-context-chip{border-radius:8px;padding:4px 7px;background:color-mix(in srgb,var(--md-sys-color-surface-container-lowest) 66%,transparent);font-size:10.5px;font-weight:650}.praxis-ai-assistant-shell__quick-reply--source-review .praxis-ai-assistant-shell__quick-reply-actions{max-width:40%}.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,.praxis-ai-assistant-shell__quick-reply--source-review .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__voice-action{color:var(--md-sys-color-on-surface-variant)}.praxis-ai-assistant-shell__voice-action--active{color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error) 10%,transparent)}.praxis-ai-assistant-shell__voice-action--error{color:var(--praxis-ai-assistant-shell-tone-warning)}.praxis-ai-assistant-shell__voice-status{margin:-2px 10px 8px;color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.3}.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"] }]
|
|
8964
9378
|
}], propDecorators: { labels: [{
|
|
8965
9379
|
type: Input
|
|
8966
9380
|
}], mode: [{
|